Help us shape the future of Go! Take the 2026 Go Developer Survey

skyquic

package
v1.3.104 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 31, 2026 License: AGPL-3.0 Imports: 17 Imported by: 0

Documentation

Overview

Package skyquic pkg/skyquic/flowcontrol.go c1-net-transport

Shared QUIC flow-control windows for every skywire QUIC-based carrier: the skynet QUIC transport (squicr, pkg/transport/network), dmsg-over-QUIC (pkg/dmsg/dmsg) and the WebTransport carriers that ride the same sockets. They live here, next to the shared TLS identity, because both packages build their own quic.Config and pkg/dmsg cannot import pkg/transport/network back.

Why they have to be set explicitly: quic-go's defaults are a 512 KB initial stream window and a 768 KB initial CONNECTION window, and the receiver's window is the whole in-flight budget of a BDP-bound path. On a 150 ms-RTT link that caps one connection at

768 KiB / 0.150 s ≈ 5.1 MB/s

which is exactly the throughput a squicr transport measured at before these were set. quic-go does auto-tune the window upward, but only while the receiver drains at least half a window inside ~4 RTT; a receive chain that hands frames to an application through a buffered channel does not reliably meet that, so the connection sits at the initial value indefinitely. One skywire transport is one QUIC connection carrying one stream, so the connection window is that transport's entire budget.

The values below start at ~8 MiB/stream and 12 MiB/connection (≈ 80 MB/s at 150 ms RTT, so the window is no longer the limit on any path we serve) and let auto-tuning grow to 64/96 MiB for longer or fatter paths. They are receive-side buffer CEILINGS, not allocations: quic-go grows the actual buffer on demand, so an idle or slow connection does not pay for them.

