OpenTTD
udp.cpp
Go to the documentation of this file.
1 /* $Id$ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * 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.
6  * 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.
7  * 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/>.
8  */
9 
14 #include "../../stdafx.h"
15 #include "../../date_func.h"
16 #include "../../debug.h"
17 #include "udp.h"
18 
19 #include "../../safeguards.h"
20 
26 {
27  if (bind != nullptr) {
28  for (NetworkAddress &addr : *bind) {
29  this->bind.push_back(addr);
30  }
31  } else {
32  /* As hostname nullptr and port 0/nullptr don't go well when
33  * resolving it we need to add an address for each of
34  * the address families we support. */
35  this->bind.emplace_back(nullptr, 0, AF_INET);
36  this->bind.emplace_back(nullptr, 0, AF_INET6);
37  }
38 }
39 
40 
46 {
47  /* Make sure socket is closed */
48  this->Close();
49 
50  for (NetworkAddress &addr : this->bind) {
51  addr.Listen(SOCK_DGRAM, &this->sockets);
52  }
53 
54  return this->sockets.size() != 0;
55 }
56 
61 {
62  for (auto &s : this->sockets) {
63  closesocket(s.second);
64  }
65  this->sockets.clear();
66 }
67 
69 {
72 }
73 
81 void NetworkUDPSocketHandler::SendPacket(Packet *p, NetworkAddress *recv, bool all, bool broadcast)
82 {
83  if (this->sockets.size() == 0) this->Listen();
84 
85  for (auto &s : this->sockets) {
86  /* Make a local copy because if we resolve it we cannot
87  * easily unresolve it so we can resolve it later again. */
88  NetworkAddress send(*recv);
89 
90  /* Not the same type */
91  if (!send.IsFamily(s.first.GetAddress()->ss_family)) continue;
92 
93  p->PrepareToSend();
94 
95  if (broadcast) {
96  /* Enable broadcast */
97  unsigned long val = 1;
98  if (setsockopt(s.second, SOL_SOCKET, SO_BROADCAST, (char *) &val, sizeof(val)) < 0) {
99  DEBUG(net, 1, "[udp] setting broadcast failed with: %i", GET_LAST_ERROR());
100  }
101  }
102 
103  /* Send the buffer */
104  int res = sendto(s.second, (const char*)p->buffer, p->size, 0, (const struct sockaddr *)send.GetAddress(), send.GetAddressLength());
105  DEBUG(net, 7, "[udp] sendto(%s)", send.GetAddressAsString());
106 
107  /* Check for any errors, but ignore it otherwise */
108  if (res == -1) DEBUG(net, 1, "[udp] sendto(%s) failed with: %i", send.GetAddressAsString(), GET_LAST_ERROR());
109 
110  if (!all) break;
111  }
112 }
113 
118 {
119  for (auto &s : this->sockets) {
120  for (int i = 0; i < 1000; i++) { // Do not infinitely loop when DoSing with UDP
121  struct sockaddr_storage client_addr;
122  memset(&client_addr, 0, sizeof(client_addr));
123 
124  Packet p(this);
125  socklen_t client_len = sizeof(client_addr);
126 
127  /* Try to receive anything */
128  SetNonBlocking(s.second); // Some OSes seem to lose the non-blocking status of the socket
129  int nbytes = recvfrom(s.second, (char*)p.buffer, SEND_MTU, 0, (struct sockaddr *)&client_addr, &client_len);
130 
131  /* Did we get the bytes for the base header of the packet? */
132  if (nbytes <= 0) break; // No data, i.e. no packet
133  if (nbytes <= 2) continue; // Invalid data; try next packet
134 
135  NetworkAddress address(client_addr, client_len);
136  p.PrepareToRead();
137 
138  /* If the size does not match the packet must be corrupted.
139  * Otherwise it will be marked as corrupted later on. */
140  if (nbytes != p.size) {
141  DEBUG(net, 1, "received a packet with mismatching size from %s", address.GetAddressAsString());
142  continue;
143  }
144 
145  /* Handle the packet */
146  this->HandleUDPPacket(&p, &address);
147  }
148  }
149 }
150 
151 
158 {
160 
161  /*
162  * Please observe the order.
163  * The parts must be read in the same order as they are sent!
164  */
165 
166  /* Update the documentation in udp.h on changes
167  * to the NetworkGameInfo wire-protocol! */
168 
169  /* NETWORK_GAME_INFO_VERSION = 4 */
170  {
171  /* Only send the GRF Identification (GRF_ID and MD5 checksum) of
172  * the GRFs that are needed, i.e. the ones that the server has
173  * selected in the NewGRF GUI and not the ones that are used due
174  * to the fact that they are in [newgrf-static] in openttd.cfg */
175  const GRFConfig *c;
176  uint count = 0;
177 
178  /* Count number of GRFs to send information about */
179  for (c = info->grfconfig; c != nullptr; c = c->next) {
180  if (!HasBit(c->flags, GCF_STATIC)) count++;
181  }
182  p->Send_uint8 (count); // Send number of GRFs
183 
184  /* Send actual GRF Identifications */
185  for (c = info->grfconfig; c != nullptr; c = c->next) {
186  if (!HasBit(c->flags, GCF_STATIC)) this->SendGRFIdentifier(p, &c->ident);
187  }
188  }
189 
190  /* NETWORK_GAME_INFO_VERSION = 3 */
191  p->Send_uint32(info->game_date);
192  p->Send_uint32(info->start_date);
193 
194  /* NETWORK_GAME_INFO_VERSION = 2 */
195  p->Send_uint8 (info->companies_max);
196  p->Send_uint8 (info->companies_on);
197  p->Send_uint8 (info->spectators_max);
198 
199  /* NETWORK_GAME_INFO_VERSION = 1 */
200  p->Send_string(info->server_name);
201  p->Send_string(info->server_revision);
202  p->Send_uint8 (info->server_lang);
203  p->Send_bool (info->use_password);
204  p->Send_uint8 (info->clients_max);
205  p->Send_uint8 (info->clients_on);
206  p->Send_uint8 (info->spectators_on);
207  p->Send_string(info->map_name);
208  p->Send_uint16(info->map_width);
209  p->Send_uint16(info->map_height);
210  p->Send_uint8 (info->map_set);
211  p->Send_bool (info->dedicated);
212 }
213 
220 {
221  static const Date MAX_DATE = ConvertYMDToDate(MAX_YEAR, 11, 31); // December is month 11
222 
223  info->game_info_version = p->Recv_uint8();
224 
225  /*
226  * Please observe the order.
227  * The parts must be read in the same order as they are sent!
228  */
229 
230  /* Update the documentation in udp.h on changes
231  * to the NetworkGameInfo wire-protocol! */
232 
233  switch (info->game_info_version) {
234  case 4: {
235  GRFConfig **dst = &info->grfconfig;
236  uint i;
237  uint num_grfs = p->Recv_uint8();
238 
239  /* Broken/bad data. It cannot have that many NewGRFs. */
240  if (num_grfs > NETWORK_MAX_GRF_COUNT) return;
241 
242  for (i = 0; i < num_grfs; i++) {
243  GRFConfig *c = new GRFConfig();
244  this->ReceiveGRFIdentifier(p, &c->ident);
246 
247  /* Append GRFConfig to the list */
248  *dst = c;
249  dst = &c->next;
250  }
251  FALLTHROUGH;
252  }
253 
254  case 3:
255  info->game_date = Clamp(p->Recv_uint32(), 0, MAX_DATE);
256  info->start_date = Clamp(p->Recv_uint32(), 0, MAX_DATE);
257  FALLTHROUGH;
258 
259  case 2:
260  info->companies_max = p->Recv_uint8 ();
261  info->companies_on = p->Recv_uint8 ();
262  info->spectators_max = p->Recv_uint8 ();
263  FALLTHROUGH;
264 
265  case 1:
266  p->Recv_string(info->server_name, sizeof(info->server_name));
267  p->Recv_string(info->server_revision, sizeof(info->server_revision));
268  info->server_lang = p->Recv_uint8 ();
269  info->use_password = p->Recv_bool ();
270  info->clients_max = p->Recv_uint8 ();
271  info->clients_on = p->Recv_uint8 ();
272  info->spectators_on = p->Recv_uint8 ();
273  if (info->game_info_version < 3) { // 16 bits dates got scrapped and are read earlier
276  }
277  p->Recv_string(info->map_name, sizeof(info->map_name));
278  info->map_width = p->Recv_uint16();
279  info->map_height = p->Recv_uint16();
280  info->map_set = p->Recv_uint8 ();
281  info->dedicated = p->Recv_bool ();
282 
283  if (info->server_lang >= NETWORK_NUM_LANGUAGES) info->server_lang = 0;
284  if (info->map_set >= NETWORK_NUM_LANDSCAPES) info->map_set = 0;
285  }
286 }
287 
294 {
295  PacketUDPType type;
296 
297  /* New packet == new client, which has not quit yet */
298  this->Reopen();
299 
300  type = (PacketUDPType)p->Recv_uint8();
301 
302  switch (this->HasClientQuit() ? PACKET_UDP_END : type) {
303  case PACKET_UDP_CLIENT_FIND_SERVER: this->Receive_CLIENT_FIND_SERVER(p, client_addr); break;
304  case PACKET_UDP_SERVER_RESPONSE: this->Receive_SERVER_RESPONSE(p, client_addr); break;
305  case PACKET_UDP_CLIENT_DETAIL_INFO: this->Receive_CLIENT_DETAIL_INFO(p, client_addr); break;
306  case PACKET_UDP_SERVER_DETAIL_INFO: this->Receive_SERVER_DETAIL_INFO(p, client_addr); break;
307  case PACKET_UDP_SERVER_REGISTER: this->Receive_SERVER_REGISTER(p, client_addr); break;
308  case PACKET_UDP_MASTER_ACK_REGISTER: this->Receive_MASTER_ACK_REGISTER(p, client_addr); break;
309  case PACKET_UDP_CLIENT_GET_LIST: this->Receive_CLIENT_GET_LIST(p, client_addr); break;
310  case PACKET_UDP_MASTER_RESPONSE_LIST: this->Receive_MASTER_RESPONSE_LIST(p, client_addr); break;
311  case PACKET_UDP_SERVER_UNREGISTER: this->Receive_SERVER_UNREGISTER(p, client_addr); break;
312  case PACKET_UDP_CLIENT_GET_NEWGRFS: this->Receive_CLIENT_GET_NEWGRFS(p, client_addr); break;
313  case PACKET_UDP_SERVER_NEWGRFS: this->Receive_SERVER_NEWGRFS(p, client_addr); break;
314  case PACKET_UDP_MASTER_SESSION_KEY: this->Receive_MASTER_SESSION_KEY(p, client_addr); break;
315 
316  default:
317  if (this->HasClientQuit()) {
318  DEBUG(net, 0, "[udp] received invalid packet type %d from %s", type, client_addr->GetAddressAsString());
319  } else {
320  DEBUG(net, 0, "[udp] received illegal packet from %s", client_addr->GetAddressAsString());
321  }
322  break;
323  }
324 }
325 
332 {
333  DEBUG(net, 0, "[udp] received packet type %d on wrong port from %s", type, client_addr->GetAddressAsString());
334 }
335 
Everything is okay.
Definition: core.h:25
Date start_date
When the game started.
Definition: game.h:36
byte spectators_max
Max spectators allowed on server.
Definition: game.h:53
uint16 map_height
Map height.
Definition: game.h:39
bool HasClientQuit() const
Whether the current client connected to the socket has quit.
Definition: core.h:69
virtual void Receive_CLIENT_GET_NEWGRFS(Packet *p, NetworkAddress *client_addr)
The client requests information about some NewGRFs.
Definition: udp.cpp:345
Internal entity of a packet.
Definition: packet.h:42
Sends a fresh session key to the client.
Definition: udp.h:34
virtual void Receive_SERVER_REGISTER(Packet *p, NetworkAddress *client_addr)
Registers the server to the master server.
Definition: udp.cpp:340
uint32 Recv_uint32()
Read a 32 bits integer from the packet.
Definition: packet.cpp:248
Queries a game server for game information.
Definition: udp.h:23
#define DAYS_TILL_ORIGINAL_BASE_YEAR
The offset in days from the &#39;_date == 0&#39; till &#39;ConvertYMDToDate(ORIGINAL_BASE_YEAR, 0, 1)&#39;.
Definition: date_type.h:82
byte game_info_version
Version of the game info.
Definition: game.h:47
Requests the name for a list of GRFs (GRF_ID and MD5)
Definition: udp.h:32
void ReceivePackets()
Receive a packet at UDP level.
Definition: udp.cpp:117
void PrepareToSend()
Writes the packet size from the raw packet from packet->size.
Definition: packet.cpp:63
byte server_lang
Language of the server (we should make a nice table for this)
Definition: game.h:48
void Send_string(const char *data)
Sends a string over the network.
Definition: packet.cpp:150
virtual void Receive_SERVER_RESPONSE(Packet *p, NetworkAddress *client_addr)
Return of server information to the client.
Definition: udp.cpp:337
Request for serverlist from master server.
Definition: udp.h:29
void SendNetworkGameInfo(Packet *p, const NetworkGameInfo *info)
Serializes the NetworkGameInfo struct to the packet.
Definition: udp.cpp:157
void Send_uint8(uint8 data)
Package a 8 bits integer in the packet.
Definition: packet.cpp:98
virtual void Receive_SERVER_UNREGISTER(Packet *p, NetworkAddress *client_addr)
A server unregisters itself at the master server.
Definition: udp.cpp:344
SocketList sockets
The opened sockets.
Definition: udp.h:53
virtual void Receive_MASTER_SESSION_KEY(Packet *p, NetworkAddress *client_addr)
The master server sends us a session key.
Definition: udp.cpp:347
GRF file is used statically (can be used in any MP game)
Definition: newgrf_config.h:26
Wrapper for (un)resolved network addresses; there&#39;s no reason to transform a numeric IP to a string a...
Definition: address.h:29
PacketUDPType
Enum with all types of UDP packets.
Definition: udp.h:22
uint16 map_width
Map width.
Definition: game.h:38
void Send_uint32(uint32 data)
Package a 32 bits integer in the packet.
Definition: packet.cpp:119
Request to be removed from the server-list.
Definition: udp.h:31
GRFIdentifier ident
grfid and md5sum to uniquely identify newgrfs
void Reopen()
Reopen the socket so we can send/receive stuff again.
Definition: core.h:74
struct GRFConfig * next
NOSAVE: Next item in the linked list.
char server_name[NETWORK_NAME_LENGTH]
Server name.
Definition: game.h:40
void ReceiveInvalidPacket(PacketUDPType, NetworkAddress *client_addr)
Helper for logging receiving invalid packets.
Definition: udp.cpp:331
bool IsFamily(int family)
Checks of this address is of the given family.
Definition: address.cpp:145
The game information that is sent from the server to the clients.
Definition: game.h:34
byte companies_max
Max companies allowed on server.
Definition: game.h:51
std::vector< NetworkAddress > NetworkAddressList
Type for a list of addresses.
Definition: address.h:20
void PrepareToRead()
Prepares the packet so it can be read.
Definition: packet.cpp:198
virtual void Receive_CLIENT_FIND_SERVER(Packet *p, NetworkAddress *client_addr)
Queries to the server for information about the game.
Definition: udp.cpp:336
virtual void HandleIncomingNetworkGameInfoGRFConfig(GRFConfig *config)
Function that is called for every GRFConfig that is read when receiving a NetworkGameInfo.
Definition: udp.h:230
byte companies_on
How many started companies do we have.
Definition: game.h:50
byte * buffer
The buffer of this packet, of basically variable length up to SEND_MTU.
Definition: packet.h:54
Must ALWAYS be on the end of this list!! (period)
Definition: udp.h:35
Information about GRF, used in the game and (part of it) in savegames.
int GetAddressLength()
Get the (valid) length of the address.
Definition: address.h:103
void Send_uint16(uint16 data)
Package a 16 bits integer in the packet.
Definition: packet.cpp:108
byte clients_max
Max clients allowed on server.
Definition: game.h:49
virtual void Receive_CLIENT_GET_LIST(Packet *p, NetworkAddress *client_addr)
The client requests a list of servers.
Definition: udp.cpp:342
Packet to register itself to the master server.
Definition: udp.h:27
Packet indicating registration has succeeded.
Definition: udp.h:28
bool use_password
Is this server passworded?
Definition: game.h:46
virtual void Receive_SERVER_NEWGRFS(Packet *p, NetworkAddress *client_addr)
The server returns information about some NewGRFs.
Definition: udp.cpp:346
void Close() override
Close the given UDP socket.
Definition: udp.cpp:60
Reply of the game server about details of the game, such as companies.
Definition: udp.h:26
uint8 flags
NOSAVE: GCF_Flags, bitset.
NetworkRecvStatus
Status of a network client; reasons why a client has quit.
Definition: core.h:24
static const byte NETWORK_GAME_INFO_VERSION
What version of game-info do we use?
Definition: config.h:38
byte clients_on
Current count of clients on server.
Definition: game.h:28
char server_revision[NETWORK_REVISION_LENGTH]
The version number the server is using (e.g.: &#39;r304&#39; or 0.5.0)
Definition: game.h:42
NetworkRecvStatus CloseConnection(bool error=true) override
Close the current connection; for TCP this will be mostly equivalent to Close(), but for UDP it just ...
Definition: udp.cpp:68
PacketSize size
The size of the whole packet for received packets.
Definition: packet.h:50
virtual void Receive_CLIENT_DETAIL_INFO(Packet *p, NetworkAddress *client_addr)
Query for detailed information about companies.
Definition: udp.cpp:338
virtual void Receive_MASTER_ACK_REGISTER(Packet *p, NetworkAddress *client_addr)
The master server acknowledges the registration.
Definition: udp.cpp:341
bool Recv_bool()
Read a boolean from the packet.
Definition: packet.cpp:210
bool Listen()
Start listening on the given host and port.
Definition: udp.cpp:45
bool dedicated
Is this a dedicated server?
Definition: game.h:43
void SendPacket(Packet *p, NetworkAddress *recv, bool all=false, bool broadcast=false)
Send a packet over UDP.
Definition: udp.cpp:81
static T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition: math_func.hpp:139
#define DEBUG(name, level,...)
Output a line of debugging information.
Definition: debug.h:37
Sends the list of NewGRF&#39;s requested.
Definition: udp.h:33
char map_name[NETWORK_NAME_LENGTH]
Map which is played ["random" for a randomized map].
Definition: game.h:27
byte map_set
Graphical set.
Definition: game.h:54
Date game_date
Current date.
Definition: game.h:37
void HandleUDPPacket(Packet *p, NetworkAddress *client_addr)
Handle an incoming packets by sending it to the correct function.
Definition: udp.cpp:293
uint8 Recv_uint8()
Read a 8 bits integer from the packet.
Definition: packet.cpp:219
virtual void Receive_SERVER_DETAIL_INFO(Packet *p, NetworkAddress *client_addr)
Reply with detailed company information.
Definition: udp.cpp:339
static bool SetNonBlocking(SOCKET d)
Try to set the socket into non-blocking mode.
virtual NetworkRecvStatus CloseConnection(bool error=true)
Close the current connection; for TCP this will be mostly equivalent to Close(), but for UDP it just ...
Definition: core.h:61
void CDECL error(const char *s,...)
Error handling for fatal non-user errors.
Definition: openttd.cpp:114
static const uint16 SEND_MTU
Number of bytes we can pack in a single packet.
Definition: config.h:35
Response from master server with server ip&#39;s + port&#39;s.
Definition: udp.h:30
NetworkAddressList bind
The address to bind to.
Definition: udp.h:51
void ReceiveNetworkGameInfo(Packet *p, NetworkGameInfo *info)
Deserializes the NetworkGameInfo struct from the packet.
Definition: udp.cpp:219
static const uint NETWORK_NUM_LANGUAGES
Number of known languages (to the network protocol) + 1 for &#39;any&#39;.
Definition: config.h:62
Queries a game server about details of the game, such as companies.
Definition: udp.h:25
int32 Date
The type to store our dates in.
Definition: date_type.h:16
Reply of the game server with game information.
Definition: udp.h:24
virtual void Receive_MASTER_RESPONSE_LIST(Packet *p, NetworkAddress *client_addr)
The server sends a list of servers.
Definition: udp.cpp:343
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
void ReceiveGRFIdentifier(Packet *p, GRFIdentifier *grf)
Deserializes the GRFIdentifier (GRF ID and MD5 checksum) from the packet.
Definition: core.cpp:73
Date ConvertYMDToDate(Year year, Month month, Day day)
Converts a tuple of Year, Month and Day to a Date.
Definition: date.cpp:149
uint16 Recv_uint16()
Read a 16 bits integer from the packet.
Definition: packet.cpp:233
static const uint NETWORK_NUM_LANDSCAPES
The number of landscapes in OpenTTD.
Definition: config.h:72
void Send_bool(bool data)
Package a boolean in the packet.
Definition: packet.cpp:89
GRFConfig * grfconfig
List of NewGRF files used.
Definition: game.h:35
void SendGRFIdentifier(Packet *p, const GRFIdentifier *grf)
Serializes the GRFIdentifier (GRF ID and MD5 checksum) to the packet.
Definition: core.cpp:59
static const Year MAX_YEAR
MAX_YEAR, nicely rounded value of the number of years that can be encoded in a single 32 bits date...
Definition: date_type.h:94
Basic functions to receive and send UDP packets.
const sockaddr_storage * GetAddress()
Get the address in its internal representation.
Definition: address.cpp:126
void GetAddressAsString(char *buffer, const char *last, bool with_family=true)
Get the address as a string, e.g.
Definition: address.cpp:79
byte spectators_on
How many spectators do we have?
Definition: game.h:52
static const uint NETWORK_MAX_GRF_COUNT
Maximum number of GRFs that can be sent.
Definition: config.h:60
void Recv_string(char *buffer, size_t size, StringValidationSettings settings=SVS_REPLACE_WITH_QUESTION_MARK)
Reads a string till it finds a &#39;\0&#39; in the stream.
Definition: packet.cpp:288
NetworkUDPSocketHandler(NetworkAddressList *bind=nullptr)
Create an UDP socket but don&#39;t listen yet.
Definition: udp.cpp:25