Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Task: Tunnel #64

Closed
4 tasks done
jacobtread opened this issue Dec 10, 2023 · 7 comments · Fixed by #65
Closed
4 tasks done

Task: Tunnel #64

jacobtread opened this issue Dec 10, 2023 · 7 comments · Fixed by #65
Assignees
Labels
enhancement New feature or request

Comments

@jacobtread
Copy link
Member

jacobtread commented Dec 10, 2023

Description

This is the tracking issue for the new server tunneling solution, this new layout will help make the WAN connectivity for Pocket Relay more reliable by using the server as a relay for the game client traffic.

In the standard game the client networking is a peer-to-peer structure where one client acts a host (server) and all the other clients connect to that client sending their information there which the host then provides the required details to the other clients.

This new solution takes advantage of being able to change the game networking topology from "PeerHosted" to "Dedicated" using this when a player creates a game as far as their game client is aware they have become a server for clients to connect too, but any other clients who join the game will be told instead that the game is a dedicated server and that they should connect to a local port (42132) this local port is apart of a pool of ports that the game server can use to talk to the client.

When the other clients then try to talk to 42132 on localhost the client takes all of the messages and forwards them to the Pocket Relay server which then sends them to the appropriate host players computer which then uses a local socket from a pool of sockets to send that data to the host "server" allowing the server and clients to communicate just as if they were all running on the same computer, thus bypassing any NAT restrictions that would normally cause issues.

The local pool of sockets is used to identify where each message is supposed to be sent, the server keeps track of which slot the player is in within the game and maps each player to one of the locally spawned sockets.

Diagrams

Below are some diagrams showcasing the different approaches

Normal Diagram

Here is a diagram of the way clients connect on the official server (And the current Pocket Relay setup pre tunneling):
image

Tunneled Diagram

Here is a diagram of the tunneled way of connecting:
image

Checklist

  • Experimental test demo
    • This was tested over LAN with two different devices and work correctly as expected
  • Needs to be optional but enabled by default
    • New configuration variable must be added for this system to allow the server to disable it
  • Proper stable implementation
    • The current implementation is very thrown together and needs to be stable/cleaned up before its distributed
  • Testing for players who've had issues playing over WAN before
@jacobtread jacobtread added the enhancement New feature or request label Dec 10, 2023
@jacobtread jacobtread self-assigned this Dec 10, 2023
@jacobtread
Copy link
Member Author

Added documentation for new tunneling configuration variable:
https://pocket-relay.pages.dev/docs/server/configuration/#tunnel

@jacobtread
Copy link
Member Author

jacobtread commented Dec 11, 2023

Tunnel Messages

Below is the message structure used by messages sent through the server tunnel

0                   1                   2        
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     Index     |            Length             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                               :
:                    Payload                    :
:                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Tunnel message frames contain the following fields:

Index: 8-bits. Determines the destination of the message within the current tunnel pool.

Length: 16-bits. Determines the size in bytes of the payload that follows

Payload: Variable length. The message bytes payload of Length in bytes

@jacobtread
Copy link
Member Author

jacobtread commented Dec 21, 2023

Currently, the tunnel system uses the client public IP address to associate the tunnels with their sessions upon game creation, however this won't be a permanent solution as multiple devices could share the same public IP and this requires that IP be determine accurately (Reverse proxies require setting up headers for forwarding).

My proposed system is a sort of "Association token" which would be a new server endpoint that the client could request (maybe "POST /server/associate" which would response with a unique token, allowing the clients to be associated by some unique token rather than IP address. The clients would then provide the association token both when connecting blaze sessions and creating tunnels so that the association can be made.

The token could be some server signed UUID or something of the sort (So that its unique and stateless but doesn't have to expire)

@jacobtread
Copy link
Member Author

The new association tokens system has been implemented in the following commits: 79ad07d PocketRelay/PocketRelayClientShared@bc53e2e PocketRelay/Client@b057ab0 PocketRelay/PocketRelayClientPlugin@34b0647 tunnel association no longer relies on IP addresses

@jacobtread
Copy link
Member Author

Local testing between two clients (One in an isolated VM) through an ngrok proxy showed that the tunnel is working correctly and was playable, still waiting on further community testing with actual players before public release can be made available:
image

@jacobtread
Copy link
Member Author

jacobtread commented Dec 26, 2023

For performance down the line it might be better to split group associations into their own pool collections with their own read/write lock so that inserting tunnels into the collection of pools doesn't block alll pool active connections from sending messages, in practice this probabbly isn't even noticeable since its only write locked for a two map insertions but worth looking into as a possible optimization.

@jacobtread
Copy link
Member Author

For performance down the line it might be better to split group associations into their own pool collections with their own read/write lock rather than the so that inserting tunnels into the collection of pools doesn't block all pool active connections from sending messages, in practice this probabbly isn't even noticeable since its only write locked for two map insertions but worth looking into as a possible optimization.

@jacobtread jacobtread linked a pull request Jan 1, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant