X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules%2Fm_spanningtree.cpp;h=22c9e92461acb262156cff05da6f2b3806363209;hb=c4458ecc70025aeac7ca87115ed0a698e7bbcdad;hp=b88083c3f034cb46bc1fd54b7d3e49eb537b52b5;hpb=903dbea2b1c4072fcd4538bf67feaf1cf968bac9;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules/m_spanningtree.cpp b/src/modules/m_spanningtree.cpp index b88083c3f..22c9e9246 100644 --- a/src/modules/m_spanningtree.cpp +++ b/src/modules/m_spanningtree.cpp @@ -41,11 +41,7 @@ using namespace std; #include "cull_list.h" #include "aes.h" -#ifdef GCC3 #define nspace __gnu_cxx -#else -#define nspace std -#endif /* * The server list in InspIRCd is maintained as two structures @@ -154,7 +150,7 @@ extern std::vector pelines; * are created and destroyed. */ -class TreeServer +class TreeServer : public classbase { TreeServer* Parent; /* Parent entry */ TreeServer* Route; /* Route entry */ @@ -167,8 +163,6 @@ class TreeServer TreeSocket* Socket; /* For directly connected servers this points at the socket object */ time_t NextPing; /* After this time, the server should be PINGed*/ bool LastPingWasGood; /* True if the server responded to the last PING with a PONG */ - std::map Users; /* Users on this server */ - bool DontModifyHash; /* When the server is splitting, this is set to true so we dont bash our own iterator to death */ public: @@ -183,7 +177,6 @@ class TreeServer VersionString = ""; UserCount = OperCount = 0; VersionString = Srv->GetVersion(); - DontModifyHash = false; } /* We use this constructor only to create the 'root' item, TreeRoot, which @@ -198,7 +191,6 @@ class TreeServer VersionString = Srv->GetVersion(); Route = NULL; Socket = NULL; /* Fix by brain */ - DontModifyHash = false; AddHashEntry(); } @@ -210,7 +202,6 @@ class TreeServer { VersionString = ""; UserCount = OperCount = 0; - DontModifyHash = false; this->SetNextPingTime(time(NULL) + 120); this->SetPingFlag(); @@ -268,56 +259,26 @@ class TreeServer this->AddHashEntry(); } - void AddUser(userrec* user) - { - if (this->DontModifyHash) - { - log(DEBUG,"Not modifying hash"); - return; - } - - log(DEBUG,"Add user %s to server %s",user->nick,this->ServerName.c_str()); - std::map::iterator iter; - iter = Users.find(user); - if (iter == Users.end()) - Users[user] = user; - } - - void DelUser(userrec* user) - { - /* FIX BY BRAIN: - * Quitting the user in QuitUsers changes the hash by removing the user here, - * corrupting the iterator! - * When netsplitting, this->DontModifyHash is set to prevent it now! - */ - if (this->DontModifyHash) - { - log(DEBUG,"Not modifying hash"); - return; - } - - log(DEBUG,"Remove user %s from server %s",user->nick,this->ServerName.c_str()); - std::map::iterator iter; - iter = Users.find(user); - if (iter != Users.end()) - Users.erase(iter); - } - int QuitUsers(const std::string &reason) { - int x = Users.size(); - log(DEBUG,"Removing %d users from server %s",x,this->ServerName.c_str()); + log(DEBUG,"Removing all users from server %s",this->ServerName.c_str()); const char* reason_s = reason.c_str(); - this->DontModifyHash = true; - for (std::map::iterator n = Users.begin(); n != Users.end(); n++) + std::vector time_to_die; + for (user_hash::iterator n = clientlist.begin(); n != clientlist.end(); n++) + { + if (!strcmp(n->second->server, this->ServerName.c_str())) + { + time_to_die.push_back(n->second); + } + } + for (std::vector::iterator n = time_to_die.begin(); n != time_to_die.end(); n++) { - log(DEBUG,"Kill %s fd=%d",n->second->nick,n->second->fd); - if (!IS_LOCAL(n->second)) - kill_link(n->second,reason_s); + userrec* a = (userrec*)*n; + log(DEBUG,"Kill %s fd=%d",a->nick,a->fd); + if (!IS_LOCAL(a)) + kill_link(a,reason_s); } - Users.clear(); - this->DontModifyHash = false; - return x; + return time_to_die.size(); } /* This method is used to add the structure to the @@ -501,7 +462,7 @@ class TreeServer * of them, and populate the list on rehash/load. */ -class Link +class Link : public classbase { public: irc::string Name; @@ -594,9 +555,9 @@ class cmd_rconnect : public command_t cmd_rconnect (Module* Callback) : command_t("RCONNECT", 'o', 2), Creator(Callback) { this->source = "m_spanningtree.so"; - } + } - void Handle (char **parameters, int pcnt, userrec *user) + void Handle (const char** parameters, int pcnt, userrec *user) { WriteServ(user->fd,"NOTICE %s :*** RCONNECT: Sending remote connect to \002%s\002 to connect server \002%s\002.",user->nick,parameters[0],parameters[1]); /* Is this aimed at our server? */ @@ -604,7 +565,7 @@ class cmd_rconnect : public command_t { /* Yes, initiate the given connect */ WriteOpers("*** Remote CONNECT from %s matching \002%s\002, connecting server \002%s\002",user->nick,parameters[0],parameters[1]); - char* para[1]; + const char* para[1]; para[0] = parameters[1]; Creator->OnPreCommand("CONNECT", para, 1, user, true); } @@ -927,7 +888,7 @@ class TreeSocket : public InspSocket return true; userrec* who = new userrec(); who->fd = FD_MAGIC_NUMBER; - char* modelist[64]; + const char* modelist[64]; memset(&modelist,0,sizeof(modelist)); for (unsigned int q = 0; q < params.size(); q++) { @@ -995,7 +956,7 @@ class TreeSocket : public InspSocket memset(&mode_users,0,sizeof(mode_users)); mode_users[0] = first; mode_users[1] = modestring; - strcpy(mode_users[1],"+"); + strcpy(first,"+"); unsigned int modectr = 2; userrec* who = NULL; @@ -1030,7 +991,7 @@ class TreeSocket : public InspSocket for (unsigned int usernum = 2; usernum < params.size(); usernum++) { /* process one channel at a time, applying modes. */ - char* usr = const_cast(params[usernum].c_str()); + char* usr = (char*)params[usernum].c_str(); /* Safety check just to make sure someones not sent us an FJOIN full of spaces * (is this even possible?) */ if (usr && *usr) @@ -1067,7 +1028,7 @@ class TreeSocket : public InspSocket { /* We also always let u-lined clients win, no matter what the TS value */ log(DEBUG,"Our our channel newer than theirs, accepting their modes"); - Srv->SendMode(mode_users,modectr,who); + Srv->SendMode((const char**)mode_users,modectr,who); } else { @@ -1097,7 +1058,7 @@ class TreeSocket : public InspSocket if (ourTS >= TS) { log(DEBUG,"Our our channel newer than theirs, accepting their modes"); - Srv->SendMode(mode_users,modectr,who); + Srv->SendMode((const char**)mode_users,modectr,who); } else { @@ -1176,24 +1137,10 @@ class TreeSocket : public InspSocket strlcpy(clientlist[tempnick]->fullname, params[7].c_str(),MAXGECOS); clientlist[tempnick]->registered = 7; clientlist[tempnick]->signon = age; - strlcpy(clientlist[tempnick]->modes, params[5].c_str(),53); - for (char *v = clientlist[tempnick]->modes; *v; v++) + for (std::string::iterator v = params[5].begin(); v != params[5].end(); v++) { - switch (*v) - { - case 'i': - clientlist[tempnick]->modebits |= UM_INVISIBLE; - break; - case 'w': - clientlist[tempnick]->modebits |= UM_WALLOPS; - break; - case 's': - clientlist[tempnick]->modebits |= UM_SERVERNOTICE; - break; - default: - break; - } + clientlist[tempnick]->modes[(*v)-65] = 1; } inet_aton(params[6].c_str(),&clientlist[tempnick]->ip4); @@ -1207,7 +1154,6 @@ class TreeSocket : public InspSocket if (SourceServer) { log(DEBUG,"Found source server of %s",clientlist[tempnick]->nick); - SourceServer->AddUser(clientlist[tempnick]); SourceServer->AddUserCount(); } @@ -1391,7 +1337,7 @@ class TreeSocket : public InspSocket { if (u->second->registered == 7) { - snprintf(data,MAXBUF,":%s NICK %lu %s %s %s %s +%s %s :%s",u->second->server,(unsigned long)u->second->age,u->second->nick,u->second->host,u->second->dhost,u->second->ident,u->second->modes,inet_ntoa(u->second->ip4),u->second->fullname); + snprintf(data,MAXBUF,":%s NICK %lu %s %s %s %s +%s %s :%s",u->second->server,(unsigned long)u->second->age,u->second->nick,u->second->host,u->second->dhost,u->second->ident,u->second->FormatModes(),inet_ntoa(u->second->ip4),u->second->fullname); this->WriteLine(data); if (*u->second->oper) { @@ -1555,11 +1501,8 @@ class TreeSocket : public InspSocket userrec* u = Srv->FindNick(prefix); if (u) { + u->modes[UM_OPERATOR] = 1; strlcpy(u->oper,opertype.c_str(),NICKMAX-1); - if (!strchr(u->modes,'o')) - { - strcat(u->modes,"o"); - } DoOneToAllButSender(u->nick,"OPERTYPE",params,u->server); } return true; @@ -2213,34 +2156,28 @@ class TreeSocket : public InspSocket bool ProcessLine(std::string line) { - if (!*line.c_str()) + std::deque params; + irc::string command; + std::string prefix; + + if (line.empty()) return true; line = line.substr(0, line.find_first_of("\r\n")); log(DEBUG,"IN: %s", line.c_str()); - - std::deque params; this->Split(line.c_str(),true,params); - irc::string command = ""; - std::string prefix = ""; - if (((params[0].c_str())[0] == ':') && (params.size() > 1)) - { - prefix = params[0]; - command = params[1].c_str(); - char* pref = (char*)prefix.c_str(); - prefix = ++pref; - params.pop_front(); - params.pop_front(); - } - else + + if ((params[0][0] == ':') && (params.size() > 1)) { - prefix = ""; - command = params[0].c_str(); + prefix = params[0].substr(1); params.pop_front(); } + command = params[0].c_str(); + params.pop_front(); + if ((!this->ctx_in) && (command == "AES")) { std::string sserv = params[0]; @@ -2590,15 +2527,7 @@ class TreeSocket : public InspSocket } if (who) { - if (command == "QUIT") - { - TreeServer* s = FindServer(who->server); - if (s) - { - s->DelUser(who); - } - } - else if ((command == "NICK") && (params.size() > 0)) + if ((command == "NICK") && (params.size() > 0)) { /* On nick messages, check that the nick doesnt * already exist here. If it does, kill their copy, @@ -2619,11 +2548,6 @@ class TreeSocket : public InspSocket userrec* y = Srv->FindNick(prefix); if (y) { - TreeServer* n = FindServer(y->server); - if (n) - { - n->DelUser(y); - } Srv->QuitUser(y,"Nickname collision"); } return DoOneToAllButSenderRaw(line,sourceserv,prefix,command,params); @@ -2631,10 +2555,10 @@ class TreeSocket : public InspSocket } // its a user target = who->server; - char* strparams[127]; + const char* strparams[127]; for (unsigned int q = 0; q < params.size(); q++) { - strparams[q] = (char*)params[q].c_str(); + strparams[q] = params[q].c_str(); } if (!Srv->CallCommandHandler(command.c_str(), strparams, params.size(), who)) { @@ -3046,14 +2970,14 @@ class ModuleSpanningTree : public Module return serverlist.size(); } - void HandleLinks(char** parameters, int pcnt, userrec* user) + void HandleLinks(const char** parameters, int pcnt, userrec* user) { ShowLinks(TreeRoot,user,0); WriteServ(user->fd,"365 %s * :End of /LINKS list.",user->nick); return; } - void HandleLusers(char** parameters, int pcnt, userrec* user) + void HandleLusers(const char** parameters, int pcnt, userrec* user) { unsigned int n_users = usercnt(); @@ -3138,7 +3062,7 @@ class ModuleSpanningTree : public Module // (a character matrix), then draw the branches as a series of "L" shapes // from the nodes. This is not only friendlier on CPU it uses less stack. - void HandleMap(char** parameters, int pcnt, userrec* user) + void HandleMap(const char** parameters, int pcnt, userrec* user) { // This array represents a virtual screen which we will // "scratch" draw to, as the console device of an irc @@ -3194,7 +3118,7 @@ class ModuleSpanningTree : public Module return; } - int HandleSquit(char** parameters, int pcnt, userrec* user) + int HandleSquit(const char** parameters, int pcnt, userrec* user) { TreeServer* s = FindServerMask(parameters[0]); if (s) @@ -3224,7 +3148,7 @@ class ModuleSpanningTree : public Module return 1; } - int HandleTime(char** parameters, int pcnt, userrec* user) + int HandleTime(const char** parameters, int pcnt, userrec* user) { if ((user->fd > -1) && (pcnt)) { @@ -3248,7 +3172,7 @@ class ModuleSpanningTree : public Module return 1; } - int HandleRemoteWhois(char** parameters, int pcnt, userrec* user) + int HandleRemoteWhois(const char** parameters, int pcnt, userrec* user) { if ((user->fd > -1) && (pcnt > 1)) { @@ -3326,7 +3250,7 @@ class ModuleSpanningTree : public Module } } - int HandleVersion(char** parameters, int pcnt, userrec* user) + int HandleVersion(const char** parameters, int pcnt, userrec* user) { // we've already checked if pcnt > 0, so this is safe TreeServer* found = FindServerMask(parameters[0]); @@ -3363,7 +3287,7 @@ class ModuleSpanningTree : public Module return 1; } - int HandleConnect(char** parameters, int pcnt, userrec* user) + int HandleConnect(const char** parameters, int pcnt, userrec* user) { for (std::vector::iterator x = LinkBlocks.begin(); x < LinkBlocks.end(); x++) { @@ -3412,7 +3336,7 @@ class ModuleSpanningTree : public Module return 0; } - virtual int OnPreCommand(const std::string &command, char **parameters, int pcnt, userrec *user, bool validated) + virtual int OnPreCommand(const std::string &command, const char** parameters, int pcnt, userrec *user, bool validated) { /* If the command doesnt appear to be valid, we dont want to mess with it. */ if (!validated) @@ -3673,7 +3597,7 @@ class ModuleSpanningTree : public Module params.push_back(user->host); params.push_back(user->dhost); params.push_back(user->ident); - params.push_back("+"+std::string(user->modes)); + params.push_back("+"+std::string(user->FormatModes())); params.push_back((char*)inet_ntoa(user->ip4)); params.push_back(":"+std::string(user->fullname)); DoOneToMany(Srv->GetServerName(),"NICK",params); @@ -3701,7 +3625,6 @@ class ModuleSpanningTree : public Module if (SourceServer) { SourceServer->DelUserCount(); - SourceServer->DelUser(user); } } @@ -3742,17 +3665,6 @@ class ModuleSpanningTree : public Module params.push_back(dest->nick); params.push_back(":"+reason); DoOneToMany(source->nick,"KILL",params); - /* NOTE: We must remove the user from the servers list here. - * If we do not, there is a chance the user could hang around - * in the list if there is a desync for example (this would - * not be good). - * Part of the 'random crash on netsplit' tidying up. -Brain - */ - TreeServer* n = FindServer(dest->server); - if (n) - { - n->DelUser(dest); - } } virtual void OnRehash(const std::string ¶meter) @@ -3944,6 +3856,13 @@ class ModuleSpanningTree : public Module (*params)[2] = ":" + (*params)[2]; DoOneToMany(Srv->GetServerName(),"METADATA",*params); } + else if (event->GetEventID() == "send_mode") + { + std::deque* params = (std::deque*)event->GetData(); + if (params->size() < 2) + return; + DoOneToMany(Srv->GetServerName(),"FMODE",*params); + } } virtual ~ModuleSpanningTree()