summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/modules.h3
-rw-r--r--src/modules/m_spanningtree/capab.cpp66
-rw-r--r--src/modules/m_spanningtree/treesocket.h8
-rw-r--r--src/modules/m_spanningtree/treesocket1.cpp1
4 files changed, 65 insertions, 13 deletions
diff --git a/include/modules.h b/include/modules.h
index e67f287c8..3f36f23da 100644
--- a/include/modules.h
+++ b/include/modules.h
@@ -50,7 +50,8 @@ enum ModuleFlags {
VF_STATIC = 1, // module is static, cannot be /unloadmodule'd
VF_VENDOR = 2, // module is a vendor module (came in the original tarball, not 3rd party)
VF_SERVICEPROVIDER = 4, // module provides a service to other modules (can be a dependency)
- VF_COMMON = 8 // module needs to be common on all servers in a network to link
+ VF_COMMON = 8, // module needs to be common on all servers in a network to link
+ VF_OPTCOMMON = 16 // module should be common on all servers for unsurprising behavior
};
/** Used with SendToMode()
diff --git a/src/modules/m_spanningtree/capab.cpp b/src/modules/m_spanningtree/capab.cpp
index a1980790f..cd8564892 100644
--- a/src/modules/m_spanningtree/capab.cpp
+++ b/src/modules/m_spanningtree/capab.cpp
@@ -22,9 +22,9 @@
/* $ModDep: m_spanningtree/utils.h m_spanningtree/treeserver.h m_spanningtree/treesocket.h */
-std::string TreeSocket::MyCapabilities()
+std::string TreeSocket::MyModules(int filter)
{
- std::vector<std::string> modlist = this->ServerInstance->Modules->GetAllModuleNames(VF_COMMON);
+ std::vector<std::string> modlist = this->ServerInstance->Modules->GetAllModuleNames(filter);
std::string capabilities;
sort(modlist.begin(),modlist.end());
for (unsigned int i = 0; i < modlist.size(); i++)
@@ -42,7 +42,8 @@ void TreeSocket::SendCapabilities()
return;
sentcapab = true;
- irc::commasepstream modulelist(MyCapabilities());
+ irc::commasepstream modulelist(MyModules(VF_COMMON));
+ irc::commasepstream optmodulelist(MyModules(VF_OPTCOMMON));
this->WriteLine("CAPAB START");
/* Send module names, split at 509 length */
@@ -64,6 +65,24 @@ void TreeSocket::SendCapabilities()
if (line != "CAPAB MODULES ")
this->WriteLine(line);
+ line = "CAPAB MODSUPPORT ";
+ while (optmodulelist.GetToken(item))
+ {
+ if (line.length() + item.length() + 1 > 509)
+ {
+ this->WriteLine(line);
+ line = "CAPAB MODSUPPORT ";
+ }
+
+ if (line != "CAPAB MODSUPPORT ")
+ line.append(",");
+
+ line.append(item);
+ }
+ if (line != "CAPAB MODSUPPORT ")
+ this->WriteLine(line);
+
+
int ip6 = 0;
#ifdef IPV6
ip6 = 1;
@@ -138,17 +157,18 @@ bool TreeSocket::Capab(const parameterlist &params)
}
if (params[0] == "START")
{
- this->ModuleList.clear();
- this->CapKeys.clear();
+ ModuleList.clear();
+ OptModuleList.clear();
+ CapKeys.clear();
}
else if (params[0] == "END")
{
std::string reason;
/* Compare ModuleList and check CapKeys */
- if ((this->ModuleList != this->MyCapabilities()) && (this->ModuleList.length()))
+ if ((this->ModuleList != this->MyModules(VF_COMMON)) && (this->ModuleList.length()))
{
- std::string diffIneed = ListDifference(this->ModuleList, this->MyCapabilities());
- std::string diffUneed = ListDifference(this->MyCapabilities(), this->ModuleList);
+ std::string diffIneed = ListDifference(this->ModuleList, this->MyModules(VF_COMMON));
+ std::string diffUneed = ListDifference(this->MyModules(VF_COMMON), this->ModuleList);
if (diffIneed.length() == 0 && diffUneed.length() == 0)
{
reason = "Module list in CAPAB is not alphabetically ordered, cannot compare lists.";
@@ -164,6 +184,23 @@ bool TreeSocket::Capab(const parameterlist &params)
this->SendError("CAPAB negotiation failed: "+reason);
return false;
}
+ if (this->OptModuleList != this->MyModules(VF_OPTCOMMON) && this->OptModuleList.length())
+ {
+ std::string diffIneed = ListDifference(this->OptModuleList, this->MyModules(VF_OPTCOMMON));
+ std::string diffUneed = ListDifference(this->MyModules(VF_OPTCOMMON), this->OptModuleList);
+ if (diffIneed.length() == 0 && diffUneed.length() == 0)
+ {
+ reason = "Optional Module list in CAPAB is not alphabetically ordered, cannot compare lists.";
+ }
+ else
+ {
+ ServerInstance->SNO->WriteToSnoMask('l',
+ "Optional module lists do not match, some commands may not work globally.%s%s%s%s",
+ diffIneed.length() ? " Not loaded here:" : "", diffIneed.c_str(),
+ diffUneed.length() ? " Not loaded there:" : "", diffUneed.c_str());
+ }
+ }
+
if (this->CapKeys.find("PROTOCOL") == this->CapKeys.end())
{
reason = "Protocol version not specified";
@@ -230,7 +267,18 @@ bool TreeSocket::Capab(const parameterlist &params)
this->ModuleList.append(params[1]);
}
}
-
+ else if ((params[0] == "MODSUPPORT") && (params.size() == 2))
+ {
+ if (!this->OptModuleList.length())
+ {
+ this->OptModuleList.append(params[1]);
+ }
+ else
+ {
+ this->OptModuleList.append(",");
+ this->OptModuleList.append(params[1]);
+ }
+ }
else if ((params[0] == "CAPABILITIES") && (params.size() == 2))
{
irc::tokenstream capabs(params[1]);
diff --git a/src/modules/m_spanningtree/treesocket.h b/src/modules/m_spanningtree/treesocket.h
index 3c736b341..1350950eb 100644
--- a/src/modules/m_spanningtree/treesocket.h
+++ b/src/modules/m_spanningtree/treesocket.h
@@ -82,7 +82,8 @@ class TreeSocket : public BufferedSocket
int num_lost_servers; /* Servers lost in split */
time_t NextPing; /* Time when we are due to ping this server */
bool LastPingWasGood; /* Responded to last ping we sent? */
- std::string ModuleList; /* Module list of other server from CAPAB */
+ std::string ModuleList; /* Required module list of other server from CAPAB */
+ std::string OptModuleList; /* Optional module list of other server from CAPAB */
std::map<std::string,std::string> CapKeys; /* CAPAB keys from other server */
Module* Hook; /* I/O hooking module that we're attached to for this socket */
std::string ourchallenge; /* Challenge sent for challenge/response */
@@ -185,9 +186,10 @@ class TreeSocket : public BufferedSocket
*/
void SendServers(TreeServer* Current, TreeServer* s, int hops);
- /** Returns my capabilities as a string
+ /** Returns module list as a string, filtered by filter
+ * @param filter a module version bitmask, such as VF_COMMON or VF_OPTCOMMON
*/
- std::string MyCapabilities();
+ std::string MyModules(int filter);
/** Send my capabilities to the remote side
*/
diff --git a/src/modules/m_spanningtree/treesocket1.cpp b/src/modules/m_spanningtree/treesocket1.cpp
index 9706271bf..e77e6717e 100644
--- a/src/modules/m_spanningtree/treesocket1.cpp
+++ b/src/modules/m_spanningtree/treesocket1.cpp
@@ -88,6 +88,7 @@ Module* TreeSocket::GetHook()
void TreeSocket::CleanNegotiationInfo()
{
ModuleList.clear();
+ OptModuleList.clear();
CapKeys.clear();
ourchallenge.clear();
theirchallenge.clear();