mirror of
https://github.com/netbirdio/netbird.git
synced 2026-05-20 23:59:55 +00:00
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.
This commit is contained in:
@@ -14,6 +14,7 @@ import (
|
||||
"github.com/netbirdio/netbird/relay/server/listener"
|
||||
"github.com/netbirdio/netbird/relay/server/listener/quic"
|
||||
"github.com/netbirdio/netbird/relay/server/listener/ws"
|
||||
"github.com/netbirdio/netbird/relay/server/listener/wt"
|
||||
quictls "github.com/netbirdio/netbird/shared/relay/tls"
|
||||
)
|
||||
|
||||
@@ -69,14 +70,27 @@ func (r *Server) Listen(cfg ListenerConfig) error {
|
||||
r.listenerMux.Lock()
|
||||
r.listeners = append(r.listeners, wSListener)
|
||||
|
||||
tlsConfigQUIC, err := quictls.ServerQUICTLSConfig(cfg.TLSConfig)
|
||||
tlsConfigQUIC, err := quictls.ServerMuxTLSConfig(cfg.TLSConfig)
|
||||
if err != nil {
|
||||
log.Warnf("Not starting QUIC listener: %v", err)
|
||||
} else {
|
||||
// WebTransport handler shares the QUIC listener's UDP socket via ALPN
|
||||
// multiplexing. http3 uses its own TLS config with only the "h3" ALPN.
|
||||
wtTLS := tlsConfigQUIC.Clone()
|
||||
wtTLS.NextProtos = []string{quictls.H3alpn}
|
||||
wtHandler := wt.New(wtTLS)
|
||||
if err := wtHandler.Install(r.relay.Accept); err != nil {
|
||||
log.Warnf("WebTransport handler not installed: %v", err)
|
||||
wtHandler = nil
|
||||
}
|
||||
|
||||
quicListener := &quic.Listener{
|
||||
Address: cfg.Address,
|
||||
TLSConfig: tlsConfigQUIC,
|
||||
}
|
||||
if wtHandler != nil {
|
||||
quicListener.H3 = wtHandler
|
||||
}
|
||||
|
||||
r.listeners = append(r.listeners, quicListener)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user