X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fusers.cpp;h=ed979e337a29db2f5fa2183f6c26572604451b5d;hb=ed105d7fef72b5bb5f23e72fae40d6b4ffdcb5b8;hp=986aea4cb83994a785adec90cd46dc129391270f;hpb=8c5d2ae45dc1cbf32f56cbcf9a0aaa0895c0541b;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/users.cpp b/src/users.cpp index 986aea4cb..ed979e337 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -300,7 +300,7 @@ userrec::userrec(InspIRCd* Instance) : ServerInstance(Instance) 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 = ""; @@ -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; @@ -673,7 +693,10 @@ void userrec::FlushWriteBuf() this->ServerInstance->SE->WantWrite(this); } else - this->SetWriteError(strerror(errno)); + { + this->QuitUser(ServerInstance, this, strerror(errno)); + return; + } } else { @@ -786,9 +809,6 @@ void userrec::QuitUser(InspIRCd* Instance, userrec *user, const std::string &qui 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)) @@ -1007,7 +1027,7 @@ void userrec::AddClient(InspIRCd* Instance, int socket, int port, bool iscached, } Instance->Log(DEBUG,"AddClient: %d %d %s",socket,port,ipaddr); - + New = new userrec(Instance); Instance->clientlist[tempnick] = New; New->fd = socket; @@ -1021,16 +1041,15 @@ void userrec::AddClient(InspIRCd* Instance, int socket, int port, bool iscached, 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; @@ -1039,8 +1058,6 @@ void userrec::AddClient(InspIRCd* Instance, int socket, int port, bool iscached, 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))) @@ -1055,8 +1072,6 @@ void userrec::AddClient(InspIRCd* Instance, int socket, int port, bool iscached, } } - 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; @@ -1064,20 +1079,15 @@ void userrec::AddClient(InspIRCd* Instance, int socket, int port, bool iscached, 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. @@ -1094,78 +1104,50 @@ void userrec::AddClient(InspIRCd* Instance, int socket, int port, bool iscached, 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::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) @@ -1200,9 +1182,7 @@ 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); @@ -2130,7 +2110,8 @@ void userrec::HandleEvent(EventType et, int errornum) 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; } }