]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_connectban.cpp
d5bb20fe3f05e67aa20f49bbed99d1e2477a62ea
[user/henk/code/inspircd.git] / src / modules / m_connectban.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd: (C) 2002-2009 InspIRCd Development Team
6  * See: http://wiki.inspircd.org/Credits
7  *
8  * This program is free but copyrighted software; see
9  *            the file COPYING for details.
10  *
11  * ---------------------------------------------------
12  */
13
14 #include "inspircd.h"
15 #include "xline.h"
16
17 /* $ModDesc: Throttles the connections of any users who try connect flood */
18
19 class ModuleConnectBan : public Module
20 {
21  private:
22         clonemap connects;
23         unsigned int threshold;
24         unsigned int banduration;
25         unsigned int ipv4_cidr;
26         unsigned int ipv6_cidr;
27  public:
28         ModuleConnectBan(InspIRCd* Me) : Module(Me)
29         {
30                 Implementation eventlist[] = { I_OnUserConnect, I_OnGarbageCollect, I_OnRehash };
31                 ServerInstance->Modules->Attach(eventlist, this, 3);
32                 OnRehash(NULL);
33         }
34
35         virtual ~ModuleConnectBan()
36         {
37         }
38
39         virtual Version GetVersion()
40         {
41                 return Version("Throttles the connections of any users who try connect flood", VF_VENDOR,API_VERSION);
42         }
43
44         virtual void OnRehash(User* user)
45         {
46                 ConfigReader Conf(ServerInstance);
47                 std::string duration;
48
49                 ipv4_cidr = Conf.ReadInteger("connectban", "ipv4cidr", 0, true);
50                 if (ipv4_cidr == 0)
51                         ipv4_cidr = 32;
52
53                 ipv6_cidr = Conf.ReadInteger("connectban", "ipv6cidr", 0, true);
54                 if (ipv6_cidr == 0)
55                         ipv6_cidr = 128;
56
57                 threshold = Conf.ReadInteger("connectban", "threshold", 0, true);
58
59                 if (threshold == 0)
60                         threshold = 10;
61
62                 duration = Conf.ReadValue("connectban", "duration", 0, true);
63
64                 if (duration.empty())
65                         duration = "10m";
66
67                 banduration = ServerInstance->Duration(duration);
68         }
69
70         virtual void OnUserConnect(User *u)
71         {
72                 int range = 32;
73                 clonemap::iterator i;
74
75                 switch (u->client_sa.sa.sa_family)
76                 {
77                         case AF_INET6:
78                                 range = ipv6_cidr;
79                         break;
80                         case AF_INET:
81                                 range = ipv4_cidr;
82                         break;
83                 }
84
85                 i = connects.find(u->GetCIDRMask(range));
86
87                 if (i != connects.end())
88                 {
89                         i->second++;
90
91                         if (i->second >= threshold)
92                         {
93                                 // Create zline for set duration.
94                                 ZLine* zl = new ZLine(ServerInstance, ServerInstance->Time(), banduration, ServerInstance->Config->ServerName, "Connect flooding", u->GetCIDRMask(range));
95                                 if (ServerInstance->XLines->AddLine(zl,NULL))
96                                         ServerInstance->XLines->ApplyLines();
97                                 else
98                                         delete zl;
99
100                                 ServerInstance->SNO->WriteGlobalSno('x',"Module m_connectban added Z:line on *@%s to expire on %s: Connect flooding", 
101                                         u->GetCIDRMask(range), ServerInstance->TimeString(zl->expiry).c_str());
102                                 ServerInstance->SNO->WriteGlobalSno('a', "Connect flooding from IP range %s (%d)", u->GetCIDRMask(range), threshold);
103                                 connects.erase(i);
104                         }
105                 }
106                 else
107                 {
108                         connects[u->GetCIDRMask(range)] = 1;
109                 }
110         }
111
112         virtual void OnGarbageCollect()
113         {
114                 ServerInstance->Logs->Log("m_connectban",DEBUG, "Clearing map.");
115                 connects.clear();
116         }
117 };
118
119 MODULE_INIT(ModuleConnectBan)