diff options
-rw-r--r-- | include/inspircd.h | 11 | ||||
-rw-r--r-- | include/modules.h | 2 | ||||
-rw-r--r-- | src/inspircd.cpp | 18 | ||||
-rw-r--r-- | src/modules/m_spanningtree.cpp | 2 | ||||
-rw-r--r-- | src/users.cpp | 65 |
5 files changed, 65 insertions, 33 deletions
diff --git a/include/inspircd.h b/include/inspircd.h index 8cce5513a..64489aaf6 100644 --- a/include/inspircd.h +++ b/include/inspircd.h @@ -193,6 +193,9 @@ class FileLogger : public EventHandler /** A list of failed port bindings, used for informational purposes on startup */ typedef std::vector<std::pair<std::string, long> > FailedPortList; +/** A list of ip addresses cross referenced against clone counts */ +typedef std::map<irc::string, unsigned int> clonemap; + class XLineManager; /** The main class of the irc server. @@ -401,6 +404,10 @@ class InspIRCd : public classbase */ std::vector<userrec*> all_opers; + clonemap local_clones; + + clonemap global_clones; + /** Whowas container, contains a map of vectors of users tracked by WHOWAS */ irc::whowas::whowas_users whowas; @@ -453,6 +460,10 @@ class InspIRCd : public classbase */ int SetTimeDelta(int delta); + void AddLocalClone(userrec* user); + + void AddGlobalClone(userrec* user); + /** Get the time offset in seconds * @return The current time delta (in seconds) */ diff --git a/include/modules.h b/include/modules.h index df8c03e3b..275063be9 100644 --- a/include/modules.h +++ b/include/modules.h @@ -79,7 +79,7 @@ enum MessageType { * ipv4 servers, so this value will be ten times as * high on ipv6 servers. */ -#define NATIVE_API_VERSION 11007 +#define NATIVE_API_VERSION 11008 #ifdef IPV6 #define API_VERSION (NATIVE_API_VERSION * 10) #else diff --git a/src/inspircd.cpp b/src/inspircd.cpp index e7801f1d5..8c297af07 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -841,6 +841,24 @@ int InspIRCd::SetTimeDelta(int delta) return old; } +void InspIRCd::AddLocalClone(userrec* user) +{ + clonemap::iterator x = local_clones.find(user->GetIPString()); + if (x != local_clones.end()) + x->second++; + else + local_clones[user->GetIPString()] = 1; +} + +void InspIRCd::AddGlobalClone(userrec* user) +{ + clonemap::iterator y = global_clones.find(user->GetIPString()); + if (y != global_clones.end()) + y->second++; + else + global_clones[user->GetIPString()] = 1; +} + int InspIRCd::GetTimeDelta() { return time_delta; diff --git a/src/modules/m_spanningtree.cpp b/src/modules/m_spanningtree.cpp index 9345b5463..a50aac256 100644 --- a/src/modules/m_spanningtree.cpp +++ b/src/modules/m_spanningtree.cpp @@ -1894,6 +1894,8 @@ class TreeSocket : public InspSocket #endif _new->SetSockAddr(AF_INET, params[6].c_str(), 0); + Instance->AddGlobalClone(_new); + this->Instance->SNO->WriteToSnoMask('C',"Client connecting at %s: %s!%s@%s [%s]",_new->server,_new->nick,_new->ident,_new->host, _new->GetIPString()); params[7] = ":" + params[7]; diff --git a/src/users.cpp b/src/users.cpp index b568bac63..f160645e2 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -331,6 +331,26 @@ userrec::~userrec() if (ip) { + clonemap::iterator x = ServerInstance->local_clones.find(this->GetIPString()); + if (x != ServerInstance->local_clones.end()) + { + x->second--; + if (!x->second) + { + ServerInstance->local_clones.erase(x); + } + } + + clonemap::iterator y = ServerInstance->global_clones.find(this->GetIPString()); + if (y != ServerInstance->global_clones.end()) + { + y->second--; + if (!y->second) + { + ServerInstance->global_clones.erase(y); + } + } + if (this->GetProtocolFamily() == AF_INET) { delete (sockaddr_in*)ip; @@ -1032,6 +1052,9 @@ void userrec::AddClient(InspIRCd* Instance, int socket, int port, bool iscached, Instance->Log(DEBUG,"Hosts set."); + Instance->AddLocalClone(New); + Instance->AddGlobalClone(New); + // set the registration timeout for this user unsigned long class_regtimeout = 90; int class_flood = 0; @@ -1130,42 +1153,20 @@ void userrec::AddClient(InspIRCd* Instance, int socket, int port, bool iscached, long userrec::GlobalCloneCount() { - char u2[128]; - long x = 0; - strlcpy(u2, this->GetIPString(), 64); - - for (user_hash::const_iterator a = ServerInstance->clientlist.begin(); a != ServerInstance->clientlist.end(); a++) - { - /* We have to match ip's as strings - we don't know what protocol - * a remote user may be using - */ - if (strcasecmp(a->second->GetIPString(), u2) == 0) - x++; - } - - return x; + clonemap::iterator x = ServerInstance->global_clones.find(this->GetIPString()); + if (x != ServerInstance->global_clones.end()) + return x->second; + else + return 0; } long userrec::LocalCloneCount() { - long x = 0; - for (std::vector<userrec*>::const_iterator a = ServerInstance->local_users.begin(); a != ServerInstance->local_users.end(); a++) - { - userrec* comp = *a; -#ifdef IPV6 - /* I dont think theres any faster way of matching two ipv6 addresses than memcmp */ - in6_addr* s1 = &(((sockaddr_in6*)comp->ip)->sin6_addr); - in6_addr* s2 = &(((sockaddr_in6*)this->ip)->sin6_addr); - if (!memcmp(s1->s6_addr, s2->s6_addr, sizeof(in6_addr))) - x++; -#else - in_addr* s1 = &((sockaddr_in*)comp->ip)->sin_addr; - in_addr* s2 = &((sockaddr_in*)this->ip)->sin_addr; - if (s1->s_addr == s2->s_addr) - x++; -#endif - } - return x; + clonemap::iterator x = ServerInstance->local_clones.find(this->GetIPString()); + if (x != ServerInstance->local_clones.end()) + return x->second; + else + return 0; } void userrec::FullConnect(CullList* Goners) |