Documentation
¶
Overview ¶
Package relayproto implements the iroh relay wire protocol: the framing, datagram, and handshake messages exchanged between a relay client and server.
It is a port of iroh-relay/src/protos. Frames are carried in binary WebSocket messages; each frame begins with a QUIC-varint frame type followed by a type-specific payload. The encodings here are byte-for-byte compatible with the Rust reference (verified by golden snapshot tests).
Index ¶
- Constants
- Variables
- func ParseHandshakeFrame(content []byte) (any, error)
- func SupportedProtocolVersions() []string
- type ClientAuth
- type ClientToRelayMsg
- type Datagrams
- type EcnCodepoint
- type FrameType
- type KeyMaterialClientAuth
- type ProtocolVersion
- type RelayToClientMsg
- type ServerChallenge
- type ServerConfirmsAuth
- type ServerDeniesAuth
- type Status
Constants ¶
const ClientAuthHeader = "x-iroh-relay-client-auth-v1"
ClientAuthHeader is the HTTP header carrying TLS key-material relay auth.
const MaxPacketSize = 64 * 1024
MaxPacketSize is the maximum size of a packet sent over the relay, counting only the visible data bytes, not the on-wire framing overhead.
const PerClientSendQueueDepth = 512
PerClientSendQueueDepth is the number of packets buffered for sending per client by a relay server.
Variables ¶
var ( ErrInvalidFrame = errors.New("relayproto: invalid frame encoding") ErrFrameTooLarge = errors.New("relayproto: frame too large") ErrUnknownFrameType = errors.New("relayproto: unknown frame type") ErrFrameTypeUnexpectedEnd = errors.New("relayproto: not enough bytes to parse frame type") ErrFrameNotAllowedInVersion = errors.New("relayproto: frame not allowed in this protocol version") )
Protocol errors.
var ( ErrServerDeniedAuth = errors.New("relayproto: the relay denied authentication") ErrSignatureInvalid = errors.New("relayproto: client signature invalid") ErrHandshakeDeserial = errors.New("relayproto: handshake frame deserialization failed") ErrUnexpectedFrameTag = errors.New("relayproto: unexpected handshake frame type") ErrNoKeyingMaterial = errors.New("relayproto: no TLS keying material") ErrKeyMaterialSuffix = errors.New("relayproto: TLS keying material suffix mismatch") )
Handshake errors.
Functions ¶
func ParseHandshakeFrame ¶
ParseHandshakeFrame parses one handshake frame from content (frame type + postcard body) into the concrete frame value, returning the value as one of *ServerChallenge, *ClientAuth, *ServerConfirmsAuth, or *ServerDeniesAuth.
func SupportedProtocolVersions ¶
func SupportedProtocolVersions() []string
SupportedProtocolVersions returns the wire identifiers of all supported protocol versions, newest first (the order offered to a relay server).
Types ¶
type ClientAuth ¶
ClientAuth is the client's authentication response: its public key and a signature of the challenge's message-to-sign.
func NewClientAuth ¶
func NewClientAuth(secretKey key.SecretKey, challenge ServerChallenge) ClientAuth
NewClientAuth builds a ClientAuth for challenge using secretKey.
func (ClientAuth) AppendTo ¶
func (a ClientAuth) AppendTo(dst []byte) []byte
AppendTo appends the framed wire encoding of a: frame type, the public key's 32 raw bytes, then the signature as a postcard serde_bytes value (varint length 64 followed by the 64 bytes).
func (ClientAuth) Verify ¶
func (a ClientAuth) Verify(challenge ServerChallenge) error
Verify checks this client auth against the challenge it answers.
type ClientToRelayMsg ¶
type ClientToRelayMsg struct {
Type FrameType
// DstEndpointID / Datagrams for FrameClientToRelayDatagram(Batch).
DstEndpointID key.EndpointID
Datagrams Datagrams
// Ping/Pong payload for FramePing/FramePong.
Ping [8]byte
}
ClientToRelayMsg is a message a client sends to a relay. Exactly one of its fields is meaningful, selected by Type.
func ParseClientToRelayMsg ¶
func ParseClientToRelayMsg(content []byte) (ClientToRelayMsg, error)
ParseClientToRelayMsg decodes a client-to-relay message.
func ParseClientToRelayMsgNoCopy ¶
func ParseClientToRelayMsgNoCopy(content []byte) (ClientToRelayMsg, error)
ParseClientToRelayMsgNoCopy decodes a client-to-relay message without copying datagram contents. The returned message aliases content.
func (ClientToRelayMsg) AppendTo ¶
func (m ClientToRelayMsg) AppendTo(dst []byte) []byte
AppendTo appends the wire encoding of m to dst.
func (ClientToRelayMsg) EncodedLen ¶
func (m ClientToRelayMsg) EncodedLen() int
EncodedLen returns the number of bytes AppendTo writes.
type Datagrams ¶
type Datagrams struct {
// Ecn is the explicit congestion notification codepoint, or 0 for Not-ECT.
Ecn EcnCodepoint
// SegmentSize is the per-datagram segment size when this transmit carries
// multiple datagrams (a batch); 0 means a single datagram.
SegmentSize uint16
// Contents holds the datagram bytes.
Contents []byte
}
Datagrams is one or multiple datagrams transferred via the relay, modeled after the QUIC transmit structure.
func DatagramsFromBytes ¶
DatagramsFromBytes wraps b as a single (non-batch) datagram.
type EcnCodepoint ¶
type EcnCodepoint uint8
EcnCodepoint is the QUIC explicit-congestion-notification codepoint carried in a relayed datagram (RFC 9000 §13.4 / IP ECN field values).
const ( // EcnEct1 is ECT(1). EcnEct1 EcnCodepoint = 1 // EcnEct0 is ECT(0). EcnEct0 EcnCodepoint = 2 // EcnCe is CE (congestion experienced). EcnCe EcnCodepoint = 3 )
type FrameType ¶
type FrameType uint32
FrameType identifies a relay protocol frame. It is encoded on the wire as a QUIC varint.
const ( FrameServerChallenge FrameType = 0 FrameClientAuth FrameType = 1 FrameServerConfirmsAuth FrameType = 2 FrameServerDeniesAuth FrameType = 3 FrameClientToRelayDatagram FrameType = 4 FrameClientToRelayDatagramBat FrameType = 5 FrameRelayToClientDatagram FrameType = 6 FrameRelayToClientDatagramBat FrameType = 7 FrameEndpointGone FrameType = 8 FramePing FrameType = 9 FramePong FrameType = 10 FrameHealth FrameType = 11 FrameRestarting FrameType = 12 FrameStatus FrameType = 13 )
Frame types, matching iroh-relay/src/protos/common.rs.
type KeyMaterialClientAuth ¶
type KeyMaterialClientAuth struct {
PublicKey key.PublicKey
Signature key.Signature
KeyMaterialSuffix [16]byte
}
KeyMaterialClientAuth is the client's 1-RTT relay authentication. It is sent in ClientAuthHeader as base64url-no-pad postcard bytes.
func KeyMaterialClientAuthFromHeader ¶
func KeyMaterialClientAuthFromHeader(value string) (KeyMaterialClientAuth, error)
KeyMaterialClientAuthFromHeader decodes a value from ClientAuthHeader.
func NewKeyMaterialClientAuth ¶
func NewKeyMaterialClientAuth(secretKey key.SecretKey, state *tls.ConnectionState) (KeyMaterialClientAuth, error)
NewKeyMaterialClientAuth builds a client auth header value from exported TLS keying material. It returns ErrNoKeyingMaterial if state cannot export it.
func (*KeyMaterialClientAuth) DecodePostcard ¶
func (a *KeyMaterialClientAuth) DecodePostcard(d *postcard.Decoder) error
DecodePostcard decodes a Rust KeyMaterialClientAuth.
func (KeyMaterialClientAuth) EncodePostcard ¶
func (a KeyMaterialClientAuth) EncodePostcard(e *postcard.Encoder) error
EncodePostcard encodes a like Rust KeyMaterialClientAuth: raw public key, serde_bytes signature, then raw 16-byte suffix.
func (KeyMaterialClientAuth) HeaderValue ¶
func (a KeyMaterialClientAuth) HeaderValue() (string, error)
HeaderValue encodes a for ClientAuthHeader.
func (KeyMaterialClientAuth) Verify ¶
func (a KeyMaterialClientAuth) Verify(state *tls.ConnectionState) error
Verify checks this key-material auth against the server's TLS state.
type ProtocolVersion ¶
type ProtocolVersion int
ProtocolVersion is the negotiated relay protocol version for a connection.
const ( ProtocolV1 ProtocolVersion = 1 ProtocolV2 ProtocolVersion = 2 )
Relay protocol versions.
func ParseProtocolVersion ¶
func ParseProtocolVersion(s string) (ProtocolVersion, bool)
ParseProtocolVersion parses a protocol version from its wire identifier.
func (ProtocolVersion) WireString ¶
func (v ProtocolVersion) WireString() string
WireString returns the wire identifier for v.
type RelayToClientMsg ¶
type RelayToClientMsg struct {
Type FrameType
// Datagrams / RemoteEndpointID for FrameRelayToClientDatagram(Batch).
RemoteEndpointID key.EndpointID
Datagrams Datagrams
// EndpointGone for FrameEndpointGone.
EndpointGone key.EndpointID
// Status for FrameStatus.
Status Status
// Ping/Pong payload for FramePing/FramePong.
Ping [8]byte
// Restarting durations for FrameRestarting.
ReconnectIn time.Duration
TryFor time.Duration
// Health problem text for FrameHealth (deprecated, V1 only).
Health string
}
RelayToClientMsg is a message a relay sends to a client. Exactly one of its fields is meaningful, selected by Type.
func ParseRelayToClientMsg ¶
func ParseRelayToClientMsg(content []byte, version ProtocolVersion) (RelayToClientMsg, error)
ParseRelayToClientMsg decodes a relay-to-client message. version gates the deprecated Health (V1 only) and Status (V2+) frames.
func ParseRelayToClientMsgNoCopy ¶
func ParseRelayToClientMsgNoCopy(content []byte, version ProtocolVersion) (RelayToClientMsg, error)
ParseRelayToClientMsgNoCopy decodes a relay-to-client message without copying datagram contents. The returned message aliases content.
func (RelayToClientMsg) AppendTo ¶
func (m RelayToClientMsg) AppendTo(dst []byte) []byte
AppendTo appends the wire encoding of m to dst.
func (RelayToClientMsg) EncodedLen ¶
func (m RelayToClientMsg) EncodedLen() int
EncodedLen returns the number of bytes AppendTo writes.
type ServerChallenge ¶
type ServerChallenge struct {
// Challenge is 16 random bytes the client must sign.
Challenge [16]byte
}
ServerChallenge is the challenge a relay sends a client to sign for endpoint authentication.
func (ServerChallenge) AppendTo ¶
func (c ServerChallenge) AppendTo(dst []byte) []byte
AppendTo appends the framed wire encoding (frame type + postcard body) of c.
type ServerConfirmsAuth ¶
type ServerConfirmsAuth struct{}
ServerConfirmsAuth confirms a successful connection. Its postcard body is empty.
func (ServerConfirmsAuth) AppendTo ¶
func (ServerConfirmsAuth) AppendTo(dst []byte) []byte
AppendTo appends the framed wire encoding of the (empty-bodied) confirmation.
type ServerDeniesAuth ¶
type ServerDeniesAuth struct {
Reason string
}
ServerDeniesAuth denies a connection with a reason.
func (ServerDeniesAuth) AppendTo ¶
func (d ServerDeniesAuth) AppendTo(dst []byte) []byte
AppendTo appends the framed wire encoding: frame type then the reason as a postcard string (varint byte-length prefix + UTF-8 bytes).
type Status ¶
type Status uint8
Status is a one-way relay-to-client message declaring the connection health.
const ( // StatusHealthy reports the connection recovered from previous problems. StatusHealthy Status = 0 // StatusSameEndpointIDConnected reports another endpoint connected with the // same id; no more messages will be received. StatusSameEndpointIDConnected Status = 1 // StatusRateLimited reports the relay is throttling this client's // outbound traffic. StatusRateLimited Status = 2 )