ModResult ModuleSpanningTree::HandleSquit(const std::vector<std::string>& parameters, User* user) { TreeServer* s = Utils->FindServerMask(parameters[0]); if (s) { if (s == Utils->TreeRoot) { user->WriteNotice("*** SQUIT: Foolish mortal, you cannot make a server SQUIT itself! (" + parameters[0] + " matches local server name)"); return MOD_RES_DENY; } TreeSocket* sock = s->GetSocket(); if (sock) { ServerInstance->SNO->WriteToSnoMask('l',"SQUIT: Server \002%s\002 removed from network by %s",parameters[0].c_str(),user->nick.c_str()); sock->Squit(s,"Server quit by " + user->GetFullRealHost()); ServerInstance->SE->DelFd(sock); sock->Close(); } else { user->WriteNotice("*** SQUIT may not be used to remove remote servers. Please use RSQUIT instead."); } } else { user->WriteNotice("*** SQUIT: The server \002" + parameters[0] + "\002 does not exist on the network."); } return MOD_RES_DENY; }
int ModuleSpanningTree::HandleSquit(const char** parameters, int pcnt, userrec* user) { TreeServer* s = Utils->FindServerMask(parameters[0]); if (s) { if (s == Utils->TreeRoot) { user->WriteServ("NOTICE %s :*** SQUIT: Foolish mortal, you cannot make a server SQUIT itself! (%s matches local server name)",user->nick,parameters[0]); return 1; } TreeSocket* sock = s->GetSocket(); if (sock) { ServerInstance->SNO->WriteToSnoMask('l',"SQUIT: Server \002%s\002 removed from network by %s",parameters[0],user->nick); sock->Squit(s,std::string("Server quit by ") + user->GetFullRealHost()); ServerInstance->SE->DelFd(sock); sock->Close(); } else { if (IS_LOCAL(user)) user->WriteServ("NOTICE %s :*** WARNING: Using SQUIT to split remote servers is deprecated. Please use RSQUIT instead.",user->nick); } } else { user->WriteServ("NOTICE %s :*** SQUIT: The server \002%s\002 does not exist on the network.",user->nick,parameters[0]); } return 1; }
CmdResult CommandSQuit::HandleServer(TreeServer* server, std::vector<std::string>& params) { TreeServer* quitting = Utils->FindServer(params[0]); if (!quitting) { ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Squit from unknown server"); return CMD_FAILURE; } TreeSocket* sock = server->GetSocket(); sock->Squit(quitting, params[1]); return CMD_SUCCESS; }
CmdResult CommandSQuit::HandleServer(TreeServer* server, std::vector<std::string>& params) { TreeServer* quitting = Utils->FindServer(params[0]); if (!quitting) { ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Squit from unknown server"); return CMD_FAILURE; } TreeSocket* sock = server->GetSocket(); sock->Squit(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 // remaining servers. return ((quitting == server) ? CMD_FAILURE : CMD_SUCCESS); }
void ModuleSpanningTree::DoPingChecks(time_t curtime) { for (unsigned int j = 0; j < Utils->TreeRoot->ChildCount(); j++) { TreeServer* serv = Utils->TreeRoot->GetChild(j); TreeSocket* sock = serv->GetSocket(); if (sock) { if (curtime >= serv->NextPingTime()) { if (serv->AnsweredLastPing()) { sock->WriteLine(std::string(":")+ServerInstance->Config->ServerName+" PING "+serv->GetName()); serv->SetNextPingTime(curtime + 60); serv->LastPing = curtime; serv->Warned = false; } else { /* they didnt answer, boot them */ sock->SendError("Ping timeout"); sock->Squit(serv,"Ping timeout"); ServerInstance->SE->DelFd(sock); sock->Close(); return; } } else if ((Utils->PingWarnTime) && (!serv->Warned) && (curtime >= serv->NextPingTime() - (60 - Utils->PingWarnTime)) && (!serv->AnsweredLastPing())) { /* The server hasnt responded, send a warning to opers */ ServerInstance->SNO->WriteToSnoMask('l',"Server \002%s\002 has not responded to PING for %d seconds, high latency.", serv->GetName().c_str(), Utils->PingWarnTime); serv->Warned = true; } } } /* Cancel remote burst mode on any servers which still have it enabled due to latency/lack of data. * This prevents lost REMOTECONNECT notices */ for (server_hash::iterator i = Utils->serverlist.begin(); i != Utils->serverlist.end(); i++) Utils->SetRemoteBursting(i->second, false); }
void ModuleSpanningTree::DoPingChecks(time_t curtime) { /* * Cancel remote burst mode on any servers which still have it enabled due to latency/lack of data. * This prevents lost REMOTECONNECT notices */ timeval t; gettimeofday(&t, NULL); long ts = (t.tv_sec * 1000) + (t.tv_usec / 1000); for (server_hash::iterator i = Utils->serverlist.begin(); i != Utils->serverlist.end(); i++) { TreeServer *s = i->second; // Fix for bug #792, do not ping servers that are not connected yet! // Remote servers have Socket == NULL and local connected servers have // Socket->LinkState == CONNECTED if (s->GetSocket() && s->GetSocket()->GetLinkState() != CONNECTED) continue; // Now do PING checks on all servers TreeServer *mts = Utils->BestRouteTo(s->GetID()); if (mts) { // Only ping if this server needs one if (curtime >= s->NextPingTime()) { // And if they answered the last if (s->AnsweredLastPing()) { // They did, send a ping to them s->SetNextPingTime(curtime + Utils->PingFreq); TreeSocket *tsock = mts->GetSocket(); // ... if we can find a proper route to them if (tsock) { tsock->WriteLine(std::string(":") + ServerInstance->Config->GetSID() + " PING " + ServerInstance->Config->GetSID() + " " + s->GetID()); s->LastPingMsec = ts; } } else { // They didn't answer the last ping, if they are locally connected, get rid of them. TreeSocket *sock = s->GetSocket(); if (sock) { sock->SendError("Ping timeout"); sock->Squit(s,"Ping timeout"); ServerInstance->SE->DelFd(sock); sock->Close(); return; } } } // If warn on ping enabled and not warned and the difference is sufficient and they didn't answer the last ping... if ((Utils->PingWarnTime) && (!s->Warned) && (curtime >= s->NextPingTime() - (Utils->PingFreq - Utils->PingWarnTime)) && (!s->AnsweredLastPing())) { /* The server hasnt responded, send a warning to opers */ ServerInstance->SNO->WriteToSnoMask('l',"Server \002%s\002 has not responded to PING for %d seconds, high latency.", s->GetName().c_str(), Utils->PingWarnTime); s->Warned = true; } } } }