summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/modules/m_spanningtree/fjoin.cpp14
1 files changed, 12 insertions, 2 deletions
diff --git a/src/modules/m_spanningtree/fjoin.cpp b/src/modules/m_spanningtree/fjoin.cpp
index 40ba5e893..42be7e781 100644
--- a/src/modules/m_spanningtree/fjoin.cpp
+++ b/src/modules/m_spanningtree/fjoin.cpp
@@ -70,6 +70,9 @@ CmdResult CommandFJoin::Handle(User* srcuser, std::vector<std::string>& params)
* losing side, so only its own modes get applied. Life is simple for those
* who succeed at internets. :-)
*
+ * Outside of netbursts, the winning side also resyncs the losing side if it
+ * detects that the other side recreated the channel.
+ *
* Syntax:
* :<sid> FJOIN <chan> <TS> <modes> :[<member> [<member> ...]]
* The last parameter is a list consisting of zero or more channel members
@@ -119,6 +122,7 @@ CmdResult CommandFJoin::Handle(User* srcuser, std::vector<std::string>& params)
const std::string& channel = params[0];
Channel* chan = ServerInstance->FindChan(channel);
bool apply_other_sides_modes = true;
+ TreeServer* const sourceserver = TreeServer::Get(srcuser);
if (!chan)
{
@@ -134,6 +138,14 @@ CmdResult CommandFJoin::Handle(User* srcuser, std::vector<std::string>& params)
/* If our TS is less than theirs, we dont accept their modes */
if (ourTS < TS)
{
+ // If the source server isn't bursting then this FJOIN is the result of them recreating the channel with a higher TS.
+ // This happens if the last user on the channel hops and before the PART propagates a user on another server joins. Fix it by doing a resync.
+ // Servers behind us won't react this way because the forwarded FJOIN will have the correct TS.
+ if (!sourceserver->IsBursting())
+ {
+ ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Server %s recreated channel %s with higher TS, resyncing", sourceserver->GetName().c_str(), chan->name.c_str());
+ sourceserver->GetSocket()->SyncChannel(chan);
+ }
apply_other_sides_modes = false;
}
else if (ourTS > TS)
@@ -162,8 +174,6 @@ CmdResult CommandFJoin::Handle(User* srcuser, std::vector<std::string>& params)
modechangelist.clear();
}
- TreeServer* const sourceserver = TreeServer::Get(srcuser);
-
// Build a new FJOIN for forwarding. Put the correct TS in it and the current modes of the channel
// after applying theirs. If they lost, the prefix modes from their message are not forwarded.
FwdFJoinBuilder fwdfjoin(chan, sourceserver);