]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_spanningtree/treesocket1.cpp
Fix typo
[user/henk/code/inspircd.git] / src / modules / m_spanningtree / treesocket1.cpp
index 31564b017d8488c389532d4e8f3faed404e324ab..d5aeb223c1b37e6e105d71bf5d55c7d0a58a81f2 100644 (file)
@@ -35,8 +35,8 @@ TreeSocket::TreeSocket(SpanningTreeUtilities* Util, InspIRCd* SI, std::string ho
                InspSocketHookRequest(this, (Module*)Utils->Creator, Hook).Send();
 }
 
-TreeSocket::TreeSocket(SpanningTreeUtilities* Util, InspIRCd* SI, std::string host, int port, bool listening, unsigned long maxtime, std::string ServerName, Module* HookMod)
-       : InspSocket(SI, host, port, listening, maxtime), Utils(Util), Hook(HookMod)
+TreeSocket::TreeSocket(SpanningTreeUtilities* Util, InspIRCd* SI, std::string host, int port, bool listening, unsigned long maxtime, const std::string &ServerName, const std::string &bindto, Module* HookMod)
+       : InspSocket(SI, host, port, listening, maxtime, bindto), Utils(Util), Hook(HookMod)
 {
        myhost = ServerName;
        this->LinkState = CONNECTING;
@@ -500,283 +500,24 @@ 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)
-       {
-               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);
-                       }
-                       else
-                       {
-                               this->Instance->CallCommandHandler("MODE", modelist, n, who);
-                       }
-                       /* HOT POTATO! PASS IT ON! */
-                       Utils->DoOneToAllButSender(source,"FMODE",params,sourceserv);
-               }
-       }
-       else
-       /* U-lined servers always win regardless of their TS */
-       if ((TS > ourTS) && (!this->Instance->ULine(source.c_str())))
-       {
-               /* 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;
-                       }
-               }
-
-               /* 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
+       if (TS <= ourTS)
        {
-               /* The server was ulined, but something iffy is up with the TS.
-                * Sound the alarm bells!
-                */
-               if ((this->Instance->ULine(sourceserv.c_str())) && (TS > ourTS))
+               if (smode)
                {
-                       this->Instance->WriteOpers("\2WARNING!\2 U-Lined server '%s' has bad TS for '%s' (accepted change): \2SYNC YOUR CLOCKS\2 to avoid this notice",sourceserv.c_str(),params[0].c_str());
+                       this->Instance->SendMode(modelist, n, who);
                }
-               /* 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 the TS is greater than ours, we drop the mode and dont pass it anywhere.
+        */
+
        if (smode)
                DELETE(who);
 
@@ -797,7 +538,7 @@ bool TreeSocket::ForceTopic(const std::string &source, std::deque<std::string> &
                {
                        std::string oldtopic = c->topic;
                        strlcpy(c->topic,params[3].c_str(),MAXTOPIC);
-                       strlcpy(c->setby,params[2].c_str(),NICKMAX-1);
+                       strlcpy(c->setby,params[2].c_str(),127);
                        c->topicset = ts;
                        /* if the topic text is the same as the current topic,
                         * dont bother to send the TOPIC command out, just silently
@@ -981,12 +722,6 @@ bool TreeSocket::ForceJoin(const std::string &source, std::deque<std::string> &p
                        who = this->Instance->FindNick(usr);
                        if (who)
                        {
-                               /* Did they get any modes? How many times? */
-                               strlcat(modestring, nm, MAXBUF);
-                               for (int k = 0; k < ntimes; k++)
-                                       mode_users[modectr++] = strdup(usr);
-                               /* Free temporary buffer used for mode sequence */
-                               delete[] nm;
                                /* Check that the user's 'direction' is correct
                                 * based on the server sending the FJOIN. We must
                                 * check each nickname in turn, because the origin of
@@ -997,8 +732,23 @@ bool TreeSocket::ForceJoin(const std::string &source, std::deque<std::string> &p
                                if ((!route_back_again) || (route_back_again->GetSocket() != this))
                                {
                                        /* Oh dear oh dear. */
+                                       delete[] nm;
                                        continue;
                                }
+
+                               /* NOTE: Moved this below the fake direction check, so that modes
+                                * arent put into the mode list for users that were collided, and
+                                * may reconnect from the other side or our side before the split
+                                * is completed!
+                                */
+
+                               /* Did they get any modes? How many times? */
+                               strlcat(modestring, nm, MAXBUF);
+                               for (int k = 0; k < ntimes; k++)
+                                       mode_users[modectr++] = strdup(usr);
+                               /* Free temporary buffer used for mode sequence */
+                               delete[] nm;
+
                                /* Finally, we can actually place the user into the channel.
                                 * We're sure its right. Final answer, phone a friend.
                                 */
@@ -1054,7 +804,7 @@ bool TreeSocket::ForceJoin(const std::string &source, std::deque<std::string> &p
                                 * in case somehow we're desynched, so that other users which might be able to see
                                 * the nickname get their fair chance to process it.
                                 */
-                               Instance->Log(SPARSE,"Warning! Invalid user in FJOIN to channel %s IGNORED", channel.c_str());
+                               Instance->Log(SPARSE,"Warning! Invalid user %s in FJOIN to channel %s IGNORED", usr, channel.c_str());
                                continue;
                        }
                }
@@ -1247,23 +997,32 @@ void TreeSocket::SendFJoins(TreeServer* Current, chanrec* c)
                modes.append("+");
        }
 
+       buffer.append(":").append(this->Instance->Config->ServerName).append(" FMODE ").append(c->name).append(" ").append(ConvToStr(c->age)).append(" +").append(c->ChanModes(true)).append("\r\n");
+
+       int linesize = 1;
        for (BanList::iterator b = c->bans.begin(); b != c->bans.end(); b++)
        {
-               modes.append("b");
-               params.append(" ").append(b->data);
-               if (params.length() >= MAXMODES)
+               int size = strlen(b->data) + 2;
+               int currsize = linesize + size;
+               if (currsize <= 350)
+               {
+                       modes.append("b");
+                       params.append(" ").append(b->data);
+                       linesize += size; 
+               }
+               if ((params.length() >= MAXMODES) || (currsize > 350))
                {
                        /* Wrap at MAXMODES */
                        buffer.append(":").append(this->Instance->Config->ServerName).append(" FMODE ").append(c->name).append(" ").append(ConvToStr(c->age)).append(" +").append(modes).append(params).append("\r\n");
                        modes = "";
                        params = "";
+                       linesize = 1;
                }
        }
-       buffer.append(":").append(this->Instance->Config->ServerName).append(" FMODE ").append(c->name).append(" ").append(ConvToStr(c->age)).append(" +").append(c->ChanModes(true));
 
        /* Only send these if there are any */
        if (!modes.empty())
-               buffer.append("\r\n").append(":").append(this->Instance->Config->ServerName).append(" FMODE ").append(c->name).append(" ").append(ConvToStr(c->age)).append(" +").append(modes).append(params);
+               buffer.append(":").append(this->Instance->Config->ServerName).append(" FMODE ").append(c->name).append(" ").append(ConvToStr(c->age)).append(" +").append(modes).append(params);
 
        this->WriteLine(buffer);
 }