Package skyquic pkg/skyquic/identity.go c1-net-transport option A), shared by the skynet QUIC transport (pkg/transport/network) and dmsg-over-QUIC (pkg/dmsg). It lives in its own package — depending only on crypto/* and pkg/cipher — because pkg/transport/network imports pkg/dmsg/dmsg (the dmsg transport), so dmsg cannot import the helpers back from there without an import cycle.

QUIC mandates TLS 1.3, but skywire authenticates with secp256k1 keys, not a CA. Following the libp2p-tls pattern, each side presents a self-signed certificate with an ephemeral ed25519 key, and a custom X.509 extension carries the skywire public key plus a signature, by the matching skywire secret key, over the TLS key. The peer's VerifyPeerCertificate extracts the extension, checks the signature (proving the TLS key — hence the QUIC session — is controlled by the holder of the skywire SK), and pins it to the expected remote PK. A connection from the wrong PK is rejected at the TLS layer.

Package skyquic pkg/skyquic/webtransport.go c1-net-transport

Index

Constants

View Source
const (
	// InitialStreamReceiveWindow is the per-stream receive window a QUIC
	// connection starts with (quic-go default: 512 KB).
	InitialStreamReceiveWindow = 8 << 20 // 8 MiB
	// MaxStreamReceiveWindow bounds per-stream auto-tuning (default: 6 MB).
	MaxStreamReceiveWindow = 64 << 20 // 64 MiB
	// InitialConnectionReceiveWindow is the whole-connection receive window a
	// QUIC connection starts with (quic-go default: 768 KB — the cap this
	// fixes).
	InitialConnectionReceiveWindow = 12 << 20 // 12 MiB
	// MaxConnectionReceiveWindow bounds whole-connection auto-tuning
	// (default: 15 MB).
	MaxConnectionReceiveWindow = 96 << 20 // 96 MiB
)
View Source
const DmsgNextProto = "skywire-dmsg-1"

DmsgNextProto is the ALPN protocol id for dmsg-over-QUIC. It is distinct from NextProto on purpose: a dmsg server and the squicr transport can sit on the same UDP port (the transport port), demuxed by ALPN, and when both offered "skywire-quic-1" a dmsg session was handed to the transport acceptor, which waited 30 s for a stream a dmsg session never opens and then closed it — every dmsg client on QUIC redialed every server every 30 s. A dmsg client offers ONLY this id, so a socket with no dmsg server behind it refuses the handshake at once and the client falls back to TCP; a dmsg server accepts both ids so clients built before this keep their sessions.

View Source
const NextProto = "skywire-quic-1"

NextProto is the ALPN protocol id for the skywire QUIC TRANSPORT (squicr).

View Source
const WebTransportNextProto = "h3"

WebTransportNextProto is the ALPN for WebTransport over HTTP/3.

Variables

This section is empty.

Functions

func MatchesPinned added in v1.3.99

func MatchesPinned(der []byte, pins [][]byte) bool

MatchesPinned reports whether the DER certificate's SHA-256 is one of pins.

func NewCertificate

func NewCertificate(lPK cipher.PubKey, lSK cipher.SecKey) (tls.Certificate, error)

NewCertificate creates a self-signed TLS certificate whose ephemeral ed25519 key is bound to the skywire static identity (lPK/lSK).

func NewWebTransportCertificate

func NewWebTransportCertificate() (tls.Certificate, [32]byte, error)

NewWebTransportCertificate returns a fresh self-signed ECDSA P-256 certificate suitable for the browser WebTransport serverCertificateHashes path, plus its SHA-256 fingerprint (the value to publish in discovery and pin in the browser constructor). Unlike the QUIC identity cert (skyquic.NewCertificate), this cert carries NO skywire-PK binding extension: WebTransport's trust comes from the browser pinning this exact cert hash, and the binding "server PK X has WT cert hash H" lives in X's signed discovery entry. The client→server skywire-PK authentication happens in the dmsg Noise handshake over the WT stream (a browser cannot present a client certificate, so it can't be done in TLS).

The cert must be ECDSA P-256 with <=14-day validity for the browser to accept it via serverCertificateHashes.

func PinnedHashes added in v1.3.99

func PinnedHashes(hexHashes ...string) ([][]byte, error)

PinnedHashes decodes the advertised hex hashes a client pins, skipping empty ones (an older server advertises no next hash). A server is accepted if its certificate matches any of them.

func TLSConfig

func TLSConfig(cert tls.Certificate, expectedRemotePK *cipher.PubKey, onPeerPK func(cipher.PubKey)) *tls.Config

TLSConfig builds a *tls.Config that presents the local skywire-bound certificate and verifies the peer's certificate binds to a skywire PK.

  • expectedRemotePK != nil (dialer): the peer MUST present that exact PK.
  • onPeerPK != nil (listener): called with the verified remote PK.

func TLSConfigALPN

func TLSConfigALPN(cert tls.Certificate, expectedRemotePK *cipher.PubKey, onPeerPK func(cipher.PubKey), protos ...string) *tls.Config

TLSConfigALPN is TLSConfig with an explicit ALPN list: the ids this side offers (dialer) or accepts (listener), most preferred first.

func VerifyCert

func VerifyCert(rawCerts [][]byte) (cipher.PubKey, error)

VerifyCert parses the leaf certificate, extracts the skywire identity extension, verifies the binding signature, and returns the authenticated skywire public key.

func WebTransportTLSConfig

func WebTransportTLSConfig(cert tls.Certificate) *tls.Config

WebTransportTLSConfig builds a server *tls.Config for the WebTransport (HTTP/3) listener presenting the given cert. No client certificate is requested — the browser cannot present one; client PK auth is done in the dmsg Noise handshake.

Types

type RotatingWebTransportCert added in v1.3.99

type RotatingWebTransportCert struct {
	// contains filtered or unexported fields
}

RotatingWebTransportCert is a WebTransport server certificate that replaces itself before it expires, and always has its successor ready.

Both hashes are advertised. A browser pins every hash it is given and accepts the server if its certificate matches any of them, so a client that learned [current, next] keeps connecting straight through a rotation, with no fresh lookup — it only has to learn the new pair within one rotation period.

TLSConfig presents whichever certificate is current at each handshake, so a rotation reaches new connections at once and leaves established ones alone.

func NewRotatingWebTransportCert added in v1.3.99

func NewRotatingWebTransportCert() (*RotatingWebTransportCert, error)

NewRotatingWebTransportCert makes the first certificate and its successor, and starts rotating. Close stops the rotation.

func (*RotatingWebTransportCert) Close added in v1.3.99

func (r *RotatingWebTransportCert) Close()

Close stops the rotation. The current certificate keeps being served.

func (*RotatingWebTransportCert) Hash added in v1.3.99

func (r *RotatingWebTransportCert) Hash() [32]byte

Hash is the SHA-256 of the current certificate.

func (*RotatingWebTransportCert) NextHash added in v1.3.99

func (r *RotatingWebTransportCert) NextHash() [32]byte

NextHash is the SHA-256 of the certificate the next rotation will serve.

func (*RotatingWebTransportCert) OnRotate added in v1.3.99

func (r *RotatingWebTransportCert) OnRotate(fn func(current, next [32]byte))

OnRotate calls fn with the current and next hashes after every rotation.

func (*RotatingWebTransportCert) Rotate added in v1.3.99

func (r *RotatingWebTransportCert) Rotate() error

Rotate serves the next certificate from now on, makes a new next one, and tells every OnRotate subscriber both hashes.

func (*RotatingWebTransportCert) TLSConfig added in v1.3.99

func (r *RotatingWebTransportCert) TLSConfig() *tls.Config

TLSConfig is a server *tls.Config, as WebTransportTLSConfig builds, that presents the current certificate at each handshake.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL