]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_spanningtree/main.cpp
m_spanningtree Fix TreeRoot UserCount being possibly wrong if loaded after startup
[user/henk/code/inspircd.git] / src / modules / m_spanningtree / main.cpp
index 34a6437de71ad8711baac934510793bb9602fbcc..967b577b15d03f466df3f3df81f7d29857d8f7ae 100644 (file)
@@ -38,6 +38,7 @@
 #include "protocolinterface.h"
 
 ModuleSpanningTree::ModuleSpanningTree()
+       : KeepNickTS(false)
 {
        Utils = new SpanningTreeUtilities(this);
        commands = new SpanningTreeCommands(this);
@@ -83,11 +84,11 @@ void ModuleSpanningTree::init()
        ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
 
        delete ServerInstance->PI;
-       ServerInstance->PI = new SpanningTreeProtocolInterface(this, Utils);
+       ServerInstance->PI = new SpanningTreeProtocolInterface(Utils);
        loopCall = false;
 
        // update our local user count
-       Utils->TreeRoot->SetUserCount(ServerInstance->Users->local_users.size());
+       Utils->TreeRoot->SetUserCount(ServerInstance->Users->LocalUserCount());
 }
 
 void ModuleSpanningTree::ShowLinks(TreeServer* Current, User* user, int hops)
@@ -145,9 +146,9 @@ std::string ModuleSpanningTree::TimeToStr(time_t secs)
        secs = secs % 60;
        mins_up = mins_up % 60;
        hours_up = hours_up % 24;
-       return ((days_up ? (ConvToStr(days_up) + "d") : std::string(""))
-                       + (hours_up ? (ConvToStr(hours_up) + "h") : std::string(""))
-                       + (mins_up ? (ConvToStr(mins_up) + "m") : std::string(""))
+       return ((days_up ? (ConvToStr(days_up) + "d") : "")
+                       + (hours_up ? (ConvToStr(hours_up) + "h") : "")
+                       + (mins_up ? (ConvToStr(mins_up) + "m") : "")
                        + ConvToStr(secs) + "s");
 }
 
