age = ServerInstance->Time(true);
lines_in = lastping = signon = idle_lastmsg = nping = registered = 0;
ChannelCount = timeout = flood = bytes_in = bytes_out = cmds_in = cmds_out = 0;
- haspassed = dns_done = false;
+ exempt = haspassed = dns_done = false;
fd = -1;
recvq = "";
sendq = "";
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;
this->ServerInstance->SE->WantWrite(this);
}
else
- this->SetWriteError(strerror(errno));
+ {
+ this->QuitUser(ServerInstance, this, strerror(errno));
+ return;
+ }
}
else
{
user->WriteCommonExcept("QUIT :%s",reason.c_str());
}
- if (IS_LOCAL(user))
- user->FlushWriteBuf();
-
FOREACH_MOD_I(Instance,I_OnUserDisconnect,OnUserDisconnect(user));
if (IS_LOCAL(user))
}
Instance->Log(DEBUG,"AddClient: %d %d %s",socket,port,ipaddr);
-
+
New = new userrec(Instance);
Instance->clientlist[tempnick] = New;
New->fd = socket;
New->signon = Instance->Time() + Instance->Config->dns_timeout;
New->lastping = 1;
- Instance->Log(DEBUG,"Setting socket addresses");
New->SetSockAddr(AF_FAMILY, ipaddr, port);
- Instance->Log(DEBUG,"Socket addresses set.");
/* Smarter than your average bear^H^H^H^Hset of strlcpys. */
for (const char* temp = New->GetIPString(); *temp && j < 64; temp++, j++)
New->dhost[j] = New->host[j] = *temp;
New->dhost[j] = New->host[j] = 0;
-
- Instance->Log(DEBUG,"Hosts set.");
+
+ Instance->AddLocalClone(New);
+ Instance->AddGlobalClone(New);
// set the registration timeout for this user
unsigned long class_regtimeout = 90;
long class_sqmax = 262144; // 256kb
long class_rqmax = 4096; // 4k
- Instance->Log(DEBUG,"Class stuff set.");
-
for (ClassVector::iterator i = Instance->Config->Classes.begin(); i != Instance->Config->Classes.end(); i++)
{
if ((i->type == CC_ALLOW) && (match(ipaddr,i->host.c_str(),true)))
}
}
- Instance->Log(DEBUG,"nping etc set.");
-
New->nping = Instance->Time() + New->pingmax + Instance->Config->dns_timeout;
New->timeout = Instance->Time() + class_regtimeout;
New->flood = class_flood;
New->sendqmax = class_sqmax;
New->recvqmax = class_rqmax;
- Instance->Log(DEBUG,"Push back to local users.");
Instance->local_users.push_back(New);
- Instance->Log(DEBUG,"Check softlimit: %d %d %d",Instance->local_users.size(), Instance->Config->SoftLimit, MAXCLIENTS);
if ((Instance->local_users.size() > Instance->Config->SoftLimit) || (Instance->local_users.size() >= MAXCLIENTS))
{
- Instance->Log(DEBUG,"Check softlimit failed");
Instance->WriteOpers("*** Warning: softlimit value has been reached: %d clients", Instance->Config->SoftLimit);
userrec::QuitUser(Instance, New,"No more connections allowed");
return;
}
- Instance->Log(DEBUG,"Softlimit passed.");
-
/*
* XXX -
* this is done as a safety check to keep the file descriptors within range of fd_ref_table.
return;
}
- Instance->Log(DEBUG,"socket < MAX_DESCRIPTORS passed.");
-
- ELine* e = Instance->XLines->matches_exception(New);
- if (!e)
+ New->exempt = (Instance->XLines->matches_exception(New) != NULL);
+ if (!New->exempt)
{
- Instance->Log(DEBUG,"Doesnt match eline.");
ZLine* r = Instance->XLines->matches_zline(ipaddr);
if (r)
{
- Instance->Log(DEBUG,"Matches zline.");
char reason[MAXBUF];
snprintf(reason,MAXBUF,"Z-Lined: %s",r->reason);
userrec::QuitUser(Instance, New, reason);
return;
}
- Instance->Log(DEBUG,"Doesnt match zline.");
}
- Instance->Log(DEBUG,"Check before AddFd.");
-
if (socket > -1)
{
- Instance->Log(DEBUG,"Adding fd.");
if (!Instance->SE->AddFd(New))
{
- Instance->Log(DEBUG,"Oops, fd already exists");
userrec::QuitUser(Instance, New, "Internal error handling connection");
return;
}
}
+ /* NOTE: even if dns lookups are *off*, we still need to display this.
+ * BOPM and other stuff requires it.
+ */
New->WriteServ("NOTICE Auth :*** Looking up your hostname...");
}
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)
return;
}
- ELine* e = ServerInstance->XLines->matches_exception(this);
-
- if (!e)
+ if (!this->exempt)
{
GLine* r = ServerInstance->XLines->matches_gline(this);
this->FlushWriteBuf();
break;
case EVENT_ERROR:
- this->SetWriteError(errornum ? strerror(errornum) : "EOF from client");
+ /** This should be safe, but dont DARE do anything after it -- Brain */
+ userrec::QuitUser(ServerInstance, this, errornum ? strerror(errornum) : "EOF from client");
break;
}
}