X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules%2Fm_spanningtree%2Ftreesocket2.cpp;h=915158f8df4227ed724afcae237d4f6c348627c1;hb=a3d00f20ae31b4d3b9147e5c9999739aef84f762;hp=341c6c473e86f4f47826cf1d8a4861406ed8e838;hpb=a00ce3bc24ca66ddf00a7a3129ac34a185af2c55;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules/m_spanningtree/treesocket2.cpp b/src/modules/m_spanningtree/treesocket2.cpp index 341c6c473..915158f8d 100644 --- a/src/modules/m_spanningtree/treesocket2.cpp +++ b/src/modules/m_spanningtree/treesocket2.cpp @@ -30,13 +30,11 @@ /* $ModDep: m_spanningtree/timesynctimer.h m_spanningtree/resolvers.h m_spanningtree/main.h m_spanningtree/utils.h m_spanningtree/treeserver.h m_spanningtree/link.h m_spanningtree/treesocket.h */ -static std::map warned; /* Server names that have had protocol violation warnings displayed for them */ - -int TreeSocket::WriteLine(std::string line) +void TreeSocket::WriteLine(std::string line) { Instance->Logs->Log("m_spanningtree",DEBUG, "S[%d] O %s", this->GetFd(), line.c_str()); line.append("\r\n"); - return this->Write(line); + this->Write(line); } @@ -296,6 +294,9 @@ bool TreeSocket::ProcessLine(std::string &line) * First up, check for any malformed commands (e.g. MODE without a timestamp) * and rewrite commands where necessary (SVSMODE -> MODE for services). -- w */ + if (command == "SVSMODE") // This isn't in an "else if" so we still force FMODE for changes on channels. + command = "MODE"; + if (command == "MODE") { if (params.size() >= 2) @@ -303,23 +304,11 @@ bool TreeSocket::ProcessLine(std::string &line) Channel* channel = Instance->FindChan(params[0]); if (channel) { - User* x = Instance->FindNick(prefix); - if (x) - { - if (warned.find(x->server) == warned.end()) - { - Instance->Logs->Log("m_spanningtree",DEFAULT,"WARNING: I revceived modes '%s' from another server '%s'. This is not compliant with InspIRCd. Please check that server for bugs.", params[1].c_str(), x->server); - Instance->SNO->WriteToSnoMask('d', "WARNING: The server %s is sending nonstandard modes: '%s MODE %s' where FMODE should be used, and may cause desyncs.", x->server, x->nick, params[1].c_str()); - warned[x->server] = x->nick; - } - } + this->SendError("MODE may no longer be used on channels. Please use FMODE, with correct timestamp rules."); + return false; } } } - else if (command == "SVSMODE") - { - command = "MODE"; - } /* @@ -347,6 +336,10 @@ bool TreeSocket::ProcessLine(std::string &line) { return this->ForceJoin(prefix,params); } + else if ((command == "NOTICE" || command == "PRIVMSG") && (Utils->IsServer(prefix))) + { + return this->ServerMessage(assign(command), prefix, params, sourceserv); + } else if (command == "STATS") { return this->Stats(prefix, params); @@ -368,6 +361,15 @@ bool TreeSocket::ProcessLine(std::string &line) { return this->Admin(prefix, params); } + else if (command == "MAP") + { + User* user = Instance->FindNick(prefix); + if (user) + { + std::vector p(params.begin(), params.end()); + return Utils->Creator->HandleMap(p, user); + } + } else if (command == "SERVER") { return this->RemoteServer(prefix,params); @@ -388,10 +390,6 @@ bool TreeSocket::ProcessLine(std::string &line) { return this->ForceTopic(prefix,params); } - else if (command == "REHASH") - { - return this->RemoteRehash(prefix,params); - } else if (command == "METADATA") { return this->MetaData(prefix,params); @@ -448,11 +446,12 @@ bool TreeSocket::ProcessLine(std::string &line) { if (params.size() == 3) { + TreeServer* pf = Utils->FindServer(prefix); User* user = this->Instance->FindNick(params[1]); Channel* chan = this->Instance->FindChan(params[0]); - if (user && chan) + if (pf && user && chan) { - if (!chan->ServerKickUser(user, params[2].c_str(), false)) + if (!chan->ServerKickUser(user, params[2].c_str(), false, pf->GetName().c_str())) /* Yikes, the channels gone! */ delete chan; } @@ -476,17 +475,12 @@ bool TreeSocket::ProcessLine(std::string &line) } return true; } - else if (command == "OPERNOTICE") - { - if (params.size() >= 1) - Instance->SNO->WriteToSnoMask('A', "From " + prefix + ": " + params[0]); - return Utils->DoOneToAllButSenderRaw(line, sourceserv, prefix, command, params); - } else if (command == "MODENOTICE") { if (params.size() >= 2) { - Instance->Users->WriteMode(params[0].c_str(), WM_AND, "*** From %s: %s", prefix.c_str(), params[1].c_str()); + if (ServerSource) + Instance->Users->WriteMode(params[0].c_str(), WM_AND, "*** From %s: %s", (ServerSource ? ServerSource->GetName().c_str() : prefix.c_str()), params[1].c_str()); } return Utils->DoOneToAllButSenderRaw(line, sourceserv, prefix, command, params); } @@ -494,7 +488,32 @@ bool TreeSocket::ProcessLine(std::string &line) { if (params.size() >= 2) { - Instance->SNO->WriteToSnoMask(*(params[0].c_str()), "From " + prefix + ": "+ params[1]); + /* + * XXX: + * The SetLocalOnly stuff here is to work around a bit of a nasty recursion bug. + * WriteToSnoMask() sends global snotices out globally, but of course this is a problem + * when triggering it from an already global snotice (yay loops). + * + * The current (horrible) solution I'm implementing here because nobody else seems to + * want to look at this except me, sets the snotice local-only temporarily, sends the snotice + * and then flushes the snomask. + * + * This works, but it is total and utter garbage, as it bypasses the snotice compression + * totally for this snomask (and may well trigger other snotices to send too early.....) + * but at least it won't crash the server. + * + * Master of hacks, we salute you! + * -- w00t + */ + + // If we get a SNONOTICE, it must have been global... so set it local + Instance->SNO->SetLocalOnly(*(params[0].c_str()), true); + // send the message + Instance->SNO->WriteToSnoMask(*(params[0].c_str()), "From " + (ServerSource ? ServerSource->GetName().c_str() : prefix) + ": "+ params[1]); + // flush the queue + Instance->SNO->FlushSnotices(); + // set it global again + Instance->SNO->SetLocalOnly(*(params[0].c_str()), true); } return Utils->DoOneToAllButSenderRaw(line, sourceserv, prefix, command, params); } @@ -503,7 +522,7 @@ bool TreeSocket::ProcessLine(std::string &line) // Set prefix server as bursting if (!ServerSource) { - this->Instance->SNO->WriteToSnoMask('l', "WTF: Got BURST from a nonexistant server(?): %s", prefix.c_str()); + this->Instance->SNO->WriteToSnoMask('l', "WTF: Got BURST from a nonexistant server(?): %s", (ServerSource ? ServerSource->GetName().c_str() : prefix.c_str())); return false; } @@ -514,22 +533,34 @@ bool TreeSocket::ProcessLine(std::string &line) { if (!ServerSource) { - this->Instance->SNO->WriteToSnoMask('l', "WTF: Got ENDBURST from a nonexistant server(?): %s", prefix.c_str()); + this->Instance->SNO->WriteToSnoMask('l', "WTF: Got ENDBURST from a nonexistant server(?): %s", (ServerSource ? ServerSource->GetName().c_str() : prefix.c_str())); return false; } ServerSource->FinishBurst(); return Utils->DoOneToAllButSenderRaw(line, sourceserv, prefix, command, params); } + else if (command == "ENCAP") + { + return this->Encap(prefix, params); + } else if (command == "MODE") { // Server-prefix MODE. - const char* modelist[MAXPARAMETERS]; - for (size_t i = 0; i < params.size(); i++) - modelist[i] = params[i].c_str(); + std::vector modelist(params.begin(), params.end()); + + /* We don't support this for channel mode changes any more! */ + if (params.size() >= 1) + { + if (Instance->FindChan(params[0])) + { + this->SendError("Protocol violation by '"+(ServerSource ? ServerSource->GetName().c_str() : prefix)+"'! MODE for channel mode changes is not supported by the InspIRCd 1.2 protocol. You must use FMODE to preserve channel timestamps."); + return false; + } + } // Insert into the parser - this->Instance->SendMode(modelist, params.size(), this->Instance->FakeClient); + this->Instance->SendMode(modelist, this->Instance->FakeClient); // Pass out to the network return Utils->DoOneToAllButSenderRaw(line,sourceserv,prefix,command,params); @@ -582,27 +613,25 @@ bool TreeSocket::ProcessLine(std::string &line) } // its a user - const char* strparams[127]; - for (unsigned int q = 0; q < params.size(); q++) - { - strparams[q] = params[q].c_str(); - } + std::vector strparams(params.begin(), params.end()); - switch (this->Instance->CallCommandHandler(command.c_str(), strparams, params.size(), who)) + switch (this->Instance->CallCommandHandler(command.c_str(), strparams, who)) { case CMD_INVALID: - // command is irc::string, hence ugliness + /* + * XXX: command is irc::string, hence ugliness + */ this->SendError("Unrecognised or malformed command '" + std::string(command.c_str()) + "' -- possibly loaded mismatched modules"); return false; break; - /* - * CMD_LOCALONLY is aliased to CMD_FAILURE, so this won't go out onto the network. - */ case CMD_FAILURE: + /* + * CMD_LOCALONLY is aliased to CMD_FAILURE, so this won't go out onto the network. + */ return true; break; default: - /* CMD_SUCCESS and CMD_USER_DELETED fall through here */ + /* CMD_SUCCESS falls through here */ break; } @@ -667,18 +696,19 @@ void TreeSocket::OnClose() int TreeSocket::OnIncomingConnection(int newsock, char* ip) { - /* To prevent anyone from attempting to flood opers/DDoS by connecting to the server port, - * or discovering if this port is the server port, we don't allow connections from any - * IPs for which we don't have a link block. - */ bool found = false; found = (std::find(Utils->ValidIPs.begin(), Utils->ValidIPs.end(), ip) != Utils->ValidIPs.end()); if (!found) { for (std::vector::iterator i = Utils->ValidIPs.begin(); i != Utils->ValidIPs.end(); i++) - if (irc::sockets::MatchCIDR(ip, (*i).c_str())) + { + if ((*i) == "*" || irc::sockets::MatchCIDR(ip, (*i).c_str())) + { found = true; + break; + } + } if (!found) {