summaryrefslogtreecommitdiff
path: root/src/network/core/udp.h
blob: 881fb0a612d8809226c7a15b2d9d45d579f14152 (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
/*
 * 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 "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.
	 * Serialized NetworkGameInfo. See game_info.h for details.
	 * @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);
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();
};

#endif /* NETWORK_CORE_UDP_H */