]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
Don't apply channel modes received in an non-burst, non-creation FJOIN, because they...
authordanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>
Mon, 2 Mar 2009 22:08:56 +0000 (22:08 +0000)
committerdanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>
Mon, 2 Mar 2009 22:08:56 +0000 (22:08 +0000)
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11162 e03df62e-2008-0410-955e-edbf42e46eb7

src/modules/m_spanningtree/fjoin.cpp

index 55c72c474e50571abe43f5e0e0ed0e03b500a087..e7ce0ac54a14f4a8aac81a57f083638de0cbc423 100644 (file)
@@ -58,7 +58,8 @@ bool TreeSocket::ForceJoin(const std::string &source, std::deque<std::string> &p
        std::string channel = params[0];                                /* Channel name, as a string */
        time_t TS = atoi(params[1].c_str());                            /* Timestamp given to us for remote side */
        irc::tokenstream users((params.size() > 3) ? params[params.size() - 1] : "");   /* users from the user list */
-       bool apply_other_sides_modes = true;                            /* True if we are accepting the other side's modes */
+       bool apply_other_sides_umodes = true;                           /* True if we are accepting the other side's user umodes */
+       bool apply_other_sides_cmodes = true;                           /* True if we are accepting the other side's channel modes */
        Channel* chan = this->ServerInstance->FindChan(channel);                /* The channel we're sending joins to */
        bool created = !chan;                                           /* True if the channel doesnt exist here yet */
        std::string item;                                               /* One item in the list of nicks */
@@ -90,7 +91,8 @@ bool TreeSocket::ForceJoin(const std::string &source, std::deque<std::string> &p
                if (ourTS < TS)
                {
                        ServerInstance->SNO->WriteToSnoMask('d', "NOT Applying modes from other side");
-                       apply_other_sides_modes = false;
+                       apply_other_sides_umodes = false;
+                       apply_other_sides_cmodes = false;
                }
                else if (ourTS > TS)
                {
@@ -104,11 +106,23 @@ bool TreeSocket::ForceJoin(const std::string &source, std::deque<std::string> &p
                        param_list.push_back(channel);
                        this->RemoveStatus(ServerInstance->Config->GetSID(), param_list);
                }
-               // The silent case here is ourTS == TS, we don't need to remove modes here, just to merge them later on.
+               else
+               {
+                       /* Timestamp equal. Apply the user modes always */
+                       apply_other_sides_umodes = true;
+                       /*
+                        * If the server is bursting, then the channel modes need to be applied;
+                        * it is expected that servers will resync modes at this time. Otherwise,
+                        * the mode string sent along with the FJOIN could be out-of-date, and
+                        * applying the mode change could cause modes to be unexpectedly bounced.
+                        */
+                       TreeServer *s = Utils->FindServer(source);
+                       apply_other_sides_cmodes = s->bursting;
+               }
        }
 
        /* First up, apply their modes if they won the TS war */
-       if (apply_other_sides_modes)
+       if (apply_other_sides_cmodes)
        {
                ServerInstance->SNO->WriteToSnoMask('d', "Applying remote modestring for %s", params[0].c_str());
                unsigned int idx = 2;
@@ -179,7 +193,7 @@ bool TreeSocket::ForceJoin(const std::string &source, std::deque<std::string> &p
        }
 
        /* Flush mode stacker if we lost the FJOIN or had equal TS */
-       if (apply_other_sides_modes)
+       if (apply_other_sides_umodes)
        {
                std::deque<std::string> stackresult;
                std::vector<std::string> mode_junk;