summaryrefslogtreecommitdiff
path: root/src/modules/m_spanningtree/treeserver.h
blob: 6bd1a4f7ca1a7da184b7fffec7e037b961094852 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
/*
 * InspIRCd -- Internet Relay Chat Daemon
 *
 *   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 "treesocket.h"

/** Each server in the tree is represented by one class of
 * type TreeServer. A locally connected TreeServer can
 * have a class of type TreeSocket associated with it, for
 * remote servers, the TreeSocket entry will be NULL.
 * Each server also maintains a pointer to its parent
 * (NULL if this server is ours, at the top of the tree)
 * and a pointer to its "Route" (see the comments in the
 * constructors below), and also a dynamic list of pointers
 * to its children which can be iterated recursively
 * if required. Creating or deleting objects of type
 i* TreeServer automatically maintains the hash_map of
 * TreeServer items, deleting and inserting them as they
 * are created and destroyed.
 */
class TreeServer : public Server
{
	TreeServer* Parent;			/* Parent entry */
	TreeServer* Route;			/* Route entry */
	std::vector<TreeServer*> Children;	/* List of child objects */
	std::string VersionString;		/* Version string or empty string */

	/** Full version string including patch version and other info
	 */
	std::string fullversion;

	TreeSocket* Socket;			/* Socket used to communicate with this server */
	time_t NextPing;			/* After this time, the server should be PINGed*/
	bool LastPingWasGood;			/* True if the server responded to the last PING with a PONG */
	std::string sid;			/* Server ID */

	/** This method is used to add this TreeServer to the
	 * hash maps. It is only called by the constructors.
	 */
	void AddHashEntry();

 public:
	typedef std::vector<TreeServer*> ChildServers;
	FakeUser* const ServerUser;		/* User representing this server */
	const time_t age;

	bool Warned;				/* True if we've warned opers about high latency on this server */
	bool bursting;				/* whether or not this server is bursting */

	unsigned int UserCount;			/* How many users are on this server? [note: doesn't care about +i] */
	unsigned int OperCount;			/* How many opers are on this server? */

	/** We use this constructor only to create the 'root' item, Utils->TreeRoot, which
	 * represents our own server. Therefore, it has no route, no parent, and
	 * no socket associated with it. Its version string is our own local version.
	 */
	TreeServer();

	/** When we create a new server, we call this constructor to initialize it.
	 * This constructor initializes the server's Route and Parent, and sets up
	 * its ping counters so that it will be pinged one minute from now.
	 */
	TreeServer(const std::string& Name, const std::string& Desc, const std::string& id, TreeServer* Above, TreeSocket* Sock, bool Hide);

	int QuitUsers(const std::string &reason);

	/** Get route.
	 * The 'route' is defined as the locally-
	 * connected server which can be used to reach this server.
	 */
	TreeServer* GetRoute();

	/** Returns true if this server is the tree root (i.e.: us)
	 */
	bool IsRoot() const { return (this->Parent == NULL); }

	/** Returns true if this server is locally connected
	 */
	bool IsLocal() const { return (this->Route == this); }

	/** Get server version string
	 */
	const std::string& GetVersion();

	/** Get the full version string of this server
	 * @return The full version string of this server, including patch version and other info
	 */
	const std::string& GetFullVersion() const { return fullversion; }

	/** Set time we are next due to ping this server
	 */
	void SetNextPingTime(time_t t);

	/** Get the time we are next due to ping this server
	 */
	time_t NextPingTime();

	/** Last ping time in milliseconds, used to calculate round trip time
	 */
	unsigned long LastPingMsec;

	/** Round trip time of last ping
	 */
	unsigned long rtt;

	/** When we recieved BURST from this server, used to calculate total burst time at ENDBURST.
	 */
	unsigned long StartBurst;

	/** True if this server is hidden
	 */
	bool Hidden;

	/** True if the server answered their last ping
	 */
	bool AnsweredLastPing();

	/** Set the server as responding to its last ping
	 */
	void SetPingFlag();

	/** Get the TreeSocket pointer for local servers.
	 * For remote servers, this returns NULL.
	 */
	TreeSocket* GetSocket();

	/** Get the parent server.
	 * For the root node, this returns NULL.
	 */
	TreeServer* GetParent();

	/** Set the server version string
	 */
	void SetVersion(const std::string &Version);

	/** Set the full version string
	 * @param verstr The version string to set
	 */
	void SetFullVersion(const std::string& verstr) { fullversion = verstr; }

	/** Sets the description of this server. Called when the description of a remote server changes
	 * and we are notified about it.
	 * @param descstr The description to set
	 */
	void SetDesc(const std::string& descstr) { description = descstr; }

	/** Return all child servers
	 */
	const ChildServers& GetChildren() const { return Children; }

	/** Add a child server
	 */
	void AddChild(TreeServer* Child);

	/** Delete a child server, return false if it didn't exist.
	 */
	bool DelChild(TreeServer* Child);

	/** Removes child nodes of this node, and of that node, etc etc.
	 * This is used during netsplits to automatically tidy up the
	 * server tree. It is slow, we don't use it for much else.
	 */
	void Tidy();

	/** Get server ID
	 */
	const std::string& GetID();

	/** Marks a server as having finished bursting and performs appropriate actions.
	 */
	void FinishBurst();
	/** Recursive call for child servers */
	void FinishBurstInternal();

	/** (Re)check the uline state of this server
	 */
	void CheckULine();

	CullResult cull();

	/** Destructor
	 * Removes the reference to this object from the
	 * hash maps.
	 */
	~TreeServer();

	/** Returns the TreeServer the given user is connected to
	 * @param user The user whose server to return
	 * @return The TreeServer this user is connected to.
	 */
	static TreeServer* Get(User* user)
	{
		return static_cast<TreeServer*>(user->server);
	}
};