summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2007-03-10 17:45:02 +0000
committerbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2007-03-10 17:45:02 +0000
commit78a1d269f8c5163fdcd88252b77176966e9e882f (patch)
tree8d44756566f663e92f343c27bb9615062fb18829
parent07ca4f5789bb54f9bfe0e24e68c5515d9708d9ee (diff)
HIGHLY EXPERIMENTAL: This needs heavy testing -- new FMODE behaviour:
(1) IF THEIRTS <= OURTS, ACCEPT MODE AND PASS ON (2) If THEIRTS > OURTS, drop the mode and DONT pass on. git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@6644 e03df62e-2008-0410-955e-edbf42e46eb7
-rw-r--r--src/modules/m_spanningtree/treesocket1.cpp259
1 files changed, 4 insertions, 255 deletions
diff --git a/src/modules/m_spanningtree/treesocket1.cpp b/src/modules/m_spanningtree/treesocket1.cpp
index ae972a37e..5f628a5e8 100644
--- a/src/modules/m_spanningtree/treesocket1.cpp
+++ b/src/modules/m_spanningtree/treesocket1.cpp
@@ -500,155 +500,10 @@ bool TreeSocket::ForceMode(const std::string &source, std::deque<std::string> &p
return true;
}
- /* TS is equal: Merge the mode changes, use voooodoooooo on modes
- * with parameters.
+ /* TS is equal or less: Merge the mode changes into ours and pass on.
*/
- if (TS == ourTS)
+ if (TS <= ourTS)
{
- ModeHandler* mh = NULL;
- unsigned long paramptr = 3;
- std::string to_bounce = "";
- std::string to_keep = "";
- std::vector<std::string> params_to_keep;
- std::string params_to_bounce = "";
- bool adding = true;
- char cur_change = 1;
- char old_change = 0;
- char old_bounce_change = 0;
- /* Merge modes, basically do special stuff to mode with params */
- for (std::string::iterator x = params[2].begin(); x != params[2].end(); x++)
- {
- switch (*x)
- {
- case '-':
- adding = false;
- break;
- case '+':
- adding = true;
- break;
- default:
- if (adding)
- {
- /* We only care about whats being set,
- * not whats being unset
- */
- mh = this->Instance->Modes->FindMode(*x, chan ? MODETYPE_CHANNEL : MODETYPE_USER);
- if ((mh) && (mh->GetNumParams(adding) > 0) && (!mh->IsListMode()))
- {
- /* We only want to do special things to
- * modes with parameters, we are going to rewrite
- * those parameters
- */
- ModePair ret;
- adding ? cur_change = '+' : cur_change = '-';
- ret = mh->ModeSet(smode ? NULL : who, dst, chan, params[paramptr]);
- /* The mode is set here, check which we should keep */
- if (ret.first)
- {
- bool which_to_keep = mh->CheckTimeStamp(TS, ourTS, params[paramptr], ret.second, chan);
- if (which_to_keep == true)
- {
- /* Keep ours, bounce theirs:
- * Send back ours to them and
- * drop their mode changs
- */
- adding ? cur_change = '+' : cur_change = '-';
- if (cur_change != old_bounce_change)
- to_bounce += cur_change;
- to_bounce += *x;
- old_bounce_change = cur_change;
- if ((mh->GetNumParams(adding) > 0) && (paramptr < params.size()))
- params_to_bounce.append(" ").append(ret.second);
- }
- else
- {
- /* Keep theirs: Accept their mode change,
- * do nothing else
- */
- adding ? cur_change = '+' : cur_change = '-';
- if (cur_change != old_change)
- to_keep += cur_change;
- to_keep += *x;
- old_change = cur_change;
- if ((mh->GetNumParams(adding) > 0) && (paramptr < params.size()))
- params_to_keep.push_back(params[paramptr]);
- }
- }
- else
- {
- /* Mode isnt set here, we want it */
- adding ? cur_change = '+' : cur_change = '-';
- if (cur_change != old_change)
- to_keep += cur_change;
- to_keep += *x;
- old_change = cur_change;
- if ((mh->GetNumParams(adding) > 0) && (paramptr < params.size()))
- params_to_keep.push_back(params[paramptr]);
- }
- paramptr++;
- }
- else
- {
- mh = this->Instance->Modes->FindMode(*x, chan ? MODETYPE_CHANNEL : MODETYPE_USER);
- if (mh)
- {
- adding ? cur_change = '+' : cur_change = '-';
-
- /* Just keep this, safe to merge with no checks
- * it has no parameters
- */
-
- if (cur_change != old_change)
- to_keep += cur_change;
- to_keep += *x;
- old_change = cur_change;
-
- if ((mh->GetNumParams(adding) > 0) && (paramptr < params.size()))
- {
- params_to_keep.push_back(params[paramptr++]);
- }
- }
- }
- }
- else
- {
- mh = this->Instance->Modes->FindMode(*x, chan ? MODETYPE_CHANNEL : MODETYPE_USER);
- if (mh)
- {
- /* Taking a mode away */
- adding ? cur_change = '+' : cur_change = '-';
- if (cur_change != old_change)
- to_keep += cur_change;
- to_keep += *x;
- old_change = cur_change;
- if ((mh->GetNumParams(adding) > 0) && (paramptr < params.size()))
- params_to_keep.push_back(params[paramptr++]);
- }
- }
- break;
- }
- }
- if (to_bounce.length())
- {
- std::deque<std::string> newparams;
- newparams.push_back(params[0]);
- newparams.push_back(ConvToStr(ourTS));
- newparams.push_back(to_bounce+params_to_bounce);
- Utils->DoOneToOne(this->Instance->Config->ServerName,"FMODE",newparams,sourceserv);
- }
- if (to_keep.length())
- {
- unsigned int n = 2;
- unsigned int q = 0;
- modelist[0] = params[0].c_str();
- modelist[1] = to_keep.c_str();
- if (params_to_keep.size() > 0)
- {
- for (q = 0; (q < params_to_keep.size()) && (q < 64); q++)
- {
- modelist[n++] = params_to_keep[q].c_str();
- }
- }
if (smode)
{
this->Instance->SendMode(modelist, n, who);
@@ -661,115 +516,9 @@ bool TreeSocket::ForceMode(const std::string &source, std::deque<std::string> &p
Utils->DoOneToAllButSender(source,"FMODE",params,sourceserv);
}
}
- else
- /* U-lined servers always win regardless of their TS */
- if (TS > ourTS)
- {
- /* Bounce the mode back to its sender.* We use our lower TS, so the other end
- * SHOULD accept it, if its clock is right.
- *
- * NOTE: We should check that we arent bouncing anything thats already set at this end.
- * If we are, bounce +ourmode to 'reinforce' it. This prevents desyncs.
- * e.g. They send +l 50, we have +l 10 set. rather than bounce -l 50, we bounce +l 10.
- *
- * Thanks to jilles for pointing out this one-hell-of-an-issue before i even finished
- * writing the code. It took me a while to come up with this solution.
- *
- * XXX: BE SURE YOU UNDERSTAND THIS CODE FULLY BEFORE YOU MESS WITH IT.
- */
- std::deque<std::string> newparams; /* New parameter list we send back */
- newparams.push_back(params[0]); /* Target, user or channel */
- newparams.push_back(ConvToStr(ourTS)); /* Timestamp value of the target */
- newparams.push_back(""); /* This contains the mode string. For now
- * it's empty, we fill it below.
- */
- /* Intelligent mode bouncing. Don't just invert, reinforce any modes which are already
- * set to avoid a desync here.
- */
- std::string modebounce = "";
- bool adding = true;
- unsigned int t = 3;
- ModeHandler* mh = NULL;
- char cur_change = 1;
- char old_change = 0;
- for (std::string::iterator x = params[2].begin(); x != params[2].end(); x++)
- {
- /* Iterate over all mode chars in the sent set */
- switch (*x)
- {
- /* Adding or subtracting modes? */
- case '-':
- adding = false;
- break;
- case '+':
- adding = true;
- break;
- default:
- /* Find the mode handler for this mode */
- mh = this->Instance->Modes->FindMode(*x, chan ? MODETYPE_CHANNEL : MODETYPE_USER);
- /* Got a mode handler?
- * This also prevents us bouncing modes we have no handler for.
- */
- if (mh)
- {
- ModePair ret;
- std::string p = "";
- /* Does the mode require a parameter right now?
- * If it does, fetch it if we can
- */
- if ((mh->GetNumParams(adding) > 0) && (t < params.size()))
- p = params[t++];
- /* Call the ModeSet method to determine if its set with the
- * given parameter here or not.
- */
- ret = mh->ModeSet(smode ? NULL : who, dst, chan, p);
- /* XXX: Really. Dont ask.
- * Determine from if its set combined with what the current
- * 'state' is (adding or not) as to wether we should 'invert'
- * or 'reinforce' the mode change
- */
- (!ret.first ? (adding ? cur_change = '-' : cur_change = '+') : (!adding ? cur_change = '-' : cur_change = '+'));
- /* Quickly determine if we have 'flipped' from + to -,
- * or - to +, to prevent unneccessary +/- chars in the
- * output string that waste bandwidth
- */
- if (cur_change != old_change)
- modebounce += cur_change;
- old_change = cur_change;
- /* Add the mode character to the output string */
- modebounce += mh->GetModeChar();
- /* We got a parameter back from ModeHandler::ModeSet,
- * are we supposed to be sending one out right now?
- */
- if (ret.second.length())
- {
- if (mh->GetNumParams(cur_change == '+') > 0)
- /* Yes we're supposed to be sending out
- * the parameter. Make sure it goes
- */
- newparams.push_back(ret.second);
- }
- }
- break;
- }
- }
+ /* If the TS is greater than ours, we drop the mode and dont pass it anywhere.
+ */
- /* Update the parameters for FMODE with the new 'bounced' string */
- newparams[2] = modebounce;
- /* Only send it back the way it came, no need to send it anywhere else */
- Utils->DoOneToOne(this->Instance->Config->ServerName,"FMODE",newparams,sourceserv);
- }
- else
- {
- /* Allow the mode, route it to either server or user command handling */
- if (smode)
- this->Instance->SendMode(modelist,n,who);
- else
- this->Instance->CallCommandHandler("MODE", modelist, n, who);
- /* HOT POTATO! PASS IT ON! */
- Utils->DoOneToAllButSender(source,"FMODE",params,sourceserv);
- }
- /* Are we supposed to free the userrec? */
if (smode)
DELETE(who);