summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAttila Molnar <attilamolnar@hush.com>2014-04-16 13:20:39 +0200
committerAttila Molnar <attilamolnar@hush.com>2014-04-16 13:20:39 +0200
commit67e0e32b86885df705a92cdc971a6085c4a7c1ba (patch)
tree1f3ba6b2d1d4f240c287d8ff11d30e98561e7adb
parent3eb205218a321e454d873ae14e2e717ce9d64142 (diff)
m_spanningtree Add ServerCommand::ExtractTS() to convert string to raw TS
Throws a ProtocolException if the input is invalid
-rw-r--r--src/modules/m_spanningtree/fjoin.cpp8
-rw-r--r--src/modules/m_spanningtree/fmode.cpp8
-rw-r--r--src/modules/m_spanningtree/ftopic.cpp11
-rw-r--r--src/modules/m_spanningtree/ijoin.cpp8
-rw-r--r--src/modules/m_spanningtree/metadata.cpp5
-rw-r--r--src/modules/m_spanningtree/servercommand.cpp8
-rw-r--r--src/modules/m_spanningtree/servercommand.h9
-rw-r--r--src/modules/m_spanningtree/uid.cpp8
8 files changed, 25 insertions, 40 deletions
diff --git a/src/modules/m_spanningtree/fjoin.cpp b/src/modules/m_spanningtree/fjoin.cpp
index ec7932766..26c3413f9 100644
--- a/src/modules/m_spanningtree/fjoin.cpp
+++ b/src/modules/m_spanningtree/fjoin.cpp
@@ -69,13 +69,7 @@ CmdResult CommandFJoin::Handle(User* srcuser, std::vector<std::string>& params)
*
*/
- time_t TS = ConvToInt(params[1]);
- if (!TS)
- {
- ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "*** BUG? *** TS of 0 sent to FJOIN. Are some services authors smoking craq, or is it 1970 again?. Dropped.");
- ServerInstance->SNO->WriteToSnoMask('d', "WARNING: The server %s is sending FJOIN with a TS of zero. Total craq. Command was dropped.", srcuser->server->GetName().c_str());
- return CMD_INVALID;
- }
+ time_t TS = ServerCommand::ExtractTS(params[1]);
const std::string& channel = params[0];
Channel* chan = ServerInstance->FindChan(channel);
diff --git a/src/modules/m_spanningtree/fmode.cpp b/src/modules/m_spanningtree/fmode.cpp
index 5627b023b..036a94947 100644
--- a/src/modules/m_spanningtree/fmode.cpp
+++ b/src/modules/m_spanningtree/fmode.cpp
@@ -24,13 +24,7 @@
/** FMODE command - server mode with timestamp checks */
CmdResult CommandFMode::Handle(User* who, std::vector<std::string>& params)
{
- time_t TS = ConvToInt(params[1]);
- if (!TS)
- {
- ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "*** BUG? *** TS of 0 sent to FMODE. Are some services authors smoking craq, or is it 1970 again?. Dropping link.");
- ServerInstance->SNO->WriteToSnoMask('d', "WARNING: The server %s is sending FMODE with a TS of zero. Total craq, dropping link.", who->server->GetName().c_str());
- return CMD_INVALID;
- }
+ time_t TS = ServerCommand::ExtractTS(params[1]);
/* Extract the TS value of the object, either User or Channel */
time_t ourTS;
diff --git a/src/modules/m_spanningtree/ftopic.cpp b/src/modules/m_spanningtree/ftopic.cpp
index bd15489a2..3c76c928a 100644
--- a/src/modules/m_spanningtree/ftopic.cpp
+++ b/src/modules/m_spanningtree/ftopic.cpp
@@ -28,19 +28,12 @@ CmdResult CommandFTopic::Handle(User* user, std::vector<std::string>& params)
if (!c)
return CMD_FAILURE;
- time_t ChanTS = ConvToInt(params[1]);
- if (!ChanTS)
- return CMD_INVALID;
-
- if (c->age < ChanTS)
+ if (c->age < ServerCommand::ExtractTS(params[1]))
// Our channel TS is older, nothing to do
return CMD_FAILURE;
- time_t ts = ConvToInt(params[2]);
- if (!ts)
- return CMD_INVALID;
-
// Channel::topicset is initialized to 0 on channel creation, so their ts will always win if we never had a topic
+ time_t ts = ServerCommand::ExtractTS(params[2]);
if (ts < c->topicset)
return CMD_FAILURE;
diff --git a/src/modules/m_spanningtree/ijoin.cpp b/src/modules/m_spanningtree/ijoin.cpp
index 637321bcb..34bd44a9b 100644
--- a/src/modules/m_spanningtree/ijoin.cpp
+++ b/src/modules/m_spanningtree/ijoin.cpp
@@ -40,13 +40,7 @@ CmdResult CommandIJoin::HandleRemote(RemoteUser* user, std::vector<std::string>&
bool apply_modes;
if (params.size() > 1)
{
- time_t RemoteTS = ConvToInt(params[1]);
- if (!RemoteTS)
- {
- ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Invalid TS in IJOIN: " + params[1]);
- return CMD_INVALID;
- }
-
+ time_t RemoteTS = ServerCommand::ExtractTS(params[1]);
if (RemoteTS < chan->age)
throw ProtocolException("Attempted to lower TS via IJOIN. LocalTS=" + ConvToStr(chan->age));
apply_modes = ((params.size() > 2) && (RemoteTS == chan->age));
diff --git a/src/modules/m_spanningtree/metadata.cpp b/src/modules/m_spanningtree/metadata.cpp
index d151bc450..13ccabc35 100644
--- a/src/modules/m_spanningtree/metadata.cpp
+++ b/src/modules/m_spanningtree/metadata.cpp
@@ -41,10 +41,7 @@ CmdResult CommandMetadata::Handle(User* srcuser, std::vector<std::string>& param
if (!c)
return CMD_FAILURE;
- time_t ChanTS = ConvToInt(params[1]);
- if (!ChanTS)
- return CMD_INVALID;
-
+ time_t ChanTS = ServerCommand::ExtractTS(params[1]);
if (c->age < ChanTS)
// Their TS is newer than ours, discard this command and do not propagate
return CMD_FAILURE;
diff --git a/src/modules/m_spanningtree/servercommand.cpp b/src/modules/m_spanningtree/servercommand.cpp
index 016788f51..3034eee7a 100644
--- a/src/modules/m_spanningtree/servercommand.cpp
+++ b/src/modules/m_spanningtree/servercommand.cpp
@@ -35,6 +35,14 @@ RouteDescriptor ServerCommand::GetRouting(User* user, const std::vector<std::str
return ROUTE_BROADCAST;
}
+time_t ServerCommand::ExtractTS(const std::string& tsstr)
+{
+ time_t TS = ConvToInt(tsstr);
+ if (!TS)
+ throw ProtocolException("Invalid TS");
+ return TS;
+}
+
ServerCommand* ServerCommandManager::GetHandler(const std::string& command) const
{
ServerCommandMap::const_iterator it = commands.find(command);
diff --git a/src/modules/m_spanningtree/servercommand.h b/src/modules/m_spanningtree/servercommand.h
index f99942079..524520a88 100644
--- a/src/modules/m_spanningtree/servercommand.h
+++ b/src/modules/m_spanningtree/servercommand.h
@@ -40,6 +40,15 @@ class ServerCommand : public CommandBase
virtual CmdResult Handle(User* user, std::vector<std::string>& parameters) = 0;
virtual RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters);
+
+ /**
+ * Extract the TS from a string.
+ * @param tsstr The string containing the TS.
+ * @return The raw timestamp value.
+ * This function throws a ProtocolException if it considers the TS invalid. Note that the detection of
+ * invalid timestamps is not designed to be bulletproof, only some cases - like "0" - trigger an exception.
+ */
+ static time_t ExtractTS(const std::string& tsstr);
};
/** Base class for server-to-server command handlers which are only valid if their source is a user.
diff --git a/src/modules/m_spanningtree/uid.cpp b/src/modules/m_spanningtree/uid.cpp
index 206f79a48..51f7026dd 100644
--- a/src/modules/m_spanningtree/uid.cpp
+++ b/src/modules/m_spanningtree/uid.cpp
@@ -31,8 +31,8 @@ CmdResult CommandUID::HandleServer(TreeServer* remoteserver, std::vector<std::st
* 0 1 2 3 4 5 6 7 8 9 (n-1)
* UID uuid age nick host dhost ident ip.string signon +modes (modepara) :gecos
*/
- time_t age_t = ConvToInt(params[1]);
- time_t signon = ConvToInt(params[7]);
+ time_t age_t = ServerCommand::ExtractTS(params[1]);
+ time_t signon = ServerCommand::ExtractTS(params[7]);
std::string empty;
const std::string& modestr = params[8];
@@ -40,10 +40,6 @@ CmdResult CommandUID::HandleServer(TreeServer* remoteserver, std::vector<std::st
if (params[0].length() != UIDGenerator::UUID_LENGTH || params[0].substr(0, 3) != remoteserver->GetID())
throw ProtocolException("Bogus UUID");
/* Check parameters for validity before introducing the client, discovered by dmb */
- if (!age_t)
- return CMD_INVALID;
- if (!signon)
- return CMD_INVALID;
if (modestr[0] != '+')
throw ProtocolException("Invalid mode string");