+ 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 ¶ms);
+
+ /** 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 channel modes and topics */
+ void SendChannelModes();
+
+ /** 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 ¶ms);
+
+ /** Remote AWAY */
+ bool Away(const std::string &prefix, parameterlist ¶ms);
+
+ /** SAVE to resolve nick collisions without killing */
+ bool ForceNick(const std::string &prefix, parameterlist ¶ms);
+
+ /** ENCAP command
+ */
+ void Encap(User* who, parameterlist ¶ms);
+
+ /** OPERQUIT command
+ */
+ bool OperQuit(const std::string &prefix, parameterlist ¶ms);
+
+ /** PONG
+ */
+ bool LocalPong(const std::string &prefix, parameterlist ¶ms);
+
+ /** VERSION
+ */
+ bool ServerVersion(const std::string &prefix, parameterlist ¶ms);
+
+ /** ADDLINE
+ */
+ bool AddLine(const std::string &prefix, parameterlist ¶ms);
+
+ /** DELLINE
+ */
+ bool DelLine(const std::string &prefix, parameterlist ¶ms);
+
+ /** WHOIS
+ */
+ bool Whois(const std::string &prefix, parameterlist ¶ms);
+
+ /** PUSH
+ */
+ bool Push(const std::string &prefix, parameterlist ¶ms);
+
+ /** PING
+ */
+ bool LocalPing(const std::string &prefix, parameterlist ¶ms);
+
+ /** <- (remote) <- SERVER
+ */
+ bool RemoteServer(const std::string &prefix, parameterlist ¶ms);
+
+ /** (local) -> SERVER
+ */
+ bool Outbound_Reply_Server(parameterlist ¶ms);
+
+ /** (local) <- SERVER
+ */
+ bool Inbound_Server(parameterlist ¶ms);
+
+ /** Handle IRC line split
+ */
+ void Split(const std::string &line, std::string& prefix, std::string& command, parameterlist ¶ms);
+
+ /** Process complete line from buffer
+ */
+ void ProcessLine(std::string &line);