]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_spanningtree/treesocket1.cpp
Allow support for multiple dns results per request. This is a significant change...
[user/henk/code/inspircd.git] / src / modules / m_spanningtree / treesocket1.cpp
index d1dad0914cbada1d51c63ec8ed2474e974cb18ba..c939f2349b90469731032106011090a35fd78b07 100644 (file)
@@ -46,7 +46,8 @@ TreeSocket::TreeSocket(SpanningTreeUtilities* Util, InspIRCd* SI, std::string ho
 {
        myhost = host;
        this->LinkState = LISTENER;
-       theirchallenge = ourchallenge = "";
+       theirchallenge.clear();
+       ourchallenge.clear();
        if (listening && Hook)
                InspSocketHookRequest(this, (Module*)Utils->Creator, Hook).Send();
 }
@@ -55,7 +56,8 @@ TreeSocket::TreeSocket(SpanningTreeUtilities* Util, InspIRCd* SI, std::string ho
        : InspSocket(SI, host, port, listening, maxtime, bindto), Utils(Util), Hook(HookMod)
 {
        myhost = ServerName;
-       theirchallenge = ourchallenge = "";
+       theirchallenge.clear();
+       ourchallenge.clear();
        this->LinkState = CONNECTING;
        if (Hook)
                InspSocketHookRequest(this, (Module*)Utils->Creator, Hook).Send();
@@ -69,7 +71,9 @@ TreeSocket::TreeSocket(SpanningTreeUtilities* Util, InspIRCd* SI, int newfd, cha
        : InspSocket(SI, newfd, ip), Utils(Util), Hook(HookMod)
 {
        this->LinkState = WAIT_AUTH_1;
-       theirchallenge = ourchallenge = "";
+       theirchallenge.clear();
+       ourchallenge.clear();
+       sentcapab = false;
        /* If we have a transport module hooked to the parent, hook the same module to this
         * socket, and set a timer waiting for handshake before we send CAPAB etc.
         */
@@ -183,6 +187,7 @@ bool TreeSocket::OnConnected()
                                        this->Instance->SNO->WriteToSnoMask('l',"Connection to \2"+myhost+"\2["+(x->HiddenFromStats ? "<hidden>" : this->GetIP())+"] using transport \2"+x->Hook+"\2");
                                }
                                this->OutboundPass = x->SendPass;
+                               sentcapab = false;
 
                                /* found who we're supposed to be connecting to, send the neccessary gubbins. */
                                if (this->GetHook())
@@ -207,6 +212,9 @@ void TreeSocket::OnError(InspSocketError e)
 {
        Link* MyLink;
 
+       if (this->LinkState == LISTENER)
+               return;
+
        switch (e)
        {
                case I_ERR_CONNECT:
@@ -274,7 +282,7 @@ void TreeSocket::SendServers(TreeServer* Current, TreeServer* s, int hops)
 std::string TreeSocket::MyCapabilities()
 {
        std::vector<std::string> modlist;
-       std::string capabilities = "";
+       std::string capabilities;
        for (int i = 0; i <= this->Instance->GetModuleCount(); i++)
        {
                if (this->Instance->modules[i]->GetVersion().Flags & VF_COMMON)
@@ -325,6 +333,10 @@ std::string TreeSocket::RandString(unsigned int length)
 
 void TreeSocket::SendCapabilities()
 {
+       if (sentcapab)
+               return;
+
+       sentcapab = true;
        irc::commasepstream modulelist(MyCapabilities());
        this->WriteLine("CAPAB START");
 
@@ -386,7 +398,7 @@ std::string TreeSocket::ListDifference(const std::string &one, const std::string
 {
        irc::commasepstream list_one(one);
        std::string item = "*";
-       std::string result = "";
+       std::string result;
        while ((item = list_one.GetToken()) != "")
        {
                if (!HasItem(two, item))
@@ -402,7 +414,7 @@ void TreeSocket::SendError(const std::string &errormessage)
 {
        /* Display the error locally as well as sending it remotely */
        this->WriteLine("ERROR :"+errormessage);
-       this->Instance->SNO->WriteToSnoMask('l',"Sent \2ERROR\2 to "+this->InboundServerName+": "+errormessage);
+       this->Instance->SNO->WriteToSnoMask('l',"Sent \2ERROR\2 to "+ (this->InboundServerName.empty() ? "<unknown>" : this->InboundServerName) +": "+errormessage);
        /* One last attempt to make sure the error reaches its target */
        this->FlushWriteBuffer();
 }
@@ -416,12 +428,12 @@ bool TreeSocket::Capab(const std::deque<std::string> &params)
        }
        if (params[0] == "START")
        {
-               this->ModuleList = "";
+               this->ModuleList.clear();
                this->CapKeys.clear();
        }
        else if (params[0] == "END")
        {
-               std::string reason = "";
+               std::string reason;
                int ip6support = 0;
 #ifdef SUPPORT_IP6LINKS
                ip6support = 1;
@@ -471,6 +483,9 @@ bool TreeSocket::Capab(const std::deque<std::string> &params)
                                reason = "Protocol version not specified";
                }
 
+               if(this->CapKeys.find("PREFIX") != this->CapKeys.end() && this->CapKeys.find("PREFIX")->second != this->Instance->Modes->BuildPrefixes())
+                       reason = "One or more of the prefixes on the remote server are invalid on this server.";
+
                if (((this->CapKeys.find("HALFOP") == this->CapKeys.end()) && (Instance->Config->AllowHalfop)) || ((this->CapKeys.find("HALFOP") != this->CapKeys.end()) && (this->CapKeys.find("HALFOP")->second != ConvToStr(Instance->Config->AllowHalfop))))
                        reason = "We don't both have halfop support enabled/disabled identically";
 
@@ -664,6 +679,13 @@ bool TreeSocket::ForceMode(const std::string &source, std::deque<std::string> &p
                        return true;
        }
 
+       if (!TS)
+       {
+               Instance->Log(DEFAULT,"*** BUG? *** TS of 0 sent to FMODE. Are some services authors smoking craq, or is it 1970 again?. Dropped.");
+               Instance->SNO->WriteToSnoMask('d', "WARNING: The server %s is sending FMODE with a TS of zero. Total craq. Mode was dropped.", sourceserv.c_str());
+               return true;
+       }
+
        /* TS is equal or less: Merge the mode changes into ours and pass on.
         */
        if (TS <= ourTS)
@@ -787,6 +809,13 @@ bool TreeSocket::ForceJoin(const std::string &source, std::deque<std::string> &p
        params[2] = ":" + params[2];
        Utils->DoOneToAllButSender(source,"FJOIN",params,source);
 
+        if (!TS)
+       {
+               Instance->Log(DEFAULT,"*** BUG? *** TS of 0 sent to FJOIN. Are some services authors smoking craq, or is it 1970 again?. Dropped.");
+               Instance->SNO->WriteToSnoMask('d', "WARNING: The server %s is sending FJOIN with a TS of zero. Total craq. Command was dropped.", source.c_str());
+               return true;
+       }
+
        /* If our TS is less than theirs, we dont accept their modes */
        if (ourTS < TS)
                apply_other_sides_modes = false;
@@ -858,7 +887,7 @@ bool TreeSocket::ForceJoin(const std::string &source, std::deque<std::string> &p
        if (apply_other_sides_modes)
        {
                std::deque<std::string> stackresult;
-               const char* mode_junk[MAXMODES+1];
+               const char* mode_junk[MAXMODES+2];
                userrec* n = new userrec(Instance);
                n->SetFd(FD_MAGIC_NUMBER);
                mode_junk[0] = channel.c_str();
@@ -892,6 +921,7 @@ bool TreeSocket::IntroduceClient(const std::string &source, std::deque<std::stri
 
        time_t age = ConvToInt(params[0]);
        const char* tempnick = params[1].c_str();
+       std::string empty;
 
        cmd_validation valid[] = { {"Nickname", 1, NICKMAX}, {"Hostname", 2, 64}, {"Displayed hostname", 3, 64}, {"Ident", 4, IDENTMAX}, {"GECOS", 7, MAXGECOS}, {"", 0, 0} };
 
@@ -949,11 +979,14 @@ bool TreeSocket::IntroduceClient(const std::string &source, std::deque<std::stri
 
        for (std::string::iterator v = params[5].begin(); v != params[5].end(); v++)
        {
-               _new->modes[(*v)-65] = 1;
                /* For each mode thats set, increase counter */
                ModeHandler* mh = Instance->Modes->FindMode(*v, MODETYPE_USER);
                if (mh)
+               {
+                       mh->OnModeChange(_new, _new, NULL, empty, true);
+                       _new->SetMode(*v, true);
                        mh->ChangeCount(1);
+               }
        }
 
        /* now we've done with modes processing, put the + back for remote servers */
@@ -998,16 +1031,14 @@ void TreeSocket::SendFJoins(TreeServer* Current, chanrec* c)
        char list[MAXBUF];
        std::string individual_halfops = std::string(":")+this->Instance->Config->ServerName+" FMODE "+c->name+" "+ConvToStr(c->age);
 
-       Instance->Log(DEBUG,"Sending FJOINs for %s", c->name);
-
        size_t dlen, curlen;
        dlen = curlen = snprintf(list,MAXBUF,":%s FJOIN %s %lu",this->Instance->Config->ServerName,c->name,(unsigned long)c->age);
        int numusers = 0;
        char* ptr = list + dlen;
 
        CUList *ulist = c->GetUsers();
-       std::string modes = "";
-       std::string params = "";
+       std::string modes;
+       std::string params;
 
        for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++)
        {
@@ -1021,7 +1052,6 @@ void TreeSocket::SendFJoins(TreeServer* Current, chanrec* c)
 
                if (curlen > (480-NICKMAX))
                {
-                       Instance->Log(DEBUG,"Flushing FJOIN buffer: %s", list);
                        buffer.append(list).append("\r\n");
                        dlen = curlen = snprintf(list,MAXBUF,":%s FJOIN %s %lu",this->Instance->Config->ServerName,c->name,(unsigned long)c->age);
                        ptr = list + dlen;
@@ -1030,13 +1060,8 @@ void TreeSocket::SendFJoins(TreeServer* Current, chanrec* c)
                }
        }
 
-       Instance->Log(DEBUG,"%d users remaining to be flushed", list);
-
        if (numusers)
-       {
-               Instance->Log(DEBUG,"Flushing final FJOIN buffer: %s", list);
                buffer.append(list).append("\r\n");
-       }
 
        buffer.append(":").append(this->Instance->Config->ServerName).append(" FMODE ").append(c->name).append(" ").append(ConvToStr(c->age)).append(" +").append(c->ChanModes(true)).append("\r\n");
 
@@ -1055,8 +1080,8 @@ void TreeSocket::SendFJoins(TreeServer* Current, chanrec* c)
                {
                        /* Wrap at MAXMODES */
                        buffer.append(":").append(this->Instance->Config->ServerName).append(" FMODE ").append(c->name).append(" ").append(ConvToStr(c->age)).append(" +").append(modes).append(params).append("\r\n");
-                       modes = "";
-                       params = "";
+                       modes.clear();
+                       params.clear();
                        linesize = 1;
                }
        }