X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fmodules%2Fm_spanningtree.cpp;h=20c81bd95af8d3086f682bc479394b82d2e3d638;hb=69c3a32784b8c638ea10c269c3f63ede86b8aaa0;hp=63733f29ae7d100ae9a356618f563e1e8998af26;hpb=e8f2288bfeab7a76e83d0ebcbedce7357b4cb18f;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules/m_spanningtree.cpp b/src/modules/m_spanningtree.cpp index 63733f29a..20c81bd95 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, @@ -124,6 +125,9 @@ class SpanningTreeUtilities /** Announce TS changes to channels on merge */ bool AnnounceTSChange; + /** Synchronize timestamps between servers + */ + bool EnableTimeSync; /** Socket bindings for listening sockets */ std::vector Bindings; @@ -1057,6 +1061,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); @@ -1588,7 +1595,7 @@ class TreeSocket : public InspSocket /* default TS is a high value, which if we dont have this * channel will let the other side apply their modes. */ - time_t ourTS = time(NULL)+600; + time_t ourTS = Instance->Time(true)+600; /* Does this channel exist? if it does, get its REAL timestamp */ if (chan) @@ -1610,7 +1617,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); @@ -1902,7 +1909,7 @@ class TreeSocket : public InspSocket if (curlen > (480-NICKMAX)) { - buffer.append(list).append("\n"); + 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; @@ -1912,7 +1919,7 @@ class TreeSocket : public InspSocket } if (numusers) - buffer.append(list).append("\n"); + buffer.append(list).append("\r\n"); for (BanList::iterator b = c->bans.begin(); b != c->bans.end(); b++) { @@ -1922,17 +1929,17 @@ class TreeSocket : public InspSocket 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("\n"); + 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(ConvToStr(c->age)).append(" +").append(c->ChanModes(true)); + 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("\n").append(":").append(this->Instance->Config->ServerName).append(" FMODE ").append(c->name).append(ConvToStr(c->age)).append(" +").append(modes).append(params); + 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); } @@ -1948,42 +1955,42 @@ class TreeSocket : public InspSocket /* 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\n",sn,(*i)->ipaddr,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason); + 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\n",sn,(*i)->nick,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason); + 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\n",sn,(*i)->hostmask,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason); + snprintf(data,MAXBUF,":%s ADDLINE G %s@%s %s %lu %lu :%s\r\n",sn,(*i)->identmask,(*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\n",sn,(*i)->hostmask,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason); + snprintf(data,MAXBUF,":%s ADDLINE E %s@%s %s %lu %lu :%s\r\n",sn,(*i)->identmask,(*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\n",sn,(*i)->ipaddr,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason); + 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\n",sn,(*i)->nick,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason); + 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\n",sn,(*i)->hostmask,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason); + snprintf(data,MAXBUF,":%s ADDLINE G %s@%s %s %lu %lu :%s\r\n",sn,(*i)->identmask,(*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\n",sn,(*i)->hostmask,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason); + snprintf(data,MAXBUF,":%s ADDLINE E %s@%s %s %lu %lu :%s\r\n",sn,(*i)->identmask,(*i)->hostmask,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason); buffer.append(data); } @@ -2058,7 +2065,7 @@ class TreeSocket : public InspSocket */ void DoBurst(TreeServer* s) { - std::string burst = "BURST "+ConvToStr(time(NULL)); + std::string burst = "BURST "+ConvToStr(Instance->Time(true)); std::string endburst = "ENDBURST"; // Because by the end of the netburst, it could be gone! std::string name = s->GetName(); @@ -2627,7 +2634,7 @@ class TreeSocket : public InspSocket char idle[MAXBUF]; snprintf(signon,MAXBUF,"%lu",(unsigned long)x->signon); - snprintf(idle,MAXBUF,"%lu",(unsigned long)abs((x->idle_lastmsg)-time(NULL))); + snprintf(idle,MAXBUF,"%lu",(unsigned long)abs((x->idle_lastmsg)-Instance->Time(true))); std::deque par; par.push_back(prefix); par.push_back(signon); @@ -2687,6 +2694,45 @@ class TreeSocket : public InspSocket return true; } + bool HandleSetTime(const std::string &prefix, std::deque ¶ms) + { + if (!params.size() || !Utils->EnableTimeSync) + return true; + + bool force = false; + + if ((params.size() == 2) && (params[1] == "FORCE")) + force = true; + + time_t rts = atoi(params[0].c_str()); + time_t us = Instance->Time(true); + + if (rts == us) + { + Instance->Log(DEBUG, "Timestamp from %s is equal", prefix.c_str()); + + Utils->DoOneToAllButSender(prefix, "TIMESET", params, prefix); + } + else if (force || (rts < us)) + { + int old = Instance->SetTimeDelta(rts - us); + Instance->Log(DEBUG, "%s TS (diff %d) from %s applied (old delta was %d)", (force) ? "Forced" : "Lower", rts - us, prefix.c_str(), old); + + Utils->DoOneToAllButSender(prefix, "TIMESET", params, prefix); + } + else + { + Instance->Log(DEBUG, "Higher TS (diff %d) from %s overridden", us - rts, prefix.c_str()); + + std::deque oparams; + oparams.push_back(ConvToStr(us)); + + Utils->DoOneToMany(prefix, "TIMESET", oparams); + } + + return true; + } + bool Time(const std::string &prefix, std::deque ¶ms) { // :source.server TIME remote.server sendernick @@ -2699,9 +2745,7 @@ class TreeSocket : public InspSocket userrec* u = this->Instance->FindNick(params[1]); if (u) { - char curtime[256]; - snprintf(curtime,256,"%lu",(unsigned long)time(NULL)); - params.push_back(curtime); + params.push_back(ConvToStr(Instance->Time(false))); params[0] = prefix; Utils->DoOneToOne(this->Instance->Config->ServerName,"TIME",params,params[0]); } @@ -3072,20 +3116,40 @@ class TreeSocket : public InspSocket } else if (command == "BURST") { - if (params.size()) + if (params.size() && Utils->EnableTimeSync) { - /* If a time stamp is provided, try and check syncronization */ - time_t THEM = atoi(params[0].c_str()); - long delta = THEM-time(NULL); + /* If a time stamp is provided, apply synchronization */ + bool force = false; + time_t them = atoi(params[0].c_str()); + time_t us = Instance->Time(true); + int delta = them - us; + + if ((params.size() == 2) && (params[1] == "FORCE")) + force = true; + if ((delta < -600) || (delta > 600)) { this->Instance->SNO->WriteToSnoMask('l',"\2ERROR\2: Your clocks are out by %d seconds (this is more than ten minutes). Link aborted, \2PLEASE SYNC YOUR CLOCKS!\2",abs(delta)); this->WriteLine("ERROR :Your clocks are out by "+ConvToStr(abs(delta))+" seconds (this is more than ten minutes). Link aborted, PLEASE SYNC YOUR CLOCKS!"); return false; } - else if ((delta < -60) || (delta > 60)) + + if (us == them) + { + this->Instance->Log(DEBUG, "Timestamps are equal; pat yourself on the back"); + } + else if (force || (us > them)) + { + this->Instance->Log(DEBUG, "Remote server has lower TS (%d seconds)", them - us); + this->Instance->SetTimeDelta(them - us); + // Send this new timestamp to any other servers + Utils->DoOneToMany(Utils->TreeRoot->GetName(), "TIMESET", params); + } + else { - this->Instance->SNO->WriteToSnoMask('l',"\2WARNING\2: Your clocks are out by %d seconds, please consider synching your clocks.",abs(delta)); + // Override the timestamp + this->Instance->Log(DEBUG, "We have a higher timestamp (by %d seconds), not updating delta", us - them); + this->WriteLine(":" + Utils->TreeRoot->GetName() + " TIMESET " + ConvToStr(us)); } } this->LinkState = CONNECTED; @@ -3294,6 +3358,10 @@ class TreeSocket : public InspSocket { return this->Push(prefix,params); } + else if (command == "TIMESET") + { + return this->HandleSetTime(prefix, params); + } else if (command == "TIME") { return this->Time(prefix,params); @@ -3344,6 +3412,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 @@ -3464,7 +3536,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) @@ -3511,7 +3585,7 @@ class ServernameResolver : public Resolver Link MyLink; SpanningTreeUtilities* Utils; public: - ServernameResolver(SpanningTreeUtilities* Util, InspIRCd* Instance, const std::string &hostname, Link x) : Resolver(Instance, hostname, DNS_QUERY_FORWARD), MyLink(x), Utils(Util) + ServernameResolver(Module* me, SpanningTreeUtilities* Util, InspIRCd* Instance, const std::string &hostname, Link x) : Resolver(Instance, hostname, DNS_QUERY_FORWARD, me), MyLink(x), Utils(Util) { /* Nothing in here, folks */ } @@ -3525,7 +3599,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 */ @@ -3556,7 +3630,7 @@ class SecurityIPResolver : public Resolver Link MyLink; SpanningTreeUtilities* Utils; public: - SecurityIPResolver(SpanningTreeUtilities* U, InspIRCd* Instance, const std::string &hostname, Link x) : Resolver(Instance, hostname, DNS_QUERY_FORWARD), MyLink(x), Utils(U) + SecurityIPResolver(Module* me, SpanningTreeUtilities* U, InspIRCd* Instance, const std::string &hostname, Link x) : Resolver(Instance, hostname, DNS_QUERY_FORWARD, me), MyLink(x), Utils(U) { } @@ -3797,33 +3871,38 @@ void SpanningTreeUtilities::ReadConfiguration(bool rebind) { std::string Type = Conf->ReadValue("bind","type",j); std::string IP = Conf->ReadValue("bind","address",j); - int Port = Conf->ReadInteger("bind","port",j,true); + std::string Port = Conf->ReadValue("bind","port",j); if (Type == "servers") { - ServerInstance->Log(DEBUG,"m_spanningtree: Binding server port %s:%d", IP.c_str(), Port); - if (IP == "*") + irc::portparser portrange(Port); + int portno = -1; + while ((portno = portrange.GetToken())) { - IP = ""; - } - TreeSocket* listener = new TreeSocket(this, ServerInstance, IP.c_str(),Port,true,10); - if (listener->GetState() == I_LISTENING) - { - ServerInstance->Log(DEFAULT,"m_spanningtree: Binding server port %s:%d successful!", IP.c_str(), Port); - Bindings.push_back(listener); - } - else - { - ServerInstance->Log(DEFAULT,"m_spanningtree: Warning: Failed to bind server port %d",Port); - listener->Close(); - DELETE(listener); + ServerInstance->Log(DEBUG,"m_spanningtree: Binding server port %s:%d", IP.c_str(), portno); + if (IP == "*") + IP = ""; + + TreeSocket* listener = new TreeSocket(this, ServerInstance, IP.c_str(), portno, true, 10); + if (listener->GetState() == I_LISTENING) + { + ServerInstance->Log(DEFAULT,"m_spanningtree: Binding server port %s:%d successful!", IP.c_str(), portno); + Bindings.push_back(listener); + } + else + { + ServerInstance->Log(DEFAULT,"m_spanningtree: Warning: Failed to bind server port %s:%d",IP.c_str(), portno); + listener->Close(); + DELETE(listener); + } + ServerInstance->Log(DEBUG,"Done with this binding"); } - ServerInstance->Log(DEBUG,"Done with this binding"); } } } FlatLinks = Conf->ReadFlag("options","flatlinks",0); HideULines = Conf->ReadFlag("options","hideulines",0); AnnounceTSChange = Conf->ReadFlag("options","announcets",0); + EnableTimeSync = !(Conf->ReadFlag("options","notimesync",0)); LinkBlocks.clear(); ValidIPs.clear(); for (int j =0; j < Conf->Enumerate("link"); j++) @@ -3839,6 +3918,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) @@ -3856,7 +3936,7 @@ void SpanningTreeUtilities::ReadConfiguration(bool rebind) { try { - SecurityIPResolver* sr = new SecurityIPResolver(this, ServerInstance, L.IPAddr, L); + SecurityIPResolver* sr = new SecurityIPResolver((Module*)this->Creator, this, ServerInstance, L.IPAddr, L); ServerInstance->AddResolver(sr); } catch (ModuleException& e) @@ -3900,7 +3980,19 @@ void SpanningTreeUtilities::ReadConfiguration(bool rebind) DELETE(Conf); } - +/** To create a timer which recurs every second, we inherit from InspTimer. + * InspTimer is only one-shot however, so at the end of each Tick() we simply + * insert another of ourselves into the pending queue :) + */ +class TimeSyncTimer : public InspTimer +{ + private: + InspIRCd *Instance; + ModuleSpanningTree *Module; + public: + TimeSyncTimer(InspIRCd *Instance, ModuleSpanningTree *Mod); + virtual void Tick(time_t TIME); +}; class ModuleSpanningTree : public Module { @@ -3912,6 +4004,7 @@ class ModuleSpanningTree : public Module SpanningTreeUtilities* Utils; public: + TimeSyncTimer *SyncTimer; ModuleSpanningTree(InspIRCd* Me) : Module::Module(Me), max_local(0), max_global(0) @@ -3920,6 +4013,14 @@ class ModuleSpanningTree : public Module command_rconnect = new cmd_rconnect(ServerInstance, this, Utils); ServerInstance->AddCommand(command_rconnect); + + if (Utils->EnableTimeSync) + { + SyncTimer = new TimeSyncTimer(ServerInstance, this); + ServerInstance->Timers->AddTimer(SyncTimer); + } + else + SyncTimer = NULL; } void ShowLinks(TreeServer* Current, userrec* user, int hops) @@ -4295,7 +4396,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 */ @@ -4311,7 +4412,7 @@ class ModuleSpanningTree : public Module { try { - ServernameResolver* snr = new ServernameResolver(Utils, ServerInstance,x->IPAddr, *x); + ServernameResolver* snr = new ServernameResolver((Module*)this, Utils, ServerInstance,x->IPAddr, *x); ServerInstance->AddResolver(snr); } catch (ModuleException& e) @@ -4414,6 +4515,13 @@ class ModuleSpanningTree : public Module return 1; } + void BroadcastTimeSync() + { + std::deque params; + params.push_back(ConvToStr(ServerInstance->Time(true))); + Utils->DoOneToMany(Utils->TreeRoot->GetName(), "TIMESET", params); + } + virtual int OnStats(char statschar, userrec* user, string_list &results) { if (statschar == 'c') @@ -4828,26 +4936,38 @@ class ModuleSpanningTree : public Module void OnLine(userrec* source, const std::string &host, bool adding, char linetype, long duration, const std::string &reason) { - if (IS_LOCAL(source)) + if (!source) { - char type[8]; - snprintf(type,8,"%cLINE",linetype); - std::string stype = type; - if (adding) - { - char sduration[MAXBUF]; - snprintf(sduration,MAXBUF,"%ld",duration); - std::deque params; - params.push_back(host); - params.push_back(sduration); - params.push_back(":"+reason); - Utils->DoOneToMany(source->nick,stype,params); - } - else + /* Server-set lines */ + char data[MAXBUF]; + snprintf(data,MAXBUF,"%c %s %s %lu %lu :%s", linetype, host.c_str(), ServerInstance->Config->ServerName, ServerInstance->Time(false), duration, reason.c_str()); + std::deque params; + params.push_back(data); + Utils->DoOneToMany(ServerInstance->Config->ServerName, "ADDLINE", params); + } + else + { + if (IS_LOCAL(source)) { - std::deque params; - params.push_back(host); - Utils->DoOneToMany(source->nick,stype,params); + char type[8]; + snprintf(type,8,"%cLINE",linetype); + std::string stype = type; + if (adding) + { + char sduration[MAXBUF]; + snprintf(sduration,MAXBUF,"%ld",duration); + std::deque params; + params.push_back(host); + params.push_back(sduration); + params.push_back(":"+reason); + Utils->DoOneToMany(source->nick,stype,params); + } + else + { + std::deque params; + params.push_back(host); + Utils->DoOneToMany(source->nick,stype,params); + } } } } @@ -4992,7 +5112,7 @@ class ModuleSpanningTree : public Module return; (*params)[1] = ":" + (*params)[1]; params->insert(params->begin() + 1,ServerInstance->Config->ServerName); - params->insert(params->begin() + 1,ConvToStr(ServerInstance->Time())); + params->insert(params->begin() + 1,ConvToStr(ServerInstance->Time(true))); Utils->DoOneToMany(ServerInstance->Config->ServerName,"FTOPIC",*params); } else if (event->GetEventID() == "send_mode") @@ -5017,6 +5137,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() @@ -5024,6 +5157,8 @@ class ModuleSpanningTree : public Module ServerInstance->Log(DEBUG,"Performing unload of spanningtree!"); /* This will also free the listeners */ delete Utils; + if (SyncTimer) + ServerInstance->Timers->DelTimer(SyncTimer); } virtual Version GetVersion() @@ -5055,6 +5190,17 @@ class ModuleSpanningTree : public Module } }; +TimeSyncTimer::TimeSyncTimer(InspIRCd *Inst, ModuleSpanningTree *Mod) : InspTimer(43200, Inst->Time()), Instance(Inst), Module(Mod) +{ +} + +void TimeSyncTimer::Tick(time_t TIME) +{ + Module->BroadcastTimeSync(); + Module->SyncTimer = new TimeSyncTimer(Instance, Module); + Instance->Timers->AddTimer(Module->SyncTimer); +} + void SpanningTreeUtilities::DoFailOver(Link* x) { if (x->FailOver.length()) @@ -5089,7 +5235,6 @@ Link* SpanningTreeUtilities::FindLink(const std::string& name) return NULL; } - class ModuleSpanningTreeFactory : public ModuleFactory { public: