Repository navigation
Conversation
…es not bind A peer can reach a transport through a proxy, a NAT, or an overlay that maps another address and port to the bound socket. InterfaceFilter::Explicit cannot express this, because it replaces each port with the bound port. TcpTransportBuilder and QuicTransportBuilder get advertise_addrs. It advertises the given socket addresses, ports included, in place of the interface_filter result. InterfaceFilter::Explicit keeps its behavior. A QUIC transport with advertised addresses lists no per-socket ports. Every lane of a peer then dials the advertised port, because a mapping covers one port. QuicTransport::bound_addr gives the address that such a mapping forwards to. Tests: two TCP nodes, each behind a byte-counting proxy on its own port, exchange a request and its response through the proxies. Two QUIC transports do the same through UDP relays, on two lanes. Signed-off-by: Ryan Olson <rolson@nvidia.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
WalkthroughTCP and QUIC builders now accept explicit advertised socket addresses while transports listen on their bound addresses. QUIC registration filters peer endpoints by address-family reachability. Documentation and integration tests cover address configuration and traffic through proxies and relays. ChangesAdvertised transport addresses
Priority: ➖ Normal Estimated code review effort: 3 (Moderate) | ~25 minutes Change: Feature Sequence Diagram(s)sequenceDiagram
participant ClientLane
participant ServerUdpRelay
participant QUICServer
participant ClientUdpRelay
ClientLane->>ServerUdpRelay: Send datagrams to the advertised endpoint
ServerUdpRelay->>QUICServer: Forward datagrams to the bound server socket
QUICServer->>ClientUdpRelay: Send reply to the advertised client endpoint
ClientUdpRelay->>ClientLane: Relay reply to the client source
Suggested reviewers: Merge Risk: ⚪ Minimal · up to
|
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
…family The QUIC dial sockets bind the family of the bind address. A peer that advertised an address of the other family first, or only, was registered, and then every frame to it failed with "invalid remote address". This happened with any such peer, and advertise_addrs made it easy to reach: an IPv4 node behind an IPv6 proxy. register now selects among the advertised addresses of the dial family only, and refuses a peer that advertises none with InvalidEndpoint. Signed-off-by: Ryan Olson <rolson@nvidia.com>
The previous commit kept only the advertised addresses of the bind address family. On Linux an IPv6 dial socket is dual-stack by default and reaches IPv4 peers through mapped addresses, so that filter refused IPv4 peers that an IPv6 transport could already reach. The builder now records whether the dial sockets reach IPv4: an IPv4 socket does, and an IPv6 socket does when IPV6_V6ONLY is off. The filter keeps IPv4 addresses on that condition, and IPv6 addresses only for an IPv6 transport. Signed-off-by: Ryan Olson <rolson@nvidia.com>
There was a problem hiding this comment.
🔵 Needs a closer look
Moderate issues remain for unused QUIC server sockets and loss of scoped IPv6 address information.
No open issues 🎉
What changed in this PR
Adds support for TCP and QUIC transports to advertise externally reachable addresses and ports while continuing to bind locally, enabling proxy, NAT, and overlay deployments.
Changes:
- Adds
advertise_addrsbuilder APIs for TCP and QUIC. - Filters QUIC peer endpoints by dial-socket address-family reachability and exposes
bound_addr(). - Adds proxy/relay integration tests and documentation for advertised-address behavior.
| File | Reviewed changes |
|---|---|
README.md |
Links to advertised-address documentation. |
lib/velo/tests/advertised_address.rs |
Tests TCP proxy traversal, QUIC relay traversal, advertised ports, and lane behavior. |
lib/velo/src/transports/utils/interfaces.rs |
Converts advertised socket addresses into transport endpoints; scoped IPv6 address handling requires changes. |
lib/velo/src/transports/tcp/transport/builder.rs |
Adds TCP advertised-address configuration. |
lib/velo/src/transports/quic/transport/builder.rs |
Adds QUIC advertised-address configuration and dial-family detection; extra server sockets remain live in advertised-address mode. |
lib/velo/src/transports/quic/transport.rs |
Exposes the bound address and filters unreachable QUIC endpoints during registration. |
lib/velo/src/transports/quic/tests.rs |
Tests QUIC address-family selection and dual-stack behavior. |
lib/velo/src/transports/quic/endpoint.rs |
Documents advertised endpoint behavior; descriptions need updating for proxy/NAT addresses. |
lib/velo/Cargo.toml |
Registers the advertised-address integration test target. |
docs/src/concepts/transports.md |
Documents advertised addresses, QUIC lane behavior, and stream limitations. |
Review effort: Lite
What
A TCP or QUIC transport can advertise socket addresses, ports included, that differ from its bind address. A peer that reaches the transport through a proxy, a NAT, or an overlay that maps another port then dials the mapped address.
TcpTransportBuilder::advertise_addrsandQuicTransportBuilder::advertise_addrs. The given addresses replace theinterface_filterresult in theWorkerAddress. The transport still listens on its bind address.InterfaceFilter::Explicitkeeps its behavior: it replaces each port with the bound port. Existing callers can depend on that, so this PR adds a builder method and does not change the variant. The change is additive. The semver gate accepts it under the 0.21.0 bump thatmainalready carries.QuicTransport::bound_addrgives the first server socket address, which is where such a mapping forwards.registerkeeps only the advertised addresses that the dial sockets reach. These are IPv4 for an IPv4 transport. For an IPv6 transport, they are IPv6, and also IPv4 if its sockets are dual-stack. A peer with no reachable address is refused at registration. Before this, the transport registered the peer, and every frame then failed.Out of scope
The per-stream TCP listener that
VeloBuilderstarts does not useadvertise_addrs. Behind a proxy, use.mux_only(). The book says this.Tests
lib/velo/tests/advertised_address.rs:With
advertise_addrsignored in both builders, all three tests fail.Conflicts
git merge-treeagainst #154 (QUIC mTLS) shows conflicts inREADME.md(both add a paragraph above the lanes paragraph) and inlib/velo/src/transports/quic/transport.rs(registerand the struct fields).builder.rs,Cargo.tomland the book merge cleanly. Whichever PR merges second needs a small rebase. The hub TLS PR (#155) merges cleanly with both.Review ledger
An independent reviewer did three rounds (
rust-code-review).registerkeeps only the reachable addresses, and refuses a peer with none (InvalidEndpoint). Two tests, which failed first.IPV6_V6ONLYoff). Testa_dual_stack_dialer_reaches_an_ipv4_peerfails with the round 1 filter.The dial sockets were not made dual-stack. That would change every QUIC dialer, and it fails on hosts with IPv6 off.