summaryrefslogtreecommitdiff
path: root/src/modules/m_spanningtree
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/m_spanningtree')
-rw-r--r--src/modules/m_spanningtree/main.cpp16
-rw-r--r--src/modules/m_spanningtree/resolvers.cpp30
-rw-r--r--src/modules/m_spanningtree/resolvers.h25
-rw-r--r--src/modules/m_spanningtree/server.cpp8
-rw-r--r--src/modules/m_spanningtree/treesocket1.cpp12
-rw-r--r--src/modules/m_spanningtree/treesocket2.cpp13
-rw-r--r--src/modules/m_spanningtree/uid.cpp2
-rw-r--r--src/modules/m_spanningtree/utils.cpp79
8 files changed, 95 insertions, 90 deletions
diff --git a/src/modules/m_spanningtree/main.cpp b/src/modules/m_spanningtree/main.cpp
index 1067852d1..f639a748d 100644
--- a/src/modules/m_spanningtree/main.cpp
+++ b/src/modules/m_spanningtree/main.cpp
@@ -765,7 +765,21 @@ void ModuleSpanningTree::OnPreRehash(User* user, const std::string &parameter)
void ModuleSpanningTree::OnRehash(User* user)
{
// Re-read config stuff
- Utils->ReadConfiguration();
+ try
+ {
+ Utils->ReadConfiguration();
+ }
+ catch (ModuleException& e)
+ {
+ // Refresh the IP cache anyway, so servers read before the error will be allowed to connect
+ Utils->RefreshIPCache();
+ // Always warn local opers with snomask +l, also warn globally (snomask +L) if the rehash was issued by a remote user
+ std::string msg = "Error in configuration: ";
+ msg.append(e.GetReason());
+ ServerInstance->SNO->WriteToSnoMask('l', msg);
+ if (!IS_LOCAL(user))
+ ServerInstance->PI->SendSNONotice("L", msg);
+ }
}
void ModuleSpanningTree::OnLoadModule(Module* mod)
diff --git a/src/modules/m_spanningtree/resolvers.cpp b/src/modules/m_spanningtree/resolvers.cpp
index ae951bd38..b69c5c29e 100644
--- a/src/modules/m_spanningtree/resolvers.cpp
+++ b/src/modules/m_spanningtree/resolvers.cpp
@@ -80,3 +80,33 @@ void ServernameResolver::OnError(ResolverError e, const std::string &errormessag
Utils->Creator->ConnectServer(myautoconnect, false);
}
+SecurityIPResolver::SecurityIPResolver(Module* me, SpanningTreeUtilities* U, const std::string &hostname, Link* x, bool &cached, QueryType qt)
+ : Resolver(hostname, qt, cached, me), MyLink(x), Utils(U), mine(me), host(hostname), query(qt)
+{
+}
+
+void SecurityIPResolver::OnLookupComplete(const std::string &result, unsigned int ttl, bool cached)
+{
+ for (std::vector<reference<Link> >::iterator i = Utils->LinkBlocks.begin(); i != Utils->LinkBlocks.end(); ++i)
+ {
+ Link* L = *i;
+ if (L->IPAddr == host)
+ {
+ Utils->ValidIPs.push_back(result);
+ break;
+ }
+ }
+}
+
+void SecurityIPResolver::OnError(ResolverError e, const std::string &errormessage)
+{
+ if (query == DNS_QUERY_AAAA)
+ {
+ bool cached;
+ SecurityIPResolver* res = new SecurityIPResolver(mine, Utils, host, MyLink, cached, DNS_QUERY_A);
+ ServerInstance->AddResolver(res, cached);
+ return;
+ }
+ ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"Could not resolve IP associated with Link '%s': %s",
+ MyLink->Name.c_str(),errormessage.c_str());
+}
diff --git a/src/modules/m_spanningtree/resolvers.h b/src/modules/m_spanningtree/resolvers.h
index cb3b38516..65b9e7249 100644
--- a/src/modules/m_spanningtree/resolvers.h
+++ b/src/modules/m_spanningtree/resolvers.h
@@ -39,28 +39,9 @@ class SecurityIPResolver : public Resolver
std::string host;
QueryType query;
public:
- SecurityIPResolver(Module* me, SpanningTreeUtilities* U, const std::string &hostname, Link* x, bool &cached, QueryType qt)
- : Resolver(hostname, qt, cached, me), MyLink(x), Utils(U), mine(me), host(hostname), query(qt)
- {
- }
-
- void OnLookupComplete(const std::string &result, unsigned int ttl, bool cached)
- {
- Utils->ValidIPs.push_back(result);
- }
-
- void OnError(ResolverError e, const std::string &errormessage)
- {
- if (query == DNS_QUERY_AAAA)
- {
- bool cached;
- SecurityIPResolver* res = new SecurityIPResolver(mine, Utils, host, MyLink, cached, DNS_QUERY_A);
- ServerInstance->AddResolver(res, cached);
- return;
- }
- ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"Could not resolve IP associated with Link '%s': %s",
- MyLink->Name.c_str(),errormessage.c_str());
- }
+ SecurityIPResolver(Module* me, SpanningTreeUtilities* U, const std::string &hostname, Link* x, bool &cached, QueryType qt);
+ void OnLookupComplete(const std::string &result, unsigned int ttl, bool cached);
+ void OnError(ResolverError e, const std::string &errormessage);
};
/** This class is used to resolve server hostnames during /connect and autoconnect.
diff --git a/src/modules/m_spanningtree/server.cpp b/src/modules/m_spanningtree/server.cpp
index 1b13fb2da..64c32e8fb 100644
--- a/src/modules/m_spanningtree/server.cpp
+++ b/src/modules/m_spanningtree/server.cpp
@@ -163,15 +163,15 @@ bool TreeSocket::Outbound_Reply_Server(parameterlist &params)
linkID = sname;
MyRoot = new TreeServer(Utils, sname, description, sid, Utils->TreeRoot, this, x->Hidden);
-
Utils->TreeRoot->AddChild(MyRoot);
+ this->DoBurst(MyRoot);
+
params[4] = ":" + params[4];
/* IMPORTANT: Take password/hmac hash OUT of here before we broadcast the introduction! */
params[1] = "*";
Utils->DoOneToAllButSender(ServerInstance->Config->GetSID(),"SERVER",params,sname);
- this->DoBurst(MyRoot);
return true;
}
@@ -259,10 +259,6 @@ bool TreeSocket::Inbound_Server(parameterlist &params)
MyRoot = new TreeServer(Utils, sname, description, sid, Utils->TreeRoot, this, x->Hidden);
Utils->TreeRoot->AddChild(MyRoot);
- params[1] = "*";
- params[4] = ":" + params[4];
- Utils->DoOneToAllButSender(ServerInstance->Config->GetSID(),"SERVER",params,sname);
-
this->LinkState = WAIT_AUTH_2;
return true;
}
diff --git a/src/modules/m_spanningtree/treesocket1.cpp b/src/modules/m_spanningtree/treesocket1.cpp
index 673b05c55..dcb35af31 100644
--- a/src/modules/m_spanningtree/treesocket1.cpp
+++ b/src/modules/m_spanningtree/treesocket1.cpp
@@ -183,10 +183,14 @@ void TreeSocket::Squit(TreeServer* Current, const std::string &reason)
{
DelServerEvent(Utils->Creator, Current->GetName());
- parameterlist params;
- params.push_back(Current->GetName());
- params.push_back(":"+reason);
- Utils->DoOneToAllButSender(Current->GetParent()->GetName(),"SQUIT",params,Current->GetName());
+ if (!Current->GetSocket() || Current->GetSocket()->GetLinkState() == CONNECTED)
+ {
+ parameterlist params;
+ params.push_back(Current->GetName());
+ params.push_back(":"+reason);
+ Utils->DoOneToAllButSender(Current->GetParent()->GetName(),"SQUIT",params,Current->GetName());
+ }
+
if (Current->GetParent() == Utils->TreeRoot)
{
ServerInstance->SNO->WriteGlobalSno('l', "Server \002"+Current->GetName()+"\002 split: "+reason);
diff --git a/src/modules/m_spanningtree/treesocket2.cpp b/src/modules/m_spanningtree/treesocket2.cpp
index 4582eb4c5..cb49d92c9 100644
--- a/src/modules/m_spanningtree/treesocket2.cpp
+++ b/src/modules/m_spanningtree/treesocket2.cpp
@@ -165,12 +165,19 @@ void TreeSocket::ProcessLine(std::string &line)
}
}
this->LinkState = CONNECTED;
-
Utils->timeoutlist.erase(this);
- parameterlist sparams;
- Utils->DoOneToAllButSender(MyRoot->GetID(), "BURST", params, MyRoot->GetName());
+
MyRoot->bursting = true;
this->DoBurst(MyRoot);
+
+ parameterlist sparams;
+ sparams.push_back(MyRoot->GetName());
+ sparams.push_back("*");
+ sparams.push_back("0");
+ sparams.push_back(MyRoot->GetID());
+ sparams.push_back(":" + MyRoot->GetDesc());
+ Utils->DoOneToAllButSender(ServerInstance->Config->GetSID(), "SERVER", sparams, MyRoot->GetName());
+ Utils->DoOneToAllButSender(MyRoot->GetID(), "BURST", params, MyRoot->GetName());
}
else if (command == "ERROR")
{
diff --git a/src/modules/m_spanningtree/uid.cpp b/src/modules/m_spanningtree/uid.cpp
index 67a21a484..0a8f4dbfc 100644
--- a/src/modules/m_spanningtree/uid.cpp
+++ b/src/modules/m_spanningtree/uid.cpp
@@ -154,7 +154,7 @@ CmdResult CommandUID::Handle(const parameterlist &params, User* serversrc)
dosend = false;
if (dosend)
- ServerInstance->SNO->WriteToSnoMask('C',"Client connecting at %s: %s!%s@%s [%s] [%s]", _new->server.c_str(), _new->nick.c_str(), _new->ident.c_str(), _new->host.c_str(), _new->GetIPString(), _new->fullname.c_str());
+ ServerInstance->SNO->WriteToSnoMask('C',"Client connecting at %s: %s!%s@%s (%s) [%s]", _new->server.c_str(), _new->nick.c_str(), _new->ident.c_str(), _new->host.c_str(), _new->GetIPString(), _new->fullname.c_str());
FOREACH_MOD(I_OnPostConnect,OnPostConnect(_new));
diff --git a/src/modules/m_spanningtree/utils.cpp b/src/modules/m_spanningtree/utils.cpp
index ec9d5aacc..75d4eaca3 100644
--- a/src/modules/m_spanningtree/utils.cpp
+++ b/src/modules/m_spanningtree/utils.cpp
@@ -319,17 +319,9 @@ void SpanningTreeUtilities::RefreshIPCache()
for (std::vector<reference<Link> >::iterator i = LinkBlocks.begin(); i != LinkBlocks.end(); ++i)
{
Link* L = *i;
- if (L->IPAddr.empty() || L->RecvPass.empty() || L->SendPass.empty() || L->Name.empty() || !L->Port)
+ if (!L->Port)
{
- if (L->Name.empty())
- {
- ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"m_spanningtree: Ignoring a malformed link block (all link blocks require a name!)");
- }
- else
- {
- ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"m_spanningtree: Ignoring a link block missing recvpass, sendpass, port or ipaddr.");
- }
-
+ ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"m_spanningtree: Ignoring a link block without a port.");
/* Invalid link block */
continue;
}
@@ -339,7 +331,7 @@ void SpanningTreeUtilities::RefreshIPCache()
irc::sockets::sockaddrs dummy;
bool ipvalid = irc::sockets::aptosa(L->IPAddr, L->Port, dummy);
- if (ipvalid)
+ if ((L->IPAddr == "*") || (ipvalid))
ValidIPs.push_back(L->IPAddr);
else
{
@@ -377,7 +369,6 @@ void SpanningTreeUtilities::ReadConfiguration()
AutoconnectBlocks.clear();
LinkBlocks.clear();
- ValidIPs.clear();
ConfigTagList tags = ServerInstance->Config->ConfTags("link");
for(ConfigIter i = tags.first; i != tags.second; ++i)
{
@@ -396,55 +387,37 @@ void SpanningTreeUtilities::ReadConfiguration()
L->Bind = tag->getString("bind");
L->Hidden = tag->getBool("hidden");
+ if (L->Name.empty())
+ throw ModuleException("Invalid configuration, found a link tag without a name!" + (!L->IPAddr.empty() ? " IP address: "+L->IPAddr : ""));
+
if (L->Name.find('.') == std::string::npos)
- throw CoreException("The link name '"+assign(L->Name)+"' is invalid and must contain at least one '.' character");
+ throw ModuleException("The link name '"+assign(L->Name)+"' is invalid as it must contain at least one '.' character");
if (L->Name.length() > 64)
- throw CoreException("The link name '"+assign(L->Name)+"' is longer than 64 characters!");
+ throw ModuleException("The link name '"+assign(L->Name)+"' is invalid as it is longer than 64 characters");
- if (L->Fingerprint.find(':') != std::string::npos)
- {
- std::string tmp = L->Fingerprint;
- L->Fingerprint.clear();
- for(unsigned int j=0; j < tmp.length(); j++)
- if (tmp[j] != ':')
- L->Fingerprint.push_back(tmp[j]);
- }
+ if (L->RecvPass.empty())
+ throw ModuleException("Invalid configuration for server '"+assign(L->Name)+"', recvpass not defined");
- if ((!L->IPAddr.empty()) && (!L->RecvPass.empty()) && (!L->SendPass.empty()) && (!L->Name.empty()) && (L->Port))
- {
- ValidIPs.push_back(L->IPAddr);
- }
- else
- {
- if (L->IPAddr.empty())
- {
- L->IPAddr = "*";
- ValidIPs.push_back("*");
- ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"Configuration warning: Link block " + assign(L->Name) + " has no IP defined! This will allow any IP to connect as this server, and MAY not be what you want.");
- }
+ if (L->SendPass.empty())
+ throw ModuleException("Invalid configuration for server '"+assign(L->Name)+"', sendpass not defined");
- if (L->RecvPass.empty())
- {
- throw CoreException("Invalid configuration for server '"+assign(L->Name)+"', recvpass not defined!");
- }
+ if ((L->SendPass.find(' ') != std::string::npos) || (L->RecvPass.find(' ') != std::string::npos))
+ throw ModuleException("Link block '" + assign(L->Name) + "' has a password set that contains a space character which is invalid");
- if (L->SendPass.empty())
- {
- throw CoreException("Invalid configuration for server '"+assign(L->Name)+"', sendpass not defined!");
- }
+ if ((L->SendPass[0] == ':') || (L->RecvPass[0] == ':'))
+ throw ModuleException("Link block '" + assign(L->Name) + "' has a password set that begins with a colon (:) which is invalid");
- if (L->Name.empty())
- {
- throw CoreException("Invalid configuration, link tag without a name! IP address: "+L->IPAddr);
- }
-
- if (!L->Port)
- {
- ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"Configuration warning: Link block " + assign(L->Name) + " has no port defined, you will not be able to /connect it.");
- }
+ if (L->IPAddr.empty())
+ {
+ L->IPAddr = "*";
+ ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"Configuration warning: Link block '" + assign(L->Name) + "' has no IP defined! This will allow any IP to connect as this server, and MAY not be what you want.");
}
+ if (!L->Port)
+ ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"Configuration warning: Link block '" + assign(L->Name) + "' has no port defined, you will not be able to /connect it.");
+
+ L->Fingerprint.erase(std::remove(L->Fingerprint.begin(), L->Fingerprint.end(), ':'), L->Fingerprint.end());
LinkBlocks.push_back(L);
}
@@ -465,12 +438,12 @@ void SpanningTreeUtilities::ReadConfiguration()
if (A->Period <= 0)
{
- throw CoreException("Invalid configuration for autoconnect, period not a positive integer!");
+ throw ModuleException("Invalid configuration for autoconnect, period not a positive integer!");
}
if (A->servers.empty())
{
- throw CoreException("Invalid configuration for autoconnect, server cannot be empty!");
+ throw ModuleException("Invalid configuration for autoconnect, server cannot be empty!");
}
AutoconnectBlocks.push_back(A);