@@ -194,7 +195,7 @@ restart:
                                        // ... if we can find a proper route to them
                                        if (tsock)
                                        {
-                                               tsock->WriteLine(std::string(":") + ServerInstance->Config->GetSID() + " PING " +
+                                               tsock->WriteLine(":" + ServerInstance->Config->GetSID() + " PING " +
                                                                ServerInstance->Config->GetSID() + " " + s->GetID());
                                                s->LastPingMsec = ts;
                                        }
@@ -265,14 +266,13 @@ void ModuleSpanningTree::ConnectServer(Link* x, Autoconnect* y)
 {
        bool ipvalid = true;
 
-       if (InspIRCd::Match(ServerInstance->Config->ServerName, assign(x->Name)))
+       if (InspIRCd::Match(ServerInstance->Config->ServerName, assign(x->Name), rfc_case_insensitive_map))
        {
                ServerInstance->SNO->WriteToSnoMask('l', "CONNECT: Not connecting to myself.");
                return;
        }
 
-       QueryType start_type = DNS_QUERY_A;
-       start_type = DNS_QUERY_AAAA;
+       QueryType start_type = DNS_QUERY_AAAA;
        if (strchr(x->IPAddr.c_str(),':'))
        {
                in6_addr n;
@@ -306,7 +306,7 @@ void ModuleSpanningTree::ConnectServer(Link* x, Autoconnect* y)
        {
                try
                {
-                       bool cached;
+                       bool cached = false;
                        ServernameResolver* snr = new ServernameResolver(Utils, x->IPAddr, x, cached, start_type, y);
                        ServerInstance->AddResolver(snr, cached);
                }
@@ -396,9 +396,9 @@ ModResult ModuleSpanningTree::HandleConnect(const std::vector<std::string>& para
        for (std::vector<reference<Link> >::iterator i = Utils->LinkBlocks.begin(); i < Utils->LinkBlocks.end(); i++)
        {
                Link* x = *i;
-               if (InspIRCd::Match(x->Name.c_str(),parameters[0]))
+               if (InspIRCd::Match(x->Name.c_str(),parameters[0], rfc_case_insensitive_map))
                {
-                       if (InspIRCd::Match(ServerInstance->Config->ServerName, assign(x->Name)))
+                       if (InspIRCd::Match(ServerInstance->Config->ServerName, assign(x->Name), rfc_case_insensitive_map))
                        {
                                RemoteMessage(user, "*** CONNECT: Server \002%s\002 is ME, not connecting.",x->Name.c_str());
                                return MOD_RES_DENY;
@@ -592,7 +592,7 @@ void ModuleSpanningTree::OnUserConnect(LocalUser* user)
        params.push_back(user->GetIPString());
        params.push_back(ConvToStr(user->signon));
        params.push_back("+"+std::string(user->FormatModes(true)));
-       params.push_back(":"+std::string(user->fullname));
+       params.push_back(":"+user->fullname);
        Utils->DoOneToMany(ServerInstance->Config->GetSID(), "UID", params);
 
        if (IS_OPER(user))
@@ -625,7 +625,7 @@ void ModuleSpanningTree::OnUserJoin(Membership* memb, bool sync, bool created, C
                params.push_back(memb->chan->name);
                params.push_back(ConvToStr(memb->chan->age));
                params.push_back(std::string("+") + memb->chan->ChanModes(true));
-               params.push_back(memb->modes+","+std::string(memb->user->uuid));
+               params.push_back(memb->modes+","+memb->user->uuid);
                Utils->DoOneToMany(ServerInstance->Config->GetSID(),"FJOIN",params);
        }
 }
@@ -646,14 +646,13 @@ void ModuleSpanningTree::OnChangeName(User* user, const std::string &gecos)
                return;
 
        parameterlist params;
-       params.push_back(gecos);
+       params.push_back(":" + gecos);
        Utils->DoOneToMany(user->uuid,"FNAME",params);
 }
 
 void ModuleSpanningTree::OnChangeIdent(User* user, const std::string &ident)
 {
-       // only occurs for local clients
-       if (user->registered != REG_ALL)
+       if ((user->registered != REG_ALL) || (!IS_LOCAL(user)))
                return;
 
        parameterlist params;
@@ -706,11 +705,12 @@ void ModuleSpanningTree::OnUserPostNick(User* user, const std::string &oldnick)
 
                /** IMPORTANT: We don't update the TS if the oldnick is just a case change of the newnick!
                 */
-               if (irc::string(user->nick.c_str()) != assign(oldnick))
+               if ((irc::string(user->nick.c_str()) != assign(oldnick)) && (!this->KeepNickTS))
                        user->age = ServerInstance->Time();
 
                params.push_back(ConvToStr(user->age));
                Utils->DoOneToMany(user->uuid,"NICK",params);
+               this->KeepNickTS = false;
        }
        else if (!loopCall && user->nick == user->uuid)
        {
@@ -754,6 +754,9 @@ void ModuleSpanningTree::OnRemoteKill(User* source, User* dest, const std::strin
 
 void ModuleSpanningTree::OnPreRehash(User* user, const std::string &parameter)
 {
+       if (loopCall)
+               return; // Don't generate a REHASH here if we're in the middle of processing a message that generated this one
+
        ServerInstance->Logs->Log("remoterehash", DEBUG, "called with param %s", parameter.c_str());
 
        // Send out to other servers
@@ -780,7 +783,7 @@ void ModuleSpanningTree::OnRehash(User* user)
                std::string msg = "Error in configuration: ";
                msg.append(e.GetReason());
                ServerInstance->SNO->WriteToSnoMask('l', msg);
-               if (!IS_LOCAL(user))
+               if (user && !IS_LOCAL(user))
                        ServerInstance->PI->SendSNONotice("L", msg);
        }
 }
@@ -803,6 +806,7 @@ void ModuleSpanningTree::OnUnloadModule(Module* mod)
 {
        ServerInstance->PI->SendMetaData(NULL, "modules", "-" + mod->ModuleSourceFile);
 
+restart:
        unsigned int items = Utils->TreeRoot->ChildCount();
        for(unsigned int x = 0; x < items; x++)
        {
@@ -812,8 +816,17 @@ void ModuleSpanningTree::OnUnloadModule(Module* mod)
                {
                        sock->SendError("SSL module unloaded");
                        sock->Close();
+                       // XXX: The list we're iterating is modified by TreeSocket::Squit() which is called by Close()
+                       goto restart;
                }
        }
+
+       for (SpanningTreeUtilities::TimeoutList::const_iterator i = Utils->timeoutlist.begin(); i != Utils->timeoutlist.end(); ++i)
+       {
+               TreeSocket* sock = i->first;
+               if (sock->GetIOHook() == mod)
+                       sock->Close();
+       }
 }
 
 // note: the protocol does not allow direct umode +o except
@@ -833,11 +846,13 @@ void ModuleSpanningTree::OnAddLine(User* user, XLine *x)
        if (!x->IsBurstable() || loopCall)
                return;
 
-       char data[MAXBUF];
-       snprintf(data,MAXBUF,"%s %s %s %lu %lu :%s", x->type.c_str(), x->Displayable(),
-       ServerInstance->Config->ServerName.c_str(), (unsigned long)x->set_time, (unsigned long)x->duration, x->reason.c_str());
        parameterlist params;
-       params.push_back(data);
+       params.push_back(x->type);
+       params.push_back(x->Displayable());
+       params.push_back(ServerInstance->Config->ServerName);
+       params.push_back(ConvToStr(x->set_time));
+       params.push_back(ConvToStr(x->duration));
+       params.push_back(":" + x->reason);
 
        if (!user)
        {
@@ -856,10 +871,9 @@ void ModuleSpanningTree::OnDelLine(User* user, XLine *x)
        if (!x->IsBurstable() || loopCall)
                return;
 
-       char data[MAXBUF];
-       snprintf(data,MAXBUF,"%s %s", x->type.c_str(), x->Displayable());
        parameterlist params;
-       params.push_back(data);
+       params.push_back(x->type);
+       params.push_back(x->Displayable());
 
        if (!user)
        {
@@ -907,7 +921,7 @@ ModResult ModuleSpanningTree::OnSetAway(User* user, const std::string &awaymsg)
                parameterlist params;
                if (!awaymsg.empty())
                {
-                       params.push_back(ConvToStr(user->awaytime));
+                       params.push_back(ConvToStr(ServerInstance->Time()));
                        params.push_back(":" + awaymsg);
                }
                Utils->DoOneToMany(user->uuid, "AWAY", params);
@@ -916,6 +930,12 @@ ModResult ModuleSpanningTree::OnSetAway(User* user, const std::string &awaymsg)
        return MOD_RES_PASSTHRU;
 }
 
+void ModuleSpanningTree::OnRequest(Request& request)
+{
+       if (!strcmp(request.id, "rehash"))
+               Utils->Rehash();
+}
+
 void ModuleSpanningTree::ProtoSendMode(void* opaque, TargetTypeFlags target_type, void* target, const parameterlist &modeline, const std::vector<TranslateType> &translate)
 {
        TreeSocket* s = (TreeSocket*)opaque;
@@ -928,12 +948,12 @@ void ModuleSpanningTree::ProtoSendMode(void* opaque, TargetTypeFlags target_type
                if (target_type == TYPE_USER)
                {
                        User* u = (User*)target;
-                       s->WriteLine(std::string(":")+ServerInstance->Config->GetSID()+" MODE "+u->uuid+" "+output_text);
+                       s->WriteLine(":"+ServerInstance->Config->GetSID()+" MODE "+u->uuid+" "+output_text);
                }
                else if (target_type == TYPE_CHANNEL)
                {
                        Channel* c = (Channel*)target;
-                       s->WriteLine(std::string(":")+ServerInstance->Config->GetSID()+" FMODE "+c->name+" "+ConvToStr(c->age)+" "+output_text);
+                       s->WriteLine(":"+ServerInstance->Config->GetSID()+" FMODE "+c->name+" "+ConvToStr(c->age)+" "+output_text);
                }
        }
 }
@@ -944,11 +964,11 @@ void ModuleSpanningTree::ProtoSendMetaData(void* opaque, Extensible* target, con
        User* u = dynamic_cast<User*>(target);
        Channel* c = dynamic_cast<Channel*>(target);
        if (u)
-               s->WriteLine(std::string(":")+ServerInstance->Config->GetSID()+" METADATA "+u->uuid+" "+extname+" :"+extdata);
+               s->WriteLine(":"+ServerInstance->Config->GetSID()+" METADATA "+u->uuid+" "+extname+" :"+extdata);
        else if (c)
-               s->WriteLine(std::string(":")+ServerInstance->Config->GetSID()+" METADATA "+c->name+" "+extname+" :"+extdata);
+               s->WriteLine(":"+ServerInstance->Config->GetSID()+" METADATA "+c->name+" "+extname+" :"+extdata);
        else if (!target)
-               s->WriteLine(std::string(":")+ServerInstance->Config->GetSID()+" METADATA * "+extname+" :"+extdata);
+               s->WriteLine(":"+ServerInstance->Config->GetSID()+" METADATA * "+extname+" :"+extdata);
 }
 
 CullResult ModuleSpanningTree::cull()