diff options
author | Attila Molnar <attilamolnar@hush.com> | 2016-04-26 15:02:50 +0200 |
---|---|---|
committer | Attila Molnar <attilamolnar@hush.com> | 2016-04-26 15:02:50 +0200 |
commit | 6cfe4011ec0e90718d7d5a449a5330b8e9a18ec3 (patch) | |
tree | 13bdd9ddc821351ff125d0a472416199ca060f42 | |
parent | 53f266a35ff6201d606a4e8f66f0c6cccb630891 (diff) | |
parent | 72501adb5c721ac7b8d148c53305457e2c5a5921 (diff) |
Merge branch 'master+sasloffline'
-rw-r--r-- | src/modules/m_sasl.cpp | 77 | ||||
-rw-r--r-- | src/modules/m_spanningtree/main.cpp | 16 | ||||
-rw-r--r-- | src/modules/m_spanningtree/treeserver.cpp | 8 |
3 files changed, 95 insertions, 6 deletions
diff --git a/src/modules/m_sasl.cpp b/src/modules/m_sasl.cpp index 639fe6778..02a302c11 100644 --- a/src/modules/m_sasl.cpp +++ b/src/modules/m_sasl.cpp @@ -23,10 +23,73 @@ #include "modules/account.h" #include "modules/sasl.h" #include "modules/ssl.h" +#include "modules/spanningtree.h" + +static std::string sasl_target; + +class ServerTracker : public SpanningTreeEventListener +{ + bool online; + + void Update(const Server* server, bool linked) + { + if (sasl_target == "*") + return; + + if (InspIRCd::Match(server->GetName(), sasl_target)) + { + ServerInstance->Logs->Log(MODNAME, LOG_VERBOSE, "SASL target server \"%s\" %s", sasl_target.c_str(), (linked ? "came online" : "went offline")); + online = linked; + } + } + + void OnServerLink(const Server* server) CXX11_OVERRIDE + { + Update(server, true); + } + + void OnServerSplit(const Server* server) CXX11_OVERRIDE + { + Update(server, false); + } + + public: + ServerTracker(Module* mod) + : SpanningTreeEventListener(mod) + { + Reset(); + } + + void Reset() + { + if (sasl_target == "*") + { + online = true; + return; + } + + online = false; + + ProtocolInterface::ServerList servers; + ServerInstance->PI->GetServerList(servers); + for (ProtocolInterface::ServerList::const_iterator i = servers.begin(); i != servers.end(); ++i) + { + const ProtocolInterface::ServerInfo& server = *i; + if (InspIRCd::Match(server.servername, sasl_target)) + { + online = true; + break; + } + } + } + + bool IsOnline() const { return online; } +}; class SASLCap : public Cap::Capability { std::string mechlist; + const ServerTracker& servertracker; bool OnRequest(LocalUser* user, bool adding) CXX11_OVERRIDE { @@ -38,14 +101,20 @@ class SASLCap : public Cap::Capability return (user->registered != REG_ALL); } + bool OnList(LocalUser* user) CXX11_OVERRIDE + { + return servertracker.IsOnline(); + } + const std::string* GetValue(LocalUser* user) const CXX11_OVERRIDE { return &mechlist; } public: - SASLCap(Module* mod) + SASLCap(Module* mod, const ServerTracker& tracker) : Cap::Capability(mod, "sasl") + , servertracker(tracker) { } @@ -62,7 +131,6 @@ class SASLCap : public Cap::Capability enum SaslState { SASL_INIT, SASL_COMM, SASL_DONE }; enum SaslResult { SASL_OK, SASL_FAIL, SASL_ABORT }; -static std::string sasl_target = "*"; static Events::ModuleEventProvider* saslevprov; static void SendSASL(const parameterlist& params) @@ -280,6 +348,7 @@ class CommandSASL : public Command class ModuleSASL : public Module { SimpleExtItem<SaslAuthenticator> authExt; + ServerTracker servertracker; SASLCap cap; CommandAuthenticate auth; CommandSASL sasl; @@ -288,7 +357,8 @@ class ModuleSASL : public Module public: ModuleSASL() : authExt("sasl_auth", ExtensionItem::EXT_USER, this) - , cap(this) + , servertracker(this) + , cap(this, servertracker) , auth(this, authExt, cap) , sasl(this, authExt) , sasleventprov(this, "event/sasl") @@ -305,6 +375,7 @@ class ModuleSASL : public Module void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE { sasl_target = ServerInstance->Config->ConfValue("sasl")->getString("target", "*"); + servertracker.Reset(); } ModResult OnUserRegister(LocalUser *user) CXX11_OVERRIDE diff --git a/src/modules/m_spanningtree/main.cpp b/src/modules/m_spanningtree/main.cpp index 5b3f9c0bb..0b9bb65df 100644 --- a/src/modules/m_spanningtree/main.cpp +++ b/src/modules/m_spanningtree/main.cpp @@ -25,6 +25,7 @@ #include "socket.h" #include "xline.h" #include "iohook.h" +#include "modules/spanningtree.h" #include "resolvers.h" #include "main.h" @@ -613,6 +614,21 @@ void ModuleSpanningTree::OnUnloadModule(Module* mod) return; ServerInstance->PI->SendMetaData("modules", "-" + mod->ModuleSourceFile); + if (mod == this) + { + // We are being unloaded, inform modules about all servers splitting which cannot be done later when the servers are actually disconnected + const server_hash& servers = Utils->serverlist; + for (server_hash::const_iterator i = servers.begin(); i != servers.end(); ++i) + { + TreeServer* server = i->second; + if (!server->IsRoot()) + FOREACH_MOD_CUSTOM(GetEventProvider(), SpanningTreeEventListener, OnServerSplit, (server)); + } + return; + } + + // Some other module is being unloaded. If it provides an IOHook we use, we must close that server connection now. + restart: // Close all connections which use an IO hook provided by this module const TreeServer::ChildServers& list = Utils->TreeRoot->GetChildren(); diff --git a/src/modules/m_spanningtree/treeserver.cpp b/src/modules/m_spanningtree/treeserver.cpp index 1fc9455b0..b29bea134 100644 --- a/src/modules/m_spanningtree/treeserver.cpp +++ b/src/modules/m_spanningtree/treeserver.cpp @@ -115,6 +115,8 @@ TreeServer::TreeServer(const std::string& Name, const std::string& Desc, const s this->AddHashEntry(); Parent->Children.push_back(this); + + FOREACH_MOD_CUSTOM(Utils->Creator->GetEventProvider(), SpanningTreeEventListener, OnServerLink, (this)); } void TreeServer::BeginBurst(uint64_t startms) @@ -151,7 +153,6 @@ void TreeServer::FinishBurst() unsigned long bursttime = ts - this->StartBurst; ServerInstance->SNO->WriteToSnoMask(Parent == Utils->TreeRoot ? 'l' : 'L', "Received end of netburst from \2%s\2 (burst time: %lu %s)", GetName().c_str(), (bursttime > 10000 ? bursttime / 1000 : bursttime), (bursttime > 10000 ? "secs" : "msecs")); - FOREACH_MOD_CUSTOM(Utils->Creator->GetEventProvider(), SpanningTreeEventListener, OnServerLink, (this)); StartBurst = 0; FinishBurstInternal(); @@ -159,8 +160,6 @@ void TreeServer::FinishBurst() void TreeServer::SQuitChild(TreeServer* server, const std::string& reason) { - if (!Utils->Creator->dying) - FOREACH_MOD_CUSTOM(Utils->Creator->GetEventProvider(), SpanningTreeEventListener, OnServerSplit, (server)); stdalgo::erase(Children, server); if (IsRoot()) @@ -205,6 +204,9 @@ void TreeServer::SQuitInternal(unsigned int& num_lost_servers) isdead = true; num_lost_servers++; RemoveHash(); + + if (!Utils->Creator->dying) + FOREACH_MOD_CUSTOM(Utils->Creator->GetEventProvider(), SpanningTreeEventListener, OnServerSplit, (this)); } unsigned int TreeServer::QuitUsers(const std::string& reason) |