diff options
Diffstat (limited to 'src/modules/m_spanningtree/nickcollide.cpp')
-rw-r--r-- | src/modules/m_spanningtree/nickcollide.cpp | 49 |
1 files changed, 30 insertions, 19 deletions
diff --git a/src/modules/m_spanningtree/nickcollide.cpp b/src/modules/m_spanningtree/nickcollide.cpp index 6c4a837a5..9656f9af3 100644 --- a/src/modules/m_spanningtree/nickcollide.cpp +++ b/src/modules/m_spanningtree/nickcollide.cpp @@ -30,8 +30,8 @@ int TreeSocket::DoCollision(User *u, time_t remotets, const std::string &remoteident, const std::string &remoteip, const std::string &remoteuid) { /* - * Under old protocol rules, we would have had to kill both clients. - * Really, this sucks. + * Under old protocol rules, we would have had to kill both clients. + * Really, this sucks. * These days, we have UID. And, so what we do is, force nick change client(s) * involved according to timestamp rules. * @@ -84,9 +84,30 @@ int TreeSocket::DoCollision(User *u, time_t remotets, const std::string &remotei } } + /* + * Cheat a little here. Instead of a dedicated command to change UID, + * use SVSNICK and accept the losing client with its UID (as we know the SVSNICK will + * not fail under any circumstances -- UIDs are netwide exclusive). + * + * This means that each side of a collide will generate one extra NICK back to where + * they have just linked (and where it got the SVSNICK from), however, it will + * be dropped harmlessly as it will come in as :928AAAB NICK 928AAAB, and we already + * have 928AAAB's nick set to that. + * -- w00t + */ if (bChangeLocal) { + /* + * Local-side nick needs to change. Just in case we are hub, and + * this "local" nick is actually behind us, send an SVSNICK out. + */ + std::deque<std::string> params; + params.push_back(u->uuid); + params.push_back(u->uuid); + params.push_back(ConvToStr(u->age)); + Utils->DoOneToMany(ServerInstance->Config->GetSID(),"SVSNICK",params); + u->ForceNickChange(u->uuid.c_str()); if (!bChangeRemote) @@ -94,28 +115,18 @@ int TreeSocket::DoCollision(User *u, time_t remotets, const std::string &remotei } if (bChangeRemote) { + User *remote = this->ServerInstance->FindUUID(remoteuid); /* - * Cheat a little here. Instead of a dedicated command to change UID, - * use SVSNICK and accept their client with it's UID (as we know the SVSNICK will - * not fail under any circumstances -- UIDs are netwide exclusive). - * - * This means that each side of a collide will generate one extra NICK back to where - * they have just linked (and where it got the SVSNICK from), however, it will - * be dropped harmlessly as it will come in as :928AAAB NICK 928AAAB, and we already - * have 928AAAB's nick set to that. - * -- w00t + * remote side needs to change. If this happens, we will modify + * the UID or halt the propagation of the nick change command, + * so other servers don't need to see the SVSNICK */ - User *remote = this->ServerInstance->FindUUID(remoteuid); + WriteLine(std::string(":")+ServerInstance->Config->GetSID()+" SVSNICK "+remoteuid+" " + remoteuid + " " + ConvToStr(remotets)); if (remote) { - /* buh.. nick change collide. force change their nick. */ - remote->ForceNickChange(remote->uuid.c_str()); - } - else - { - /* user has not been introduced yet, just inform their server */ - this->WriteLine(std::string(":")+this->ServerInstance->Config->GetSID()+" SVSNICK "+remoteuid+" " + remoteuid + " " + ConvToStr(remotets)); + /* nick change collide. Force change their nick. */ + remote->ForceNickChange(remoteuid.c_str()); } if (!bChangeLocal) |