X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules%2Fm_spanningtree.cpp;h=7d034c17ce263f7986cb93d57f17af56223949c7;hb=1c600e3912db8d2ab0fd72fb3869083fcc6c9e46;hp=155ad70993095e6df845a6b4059f24036471ec6c;hpb=68c8383ce3df85cd119c29c5a9dfcdf7f16341f8;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules/m_spanningtree.cpp b/src/modules/m_spanningtree.cpp index 155ad7099..7d034c17c 100644 --- a/src/modules/m_spanningtree.cpp +++ b/src/modules/m_spanningtree.cpp @@ -100,6 +100,7 @@ class Link : public classbase std::string EncryptionKey; bool HiddenFromStats; std::string FailOver; + int Timeout; }; /** Contains helper functions and variables for this module, @@ -1057,6 +1058,9 @@ class TreeSocket : public InspSocket { if ((Current) && (Current != Utils->TreeRoot)) { + Event rmode((char*)Current->GetName().c_str(), (Module*)Utils->Creator, "lost_server"); + rmode.Send(Instance); + std::deque params; params.push_back(Current->GetName()); params.push_back(":"+reason); @@ -1610,7 +1614,7 @@ class TreeSocket : public InspSocket /* Lower the TS here */ if (Utils->AnnounceTSChange && chan) chan->WriteChannelWithServ(Instance->Config->ServerName, - "TS for %s changed from %lu to %lu", chan->name, ourTS, TS); + "NOTICE %s :TS for %s changed from %lu to %lu", chan->name, chan->name, ourTS, TS); ourTS = TS; param_list.push_back(channel); @@ -1875,6 +1879,8 @@ class TreeSocket : public InspSocket */ void SendFJoins(TreeServer* Current, chanrec* c) { + std::string buffer; + Instance->Log(DEBUG,"Sending FJOINs to other server for %s",c->name); char list[MAXBUF]; std::string individual_halfops = std::string(":")+this->Instance->Config->ServerName+" FMODE "+c->name+" "+ConvToStr(c->age); @@ -1900,7 +1906,8 @@ class TreeSocket : public InspSocket if (curlen > (480-NICKMAX)) { - this->WriteLine(list); + buffer.append(list).append("\r\n"); + dlen = curlen = snprintf(list,MAXBUF,":%s FJOIN %s %lu",this->Instance->Config->ServerName,c->name,(unsigned long)c->age); ptr = list + dlen; ptrlen = 0; @@ -1909,64 +1916,83 @@ class TreeSocket : public InspSocket } if (numusers) - this->WriteLine(list); + buffer.append(list).append("\r\n"); - for (BanList::iterator b = c->bans.begin(); b != c->bans.end(); b++) - { + for (BanList::iterator b = c->bans.begin(); b != c->bans.end(); b++) + { modes.append("b"); - params.append(b->data).append(" "); - } - this->WriteLine(std::string(":")+this->Instance->Config->ServerName+" FMODE "+c->name+" "+ConvToStr(c->age)+" +"+c->ChanModes(true)+modes+" "+params); + params.append(" ").append(b->data); + + if (params.length() >= MAXMODES) + { + /* Wrap at MAXMODES */ + buffer.append(":").append(this->Instance->Config->ServerName).append(" FMODE ").append(c->name).append(" ").append(ConvToStr(c->age)).append(" +").append(modes).append(params).append("\r\n"); + modes = ""; + params = ""; + } + } + + buffer.append(":").append(this->Instance->Config->ServerName).append(" FMODE ").append(c->name).append(" ").append(ConvToStr(c->age)).append(" +").append(c->ChanModes(true)); + + /* Only send these if there are any */ + if (!modes.empty()) + buffer.append("\r\n").append(":").append(this->Instance->Config->ServerName).append(" FMODE ").append(c->name).append(" ").append(ConvToStr(c->age)).append(" +").append(modes).append(params); + + this->WriteLine(buffer); } /** Send G, Q, Z and E lines */ void SendXLines(TreeServer* Current) { char data[MAXBUF]; + std::string buffer; std::string n = this->Instance->Config->ServerName; const char* sn = n.c_str(); int iterations = 0; /* Yes, these arent too nice looking, but they get the job done */ for (std::vector::iterator i = Instance->XLines->zlines.begin(); i != Instance->XLines->zlines.end(); i++, iterations++) { - snprintf(data,MAXBUF,":%s ADDLINE Z %s %s %lu %lu :%s",sn,(*i)->ipaddr,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason); - this->WriteLine(data); + snprintf(data,MAXBUF,":%s ADDLINE Z %s %s %lu %lu :%s\r\n",sn,(*i)->ipaddr,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason); + buffer.append(data); } for (std::vector::iterator i = Instance->XLines->qlines.begin(); i != Instance->XLines->qlines.end(); i++, iterations++) { - snprintf(data,MAXBUF,":%s ADDLINE Q %s %s %lu %lu :%s",sn,(*i)->nick,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason); - this->WriteLine(data); + snprintf(data,MAXBUF,":%s ADDLINE Q %s %s %lu %lu :%s\r\n",sn,(*i)->nick,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason); + buffer.append(data); } for (std::vector::iterator i = Instance->XLines->glines.begin(); i != Instance->XLines->glines.end(); i++, iterations++) { - snprintf(data,MAXBUF,":%s ADDLINE G %s %s %lu %lu :%s",sn,(*i)->hostmask,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason); - this->WriteLine(data); + snprintf(data,MAXBUF,":%s ADDLINE G %s %s %lu %lu :%s\r\n",sn,(*i)->hostmask,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason); + buffer.append(data); } for (std::vector::iterator i = Instance->XLines->elines.begin(); i != Instance->XLines->elines.end(); i++, iterations++) { - snprintf(data,MAXBUF,":%s ADDLINE E %s %s %lu %lu :%s",sn,(*i)->hostmask,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason); - this->WriteLine(data); + snprintf(data,MAXBUF,":%s ADDLINE E %s %s %lu %lu :%s\r\n",sn,(*i)->hostmask,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason); + buffer.append(data); } for (std::vector::iterator i = Instance->XLines->pzlines.begin(); i != Instance->XLines->pzlines.end(); i++, iterations++) { - snprintf(data,MAXBUF,":%s ADDLINE Z %s %s %lu %lu :%s",sn,(*i)->ipaddr,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason); - this->WriteLine(data); + snprintf(data,MAXBUF,":%s ADDLINE Z %s %s %lu %lu :%s\r\n",sn,(*i)->ipaddr,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason); + buffer.append(data); } for (std::vector::iterator i = Instance->XLines->pqlines.begin(); i != Instance->XLines->pqlines.end(); i++, iterations++) { - snprintf(data,MAXBUF,":%s ADDLINE Q %s %s %lu %lu :%s",sn,(*i)->nick,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason); - this->WriteLine(data); + snprintf(data,MAXBUF,":%s ADDLINE Q %s %s %lu %lu :%s\r\n",sn,(*i)->nick,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason); + buffer.append(data); } for (std::vector::iterator i = Instance->XLines->pglines.begin(); i != Instance->XLines->pglines.end(); i++, iterations++) { - snprintf(data,MAXBUF,":%s ADDLINE G %s %s %lu %lu :%s",sn,(*i)->hostmask,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason); - this->WriteLine(data); + snprintf(data,MAXBUF,":%s ADDLINE G %s %s %lu %lu :%s\r\n",sn,(*i)->hostmask,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason); + buffer.append(data); } for (std::vector::iterator i = Instance->XLines->pelines.begin(); i != Instance->XLines->pelines.end(); i++, iterations++) { - snprintf(data,MAXBUF,":%s ADDLINE E %s %s %lu %lu :%s",sn,(*i)->hostmask,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason); - this->WriteLine(data); + snprintf(data,MAXBUF,":%s ADDLINE E %s %s %lu %lu :%s\r\n",sn,(*i)->hostmask,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason); + buffer.append(data); } + + if (!buffer.empty()) + this->WriteLine(buffer); } /** Send channel modes and topics */ @@ -2000,6 +2026,7 @@ class TreeSocket : public InspSocket { char data[MAXBUF]; std::deque list; + std::string dataline; int iterations = 0; for (user_hash::iterator u = this->Instance->clientlist.begin(); u != this->Instance->clientlist.end(); u++, iterations++) { @@ -2009,11 +2036,13 @@ class TreeSocket : public InspSocket this->WriteLine(data); if (*u->second->oper) { - this->WriteLine(":"+std::string(u->second->nick)+" OPERTYPE "+std::string(u->second->oper)); + snprintf(data,MAXBUF,":%s OPERTYPE %s", u->second->nick, u->second->oper); + this->WriteLine(data); } if (*u->second->awaymsg) { - this->WriteLine(":"+std::string(u->second->nick)+" AWAY :"+std::string(u->second->awaymsg)); + snprintf(data,MAXBUF,":%s AWAY :%s", u->second->nick, u->second->awaymsg); + this->WriteLine(data); } FOREACH_MOD_I(this->Instance,I_OnSyncUser,OnSyncUser(u->second,(Module*)Utils->Creator,(void*)this)); list.clear(); @@ -3319,6 +3348,10 @@ class TreeSocket : public InspSocket sourceserv = this->InboundServerName; } this->Instance->SNO->WriteToSnoMask('l',"Received end of netburst from \2%s\2",sourceserv.c_str()); + + Event rmode((char*)sourceserv.c_str(), (Module*)Utils->Creator, "new_server"); + rmode.Send(Instance); + return true; } else @@ -3439,7 +3472,9 @@ class TreeSocket : public InspSocket { Squit(s,"Remote host closed the connection"); } - this->Instance->SNO->WriteToSnoMask('l',"Connection to '\2%s\2' failed.",quitserver.c_str()); + + if (quitserver != "") + this->Instance->SNO->WriteToSnoMask('l',"Connection to '\2%s\2' failed.",quitserver.c_str()); } virtual int OnIncomingConnection(int newsock, char* ip) @@ -3500,7 +3535,7 @@ class ServernameResolver : public Resolver TreeServer* CheckDupe = Utils->FindServer(MyLink.Name.c_str()); if (!CheckDupe) /* Check that nobody tried to connect it successfully while we were resolving */ { - TreeSocket* newsocket = new TreeSocket(this->Utils, ServerInstance, result,MyLink.Port,false,10,MyLink.Name.c_str()); + TreeSocket* newsocket = new TreeSocket(this->Utils, ServerInstance, result,MyLink.Port,false,MyLink.Timeout ? MyLink.Timeout : 10,MyLink.Name.c_str()); if (newsocket->GetFd() > -1) { /* We're all OK */ @@ -3814,6 +3849,7 @@ void SpanningTreeUtilities::ReadConfiguration(bool rebind) L.AutoConnect = Conf->ReadInteger("link","autoconnect",j,true); L.EncryptionKey = Conf->ReadValue("link","encryptionkey",j); L.HiddenFromStats = Conf->ReadFlag("link","hidden",j); + L.Timeout = Conf->ReadInteger("link","timeout",j,true); L.NextConnectTime = time(NULL) + L.AutoConnect; /* Bugfix by brain, do not allow people to enter bad configurations */ if (L.Name != ServerInstance->Config->ServerName) @@ -4270,7 +4306,7 @@ class ModuleSpanningTree : public Module /* Do we already have an IP? If so, no need to resolve it. */ if (insp_aton(x->IPAddr.c_str(), &binip) > 0) { - TreeSocket* newsocket = new TreeSocket(Utils, ServerInstance, x->IPAddr,x->Port,false,10,x->Name.c_str()); + TreeSocket* newsocket = new TreeSocket(Utils, ServerInstance, x->IPAddr,x->Port,false,x->Timeout ? x->Timeout : 10,x->Name.c_str()); if (newsocket->GetFd() > -1) { /* Handled automatically on success */ @@ -4992,6 +5028,19 @@ class ModuleSpanningTree : public Module params->insert(params->begin() + 1,ConvToStr(ourTS)); Utils->DoOneToMany(ServerInstance->Config->ServerName,"FMODE",*params); } + else if (event->GetEventID() == "send_push") + { + if (params->size() < 2) + return; + + userrec *a = ServerInstance->FindNick((*params)[0]); + + if (!a) + return; + + (*params)[1] = ":" + (*params)[1]; + Utils->DoOneToOne(ServerInstance->Config->ServerName, "PUSH", *params, a->server); + } } virtual ~ModuleSpanningTree()