1
0
mirror of https://github.com/unrealircd/unrealircd.git synced 2026-06-12 17:34:46 +02:00

Update the messages regarding too many (new) connections.

Changed "Too many connections from your IP" to have "[maxperip]" at the end.
Also create new setting and swap it with existing-one-during-development.

Long story short, we now have 3 different messages for these limits:

set::reject-message::too-many-connections
 "Too many connections from your IP [maxperip]"

set::reject-message::too-many-connections-ipv6-range
 "Too many connections from your IPv6 range ($prefix_addr/$prefix_len) [maxperip]"

set::reject-message::too-many-new-connections-ipv6-range
 "Too many new connections from this IPv6 range ($prefix_addr/$prefix_len) [connthrottle]"

So we explicitly mention whether it is maxperip or connthrottle limiting the
user, that should provide enough clue to the IRCOp if the user pastes the
message to them.
This commit is contained in:
Bram Matthys
2026-05-05 13:17:55 +02:00
parent 32e7dbfb3c
commit 0940ed5d13
6 changed files with 62 additions and 28 deletions
+1
View File
@@ -160,6 +160,7 @@ struct Configuration {
BanTarget manual_ban_target;
char *reject_message_too_many_connections;
char *reject_message_too_many_connections_ipv6_range;
char *reject_message_too_many_new_connections_ipv6_range;
char *reject_message_server_full;
char *reject_message_unauthorized;
char *reject_message_kline;
+1
View File
@@ -529,6 +529,7 @@ extern const char *inetntop(int af, const void *in, char *local_dummy, size_t th
extern void mask_ipv6_rawip(const char *src, int prefix, char *dst);
extern const char *get_clone_mask_ipstr(Client *client, char *buf, size_t buflen);
extern const char *format_ipv6_prefix_reject_message(const char *template, const char *masked_rawip, int prefix);
extern void delletterfromstring(char *s, char letter);
extern void addlettertodynamicstringsorted(char **str, char letter);
+10 -2
View File
@@ -1784,6 +1784,7 @@ void free_iConf(Configuration *i)
safe_free(i->spamexcept_line);
safe_free(i->reject_message_too_many_connections);
safe_free(i->reject_message_too_many_connections_ipv6_range);
safe_free(i->reject_message_too_many_new_connections_ipv6_range);
safe_free(i->reject_message_server_full);
safe_free(i->reject_message_unauthorized);
safe_free(i->reject_message_kline);
@@ -1916,8 +1917,9 @@ void config_setdefaultsettings(Configuration *i)
i->outdated_tls_policy_oper = POLICY_DENY;
i->outdated_tls_policy_server = POLICY_DENY;
safe_strdup(i->reject_message_too_many_connections, "Too many connections from your IP");
safe_strdup(i->reject_message_too_many_connections_ipv6_range, "Too many new connections from this IPv6 range ($prefix_addr/$prefix_len)");
safe_strdup(i->reject_message_too_many_connections, "Too many connections from your IP [maxperip]");
safe_strdup(i->reject_message_too_many_connections_ipv6_range, "Too many connections from your IPv6 range ($prefix_addr/$prefix_len) [maxperip]");
safe_strdup(i->reject_message_too_many_new_connections_ipv6_range, "Too many new connections from this IPv6 range ($prefix_addr/$prefix_len) [connthrottle]");
safe_strdup(i->reject_message_server_full, "This server is full");
safe_strdup(i->reject_message_unauthorized, "You are not authorized to connect to this server");
safe_strdup(i->reject_message_kline, "You are not welcome on this server. $bantype: $banreason. Email $klineaddr for more information.");
@@ -8399,6 +8401,8 @@ int _conf_set(ConfigFile *conf, ConfigEntry *ce)
safe_strdup(tempiConf.reject_message_too_many_connections, cepp->value);
else if (!strcmp(cepp->name, "too-many-connections-ipv6-range"))
safe_strdup(tempiConf.reject_message_too_many_connections_ipv6_range, cepp->value);
else if (!strcmp(cepp->name, "too-many-new-connections-ipv6-range"))
safe_strdup(tempiConf.reject_message_too_many_new_connections_ipv6_range, cepp->value);
else if (!strcmp(cepp->name, "server-full"))
safe_strdup(tempiConf.reject_message_server_full, cepp->value);
else if (!strcmp(cepp->name, "unauthorized"))
@@ -9916,6 +9920,10 @@ int _test_set(ConfigFile *conf, ConfigEntry *ce)
;
else if (!strcmp(cepp->name, "too-many-connections"))
;
else if (!strcmp(cepp->name, "too-many-connections-ipv6-range"))
;
else if (!strcmp(cepp->name, "too-many-new-connections-ipv6-range"))
;
else if (!strcmp(cepp->name, "server-full"))
;
else if (!strcmp(cepp->name, "unauthorized"))
+37
View File
@@ -939,3 +939,40 @@ const char *get_clone_mask_ipstr(Client *client, char *buf, size_t buflen)
mask_ipv6_rawip(client->rawip, iConf.default_ipv6_clone_mask, masked);
return inetntop(AF_INET6, masked, buf, buflen);
}
/** Format a user-facing reject message for an IPv6 prefix-aware rejection.
*
* Substitutes $prefix_addr (compressed IPv6 form, e.g. "2001:db8::") and
* $prefix_len (decimal) into the supplied template via buildvarstring.
*
* Used by both maxperip (for /N clone-cap rejections) and connthrottle
* (for /56/48/32 wider-prefix rejections).
*
* Returns a pointer to internal static storage, overwritten on each call.
*
* @param template The message template (typically iConf.reject_message_*).
* @param masked_rawip 16-byte masked raw IPv6 address.
* @param prefix Prefix length in bits.
* @return Formatted message in static buffer.
*/
const char *format_ipv6_prefix_reject_message(const char *template,
const char *masked_rawip,
int prefix)
{
static char buf[512];
char prefix_len_str[8];
char addr_str[128]; /* generously oversized; longest IPv6 string form is ~46 chars */
const char *vars[3], *values[3];
if (!inet_ntop(AF_INET6, masked_rawip, addr_str, sizeof(addr_str)))
strlcpy(addr_str, "?", sizeof(addr_str));
ircsnprintf(prefix_len_str, sizeof(prefix_len_str), "%d", prefix);
vars[0] = "prefix_addr";
values[0] = addr_str;
vars[1] = "prefix_len";
values[1] = prefix_len_str;
vars[2] = NULL;
values[2] = NULL;
buildvarstring(template, buf, sizeof(buf), vars, values);
return buf;
}
+3 -26
View File
@@ -135,7 +135,6 @@ static void ct_bucket_bump_client(Client *client, ConnThrottleCategory category)
static void ct_bucket_unbump_client(Client *client, ConnThrottleCategory category);
static void ct_buckets_rebuild(void);
static void ct_buckets_free(void);
static const char *ct_format_reject_reason(const char *masked, int prefix);
static const char *ct_module_status_text(void);
const char *ct_allow_client(Client *client, ConfigItem_allow *aconf);
int ct_remote_connect_buckets(Client *client);
@@ -1194,30 +1193,6 @@ static void ct_bucket_unbump_client(Client *client, ConnThrottleCategory categor
}
}
/* Build the user-facing rejection message. With $prefix_addr (compressed
* form, not the usual uncompressed form we use) and with $tier.
*/
static const char *ct_format_reject_reason(const char *masked, int prefix)
{
static char buf[512];
char prefix_len_str[8];
char addr_str[INET6_ADDRSTRLEN];
const char *vars[3], *values[3];
if (!inet_ntop(AF_INET6, masked, addr_str, sizeof(addr_str)))
strlcpy(addr_str, "?", sizeof(addr_str));
ircsnprintf(prefix_len_str, sizeof(prefix_len_str), "%d", prefix);
vars[0] = "prefix_addr";
values[0] = addr_str;
vars[1] = "prefix_len";
values[1] = prefix_len_str;
vars[2] = NULL;
values[2] = NULL;
buildvarstring(iConf.reject_message_too_many_connections_ipv6_range,
buf, sizeof(buf), vars, values);
return buf;
}
/** HOOKTYPE_ALLOW_CLIENT: classify the client, add to buckets, and
* reject if the unknown_users count for this client's category exceeds
* the limit at any tier. Multiple matched allow blocks may invoke this
@@ -1270,7 +1245,9 @@ const char *ct_allow_client(Client *client, ConfigItem_allow *aconf)
ct_make_rawip(client, tier, masked);
b = ct_find_bucket(tier, masked);
if (b && (b->unknown_users > effective_limit))
return ct_format_reject_reason(masked, ct_tier_prefix[tier]);
return format_ipv6_prefix_reject_message(
iConf.reject_message_too_many_new_connections_ipv6_range,
masked, ct_tier_prefix[tier]);
}
return NULL;
+10
View File
@@ -458,7 +458,17 @@ int maxperip_remote_connect(Client *client)
const char *maxperip_allow_client(Client *client, ConfigItem_allow *aconf)
{
if (exceeds_maxperip(client, aconf))
{
if (IsIPV6(client) && iConf.default_ipv6_clone_mask < 128)
{
char masked[16];
mask_ipv6_rawip(client->rawip, iConf.default_ipv6_clone_mask, masked);
return format_ipv6_prefix_reject_message(
iConf.reject_message_too_many_connections_ipv6_range,
masked, iConf.default_ipv6_clone_mask);
}
return iConf.reject_message_too_many_connections;
}
return NULL;
}