Todo:
NAT problems
Private-natted peers are a problem. There are two cases:
- public-natted peer connects to private-natted host
- Callback: public peer needs to request a callback from private host
- Signalling: private host needs to "hear" the request
- private-natted peer connects to private-natted host (the double NAT problem)
- Relay: private peer needs to relay messages to the host through a public peer
- NAT detection: a peer needs to know whether it's private
libp2p's autorelay is supposed to solve these problems implicitly but I haven't been able to get it to work. I also tried regular relay, which I also haven't been able to get to work.
libp2p's autonat project does NAT detection but it takes 30 seconds for my machine to detect that it's private. Maybe we could run a NAT detection response service on Textcraft to speed this up?
Failing autorelay, I tried using the DHT for signalling by having the private host monitor the DHT for "advertisements" of callback requests from public peers. I might be doing something wrong but it's taking more than a minute for the host to "hear" a request. This is in addition to the 30 seconds it takes for NAT detection. So that has to be faster.
So here's my approach for working around most of these problems:
The easy case: connections to public hosts
- A public host generates a session token
- The host user shares the token with other people over a messenger
- Other people paste the session token in their GUI to connect to the host
The hard case: connections to private hosts
- A private host user generates a request token and sends it to a public peer user over a messenger
- The public peer user pastes it in their GUI and tells the private host user over a messenger to connect
- The private host user connects to the public peer and generates a session token
- The private host user shares the session token with other users over a messenger
- Other users paste the session token in the GUI to connect
- Each public peer connection generates a new session token that can relay through it
The magic session token here makes peers connect to the public peer instead of the private host. The public peer acts as a signal/relay peer (both signalling and relay). The session token specifies which public peer to use.
When a public peer connects, the signalling peer sends a callback request to the private host, which connects to the new public peer, causing the new peer to become another signaling/relay peer.
When a private peer connects, the signal/relay peer it connects through relays all messages to the private host.
The caveat
This means that in order to be a host, a private-natted peer needs at least one public-natted peer to connect and be a signal/relay peer. I think this is OK because a ton of routers support UPnP so public peers should be fairly common among a user base. The best solution for private-only sessions that I can think of is to allow public peers that are not connected to signal/relay for other sessions.
To get a list of public peers, we could actually use the DHT, which is slow, by caching the result and updating new info as it comes in. A host could reuse session ids and peers that connect through relay peers could pick their relay randomly.
Invite-only sessions
- A host peer has a list of peers that are allowed to connect
- Each peer already has its own key pair it can use to sign data
- Instead of a public session token, the host generates a unique session token for each invite
- The invited peer signs each message it sends and includes a nonce
- Messages could be encrypted with the host's public key or with a shared secret
Todo:
NAT problems
Private-natted peers are a problem. There are two cases:
libp2p's autorelay is supposed to solve these problems implicitly but I haven't been able to get it to work. I also tried regular relay, which I also haven't been able to get to work.
libp2p's autonat project does NAT detection but it takes 30 seconds for my machine to detect that it's private. Maybe we could run a NAT detection response service on Textcraft to speed this up?
Failing autorelay, I tried using the DHT for signalling by having the private host monitor the DHT for "advertisements" of callback requests from public peers. I might be doing something wrong but it's taking more than a minute for the host to "hear" a request. This is in addition to the 30 seconds it takes for NAT detection. So that has to be faster.
So here's my approach for working around most of these problems:
The easy case: connections to public hosts
The hard case: connections to private hosts
The magic session token here makes peers connect to the public peer instead of the private host. The public peer acts as a signal/relay peer (both signalling and relay). The session token specifies which public peer to use.
When a public peer connects, the signalling peer sends a callback request to the private host, which connects to the new public peer, causing the new peer to become another signaling/relay peer.
When a private peer connects, the signal/relay peer it connects through relays all messages to the private host.
The caveat
This means that in order to be a host, a private-natted peer needs at least one public-natted peer to connect and be a signal/relay peer. I think this is OK because a ton of routers support UPnP so public peers should be fairly common among a user base. The best solution for private-only sessions that I can think of is to allow public peers that are not connected to signal/relay for other sessions.
To get a list of public peers, we could actually use the DHT, which is slow, by caching the result and updating new info as it comes in. A host could reuse session ids and peers that connect through relay peers could pick their relay randomly.
Invite-only sessions