The InspIRCd Project
Home | Developers | Wiki | Forums | Bug Tracker | SVN | Download
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

m_connectban.cpp

Go to the documentation of this file.
00001 /*       +------------------------------------+
00002  *       | Inspire Internet Relay Chat Daemon |
00003  *       +------------------------------------+
00004  *
00005  *  InspIRCd: (C) 2002-2008 InspIRCd Development Team
00006  * See: http://www.inspircd.org/wiki/index.php/Credits
00007  *
00008  * This program is free but copyrighted software; see
00009  *            the file COPYING for details.
00010  *
00011  * ---------------------------------------------------
00012  */
00013 
00014 #include "inspircd.h"
00015 #include "xline.h"
00016 
00017 /* $ModDesc: Throttles the connections of any users who try connect flood */
00018 
00019 class ModuleConnectBan : public Module
00020 {
00021  private:
00022         clonemap connects;
00023         unsigned int threshold;
00024         unsigned int banduration;
00025         unsigned int ipv4_cidr;
00026         unsigned int ipv6_cidr;
00027  public:
00028         ModuleConnectBan(InspIRCd* Me) : Module(Me)
00029         {
00030                 Implementation eventlist[] = { I_OnUserConnect, I_OnGarbageCollect, I_OnRehash };
00031                 ServerInstance->Modules->Attach(eventlist, this, 3);
00032                 OnRehash(NULL, "");
00033         }
00034 
00035         virtual ~ModuleConnectBan()
00036         {
00037         }
00038 
00039         virtual Version GetVersion()
00040         {
00041                 return Version("$Id: m_connectban.cpp 10799 2008-11-08 17:21:46Z brain $", VF_VENDOR,API_VERSION);
00042         }
00043 
00044         virtual void OnRehash(User* user, const std::string &parameter)
00045         {
00046                 ConfigReader Conf(ServerInstance);
00047                 std::string duration;
00048 
00049                 ipv4_cidr = Conf.ReadInteger("connectban", "ipv4cidr", 0, true);
00050                 if (ipv4_cidr == 0)
00051                         ipv4_cidr = 32;
00052 
00053                 ipv6_cidr = Conf.ReadInteger("connectban", "ipv6cidr", 0, true);
00054                 if (ipv6_cidr == 0)
00055                         ipv6_cidr = 128;
00056 
00057                 threshold = Conf.ReadInteger("connectban", "threshold", 0, true);
00058 
00059                 if (threshold == 0)
00060                         threshold = 10;
00061 
00062                 duration = Conf.ReadValue("connectban", "duration", 0, true);
00063 
00064                 if (duration.empty())
00065                         duration = "10m";
00066 
00067                 banduration = ServerInstance->Duration(duration);
00068         }
00069 
00070         virtual void OnUserConnect(User *u)
00071         {
00072                 int range = 32;
00073                 clonemap::iterator i;
00074 
00075                 switch (u->GetProtocolFamily())
00076                 {
00077         #ifdef SUPPORT_IP6LINKS
00078                         case AF_INET6:
00079                         {
00080                                 range = ipv6_cidr;
00081                         }
00082                         break;
00083         #endif
00084                         case AF_INET:
00085                         {
00086                                 range = ipv4_cidr;
00087                         }
00088                         break;
00089                 }
00090 
00091                 i = connects.find(u->GetCIDRMask(range));
00092 
00093                 if (i != connects.end())
00094                 {
00095                         i->second++;
00096 
00097                         if (i->second >= threshold)
00098                         {
00099                                 // Create zline for set duration.
00100                                 ZLine* zl = new ZLine(ServerInstance, ServerInstance->Time(), banduration, ServerInstance->Config->ServerName, "Connect flooding", u->GetCIDRMask(range));
00101                                 if (ServerInstance->XLines->AddLine(zl,NULL))
00102                                         ServerInstance->XLines->ApplyLines();
00103                                 else
00104                                         delete zl;
00105 
00106                                 ServerInstance->SNO->WriteToSnoMask('x', "Connect flooding from IP range %s (%d)", u->GetCIDRMask(range), threshold);
00107                                 connects.erase(i);
00108                         }
00109                 }
00110                 else
00111                 {
00112                         connects[u->GetCIDRMask(range)] = 1;
00113                 }
00114         }
00115 
00116         virtual void OnGarbageCollect()
00117         {
00118                 ServerInstance->Logs->Log("m_connectban",DEBUG, "Clearing map.");
00119                 connects.clear();
00120         }
00121 };
00122 
00123 MODULE_INIT(ModuleConnectBan)