summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/inspircd.h11
-rw-r--r--include/modules.h2
-rw-r--r--src/inspircd.cpp18
-rw-r--r--src/modules/m_spanningtree.cpp2
-rw-r--r--src/users.cpp65
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)