From: danieldg Date: Thu, 17 Sep 2009 22:33:35 +0000 (+0000) Subject: Add blocks [jackmcbarn] X-Git-Tag: v2.0.23~1510 X-Git-Url: https://git.netwichtig.de/gitweb/?a=commitdiff_plain;h=164e9d9171850877161ae057764ff8b579bedd36;p=user%2Fhenk%2Fcode%2Finspircd.git Add blocks [jackmcbarn] Replaces and git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11741 e03df62e-2008-0410-955e-edbf42e46eb7 --- diff --git a/src/modules/m_spanningtree/link.h b/src/modules/m_spanningtree/link.h index 4805f978c..d7630cac3 100644 --- a/src/modules/m_spanningtree/link.h +++ b/src/modules/m_spanningtree/link.h @@ -30,10 +30,7 @@ class Link : public classbase std::string RecvPass; std::string Fingerprint; std::string AllowMask; - unsigned long AutoConnect; - time_t NextConnectTime; bool HiddenFromStats; - std::string FailOver; std::string Hook; int Timeout; std::string Bind; diff --git a/src/modules/m_spanningtree/main.cpp b/src/modules/m_spanningtree/main.cpp index 8866e8d6d..1bc3dfe39 100644 --- a/src/modules/m_spanningtree/main.cpp +++ b/src/modules/m_spanningtree/main.cpp @@ -244,7 +244,7 @@ void ModuleSpanningTree::DoPingChecks(time_t curtime) } } -void ModuleSpanningTree::ConnectServer(Link* x) +void ModuleSpanningTree::ConnectServer(Link* x, Autoconnect* y) { bool ipvalid = true; @@ -275,7 +275,7 @@ void ModuleSpanningTree::ConnectServer(Link* x) /* Gave a hook, but it wasnt one we know */ if ((!x->Hook.empty()) && (Utils->hooks.find(x->Hook.c_str()) == Utils->hooks.end())) return; - TreeSocket* newsocket = new TreeSocket(Utils, ServerInstance, x->IPAddr,x->Port, x->Timeout ? x->Timeout : 10,x->Name.c_str(), x->Bind, x->Hook.empty() ? NULL : Utils->hooks[x->Hook.c_str()]); + TreeSocket* newsocket = new TreeSocket(Utils, ServerInstance, x->IPAddr,x->Port, x->Timeout ? x->Timeout : 10,x->Name.c_str(), x->Bind, y, x->Hook.empty() ? NULL : Utils->hooks[x->Hook.c_str()]); if (newsocket->GetFd() > -1) { /* Handled automatically on success */ @@ -285,7 +285,7 @@ void ModuleSpanningTree::ConnectServer(Link* x) ServerInstance->SNO->WriteToSnoMask('l', "CONNECT: Error connecting \002%s\002: %s.",x->Name.c_str(),strerror(errno)); if (ServerInstance->SocketCull.find(newsocket) == ServerInstance->SocketCull.end()) ServerInstance->SocketCull[newsocket] = newsocket; - Utils->DoFailOver(x); + Utils->DoFailOver(y); } } else @@ -293,25 +293,26 @@ void ModuleSpanningTree::ConnectServer(Link* x) try { bool cached; - ServernameResolver* snr = new ServernameResolver((Module*)this, Utils, ServerInstance,x->IPAddr, *x, cached, start_type); + ServernameResolver* snr = new ServernameResolver((Module*)this, Utils, ServerInstance,x->IPAddr, *x, cached, start_type, y); ServerInstance->AddResolver(snr, cached); } catch (ModuleException& e) { ServerInstance->SNO->WriteToSnoMask('l', "CONNECT: Error connecting \002%s\002: %s.",x->Name.c_str(), e.GetReason()); - Utils->DoFailOver(x); + Utils->DoFailOver(y); } } } void ModuleSpanningTree::AutoConnectServers(time_t curtime) { - for (std::vector::iterator x = Utils->LinkBlocks.begin(); x < Utils->LinkBlocks.end(); x++) + for (std::vector::iterator x = Utils->AutoconnectBlocks.begin(); x < Utils->AutoconnectBlocks.end(); ++x) { - if ((x->AutoConnect) && (curtime >= x->NextConnectTime)) + if (curtime >= x->NextConnectTime) { - x->NextConnectTime = curtime + x->AutoConnect; - TreeServer* CheckDupe = Utils->FindServer(x->Name.c_str()); + x->NextConnectTime = curtime + x->Period; + TreeServer* CheckDupe = Utils->FindServer(x->Server.c_str()); + Link* y = Utils->FindLink(x->Server); if (x->FailOver.length()) { TreeServer* CheckFailOver = Utils->FindServer(x->FailOver.c_str()); @@ -327,8 +328,8 @@ void ModuleSpanningTree::AutoConnectServers(time_t curtime) if (!CheckDupe) { // an autoconnected server is not connected. Check if its time to connect it - ServerInstance->SNO->WriteToSnoMask('l',"AUTOCONNECT: Auto-connecting server \002%s\002 (%lu seconds until next attempt)",x->Name.c_str(),x->AutoConnect); - this->ConnectServer(&(*x)); + ServerInstance->SNO->WriteToSnoMask('l',"AUTOCONNECT: Auto-connecting server \002%s\002 (%lu seconds until next attempt)",y->Name.c_str(),x->Period); + this->ConnectServer(&(*y), &(*x)); } } } @@ -336,7 +337,7 @@ void ModuleSpanningTree::AutoConnectServers(time_t curtime) void ModuleSpanningTree::DoConnectTimeout(time_t curtime) { - std::vector failovers; + std::vector failovers; for (std::map >::iterator i = Utils->timeoutlist.begin(); i != Utils->timeoutlist.end(); i++) { TreeSocket* s = i->first; @@ -344,15 +345,13 @@ void ModuleSpanningTree::DoConnectTimeout(time_t curtime) if (curtime > s->age + p.second) { ServerInstance->SNO->WriteToSnoMask('l',"CONNECT: Error connecting \002%s\002 (timeout of %d seconds)",p.first.c_str(),p.second); + failovers.push_back(s->myautoconnect); ServerInstance->SE->DelFd(s); s->Close(); - Link* MyLink = Utils->FindLink(p.first); - if (MyLink) - failovers.push_back(MyLink); } } /* Trigger failover for each timed out socket */ - for (std::vector::const_iterator n = failovers.begin(); n != failovers.end(); ++n) + for (std::vector::const_iterator n = failovers.begin(); n != failovers.end(); ++n) { Utils->DoFailOver(*n); } @@ -411,7 +410,7 @@ ModResult ModuleSpanningTree::HandleConnect(const std::vector& para if (!CheckDupe) { RemoteMessage(user, "*** CONNECT: Connecting to server: \002%s\002 (%s:%d)",x->Name.c_str(),(x->HiddenFromStats ? "" : x->IPAddr.c_str()),x->Port); - ConnectServer(&(*x)); + ConnectServer(&(*x), NULL); return MOD_RES_DENY; } else diff --git a/src/modules/m_spanningtree/main.h b/src/modules/m_spanningtree/main.h index 0144eb4a3..0d44169c7 100644 --- a/src/modules/m_spanningtree/main.h +++ b/src/modules/m_spanningtree/main.h @@ -37,6 +37,7 @@ class SpanningTreeUtilities; class CacheRefreshTimer; class TreeServer; class Link; +class Autoconnect; /** This is the main class for the spanningtree module */ @@ -123,7 +124,7 @@ class ModuleSpanningTree : public Module /** Connect a server locally */ - void ConnectServer(Link* x); + void ConnectServer(Link* x, Autoconnect* y); /** Check if any servers are due to be autoconnected */ diff --git a/src/modules/m_spanningtree/override_stats.cpp b/src/modules/m_spanningtree/override_stats.cpp index aa4834303..9986763d9 100644 --- a/src/modules/m_spanningtree/override_stats.cpp +++ b/src/modules/m_spanningtree/override_stats.cpp @@ -60,7 +60,7 @@ ModResult ModuleSpanningTree::OnStats(char statschar, User* user, string_list &r { for (unsigned int i = 0; i < Utils->LinkBlocks.size(); i++) { - results.push_back(std::string(ServerInstance->Config->ServerName)+" 213 "+user->nick+" "+statschar+" *@"+(Utils->LinkBlocks[i].HiddenFromStats ? "" : Utils->LinkBlocks[i].IPAddr)+" * "+Utils->LinkBlocks[i].Name.c_str()+" "+ConvToStr(Utils->LinkBlocks[i].Port)+" "+(Utils->LinkBlocks[i].Hook.empty() ? "plaintext" : Utils->LinkBlocks[i].Hook)+" "+(Utils->LinkBlocks[i].AutoConnect ? 'a': '-')+'s'); + results.push_back(std::string(ServerInstance->Config->ServerName)+" 213 "+user->nick+" "+statschar+" *@"+(Utils->LinkBlocks[i].HiddenFromStats ? "" : Utils->LinkBlocks[i].IPAddr)+" * "+Utils->LinkBlocks[i].Name.c_str()+" "+ConvToStr(Utils->LinkBlocks[i].Port)+" "+(Utils->LinkBlocks[i].Hook.empty() ? "plaintext" : Utils->LinkBlocks[i].Hook)); if (statschar == 'c') results.push_back(std::string(ServerInstance->Config->ServerName)+" 244 "+user->nick+" H * * "+Utils->LinkBlocks[i].Name.c_str()); } diff --git a/src/modules/m_spanningtree/resolvers.cpp b/src/modules/m_spanningtree/resolvers.cpp index fc3011bc2..73e67c4f7 100644 --- a/src/modules/m_spanningtree/resolvers.cpp +++ b/src/modules/m_spanningtree/resolvers.cpp @@ -31,7 +31,7 @@ * callback to OnLookupComplete or OnError when completed. Once it has completed we * will have an IP address which we can then use to continue our connection. */ -ServernameResolver::ServernameResolver(Module* me, SpanningTreeUtilities* Util, InspIRCd* Instance, const std::string &hostname, Link x, bool &cached, QueryType qt) : Resolver(Instance, hostname, qt, cached, me), MyLink(x), Utils(Util), query(qt), host(hostname), mine(me) +ServernameResolver::ServernameResolver(Module* me, SpanningTreeUtilities* Util, InspIRCd* Instance, const std::string &hostname, Link x, bool &cached, QueryType qt, Autoconnect* myac) : Resolver(Instance, hostname, qt, cached, me), MyLink(x), Utils(Util), query(qt), host(hostname), mine(me), myautoconnect(myac) { /* Nothing in here, folks */ } @@ -50,7 +50,7 @@ void ServernameResolver::OnLookupComplete(const std::string &result, unsigned in return; TreeSocket* newsocket = new TreeSocket(this->Utils, ServerInstance, result,MyLink.Port,MyLink.Timeout ? MyLink.Timeout : 10,MyLink.Name.c_str(), - MyLink.Bind, MyLink.Hook.empty() ? NULL : Utils->hooks[MyLink.Hook.c_str()]); + MyLink.Bind, myautoconnect, MyLink.Hook.empty() ? NULL : Utils->hooks[MyLink.Hook.c_str()]); if (newsocket->GetFd() > -1) { /* We're all OK */ @@ -61,7 +61,7 @@ void ServernameResolver::OnLookupComplete(const std::string &result, unsigned in ServerInstance->SNO->WriteToSnoMask('l', "CONNECT: Error connecting \002%s\002: %s.",MyLink.Name.c_str(),strerror(errno)); if (ServerInstance->SocketCull.find(newsocket) == ServerInstance->SocketCull.end()) ServerInstance->SocketCull[newsocket] = newsocket; - Utils->DoFailOver(&MyLink); + Utils->DoFailOver(myautoconnect); } } } @@ -72,11 +72,11 @@ void ServernameResolver::OnError(ResolverError e, const std::string &errormessag if (query == DNS_QUERY_AAAA) { bool cached; - ServernameResolver* snr = new ServernameResolver(mine, Utils, ServerInstance, host, MyLink, cached, DNS_QUERY_A); + ServernameResolver* snr = new ServernameResolver(mine, Utils, ServerInstance, host, MyLink, cached, DNS_QUERY_A, myautoconnect); ServerInstance->AddResolver(snr, cached); return; } ServerInstance->SNO->WriteToSnoMask('l', "CONNECT: Error connecting \002%s\002: Unable to resolve hostname - %s", MyLink.Name.c_str(), errormessage.c_str() ); - Utils->DoFailOver(&MyLink); + Utils->DoFailOver(myautoconnect); } diff --git a/src/modules/m_spanningtree/resolvers.h b/src/modules/m_spanningtree/resolvers.h index fc85cd049..e4404d6a5 100644 --- a/src/modules/m_spanningtree/resolvers.h +++ b/src/modules/m_spanningtree/resolvers.h @@ -74,8 +74,9 @@ class ServernameResolver : public Resolver QueryType query; std::string host; Module* mine; + Autoconnect* myautoconnect; public: - ServernameResolver(Module* me, SpanningTreeUtilities* Util, InspIRCd* Instance, const std::string &hostname, Link x, bool &cached, QueryType qt); + ServernameResolver(Module* me, SpanningTreeUtilities* Util, InspIRCd* Instance, const std::string &hostname, Link x, bool &cached, QueryType qt, Autoconnect* myac); void OnLookupComplete(const std::string &result, unsigned int ttl, bool cached); void OnError(ResolverError e, const std::string &errormessage); }; diff --git a/src/modules/m_spanningtree/treesocket.h b/src/modules/m_spanningtree/treesocket.h index 37cfbbd9e..a26e89f85 100644 --- a/src/modules/m_spanningtree/treesocket.h +++ b/src/modules/m_spanningtree/treesocket.h @@ -93,6 +93,7 @@ class TreeSocket : public BufferedSocket int proto_version; /* Remote protocol version */ public: HandshakeTimer* hstimer; /* Handshake timer, needed to work around I/O hook buffering */ + Autoconnect* myautoconnect; /* Autoconnect used to cause this connection, if any */ time_t age; /** Because most of the I/O gubbins are encapsulated within @@ -100,13 +101,13 @@ class TreeSocket : public BufferedSocket * most of the action, and append a few of our own values * to it. */ - TreeSocket(SpanningTreeUtilities* Util, InspIRCd* SI, std::string host, int port, unsigned long maxtime, const std::string &ServerName, const std::string &bindto, Module* HookMod = NULL); + TreeSocket(SpanningTreeUtilities* Util, InspIRCd* SI, std::string host, int port, unsigned long maxtime, const std::string &ServerName, const std::string &bindto, Autoconnect* myac, Module* HookMod = NULL); /** When a listening socket gives us a new file descriptor, * we must associate it with a socket without creating a new * connection. This constructor is used for this purpose. */ - TreeSocket(SpanningTreeUtilities* Util, InspIRCd* SI, int newfd, char* ip, Module* HookMod = NULL); + TreeSocket(SpanningTreeUtilities* Util, InspIRCd* SI, int newfd, char* ip, Autoconnect* myac, Module* HookMod = NULL); /** Get link state */ diff --git a/src/modules/m_spanningtree/treesocket1.cpp b/src/modules/m_spanningtree/treesocket1.cpp index 6703021a8..d59364751 100644 --- a/src/modules/m_spanningtree/treesocket1.cpp +++ b/src/modules/m_spanningtree/treesocket1.cpp @@ -34,8 +34,8 @@ * most of the action, and append a few of our own values * to it. */ -TreeSocket::TreeSocket(SpanningTreeUtilities* Util, InspIRCd* SI, std::string shost, int iport, unsigned long maxtime, const std::string &ServerName, const std::string &bindto, Module* HookMod) - : BufferedSocket(SI, shost, iport, maxtime, bindto), Utils(Util), Hook(HookMod) +TreeSocket::TreeSocket(SpanningTreeUtilities* Util, InspIRCd* SI, std::string shost, int iport, unsigned long maxtime, const std::string &ServerName, const std::string &bindto, Autoconnect* myac, Module* HookMod) + : BufferedSocket(SI, shost, iport, maxtime, bindto), Utils(Util), Hook(HookMod), myautoconnect(myac) { age = SI->Time(); myhost = ServerName; @@ -52,8 +52,8 @@ TreeSocket::TreeSocket(SpanningTreeUtilities* Util, InspIRCd* SI, std::string sh * we must associate it with a socket without creating a new * connection. This constructor is used for this purpose. */ -TreeSocket::TreeSocket(SpanningTreeUtilities* Util, InspIRCd* SI, int newfd, char* ip, Module* HookMod) - : BufferedSocket(SI, newfd, ip), Utils(Util), Hook(HookMod) +TreeSocket::TreeSocket(SpanningTreeUtilities* Util, InspIRCd* SI, int newfd, char* ip, Autoconnect* myac, Module* HookMod) + : BufferedSocket(SI, newfd, ip), Utils(Util), Hook(HookMod), myautoconnect(myac) { age = SI->Time(); LinkState = WAIT_AUTH_1; @@ -149,15 +149,11 @@ bool TreeSocket::OnConnected() void TreeSocket::OnError(BufferedSocketError e) { - Link* MyLink; - switch (e) { case I_ERR_CONNECT: ServerInstance->SNO->WriteToSnoMask('l', "Connection failed: Connection to \002%s\002 refused", myhost.c_str()); - MyLink = Utils->FindLink(myhost); - if (MyLink) - Utils->DoFailOver(MyLink); + Utils->DoFailOver(myautoconnect); break; case I_ERR_SOCKET: ServerInstance->SNO->WriteToSnoMask('l', "Connection failed: Could not create socket (%s)", strerror(errno)); diff --git a/src/modules/m_spanningtree/treesocket2.cpp b/src/modules/m_spanningtree/treesocket2.cpp index dac0216aa..793802781 100644 --- a/src/modules/m_spanningtree/treesocket2.cpp +++ b/src/modules/m_spanningtree/treesocket2.cpp @@ -608,9 +608,7 @@ void TreeSocket::OnTimeout() if (this->LinkState == CONNECTING) { this->ServerInstance->SNO->WriteToSnoMask('l', "CONNECT: Connection to \002%s\002 timed out.", myhost.c_str()); - Link* MyLink = Utils->FindLink(myhost); - if (MyLink) - Utils->DoFailOver(MyLink); + Utils->DoFailOver(myautoconnect); } } diff --git a/src/modules/m_spanningtree/utils.cpp b/src/modules/m_spanningtree/utils.cpp index 1550a1e37..b37aecc4b 100644 --- a/src/modules/m_spanningtree/utils.cpp +++ b/src/modules/m_spanningtree/utils.cpp @@ -61,7 +61,7 @@ void ServerSocketListener::OnAcceptReady(int newsock) } /* we don't need a pointer to this, creating it stores it in the necessary places */ - new TreeSocket(this->Utils, this->ServerInstance, newsock, ip, this->GetIOHook()); + new TreeSocket(this->Utils, this->ServerInstance, newsock, ip, NULL, this->GetIOHook()); return; } @@ -520,21 +520,20 @@ void SpanningTreeUtilities::ReadConfiguration(bool rebind) if (PingWarnTime < 0 || PingWarnTime > PingFreq - 1) PingWarnTime = 0; + AutoconnectBlocks.clear(); LinkBlocks.clear(); ValidIPs.clear(); - for (int j = 0; j < Conf->Enumerate("link"); j++) + for (int j = 0; j < Conf->Enumerate("link"); ++j) { Link L; std::string Allow = Conf->ReadValue("link", "allowmask", j); L.Name = (Conf->ReadValue("link", "name", j)).c_str(); L.AllowMask = Allow; L.IPAddr = Conf->ReadValue("link", "ipaddr", j); - L.FailOver = Conf->ReadValue("link", "failover", j).c_str(); L.Port = Conf->ReadInteger("link", "port", j, true); L.SendPass = Conf->ReadValue("link", "sendpass", j); L.RecvPass = Conf->ReadValue("link", "recvpass", j); L.Fingerprint = Conf->ReadValue("link", "fingerprint", j); - L.AutoConnect = Conf->ReadInteger("link", "autoconnect", j, true); L.HiddenFromStats = Conf->ReadFlag("link", "statshidden", j); L.Timeout = Conf->ReadInteger("link", "timeout", j, true); L.Hook = Conf->ReadValue("link", "transport", j); @@ -548,10 +547,6 @@ void SpanningTreeUtilities::ReadConfiguration(bool rebind) } - // Fix: Only trip autoconnects if this wouldn't delay autoconnect.. - if (L.NextConnectTime > ((time_t)(ServerInstance->Time() + L.AutoConnect))) - L.NextConnectTime = ServerInstance->Time() + L.AutoConnect; - if (L.Name.find('.') == std::string::npos) throw CoreException("The link name '"+assign(L.Name)+"' is invalid and must contain at least one '.' character"); @@ -627,16 +622,41 @@ void SpanningTreeUtilities::ReadConfiguration(bool rebind) LinkBlocks.push_back(L); } + + for (int j = 0; j < Conf->Enumerate("autoconnect"); ++j) + { + Autoconnect A; + A.Period = Conf->ReadInteger("autoconnect", "period", j, true); + A.Server = Conf->ReadValue("autoconnect", "server", j); + A.FailOver = Conf->ReadValue("autoconnect", "failover", j).c_str(); + + // Fix: Only trip autoconnects if this wouldn't delay autoconnect.. + if (A.NextConnectTime > ((time_t)(ServerInstance->Time() + A.Period))) + A.NextConnectTime = ServerInstance->Time() + A.Period; + + if (A.Period <= 0) + { + throw CoreException("Invalid configuration for autoconnect, period not a positive integer!"); + } + + if (A.Server.empty()) + { + throw CoreException("Invalid configuration for autoconnect, server cannot be empty!"); + } + + AutoconnectBlocks.push_back(A); + } + delete Conf; } -void SpanningTreeUtilities::DoFailOver(Link* x) +void SpanningTreeUtilities::DoFailOver(Autoconnect* x) { - if (x->FailOver.length()) + if (x && x->FailOver.length()) { - if (x->FailOver == x->Name) + if (x->FailOver == x->Server) { - this->ServerInstance->SNO->WriteToSnoMask('l', "FAILOVER: Some muppet configured the failover for server \002%s\002 to point at itself. Not following it!", x->Name.c_str()); + this->ServerInstance->SNO->WriteToSnoMask('l', "FAILOVER: Some muppet configured the failover for server \002%s\002 to point at itself. Not following it!", x->Server.c_str()); return; } Link* TryThisOne = this->FindLink(x->FailOver.c_str()); @@ -649,13 +669,13 @@ void SpanningTreeUtilities::DoFailOver(Link* x) } else { - this->ServerInstance->SNO->WriteToSnoMask('l', "FAILOVER: Trying failover link for \002%s\002: \002%s\002...", x->Name.c_str(), TryThisOne->Name.c_str()); - Creator->ConnectServer(TryThisOne); + this->ServerInstance->SNO->WriteToSnoMask('l', "FAILOVER: Trying failover link for \002%s\002: \002%s\002...", x->Server.c_str(), TryThisOne->Name.c_str()); + Creator->ConnectServer(TryThisOne, NULL); } } else { - this->ServerInstance->SNO->WriteToSnoMask('l', "FAILOVER: Invalid failover server specified for server \002%s\002, will not follow!", x->Name.c_str()); + this->ServerInstance->SNO->WriteToSnoMask('l', "FAILOVER: Invalid failover server specified for server \002%s\002, will not follow!", x->Server.c_str()); } } } diff --git a/src/modules/m_spanningtree/utils.h b/src/modules/m_spanningtree/utils.h index 6ac657851..09c707131 100644 --- a/src/modules/m_spanningtree/utils.h +++ b/src/modules/m_spanningtree/utils.h @@ -59,6 +59,21 @@ typedef std::map TreeServerList; */ typedef std::map hookmodules; +/** The Autoconnect class might as well be a struct, + * but this is C++ and we don't believe in structs (!). + * It holds the entire information of one + * tag from the main config file. We maintain a list + * of them, and populate the list on rehash/load. + */ +class Autoconnect : public classbase +{ + public: + unsigned long Period; + std::string Server; + time_t NextConnectTime; + std::string FailOver; +}; + /** Contains helper functions and variables for this module, * and keeps them out of the global namespace */ @@ -122,6 +137,9 @@ class SpanningTreeUtilities : public classbase /** Holds the data from the tags in the conf */ std::vector LinkBlocks; + /** Holds the data from the tags in the conf + */ + std::vector AutoconnectBlocks; /** List of module pointers which can provide I/O abstraction */ @@ -209,7 +227,7 @@ class SpanningTreeUtilities : public classbase /** Attempt to connect to the failover link of link x */ - void DoFailOver(Link* x); + void DoFailOver(Autoconnect* x); /** Find a link tag from a server name */