From 29cceb59a5b58d8c00a78022091f78838392cdce Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Thu, 15 Jul 2021 19:43:01 +0200 Subject: Doc: explain in a bit more detail how we implemented STUN --- docs/game_coordinator.md | 64 +++++++++++++++++++++++++++++++++++++++ src/network/network_coordinator.h | 4 ++- 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 docs/game_coordinator.md diff --git a/docs/game_coordinator.md b/docs/game_coordinator.md new file mode 100644 index 000000000..e8260f2e1 --- /dev/null +++ b/docs/game_coordinator.md @@ -0,0 +1,64 @@ +# Game Coordinator + +To allow two players to play together, OpenTTD uses a Game Coordinator to +facilitate this. + +When a server starts, it can register itself to the Game Coordinator. This +happens when `server_game_type` is set to either `invite-only` or `public`. +Upon registration, the Game Coordinator probes the network of the server, and +assigns the server an unique code, called an `invite code`. + +When a client wants to join a server, it asks the Game Coordinator to help +with this by giving it the `invite code` of the server. The Game Coordinator +will, in this order, attempt several ways to connect the client and server +together: + +## 1) Via direct IPv4 / IPv6 + +Upon registration, the Game Coordinator probes the server to see if a +direction connection to the server is possible based on the game port. It +tries this over the public IPv4 and IPv6, as announced by the server. +If either (or both) are successful, a client will always be asked to try +these direct IPs first when it wants to connect to this server. + +- If the server is IPv4 only, the client is only asked to connect via IPv4. +- If the server is IPv6 only, the client is only asked to connect via IPv6. +- If the server is both IPv4 and IPv6, the client is asked to connect to to + one of those first. If that fails, it is asked to connect to the other. + Whether it tries IPv4 or IPv6 first, strongly depends on several network + infrastructure related events. The biggest influence is the network + latency over both protocols to the OpenTTD infrastructure. + +In the end, if either the server is not reachable directly from the Internet +or the client fails to connect to either one of them, the connection attempt +continues with the next available method. + +## 2) Via STUN + +When a client wants to join a server via STUN, both the client and server +are asked to create a connection to the STUN server (normally +`stun.openttd.org`) via both IPv4 and IPv6. If the client or server has no +IPv4 or IPv6, it will not make a connection attempt via that protocol. + +The STUN server collects the public IPv4 and/or IPv6 of the client and server, +together with the port the connection came in from. For most NAT gateways it +holds true that as long as you use the same local IP + port, your public +IP + port will remain the same, and allow for bi-directional communication. +And this fact is used to later on pair the client and server. + +The STUN server reports this information directly to the Game Coordinator +(this in contrast to most STUN implementation, where this information is +first reported back to the peer itself, which has to relay it back to the +coordinator. OpenTTD skips this step, as the STUN server can directly talk to +the Game Coordinator). When the Game Coordinator sees a matching pair (in +terms of IPv4 / IPv6), it will ask both the client and server to connect to +their peer based on this public IP + port. + +As the NAT gateway forwards the traffic on the public IP + port to the local +port, this creates a bi-directional socket between client and server. The +connection to the STUN server can now safely be closed, and the client and +server can continue to talk to each other. + +Some NAT gateways do not allow this method; for those this attempt will fail, +and this also means that it is not possible to create a connection between +the client and server. diff --git a/src/network/network_coordinator.h b/src/network/network_coordinator.h index 9dd4c9b39..f6859f859 100644 --- a/src/network/network_coordinator.h +++ b/src/network/network_coordinator.h @@ -16,6 +16,8 @@ /** * Game Coordinator communication. + * For more detail about what the Game Coordinator does, please see + * docs/game_coordinator.md. * * For servers: * - Server sends SERVER_REGISTER. @@ -34,7 +36,7 @@ * - Send the client a GC_CONNECT with the peer address. * - a) Client connects, client sends CLIENT_CONNECTED to Game Coordinator. * - b) Client connect fails, client sends CLIENT_CONNECT_FAILED to Game Coordinator. - * 2) STUN? (see https://en.wikipedia.org/wiki/STUN) + * 2) STUN? * - Game Coordinator sends GC_STUN_REQUEST to server/client (asking for both IPv4 and IPv6 STUN requests). * - Game Coordinator collects what combination works and sends GC_STUN_CONNECT to server/client. * - a) Server/client connect, client sends CLIENT_CONNECTED to Game Coordinator. -- cgit v1.2.3-70-g09d2