From 4820e6bb9578e53ea1553070108599349d0ffbcb Mon Sep 17 00:00:00 2001 From: danieldg Date: Mon, 2 Mar 2009 22:08:56 +0000 Subject: Don't apply channel modes received in an non-burst, non-creation FJOIN, because they could be out of date git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11162 e03df62e-2008-0410-955e-edbf42e46eb7 --- src/modules/m_spanningtree/fjoin.cpp | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/modules/m_spanningtree/fjoin.cpp b/src/modules/m_spanningtree/fjoin.cpp index 55c72c474..e7ce0ac54 100644 --- a/src/modules/m_spanningtree/fjoin.cpp +++ b/src/modules/m_spanningtree/fjoin.cpp @@ -58,7 +58,8 @@ bool TreeSocket::ForceJoin(const std::string &source, std::deque &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 &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 &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 &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 stackresult; std::vector mode_junk; -- cgit v1.2.3