]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_spanningtree/treesocket.h
m_spanningtree Netburst: Refactor SendChannelModes()
[user/henk/code/inspircd.git] / src / modules / m_spanningtree / treesocket.h
index bd99c1480e315493bbf77a7a232ddf944c98ec9d..ae54bc6aab3c5ef0aa8a0fdf9cee8203d480bccb 100644 (file)
@@ -1 +1,319 @@
-/*       +------------------------------------+\r *       | Inspire Internet Relay Chat Daemon |\r *       +------------------------------------+\r *\r *  InspIRCd: (C) 2002-2007 InspIRCd Development Team\r * See: http://www.inspircd.org/wiki/index.php/Credits\r *\r * This program is free but copyrighted software; see\r *            the file COPYING for details.\r *\r * ---------------------------------------------------\r */\r\r#ifndef __TREESOCKET_H__\r#define __TREESOCKET_H__\r\r#include "configreader.h"\r#include "users.h"\r#include "channels.h"\r#include "modules.h"\r#include "commands/cmd_whois.h"\r#include "commands/cmd_stats.h"\r#include "socket.h"\r#include "inspircd.h"\r#include "wildcard.h"\r#include "xline.h"\r#include "transport.h"\r\r#include "m_spanningtree/utils.h"\r\r/*\r * The server list in InspIRCd is maintained as two structures\r * which hold the data in different ways. Most of the time, we\r * want to very quicky obtain three pieces of information:\r *\r * (1) The information on a server\r * (2) The information on the server we must send data through\r *     to actually REACH the server we're after\r * (3) Potentially, the child/parent objects of this server\r *\r * The InspIRCd spanning protocol provides easy access to these\r * by storing the data firstly in a recursive structure, where\r * each item references its parent item, and a dynamic list\r * of child items, and another structure which stores the items\r * hashed, linearly. This means that if we want to find a server\r * by name quickly, we can look it up in the hash, avoiding\r * any O(n) lookups. If however, during a split or sync, we want\r * to apply an operation to a server, and any of its child objects\r * we can resort to recursion to walk the tree structure.\r * Any socket can have one of five states at any one time.\r * The LISTENER state indicates a socket which is listening\r * for connections. It cannot receive data itself, only incoming\r * sockets.\r * The CONNECTING state indicates an outbound socket which is\r * waiting to be writeable.\r * The WAIT_AUTH_1 state indicates the socket is outbound and\r * has successfully connected, but has not yet sent and received\r * SERVER strings.\r * The WAIT_AUTH_2 state indicates that the socket is inbound\r * (allocated by a LISTENER) but has not yet sent and received\r * SERVER strings.\r * The CONNECTED state represents a fully authorized, fully\r * connected server.\r */\renum ServerState { LISTENER, CONNECTING, WAIT_AUTH_1, WAIT_AUTH_2, CONNECTED };\r\r/** Every SERVER connection inbound or outbound is represented by\r * an object of type TreeSocket.\r * TreeSockets, being inherited from InspSocket, can be tied into\r * the core socket engine, and we cn therefore receive activity events\r * for them, just like activex objects on speed. (yes really, that\r * is a technical term!) Each of these which relates to a locally\r * connected server is assocated with it, by hooking it onto a\r * TreeSocket class using its constructor. In this way, we can\r * maintain a list of servers, some of which are directly connected,\r * some of which are not.\r */\rclass TreeSocket : public InspSocket\r{\r     SpanningTreeUtilities* Utils;           /* Utility class */\r    std::string myhost;                     /* Canonical hostname */\r       std::string in_buffer;                  /* Input buffer */\r     ServerState LinkState;                  /* Link state */\r       std::string InboundServerName;          /* Server name sent to us by other side */\r     std::string InboundDescription;         /* Server description (GECOS) sent to us by the other side */\r  int num_lost_users;                     /* Users lost in split */\r      int num_lost_servers;                   /* Servers lost in split */\r    time_t NextPing;                        /* Time when we are due to ping this server */\r bool LastPingWasGood;                   /* Responded to last ping we sent? */\r  bool bursting;                          /* True if not finished bursting yet */\r        unsigned int keylength;                 /* Is this still used? */\r      std::string ModuleList;                 /* Module list of other server from CAPAB */\r   std::map<std::string,std::string> CapKeys;      /* CAPAB keys from other server */\r     Module* Hook;                           /* I/O hooking module that we're attached to for this socket */\r        std::string ourchallenge;               /* Challenge sent for challenge/response */\r    std::string theirchallenge;             /* Challenge recv for challenge/response */\r    std::string OutboundPass;               /* Outbound password */\r        bool sentcapab;                         /* Have sent CAPAB already */\r public:\r\r        /** Because most of the I/O gubbins are encapsulated within\r     * InspSocket, we just call the superclass constructor for\r      * most of the action, and append a few of our own values\r       * to it.\r       */\r    TreeSocket(SpanningTreeUtilities* Util, InspIRCd* SI, std::string host, int port, bool listening, unsigned long maxtime, Module* HookMod = NULL);\r\r     /** Because most of the I/O gubbins are encapsulated within\r     * InspSocket, we just call the superclass constructor for\r      * most of the action, and append a few of our own values\r       * to it.\r       */\r    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 = NULL);\r\r   /** When a listening socket gives us a new file descriptor,\r     * we must associate it with a socket without creating a new\r    * connection. This constructor is used for this purpose.\r       */\r    TreeSocket(SpanningTreeUtilities* Util, InspIRCd* SI, int newfd, char* ip, Module* HookMod = NULL);\r\r   /** Get link state\r      */\r    ServerState GetLinkState();\r\r   /** Get challenge set in our CAPAB for challenge/response\r       */\r    const std::string& GetOurChallenge();\r\r /** Get challenge set in our CAPAB for challenge/response\r       */\r    void SetOurChallenge(const std::string &c);\r\r   /** Get challenge set in their CAPAB for challenge/response\r     */\r    const std::string& GetTheirChallenge();\r\r       /** Get challenge set in their CAPAB for challenge/response\r     */\r    void SetTheirChallenge(const std::string &c);\r\r /** Compare two passwords based on authentication scheme\r        */\r    bool ComparePass(const std::string &ours, const std::string &theirs);\r\r /** Return the module which we are hooking to for I/O encapsulation\r     */\r    Module* GetHook();\r\r    /** Destructor\r  */\r    ~TreeSocket();\r\r        /** Generate random string used for challenge-response auth\r     */\r    std::string RandString(unsigned int length);\r\r  /** Construct a password, optionally hashed with the other side's\r       * challenge string\r     */\r    std::string MakePass(const std::string &password, const std::string &challenge);\r\r      /** When an outbound connection finishes connecting, we receive\r         * this event, and must send our SERVER string to the other\r     * side. If the other side is happy, as outlined in the server\r  * to server docs on the inspircd.org site, the other side\r      * will then send back its own server string.\r   */\r    virtual bool OnConnected();\r\r   /** Handle socket error event\r   */\r    virtual void OnError(InspSocketError e);\r\r      /** Sends an error to the remote server, and displays it locally to show\r        * that it was sent.\r    */\r    void SendError(const std::string &errormessage);\r\r      /** Handle socket disconnect event\r      */\r    virtual int OnDisconnect();\r\r   /** Recursively send the server tree with distances as hops.\r    * This is used during network burst to inform the other server\r         * (and any of ITS servers too) of what servers we know about.\r  * If at any point any of these servers already exist on the other\r      * end, our connection may be terminated. The hopcounts given\r   * by this function are relative, this doesn't matter so long as\r        * they are all >1, as all the remote servers re-calculate them\r         * to be relative too, with themselves as hop 0.\r        */\r    void SendServers(TreeServer* Current, TreeServer* s, int hops);\r\r       /** Returns my capabilities as a string\r         */\r    std::string MyCapabilities();\r\r /** Send my capabilities to the remote side\r     */\r    void SendCapabilities();\r\r      /* Check a comma seperated list for an item */\r bool HasItem(const std::string &list, const std::string &item);\r\r       /* Isolate and return the elements that are different between two comma seperated lists */\r     std::string ListDifference(const std::string &one, const std::string &two);\r\r   bool Capab(const std::deque<std::string> &params);\r\r    /** This function forces this server to quit, removing this server\r      * and any users on it (and servers and users below that, etc etc).\r     * It's very slow and pretty clunky, but luckily unless your network\r    * is having a REAL bad hair day, this function shouldnt be called\r      * too many times a month ;-)\r   */\r    void SquitServer(std::string &from, TreeServer* Current);\r\r     /** This is a wrapper function for SquitServer above, which\r     * does some validation first and passes on the SQUIT to all\r    * other remaining servers.\r     */\r    void Squit(TreeServer* Current, const std::string &reason);\r\r   /** FMODE command - server mode with timestamp checks */\r       bool ForceMode(const std::string &source, std::deque<std::string> &params);\r\r   /** FTOPIC command */\r  bool ForceTopic(const std::string &source, std::deque<std::string> &params);\r\r  /** FJOIN, similar to TS6 SJOIN, but not quite. */\r     bool ForceJoin(const std::string &source, std::deque<std::string> &params);\r\r   /** NICK command */\r    bool IntroduceClient(const std::string &source, std::deque<std::string> &params);\r\r     /** Send one or more FJOINs for a channel of users.\r     * If the length of a single line is more than 480-NICKMAX\r      * in length, it is split over multiple lines.\r  */\r    void SendFJoins(TreeServer* Current, chanrec* c);\r\r     /** Send G, Q, Z and E lines */\r        void SendXLines(TreeServer* Current);\r\r /** Send channel modes and topics */\r   void SendChannelModes(TreeServer* Current);\r\r   /** send all users and their oper state/modes */\r       void SendUsers(TreeServer* Current);\r\r  /** This function is called when we want to send a netburst to a local\r  * server. There is a set order we must do this, because for example\r    * users require their servers to exist, and channels require their\r     * users to exist. You get the idea.\r    */\r    void DoBurst(TreeServer* s);\r\r  /** This function is called when we receive data from a remote\r  * server. We buffer the data in a std::string (it doesnt stay\r  * there for long), reading using InspSocket::Read() which can\r  * read up to 16 kilobytes in one operation.\r    *\r      * IF THIS FUNCTION RETURNS FALSE, THE CORE CLOSES AND DELETES\r  * THE SOCKET OBJECT FOR US.\r    */\r    virtual bool OnDataReady();\r\r   /** Send one or more complete lines down the socket\r     */\r    int WriteLine(std::string line);\r\r      /** Handle ERROR command */\r    bool Error(std::deque<std::string> &params);\r\r  /** remote MOTD. leet, huh? */\r bool Motd(const std::string &prefix, std::deque<std::string> &params);\r\r        /** remote ADMIN. leet, huh? */\r        bool Admin(const std::string &prefix, std::deque<std::string> &params);\r\r       /** Remote MODULES */\r  bool Modules(const std::string &prefix, std::deque<std::string> &params);\r\r     bool Stats(const std::string &prefix, std::deque<std::string> &params);\r\r       /** Because the core won't let users or even SERVERS set +o,\r    * we use the OPERTYPE command to do this.\r      */\r    bool OperType(const std::string &prefix, std::deque<std::string> &params);\r\r    /** Because Andy insists that services-compatible servers must\r  * implement SVSNICK and SVSJOIN, that's exactly what we do :p\r  */\r    bool ForceNick(const std::string &prefix, std::deque<std::string> &params);\r\r   bool OperQuit(const std::string &prefix, std::deque<std::string> &params);\r\r    /** SVSJOIN\r     */\r    bool ServiceJoin(const std::string &prefix, std::deque<std::string> &params);\r\r /** REHASH\r      */\r    bool RemoteRehash(const std::string &prefix, std::deque<std::string> &params);\r\r        /** KILL\r        */\r    bool RemoteKill(const std::string &prefix, std::deque<std::string> &params);\r\r  /** PONG\r        */\r    bool LocalPong(const std::string &prefix, std::deque<std::string> &params);\r\r   /** METADATA\r    */\r    bool MetaData(const std::string &prefix, std::deque<std::string> &params);\r\r    /** VERSION\r     */\r    bool ServerVersion(const std::string &prefix, std::deque<std::string> &params);\r\r       /** CHGHOST\r     */\r    bool ChangeHost(const std::string &prefix, std::deque<std::string> &params);\r\r  /** ADDLINE\r     */\r    bool AddLine(const std::string &prefix, std::deque<std::string> &params);\r\r     /** CHGNAME\r     */\r    bool ChangeName(const std::string &prefix, std::deque<std::string> &params);\r\r  /** WHOIS\r       */\r    bool Whois(const std::string &prefix, std::deque<std::string> &params);\r\r       /** PUSH\r        */\r    bool Push(const std::string &prefix, std::deque<std::string> &params);\r\r        /** SETTIME\r     */\r    bool HandleSetTime(const std::string &prefix, std::deque<std::string> &params);\r\r       /** TIME\r        */\r    bool Time(const std::string &prefix, std::deque<std::string> &params);\r\r        /** PING\r        */\r    bool LocalPing(const std::string &prefix, std::deque<std::string> &params);\r\r   /** Remove all modes from a channel, including statusmodes (+qaovh etc), simplemodes, parameter modes.\r  * This does not update the timestamp of the target channel, this must be done seperately.\r      */\r    bool RemoveStatus(const std::string &prefix, std::deque<std::string> &params);\r\r        /** <- (remote) <- SERVER\r       */\r    bool RemoteServer(const std::string &prefix, std::deque<std::string> &params);\r\r        /** (local) -> SERVER\r   */\r    bool Outbound_Reply_Server(std::deque<std::string> &params);\r\r  /** (local) <- SERVER\r   */\r    bool Inbound_Server(std::deque<std::string> &params);\r\r /** Handle netsplit\r     */\r    void Split(const std::string &line, std::deque<std::string> &n);\r\r      /** Process complete line from buffer\r   */\r    bool ProcessLine(std::string &line);\r\r  /** Get this server's name\r      */\r    virtual std::string GetName();\r\r        /** Handle socket timeout from connect()\r        */\r    virtual void OnTimeout();\r\r     /** Handle socket close event\r   */\r    virtual void OnClose();\r\r       /** Handle incoming connection event\r    */\r    virtual int OnIncomingConnection(int newsock, char* ip);\r};\r\r/* Used to validate the value lengths of multiple parameters for a command */\rstruct cmd_validation\r{\r     const char* item;\r      size_t param;\r  size_t length;\r};\r\r/* Used to validate the length values in CAPAB CAPABILITIES */\rstruct cap_validation\r{\r      const char* reason;\r    const char* key;\r       size_t size;\r};\r\r#endif\r\r
\ No newline at end of file
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2008 Robin Burchell <robin+git@viroteck.net>
+ *   Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
+ *   Copyright (C) 2007 Craig Edwards <craigedwards@brainbox.cc>
+ *
+ * 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/>.
+ */
+
+
+#pragma once
+
+#include "socket.h"
+#include "inspircd.h"
+#include "xline.h"
+
+#include "utils.h"
+
+/*
+ * The server list in InspIRCd is maintained as two structures
+ * which hold the data in different ways. Most of the time, we
+ * want to very quicky obtain three pieces of information:
+ *
+ * (1) The information on a server
+ * (2) The information on the server we must send data through
+ *     to actually REACH the server we're after
+ * (3) Potentially, the child/parent objects of this server
+ *
+ * The InspIRCd spanning protocol provides easy access to these
+ * by storing the data firstly in a recursive structure, where
+ * each item references its parent item, and a dynamic list
+ * of child items, and another structure which stores the items
+ * hashed, linearly. This means that if we want to find a server
+ * by name quickly, we can look it up in the hash, avoiding
+ * any O(n) lookups. If however, during a split or sync, we want
+ * to apply an operation to a server, and any of its child objects
+ * we can resort to recursion to walk the tree structure.
+ * Any socket can have one of five states at any one time.
+ *
+ * CONNECTING: indicates an outbound socket which is
+ *                                                     waiting to be writeable.
+ * WAIT_AUTH_1:        indicates the socket is outbound and
+ *                                                     has successfully connected, but has not
+ *                                                     yet sent and received SERVER strings.
+ * WAIT_AUTH_2:        indicates that the socket is inbound
+ *                                                     but has not yet sent and received
+ *                                                     SERVER strings.
+ * CONNECTED:   represents a fully authorized, fully
+ *                                                     connected server.
+ * DYING:       represents a server that has had an error.
+ */
+enum ServerState { CONNECTING, WAIT_AUTH_1, WAIT_AUTH_2, CONNECTED, DYING };
+
+struct CapabData
+{
+       reference<Link> link;                   /* Link block used for this connection */
+       reference<Autoconnect> ac;              /* Autoconnect used to cause this connection, if any */
+       std::string ModuleList;                 /* Required module list of other server from CAPAB */
+       std::string OptModuleList;              /* Optional module list of other server from CAPAB */
+       std::string ChanModes;
+       std::string UserModes;
+       std::map<std::string,std::string> CapKeys;      /* CAPAB keys from other server */
+       std::string ourchallenge;               /* Challenge sent for challenge/response */
+       std::string theirchallenge;             /* Challenge recv for challenge/response */
+       int capab_phase;                        /* Have sent CAPAB already */
+       bool auth_fingerprint;                  /* Did we auth using SSL fingerprint */
+       bool auth_challenge;                    /* Did we auth using challenge/response */
+};
+
+/** Every SERVER connection inbound or outbound is represented by an object of
+ * type TreeSocket. During setup, the object can be found in Utils->timeoutlist;
+ * after setup, MyRoot will have been created as a child of Utils->TreeRoot
+ */
+class TreeSocket : public BufferedSocket
+{
+       SpanningTreeUtilities* Utils;           /* Utility class */
+       std::string linkID;                     /* Description for this link */
+       ServerState LinkState;                  /* Link state */
+       CapabData* capab;                       /* Link setup data (held until burst is sent) */
+       TreeServer* MyRoot;                     /* The server we are talking to */
+       time_t NextPing;                        /* Time when we are due to ping this server */
+       bool LastPingWasGood;                   /* Responded to last ping we sent? */
+       int proto_version;                      /* Remote protocol version */
+       bool ConnectionFailureShown; /* Set to true if a connection failure message was shown */
+ public:
+       time_t age;
+
+       /** Because most of the I/O gubbins are encapsulated within
+        * BufferedSocket, we just call the superclass constructor for
+        * most of the action, and append a few of our own values
+        * to it.
+        */
+       TreeSocket(SpanningTreeUtilities* Util, Link* link, Autoconnect* myac, const std::string& ipaddr);
+
+       /** When a listening socket gives us a new file descriptor,
+        * we must associate it with a socket without creating a new
+        * connection. This constructor is used for this purpose.
+        */
+       TreeSocket(SpanningTreeUtilities* Util, int newfd, ListenSocket* via, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server);
+
+       /** Get link state
+        */
+       ServerState GetLinkState();
+
+       /** Get challenge set in our CAPAB for challenge/response
+        */
+       const std::string& GetOurChallenge();
+
+       /** Get challenge set in our CAPAB for challenge/response
+        */
+       void SetOurChallenge(const std::string &c);
+
+       /** Get challenge set in their CAPAB for challenge/response
+        */
+       const std::string& GetTheirChallenge();
+
+       /** Get challenge set in their CAPAB for challenge/response
+        */
+       void SetTheirChallenge(const std::string &c);
+
+       /** Compare two passwords based on authentication scheme
+        */
+       bool ComparePass(const Link& link, const std::string &theirs);
+
+       /** Clean up information used only during server negotiation
+        */
+       void CleanNegotiationInfo();
+
+       CullResult cull();
+       /** Destructor
+        */
+       ~TreeSocket();
+
+       /** Construct a password, optionally hashed with the other side's
+        * challenge string
+        */
+       std::string MakePass(const std::string &password, const std::string &challenge);
+
+       /** When an outbound connection finishes connecting, we receive
+        * this event, and must send our SERVER string to the other
+        * side. If the other side is happy, as outlined in the server
+        * to server docs on the inspircd.org site, the other side
+        * will then send back its own server string.
+        */
+       virtual void OnConnected();
+
+       /** Handle socket error event
+        */
+       virtual void OnError(BufferedSocketError e);
+
+       /** Sends an error to the remote server, and displays it locally to show
+        * that it was sent.
+        */
+       void SendError(const std::string &errormessage);
+
+       /** Recursively send the server tree with distances as hops.
+        * This is used during network burst to inform the other server
+        * (and any of ITS servers too) of what servers we know about.
+        * If at any point any of these servers already exist on the other
+        * end, our connection may be terminated. The hopcounts given
+        * by this function are relative, this doesn't matter so long as
+        * they are all >1, as all the remote servers re-calculate them
+        * to be relative too, with themselves as hop 0.
+        */
+       void SendServers(TreeServer* Current, TreeServer* s, int hops);
+
+       /** Returns module list as a string, filtered by filter
+        * @param filter a module version bitmask, such as VF_COMMON or VF_OPTCOMMON
+        */
+       std::string MyModules(int filter);
+
+       /** Send my capabilities to the remote side
+        */
+       void SendCapabilities(int phase);
+
+       /* Isolate and return the elements that are different between two lists */
+       void ListDifference(const std::string &one, const std::string &two, char sep,
+               std::string& mleft, std::string& mright);
+
+       bool Capab(const parameterlist &params);
+
+       /** This function forces this server to quit, removing this server
+        * and any users on it (and servers and users below that, etc etc).
+        * It's very slow and pretty clunky, but luckily unless your network
+        * is having a REAL bad hair day, this function shouldnt be called
+        * too many times a month ;-)
+        */
+       void SquitServer(std::string &from, TreeServer* Current, int& num_lost_servers, int& num_lost_users);
+
+       /** This is a wrapper function for SquitServer above, which
+        * does some validation first and passes on the SQUIT to all
+        * other remaining servers.
+        */
+       void Squit(TreeServer* Current, const std::string &reason);
+
+       /* Used on nick collision ... XXX ugly function HACK */
+       int DoCollision(User *u, time_t remotets, const std::string &remoteident, const std::string &remoteip, const std::string &remoteuid);
+
+       /** Send one or more FJOINs for a channel of users.
+        * If the length of a single line is more than 480-NICKMAX
+        * in length, it is split over multiple lines.
+        */
+       void SendFJoins(Channel* c);
+
+       /** Send G, Q, Z and E lines */
+       void SendXLines();
+
+       /** Send all known information about a channel */
+       void SyncChannel(Channel* chan);
+
+       /** send all users and their oper state/modes */
+       void SendUsers();
+
+       /** This function is called when we want to send a netburst to a local
+        * server. There is a set order we must do this, because for example
+        * users require their servers to exist, and channels require their
+        * users to exist. You get the idea.
+        */
+       void DoBurst(TreeServer* s);
+
+       /** This function is called when we receive data from a remote
+        * server.
+        */
+       void OnDataReady();
+
+       /** Send one or more complete lines down the socket
+        */
+       void WriteLine(std::string line);
+
+       /** Handle ERROR command */
+       void Error(parameterlist &params);
+
+       /** Remote AWAY */
+       bool Away(const std::string &prefix, parameterlist &params);
+
+       /** SAVE to resolve nick collisions without killing */
+       bool ForceNick(const std::string &prefix, parameterlist &params);
+
+       /** ENCAP command
+        */
+       void Encap(User* who, parameterlist &params);
+
+       /** OPERQUIT command
+        */
+       bool OperQuit(const std::string &prefix, parameterlist &params);
+
+       /** PONG
+        */
+       bool LocalPong(const std::string &prefix, parameterlist &params);
+
+       /** VERSION
+        */
+       bool ServerVersion(const std::string &prefix, parameterlist &params);
+
+       /** ADDLINE
+        */
+       bool AddLine(const std::string &prefix, parameterlist &params);
+
+       /** DELLINE
+        */
+       bool DelLine(const std::string &prefix, parameterlist &params);
+
+       /** WHOIS
+        */
+       bool Whois(const std::string &prefix, parameterlist &params);
+
+       /** PUSH
+        */
+       bool Push(const std::string &prefix, parameterlist &params);
+
+       /** PING
+        */
+       bool LocalPing(const std::string &prefix, parameterlist &params);
+
+       /** <- (remote) <- SERVER
+        */
+       bool RemoteServer(const std::string &prefix, parameterlist &params);
+
+       /** (local) -> SERVER
+        */
+       bool Outbound_Reply_Server(parameterlist &params);
+
+       /** (local) <- SERVER
+        */
+       bool Inbound_Server(parameterlist &params);
+
+       /** Handle IRC line split
+        */
+       void Split(const std::string &line, std::string& prefix, std::string& command, parameterlist &params);
+
+       /** Process complete line from buffer
+        */
+       void ProcessLine(std::string &line);
+
+       void ProcessConnectedLine(std::string& prefix, std::string& command, parameterlist& params);
+
+       /** Handle socket timeout from connect()
+        */
+       virtual void OnTimeout();
+       /** Handle server quit on close
+        */
+       virtual void Close();
+
+       /** Returns true if this server was introduced to the rest of the network
+        */
+       bool Introduced();
+};