s2n-quic icon indicating copy to clipboard operation
s2n-quic copied to clipboard

Allow acessing the UDP socket to enable sidechannel messages for NAT hole punching

Open Frando opened this issue 2 years ago • 2 comments

Problem:

I'd like to use s2n_quic in a peer-to-peer scenario with UDP hole punching. Usually, a rendevouz server is used to tell a peer acting as a Server the addresses of other peers wanting to connect. The "server" peer then sends UDP packets to the peer's address, to open holes through their NAT. After a few packets, the socket is able to accept incoming connections from the peer. I have a demo that first hole-punches a UDP socket and then uses the same socket to construct a Server (through s2n_quic::provider::io::tokio::Builder::default().with_rx_socket(socket)?. This works fine and my server, which is behind a NAT, can accept connections from peers.

However after having punched a hole to the first peer, the UDP socket is passed to s2n_quic and then isn't accessible outside of the QUIC flow anymore. To accept further connections, I'd need to send more hole punching packets to other peers.

Solution:

A way to either access the raw UDP socket passed into s2n_quic, or a way to abstract over the raw socket, to handle hole punching messages there. The hole punching messages themselves can be anything socket.send_to(&[0u8], peer_addr) is fine.

For example, quinn provides a new_with_abstract_socket method that can be used to wrap a raw UDP socket and handle sending holepunching messages from the wrapper.

  • Does this change what s2n-quic sends over the wire? Somehow, as it would allow to send messages over the UDP socket outside of the QUIC flow. Optionally of course.
  • Does this change any public APIs? --> Maybe

Requirements / Acceptance Criteria:

Out of scope:

Frando avatar Jan 20 '23 10:01 Frando

Are you able to use try_clone before passing the socket to s2n-quic?

Because we've released v1, abstracting the socket interface will lock us into the currently implemented features and make it more difficult to add new features in the future (at least without releasing a new major version, which we would really like to avoid).

camshaft avatar Jan 25 '23 19:01 camshaft

I am working on a hole punching implementation that abstracts the UDPSocket entirely, as it might tunnel over a different protocol or use different sockets, depending on what is available. In quinn there is AsyncUdpSocket which allows me to abstract over the actual socket and inject my logic on how to handle the packets.

dignifiedquire avatar Mar 16 '23 13:03 dignifiedquire