ChainSafe / ChainSafe/js-libp2p-quic

Dial from the listener's endpoint so QUIC connections can be hole punched

Open
#68 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
12
Forks
6
Avg merge
15m
Merged PRs (30d)
2

Description

Hole punching over QUIC needs the dial to be sent from the same UDP port the listener is bound to. Only then does the outgoing packet open the same NAT mapping that the other peer was told to send to. The transport cannot do this today.

`Client::new` in rust/lib.rs creates its own `quinn::Endpoint` on a random free port, while `Server::new` binds the configured one. That is two endpoints on two sockets, so a dial never uses the listener's mapping, and two dials timed together never meet. `@libp2p/tcp` has the same problem, which is why hole punching in js-libp2p today needs a circuit relay for the WebRTC signalling path.

quinn already supports one endpoint doing both. Its `Endpoint` is documented for use with incoming and outgoing connections, and the endpoint that `Server::new` builds through `new_with_abstract_socket` already gets `Some(server_config)`. It only lacks a default client config, so `connect()` returns `NoDefaultClientConfig`. rust-libp2p used this approach for its QUIC hole punching (libp2p/rust-libp2p#3964).

Would you accept a PR for this, and which shape do you prefer?

1. Dials reuse the listener's endpoint automatically whenever the transport is listening on a matching address family, and fall back to the current client otherwise. This is the better option for hole punching, but it changes the source port of outgoing connections for everyone using the package.
2. An option on `quic()` that turns it on, leaving current behaviour unchanged.

I am happy to write it either way. I would rather ask first than guess at the API.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with rust/lib.rs, especially Client::new, Server::new, and the quinn::Endpoint setup, then inspect the quic() entry point and existing connection tests. First resolve whether listener endpoint reuse is automatic or opt-in; done means the selected API lets QUIC dials use the listener's bound UDP port where applicable while preserving the intended fallback behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust, typescript
Domain
networking
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.