willneedit / Arteranos

VR social app in a decentralized server-client model
Mozilla Public License 2.0
2 stars 1 forks source link

Relay service for connection establishment #172

Open willneedit opened 1 week ago

willneedit commented 1 week ago

Ref. #171, outgoing connections on IPv6 is usually fine, but IPv4 generally use Network Address Translation, like in the router.

The routers allow outgoing connections, and the incoming connections, too, as long as there's activity on the same channel. "Same channel" means a 5-tuple of (local address, local port, remote address, remote port, protocol).

Given the communication parts, A and B, both firewalled (or NATed), and the relay C (open to public), this would work....

Preconditions

Process

  1. A attempts to contact B, building the 5-tuple of the communication data, basing B's data (see above) and A's (local address, local port)
  2. A sends the 5-tuple to C (NB: C is open to public)
  3. C sends the data to (A and) B
  4. (*) A sends a 'ping' message to B - A's firewall is already primed by the communication attempt on 1). The attempt was been discarded by B's firewall.
  5. B sends a 'ping' message to A - B's firewall will be primed because A's outgoing messages will be treated as B's replies.

Once done, connections can be established.

As long as viable relays exist, NAT and firewalls are of little concern, even if it's dealing with IPv4-only users with no specific router configuration

willneedit commented 1 week ago

IPFS helps to keep a list of servers currently online. The list has to be extended to contain relays -- either servers could advertise themselves as relays, too, or A would put a 'message to all' for responding relays on the server advertisement channel.

🤔 That... could work.

willneedit commented 1 week ago

It works. Maybe I still need a better "I'm behind a firewall" detection, but better safe than sorry.

Initiating NAT punch process on accessible peers is like running through open doors, so false positives won't matter.

willneedit commented 1 week ago

Hmmm. Maybe a little bit over-engineered.

If we can use client.Connect(server) and server.Connect(client) - on both sides - NAT hole punching would naturally commence -- no relay needed.

Only unknown value is the client's public port - something the relay sees - but as long as I've seen, the port in the local net is equal to the port in the remote net. But, that isn't a given.

So, A can send (A.PemoteIP, A.LocalPort, C, token) to B via IPFS, in hope for B to

  1. B.Connect(A.RemoteIP, A.LocalPort) and
  2. send the NAT introduction request (token) to C (the relay)

If A.LocalPort is valid (from B's view) B.Connect() would work, because A's NAT would be already opened due to A's Connect() attempt on its part. Else, C would tell B A's correct remote port and the usual NAT punch process comtinue as usual.