unrealircd

- supernets unrealircd source & configuration
git clone git://git.acid.vegas/unrealircd.git
Log | Files | Refs | Archive | README | LICENSE

max-unknown-connections-per-ip.c (2137B)

      1 /*
      2  * Connection throttling (set::max-unknown-connections-per-ip)
      3  * (C) Copyright 2022- Bram Matthys and the UnrealIRCd team.
      4  * License: GPLv2 or later
      5  */
      6 
      7 #include "unrealircd.h"
      8 
      9 ModuleHeader MOD_HEADER
     10   = {
     11 	"max-unknown-connections-per-ip",
     12 	"6.0.0",
     13 	"set::max-unknown-connections-per-ip",
     14 	"UnrealIRCd Team",
     15 	"unrealircd-6",
     16     };
     17 
     18 /* Forward declaration */
     19 int max_unknown_connections_accept(Client *client);
     20 int max_unknown_connections_ip_change(Client *client, const char *oldip);
     21 
     22 MOD_INIT()
     23 {
     24 	MARK_AS_OFFICIAL_MODULE(modinfo);
     25 
     26 	HookAdd(modinfo->handle, HOOKTYPE_ACCEPT, -2000, max_unknown_connections_accept);
     27 	HookAdd(modinfo->handle, HOOKTYPE_IP_CHANGE, -2000, max_unknown_connections_ip_change);
     28 
     29 	return MOD_SUCCESS;
     30 }
     31 
     32 MOD_LOAD()
     33 {
     34 	return MOD_SUCCESS;
     35 }
     36 
     37 MOD_UNLOAD()
     38 {
     39 	return MOD_SUCCESS;
     40 }
     41 
     42 /** This checks set::max-unknown-connections-per-ip,
     43  * which is an important safety feature.
     44  */
     45 static int check_too_many_unknown_connections(Client *client)
     46 {
     47 	int cnt = 1;
     48 	Client *c;
     49 
     50 	if (!find_tkl_exception(TKL_CONNECT_FLOOD, client))
     51 	{
     52 		list_for_each_entry(c, &unknown_list, lclient_node)
     53 		{
     54 			if (client->local && client->local->listener &&
     55 			    (client->local->listener->options & LISTENER_NO_CHECK_CONNECT_FLOOD))
     56 			{
     57 				continue;
     58 			}
     59 			if (!strcmp(client->ip,GetIP(c)))
     60 			{
     61 				cnt++;
     62 				if (cnt > iConf.max_unknown_connections_per_ip)
     63 					return 1;
     64 			}
     65 		}
     66 	}
     67 
     68 	return 0;
     69 }
     70 
     71 int max_unknown_connections_accept(Client *client)
     72 {
     73 	if (client->local->listener->options & LISTENER_NO_CHECK_CONNECT_FLOOD)
     74 		return 0;
     75 
     76 	/* Check set::max-unknown-connections-per-ip */
     77 	if (check_too_many_unknown_connections(client))
     78 	{
     79 		send_raw_direct(client, "ERROR :Closing Link: [%s] (Too many unknown connections from your IP)", client->ip);
     80 		return HOOK_DENY;
     81 	}
     82 
     83 	return 0;
     84 }
     85 
     86 int max_unknown_connections_ip_change(Client *client, const char *oldip)
     87 {
     88 	/* Check set::max-unknown-connections-per-ip */
     89 	if (check_too_many_unknown_connections(client))
     90 	{
     91 		sendto_one(client, NULL, "ERROR :Closing Link: [%s] (Too many unknown connections from your IP)", client->ip);
     92 		return HOOK_DENY;
     93 	}
     94 
     95 	return 0;
     96 }