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 /*! \file stk_host.hpp
20  *  \brief Defines an interface to use network low-level functions easily.
21  */
22 #ifndef STK_HOST_HPP
23 #define STK_HOST_HPP
24 
25 #include "utils/stk_process.hpp"
26 #include "utils/synchronised.hpp"
27 #include "utils/time.hpp"
28 
29 #include "irrString.h"
30 
31 // enet.h includes win32.h, which without lean_and_mean includes
32 // winspool.h, which defines MAX_PRIORITY as a macro, which then
33 // results in request_manager.hpp not being compilable.
34 #define WIN32_LEAN_AND_MEAN
35 #include <enet/enet.h>
36 
37 #include <atomic>
38 #include <cassert>
39 #include <cstring>
40 #include <list>
41 #include <functional>
42 #include <map>
43 #include <memory>
44 #include <mutex>
45 #include <set>
46 #include <thread>
47 #include <tuple>
48 #include <vector>
49 
50 class BareNetworkString;
51 class GameSetup;
52 class LobbyProtocol;
53 class Network;
54 class NetworkPlayerProfile;
55 class NetworkString;
56 class NetworkTimerSynchronizer;
57 class Server;
58 class ServerLobby;
59 class ChildLoop;
60 class SocketAddress;
61 class STKPeer;
62 
63 using namespace irr;
64 
65 enum ENetCommandType : unsigned int
66 {
67     ECT_SEND_PACKET = 0,
68     ECT_DISCONNECT = 1,
69     ECT_RESET = 2
70 };
71 
72 class STKHost
73 {
74 private:
75     /** Singleton pointer to the instance. */
76     static STKHost* m_stk_host[PT_COUNT];
77 
78     /** Separate process of server instance. */
79     ChildLoop* m_client_loop;
80 
81     std::thread m_client_loop_thread;
82 
83     /** ENet host interfacing sockets. */
84     Network* m_network;
85 
86     /** Network console thread */
87     std::thread m_network_console;
88 
89     /** Make sure the removing or adding a peer is thread-safe. */
90     mutable std::mutex m_peers_mutex;
91 
92     /** Let (atm enet_peer_send and enet_peer_disconnect) run in the listening
93      *  thread. */
94     std::vector<std::tuple</*peer receive*/ENetPeer*,
95         /*packet to send*/ENetPacket*, /*integer data*/uint32_t,
96         ENetCommandType, ENetAddress> > m_enet_cmd;
97 
98     /** Protect \ref m_enet_cmd from multiple threads usage. */
99     std::mutex m_enet_cmd_mutex;
100 
101     /** The list of peers connected to this instance. */
102     std::map<ENetPeer*, std::shared_ptr<STKPeer> > m_peers;
103 
104     /** Next unique host id. It is increased whenever a new peer is added (see
105      *  getPeer()), but not decreased whena host (=peer) disconnects. This
106      *  results in a unique host id for each host, even when a host should
107      *  disconnect and then reconnect. */
108     uint32_t m_next_unique_host_id = 0;
109 
110     /** Host id of this host. */
111     uint32_t m_host_id = 0;
112 
113     /** Id of thread listening to enet events. */
114     std::thread m_listening_thread;
115 
116     /** Flag which is set from the protocol manager thread which
117      *  triggers a shutdown of the STKHost (and the Protocolmanager). */
118     std::atomic_bool m_shutdown;
119 
120     /** True if this local host is authorised to control a server. */
121     std::atomic_bool m_authorised;
122 
123     /** Use as a timeout to waiting a disconnect event when exiting. */
124     std::atomic<uint64_t> m_exit_timeout;
125 
126     /** An error message, which is set by a protocol to be displayed
127      *  in the GUI. */
128     irr::core::stringw m_error_message;
129 
130     /** The public address found by stun (if WAN is used). */
131     std::unique_ptr<SocketAddress> m_public_address;
132 
133     /** The public IPv6 address found by stun (if WAN is used). */
134     std::string m_public_ipv6_address;
135 
136     /** The public IPv4 address stun server used. */
137     std::unique_ptr<SocketAddress> m_stun_ipv4;
138 
139     /** The public IPv6 address stun server used. */
140     std::unique_ptr<SocketAddress> m_stun_ipv6;
141 
142     Synchronised<std::map<uint32_t, uint32_t> > m_peer_pings;
143 
144     std::atomic<uint32_t> m_client_ping;
145 
146     std::atomic<uint32_t> m_upload_speed;
147 
148     std::atomic<uint32_t> m_download_speed;
149 
150     std::atomic<uint32_t> m_players_in_game;
151 
152     std::atomic<uint32_t> m_players_waiting;
153 
154     std::atomic<uint32_t> m_total_players;
155 
156     std::atomic<int64_t> m_network_timer;
157 
158     std::unique_ptr<NetworkTimerSynchronizer> m_nts;
159 
160     // ------------------------------------------------------------------------
161     STKHost(bool server);
162     // ------------------------------------------------------------------------
163     ~STKHost();
164     // ------------------------------------------------------------------------
165     void init();
166     // ------------------------------------------------------------------------
167     void handleDirectSocketRequest(Network* direct_socket,
168                                    std::shared_ptr<ServerLobby> sl,
169                                    std::map<std::string, uint64_t>& ctp);
170     // ------------------------------------------------------------------------
171     void mainLoop(ProcessType pt);
172     // ------------------------------------------------------------------------
173     void getIPFromStun(int socket, const std::string& stun_address,
174                        short family, SocketAddress* result);
175 public:
176     /** If a network console should be started. */
177     static bool m_enable_console;
178 
179     /** Creates the STKHost. It takes all confifguration parameters from
180      *  NetworkConfig. This STKHost can either be a client or a server.
181      */
182     static std::shared_ptr<LobbyProtocol> create(ChildLoop* cl = NULL);
183     // ------------------------------------------------------------------------
184     /** Returns the instance of STKHost. */
get()185     static STKHost *get()
186     {
187         ProcessType pt = STKProcess::getType();
188         assert(m_stk_host[pt] != NULL);
189         return m_stk_host[pt];
190     }   // get
191     // ------------------------------------------------------------------------
getByType(ProcessType pt)192     static STKHost *getByType(ProcessType pt)
193     {
194         assert(m_stk_host[pt] != NULL);
195         return m_stk_host[pt];
196     }   // get
197     // ------------------------------------------------------------------------
destroy()198     static void destroy()
199     {
200         ProcessType pt = STKProcess::getType();
201         assert(m_stk_host[pt] != NULL);
202         delete m_stk_host[pt];
203         m_stk_host[pt] = NULL;
204     }   // destroy
205     // ------------------------------------------------------------------------
206     /** Checks if the STKHost has been created. */
existHost()207     static bool existHost()
208                        { return m_stk_host[STKProcess::getType()] != NULL; }
209     // ------------------------------------------------------------------------
clear()210     static void clear()          { memset(m_stk_host, 0, sizeof(m_stk_host)); }
211     // ------------------------------------------------------------------------
getPublicAddress() const212     const SocketAddress& getPublicAddress() const
213                                             { return *m_public_address.get(); }
214     // ------------------------------------------------------------------------
getPublicIPv6Address() const215     const std::string& getPublicIPv6Address() const
216                                               { return m_public_ipv6_address; }
217     // ------------------------------------------------------------------------
218     std::string getValidPublicAddress() const;
219     // ------------------------------------------------------------------------
getStunIPv4Address() const220     const SocketAddress* getStunIPv4Address() const
221                                                   { return m_stun_ipv4.get(); }
222     // ------------------------------------------------------------------------
getStunIPv6Address() const223     const SocketAddress* getStunIPv6Address() const
224                                                   { return m_stun_ipv6.get(); }
225     // ------------------------------------------------------------------------
226     uint16_t getPrivatePort() const;
227     // ------------------------------------------------------------------------
228     void setPublicAddress(short family);
229     // ------------------------------------------------------------------------
230     void disconnectAllPeers(bool timeout_waiting = false);
231     //-------------------------------------------------------------------------
232     /** Requests that the network infrastructure is to be shut down. This
233     *   function is called from a thread, but the actual shutdown needs to be
234     *   done from the main thread to avoid race conditions (e.g.
235     *   ProtocolManager might still access data structures when the main thread
236     *   tests if STKHost exist (which it does, but ProtocolManager might be
237     *   shut down already.
238     */
requestShutdown()239     void requestShutdown()
240     {
241         m_shutdown.store(true);
242     }   // requestExit
243     //-------------------------------------------------------------------------
244     void shutdown();
245     //-------------------------------------------------------------------------
246     void sendPacketToAllPeersInServer(NetworkString *data,
247                                       bool reliable = true);
248     // ------------------------------------------------------------------------
249     void sendPacketToAllPeers(NetworkString *data, bool reliable = true);
250     // ------------------------------------------------------------------------
251     void sendPacketToAllPeersWith(std::function<bool(STKPeer*)> predicate,
252                                   NetworkString* data, bool reliable = true);
253     // ------------------------------------------------------------------------
254     /** Returns true if this client instance is allowed to control the server.
255      *  It will auto transfer ownership if previous server owner disconnected.
256      */
isAuthorisedToControl() const257     bool isAuthorisedToControl() const          { return m_authorised.load(); }
258     // ------------------------------------------------------------------------
259     /** Sets if this local host is authorised to control the server. */
setAuthorisedToControl(bool authorised)260     void setAuthorisedToControl(bool authorised)
261                                             { m_authorised.store(authorised); }
262     // ------------------------------------------------------------------------
263     std::vector<std::shared_ptr<NetworkPlayerProfile> >
264                                                   getAllPlayerProfiles() const;
265     // ------------------------------------------------------------------------
266     std::set<uint32_t> getAllPlayerOnlineIds() const;
267     // ------------------------------------------------------------------------
268     std::shared_ptr<STKPeer> findPeerByHostId(uint32_t id) const;
269     // ------------------------------------------------------------------------
270     std::shared_ptr<STKPeer> findPeerByName(const core::stringw& name) const;
271     // ------------------------------------------------------------------------
272     void sendPacketExcept(STKPeer* peer, NetworkString *data,
273                           bool reliable = true);
274     // ------------------------------------------------------------------------
275     void setupClient(int peer_count, int channel_limit,
276                      uint32_t max_incoming_bandwidth,
277                      uint32_t max_outgoing_bandwidth);
278     // ------------------------------------------------------------------------
279     void startListening();
280     // ------------------------------------------------------------------------
281     void stopListening();
282     // ------------------------------------------------------------------------
283     bool peerExists(const SocketAddress& peer_address);
284     // ------------------------------------------------------------------------
285     std::shared_ptr<STKPeer> getServerPeerForClient() const;
286     // ------------------------------------------------------------------------
287     void setErrorMessage(const irr::core::stringw &message);
288     // ------------------------------------------------------------------------
addEnetCommand(ENetPeer * peer,ENetPacket * packet,uint32_t i,ENetCommandType ect,ENetAddress ea)289     void addEnetCommand(ENetPeer* peer, ENetPacket* packet, uint32_t i,
290                         ENetCommandType ect, ENetAddress ea)
291     {
292         std::lock_guard<std::mutex> lock(m_enet_cmd_mutex);
293         m_enet_cmd.emplace_back(peer, packet, i, ect, ea);
294     }
295     // ------------------------------------------------------------------------
296     /** Returns the last error (or "" if no error has happened). */
getErrorMessage() const297     const irr::core::stringw& getErrorMessage() const
298                                                     { return m_error_message; }
299     // ------------------------------------------------------------------------
300     /** Returns true if a shutdown of the network infrastructure was
301      *  requested. */
requestedShutdown() const302     bool requestedShutdown() const                { return m_shutdown.load(); }
303     // ------------------------------------------------------------------------
304     int receiveRawPacket(char *buffer, int buffer_len,
305                          SocketAddress* sender, int max_tries = -1);
306     // ------------------------------------------------------------------------
307     void sendRawPacket(const BareNetworkString &buffer,
308                        const SocketAddress& dst);
309     // ------------------------------------------------------------------------
getNetwork() const310     Network* getNetwork() const                           { return m_network; }
311     // ------------------------------------------------------------------------
312     /** Returns a copied list of peers. */
getPeers() const313     std::vector<std::shared_ptr<STKPeer> > getPeers() const
314     {
315         std::lock_guard<std::mutex> lock(m_peers_mutex);
316         std::vector<std::shared_ptr<STKPeer> > peers;
317         for (auto p : m_peers)
318         {
319             peers.push_back(p.second);
320         }
321         return peers;
322     }
323     // ------------------------------------------------------------------------
324     /** Returns the next (unique) host id. */
getNextHostId() const325     unsigned int getNextHostId() const
326     {
327         assert(m_next_unique_host_id >= 0);
328         return m_next_unique_host_id;
329     }
330     // ------------------------------------------------------------------------
setNextHostId(uint32_t id)331     void setNextHostId(uint32_t id)             { m_next_unique_host_id = id; }
332     // ------------------------------------------------------------------------
333     /** Returns the number of currently connected peers. */
getPeerCount() const334     unsigned int getPeerCount() const
335     {
336         std::lock_guard<std::mutex> lock(m_peers_mutex);
337         return (unsigned)m_peers.size();
338     }
339     // ------------------------------------------------------------------------
340     /** Sets the global host id of this host (client use). */
setMyHostId(uint32_t my_host_id)341     void setMyHostId(uint32_t my_host_id)           { m_host_id = my_host_id; }
342     // ------------------------------------------------------------------------
343     /** Returns the host id of this host. */
getMyHostId() const344     uint32_t getMyHostId() const                          { return m_host_id; }
345     // ------------------------------------------------------------------------
346     void sendToServer(NetworkString *data, bool reliable = true);
347     // ------------------------------------------------------------------------
348     bool isClientServer() const;
349     // ------------------------------------------------------------------------
350     void initClientNetwork(ENetEvent& event, Network* new_network);
351     // ------------------------------------------------------------------------
getPeerPings()352     std::map<uint32_t, uint32_t> getPeerPings()
353                                            { return m_peer_pings.getAtomic(); }
354     // ------------------------------------------------------------------------
getClientPingToServer() const355     uint32_t getClientPingToServer() const
356                       { return m_client_ping.load(std::memory_order_relaxed); }
357     // ------------------------------------------------------------------------
getNetworkTimerSynchronizer() const358     NetworkTimerSynchronizer* getNetworkTimerSynchronizer() const
359                                                         { return m_nts.get(); }
360     // ------------------------------------------------------------------------
getNetworkTimer() const361     uint64_t getNetworkTimer() const
362                   { return StkTime::getMonoTimeMs() - m_network_timer.load(); }
363     // ------------------------------------------------------------------------
setNetworkTimer(uint64_t ticks)364     void setNetworkTimer(uint64_t ticks)
365     {
366         m_network_timer.store(
367             (int64_t)StkTime::getMonoTimeMs() - (int64_t)ticks);
368     }
369     // ------------------------------------------------------------------------
370     std::pair<int, int> getAllPlayersTeamInfo() const;
371     // ------------------------------------------------------------------------
372     /* Return upload speed in bytes per second. */
getUploadSpeed() const373     unsigned getUploadSpeed() const           { return m_upload_speed.load(); }
374     // ------------------------------------------------------------------------
375     /* Return download speed in bytes per second. */
getDownloadSpeed() const376     unsigned getDownloadSpeed() const       { return m_download_speed.load(); }
377     // ------------------------------------------------------------------------
378     void updatePlayers(unsigned* ingame = NULL,
379                        unsigned* waiting = NULL,
380                        unsigned* total = NULL);
381     // ------------------------------------------------------------------------
getPlayersInGame() const382     uint32_t getPlayersInGame() const      { return m_players_in_game.load(); }
383     // ------------------------------------------------------------------------
getWaitingPlayers() const384     uint32_t getWaitingPlayers() const     { return m_players_waiting.load(); }
385     // ------------------------------------------------------------------------
getTotalPlayers() const386     uint32_t getTotalPlayers() const         { return m_total_players.load(); }
387     // ------------------------------------------------------------------------
388     std::vector<std::shared_ptr<NetworkPlayerProfile> >
389         getPlayersForNewGame(bool* has_always_on_spectators = NULL) const;
390     // ------------------------------------------------------------------------
replaceNetwork(Network * new_network)391     void replaceNetwork(Network* new_network)
392     {
393         m_network = new_network;
394     }
395     // ------------------------------------------------------------------------
396     static BareNetworkString getStunRequest(uint8_t* stun_tansaction_id);
397     // ------------------------------------------------------------------------
getChildLoop() const398     ChildLoop* getChildLoop() const { return m_client_loop; }
399 };   // class STKHost
400 
401 #endif // STK_HOST_HPP
402