mirror of
https://github.com/unrealircd/unrealircd.git
synced 2026-07-06 07:33:12 +02:00
Add set::anti-flood options lag-penalty and lag-penalty-sec.
This also allows known-users to execute slightly more commands per second. For people who want their trusted users/bots to allow even more commands per second (eg 20cmds/sec) we now have a nice FAQ item that uses this: https://www.unrealircd.org/docs/FAQ#high-command-rate
This commit is contained in:
@@ -33,6 +33,14 @@ Enhancements:
|
||||
* New [security-group block](https://www.unrealircd.org/docs/Security-group_block)
|
||||
item called *include-mask*. This can be used to put clients matching
|
||||
a [mask](https://www.unrealircd.org/docs/Mask_item) into a security group.
|
||||
* New option *lag-penalty* and *lag-penalty-bytes* in the
|
||||
[set::anti-flood block](https://www.unrealircd.org/docs/Anti-flood_settings).
|
||||
* *known-users* can now executes commands at a slightly faster rate than
|
||||
*unknown-users*.
|
||||
* It can further be used to allow really trusted users/bots to execute
|
||||
commands at even higher rates, such as 20 commands per second,
|
||||
without making them IRCOp. This explained in
|
||||
[FAQ: How to allow users to send more commands per second](https://www.unrealircd.org/docs/FAQ#high-command-rate).
|
||||
|
||||
UnrealIRCd 5.2.0
|
||||
-----------------
|
||||
|
||||
@@ -1225,6 +1225,7 @@ typedef enum FloodOption {
|
||||
FLD_INVITE = 3, /**< invite-flood */
|
||||
FLD_KNOCK = 4, /**< knock-flood */
|
||||
FLD_CONVERSATIONS = 5, /**< max-concurrent-conversations */
|
||||
FLD_LAG_PENALTY = 6, /**< lag-penalty / lag-penalty-bytes */
|
||||
} FloodOption;
|
||||
#define MAXFLOODOPTIONS 10
|
||||
|
||||
@@ -1268,6 +1269,7 @@ struct LocalClient {
|
||||
int fd; /**< File descriptor, can be <0 if socket has been closed already. */
|
||||
SSL *ssl; /**< OpenSSL/LibreSSL struct for SSL/TLS connection */
|
||||
time_t since; /**< Time when user will next be allowed to send something (actually since<currenttime+10) */
|
||||
int since_msec; /**< Used for calculating 'since' penalty (modulo) */
|
||||
time_t firsttime; /**< Time user was created (connected on IRC) */
|
||||
time_t lasttime; /**< Last time any message was received */
|
||||
dbuf sendQ; /**< Outgoing send queue (data to be sent) */
|
||||
|
||||
+48
@@ -1807,6 +1807,7 @@ void config_setdefaultsettings(Configuration *i)
|
||||
config_parse_flood_generic("4:60", i, "known-users", FLD_INVITE); /* INVITE flood protection: max 4 per 60s */
|
||||
config_parse_flood_generic("4:120", i, "known-users", FLD_KNOCK); /* KNOCK protection: max 4 per 120s */
|
||||
config_parse_flood_generic("10:15", i, "known-users", FLD_CONVERSATIONS); /* 10 users, new user every 15s */
|
||||
config_parse_flood_generic("180:750", i, "known-users", FLD_LAG_PENALTY); /* 180 bytes / 750 msec */
|
||||
/* - unknown-users */
|
||||
config_parse_flood_generic("2:60", i, "unknown-users", FLD_NICK); /* NICK flood protection: max 2 per 60s */
|
||||
config_parse_flood_generic("2:90", i, "unknown-users", FLD_JOIN); /* JOIN flood protection: max 2 per 90s */
|
||||
@@ -1814,6 +1815,7 @@ void config_setdefaultsettings(Configuration *i)
|
||||
config_parse_flood_generic("2:60", i, "unknown-users", FLD_INVITE); /* INVITE flood protection: max 2 per 60s */
|
||||
config_parse_flood_generic("2:120", i, "unknown-users", FLD_KNOCK); /* KNOCK protection: max 2 per 120s */
|
||||
config_parse_flood_generic("4:15", i, "unknown-users", FLD_CONVERSATIONS); /* 4 users, new user every 15s */
|
||||
config_parse_flood_generic("90:1000", i, "unknown-users", FLD_LAG_PENALTY); /* 90 bytes / 1000 msec */
|
||||
|
||||
/* SSL/TLS options */
|
||||
i->tls_options = safe_alloc(sizeof(TLSOptions));
|
||||
@@ -7681,6 +7683,8 @@ int _conf_set(ConfigFile *conf, ConfigEntry *ce)
|
||||
else if (!strcmp(cep->ce_varname, "anti-flood")) {
|
||||
for (cepp = cep->ce_entries; cepp; cepp = cepp->ce_next)
|
||||
{
|
||||
int lag_penalty = -1;
|
||||
int lag_penalty_bytes = -1;
|
||||
for (ceppp = cepp->ce_entries; ceppp; ceppp = ceppp->ce_next)
|
||||
{
|
||||
if (!strcmp(ceppp->ce_varname, "handshake-data-flood"))
|
||||
@@ -7715,6 +7719,16 @@ int _conf_set(ConfigFile *conf, ConfigEntry *ce)
|
||||
{
|
||||
config_parse_flood_generic(ceppp->ce_vardata, &tempiConf, cepp->ce_varname, FLD_KNOCK);
|
||||
}
|
||||
else if (!strcmp(ceppp->ce_varname, "lag-penalty"))
|
||||
{
|
||||
lag_penalty = atoi(ceppp->ce_vardata);
|
||||
}
|
||||
else if (!strcmp(ceppp->ce_varname, "lag-penalty-bytes"))
|
||||
{
|
||||
lag_penalty_bytes = config_checkval(ceppp->ce_vardata, CFG_SIZE);
|
||||
if (lag_penalty_bytes <= 0)
|
||||
lag_penalty_bytes = INT_MAX;
|
||||
}
|
||||
else if (!strcmp(ceppp->ce_varname, "connect-flood"))
|
||||
{
|
||||
int cnt, period;
|
||||
@@ -7752,6 +7766,13 @@ int _conf_set(ConfigFile *conf, ConfigEntry *ce)
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((lag_penalty != -1) && (lag_penalty_bytes != -1))
|
||||
{
|
||||
/* We use a hack here to make it fit our storage format */
|
||||
char buf[64];
|
||||
snprintf(buf, sizeof(buf), "%d:%d", lag_penalty_bytes, lag_penalty);
|
||||
config_parse_flood_generic(buf, &tempiConf, cepp->ce_varname, FLD_LAG_PENALTY);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strcmp(cep->ce_varname, "options")) {
|
||||
@@ -8508,6 +8529,9 @@ int _test_set(ConfigFile *conf, ConfigEntry *ce)
|
||||
|
||||
for (cepp = cep->ce_entries; cepp; cepp = cepp->ce_next)
|
||||
{
|
||||
int has_lag_penalty = 0;
|
||||
int has_lag_penalty_bytes = 0;
|
||||
|
||||
/* Test for old options: */
|
||||
if (flood_option_is_old(cepp->ce_varname))
|
||||
{
|
||||
@@ -8721,6 +8745,24 @@ int _test_set(ConfigFile *conf, ConfigEntry *ce)
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(ceppp->ce_varname, "lag-penalty"))
|
||||
{
|
||||
int v;
|
||||
CheckNull(ceppp);
|
||||
v = atoi(ceppp->ce_vardata);
|
||||
has_lag_penalty = 1;
|
||||
if ((v < 0) || (v > 10000))
|
||||
{
|
||||
config_error("%s:%i: set::anti-flood::%s::lag-penalty: value is in milliseconds and should be between 0 and 10000",
|
||||
ceppp->ce_fileptr->cf_filename, ceppp->ce_varlinenum, cepp->ce_varname);
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(ceppp->ce_varname, "lag-penalty-bytes"))
|
||||
{
|
||||
has_lag_penalty_bytes = 1;
|
||||
CheckNull(ceppp);
|
||||
}
|
||||
else if (!strcmp(ceppp->ce_varname, "connect-flood"))
|
||||
{
|
||||
int cnt, period;
|
||||
@@ -8782,6 +8824,12 @@ int _test_set(ConfigFile *conf, ConfigEntry *ce)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (has_lag_penalty+has_lag_penalty_bytes == 1)
|
||||
{
|
||||
config_error("%s:%i: set::anti-flood::%s: if you use lag-penalty then you must also add an lag-penalty-bytes item (and vice-versa)",
|
||||
cepp->ce_fileptr->cf_filename, cepp->ce_varlinenum, cepp->ce_varname);
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
/* Now the warnings: */
|
||||
if (anti_flood_old == 1)
|
||||
|
||||
@@ -796,6 +796,14 @@ static void stats_set_anti_flood(Client *client, FloodSettings *f)
|
||||
f->name, floodoption_names[i],
|
||||
(int)f->limit[i], pretty_time_val(f->period[i]));
|
||||
}
|
||||
if (i == FLD_LAG_PENALTY)
|
||||
{
|
||||
sendtxtnumeric(client, "anti-flood::%s::lag-penalty: %d msec",
|
||||
f->name, (int)f->period[i]);
|
||||
sendtxtnumeric(client, "anti-flood::%s::lag-penalty-bytes: %d",
|
||||
f->name,
|
||||
f->limit[i] == INT_MAX ? 0 : (int)f->limit[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
sendtxtnumeric(client, "anti-flood::%s::%s: %d per %s",
|
||||
|
||||
+12
-1
@@ -573,13 +573,24 @@ static void ban_handshake_data_flooder(Client *client)
|
||||
*/
|
||||
void parse_addlag(Client *client, int cmdbytes)
|
||||
{
|
||||
FloodSettings *settings = get_floodsettings_for_user(client, FLD_LAG_PENALTY);
|
||||
|
||||
if (!IsServer(client) && !IsNoFakeLag(client) &&
|
||||
#ifdef FAKELAG_CONFIGURABLE
|
||||
!(client->local->class && (client->local->class->options & CLASS_OPT_NOFAKELAG)) &&
|
||||
#endif
|
||||
!ValidatePermissionsForPath("immune:lag",client,NULL,NULL,NULL))
|
||||
{
|
||||
client->local->since += (1 + cmdbytes/90);
|
||||
int lag_penalty = settings->period[FLD_LAG_PENALTY];
|
||||
int lag_penalty_bytes = settings->limit[FLD_LAG_PENALTY];
|
||||
|
||||
client->local->since_msec += (1 + (cmdbytes/lag_penalty_bytes)) * lag_penalty;
|
||||
|
||||
/* This code takes into account not only the msecs we just calculated
|
||||
* but also any leftover msec from previous lagging up.
|
||||
*/
|
||||
client->local->since += (client->local->since_msec / 1000);
|
||||
client->local->since_msec = client->local->since_msec % 1000;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1086,5 +1086,6 @@ MODVAR char *floodoption_names[] = {
|
||||
"invite-flood",
|
||||
"knock-flood",
|
||||
"max-concurrent-conversations",
|
||||
"lag-penalty",
|
||||
NULL
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user