summaryrefslogtreecommitdiff
path: root/src/modules
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules')
-rw-r--r--src/modules/extra/m_geoip.cpp63
-rw-r--r--src/modules/m_cap.h9
-rw-r--r--src/modules/m_check.cpp4
-rw-r--r--src/modules/m_dnsbl.cpp22
-rw-r--r--src/modules/m_ircv3.cpp214
-rw-r--r--src/modules/m_namesx.cpp39
-rw-r--r--src/modules/m_services_account.cpp4
-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
-rw-r--r--src/modules/m_stripcolor.cpp2
16 files changed, 421 insertions, 121 deletions
diff --git a/src/modules/extra/m_geoip.cpp b/src/modules/extra/m_geoip.cpp
index 939752875..cf87de51e 100644
--- a/src/modules/extra/m_geoip.cpp
+++ b/src/modules/extra/m_geoip.cpp
@@ -35,6 +35,16 @@ class ModuleGeoIP : public Module
LocalStringExt ext;
GeoIP* gi;
+ void SetExt(LocalUser* user)
+ {
+ const char* c = GeoIP_country_code_by_addr(gi, user->GetIPString());
+ if (!c)
+ c = "UNK";
+
+ std::string* cc = new std::string(c);
+ ext.set(user, cc);
+ }
+
public:
ModuleGeoIP() : ext("geoip_cc", this), gi(NULL)
{
@@ -47,13 +57,23 @@ class ModuleGeoIP : public Module
throw ModuleException("Unable to initialize geoip, are you missing GeoIP.dat?");
ServerInstance->Modules->AddService(ext);
- Implementation eventlist[] = { I_OnSetConnectClass };
- ServerInstance->Modules->Attach(eventlist, this, 1);
+ Implementation eventlist[] = { I_OnSetConnectClass, I_OnStats };
+ ServerInstance->Modules->Attach(eventlist, this, 2);
+
+ for (std::vector<LocalUser*>::const_iterator i = ServerInstance->Users->local_users.begin(); i != ServerInstance->Users->local_users.end(); ++i)
+ {
+ LocalUser* user = *i;
+ if ((user->registered == REG_ALL) && (!ext.get(user)))
+ {
+ SetExt(user);
+ }
+ }
}
~ModuleGeoIP()
{
- GeoIP_delete(gi);
+ if (gi)
+ GeoIP_delete(gi);
}
Version GetVersion()
@@ -65,13 +85,8 @@ class ModuleGeoIP : public Module
{
std::string* cc = ext.get(user);
if (!cc)
- {
- const char* c = GeoIP_country_code_by_addr(gi, user->GetIPString());
- if (!c)
- c = "UNK";
- cc = new std::string(c);
- ext.set(user, cc);
- }
+ SetExt(user);
+
std::string geoip = myclass->config->getString("geoip");
if (geoip.empty())
return MOD_RES_PASSTHRU;
@@ -82,6 +97,34 @@ class ModuleGeoIP : public Module
return MOD_RES_PASSTHRU;
return MOD_RES_DENY;
}
+
+ ModResult OnStats(char symbol, User* user, string_list &out)
+ {
+ if (symbol != 'G')
+ return MOD_RES_PASSTHRU;
+
+ unsigned int unknown = 0;
+ std::map<std::string, unsigned int> results;
+ for (std::vector<LocalUser*>::const_iterator i = ServerInstance->Users->local_users.begin(); i != ServerInstance->Users->local_users.end(); ++i)
+ {
+ std::string* cc = ext.get(*i);
+ if (cc)
+ results[*cc]++;
+ else
+ unknown++;
+ }
+
+ std::string p = ServerInstance->Config->ServerName + " 801 " + user->nick + " :GeoIPSTATS ";
+ for (std::map<std::string, unsigned int>::const_iterator i = results.begin(); i != results.end(); ++i)
+ {
+ out.push_back(p + i->first + " " + ConvToStr(i->second));
+ }
+
+ if (unknown)
+ out.push_back(p + "Unknown " + ConvToStr(unknown));
+
+ return MOD_RES_DENY;
+ }
};
MODULE_INIT(ModuleGeoIP)
diff --git a/src/modules/m_cap.h b/src/modules/m_cap.h
index 0fc782b97..604fdb0ef 100644
--- a/src/modules/m_cap.h
+++ b/src/modules/m_cap.h
@@ -59,19 +59,16 @@ class GenericCap
ext.set(data->user, 1);
}
}
-
- if (ev.id == "cap_ls")
+ else if (ev.id == "cap_ls")
{
data->wanted.push_back(cap);
}
-
- if (ev.id == "cap_list")
+ else if (ev.id == "cap_list")
{
if (ext.get(data->user))
data->wanted.push_back(cap);
}
-
- if (ev.id == "cap_clear")
+ else if (ev.id == "cap_clear")
{
data->ack.push_back("-" + cap);
ext.set(data->user, 0);
diff --git a/src/modules/m_check.cpp b/src/modules/m_check.cpp
index 8316b09fe..099661de7 100644
--- a/src/modules/m_check.cpp
+++ b/src/modules/m_check.cpp
@@ -225,13 +225,13 @@ class CommandCheck : public Command
if (InspIRCd::Match(a->second->host, parameters[0], ascii_case_insensitive_map) || InspIRCd::Match(a->second->dhost, parameters[0], ascii_case_insensitive_map))
{
/* host or vhost matches mask */
- user->SendText(checkstr + " match " + ConvToStr(++x) + " " + a->second->GetFullRealHost());
+ user->SendText(checkstr + " match " + ConvToStr(++x) + " " + a->second->GetFullRealHost() + " " + a->second->GetIPString() + " " + a->second->fullname);
}
/* IP address */
else if (InspIRCd::MatchCIDR(a->second->GetIPString(), parameters[0]))
{
/* same IP. */
- user->SendText(checkstr + " match " + ConvToStr(++x) + " " + a->second->GetFullRealHost());
+ user->SendText(checkstr + " match " + ConvToStr(++x) + " " + a->second->GetFullRealHost() + " " + a->second->GetIPString() + " " + a->second->fullname);
}
}
diff --git a/src/modules/m_dnsbl.cpp b/src/modules/m_dnsbl.cpp
index 2160b02dc..6a41c484f 100644
--- a/src/modules/m_dnsbl.cpp
+++ b/src/modules/m_dnsbl.cpp
@@ -243,7 +243,7 @@ class ModuleDNSBL : public Module
ReadConf();
ServerInstance->Modules->AddService(nameExt);
ServerInstance->Modules->AddService(countExt);
- Implementation eventlist[] = { I_OnRehash, I_OnUserInit, I_OnStats, I_OnSetConnectClass, I_OnCheckReady };
+ Implementation eventlist[] = { I_OnRehash, I_OnSetClientIP, I_OnStats, I_OnSetConnectClass, I_OnCheckReady };
ServerInstance->Modules->Attach(eventlist, this, 5);
}
@@ -348,22 +348,24 @@ class ModuleDNSBL : public Module
ReadConf();
}
- void OnUserInit(LocalUser* user)
+ void OnSetClientIP(User* user)
{
- if (user->exempt)
+ LocalUser *luser = IS_LOCAL(user);
+
+ if (!luser || luser->exempt)
return;
unsigned char a, b, c, d;
char reversedipbuf[128];
std::string reversedip;
- if (user->client_sa.sa.sa_family != AF_INET)
+ if (luser->client_sa.sa.sa_family != AF_INET)
return;
- d = (unsigned char) (user->client_sa.in4.sin_addr.s_addr >> 24) & 0xFF;
- c = (unsigned char) (user->client_sa.in4.sin_addr.s_addr >> 16) & 0xFF;
- b = (unsigned char) (user->client_sa.in4.sin_addr.s_addr >> 8) & 0xFF;
- a = (unsigned char) user->client_sa.in4.sin_addr.s_addr & 0xFF;
+ d = (unsigned char) (luser->client_sa.in4.sin_addr.s_addr >> 24) & 0xFF;
+ c = (unsigned char) (luser->client_sa.in4.sin_addr.s_addr >> 16) & 0xFF;
+ b = (unsigned char) (luser->client_sa.in4.sin_addr.s_addr >> 8) & 0xFF;
+ a = (unsigned char) luser->client_sa.in4.sin_addr.s_addr & 0xFF;
snprintf(reversedipbuf, 128, "%d.%d.%d.%d", d, c, b, a);
reversedip = std::string(reversedipbuf);
@@ -377,11 +379,11 @@ class ModuleDNSBL : public Module
/* now we'd need to fire off lookups for `hostname'. */
bool cached;
- DNSBLResolver *r = new DNSBLResolver(this, nameExt, countExt, hostname, user, DNSBLConfEntries[i], cached);
+ DNSBLResolver *r = new DNSBLResolver(this, nameExt, countExt, hostname, luser, DNSBLConfEntries[i], cached);
ServerInstance->AddResolver(r, cached);
i++;
}
- countExt.set(user, i);
+ countExt.set(luser, i);
}
ModResult OnSetConnectClass(LocalUser* user, ConnectClass* myclass)
diff --git a/src/modules/m_ircv3.cpp b/src/modules/m_ircv3.cpp
new file mode 100644
index 000000000..fe400fa80
--- /dev/null
+++ b/src/modules/m_ircv3.cpp
@@ -0,0 +1,214 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ * Copyright (C) 2012 Attila Molnar <attilamolnar@hush.com>
+ *
+ * This file is part of InspIRCd. InspIRCd is free software: you can
+ * redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* $ModDesc: Provides support for extended-join, away-notify and account-notify CAP capabilities */
+
+#include "inspircd.h"
+#include "account.h"
+#include "m_cap.h"
+
+class ModuleIRCv3 : public Module
+{
+ GenericCap cap_accountnotify;
+ GenericCap cap_awaynotify;
+ GenericCap cap_extendedjoin;
+ bool accountnotify;
+ bool awaynotify;
+ bool extendedjoin;
+
+ void WriteNeighboursWithExt(User* user, const std::string& line, const LocalIntExt& ext)
+ {
+ UserChanList chans(user->chans);
+
+ std::map<User*, bool> exceptions;
+ FOREACH_MOD(I_OnBuildNeighborList, OnBuildNeighborList(user, chans, exceptions));
+
+ // Send it to all local users who were explicitly marked as neighbours by modules and have the required ext
+ for (std::map<User*, bool>::const_iterator i = exceptions.begin(); i != exceptions.end(); ++i)
+ {
+ LocalUser* u = IS_LOCAL(i->first);
+ if ((u) && (i->second) && (ext.get(u)))
+ u->Write(line);
+ }
+
+ // Now consider sending it to all other users who has at least a common channel with the user
+ std::set<User*> already_sent;
+ for (UCListIter i = chans.begin(); i != chans.end(); ++i)
+ {
+ const UserMembList* userlist = (*i)->GetUsers();
+ for (UserMembList::const_iterator m = userlist->begin(); m != userlist->end(); ++m)
+ {
+ /*
+ * Send the line if the channel member in question meets all of the following criteria:
+ * - local
+ * - not the user who is doing the action (i.e. whose channels we're iterating)
+ * - has the given extension
+ * - not on the except list built by modules
+ * - we haven't sent the line to the member yet
+ *
+ */
+ LocalUser* member = IS_LOCAL(m->first);
+ if ((member) && (member != user) && (ext.get(member)) && (exceptions.find(member) == exceptions.end()) && (already_sent.insert(member).second))
+ member->Write(line);
+ }
+ }
+ }
+
+ public:
+ ModuleIRCv3() : cap_accountnotify(this, "account-notify"),
+ cap_awaynotify(this, "away-notify"),
+ cap_extendedjoin(this, "extended-join")
+ {
+ OnRehash(NULL);
+ Implementation eventlist[] = { I_OnUserJoin, I_OnSetAway, I_OnEvent };
+ ServerInstance->Modules->Attach(eventlist, this, 3);
+ }
+
+ void OnRehash(User* user)
+ {
+ ConfigTag* conf = ServerInstance->Config->ConfValue("ircv3");
+ accountnotify = conf->getBool("accoutnotify", true);
+ awaynotify = conf->getBool("awaynotify", true);
+ extendedjoin = conf->getBool("extendedjoin", true);
+ }
+
+ void OnEvent(Event& ev)
+ {
+ if (awaynotify)
+ cap_awaynotify.HandleEvent(ev);
+ if (extendedjoin)
+ cap_extendedjoin.HandleEvent(ev);
+
+ if (accountnotify)
+ {
+ cap_accountnotify.HandleEvent(ev);
+
+ if (ev.id == "account_login")
+ {
+ AccountEvent* ae = static_cast<AccountEvent*>(&ev);
+
+ // :nick!user@host ACCOUNT account
+ // or
+ // :nick!user@host ACCOUNT *
+ std::string line = ":" + ae->user->GetFullHost() + " ACCOUNT ";
+ if (ae->account.empty())
+ line += "*";
+ else
+ line += std::string(ae->account);
+
+ WriteNeighboursWithExt(ae->user, line, cap_accountnotify.ext);
+ }
+ }
+ }
+
+ void OnUserJoin(Membership* memb, bool sync, bool created, CUList& excepts)
+ {
+ if (!extendedjoin)
+ return;
+
+ /*
+ * Send extended joins to clients who have the extended-join capability.
+ * An extended join looks like this:
+ *
+ * :nick!user@host JOIN #chan account :realname
+ *
+ * account is the joining user's account if he's logged in, otherwise it's an asterisk (*).
+ */
+
+ std::string line;
+ std::string mode;
+
+ const UserMembList* userlist = memb->chan->GetUsers();
+ for (UserMembCIter it = userlist->begin(); it != userlist->end(); ++it)
+ {
+ // Send the extended join line if the current member is local, has the extended-join cap and isn't excepted
+ User* member = IS_LOCAL(it->first);
+ if ((member) && (cap_extendedjoin.ext.get(member)) && (excepts.find(member) == excepts.end()))
+ {
+ // Construct the lines we're going to send if we haven't constructed them already
+ if (line.empty())
+ {
+ bool has_account = false;
+ line = ":" + memb->user->GetFullHost() + " JOIN " + memb->chan->name + " ";
+ const AccountExtItem* accountext = GetAccountExtItem();
+ if (accountext)
+ {
+ std::string* accountname;
+ accountname = accountext->get(memb->user);
+ if (accountname)
+ {
+ line += *accountname;
+ has_account = true;
+ }
+ }
+
+ if (!has_account)
+ line += "*";
+
+ line += " :" + memb->user->fullname;
+
+ // If the joining user received privileges from another module then we must send them as well,
+ // since silencing the normal join means the MODE will be silenced as well
+ if (!memb->modes.empty())
+ {
+ const std::string& modefrom = ServerInstance->Config->CycleHostsFromUser ? memb->user->GetFullHost() : ServerInstance->Config->ServerName;
+ mode = ":" + modefrom + " MODE " + memb->chan->name + " +" + memb->modes;
+
+ for (unsigned int i = 0; i < memb->modes.length(); i++)
+ mode += " " + memb->user->nick;
+ }
+ }
+
+ // Write the JOIN and the MODE, if any
+ member->Write(line);
+ if ((!mode.empty()) && (member != memb->user))
+ member->Write(mode);
+
+ // Prevent the core from sending the JOIN and MODE to this user
+ excepts.insert(it->first);
+ }
+ }
+ }
+
+ ModResult OnSetAway(User* user, const std::string &awaymsg)
+ {
+ if (awaynotify)
+ {
+ // Going away: n!u@h AWAY :reason
+ // Back from away: n!u@h AWAY
+ std::string line = ":" + user->GetFullHost() + " AWAY";
+ if (!awaymsg.empty())
+ line += " :" + awaymsg;
+
+ WriteNeighboursWithExt(user, line, cap_awaynotify.ext);
+ }
+ return MOD_RES_PASSTHRU;
+ }
+
+ void Prioritize()
+ {
+ ServerInstance->Modules->SetPriority(this, I_OnUserJoin, PRIORITY_LAST);
+ }
+
+ Version GetVersion()
+ {
+ return Version("Provides support for extended-join, away-notify and account-notify CAP capabilities", VF_VENDOR);
+ }
+};
+
+MODULE_INIT(ModuleIRCv3)
diff --git a/src/modules/m_namesx.cpp b/src/modules/m_namesx.cpp
index 1ab824388..2603b0ce5 100644
--- a/src/modules/m_namesx.cpp
+++ b/src/modules/m_namesx.cpp
@@ -31,8 +31,8 @@ class ModuleNamesX : public Module
GenericCap cap;
ModuleNamesX() : cap(this, "multi-prefix")
{
- Implementation eventlist[] = { I_OnPreCommand, I_OnNamesListItem, I_On005Numeric, I_OnEvent };
- ServerInstance->Modules->Attach(eventlist, this, 4);
+ Implementation eventlist[] = { I_OnPreCommand, I_OnNamesListItem, I_On005Numeric, I_OnEvent, I_OnSendWhoLine };
+ ServerInstance->Modules->Attach(eventlist, this, 5);
}
@@ -81,6 +81,41 @@ class ModuleNamesX : public Module
prefixes = memb->chan->GetAllPrefixChars(memb->user);
}
+ void OnSendWhoLine(User* source, const std::vector<std::string>& params, User* user, std::string& line)
+ {
+ if (!cap.ext.get(source) || line.empty())
+ return;
+
+ std::string::size_type pos = line.find(':');
+ if (pos == std::string::npos || pos < 2)
+ return;
+ pos -= 2;
+ // Don't do anything if the user has no prefixes
+ if ((line[pos] == 'H') || (line[pos] == 'G') || (line[pos] == '*'))
+ return;
+
+ // 352 21DAAAAAB #chan ident localhost insp21.test 21DAAAAAB H@ :0 a
+ // a b pos
+ std::string::size_type a = 4 + source->nick.length() + 1;
+ std::string::size_type b = line.find(' ', a);
+ if (b == std::string::npos)
+ return;
+
+ // Try to find this channel
+ std::string channame = line.substr(a, b-a);
+ Channel* chan = ServerInstance->FindChan(channame.c_str());
+ if (!chan)
+ return;
+
+ // Don't do anything if the user has only one prefix
+ std::string prefixes = chan->GetAllPrefixChars(user);
+ if (prefixes.length() <= 1)
+ return;
+
+ line.erase(pos, 1);
+ line.insert(pos, prefixes);
+ }
+
void OnEvent(Event& ev)
{
cap.HandleEvent(ev);
diff --git a/src/modules/m_services_account.cpp b/src/modules/m_services_account.cpp
index 7f3c54907..cd34e955a 100644
--- a/src/modules/m_services_account.cpp
+++ b/src/modules/m_services_account.cpp
@@ -277,6 +277,10 @@ class ModuleServicesAccount : public Module
AccountEvent(this, dest, *account).Send();
}
+ else
+ {
+ AccountEvent(this, dest, "").Send();
+ }
}
}
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);
diff --git a/src/modules/m_stripcolor.cpp b/src/modules/m_stripcolor.cpp
index aab506fdc..cd4f35c4b 100644
--- a/src/modules/m_stripcolor.cpp
+++ b/src/modules/m_stripcolor.cpp
@@ -75,7 +75,7 @@ class ModuleStripColor : public Module
std::string::iterator i,safei;
for (i = sentence.begin(); i != sentence.end();)
{
- if ((*i == 3))
+ if (*i == 3)
seq = 1;
else if (seq && (( ((*i >= '0') && (*i <= '9')) || (*i == ',') ) ))
{