1 //
2 // SuperTuxKart - a fun racing game with go-kart
3 // Copyright (C) 2013-2015 SuperTuxKart-Team
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 3
8 // of the License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 #include "network/stk_host.hpp"
20
21 #include "config/stk_config.hpp"
22 #include "config/user_config.hpp"
23 #include "io/file_manager.hpp"
24 #include "network/event.hpp"
25 #include "network/game_setup.hpp"
26 #include "network/network.hpp"
27 #include "network/network_config.hpp"
28 #include "network/network_console.hpp"
29 #include "network/network_player_profile.hpp"
30 #include "network/network_string.hpp"
31 #include "network/network_timer_synchronizer.hpp"
32 #include "network/protocols/connect_to_peer.hpp"
33 #include "network/protocols/server_lobby.hpp"
34 #include "network/protocol_manager.hpp"
35 #include "network/server_config.hpp"
36 #include "network/child_loop.hpp"
37 #include "network/stk_ipv6.hpp"
38 #include "network/stk_peer.hpp"
39 #include "utils/log.hpp"
40 #include "utils/string_utils.hpp"
41 #include "utils/time.hpp"
42 #include "utils/vs.hpp"
43
44 #include <string.h>
45 #if defined(WIN32)
46 # include "ws2tcpip.h"
47 # define inet_ntop InetNtop
48 #else
49 # include <arpa/inet.h>
50 # include <errno.h>
51 # include <sys/socket.h>
52 #endif
53
54 #ifdef __MINGW32__
55 # undef _WIN32_WINNT
56 # define _WIN32_WINNT 0x501
57 #endif
58
59 #ifdef WIN32
60 # include <winsock2.h>
61 # include <ws2tcpip.h>
62 #else
63 # include <netdb.h>
64 #endif
65 #include <sys/types.h>
66
67 #include <algorithm>
68 #include <functional>
69 #include <limits>
70 #include <random>
71 #include <string>
72 #include <utility>
73
74 STKHost *STKHost::m_stk_host[PT_COUNT];
75 bool STKHost::m_enable_console = false;
76
create(ChildLoop * cl)77 std::shared_ptr<LobbyProtocol> STKHost::create(ChildLoop* cl)
78 {
79 ProcessType pt = STKProcess::getType();
80 assert(m_stk_host[pt] == NULL);
81 std::shared_ptr<LobbyProtocol> lp;
82 if (NetworkConfig::get()->isServer())
83 {
84 std::shared_ptr<ServerLobby> sl =
85 LobbyProtocol::create<ServerLobby>();
86 m_stk_host[pt] = new STKHost(true/*server*/);
87 sl->initServerStatsTable();
88 lp = sl;
89 }
90 else
91 {
92 m_stk_host[pt] = new STKHost(false/*server*/);
93 }
94 // Separate process for client-server gui if exists
95 m_stk_host[pt]->m_client_loop = cl;
96 if (cl)
97 {
98 m_stk_host[pt]->m_client_loop_thread = std::thread(
99 std::bind(&ChildLoop::run, cl));
100 }
101 if (!m_stk_host[pt]->m_network)
102 {
103 delete m_stk_host[pt];
104 m_stk_host[pt] = NULL;
105 }
106 return lp;
107 } // create
108
109 // ============================================================================
110 /** \class STKHost
111 * \brief Represents the local host. It is the main managing point for
112 * networking. It is responsible for sending and receiving messages,
113 * and keeping track of connected peers. It also provides some low
114 * level socket functions (i.e. to avoid that enet adds its headers
115 * to messages, useful for broadcast in LAN and for stun). It can be
116 * either instantiated as server, or as client.
117 * Additionally this object stores information from the various protocols,
118 * which can be queried by the GUI. The online game works
119 * closely together with the stk server: a (game) server first connects
120 * to the stk server and registers itself, clients find the list of servers
121 * from the stk server. They insert a connections request into the stk
122 * server, which is regularly polled by the client. On detecting a new
123 * connection request the server will try to send a message to the client.
124 * This allows connections between server and client even if they are
125 * sitting behind a NAT firewall. The following tables on
126 * the stk server are used:
127 * client_sessions: It stores the list of all online users (so loging in
128 * means to insert a row in this table), including their token
129 * used for authentication. In case of a client or server, their
130 * public ip address and port number and private port (for LAN)
131 * are added to the entry.
132 * servers: Registers all servers and gives them a unique id, together
133 * with the user id (which is stored as host_id in this table).
134 * server_conn: This table stores connection requests from clients to
135 * servers. It has the aes_key and aes_iv which are used to validate
136 * clients if it's the same online user id joining a server,
137 * ip and port for NAT penetration and a connected_since which
138 * stores the timestamp the user joined this server to know the time
139 * playing spent playing on it.
140 *
141 * The following outlines the protocol happening in order to connect a
142 * client to a server in more details:
143 *
144 * First it calls setPublicAddress() here to discover the public ip address
145 * and port number of this host,
146 * Server:
147 *
148 * 1. ServerLobby:
149 * 1. Register this server with stk server (i.e. publish its public
150 * ip address, port number and game info) - 'create' request. This
151 * enters the server into the 'servers' table. This server can now
152 * be detected by other clients, so they can request a connection.
153 * 2. The server lobby now polls the stk server for client connection
154 * requests using the 'poll-connection-requests' each 5 seconds, which
155 * queries the servers table to get the server id (based on address
156 * and user id), and then the server_conn table. The server will map
157 * each joined AES key within 45 seconds to each connected client to
158 * handle validation.
159 * Client:
160 *
161 * The GUI queries the stk server to get a list of available servers
162 * ('get-all' request, submitted from ServersManager to query the 'servers'
163 * table). The user picks one (or in case of quick play one is picked
164 * randomly), and then instantiates STKHost with the id of this server.
165 * STKHost then triggers ConnectToServer, which do the following:
166 * 1. Register the client with the STK host ('join-server-key' command,
167 * into the table 'server_conn'). Its public ip address and port will
168 * be registerd with a AES key and iv set by client.
169 * 2. Run ConnectToServer::tryConnect for 30 seconds to connect to server,
170 * It will auto change to a correct server port in case the server is
171 * behind a strong firewall, see intercept below.
172 *
173 * Server:
174 *
175 * The ServerLobbyProtocol (SLP) will then detect the above client
176 * requests, and start a ConnectToPeer protocol for each incoming client.
177 * The ConnectToPeer protocol send client a raw packet with
178 * "0xffff" and "aloha-stk", so the client can use the intercept in enet for
179 * advanced NAT penetration, see ConnectToServer::interceptCallback for
180 * details.
181 *
182 * Each client will run a ClientLobbyProtocol (CLP) to handle the further
183 * interaction with the server. The client will first request a connection
184 * with the server (this is for the 'logical' connection to the server; so
185 * far it was mostly about the 'physical' connection, i.e. being able to send
186 * a message to the server).
187 *
188 * Each protocol has its own protocol id, which is added to each message in
189 * Protocol::sendMessage(). The ProtocolManager will automatically forward
190 * each received message to the protocol with the same id. So any message
191 * sent by protocol X on the server will be received by protocol X on the
192 * client and vice versa. The only exception are the client- and server-lobby:
193 * They share the same id (set in LobbyProtocol), so a message sent by
194 * the SLP will be received by the CLP, and a message from the CLP will be
195 * received by the SLP.
196 *
197 * The server will reply with either a reject message (e.g. too many clients
198 * already connected), or an accept message. The accept message will contain
199 * the global player id of the client. Each time any client connect,
200 * disconnect or change team / handicap server will send a new list of
201 * currently available players and update them in the networking lobby.
202 *
203 * When the authorised client or ownerless server timed up and start the kart
204 * selection, the SLP informs all clients to start the kart selection
205 * (SLP::startSelection). This triggers the creation of the kart selection
206 * (if grand prix in progress then goes track screen directly) screen in
207 * CLP::startSelection / CLP::update for all clients. The clients create
208 * the ActivePlayer object (which stores which device is used by which
209 * player).
210 *
211 * After selecting a kart, the track selection screen is shown. On selecting
212 * a track, a vote for the track, laps and reversed is sent to the client
213 * (TrackScreen::eventCallback). The server will send
214 * all votes (track, #laps, ...) to all clients (see e.g. SLP::handlePlayerVote
215 * etc), which are handled in e.g. CLP::receivePlayerVote().
216 *
217 * --> Server and all clients have identical information about all votes
218 * stored in m_peers_votes in LobbyProtocol base class.
219 *
220 * The server will decide the best track vote based on the discussion from
221 * clients, then it will inform all clients to load the world (addAllPlayers)
222 * with the final players currently connected with team / handicap settings.
223 * Then (state LOAD_GAME) the server will load the world and wait for all
224 * clients to finish loading (WAIT_FOR_WORLD_LOADED).
225 *
226 * In LR::loadWorld all ActivePlayers for all non-local players are created.
227 * (on a server all karts are non-local). On a client, the ActivePlayer
228 * objects for each local players have been created (to store the device
229 * used by each player when joining), so they are used to create the
230 * LocalPlayerController for each kart. Each remote player gets a
231 * NULL ActivePlayer (the ActivePlayer is only used for assigning the input
232 * device to each kart, achievements and highscores, so it's not needed for
233 * remote players). It will also start the RaceEventManager and then load the
234 * world.
235 *
236 * Below you can see the definition of ping packet, it's a special packet that
237 * will be sent to each client waiting in lobby, the 1st byte is 255 so
238 * ProtocolManager won't handle it, after 5 bytes it comes with real data:
239 * 1. Server time in uint64_t (for synchronization)
240 * 2. Host id with ping to each client currently connected
241 * 3. If game is currently started, 2 uint32_t which tell remaining time or
242 * progress in percent
243 * 4. If game is currently started, the track internal identity
244 */
245 // ============================================================================
246 constexpr std::array<uint8_t, 5> g_ping_packet {{ 255, 'p', 'i', 'n', 'g' }};
247
248 // ============================================================================
isPingPacket(unsigned char * data,size_t length)249 constexpr bool isPingPacket(unsigned char* data, size_t length)
250 {
251 return length > g_ping_packet.size() && data[0] == g_ping_packet[0] &&
252 data[1] == g_ping_packet[1] && data[2] == g_ping_packet[2] &&
253 data[3] == g_ping_packet[3] && data[4] == g_ping_packet[4];
254 } // isPingPacket
255
256 // ============================================================================
257 /** The constructor for a server or client.
258 */
STKHost(bool server)259 STKHost::STKHost(bool server)
260 {
261 m_public_address.reset(new SocketAddress());
262 init();
263 m_host_id = std::numeric_limits<uint32_t>::max();
264
265 ENetAddress addr = {};
266 if (server)
267 {
268 setIPv6Socket(ServerConfig::m_ipv6_connection ? 1 : 0);
269 #ifdef ENABLE_IPV6
270 if (NetworkConfig::get()->getIPType() == NetworkConfig::IP_V4 &&
271 ServerConfig::m_ipv6_connection)
272 {
273 Log::warn("STKHost", "Disable IPv6 socket due to missing IPv6.");
274 setIPv6Socket(0);
275 }
276 #endif
277 addr.port = ServerConfig::m_server_port;
278 if (addr.port == 0 && !UserConfigParams::m_random_server_port)
279 addr.port = stk_config->m_server_port;
280 // Reserve 1 peer to deliver full server message
281 int peer_count = ServerConfig::m_server_max_players + 1;
282 // 1 more peer to hold ai peer
283 if (ServerConfig::m_ai_handling)
284 peer_count++;
285 m_network = new Network(peer_count,
286 /*channel_limit*/EVENT_CHANNEL_COUNT, /*max_in_bandwidth*/0,
287 /*max_out_bandwidth*/ 0, &addr, true/*change_port_if_bound*/);
288 }
289 else
290 {
291 addr.port = NetworkConfig::get()->getClientPort();
292 // Client only has 1 peer
293 m_network = new Network(/*peer_count*/1,
294 /*channel_limit*/EVENT_CHANNEL_COUNT,
295 /*max_in_bandwidth*/0, /*max_out_bandwidth*/0, &addr,
296 true/*change_port_if_bound*/);
297 m_nts.reset(new NetworkTimerSynchronizer());
298 }
299
300 if (!m_network)
301 {
302 Log::fatal("STKHost", "An error occurred while trying to create an "
303 "ENet server host.");
304 }
305 if (server)
306 Log::info("STKHost", "Server port is %d", getPrivatePort());
307 } // STKHost
308
309 // ----------------------------------------------------------------------------
310 /** Initialises the internal data structures and starts the protocol manager
311 * and the debug console.
312 */
init()313 void STKHost::init()
314 {
315 m_players_in_game.store(0);
316 m_players_waiting.store(0);
317 m_total_players.store(0);
318 m_network_timer.store((int64_t)StkTime::getMonoTimeMs());
319 m_shutdown = false;
320 m_authorised = false;
321 m_network = NULL;
322 m_exit_timeout.store(std::numeric_limits<uint64_t>::max());
323 m_client_ping.store(0);
324
325 // Start with initialising ENet
326 // ============================
327 if (enet_initialize() != 0)
328 {
329 Log::error("STKHost", "Could not initialize enet.");
330 return;
331 }
332
333 Log::info("STKHost", "Host initialized.");
334 Network::openLog(); // Open packet log file
335 ProtocolManager::createInstance();
336
337 // Optional: start the network console
338 if (m_enable_console)
339 {
340 m_network_console = std::thread(std::bind(&NetworkConsole::mainLoop,
341 this));
342 }
343 } // STKHost
344
345 // ----------------------------------------------------------------------------
346 /** Destructor. Stops the listening thread, closes the packet log file and
347 * destroys the enet host.
348 */
~STKHost()349 STKHost::~STKHost()
350 {
351 // Abort the server loop earlier so it can be stopped in background as
352 // soon as possible
353 if (m_client_loop)
354 m_client_loop->abort();
355
356 NetworkConfig::get()->clearActivePlayersForClient();
357 requestShutdown();
358 if (m_network_console.joinable())
359 m_network_console.join();
360
361 disconnectAllPeers(true/*timeout_waiting*/);
362 Network::closeLog();
363 stopListening();
364
365 // Drop all unsent packets
366 for (auto& p : m_enet_cmd)
367 {
368 if (std::get<3>(p) == ECT_SEND_PACKET)
369 {
370 ENetPacket* packet = std::get<1>(p);
371 enet_packet_destroy(packet);
372 }
373 }
374 delete m_network;
375 enet_deinitialize();
376 if (m_client_loop)
377 {
378 m_client_loop_thread.join();
379 delete m_client_loop;
380 }
381 } // ~STKHost
382
383 //-----------------------------------------------------------------------------
384 /** Called from the main thread when the network infrastructure is to be shut
385 * down.
386 */
shutdown()387 void STKHost::shutdown()
388 {
389 ProtocolManager::lock()->abort();
390 destroy();
391 } // shutdown
392
393 //-----------------------------------------------------------------------------
394 /** Get the stun network string required for binding request
395 * \param stun_tansaction_id 16 bytes array for filling to validate later.
396 */
getStunRequest(uint8_t * stun_tansaction_id)397 BareNetworkString STKHost::getStunRequest(uint8_t* stun_tansaction_id)
398 {
399 // Assemble the message for the stun server
400 BareNetworkString s(20);
401
402 constexpr uint32_t magic_cookie = 0x2112A442;
403 // bytes 0-1: the type of the message
404 // bytes 2-3: message length added to header (attributes)
405 uint16_t message_type = 0x0001; // binding request
406 uint16_t message_length = 0x0000;
407 s.addUInt16(message_type).addUInt16(message_length)
408 .addUInt32(magic_cookie);
409
410 stun_tansaction_id[0] = 0x21;
411 stun_tansaction_id[1] = 0x12;
412 stun_tansaction_id[2] = 0xA4;
413 stun_tansaction_id[3] = 0x42;
414 // bytes 8-19: the transaction id
415 for (int i = 0; i < 12; i++)
416 {
417 uint8_t random_byte = rand() % 256;
418 s.addUInt8(random_byte);
419 stun_tansaction_id[i + 4] = random_byte;
420 }
421 return s;
422 } // getStunRequest
423
424 //-----------------------------------------------------------------------------
getIPFromStun(int socket,const std::string & stun_address,short family,SocketAddress * result)425 void STKHost::getIPFromStun(int socket, const std::string& stun_address,
426 short family, SocketAddress* result)
427 {
428 // The IPv4 stun address has no AAAA record, so give it an AF_INET6 will
429 // return one using NAT64 and DNS64
430 if (isIPv6Socket() && family == AF_INET &&
431 NetworkConfig::get()->getIPType() == NetworkConfig::IP_V6_NAT64)
432 family = AF_INET6;
433
434 SocketAddress stun(stun_address, 0/*port is specified in address*/,
435 family);
436 // We specify ai_family, so only IPv4 or IPv6 is found
437 if (stun.isUnset())
438 return;
439 stun.convertForIPv6Socket(isIPv6Socket());
440
441 // We only need to keep the stun address for server to keep the port open
442 if (NetworkConfig::get()->isServer())
443 {
444 if (stun.isIPv6())
445 m_stun_ipv6.reset(new SocketAddress(stun));
446 else
447 m_stun_ipv4.reset(new SocketAddress(stun));
448 }
449
450 uint8_t stun_tansaction_id[16];
451 constexpr uint32_t magic_cookie = 0x2112A442;
452 BareNetworkString s = getStunRequest(stun_tansaction_id);
453
454 sendto(socket, s.getData(), s.size(), 0, stun.getSockaddr(),
455 stun.getSocklen());
456
457 // Recieve now
458 const int LEN = 2048;
459 char buffer[LEN];
460
461 struct sockaddr_in addr4_rev;
462 struct sockaddr_in6 addr6_rev;
463 struct sockaddr* addr_rev = isIPv6Socket() ?
464 (struct sockaddr*)(&addr6_rev) : (struct sockaddr*)(&addr4_rev);
465 socklen_t from_len = isIPv6Socket() ? sizeof(addr6_rev) : sizeof(addr4_rev);
466 int len = -1;
467 int count = 0;
468 while (len < 0 && count < 2000)
469 {
470 len = recvfrom(socket, buffer, LEN, 0, addr_rev,
471 &from_len);
472 if (len > 0)
473 break;
474 count++;
475 StkTime::sleep(1);
476 }
477
478 if (len <= 0)
479 {
480 Log::error("STKHost", "STUN response contains no data at all");
481 return;
482 }
483
484 // Convert to network string.
485 BareNetworkString response(buffer, len);
486 if (response.size() < 20)
487 {
488 Log::error("STKHost", "STUN response should be at least 20 bytes.");
489 return;
490 }
491
492 if (response.getUInt16() != 0x0101)
493 {
494 Log::error("STKHost", "STUN has no binding success response.");
495 return;
496 }
497
498 // Skip message size
499 response.getUInt16();
500
501 if (response.getUInt32() != magic_cookie)
502 {
503 Log::error("STKHost", "STUN response doesn't contain the magic "
504 "cookie");
505 return;
506 }
507
508 for (int i = 0; i < 12; i++)
509 {
510 if (response.getUInt8() != stun_tansaction_id[i + 4])
511 {
512 Log::error("STKHost", "STUN response doesn't contain the "
513 "transaction ID");
514 return;
515 }
516 }
517
518 // The stun message is valid, so we parse it now:
519 // Those are the port and the address to be detected
520 SocketAddress non_xor_addr, xor_addr;
521 while (true)
522 {
523 if (response.size() < 4)
524 break;
525
526 unsigned type = response.getUInt16();
527 unsigned size = response.getUInt16();
528
529 // Bit determining whether comprehension of an attribute is optional.
530 // Described in section 15 of RFC 5389.
531 constexpr uint16_t comprehension_optional = 0x1 << 15;
532
533 // Bit determining whether the bit was assigned by IETF Review.
534 // Described in section 18.1. of RFC 5389.
535 constexpr uint16_t IETF_review = 0x1 << 14;
536
537 // Defined in section 15.1 of RFC 5389
538 constexpr uint8_t ipv4_returned = 0x01;
539 constexpr uint8_t ipv6_returned = 0x02;
540
541 // Defined in section 18.2 of RFC 5389
542 constexpr uint16_t mapped_address = 0x001;
543 constexpr uint16_t xor_mapped_address = 0x0020;
544 // The first two bits are irrelevant to the type
545 type &= ~(comprehension_optional | IETF_review);
546 if (type == mapped_address || type == xor_mapped_address)
547 {
548 if (response.size() < 2)
549 {
550 Log::error("STKHost", "Invalid STUN mapped address length.");
551 return;
552 }
553 // Ignore the first byte as mentioned in Section 15.1 of RFC 5389.
554 uint8_t ip_type = response.getUInt8();
555 ip_type = response.getUInt8();
556 if (ip_type == ipv4_returned)
557 {
558 // Above got 2 bytes
559 if (size != 8 || response.size() < 6)
560 {
561 Log::error("STKHost", "Invalid STUN mapped address length.");
562 return;
563 }
564 uint16_t port = response.getUInt16();
565 uint32_t ip = response.getUInt32();
566 if (type == xor_mapped_address)
567 {
568 // Obfuscation is described in Section 15.2 of RFC 5389.
569 port ^= magic_cookie >> 16;
570 ip ^= magic_cookie;
571 xor_addr.setIP(ip);
572 xor_addr.setPort(port);
573 }
574 else
575 {
576 non_xor_addr.setIP(ip);
577 non_xor_addr.setPort(port);
578 }
579 }
580 else if (ip_type == ipv6_returned)
581 {
582 // Above got 2 bytes
583 if (size != 20 || response.size() < 18)
584 {
585 Log::error("STKHost", "Invalid STUN mapped address length.");
586 return;
587 }
588 uint16_t port = response.getUInt16();
589 uint8_t bytes[16];
590 for (int i = 0; i < 16; i++)
591 bytes[i] = response.getUInt8();
592 if (type == xor_mapped_address)
593 {
594 port ^= magic_cookie >> 16;
595 for (int i = 0; i < 16; i++)
596 bytes[i] ^= stun_tansaction_id[i];
597 xor_addr.setIPv6(bytes, port);
598 }
599 else
600 {
601 non_xor_addr.setIPv6(bytes, port);
602 }
603 }
604 } // type == mapped_address || type == xor_mapped_address
605 else
606 {
607 response.skip(size);
608 int padding = size % 4;
609 if (padding != 0)
610 response.skip(4 - padding);
611 }
612 } // while true
613 // Found public address and port
614 if (!xor_addr.isUnset() || !non_xor_addr.isUnset())
615 {
616 // Use XOR mapped address when possible to avoid translation of
617 // the packet content by application layer gateways (ALGs) that
618 // perform deep packet inspection in an attempt to perform
619 // alternate NAT traversal methods.
620 if (!xor_addr.isUnset())
621 {
622 *result = xor_addr;
623 }
624 else
625 {
626 Log::warn("STKHost", "Only non xor-mapped address returned.");
627 *result = non_xor_addr;
628 }
629 }
630 } // getIPFromStun
631
632 //-----------------------------------------------------------------------------
633 /** Set the public address using stun protocol.
634 */
setPublicAddress(short family)635 void STKHost::setPublicAddress(short family)
636 {
637 auto& stunv4_map = UserConfigParams::m_stun_servers_v4;
638 for (auto& s : NetworkConfig::getStunList(true/*ipv4*/))
639 {
640 if (s.second == 0)
641 stunv4_map.erase(s.first);
642 else if (stunv4_map.find(s.first) == stunv4_map.end())
643 stunv4_map[s.first] = 0;
644 }
645
646 auto& stunv6_map = UserConfigParams::m_stun_servers;
647 for (auto& s : NetworkConfig::getStunList(false/*ipv4*/))
648 {
649 if (s.second == 0)
650 stunv6_map.erase(s.first);
651 else if (stunv6_map.find(s.first) == stunv6_map.end())
652 stunv6_map[s.first] = 0;
653 }
654
655 auto& stun_map = family == AF_INET ? UserConfigParams::m_stun_servers_v4 :
656 UserConfigParams::m_stun_servers;
657 std::vector<std::pair<std::string, uint32_t> > untried_server;
658 for (auto& p : stun_map)
659 untried_server.push_back(p);
660
661 // Randomly use stun servers of the low ping from top-half of the list
662 std::sort(untried_server.begin(), untried_server.end(),
663 [] (const std::pair<std::string, uint32_t>& a,
664 const std::pair<std::string, uint32_t>& b)->bool
665 {
666 return a.second > b.second;
667 });
668 std::random_device rd;
669 std::mt19937 g(rd());
670 if (untried_server.size() > 2)
671 {
672 std::shuffle(untried_server.begin() + (untried_server.size() / 2),
673 untried_server.end(), g);
674 }
675 else
676 {
677 Log::warn("STKHost", "Failed to get enough stun servers using SRV"
678 " record.");
679 }
680
681 while (!untried_server.empty() && !ProtocolManager::lock()->isExiting())
682 {
683 // Pick last element in untried servers
684 std::string server_name = untried_server.back().first.c_str();
685 stun_map[server_name] = (uint32_t)-1;
686 Log::debug("STKHost", "Using STUN server %s", server_name.c_str());
687 uint64_t ping = StkTime::getMonoTimeMs();
688 SocketAddress result;
689 getIPFromStun((int)m_network->getENetHost()->socket, server_name, family,
690 &result);
691 if (!result.isUnset())
692 {
693 if (result.getFamily() != family)
694 {
695 Log::error("STKHost",
696 "Public address family differ from request");
697 // This happens when you force to use IPv6 connection to detect
698 // public address if there is only IPv4 connection, which it
699 // will give you an IPv4 address, so we can exit earlier
700 return;
701 }
702 // For dual stack server we get the IPv6 address and then IPv4, if
703 // their ports differ we discard the public IPv6 address of server
704 if (NetworkConfig::get()->isServer() && family == AF_INET &&
705 result.getPort() != m_public_address->getPort())
706 {
707 if (isIPv6Socket())
708 {
709 Log::error("STKHost",
710 "IPv6 has different port than IPv4.");
711 }
712 m_public_ipv6_address.clear();
713 }
714 if (family == AF_INET)
715 *m_public_address = result;
716 else
717 m_public_ipv6_address = result.toString(false/*show_port*/);
718 m_public_address->setPort(result.getPort());
719 ping = StkTime::getMonoTimeMs() - ping;
720 // Succeed, save ping
721 stun_map[server_name] = (uint32_t)(ping);
722 untried_server.clear();
723 }
724 else
725 {
726 // Erase from user config in stun, if it's provide by SRV records
727 // from STK then it will be re-added next time, and STK team will
728 // remove it if it stops working
729 stun_map.erase(untried_server.back().first);
730 untried_server.pop_back();
731 }
732 }
733 } // setPublicAddress
734
735 //-----------------------------------------------------------------------------
736 /** Disconnect all connected peers.
737 */
disconnectAllPeers(bool timeout_waiting)738 void STKHost::disconnectAllPeers(bool timeout_waiting)
739 {
740 std::lock_guard<std::mutex> lock(m_peers_mutex);
741 if (!m_peers.empty() && timeout_waiting)
742 {
743 for (auto peer : m_peers)
744 peer.second->disconnect();
745 // Wait for at most 2 seconds for disconnect event to be generated
746 m_exit_timeout.store(StkTime::getMonoTimeMs() + 2000);
747 }
748 m_peers.clear();
749 } // disconnectAllPeers
750
751 //-----------------------------------------------------------------------------
752 /** Sets an error message for the gui.
753 */
setErrorMessage(const irr::core::stringw & message)754 void STKHost::setErrorMessage(const irr::core::stringw &message)
755 {
756 if (!message.empty())
757 {
758 Log::error("STKHost", "%s", StringUtils::wideToUtf8(message).c_str());
759 }
760 m_error_message = message;
761 } // setErrorMessage
762
763 // ----------------------------------------------------------------------------
764 /** \brief Starts the listening of events from ENet.
765 * Starts a thread for receiveData that updates it as often as possible.
766 */
startListening()767 void STKHost::startListening()
768 {
769 m_exit_timeout.store(std::numeric_limits<uint64_t>::max());
770 m_listening_thread = std::thread(std::bind(&STKHost::mainLoop, this,
771 STKProcess::getType()));
772 } // startListening
773
774 // ----------------------------------------------------------------------------
775 /** \brief Stops the listening of events from ENet.
776 * Stops the thread that was receiving events.
777 */
stopListening()778 void STKHost::stopListening()
779 {
780 if (m_exit_timeout.load() == std::numeric_limits<uint64_t>::max())
781 m_exit_timeout.store(0);
782 if (m_listening_thread.joinable())
783 m_listening_thread.join();
784 } // stopListening
785
786 // ----------------------------------------------------------------------------
787 /** \brief Thread function checking if data is received.
788 * This function tries to get data from network low-level functions as
789 * often as possible. When something is received, it generates an
790 * event and passes it to the Network Manager.
791 * \param pt : Used to register to different singleton.
792 */
mainLoop(ProcessType pt)793 void STKHost::mainLoop(ProcessType pt)
794 {
795 std::string thread_name = "STKHost";
796 if (pt == PT_CHILD)
797 thread_name += "_child";
798 VS::setThreadName(thread_name.c_str());
799
800 STKProcess::init(pt);
801 Log::info("STKHost", "Listening has been started.");
802 ENetEvent event;
803 ENetHost* host = m_network->getENetHost();
804 const bool is_server = NetworkConfig::get()->isServer();
805
806 // A separate network connection (socket) to handle LAN requests.
807 Network* direct_socket = NULL;
808 if ((NetworkConfig::get()->isLAN() && is_server) ||
809 NetworkConfig::get()->isPublicServer())
810 {
811 ENetAddress eaddr = {};
812 eaddr.port = stk_config->m_server_discovery_port;
813 direct_socket = new Network(1, 1, 0, 0, &eaddr);
814 if (direct_socket->getENetHost() == NULL)
815 {
816 Log::warn("STKHost", "No direct socket available, this "
817 "server may not be connected by lan network");
818 delete direct_socket;
819 direct_socket = NULL;
820 }
821 }
822
823 uint64_t last_ping_time = StkTime::getMonoTimeMs();
824 uint64_t last_update_speed_time = StkTime::getMonoTimeMs();
825 uint64_t last_ping_time_update_for_client = StkTime::getMonoTimeMs();
826 std::map<std::string, uint64_t> ctp;
827 while (m_exit_timeout.load() > StkTime::getMonoTimeMs())
828 {
829 // Clear outdated connect to peer list every 15 seconds
830 for (auto it = ctp.begin(); it != ctp.end();)
831 {
832 if (it->second + 15000 < StkTime::getMonoTimeMs())
833 it = ctp.erase(it);
834 else
835 it++;
836 }
837
838 if (last_update_speed_time < StkTime::getMonoTimeMs())
839 {
840 // Update upload / download speed per second
841 last_update_speed_time = StkTime::getMonoTimeMs() + 1000;
842 m_upload_speed.store(getNetwork()->getENetHost()->totalSentData);
843 m_download_speed.store(
844 getNetwork()->getENetHost()->totalReceivedData);
845 getNetwork()->getENetHost()->totalSentData = 0;
846 getNetwork()->getENetHost()->totalReceivedData = 0;
847 }
848
849 auto sl = LobbyProtocol::get<ServerLobby>();
850 if (direct_socket && sl && sl->waitingForPlayers())
851 {
852 try
853 {
854 handleDirectSocketRequest(direct_socket, sl, ctp);
855 }
856 catch (std::exception& e)
857 {
858 Log::warn("STKHost", "Direct socket error: %s",
859 e.what());
860 }
861 } // if discovery host
862
863 if (is_server)
864 {
865 std::unique_lock<std::mutex> peer_lock(m_peers_mutex);
866 const float timeout = ServerConfig::m_validation_timeout;
867 bool need_ping = false;
868 if (sl && (!sl->isRacing() || sl->allowJoinedPlayersWaiting()) &&
869 last_ping_time < StkTime::getMonoTimeMs())
870 {
871 // If not racing, send an reliable packet at the 10 packets
872 // per second, which is for accurate ping calculation by enet
873 last_ping_time = StkTime::getMonoTimeMs() +
874 (uint64_t)((1.0f / 10.0f) * 1000.0f);
875 need_ping = true;
876 }
877
878 BareNetworkString ping_packet;
879 if (need_ping)
880 {
881 m_peer_pings.getData().clear();
882 for (auto& p : m_peers)
883 {
884 m_peer_pings.getData()[p.second->getHostId()] =
885 p.second->getPing();
886 // Set packet loss before enet command, so if the peer is
887 // disconnected later the loss won't be cleared
888 p.second->setPacketLoss(p.first->packetLoss);
889 const unsigned ap = p.second->getAveragePing();
890 const unsigned max_ping = ServerConfig::m_max_ping;
891 if (p.second->isValidated() &&
892 p.second->getConnectedTime() > 5.0f && ap > max_ping)
893 {
894 std::string player_name;
895 if (!p.second->getPlayerProfiles().empty())
896 {
897 player_name = StringUtils::wideToUtf8
898 (p.second->getPlayerProfiles()[0]->getName());
899 }
900 const bool peer_not_in_game =
901 sl->getCurrentState() <= ServerLobby::SELECTING
902 || p.second->isWaitingForGame();
903 if (ServerConfig::m_kick_high_ping_players &&
904 !p.second->isDisconnected() && peer_not_in_game)
905 {
906 Log::info("STKHost", "%s %s with ping %d is higher"
907 " than %d ms when not in game, kick.",
908 p.second->getAddress().toString().c_str(),
909 player_name.c_str(), ap, max_ping);
910 p.second->setWarnedForHighPing(true);
911 p.second->setDisconnected(true);
912 std::lock_guard<std::mutex> lock(m_enet_cmd_mutex);
913 m_enet_cmd.emplace_back(p.second->getENetPeer(),
914 (ENetPacket*)NULL, PDI_KICK_HIGH_PING,
915 ECT_DISCONNECT, p.first->address);
916 }
917 else if (!p.second->hasWarnedForHighPing())
918 {
919 Log::info("STKHost", "%s %s with ping %d is higher"
920 " than %d ms.",
921 p.second->getAddress().toString().c_str(),
922 player_name.c_str(), ap, max_ping);
923 p.second->setWarnedForHighPing(true);
924 NetworkString msg(PROTOCOL_LOBBY_ROOM);
925 msg.setSynchronous(true);
926 msg.addUInt8(LobbyProtocol::LE_BAD_CONNECTION);
927 p.second->sendPacket(&msg, /*reliable*/true);
928 }
929 }
930 }
931 uint64_t network_timer = getNetworkTimer();
932 ping_packet.addUInt64(network_timer);
933 ping_packet.addUInt8((uint8_t)m_peer_pings.getData().size());
934 for (auto& p : m_peer_pings.getData())
935 ping_packet.addUInt32(p.first).addUInt32(p.second);
936 if (sl)
937 {
938 auto progress = sl->getGameStartedProgress();
939 ping_packet.addUInt32(progress.first)
940 .addUInt32(progress.second);
941 ping_packet.encodeString(sl->getPlayingTrackIdent());
942 }
943 else
944 {
945 ping_packet.addUInt32(std::numeric_limits<uint32_t>::max())
946 .addUInt32(std::numeric_limits<uint32_t>::max())
947 .addUInt8(0);
948 }
949 ping_packet.getBuffer().insert(
950 ping_packet.getBuffer().begin(), g_ping_packet.begin(),
951 g_ping_packet.end());
952 }
953
954 for (auto it = m_peers.begin(); it != m_peers.end();)
955 {
956 if (!ping_packet.getBuffer().empty() &&
957 (!sl->allowJoinedPlayersWaiting() ||
958 !sl->isRacing() || it->second->isWaitingForGame()))
959 {
960 ENetPacket* packet = enet_packet_create(ping_packet.getData(),
961 ping_packet.getTotalSize(), ENET_PACKET_FLAG_RELIABLE);
962 if (packet)
963 {
964 // If enet_peer_send failed, destroy the packet to
965 // prevent leaking, this can only be done if the packet
966 // is copied instead of shared sending to all peers
967 if (enet_peer_send(
968 it->first, EVENT_CHANNEL_UNENCRYPTED, packet) < 0)
969 {
970 enet_packet_destroy(packet);
971 }
972 }
973 }
974
975 // Remove peer which has not been validated after a specific time
976 // It is validated when the first connection request has finished
977 if (!it->second->isAIPeer() &&
978 !it->second->isValidated() &&
979 it->second->getConnectedTime() > timeout)
980 {
981 Log::info("STKHost", "%s has not been validated for more"
982 " than %f seconds, disconnect it by force.",
983 it->second->getAddress().toString().c_str(),
984 timeout);
985 enet_host_flush(host);
986 enet_peer_reset(it->first);
987 it = m_peers.erase(it);
988 }
989 else
990 {
991 it++;
992 }
993 }
994 peer_lock.unlock();
995 }
996
997 std::vector<std::tuple<ENetPeer*, ENetPacket*, uint32_t,
998 ENetCommandType, ENetAddress> > copied_list;
999 std::unique_lock<std::mutex> lock(m_enet_cmd_mutex);
1000 std::swap(copied_list, m_enet_cmd);
1001 lock.unlock();
1002 for (auto& p : copied_list)
1003 {
1004 ENetPeer* peer = std::get<0>(p);
1005 ENetAddress& ea = std::get<4>(p);
1006 ENetAddress& ea_peer_now = peer->address;
1007 ENetPacket* packet = std::get<1>(p);
1008 // Enet will reuse a disconnected peer so we check here to avoid
1009 // sending to wrong peer
1010 if (peer->state != ENET_PEER_STATE_CONNECTED ||
1011 #ifdef ENABLE_IPV6
1012 (enet_ip_not_equal(ea_peer_now.host, ea.host) &&
1013 ea_peer_now.port != ea.port))
1014 #else
1015 (ea_peer_now.host != ea.host && ea_peer_now.port != ea.port))
1016 #endif
1017 {
1018 if (packet != NULL)
1019 enet_packet_destroy(packet);
1020 continue;
1021 }
1022
1023 switch (std::get<3>(p))
1024 {
1025 case ECT_SEND_PACKET:
1026 {
1027 // If enet_peer_send failed, destroy the packet to
1028 // prevent leaking, this can only be done if the packet
1029 // is copied instead of shared sending to all peers
1030 if (enet_peer_send(peer, (uint8_t)std::get<2>(p), packet) < 0)
1031 {
1032 enet_packet_destroy(packet);
1033 }
1034 break;
1035 }
1036 case ECT_DISCONNECT:
1037 enet_peer_disconnect(peer, std::get<2>(p));
1038 break;
1039 case ECT_RESET:
1040 // Flush enet before reset (so previous command is send)
1041 enet_host_flush(host);
1042 enet_peer_reset(peer);
1043 // Remove the stk peer of it
1044 std::lock_guard<std::mutex> lock(m_peers_mutex);
1045 m_peers.erase(peer);
1046 break;
1047 }
1048 }
1049
1050 bool need_ping_update = false;
1051 while (enet_host_service(host, &event, 10) != 0)
1052 {
1053 auto lp = LobbyProtocol::get<LobbyProtocol>();
1054 if (!is_server &&
1055 last_ping_time_update_for_client < StkTime::getMonoTimeMs())
1056 {
1057 last_ping_time_update_for_client =
1058 StkTime::getMonoTimeMs() + 2000;
1059 if (lp && lp->isRacing())
1060 {
1061 auto p = getServerPeerForClient();
1062 if (p)
1063 {
1064 m_client_ping.store(p->getPing(),
1065 std::memory_order_relaxed);
1066 }
1067 need_ping_update = false;
1068 }
1069 else
1070 need_ping_update = true;
1071 }
1072 if (event.type == ENET_EVENT_TYPE_NONE)
1073 continue;
1074
1075 Event* stk_event = NULL;
1076 if (event.type == ENET_EVENT_TYPE_CONNECT)
1077 {
1078 // ++m_next_unique_host_id for unique host id for database
1079 auto stk_peer = std::make_shared<STKPeer>
1080 (event.peer, this, ++m_next_unique_host_id);
1081 std::unique_lock<std::mutex> lock(m_peers_mutex);
1082 m_peers[event.peer] = stk_peer;
1083 size_t new_peer_count = m_peers.size();
1084 lock.unlock();
1085 stk_event = new Event(&event, stk_peer);
1086 Log::info("STKHost", "%s has just connected. There are "
1087 "now %u peers.", stk_peer->getAddress().toString().c_str(),
1088 new_peer_count);
1089 // Client always trust the server
1090 if (!is_server)
1091 stk_peer->setValidated(true);
1092 } // ENET_EVENT_TYPE_CONNECT
1093 else if (event.type == ENET_EVENT_TYPE_DISCONNECT)
1094 {
1095 Log::flushBuffers();
1096
1097 // If used a timeout waiting disconnect, exit now
1098 if (m_exit_timeout.load() !=
1099 std::numeric_limits<uint64_t>::max())
1100 {
1101 m_exit_timeout.store(0);
1102 break;
1103 }
1104 // Use the previous stk peer so protocol can see the network
1105 // profile and handle it for disconnection
1106 std::string addr;
1107 std::lock_guard<std::mutex> lock(m_peers_mutex);
1108 size_t new_peer_count = m_peers.size();
1109 if (m_peers.find(event.peer) != m_peers.end())
1110 {
1111 std::shared_ptr<STKPeer>& peer = m_peers.at(event.peer);
1112 addr = peer->getAddress().toString();
1113 stk_event = new Event(&event, peer);
1114 m_peers.erase(event.peer);
1115 new_peer_count = m_peers.size();
1116 }
1117 Log::info("STKHost", "%s has just disconnected. There are "
1118 "now %u peers.", addr.c_str(), new_peer_count);
1119 } // ENET_EVENT_TYPE_DISCONNECT
1120
1121 std::unique_lock<std::mutex> lock(m_peers_mutex);
1122 if (!stk_event && m_peers.find(event.peer) != m_peers.end())
1123 {
1124 std::shared_ptr<STKPeer> peer = m_peers.at(event.peer);
1125 lock.unlock();
1126 if (isPingPacket(event.packet->data, event.packet->dataLength))
1127 {
1128 if (!is_server)
1129 {
1130 BareNetworkString ping_packet((char*)event.packet->data,
1131 (int)event.packet->dataLength);
1132 std::map<uint32_t, uint32_t> peer_pings;
1133 ping_packet.skip((int)g_ping_packet.size());
1134 uint64_t server_time = ping_packet.getUInt64();
1135 unsigned peer_size = ping_packet.getUInt8();
1136 for (unsigned i = 0; i < peer_size; i++)
1137 {
1138 unsigned host_id = ping_packet.getUInt32();
1139 unsigned ping = ping_packet.getUInt32();
1140 peer_pings[host_id] = ping;
1141 }
1142 const uint32_t client_ping =
1143 peer_pings.find(m_host_id) != peer_pings.end() ?
1144 peer_pings.at(m_host_id) : 0;
1145 uint32_t remaining_time =
1146 std::numeric_limits<uint32_t>::max();
1147 uint32_t progress =
1148 std::numeric_limits<uint32_t>::max();
1149 std::string current_track;
1150 try
1151 {
1152 remaining_time = ping_packet.getUInt32();
1153 progress = ping_packet.getUInt32();
1154 ping_packet.decodeString(¤t_track);
1155 }
1156 catch (std::exception& e)
1157 {
1158 // For old server
1159 Log::debug("STKHost", "%s", e.what());
1160 }
1161 if (client_ping > 0)
1162 {
1163 assert(m_nts);
1164 m_nts->addAndSetTime(client_ping, server_time);
1165 }
1166 if (need_ping_update)
1167 {
1168 m_peer_pings.lock();
1169 std::swap(m_peer_pings.getData(), peer_pings);
1170 m_peer_pings.unlock();
1171 m_client_ping.store(client_ping,
1172 std::memory_order_relaxed);
1173 if (lp)
1174 {
1175 lp->setGameStartedProgress(
1176 std::make_pair(remaining_time, progress));
1177 lp->storePlayingTrack(current_track);
1178 }
1179 }
1180 }
1181 enet_packet_destroy(event.packet);
1182 continue;
1183 }
1184 try
1185 {
1186 stk_event = new Event(&event, peer);
1187 }
1188 catch (std::exception& e)
1189 {
1190 Log::warn("STKHost", "%s", e.what());
1191 enet_packet_destroy(event.packet);
1192 continue;
1193 }
1194 }
1195 else if (!stk_event)
1196 {
1197 enet_packet_destroy(event.packet);
1198 continue;
1199 }
1200 if (stk_event->getType() == EVENT_TYPE_MESSAGE)
1201 {
1202 Network::logPacket(stk_event->data(), true);
1203 #ifdef DEBUG_MESSAGE_CONTENT
1204 Log::verbose("NetworkManager",
1205 "Message, Sender : %s time %f message:",
1206 stk_event->getPeer()->getAddress()
1207 .toString(/*show port*/false).c_str(),
1208 StkTime::getRealTime());
1209 Log::verbose("NetworkManager", "%s",
1210 stk_event->data().getLogMessage().c_str());
1211 #endif
1212 } // if message event
1213
1214 // notify for the event now.
1215 auto pm = ProtocolManager::lock();
1216 if (pm && !pm->isExiting())
1217 pm->propagateEvent(stk_event);
1218 else
1219 delete stk_event;
1220 } // while enet_host_service
1221 } // while m_exit_timeout.load() > StkTime::getMonoTimeMs()
1222 delete direct_socket;
1223 Log::info("STKHost", "Listening has been stopped.");
1224 } // mainLoop
1225
1226 // ----------------------------------------------------------------------------
1227 /** Handles a direct request given to a socket. This is typically a LAN
1228 * request, but can also be used if the server is public (i.e. not behind
1229 * a fire wall) to allow direct connection to the server (without using the
1230 * STK server). It checks for any messages (i.e. a LAN broadcast requesting
1231 * server details or a connection request) and if a valid LAN server-request
1232 * message is received, will answer with a message containing server details
1233 * (and sender IP address and port).
1234 */
handleDirectSocketRequest(Network * direct_socket,std::shared_ptr<ServerLobby> sl,std::map<std::string,uint64_t> & ctp)1235 void STKHost::handleDirectSocketRequest(Network* direct_socket,
1236 std::shared_ptr<ServerLobby> sl,
1237 std::map<std::string, uint64_t>& ctp)
1238 {
1239 const int LEN=2048;
1240 char buffer[LEN];
1241
1242 SocketAddress sender;
1243 int len = direct_socket->receiveRawPacket(buffer, LEN, &sender, 1);
1244 if(len<=0) return;
1245 BareNetworkString message(buffer, len);
1246 std::string command;
1247 message.decodeString(&command);
1248 const std::string connection_cmd = std::string("connection-request") +
1249 StringUtils::toString(getPrivatePort());
1250
1251 if (command == "stk-server")
1252 {
1253 Log::verbose("STKHost", "Received LAN server query");
1254 const std::string& name = sl->getGameSetup()->getServerNameUtf8();
1255 // Send the answer, consisting of server name, max players,
1256 // current players
1257 const std::string& pw = ServerConfig::m_private_server_password;
1258 BareNetworkString s((int)name.size()+1+11);
1259 s.addUInt32(ServerConfig::m_server_version);
1260 s.encodeString(name);
1261 s.addUInt8((uint8_t)ServerConfig::m_server_max_players);
1262 s.addUInt8((uint8_t)sl->getLobbyPlayers());
1263 s.addUInt16(getPrivatePort());
1264 s.addUInt8((uint8_t)sl->getDifficulty());
1265 s.addUInt8((uint8_t)sl->getGameMode());
1266 s.addUInt8(!pw.empty());
1267 s.addUInt8((uint8_t)
1268 (sl->getCurrentState() == ServerLobby::WAITING_FOR_START_GAME ?
1269 0 : 1));
1270 s.encodeString(sl->getPlayingTrackIdent());
1271 direct_socket->sendRawPacket(s, sender);
1272 } // if message is server-requested
1273 else if (command == connection_cmd)
1274 {
1275 const std::string& peer_addr = sender.toString();
1276 // In case of a LAN connection, we only allow connections from
1277 // a LAN address (192.168*, ..., and 127.*).
1278 if (!sender.isLAN() && !sender.isPublicAddressLocalhost() &&
1279 !NetworkConfig::get()->isPublicServer())
1280 {
1281 Log::error("STKHost", "Client trying to connect from '%s'",
1282 peer_addr.c_str());
1283 Log::error("STKHost", "which is outside of LAN - rejected.");
1284 return;
1285 }
1286 if (ctp.find(peer_addr) == ctp.end())
1287 {
1288 ctp[peer_addr] = StkTime::getMonoTimeMs();
1289 std::make_shared<ConnectToPeer>(sender)->requestStart();
1290 }
1291 }
1292 else if (command == "stk-server-port")
1293 {
1294 BareNetworkString s;
1295 s.addUInt16(getPrivatePort());
1296 direct_socket->sendRawPacket(s, sender);
1297 }
1298 else
1299 Log::info("STKHost", "Received unknown command '%s'",
1300 std::string(buffer, len).c_str());
1301
1302 } // handleDirectSocketRequest
1303
1304 // ----------------------------------------------------------------------------
1305 /** \brief Tells if a peer is known.
1306 * \return True if the peer is known, false elseway.
1307 */
peerExists(const SocketAddress & peer)1308 bool STKHost::peerExists(const SocketAddress& peer)
1309 {
1310 std::lock_guard<std::mutex> lock(m_peers_mutex);
1311 for (auto p : m_peers)
1312 {
1313 auto stk_peer = p.second;
1314 if (stk_peer->getAddress() == peer ||
1315 ((stk_peer->getAddress().isPublicAddressLocalhost() &&
1316 peer.isPublicAddressLocalhost()) &&
1317 stk_peer->getAddress().getPort() == peer.getPort()))
1318 return true;
1319 }
1320 return false;
1321 } // peerExists
1322
1323 // ----------------------------------------------------------------------------
1324 /** \brief Return the only server peer for client.
1325 * \return STKPeer the STKPeer of server.
1326 */
getServerPeerForClient() const1327 std::shared_ptr<STKPeer> STKHost::getServerPeerForClient() const
1328 {
1329 assert(NetworkConfig::get()->isClient());
1330 if (m_peers.size() != 1)
1331 return nullptr;
1332 return m_peers.begin()->second;
1333 } // getServerPeerForClient
1334
1335 //-----------------------------------------------------------------------------
1336 /** Sends data to all validated peers currently in server
1337 * \param data Data to sent.
1338 * \param reliable If the data should be sent reliable or now.
1339 */
sendPacketToAllPeersInServer(NetworkString * data,bool reliable)1340 void STKHost::sendPacketToAllPeersInServer(NetworkString *data, bool reliable)
1341 {
1342 std::lock_guard<std::mutex> lock(m_peers_mutex);
1343 for (auto p : m_peers)
1344 {
1345 if (p.second->isValidated())
1346 p.second->sendPacket(data, reliable);
1347 }
1348 } // sendPacketToAllPeersInServer
1349
1350 //-----------------------------------------------------------------------------
1351 /** Sends data to all validated peers currently in game
1352 * \param data Data to sent.
1353 * \param reliable If the data should be sent reliable or now.
1354 */
sendPacketToAllPeers(NetworkString * data,bool reliable)1355 void STKHost::sendPacketToAllPeers(NetworkString *data, bool reliable)
1356 {
1357 std::lock_guard<std::mutex> lock(m_peers_mutex);
1358 for (auto p : m_peers)
1359 {
1360 if (p.second->isValidated() && !p.second->isWaitingForGame())
1361 p.second->sendPacket(data, reliable);
1362 }
1363 } // sendPacketToAllPeers
1364
1365 //-----------------------------------------------------------------------------
1366 /** Sends data to all validated peers except the specified currently in game
1367 * \param peer Peer which will not receive the message.
1368 * \param data Data to sent.
1369 * \param reliable If the data should be sent reliable or now.
1370 */
sendPacketExcept(STKPeer * peer,NetworkString * data,bool reliable)1371 void STKHost::sendPacketExcept(STKPeer* peer, NetworkString *data,
1372 bool reliable)
1373 {
1374 std::lock_guard<std::mutex> lock(m_peers_mutex);
1375 for (auto p : m_peers)
1376 {
1377 STKPeer* stk_peer = p.second.get();
1378 if (!stk_peer->isSamePeer(peer) && p.second->isValidated() &&
1379 !p.second->isWaitingForGame())
1380 {
1381 stk_peer->sendPacket(data, reliable);
1382 }
1383 }
1384 } // sendPacketExcept
1385
1386 //-----------------------------------------------------------------------------
1387 /** Sends data to peers with custom rule
1388 * \param predicate boolean function for peer to predicate whether to send
1389 * \param data Data to sent.
1390 * \param reliable If the data should be sent reliable or now.
1391 */
sendPacketToAllPeersWith(std::function<bool (STKPeer *)> predicate,NetworkString * data,bool reliable)1392 void STKHost::sendPacketToAllPeersWith(std::function<bool(STKPeer*)> predicate,
1393 NetworkString* data, bool reliable)
1394 {
1395 std::lock_guard<std::mutex> lock(m_peers_mutex);
1396 for (auto p : m_peers)
1397 {
1398 STKPeer* stk_peer = p.second.get();
1399 if (!stk_peer->isValidated())
1400 continue;
1401 if (predicate(stk_peer))
1402 stk_peer->sendPacket(data, reliable);
1403 }
1404 } // sendPacketToAllPeersWith
1405
1406 //-----------------------------------------------------------------------------
1407 /** Sends a message from a client to the server. */
sendToServer(NetworkString * data,bool reliable)1408 void STKHost::sendToServer(NetworkString *data, bool reliable)
1409 {
1410 std::lock_guard<std::mutex> lock(m_peers_mutex);
1411 if (m_peers.empty())
1412 return;
1413 assert(NetworkConfig::get()->isClient());
1414 m_peers.begin()->second->sendPacket(data, reliable);
1415 } // sendToServer
1416
1417 //-----------------------------------------------------------------------------
1418 std::vector<std::shared_ptr<NetworkPlayerProfile> >
getAllPlayerProfiles() const1419 STKHost::getAllPlayerProfiles() const
1420 {
1421 std::vector<std::shared_ptr<NetworkPlayerProfile> > p;
1422 std::unique_lock<std::mutex> lock(m_peers_mutex);
1423 for (auto& peer : m_peers)
1424 {
1425 if (peer.second->isDisconnected() || !peer.second->isValidated())
1426 continue;
1427 if (ServerConfig::m_ai_handling && peer.second->isAIPeer())
1428 continue;
1429 auto peer_profile = peer.second->getPlayerProfiles();
1430 p.insert(p.end(), peer_profile.begin(), peer_profile.end());
1431 }
1432 lock.unlock();
1433 return p;
1434 } // getAllPlayerProfiles
1435
1436 //-----------------------------------------------------------------------------
getAllPlayerOnlineIds() const1437 std::set<uint32_t> STKHost::getAllPlayerOnlineIds() const
1438 {
1439 std::set<uint32_t> online_ids;
1440 std::unique_lock<std::mutex> lock(m_peers_mutex);
1441 for (auto& peer : m_peers)
1442 {
1443 if (peer.second->isDisconnected() || !peer.second->isValidated())
1444 continue;
1445 if (!peer.second->getPlayerProfiles().empty())
1446 {
1447 online_ids.insert(
1448 peer.second->getPlayerProfiles()[0]->getOnlineId());
1449 }
1450 }
1451 lock.unlock();
1452 return online_ids;
1453 } // getAllPlayerOnlineIds
1454
1455 //-----------------------------------------------------------------------------
findPeerByHostId(uint32_t id) const1456 std::shared_ptr<STKPeer> STKHost::findPeerByHostId(uint32_t id) const
1457 {
1458 std::lock_guard<std::mutex> lock(m_peers_mutex);
1459 auto ret = std::find_if(m_peers.begin(), m_peers.end(),
1460 [id](const std::pair<ENetPeer*, std::shared_ptr<STKPeer> >& p)
1461 {
1462 return p.second->getHostId() == id;
1463 });
1464 return ret != m_peers.end() ? ret->second : nullptr;
1465 } // findPeerByHostId
1466
1467 //-----------------------------------------------------------------------------
1468 std::shared_ptr<STKPeer>
findPeerByName(const core::stringw & name) const1469 STKHost::findPeerByName(const core::stringw& name) const
1470 {
1471 std::lock_guard<std::mutex> lock(m_peers_mutex);
1472 auto ret = std::find_if(m_peers.begin(), m_peers.end(),
1473 [name](const std::pair<ENetPeer*, std::shared_ptr<STKPeer> >& p)
1474 {
1475 bool found = false;
1476 for (auto& profile : p.second->getPlayerProfiles())
1477 {
1478 if (profile->getName() == name)
1479 {
1480 found = true;
1481 break;
1482 }
1483 }
1484 return found;
1485 });
1486 return ret != m_peers.end() ? ret->second : nullptr;
1487 } // findPeerByName
1488
1489 //-----------------------------------------------------------------------------
initClientNetwork(ENetEvent & event,Network * new_network)1490 void STKHost::initClientNetwork(ENetEvent& event, Network* new_network)
1491 {
1492 assert(NetworkConfig::get()->isClient());
1493 assert(!m_listening_thread.joinable());
1494 assert(new_network->getENetHost()->peerCount == 1);
1495 if (m_network != new_network)
1496 {
1497 delete m_network;
1498 m_network = new_network;
1499 }
1500 auto stk_peer = std::make_shared<STKPeer>(event.peer, this,
1501 m_next_unique_host_id++);
1502 stk_peer->setValidated(true);
1503 m_peers[event.peer] = stk_peer;
1504 auto pm = ProtocolManager::lock();
1505 if (pm && !pm->isExiting())
1506 pm->propagateEvent(new Event(&event, stk_peer));
1507 } // initClientNetwork
1508
1509 // ----------------------------------------------------------------------------
getAllPlayersTeamInfo() const1510 std::pair<int, int> STKHost::getAllPlayersTeamInfo() const
1511 {
1512 int red_count = 0;
1513 int blue_count = 0;
1514 auto pp = getAllPlayerProfiles();
1515 for (auto& player : pp)
1516 {
1517 if (player->getTeam() == KART_TEAM_RED)
1518 red_count++;
1519 else if (player->getTeam() == KART_TEAM_BLUE)
1520 blue_count++;
1521 }
1522 return std::make_pair(red_count, blue_count);
1523
1524 } // getAllPlayersTeamInfo
1525
1526 // ----------------------------------------------------------------------------
1527 /** Get the players for starting a new game.
1528 * \return A vector containing pointers on the players profiles. */
1529 std::vector<std::shared_ptr<NetworkPlayerProfile> >
getPlayersForNewGame(bool * has_always_on_spectators) const1530 STKHost::getPlayersForNewGame(bool* has_always_on_spectators) const
1531 {
1532 std::vector<std::shared_ptr<NetworkPlayerProfile> > players;
1533 std::lock_guard<std::mutex> lock(m_peers_mutex);
1534 for (auto& p : m_peers)
1535 {
1536 auto& stk_peer = p.second;
1537 // Handle always spectate for peer
1538 if (has_always_on_spectators && stk_peer->alwaysSpectate())
1539 {
1540 *has_always_on_spectators = true;
1541 stk_peer->setWaitingForGame(false);
1542 stk_peer->setSpectator(true);
1543 continue;
1544 }
1545 if (stk_peer->isWaitingForGame())
1546 continue;
1547 if (ServerConfig::m_ai_handling && stk_peer->isAIPeer())
1548 continue;
1549 for (auto& q : stk_peer->getPlayerProfiles())
1550 players.push_back(q);
1551 }
1552 return players;
1553 } // getPlayersForNewGame
1554
1555 // ----------------------------------------------------------------------------
1556 /** Update players count in server
1557 * \param ingame store the in game players count now
1558 * \param waiting store the waiting players count now
1559 * \param total store the total players count now
1560 */
updatePlayers(unsigned * ingame,unsigned * waiting,unsigned * total)1561 void STKHost::updatePlayers(unsigned* ingame, unsigned* waiting,
1562 unsigned* total)
1563 {
1564 uint32_t ingame_players = 0;
1565 uint32_t waiting_players = 0;
1566 uint32_t total_players = 0;
1567 std::lock_guard<std::mutex> lock(m_peers_mutex);
1568 for (auto& p : m_peers)
1569 {
1570 auto& stk_peer = p.second;
1571 if (!stk_peer->isValidated())
1572 continue;
1573 if (ServerConfig::m_ai_handling && stk_peer->isAIPeer())
1574 continue;
1575 if (stk_peer->isWaitingForGame())
1576 waiting_players += (uint32_t)stk_peer->getPlayerProfiles().size();
1577 else
1578 ingame_players += (uint32_t)stk_peer->getPlayerProfiles().size();
1579 total_players += (uint32_t)stk_peer->getPlayerProfiles().size();
1580 }
1581 m_players_in_game.store(ingame_players);
1582 m_players_waiting.store(waiting_players);
1583 m_total_players.store(total_players);
1584 if (ingame)
1585 *ingame = ingame_players;
1586 if (waiting)
1587 *waiting = waiting_players;
1588 if (total)
1589 *total = total_players;
1590 } // updatePlayers
1591
1592 // ----------------------------------------------------------------------------
1593 /** True if this is a client and server in graphics mode made by server
1594 * creation screen. */
isClientServer() const1595 bool STKHost::isClientServer() const
1596 {
1597 return m_client_loop != NULL;
1598 } // isClientServer
1599
1600 // ----------------------------------------------------------------------------
1601 /** Return an valid public IPv4 or IPv6 address with port, empty if both are
1602 * unset, IPv6 will come first if both exists. */
getValidPublicAddress() const1603 std::string STKHost::getValidPublicAddress() const
1604 {
1605 if (!m_public_ipv6_address.empty() && m_public_address->getPort() != 0)
1606 {
1607 return std::string("[") + m_public_ipv6_address + "]:" +
1608 StringUtils::toString(m_public_address->getPort());
1609 }
1610 if (!m_public_address->isUnset())
1611 return m_public_address->toString();
1612 return "";
1613 } // getValidPublicAddress
1614
1615 // ----------------------------------------------------------------------------
receiveRawPacket(char * buffer,int buffer_len,SocketAddress * sender,int max_tries)1616 int STKHost::receiveRawPacket(char *buffer, int buffer_len,
1617 SocketAddress* sender, int max_tries)
1618 {
1619 return m_network->receiveRawPacket(buffer, buffer_len, sender,
1620 max_tries);
1621 } // receiveRawPacket
1622
1623 // ----------------------------------------------------------------------------
sendRawPacket(const BareNetworkString & buffer,const SocketAddress & dst)1624 void STKHost::sendRawPacket(const BareNetworkString &buffer,
1625 const SocketAddress& dst)
1626 {
1627 m_network->sendRawPacket(buffer, dst);
1628 } // sendRawPacket
1629
1630 // ----------------------------------------------------------------------------
getPrivatePort() const1631 uint16_t STKHost::getPrivatePort() const
1632 {
1633 return m_network->getPort();
1634 } // getPrivatePort
1635