]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_spanningtree/treesocket1.cpp
Merge insp20
[user/henk/code/inspircd.git] / src / modules / m_spanningtree / treesocket1.cpp
index 5deef8394b8c8091d8078dfb83cf23686c86b95f..025bd1e611fd633a304e271dfc7d977bf6ee85d5 100644 (file)
@@ -69,11 +69,6 @@ TreeSocket::TreeSocket(int newfd, ListenSocket* via, irc::sockets::sockaddrs* cl
        Utils->timeoutlist[this] = std::pair<std::string, int>(linkID, 30);
 }
 
-ServerState TreeSocket::GetLinkState()
-{
-       return this->LinkState;
-}
-
 void TreeSocket::CleanNegotiationInfo()
 {
        // connect is good, reset the autoconnect block (if used)
@@ -128,6 +123,7 @@ void TreeSocket::OnError(BufferedSocketError e)
        ServerInstance->SNO->WriteGlobalSno('l', "Connection to '\002%s\002' failed with error: %s",
                linkID.c_str(), getError().c_str());
        LinkState = DYING;
+       Close();
 }
 
 void TreeSocket::SendError(const std::string &errormessage)
@@ -138,82 +134,6 @@ void TreeSocket::SendError(const std::string &errormessage)
        SetError(errormessage);
 }
 
-/** This function forces this server to quit, removing this server
- * and any users on it (and servers and users below that, etc etc).
- * It's very slow and pretty clunky, but luckily unless your network
- * is having a REAL bad hair day, this function shouldnt be called
- * too many times a month ;-)
- */
-void TreeSocket::SquitServer(std::string &from, TreeServer* Current, int& num_lost_servers, int& num_lost_users)
-{
-       ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "SquitServer for %s from %s", Current->GetName().c_str(), from.c_str());
-       /* recursively squit the servers attached to 'Current'.
-        * We're going backwards so we don't remove users
-        * while we still need them ;)
-        */
-       const TreeServer::ChildServers& children = Current->GetChildren();
-       for (TreeServer::ChildServers::const_iterator i = children.begin(); i != children.end(); ++i)
-       {
-               TreeServer* recursive_server = *i;
-               this->SquitServer(from,recursive_server, num_lost_servers, num_lost_users);
-       }
-       /* Now we've whacked the kids, whack self */
-       num_lost_servers++;
-       num_lost_users += Current->QuitUsers(from);
-}
-
-/** This is a wrapper function for SquitServer above, which
- * does some validation first and passes on the SQUIT to all
- * other remaining servers.
- */
-void TreeSocket::Squit(TreeServer* Current, const std::string &reason)
-{
-       bool LocalSquit = false;
-
-       if (!Current->IsRoot())
-       {
-               DelServerEvent(Utils->Creator, Current->GetName());
-
-               if (Current->IsLocal())
-               {
-                       ServerInstance->SNO->WriteGlobalSno('l', "Server \002"+Current->GetName()+"\002 split: "+reason);
-                       LocalSquit = true;
-                       if (Current->GetSocket()->Introduced())
-                       {
-                               CmdBuilder params("SQUIT");
-                               params.push_back(Current->GetID());
-                               params.push_last(reason);
-                               params.Broadcast();
-                       }
-               }
-               else
-               {
-                       ServerInstance->SNO->WriteToSnoMask('L', "Server \002"+Current->GetName()+"\002 split from server \002"+Current->GetParent()->GetName()+"\002 with reason: "+reason);
-               }
-               int num_lost_servers = 0;
-               int num_lost_users = 0;
-               std::string from = Current->GetParent()->GetName()+" "+Current->GetName();
-
-               ModuleSpanningTree* st = Utils->Creator;
-               st->SplitInProgress = true;
-               SquitServer(from, Current, num_lost_servers, num_lost_users);
-               st->SplitInProgress = false;
-
-               ServerInstance->SNO->WriteToSnoMask(LocalSquit ? 'l' : 'L', "Netsplit complete, lost \002%d\002 user%s on \002%d\002 server%s.",
-                       num_lost_users, num_lost_users != 1 ? "s" : "", num_lost_servers, num_lost_servers != 1 ? "s" : "");
-               Current->Tidy();
-               Current->GetParent()->DelChild(Current);
-               Current->cull();
-               const bool ismyroot = (Current == MyRoot);
-               delete Current;
-               if (ismyroot)
-               {
-                       MyRoot = NULL;
-                       Close();
-               }
-       }
-}
-
 CmdResult CommandSQuit::HandleServer(TreeServer* server, std::vector<std::string>& params)
 {
        TreeServer* quitting = Utils->FindServer(params[0]);
@@ -223,15 +143,22 @@ CmdResult CommandSQuit::HandleServer(TreeServer* server, std::vector<std::string
                return CMD_FAILURE;
        }
 
-       TreeSocket* sock = server->GetSocket();
-       sock->Squit(quitting, params[1]);
+       CmdResult ret = CMD_SUCCESS;
+       if (quitting == server)
+       {
+               ret = CMD_FAILURE;
+               server = server->GetParent();
+       }
+       else if (quitting->GetParent() != server)
+               throw ProtocolException("Attempted to SQUIT a non-directly connected server or the parent");
+
+       server->SQuitChild(quitting, params[1]);
 
        // XXX: Return CMD_FAILURE when servers SQUIT themselves (i.e. :00S SQUIT 00S :Shutting down)
-       // to avoid RouteCommand() being called. RouteCommand() requires a valid command source but we
-       // do not have one because the server user is deleted when its TreeServer is destructed.
-       // We generate a SQUIT in TreeSocket::Squit(), with our sid as the source and send it to the
+       // to stop this message from being forwarded.
+       // The squit logic generates a SQUIT message with our sid as the source and sends it to the
        // remaining servers.
-       return ((quitting == server) ? CMD_FAILURE : CMD_SUCCESS);
+       return ret;
 }
 
 /** This function is called when we receive data from a remote
@@ -245,7 +172,7 @@ void TreeSocket::OnDataReady()
        {
                std::string::size_type rline = line.find('\r');
                if (rline != std::string::npos)
-                       line = line.substr(0,rline);
+                       line.erase(rline);
                if (line.find('\0') != std::string::npos)
                {
                        SendError("Read null character from socket");
@@ -270,8 +197,3 @@ void TreeSocket::OnDataReady()
                SendError("RecvQ overrun (line too long)");
        Utils->Creator->loopCall = false;
 }
-
-bool TreeSocket::Introduced()
-{
-       return (capab == NULL);
-}