summaryrefslogtreecommitdiff
path: root/src/network/core/udp.h
blob: 9ed2705ef9ce8edefc8fb395752d9ae97a6cb0f3 (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
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
/* $Id$ */

/*
 * This file is part of OpenTTD.
 * OpenTTD 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.
 * OpenTTD 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 OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * @file core/udp.h Basic functions to receive and send UDP packets.
 */

#ifndef NETWORK_CORE_UDP_H
#define NETWORK_CORE_UDP_H

#include "address.h"
#include "game.h"
#include "packet.h"

/** Enum with all types of UDP packets. The order MUST not be changed **/
enum PacketUDPType {
	PACKET_UDP_CLIENT_FIND_SERVER,   ///< Queries a game server for game information
	PACKET_UDP_SERVER_RESPONSE,      ///< Reply of the game server with game information
	PACKET_UDP_CLIENT_DETAIL_INFO,   ///< Queries a game server about details of the game, such as companies
	PACKET_UDP_SERVER_DETAIL_INFO,   ///< Reply of the game server about details of the game, such as companies
	PACKET_UDP_SERVER_REGISTER,      ///< Packet to register itself to the master server
	PACKET_UDP_MASTER_ACK_REGISTER,  ///< Packet indicating registration has succeeded
	PACKET_UDP_CLIENT_GET_LIST,      ///< Request for serverlist from master server
	PACKET_UDP_MASTER_RESPONSE_LIST, ///< Response from master server with server ip's + port's
	PACKET_UDP_SERVER_UNREGISTER,    ///< Request to be removed from the server-list
	PACKET_UDP_CLIENT_GET_NEWGRFS,   ///< Requests the name for a list of GRFs (GRF_ID and MD5)
	PACKET_UDP_SERVER_NEWGRFS,       ///< Sends the list of NewGRF's requested.
	PACKET_UDP_MASTER_SESSION_KEY,   ///< Sends a fresh session key to the client
	PACKET_UDP_END,                  ///< Must ALWAYS be on the end of this list!! (period)
};

/** The types of server lists we can get */
enum ServerListType {
	SLT_IPv4 = 0,   ///< Get the IPv4 addresses
	SLT_IPv6 = 1,   ///< Get the IPv6 addresses
	SLT_AUTODETECT, ///< Autodetect the type based on the connection

	SLT_END = SLT_AUTODETECT, ///< End of 'arrays' marker
};

/** Base socket handler for all UDP sockets */
class NetworkUDPSocketHandler : public NetworkSocketHandler {
protected:
	/** The address to bind to. */
	NetworkAddressList bind;
	/** The opened sockets. */
	SocketList sockets;

	NetworkRecvStatus CloseConnection(bool error = true) override;

	void ReceiveInvalidPacket(PacketUDPType, NetworkAddress *client_addr);

	/**
	 * Queries to the server for information about the game.
	 * @param p           The received packet.
	 * @param client_addr The origin of the packet.
	 */
	virtual void Receive_CLIENT_FIND_SERVER(Packet *p, NetworkAddress *client_addr);

	/**
	 * Return of server information to the client.
	 * This packet has several legacy versions, so we list the version and size of each "field":
	 *
	 * Version: Bytes:  Description:
	 *   all      1       the version of this packet's structure
	 *
	 *   4+       1       number of GRFs attached (n)
	 *   4+       n * 20  unique identifier for GRF files. Consists of:
	 *                     - one 4 byte variable with the GRF ID
	 *                     - 16 bytes (sent sequentially) for the MD5 checksum
	 *                       of the GRF
	 *
	 *   3+       4       current game date in days since 1-1-0 (DMY)
	 *   3+       4       game introduction date in days since 1-1-0 (DMY)
	 *
	 *   2+       1       maximum number of companies allowed on the server
	 *   2+       1       number of companies on the server
	 *   2+       1       maximum number of spectators allowed on the server
	 *
	 *   1+       var     string with the name of the server
	 *   1+       var     string with the revision of the server
	 *   1+       1       the language run on the server
	 *                    (0 = any, 1 = English, 2 = German, 3 = French)
	 *   1+       1       whether the server uses a password (0 = no, 1 = yes)
	 *   1+       1       maximum number of clients allowed on the server
	 *   1+       1       number of clients on the server
	 *   1+       1       number of spectators on the server
	 *   1 & 2    2       current game date in days since 1-1-1920 (DMY)
	 *   1 & 2    2       game introduction date in days since 1-1-1920 (DMY)
	 *   1+       var     string with the name of the map
	 *   1+       2       width of the map in tiles
	 *   1+       2       height of the map in tiles
	 *   1+       1       type of map:
	 *                    (0 = temperate, 1 = arctic, 2 = desert, 3 = toyland)
	 *   1+       1       whether the server is dedicated (0 = no, 1 = yes)
	 * @param p           The received packet.
	 * @param client_addr The origin of the packet.
	 */
	virtual void Receive_SERVER_RESPONSE(Packet *p, NetworkAddress *client_addr);

	/**
	 * Query for detailed information about companies.
	 * @param p           The received packet.
	 * @param client_addr The origin of the packet.
	 */
	virtual void Receive_CLIENT_DETAIL_INFO(Packet *p, NetworkAddress *client_addr);

	/**
	 * Reply with detailed company information.
	 * uint8   Version of the packet.
	 * uint8   Number of companies.
	 * For each company:
	 *   uint8   ID of the company.
	 *   string  Name of the company.
	 *   uint32  Year the company was inaugurated.
	 *   uint64  Value.
	 *   uint64  Money.
	 *   uint64  Income.
	 *   uint16  Performance (last quarter).
	 *   bool    Company is password protected.
	 *   uint16  Number of trains.
	 *   uint16  Number of lorries.
	 *   uint16  Number of busses.
	 *   uint16  Number of planes.
	 *   uint16  Number of ships.
	 *   uint16  Number of train stations.
	 *   uint16  Number of lorry stations.
	 *   uint16  Number of bus stops.
	 *   uint16  Number of airports and heliports.
	 *   uint16  Number of harbours.
	 *   bool    Company is an AI.
	 * @param p           The received packet.
	 * @param client_addr The origin of the packet.
	 */
	virtual void Receive_SERVER_DETAIL_INFO(Packet *p, NetworkAddress *client_addr);

	/**
	 * Registers the server to the master server.
	 * string  The "welcome" message to root out other binary packets.
	 * uint8   Version of the protocol.
	 * uint16  The port to unregister.
	 * uint64  The session key.
	 * @param p           The received packet.
	 * @param client_addr The origin of the packet.
	 */
	virtual void Receive_SERVER_REGISTER(Packet *p, NetworkAddress *client_addr);

	/**
	 * The master server acknowledges the registration.
	 * @param p           The received packet.
	 * @param client_addr The origin of the packet.
	 */
	virtual void Receive_MASTER_ACK_REGISTER(Packet *p, NetworkAddress *client_addr);

	/**
	 * The client requests a list of servers.
	 * uint8   The protocol version.
	 * uint8   The type of server to look for: IPv4, IPv6 or based on the received packet.
	 * @param p           The received packet.
	 * @param client_addr The origin of the packet.
	 */
	virtual void Receive_CLIENT_GET_LIST(Packet *p, NetworkAddress *client_addr);

	/**
	 * The server sends a list of servers.
	 * uint8   The protocol version.
	 * For each server:
	 *   4 or 16 bytes of IPv4 or IPv6 address.
	 *   uint8   The port.
	 * @param p           The received packet.
	 * @param client_addr The origin of the packet.
	 */
	virtual void Receive_MASTER_RESPONSE_LIST(Packet *p, NetworkAddress *client_addr);

	/**
	 * A server unregisters itself at the master server.
	 * uint8   Version of the protocol.
	 * uint16  The port to unregister.
	 * @param p           The received packet.
	 * @param client_addr The origin of the packet.
	 */
	virtual void Receive_SERVER_UNREGISTER(Packet *p, NetworkAddress *client_addr);

	/**
	 * The client requests information about some NewGRFs.
	 * uint8   The number of NewGRFs information is requested about.
	 * For each NewGRF:
	 *   uint32      The GRFID.
	 *   16 * uint8  MD5 checksum of the GRF.
	 * @param p           The received packet.
	 * @param client_addr The origin of the packet.
	 */
	virtual void Receive_CLIENT_GET_NEWGRFS(Packet *p, NetworkAddress *client_addr);

	/**
	 * The server returns information about some NewGRFs.
	 * uint8   The number of NewGRFs information is requested about.
	 * For each NewGRF:
	 *   uint32      The GRFID.
	 *   16 * uint8  MD5 checksum of the GRF.
	 *   string      The name of the NewGRF.
	 * @param p           The received packet.
	 * @param client_addr The origin of the packet.
	 */
	virtual void Receive_SERVER_NEWGRFS(Packet *p, NetworkAddress *client_addr);

	/**
	 * The master server sends us a session key.
	 * uint64  The session key.
	 * @param p           The received packet.
	 * @param client_addr The origin of the packet.
	 */
	virtual void Receive_MASTER_SESSION_KEY(Packet *p, NetworkAddress *client_addr);

	void HandleUDPPacket(Packet *p, NetworkAddress *client_addr);

	/**
	 * Function that is called for every GRFConfig that is read when receiving
	 * a NetworkGameInfo. Only grfid and md5sum are set, the rest is zero. This
	 * function must set all appropriate fields. This GRF is later appended to
	 * the grfconfig list of the NetworkGameInfo.
	 * @param config the GRF to handle
	 */
	virtual void HandleIncomingNetworkGameInfoGRFConfig(GRFConfig *config) { NOT_REACHED(); }
public:
	NetworkUDPSocketHandler(NetworkAddressList *bind = nullptr);

	/** On destructing of this class, the socket needs to be closed */
	virtual ~NetworkUDPSocketHandler() { this->Close(); }

	bool Listen();
	void Close() override;

	void SendPacket(Packet *p, NetworkAddress *recv, bool all = false, bool broadcast = false);
	void ReceivePackets();

	void SendNetworkGameInfo(Packet *p, const NetworkGameInfo *info);
	void ReceiveNetworkGameInfo(Packet *p, NetworkGameInfo *info);
};

#endif /* NETWORK_CORE_UDP_H */