Files
netbird/shared/relay/client/endpoint.go
Claude 078c323ef3 relay: add WebTransport listener + WASM client, share UDP/443 via ALPN mux
The relay now accepts WebTransport sessions on the same UDP socket that
serves raw QUIC. The ALPN-multiplexing QUIC listener owns the socket and
dispatches incoming connections: "nb-quic" continues to the existing
relay handler, "h3" is handed to webtransport-go via http3.Server.
Browsers reach the relay over 443/udp without a second port.

Client side:
- Native builds keep using raw QUIC (no WT dialer registered).
- WASM/browser builds gain a WebTransport dialer that bridges syscall/js
  to the browser's WebTransport API and uses datagrams (matching the
  native QUIC dialer's semantics — no head-of-line blocking).
- The race dialer learned a transport hint so clients skip dialers a
  given relay has not advertised.

Management protocol carries the hint as a new RelayEndpoint{url,
transports[]} list on RelayConfig, mirroring how peers and proxies
announce capabilities. Older management servers that only send urls keep
working unchanged.

devcert build: relay generates an ECDSA P-256 cert with 13-day validity
(within the WebTransport serverCertificateHashes 14-day cap) and exposes
its SHA-256 so the WASM dialer can pin it.

Bumps quic-go v0.55.0 -> v0.59.0 (no API breaks for relay's importers)
and adds github.com/quic-go/webtransport-go v0.10.0.
2026-05-17 11:08:30 +00:00

38 lines
1.1 KiB
Go

package client
// ServerEndpoint announces a relay server along with the transports it speaks.
// Carried via the management RelayConfig.endpoints field; falls back to a
// URL-only entry (Transports == nil, meaning "try all dialers") for back-compat
// with older management servers that only sent flat URLs.
type ServerEndpoint struct {
URL string
Transports []string
}
// EndpointsFromURLs builds a list of hint-less endpoints from a flat URL list.
// Used when the management server sends only RelayConfig.urls (no per-relay
// capability metadata).
func EndpointsFromURLs(urls []string) []ServerEndpoint {
if len(urls) == 0 {
return nil
}
out := make([]ServerEndpoint, len(urls))
for i, u := range urls {
out[i] = ServerEndpoint{URL: u}
}
return out
}
// URLsFromEndpoints projects a list of endpoints back to a flat URL slice,
// preserving order. Used by call sites that don't yet consume transport hints.
func URLsFromEndpoints(endpoints []ServerEndpoint) []string {
if len(endpoints) == 0 {
return nil
}
out := make([]string, len(endpoints))
for i, e := range endpoints {
out[i] = e.URL
}
return out
}