OpenTTD Source  12.0-beta1
network_coordinator.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of OpenTTD.
3  * 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.
4  * 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.
5  * 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/>.
6  */
7 
10 #include "../stdafx.h"
11 #include "../debug.h"
12 #include "../error.h"
13 #include "../rev.h"
14 #include "../settings_type.h"
15 #include "../strings_func.h"
16 #include "../window_func.h"
17 #include "../window_type.h"
18 #include "network.h"
19 #include "network_coordinator.h"
20 #include "network_gamelist.h"
21 #include "network_gui.h"
22 #include "network_internal.h"
23 #include "network_server.h"
24 #include "network_stun.h"
25 #include "table/strings.h"
26 
27 #include "../safeguards.h"
28 
29 static const auto NETWORK_COORDINATOR_DELAY_BETWEEN_UPDATES = std::chrono::seconds(30);
32 std::string _network_server_invite_code = "";
33 
36 private:
37  std::string token;
39 
40 public:
48  NetworkDirectConnecter(const std::string &hostname, uint16 port, const std::string &token, uint8 tracking_number) : TCPConnecter(hostname, port), token(token), tracking_number(tracking_number) {}
49 
50  void OnFailure() override
51  {
52  _network_coordinator_client.ConnectFailure(this->token, this->tracking_number);
53  }
54 
55  void OnConnect(SOCKET s) override
56  {
58  _network_coordinator_client.ConnectSuccess(this->token, s, address);
59  }
60 };
61 
64 private:
65  std::string token;
67  uint8 family;
68 
69 public:
79  NetworkReuseStunConnecter(const std::string &hostname, uint16 port, const NetworkAddress &bind_address, std::string token, uint8 tracking_number, uint8 family) :
80  TCPConnecter(hostname, port, bind_address),
81  token(token),
83  family(family)
84  {
85  }
86 
87  void OnFailure() override
88  {
89  /* Close the STUN connection too, as it is no longer of use. */
90  _network_coordinator_client.CloseStunHandler(this->token, this->family);
91 
92  _network_coordinator_client.ConnectFailure(this->token, this->tracking_number);
93  }
94 
95  void OnConnect(SOCKET s) override
96  {
98  _network_coordinator_client.ConnectSuccess(this->token, s, address);
99  }
100 };
101 
104 public:
110 
111  void OnFailure() override
112  {
115  }
116 
117  void OnConnect(SOCKET s) override
118  {
119  assert(_network_coordinator_client.sock == INVALID_SOCKET);
120 
122  _network_coordinator_client.last_activity = std::chrono::steady_clock::now();
124  }
125 };
126 
128 {
130  std::string detail = p->Recv_string(NETWORK_ERROR_DETAIL_LENGTH);
131 
132  switch (error) {
134  this->CloseConnection();
135  return false;
136 
138  SetDParamStr(0, detail);
139  ShowErrorMessage(STR_NETWORK_ERROR_COORDINATOR_REGISTRATION_FAILED, STR_JUST_RAW_STRING, WL_ERROR);
140 
141  /* To prevent that we constantly try to reconnect, switch to local game. */
142  _settings_client.network.server_game_type = SERVER_GAME_TYPE_LOCAL;
143 
144  this->CloseConnection();
145  return false;
146 
148  auto connecter_pre_it = this->connecter_pre.find(detail);
149  if (connecter_pre_it != this->connecter_pre.end()) {
150  connecter_pre_it->second->SetFailure();
151  this->connecter_pre.erase(connecter_pre_it);
152  }
153 
154  /* Mark the server as offline. */
155  NetworkGameList *item = NetworkGameListAddItem(detail);
156  item->online = false;
157 
159  return true;
160  }
161 
162  default:
163  Debug(net, 0, "Invalid error type {} received from Game Coordinator", error);
164  this->CloseConnection();
165  return false;
166  }
167 }
168 
170 {
171  /* Schedule sending an update. */
172  this->next_update = std::chrono::steady_clock::now();
173 
177 
179  ShowErrorMessage(STR_NETWORK_ERROR_COORDINATOR_ISOLATED, STR_NETWORK_ERROR_COORDINATOR_ISOLATED_DETAIL, WL_ERROR);
180  }
181 
182  /* Users can change the invite code in the settings, but this has no effect
183  * on the invite code as assigned by the server. So
184  * _network_server_invite_code contains the current invite code,
185  * and _settings_client.network.server_invite_code contains the one we will
186  * attempt to re-use when registering again. */
188 
190 
191  if (_network_dedicated) {
192  std::string connection_type;
194  case CONNECTION_TYPE_ISOLATED: connection_type = "Remote players can't connect"; break;
195  case CONNECTION_TYPE_DIRECT: connection_type = "Public"; break;
196  case CONNECTION_TYPE_STUN: connection_type = "Behind NAT"; break;
197  case CONNECTION_TYPE_TURN: connection_type = "Via relay"; break;
198 
199  case CONNECTION_TYPE_UNKNOWN: // Never returned from Game Coordinator.
200  default: connection_type = "Unknown"; break; // Should never happen, but don't fail if it does.
201  }
202 
203  std::string game_type;
205  case SERVER_GAME_TYPE_INVITE_ONLY: game_type = "Invite only"; break;
206  case SERVER_GAME_TYPE_PUBLIC: game_type = "Public"; break;
207 
208  case SERVER_GAME_TYPE_LOCAL: // Impossible to register local servers.
209  default: game_type = "Unknown"; break; // Should never happen, but don't fail if it does.
210  }
211 
212  Debug(net, 3, "----------------------------------------");
213  Debug(net, 3, "Your server is now registered with the Game Coordinator:");
214  Debug(net, 3, " Game type: {}", game_type);
215  Debug(net, 3, " Connection type: {}", connection_type);
216  Debug(net, 3, " Invite code: {}", _network_server_invite_code);
217  Debug(net, 3, "----------------------------------------");
218  } else {
219  Debug(net, 3, "Game Coordinator registered our server with invite code '{}'", _network_server_invite_code);
220  }
221 
222  return true;
223 }
224 
226 {
227  uint8 servers = p->Recv_uint16();
228 
229  /* End of list; we can now remove all expired items from the list. */
230  if (servers == 0) {
232  return true;
233  }
234 
235  for (; servers > 0; servers--) {
236  std::string connection_string = p->Recv_string(NETWORK_HOSTNAME_PORT_LENGTH);
237 
238  /* Read the NetworkGameInfo from the packet. */
239  NetworkGameInfo ngi = {};
241 
242  /* Now we know the connection string, we can add it to our list. */
243  NetworkGameList *item = NetworkGameListAddItem(connection_string);
244 
245  /* Clear any existing GRFConfig chain. */
247  /* Copy the new NetworkGameInfo info. */
248  item->info = ngi;
249  /* Check for compatability with the client. */
251  /* Mark server as online. */
252  item->online = true;
253  /* Mark the item as up-to-date. */
255  }
256 
258  return true;
259 }
260 
262 {
263  std::string token = p->Recv_string(NETWORK_TOKEN_LENGTH);
264  std::string invite_code = p->Recv_string(NETWORK_INVITE_CODE_LENGTH);
265 
266  /* Find the connecter based on the invite code. */
267  auto connecter_pre_it = this->connecter_pre.find(invite_code);
268  if (connecter_pre_it == this->connecter_pre.end()) {
269  this->CloseConnection();
270  return false;
271  }
272 
273  /* Now store it based on the token. */
274  this->connecter[token] = connecter_pre_it->second;
275  this->connecter_pre.erase(connecter_pre_it);
276 
277  return true;
278 }
279 
281 {
282  std::string token = p->Recv_string(NETWORK_TOKEN_LENGTH);
283  this->CloseToken(token);
284 
285  return true;
286 }
287 
289 {
290  std::string token = p->Recv_string(NETWORK_TOKEN_LENGTH);
291  uint8 tracking_number = p->Recv_uint8();
292  std::string hostname = p->Recv_string(NETWORK_HOSTNAME_LENGTH);
293  uint16 port = p->Recv_uint16();
294 
295  /* Ensure all other pending connection attempts are killed. */
296  if (this->game_connecter != nullptr) {
297  this->game_connecter->Kill();
298  this->game_connecter = nullptr;
299  }
300 
301  this->game_connecter = new NetworkDirectConnecter(hostname, port, token, tracking_number);
302  return true;
303 }
304 
306 {
307  std::string token = p->Recv_string(NETWORK_TOKEN_LENGTH);
308 
309  this->stun_handlers[token][AF_INET6] = ClientNetworkStunSocketHandler::Stun(token, AF_INET6);
310  this->stun_handlers[token][AF_INET] = ClientNetworkStunSocketHandler::Stun(token, AF_INET);
311  return true;
312 }
313 
315 {
316  std::string token = p->Recv_string(NETWORK_TOKEN_LENGTH);
317  uint8 tracking_number = p->Recv_uint8();
318  uint8 family = p->Recv_uint8();
319  std::string host = p->Recv_string(NETWORK_HOSTNAME_PORT_LENGTH);
320  uint16 port = p->Recv_uint16();
321 
322  /* Check if we know this token. */
323  auto stun_it = this->stun_handlers.find(token);
324  if (stun_it == this->stun_handlers.end()) return true;
325  auto family_it = stun_it->second.find(family);
326  if (family_it == stun_it->second.end()) return true;
327 
328  /* Ensure all other pending connection attempts are killed. */
329  if (this->game_connecter != nullptr) {
330  this->game_connecter->Kill();
331  this->game_connecter = nullptr;
332  }
333 
334  /* We now mark the connection as closed, but we do not really close the
335  * socket yet. We do this when the NetworkReuseStunConnecter is connected.
336  * This prevents any NAT to already remove the route while we create the
337  * second connection on top of the first. */
338  family_it->second->CloseConnection(false);
339 
340  /* Connect to our peer from the same local address as we use for the
341  * STUN server. This means that if there is any NAT in the local network,
342  * the public ip:port is still pointing to the local address, and as such
343  * a connection can be established. */
344  this->game_connecter = new NetworkReuseStunConnecter(host, port, family_it->second->local_addr, token, tracking_number, family);
345  return true;
346 }
347 
349 {
351 
352  uint16 newgrfs = p->Recv_uint16();
353  for (; newgrfs> 0; newgrfs--) {
354  uint32 index = p->Recv_uint32();
356  }
357  return true;
358 }
359 
361 {
362  std::string token = p->Recv_string(NETWORK_TOKEN_LENGTH);
363  uint8 tracking_number = p->Recv_uint8();
364  std::string ticket = p->Recv_string(NETWORK_TOKEN_LENGTH);
365  std::string connection_string = p->Recv_string(NETWORK_HOSTNAME_PORT_LENGTH);
366 
367  /* Ensure all other pending connection attempts are killed. */
368  if (this->game_connecter != nullptr) {
369  this->game_connecter->Kill();
370  this->game_connecter = nullptr;
371  }
372 
373  this->turn_handlers[token] = ClientNetworkTurnSocketHandler::Turn(token, tracking_number, ticket, connection_string);
374 
375  if (!_network_server) {
377  case URS_NEVER:
378  this->ConnectFailure(token, 0);
379  break;
380 
381  case URS_ASK:
382  ShowNetworkAskRelay(connection_string, token);
383  break;
384 
385  case URS_ALLOW:
386  this->StartTurnConnection(token);
387  break;
388  }
389  } else {
390  this->StartTurnConnection(token);
391  }
392 
393  return true;
394 }
395 
396 void ClientNetworkCoordinatorSocketHandler::StartTurnConnection(std::string &token)
397 {
398  auto turn_it = this->turn_handlers.find(token);
399  if (turn_it == this->turn_handlers.end()) return;
400 
401  turn_it->second->Connect();
402 }
403 
404 void ClientNetworkCoordinatorSocketHandler::Connect()
405 {
406  /* We are either already connected or are trying to connect. */
407  if (this->sock != INVALID_SOCKET || this->connecting) return;
408 
409  this->Reopen();
410 
411  this->connecting = true;
412  this->last_activity = std::chrono::steady_clock::now();
413 
415 }
416 
418 {
420 
421  this->CloseSocket();
422  this->connecting = false;
423 
425  this->next_update = {};
426 
427  this->CloseAllConnections();
428 
430 
432 }
433 
438 {
440  this->next_update = {};
441 
443 
444  this->Connect();
445 
451  p->Send_string("");
452  p->Send_string("");
453  } else {
456  }
457 
458  this->SendPacket(p);
459 }
460 
465 {
466  Debug(net, 6, "Sending server update to Game Coordinator");
467 
470  SerializeNetworkGameInfo(p, GetCurrentNetworkServerGameInfo(), this->next_update.time_since_epoch() != std::chrono::nanoseconds::zero());
471 
472  this->SendPacket(p);
473 
474  this->next_update = std::chrono::steady_clock::now() + NETWORK_COORDINATOR_DELAY_BETWEEN_UPDATES;
475 }
476 
481 {
482  this->Connect();
483 
485 
489  p->Send_string(_openttd_revision);
491 
492  this->SendPacket(p);
493 }
494 
500 void ClientNetworkCoordinatorSocketHandler::ConnectToServer(const std::string &invite_code, TCPServerConnecter *connecter)
501 {
502  assert(StrStartsWith(invite_code, "+"));
503 
504  if (this->connecter_pre.find(invite_code) != this->connecter_pre.end()) {
505  /* If someone is hammering the refresh key, one can sent out two
506  * requests for the same invite code. There isn't really a great way
507  * of handling this, so just ignore this request. */
508  connecter->SetFailure();
509  return;
510  }
511 
512  /* Initially we store based on invite code; on first reply we know the
513  * token, and will start using that key instead. */
514  this->connecter_pre[invite_code] = connecter;
515 
516  this->Connect();
517 
520  p->Send_string(invite_code);
521 
522  this->SendPacket(p);
523 }
524 
530 void ClientNetworkCoordinatorSocketHandler::ConnectFailure(const std::string &token, uint8 tracking_number)
531 {
532  /* Connecter will destroy itself. */
533  this->game_connecter = nullptr;
534 
537  p->Send_string(token);
538  p->Send_uint8(tracking_number);
539 
540  this->SendPacket(p);
541 
542  /* We do not close the associated connecter here yet, as the
543  * Game Coordinator might have other methods of connecting available. */
544 }
545 
552 void ClientNetworkCoordinatorSocketHandler::ConnectSuccess(const std::string &token, SOCKET sock, NetworkAddress &address)
553 {
554  /* Connecter will destroy itself. */
555  this->game_connecter = nullptr;
556 
557  if (_network_server) {
558  if (!ServerNetworkGameSocketHandler::ValidateClient(sock, address)) return;
559  Debug(net, 3, "[{}] Client connected from {} on frame {}", ServerNetworkGameSocketHandler::GetName(), address.GetHostname(), _frame_counter);
561  } else {
562  /* The client informs the Game Coordinator about the success. The server
563  * doesn't have to, as it is implied by the client telling. */
566  p->Send_string(token);
567  this->SendPacket(p);
568 
569  /* Find the connecter; it can happen it no longer exist, in cases where
570  * we aborted the connect but the Game Coordinator was already in the
571  * processes of connecting us. */
572  auto connecter_it = this->connecter.find(token);
573  if (connecter_it != this->connecter.end()) {
574  connecter_it->second->SetConnected(sock);
575  this->connecter.erase(connecter_it);
576  }
577  }
578 
579  /* Close all remaining connections. */
580  this->CloseToken(token);
581 }
582 
590 void ClientNetworkCoordinatorSocketHandler::StunResult(const std::string &token, uint8 family, bool result)
591 {
594  p->Send_string(token);
595  p->Send_uint8(family);
596  p->Send_bool(result);
597  this->SendPacket(p);
598 }
599 
605 void ClientNetworkCoordinatorSocketHandler::CloseStunHandler(const std::string &token, uint8 family)
606 {
607  auto stun_it = this->stun_handlers.find(token);
608  if (stun_it == this->stun_handlers.end()) return;
609 
610  if (family == AF_UNSPEC) {
611  for (auto &[family, stun_handler] : stun_it->second) {
612  stun_handler->CloseConnection();
613  stun_handler->CloseSocket();
614  }
615 
616  this->stun_handlers.erase(stun_it);
617  } else {
618  auto family_it = stun_it->second.find(family);
619  if (family_it == stun_it->second.end()) return;
620 
621  family_it->second->CloseConnection();
622  family_it->second->CloseSocket();
623 
624  stun_it->second.erase(family_it);
625  }
626 }
627 
633 {
635 
636  auto turn_it = this->turn_handlers.find(token);
637  if (turn_it == this->turn_handlers.end()) return;
638 
639  turn_it->second->CloseConnection();
640  turn_it->second->CloseSocket();
641 
642  /* We don't remove turn_handler here, as we can be called from within that
643  * turn_handler instance, so our object cannot be free'd yet. Instead, we
644  * check later if the connection is closed, and free the object then. */
645 }
646 
652 {
653  /* Close all remaining STUN / TURN connections. */
654  this->CloseStunHandler(token);
655  this->CloseTurnHandler(token);
656 
657  /* Close the caller of the connection attempt. */
658  auto connecter_it = this->connecter.find(token);
659  if (connecter_it != this->connecter.end()) {
660  connecter_it->second->SetFailure();
661  this->connecter.erase(connecter_it);
662  }
663 }
664 
669 {
670  /* Ensure all other pending connection attempts are also killed. */
671  if (this->game_connecter != nullptr) {
672  this->game_connecter->Kill();
673  this->game_connecter = nullptr;
674  }
675 
676  /* Mark any pending connecters as failed. */
677  for (auto &[token, it] : this->connecter) {
678  this->CloseStunHandler(token);
679  this->CloseTurnHandler(token);
680  it->SetFailure();
681 
682  /* Inform the Game Coordinator he can stop trying to connect us to the server. */
683  this->ConnectFailure(token, 0);
684  }
685  this->stun_handlers.clear();
686  this->turn_handlers.clear();
687  this->connecter.clear();
688 
689  /* Also close any pending invite-code requests. */
690  for (auto &[invite_code, it] : this->connecter_pre) {
691  it->SetFailure();
692  }
693  this->connecter_pre.clear();
694 }
695 
701 {
702  /* Private games are not listed via the Game Coordinator. */
703  if (_network_server && _settings_client.network.server_game_type == SERVER_GAME_TYPE_LOCAL) {
704  if (this->sock != INVALID_SOCKET) {
705  this->CloseConnection();
706  }
707  return;
708  }
709 
710  static int last_attempt_backoff = 1;
711  static bool first_reconnect = true;
712 
713  if (this->sock == INVALID_SOCKET) {
714  static std::chrono::steady_clock::time_point last_attempt = {};
715 
716  /* Don't auto-reconnect when we are not a server. */
717  if (!_network_server) return;
718  /* Don't reconnect if we are connecting. */
719  if (this->connecting) return;
720  /* Throttle how often we try to reconnect. */
721  if (std::chrono::steady_clock::now() < last_attempt + std::chrono::seconds(1) * last_attempt_backoff) return;
722 
723  last_attempt = std::chrono::steady_clock::now();
724  /* Delay reconnecting with up to 32 seconds. */
725  if (last_attempt_backoff < 32) {
726  last_attempt_backoff *= 2;
727  }
728 
729  /* Do not reconnect on the first attempt, but only initialize the
730  * last_attempt variables. Otherwise after an outage all servers
731  * reconnect at the same time, potentially overwhelming the
732  * Game Coordinator. */
733  if (first_reconnect) {
734  first_reconnect = false;
735  return;
736  }
737 
738  Debug(net, 1, "Connection with Game Coordinator lost; reconnecting...");
739  this->Register();
740  return;
741  }
742 
743  last_attempt_backoff = 1;
744  first_reconnect = true;
745 
746  if (_network_server && _network_server_connection_type != CONNECTION_TYPE_UNKNOWN && std::chrono::steady_clock::now() > this->next_update) {
747  this->SendServerUpdate();
748  }
749 
750  if (!_network_server && std::chrono::steady_clock::now() > this->last_activity + IDLE_TIMEOUT) {
751  this->CloseConnection();
752  return;
753  }
754 
755  if (this->CanSendReceive()) {
756  if (this->ReceivePackets()) {
757  this->last_activity = std::chrono::steady_clock::now();
758  }
759  }
760 
761  this->SendPackets();
762 
763  for (const auto &[token, families] : this->stun_handlers) {
764  for (const auto &[family, stun_handler] : families) {
765  stun_handler->SendReceive();
766  }
767  }
768 
769  /* Check for handlers that are not connecting nor connected. Destroy those objects. */
770  for (auto turn_it = this->turn_handlers.begin(); turn_it != this->turn_handlers.end(); /* nothing */) {
771  if (turn_it->second->connect_started && turn_it->second->connecter == nullptr && !turn_it->second->IsConnected()) {
772  turn_it = this->turn_handlers.erase(turn_it);
773  } else {
774  turn_it++;
775  }
776  }
777 
778  for (const auto &[token, turn_handler] : this->turn_handlers) {
779  turn_handler->SendReceive();
780  }
781 }
SerializeNetworkGameInfo
void SerializeNetworkGameInfo(Packet *p, const NetworkServerGameInfo *info, bool send_newgrf_names)
Serializes the NetworkGameInfo struct to the packet.
Definition: game_info.cpp:185
NetworkGameInfo
The game information that is sent from the server to the clients with extra information only required...
Definition: game_info.h:117
_frame_counter
uint32 _frame_counter
The current frame.
Definition: network.cpp:70
ClientNetworkCoordinatorSocketHandler::ConnectFailure
void ConnectFailure(const std::string &token, uint8 tracking_number)
Callback from a Connecter to let the Game Coordinator know the connection failed.
Definition: network_coordinator.cpp:530
CONNECTION_TYPE_ISOLATED
@ CONNECTION_TYPE_ISOLATED
The Game Coordinator failed to find a way to connect to your server. Nobody will be able to join.
Definition: tcp_coordinator.h:54
NetworkDirectConnecter::NetworkDirectConnecter
NetworkDirectConnecter(const std::string &hostname, uint16 port, const std::string &token, uint8 tracking_number)
Try to establish a direct (hostname:port based) connection.
Definition: network_coordinator.cpp:48
SetWindowDirty
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition: window.cpp:3120
TCPConnecter::connection_string
std::string connection_string
Current address we are connecting to (before resolving).
Definition: tcp.h:100
NETWORK_COORDINATOR_SERVER_PORT
static const uint16 NETWORK_COORDINATOR_SERVER_PORT
The default port of the Game Coordinator server (TCP)
Definition: config.h:23
ClearGRFConfigList
void ClearGRFConfigList(GRFConfig **config)
Clear a GRF Config list, freeing all nodes.
Definition: newgrf_config.cpp:400
_network_server_connection_type
ConnectionType _network_server_connection_type
What type of connection the Game Coordinator detected we are on.
Definition: network_coordinator.cpp:31
NetworkCoordinatorErrorType
NetworkCoordinatorErrorType
The type of error from the Game Coordinator.
Definition: tcp_coordinator.h:63
NETWORK_INVITE_CODE_SECRET_LENGTH
static const uint NETWORK_INVITE_CODE_SECRET_LENGTH
The maximum length of the invite code secret, in bytes including '\0'.
Definition: config.h:75
NetworkSettings::server_port
uint16 server_port
port the server listens on
Definition: settings_type.h:273
TCPConnecter
"Helper" class for creating TCP connections in a non-blocking manner
Definition: tcp.h:71
PACKET_COORDINATOR_CLIENT_CONNECTED
@ PACKET_COORDINATOR_CLIENT_CONNECTED
Client informs the Game Coordinator the connection with the server is established.
Definition: tcp_coordinator.h:39
_network_server
bool _network_server
network-server is active
Definition: network.cpp:57
NetworkCoordinatorConnectionString
const char * NetworkCoordinatorConnectionString()
Get the connection string for the game coordinator from the environment variable OTTD_COORDINATOR_CS,...
Definition: config.cpp:36
NetworkSettings::server_invite_code_secret
std::string server_invite_code_secret
Secret to proof we got this invite code from the Game Coordinator.
Definition: settings_type.h:278
WC_CLIENT_LIST
@ WC_CLIENT_LIST
Client list; Window numbers:
Definition: window_type.h:470
CONNECTION_TYPE_DIRECT
@ CONNECTION_TYPE_DIRECT
The Game Coordinator can directly connect to your server.
Definition: tcp_coordinator.h:55
ClientNetworkCoordinatorSocketHandler::Receive_GC_CONNECT_FAILED
bool Receive_GC_CONNECT_FAILED(Packet *p) override
Game Coordinator informs the Client that it failed to find a way to connect the Client to the Server.
Definition: network_coordinator.cpp:280
ClientNetworkCoordinatorSocketHandler::ConnectSuccess
void ConnectSuccess(const std::string &token, SOCKET sock, NetworkAddress &address)
Callback from a Connecter to let the Game Coordinator know the connection to the game server is estab...
Definition: network_coordinator.cpp:552
network_stun.h
ClientNetworkCoordinatorSocketHandler::Receive_GC_STUN_CONNECT
bool Receive_GC_STUN_CONNECT(Packet *p) override
Game Coordinator informs the client/server of its STUN peer (the host:ip of the other side).
Definition: network_coordinator.cpp:314
TCPConnecter::Kill
void Kill()
Kill this connecter.
Definition: tcp_connect.cpp:85
NetworkTCPSocketHandler::sock
SOCKET sock
The socket currently connected to.
Definition: tcp.h:39
ServerNetworkGameSocketHandler::GetName
static const char * GetName()
Get the name used by the listener.
Definition: network_server.h:111
ClientNetworkCoordinatorSocketHandler::connecter
std::map< std::string, TCPServerConnecter * > connecter
Based on tokens, the current connecters that are pending.
Definition: network_coordinator.h:57
ClientNetworkCoordinatorSocketHandler::Receive_GC_ERROR
bool Receive_GC_ERROR(Packet *p) override
Game Coordinator indicates there was an error.
Definition: network_coordinator.cpp:127
NetworkReuseStunConnecter::OnFailure
void OnFailure() override
Callback for when the connection attempt failed.
Definition: network_coordinator.cpp:87
_settings_client
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:52
UpdateNetworkGameWindow
void UpdateNetworkGameWindow()
Update the network new window because a new server is found on the network.
Definition: network_gui.cpp:66
NetworkGameListAddItem
NetworkGameList * NetworkGameListAddItem(const std::string &connection_string)
Add a new item to the linked gamelist.
Definition: network_gamelist.cpp:32
NETWORK_COORDINATOR_DELAY_BETWEEN_UPDATES
static const auto NETWORK_COORDINATOR_DELAY_BETWEEN_UPDATES
How many time between updates the server sends to the Game Coordinator.
Definition: network_coordinator.cpp:29
network_gui.h
NETWORK_TOKEN_LENGTH
static const uint NETWORK_TOKEN_LENGTH
The maximum length of a token, in bytes including '\0'.
Definition: config.h:76
NetworkSettings::use_relay_service
UseRelayService use_relay_service
Use relay service?
Definition: settings_type.h:299
Packet::Send_uint8
void Send_uint8(uint8 data)
Package a 8 bits integer in the packet.
Definition: packet.cpp:129
NetworkAddress::GetPeerAddress
static NetworkAddress GetPeerAddress(SOCKET sock)
Get the peer address of a socket as NetworkAddress.
Definition: address.cpp:407
ShowErrorMessage
void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel wl, int x=0, int y=0, const GRFFile *textref_stack_grffile=nullptr, uint textref_stack_size=0, const uint32 *textref_stack=nullptr)
Display an error message in a window.
Definition: error_gui.cpp:383
Packet::Send_uint32
void Send_uint32(uint32 data)
Package a 32 bits integer in the packet.
Definition: packet.cpp:150
PACKET_COORDINATOR_CLIENT_LISTING
@ PACKET_COORDINATOR_CLIENT_LISTING
Client is requesting a listing of all public servers.
Definition: tcp_coordinator.h:33
ClientNetworkCoordinatorSocketHandler::CloseAllConnections
void CloseAllConnections()
Close all pending connection tokens.
Definition: network_coordinator.cpp:668
Packet::Recv_string
std::string Recv_string(size_t length, StringValidationSettings settings=SVS_REPLACE_WITH_QUESTION_MARK)
Reads characters (bytes) from the packet until it finds a '\0', or reaches a maximum of length charac...
Definition: packet.cpp:380
ClientNetworkCoordinatorSocketHandler::Receive_GC_STUN_REQUEST
bool Receive_GC_STUN_REQUEST(Packet *p) override
Game Coordinator requests the client/server to do a STUN request to the STUN server.
Definition: network_coordinator.cpp:305
network_coordinator.h
NetworkReuseStunConnecter::token
std::string token
Token of this connection.
Definition: network_coordinator.cpp:65
NETWORK_ERROR_DETAIL_LENGTH
static const uint NETWORK_ERROR_DETAIL_LENGTH
The maximum length of the error detail, in bytes including '\0'.
Definition: config.h:73
Packet::Recv_uint32
uint32 Recv_uint32()
Read a 32 bits integer from the packet.
Definition: packet.cpp:335
NetworkReuseStunConnecter::tracking_number
uint8 tracking_number
Tracking number of this connection.
Definition: network_coordinator.cpp:66
NETWORK_COORDINATOR_ERROR_INVALID_INVITE_CODE
@ NETWORK_COORDINATOR_ERROR_INVALID_INVITE_CODE
The invite code given is invalid.
Definition: tcp_coordinator.h:66
ClientNetworkCoordinatorSocketHandler::ConnectToServer
void ConnectToServer(const std::string &invite_code, TCPServerConnecter *connecter)
Join a server based on an invite code.
Definition: network_coordinator.cpp:500
NetworkSocketHandler::Reopen
void Reopen()
Reopen the socket so we can send/receive stuff again.
Definition: core.h:73
ClientNetworkCoordinatorSocketHandler::Receive_GC_TURN_CONNECT
bool Receive_GC_TURN_CONNECT(Packet *p) override
Game Coordinator requests that we make a connection to the indicated peer, which is a TURN server.
Definition: network_coordinator.cpp:360
ShowNetworkAskRelay
void ShowNetworkAskRelay(const std::string &connection_string, const std::string &token)
Show a modal confirmation window with "no" / "yes, once" / "yes, always" buttons.
Definition: network_gui.cpp:2457
PACKET_COORDINATOR_SERCLI_STUN_RESULT
@ PACKET_COORDINATOR_SERCLI_STUN_RESULT
Client/server informs the Game Coordinator of the result of the STUN request.
Definition: tcp_coordinator.h:42
NetworkDirectConnecter::token
std::string token
Token of this connection.
Definition: network_coordinator.cpp:37
ClientNetworkCoordinatorSocketHandler::stun_handlers
std::map< std::string, std::map< int, std::unique_ptr< ClientNetworkStunSocketHandler > > > stun_handlers
All pending STUN handlers, stored by token:family.
Definition: network_coordinator.h:59
ClientNetworkCoordinatorSocketHandler::game_connecter
TCPConnecter * game_connecter
Pending connecter to the game server.
Definition: network_coordinator.h:61
StrStartsWith
bool StrStartsWith(const std::string_view str, const std::string_view prefix)
Check whether the given string starts with the given prefix.
Definition: string.cpp:367
ClientNetworkCoordinatorSocketHandler::CloseConnection
NetworkRecvStatus CloseConnection(bool error=true) override
This will put this socket handler in a close state.
Definition: network_coordinator.cpp:417
PACKET_COORDINATOR_CLIENT_CONNECT
@ PACKET_COORDINATOR_CLIENT_CONNECT
Client wants to connect to a server based on an invite code.
Definition: tcp_coordinator.h:35
PACKET_COORDINATOR_SERVER_REGISTER
@ PACKET_COORDINATOR_SERVER_REGISTER
Server registration.
Definition: tcp_coordinator.h:30
Packet::Send_uint16
void Send_uint16(uint16 data)
Package a 16 bits integer in the packet.
Definition: packet.cpp:139
NetworkTCPSocketHandler::SendPacket
virtual void SendPacket(Packet *packet)
This function puts the packet in the send-queue and it is send as soon as possible.
Definition: tcp.cpp:81
NetworkReuseStunConnecter::NetworkReuseStunConnecter
NetworkReuseStunConnecter(const std::string &hostname, uint16 port, const NetworkAddress &bind_address, std::string token, uint8 tracking_number, uint8 family)
Try to establish a STUN-based connection.
Definition: network_coordinator.cpp:79
NetworkTCPSocketHandler::CloseConnection
virtual NetworkRecvStatus CloseConnection(bool error=true)
This will put this socket handler in a close state.
Definition: tcp.cpp:65
NetworkGameList::version
int version
Used to see which servers are no longer available on the Game Coordinator and can be removed.
Definition: network_gamelist.h:26
NetworkCoordinatorConnecter
Connect to the Game Coordinator server.
Definition: network_coordinator.cpp:103
ClientNetworkCoordinatorSocketHandler::StunResult
void StunResult(const std::string &token, uint8 family, bool result)
Callback from the STUN connecter to inform the Game Coordinator about the result of the STUN.
Definition: network_coordinator.cpp:590
TCP_MTU
static const uint16 TCP_MTU
Number of bytes we can pack in a single TCP packet.
Definition: config.h:47
ClientNetworkCoordinatorSocketHandler::GetListing
void GetListing()
Request a listing of all public servers.
Definition: network_coordinator.cpp:480
network_server.h
_network_dedicated
bool _network_dedicated
are we a dedicated server?
Definition: network.cpp:59
ClientNetworkCoordinatorSocketHandler::Register
void Register()
Register our server to receive our invite code.
Definition: network_coordinator.cpp:437
Packet
Internal entity of a packet.
Definition: packet.h:44
ClientNetworkCoordinatorSocketHandler::newgrf_lookup_table_cursor
uint32 newgrf_lookup_table_cursor
Last received cursor for the GameInfoNewGRFLookupTable updates.
Definition: network_coordinator.h:63
ServerNetworkGameSocketHandler::AcceptConnection
static void AcceptConnection(SOCKET s, const NetworkAddress &address)
Handle the accepting of a connection to the server.
Definition: network.cpp:550
ConnectionType
ConnectionType
The type of connection the Game Coordinator can detect we have.
Definition: tcp_coordinator.h:52
NETWORK_COORDINATOR_ERROR_UNKNOWN
@ NETWORK_COORDINATOR_ERROR_UNKNOWN
There was an unknown error.
Definition: tcp_coordinator.h:64
NetworkGameListRemoveExpired
void NetworkGameListRemoveExpired()
Remove all servers that have not recently been updated.
Definition: network_gamelist.cpp:91
NETWORK_HOSTNAME_PORT_LENGTH
static const uint NETWORK_HOSTNAME_PORT_LENGTH
The maximum length of the host name + port, in bytes including '\0'. The extra six is ":" + port numb...
Definition: config.h:58
DeserializeNetworkGameInfo
void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info, const GameInfoNewGRFLookupTable *newgrf_lookup_table)
Deserializes the NetworkGameInfo struct from the packet.
Definition: game_info.cpp:256
CONNECTION_TYPE_UNKNOWN
@ CONNECTION_TYPE_UNKNOWN
The Game Coordinator hasn't informed us yet what type of connection we have.
Definition: tcp_coordinator.h:53
GetCurrentNetworkServerGameInfo
const NetworkServerGameInfo * GetCurrentNetworkServerGameInfo()
Get the NetworkServerGameInfo structure with the latest information of the server.
Definition: game_info.cpp:143
Packet::Send_bool
void Send_bool(bool data)
Package a boolean in the packet.
Definition: packet.cpp:120
NetworkReuseStunConnecter::family
uint8 family
Family of this connection.
Definition: network_coordinator.cpp:67
NetworkDirectConnecter::OnFailure
void OnFailure() override
Callback for when the connection attempt failed.
Definition: network_coordinator.cpp:50
NetworkDirectConnecter::OnConnect
void OnConnect(SOCKET s) override
Callback when the connection succeeded.
Definition: network_coordinator.cpp:55
ClientNetworkCoordinatorSocketHandler::newgrf_lookup_table
GameInfoNewGRFLookupTable newgrf_lookup_table
Table to look up NewGRFs in the GC_LISTING packets.
Definition: network_coordinator.h:64
ClientNetworkCoordinatorSocketHandler::Receive_GC_LISTING
bool Receive_GC_LISTING(Packet *p) override
Game Coordinator replies with a list of all public servers.
Definition: network_coordinator.cpp:225
NetworkSettings::server_game_type
ServerGameType server_game_type
Server type: local / public / invite-only.
Definition: settings_type.h:276
NetworkTCPSocketHandler::SendPackets
SendPacketsState SendPackets(bool closing_down=false)
Sends all the buffered packets out for this client.
Definition: tcp.cpp:99
ClientNetworkCoordinatorSocketHandler::Receive_GC_DIRECT_CONNECT
bool Receive_GC_DIRECT_CONNECT(Packet *p) override
Game Coordinator requests that the Client makes a direct connection to the indicated peer,...
Definition: network_coordinator.cpp:288
NetworkAddress
Wrapper for (un)resolved network addresses; there's no reason to transform a numeric IP to a string a...
Definition: address.h:30
ClientNetworkCoordinatorSocketHandler::connecter_pre
std::map< std::string, TCPServerConnecter * > connecter_pre
Based on invite codes, the current connecters that are pending.
Definition: network_coordinator.h:58
ClientNetworkCoordinatorSocketHandler::Receive_GC_NEWGRF_LOOKUP
bool Receive_GC_NEWGRF_LOOKUP(Packet *p) override
Game Coordinator informs the client of updates for the NewGRFs lookup table as used by the NewGRF des...
Definition: network_coordinator.cpp:348
NetworkTCPSocketHandler::CanSendReceive
bool CanSendReceive()
Check whether this socket can send or receive something.
Definition: tcp.cpp:218
NetworkReuseStunConnecter::OnConnect
void OnConnect(SOCKET s) override
Callback when the connection succeeded.
Definition: network_coordinator.cpp:95
ClientNetworkCoordinatorSocketHandler::SendReceive
void SendReceive()
Check whether we received/can send some data from/to the Game Coordinator server and when that's the ...
Definition: network_coordinator.cpp:700
CloseWindowByClass
void CloseWindowByClass(WindowClass cls)
Close all windows of a given class.
Definition: window.cpp:1188
NetworkRecvStatus
NetworkRecvStatus
Status of a network client; reasons why a client has quit.
Definition: core.h:22
ClientNetworkCoordinatorSocketHandler::last_activity
std::chrono::steady_clock::time_point last_activity
The last time there was network activity.
Definition: network_coordinator.h:82
ClientNetworkCoordinatorSocketHandler
Game Coordinator communication.
Definition: network_coordinator.h:54
NETWORK_INVITE_CODE_LENGTH
static const uint NETWORK_INVITE_CODE_LENGTH
The maximum length of the invite code, in bytes including '\0'.
Definition: config.h:74
NetworkReuseStunConnecter
Connecter used after STUN exchange to connect from both sides to each other.
Definition: network_coordinator.cpp:63
_network_coordinator_client
ClientNetworkCoordinatorSocketHandler _network_coordinator_client
The connection to the Game Coordinator.
Definition: network_coordinator.cpp:30
network_internal.h
NetworkSettings::server_invite_code
std::string server_invite_code
Invite code to use when registering as server.
Definition: settings_type.h:277
NetworkAddress::GetHostname
const std::string & GetHostname()
Get the hostname; in case it wasn't given the IPv4 dotted representation is given.
Definition: address.cpp:23
WC_NETWORK_ASK_RELAY
@ WC_NETWORK_ASK_RELAY
Network ask relay window; Window numbers:
Definition: window_type.h:483
ClientNetworkCoordinatorSocketHandler::SendServerUpdate
void SendServerUpdate()
Send an update of our server status to the Game Coordinator.
Definition: network_coordinator.cpp:464
CONNECTION_TYPE_TURN
@ CONNECTION_TYPE_TURN
The Game Coordinator needs you to connect to a relay.
Definition: tcp_coordinator.h:57
NetworkCoordinatorConnecter::NetworkCoordinatorConnecter
NetworkCoordinatorConnecter(const std::string &connection_string)
Initiate the connecting.
Definition: network_coordinator.cpp:109
Packet::Recv_uint8
uint8 Recv_uint8()
Read a 8 bits integer from the packet.
Definition: packet.cpp:306
ClientNetworkCoordinatorSocketHandler::next_update
std::chrono::steady_clock::time_point next_update
When to send the next update (if server and public).
Definition: network_coordinator.h:56
WL_ERROR
@ WL_ERROR
Errors (eg. saving/loading failed)
Definition: error.h:24
TCPServerConnecter
Definition: tcp.h:138
ClientNetworkStunSocketHandler::Stun
static std::unique_ptr< ClientNetworkStunSocketHandler > Stun(const std::string &token, uint8 family)
Send a STUN packet to the STUN server.
Definition: network_stun.cpp:83
NetworkCoordinatorConnecter::OnFailure
void OnFailure() override
Callback for when the connection attempt failed.
Definition: network_coordinator.cpp:111
NetworkCoordinatorConnecter::OnConnect
void OnConnect(SOCKET s) override
Callback when the connection succeeded.
Definition: network_coordinator.cpp:117
error
void CDECL error(const char *s,...)
Error handling for fatal non-user errors.
Definition: openttd.cpp:132
CheckGameCompatibility
void CheckGameCompatibility(NetworkGameInfo &ngi)
Check if an game entry is compatible with our client.
Definition: game_info.cpp:107
NetworkGameList
Structure with information shown in the game list (GUI)
Definition: network_gamelist.h:18
network.h
Packet::Send_string
void Send_string(const std::string_view data)
Sends a string over the network.
Definition: packet.cpp:181
ClientNetworkCoordinatorSocketHandler::turn_handlers
std::map< std::string, std::unique_ptr< ClientNetworkTurnSocketHandler > > turn_handlers
Pending TURN handler (if any), stored by token.
Definition: network_coordinator.h:60
DeserializeGRFIdentifierWithName
void DeserializeGRFIdentifierWithName(Packet *p, NamedGRFIdentifier *grf)
Deserializes the NamedGRFIdentifier (GRF ID, MD5 checksum and name) from the packet.
Definition: game_info.cpp:391
Debug
#define Debug(name, level, format_string,...)
Ouptut a line of debugging information.
Definition: debug.h:37
ClientSettings::network
NetworkSettings network
settings related to the network
Definition: settings_type.h:594
CONNECTION_TYPE_STUN
@ CONNECTION_TYPE_STUN
The Game Coordinator can connect to your server via a STUN request.
Definition: tcp_coordinator.h:56
NetworkDirectConnecter
Connect to a game server by IP:port.
Definition: network_coordinator.cpp:35
NETWORK_HOSTNAME_LENGTH
static const uint NETWORK_HOSTNAME_LENGTH
The maximum length of the host name, in bytes including '\0'.
Definition: config.h:57
NETWORK_RECV_STATUS_OKAY
@ NETWORK_RECV_STATUS_OKAY
Everything is okay.
Definition: core.h:23
network_gamelist.h
ClientNetworkCoordinatorSocketHandler::CloseToken
void CloseToken(const std::string &token)
Close everything related to this connection token.
Definition: network_coordinator.cpp:651
NETWORK_COORDINATOR_VERSION
static const byte NETWORK_COORDINATOR_VERSION
What version of game-coordinator-protocol do we use?
Definition: config.h:53
ClientNetworkCoordinatorSocketHandler::CloseTurnHandler
void CloseTurnHandler(const std::string &token)
Close the TURN handler.
Definition: network_coordinator.cpp:632
ClientNetworkCoordinatorSocketHandler::Receive_GC_REGISTER_ACK
bool Receive_GC_REGISTER_ACK(Packet *p) override
Game Coordinator acknowledges the registration.
Definition: network_coordinator.cpp:169
NETWORK_GAME_INFO_VERSION
static const byte NETWORK_GAME_INFO_VERSION
What version of game-info do we use?
Definition: config.h:51
NetworkCoordinatorSocketHandler::ReceivePackets
bool ReceivePackets()
Receive a packet at TCP level.
Definition: tcp_coordinator.cpp:58
NetworkGameList::info
NetworkGameInfo info
The game information of this server.
Definition: network_gamelist.h:21
ClientNetworkTurnSocketHandler::Turn
static std::unique_ptr< ClientNetworkTurnSocketHandler > Turn(const std::string &token, uint8 tracking_number, const std::string &ticket, const std::string &connection_string)
Prepare a TURN connection.
Definition: network_turn.cpp:89
NetworkDirectConnecter::tracking_number
uint8 tracking_number
Tracking number of this connection.
Definition: network_coordinator.cpp:38
PACKET_COORDINATOR_SERCLI_CONNECT_FAILED
@ PACKET_COORDINATOR_SERCLI_CONNECT_FAILED
Client/server tells the Game Coordinator the current connection attempt failed.
Definition: tcp_coordinator.h:37
_network_game_list_version
int _network_game_list_version
Current version of all items in the list.
Definition: network_gamelist.cpp:24
_network_server_invite_code
std::string _network_server_invite_code
Our invite code as indicated by the Game Coordinator.
Definition: network_coordinator.cpp:32
NetworkGameList::online
bool online
False if the server did not respond (default status)
Definition: network_gamelist.h:23
NetworkServerGameInfo::grfconfig
GRFConfig * grfconfig
List of NewGRF files used.
Definition: game_info.h:94
TCPConnecter::bind_address
NetworkAddress bind_address
Address we're binding to, if any.
Definition: tcp.h:101
NetworkTCPSocketHandler::CloseSocket
void CloseSocket()
Close the actual socket of the connection.
Definition: tcp.cpp:53
SetDParamStr
void SetDParamStr(uint n, const char *str)
This function is used to "bind" a C string to a OpenTTD dparam slot.
Definition: strings.cpp:296
PACKET_COORDINATOR_SERVER_UPDATE
@ PACKET_COORDINATOR_SERVER_UPDATE
Server sends an set intervals an update of the server.
Definition: tcp_coordinator.h:32
NETWORK_COORDINATOR_ERROR_REGISTRATION_FAILED
@ NETWORK_COORDINATOR_ERROR_REGISTRATION_FAILED
Your request for registration failed.
Definition: tcp_coordinator.h:65
Packet::Recv_uint16
uint16 Recv_uint16()
Read a 16 bits integer from the packet.
Definition: packet.cpp:320
ClientNetworkCoordinatorSocketHandler::connecting
bool connecting
Are we connecting to the Game Coordinator?
Definition: network_coordinator.h:83
ClientNetworkCoordinatorSocketHandler::IDLE_TIMEOUT
static constexpr std::chrono::seconds IDLE_TIMEOUT
The idle timeout; when to close the connection because it's idle.
Definition: network_coordinator.h:80
ClientNetworkCoordinatorSocketHandler::CloseStunHandler
void CloseStunHandler(const std::string &token, uint8 family=AF_UNSPEC)
Close the STUN handler.
Definition: network_coordinator.cpp:605
ClientNetworkCoordinatorSocketHandler::Receive_GC_CONNECTING
bool Receive_GC_CONNECTING(Packet *p) override
Game Coordinator informs the Client under what token it will start the attempt to connect the Server ...
Definition: network_coordinator.cpp:261