Documentation
¶
Overview ¶
Package protocol implements the versioned WireHop wire protocol.
Index ¶
- Constants
- Variables
- func AppendDataFrame(destination []byte, data Data) ([]byte, error)
- func AppendFrame(destination []byte, frame Frame) ([]byte, error)
- func DataFrameSize(data Data) (int, error)
- func MarshalClientHello(hello ClientHello) ([]byte, error)
- func MarshalDataFrame(data Data) ([]byte, error)
- func MarshalFrame(frame Frame) ([]byte, error)
- func MarshalServerHello(hello ServerHello) ([]byte, error)
- func SignClientHello(hello *ClientHello, key []byte) error
- func SignServerHello(hello *ServerHello, key []byte) error
- func VerifyClientHello(hello ClientHello, key []byte) error
- func VerifyServerHello(hello ServerHello, key []byte) error
- func WriteClientHello(writer io.Writer, hello ClientHello) error
- func WriteServerHello(writer io.Writer, hello ServerHello) error
- type AuthTag
- type ClientHello
- type ClockSync
- type CloseReason
- type Data
- type DeliveryReport
- type ErrorClass
- type ErrorCode
- type ErrorFrame
- type ErrorScope
- type Frame
- func AppendFrames(destination []Frame, message []byte) ([]Frame, error)
- func MarshalClockSync(sync ClockSync) (Frame, error)
- func MarshalData(data Data) (Frame, error)
- func MarshalDeliveryReport(report DeliveryReport) (Frame, error)
- func MarshalErrorFrame(value ErrorFrame) (Frame, error)
- func MarshalLaneAbandon(lane LaneGeneration) (Frame, error)
- func MarshalLaneAccepted(accepted LaneAccepted) (Frame, error)
- func MarshalProbe(probe Probe) (Frame, error)
- func MarshalSessionClose(reason CloseReason) (Frame, error)
- func MarshalSessionCreated(created SessionCreated) (Frame, error)
- func MarshalTimingPing(ping TimingPing) (Frame, error)
- func MarshalTimingPong(pong TimingPong) (Frame, error)
- func ParseFrames(message []byte) ([]Frame, error)
- func ReadFrame(reader io.Reader) (Frame, error)
- type FrameReader
- type FrameSequence
- type FrameType
- type HelloMode
- type LaneAccepted
- type LaneGeneration
- type LaneID
- type Nonce
- type PathGroupID
- type Probe
- type ServerHello
- type ServerHelloResult
- type SessionCreated
- type SessionID
- type SessionSecret
- type TimingPing
- type TimingPong
Constants ¶
const ( // MaxProbePayloadSize bounds opaque probe traffic in one frame. MaxProbePayloadSize = 1200 // ProbeFrameOverhead is the complete per-probe frame overhead excluding opaque padding. ProbeFrameOverhead = frameHeaderSize + 8 )
const ( // DataFrameOverhead is the complete per-datagram frame overhead excluding the WireGuard payload. DataFrameOverhead = frameHeaderSize + dataHeaderSize // MaxPacketSize is the largest UDP datagram carried by WireHop. MaxPacketSize = 65_535 // MaxPacketLifetimeMicros is the absolute wire-protocol packet lifetime limit. MaxPacketLifetimeMicros = 5 * 60 * 1_000_000 )
const ( // Version is the current WireHop wire protocol version. Version uint16 = 1 // MaxFrameContentSize is the largest valid type-specific frame content. MaxFrameContentSize = dataHeaderSize + MaxPacketSize // MaxEncodedFrameSize is the largest valid frame including its common header. MaxEncodedFrameSize = frameHeaderSize + MaxFrameContentSize )
const ( // MaxClientHelloSize bounds a creation hello containing the longest canonical target. MaxClientHelloSize = clientHelloMinimumSize + target.MaxTextSize // MaxDiagnosticSize bounds a peer-controlled handshake diagnostic. MaxDiagnosticSize = 512 )
const ( // SessionIDSize is the encoded size of a session identifier. SessionIDSize = 16 // SessionSecretSize is the encoded size of an ephemeral session secret. SessionSecretSize = 32 // LaneIDSize is the encoded size of a stable lane identifier. LaneIDSize = 16 // PathGroupIDSize is the encoded size of a session-scoped path group identifier. PathGroupIDSize = 16 // NonceSize is the encoded size of a handshake nonce. NonceSize = 12 )
Variables ¶
var ( // ErrInvalidControlFrame indicates malformed control-frame fields or length. ErrInvalidControlFrame = errors.New("invalid control frame") // ErrProbeTooLarge indicates probe padding above its absolute protocol limit. ErrProbeTooLarge = errors.New("probe too large") )
var ( // ErrInvalidFrameType indicates an unknown or unset frame type. ErrInvalidFrameType = errors.New("invalid frame type") // ErrFrameTooLarge indicates a frame above the absolute protocol limit. ErrFrameTooLarge = errors.New("frame too large") // ErrTrailingFrameData indicates bytes remaining after a complete frame sequence. ErrTrailingFrameData = errors.New("trailing frame data") )
var ( // ErrInvalidMagic indicates input that does not carry a WireHop protocol preface. ErrInvalidMagic = errors.New("invalid protocol magic") // ErrUnsupportedVersion indicates an incompatible WireHop protocol version. ErrUnsupportedVersion = errors.New("unsupported protocol version") // ErrInvalidClientHello indicates inconsistent client hello fields. ErrInvalidClientHello = errors.New("invalid client hello") // ErrInvalidServerHello indicates inconsistent server hello fields. ErrInvalidServerHello = errors.New("invalid server hello") // ErrMissingAuthKey indicates an empty long-term token or session secret. ErrMissingAuthKey = errors.New("missing authentication key") // ErrAuthenticationFailed indicates a mismatched handshake authentication tag. ErrAuthenticationFailed = errors.New("authentication failed") // ErrDiagnosticTooLarge indicates a handshake diagnostic above its protocol limit. ErrDiagnosticTooLarge = errors.New("diagnostic too large") )
var ( // ErrInvalidDataFrame indicates malformed data-frame fields or packet length. ErrInvalidDataFrame = errors.New("invalid data frame") )
Functions ¶
func AppendDataFrame ¶
AppendDataFrame appends one complete data frame to destination.
func AppendFrame ¶
AppendFrame appends the typed and length-prefixed binary encoding of frame to destination.
func DataFrameSize ¶
DataFrameSize validates data and returns its complete encoded wire size.
func MarshalClientHello ¶
func MarshalClientHello(hello ClientHello) ([]byte, error)
MarshalClientHello returns the canonical variable-width encoding of hello.
func MarshalDataFrame ¶
MarshalDataFrame returns one complete data-frame encoding without an intermediate payload copy.
func MarshalFrame ¶
MarshalFrame returns the typed and length-prefixed binary encoding of frame.
func MarshalServerHello ¶
func MarshalServerHello(hello ServerHello) ([]byte, error)
MarshalServerHello returns the variable-width canonical encoding of hello.
func SignClientHello ¶
func SignClientHello(hello *ClientHello, key []byte) error
SignClientHello validates hello and authenticates its canonical encoding with key.
func SignServerHello ¶
func SignServerHello(hello *ServerHello, key []byte) error
SignServerHello validates hello and authenticates its canonical encoding with key.
func VerifyClientHello ¶
func VerifyClientHello(hello ClientHello, key []byte) error
VerifyClientHello verifies hello against key without modifying it.
func VerifyServerHello ¶
func VerifyServerHello(hello ServerHello, key []byte) error
VerifyServerHello verifies hello against key without modifying it.
func WriteClientHello ¶
func WriteClientHello(writer io.Writer, hello ClientHello) error
WriteClientHello writes one complete client hello to writer.
func WriteServerHello ¶
func WriteServerHello(writer io.Writer, hello ServerHello) error
WriteServerHello writes one complete server hello to writer.
Types ¶
type ClientHello ¶
type ClientHello struct {
Mode HelloMode
UnixSeconds int64
MonotonicMicros uint64
Nonce Nonce
LaneID LaneID
Generation uint64
PathGroupID PathGroupID
SessionID SessionID
Target target.Endpoint
AuthTag AuthTag
}
ClientHello authenticates session creation or a lane connection generation.
func ParseClientHello ¶
func ParseClientHello(encoded []byte) (ClientHello, error)
ParseClientHello parses and validates a canonical variable-width client hello.
func ReadClientHello ¶
func ReadClientHello(reader io.Reader) (ClientHello, error)
ReadClientHello reads one complete variable-width client hello from reader.
type ClockSync ¶
type ClockSync struct {
ClientSendMicros uint64
ServerReceiveMicros uint64
ServerSendMicros uint64
ClientReceiveMicros uint64
}
ClockSync carries one complete four-timestamp clock sample.
func ParseClockSync ¶
ParseClockSync parses a clock synchronization frame.
type CloseReason ¶
type CloseReason uint8
CloseReason identifies an intentional session-close cause.
const ( // CloseClientShutdown identifies an intentional client process shutdown. CloseClientShutdown CloseReason = 1 )
func ParseSessionClose ¶
func ParseSessionClose(frame Frame) (CloseReason, error)
ParseSessionClose parses an explicit session-close control frame.
func (CloseReason) Valid ¶
func (r CloseReason) Valid() bool
Valid reports whether the close reason is defined by this protocol version.
type DeliveryReport ¶
type DeliveryReport struct {
LaneID LaneID
Generation uint64
DataBytes uint64
DataPackets uint64
ProbeBytes uint64
ProbePackets uint64
}
DeliveryReport reports cumulative parsing progress for one lane generation and direction.
func ParseDeliveryReport ¶
func ParseDeliveryReport(frame Frame) (DeliveryReport, error)
ParseDeliveryReport parses a cumulative delivery report frame.
type ErrorClass ¶
type ErrorClass uint8
ErrorClass determines client retry and process-lifecycle behavior.
const ( // ErrorRetryable identifies a temporary transport or capacity failure. ErrorRetryable ErrorClass = iota + 1 // ErrorLaneRejected identifies a terminal rejection scoped to one lane candidate. ErrorLaneRejected // ErrorSessionGone identifies a session that no longer exists on the server. ErrorSessionGone // ErrorSessionRejected identifies a terminal rejection of the authenticated session. ErrorSessionRejected )
func (ErrorClass) Valid ¶
func (c ErrorClass) Valid() bool
Valid reports whether the error class is defined by this protocol version.
type ErrorCode ¶
type ErrorCode uint16
ErrorCode identifies one machine-readable protocol, policy, or capacity failure.
const ( // ErrorMalformed identifies malformed handshake or frame input. ErrorMalformed ErrorCode = iota + 1 // ErrorUnsupportedVersion identifies an incompatible wire protocol version. ErrorUnsupportedVersion // ErrorAuthentication identifies invalid authentication material. ErrorAuthentication // ErrorReplay identifies a reused authenticated handshake nonce. ErrorReplay // ErrorTargetDenied identifies a target outside server policy. ErrorTargetDenied // ErrorSessionNotFound identifies an unknown or expired session. ErrorSessionNotFound // ErrorStaleGeneration identifies a non-increasing lane connection generation. ErrorStaleGeneration // ErrorLaneLimit identifies a per-session lane limit. ErrorLaneLimit // ErrorSessionLimit identifies a server session limit. ErrorSessionLimit // ErrorProtocolViolation identifies invalid in-session behavior. ErrorProtocolViolation ErrorUnavailable // ErrorRateLimited identifies a temporary admission or reconnect rate limit. ErrorRateLimited // ErrorInternal identifies an unexpected server failure. ErrorInternal // ErrorClockSkew identifies an authenticated timestamp outside the server's acceptance window. ErrorClockSkew )
type ErrorFrame ¶
type ErrorFrame struct {
Code ErrorCode
Class ErrorClass
Scope ErrorScope
LaneID LaneID
Generation uint64
Diagnostic string
}
ErrorFrame carries a stable in-session error and bounded diagnostic.
func ParseErrorFrame ¶
func ParseErrorFrame(frame Frame) (ErrorFrame, error)
ParseErrorFrame parses an in-session error frame.
type ErrorScope ¶
type ErrorScope uint8
ErrorScope identifies the state affected by a protocol error.
const ( // ErrorScopeLane limits an error to one lane generation. ErrorScopeLane ErrorScope = iota + 1 // ErrorScopeSession applies an error to the complete session. ErrorScopeSession )
func (ErrorScope) Valid ¶
func (s ErrorScope) Valid() bool
Valid reports whether the error scope is defined by this protocol version.
type Frame ¶
Frame is one decoded WireHop frame. Callers must treat Payload as read-only and honor the lifetime documented by the decoder that returned it.
func AppendFrames ¶
AppendFrames appends complete frames whose payloads alias message. On error, it returns destination at its original length.
func MarshalClockSync ¶
MarshalClockSync returns a clock synchronization frame.
func MarshalData ¶
MarshalData returns a generic frame containing data.
func MarshalDeliveryReport ¶
func MarshalDeliveryReport(report DeliveryReport) (Frame, error)
MarshalDeliveryReport returns a cumulative delivery report frame.
func MarshalErrorFrame ¶
func MarshalErrorFrame(value ErrorFrame) (Frame, error)
MarshalErrorFrame returns an in-session error frame.
func MarshalLaneAbandon ¶
func MarshalLaneAbandon(lane LaneGeneration) (Frame, error)
MarshalLaneAbandon returns a generation-specific lane-abandon frame.
func MarshalLaneAccepted ¶
func MarshalLaneAccepted(accepted LaneAccepted) (Frame, error)
MarshalLaneAccepted returns a lane-accepted control frame.
func MarshalProbe ¶
MarshalProbe returns a bounded probe frame.
func MarshalSessionClose ¶
func MarshalSessionClose(reason CloseReason) (Frame, error)
MarshalSessionClose returns an explicit session-close control frame.
func MarshalSessionCreated ¶
func MarshalSessionCreated(created SessionCreated) (Frame, error)
MarshalSessionCreated returns a session-created control frame.
func MarshalTimingPing ¶
func MarshalTimingPing(ping TimingPing) (Frame, error)
MarshalTimingPing returns a timing ping frame.
func MarshalTimingPong ¶
func MarshalTimingPong(pong TimingPong) (Frame, error)
MarshalTimingPong returns a timing pong frame.
func ParseFrames ¶
ParseFrames parses complete frames whose payloads alias message.
type FrameReader ¶
type FrameReader struct {
// contains filtered or unexported fields
}
FrameReader incrementally decodes stream frames with connection-local reusable storage.
type FrameSequence ¶
type FrameSequence struct {
// contains filtered or unexported fields
}
FrameSequence iterates over one completely validated frame sequence without allocating per-frame metadata. The source message must remain unchanged while the sequence or any returned frame is in use.
func ParseFrameSequence ¶
func ParseFrameSequence(message []byte) (FrameSequence, error)
ParseFrameSequence validates one complete frame sequence and returns an allocation-free iterator whose frame payloads alias message.
func (*FrameSequence) Next ¶
func (s *FrameSequence) Next() (Frame, bool)
Next returns the next frame whose payload aliases the validated message.
type FrameType ¶
type FrameType uint8
FrameType identifies one data-plane or control-plane frame.
const ( // FrameData carries one WireGuard UDP datagram. FrameData FrameType = iota + 1 // FramePing requests a lane timing response. FramePing // FramePong responds to a lane timing request. FramePong // FrameClockSync updates the shared session clock mapping. FrameClockSync // FrameProbe measures lane delivery behavior without reaching the UDP target. FrameProbe // FrameDeliveryReport reports cumulative peer parsing progress. FrameDeliveryReport // FrameSessionCreated accepts a newly created session. FrameSessionCreated // FrameLaneAccepted accepts a lane joined to an existing session. FrameLaneAccepted // FrameSessionClose explicitly closes a session. FrameSessionClose // FrameLaneAbandon coordinates generation-specific connection abandonment. FrameLaneAbandon // FrameError reports an in-session protocol or policy error. FrameError )
type LaneAccepted ¶
type LaneAccepted struct {
SessionID SessionID
PathGroupID PathGroupID
ReceiveMicros uint64
SendMicros uint64
}
LaneAccepted carries the effective path group and clock-bootstrap timestamps for a joined lane.
func ParseLaneAccepted ¶
func ParseLaneAccepted(frame Frame) (LaneAccepted, error)
ParseLaneAccepted parses a lane-accepted control frame.
type LaneGeneration ¶
LaneGeneration identifies one stable lane and exact connection generation.
func ParseLaneAbandon ¶
func ParseLaneAbandon(frame Frame) (LaneGeneration, error)
ParseLaneAbandon parses a generation-specific lane-abandon frame.
type LaneID ¶
type LaneID [LaneIDSize]byte
LaneID identifies one stable lane across connection generations.
func NewLaneID ¶
func NewLaneID() LaneID
NewLaneID returns a cryptographically random stable lane identifier.
func ParseLaneID ¶
ParseLaneID parses a lowercase or uppercase hexadecimal lane identifier.
type Nonce ¶
Nonce prevents replay of one authenticated handshake.
func ParseNonce ¶
ParseNonce parses a lowercase or uppercase hexadecimal handshake nonce.
type PathGroupID ¶
type PathGroupID [PathGroupIDSize]byte
PathGroupID identifies one session-scoped scheduling path group.
func NewPathGroupID ¶
func NewPathGroupID() PathGroupID
NewPathGroupID returns a cryptographically random path group identifier.
func ParsePathGroupID ¶
func ParsePathGroupID(value string) (PathGroupID, error)
ParsePathGroupID parses a lowercase or uppercase hexadecimal path group identifier.
func (PathGroupID) IsZero ¶
func (id PathGroupID) IsZero() bool
IsZero reports whether the path group identifier is unset.
func (PathGroupID) String ¶
func (id PathGroupID) String() string
String returns the lowercase hexadecimal path group identifier.
type Probe ¶
Probe carries bounded opaque bytes for lane delivery measurement.
func ParseProbe ¶
ParseProbe parses a bounded probe frame.
type ServerHello ¶
type ServerHello struct {
Result ServerHelloResult
RequestNonce Nonce
ServerUnixSeconds int64
SessionID SessionID
SessionSecret SessionSecret
PathGroupID PathGroupID
ReceiveMicros uint64
SendMicros uint64
ErrorCode ErrorCode
ErrorClass ErrorClass
ErrorScope ErrorScope
Diagnostic string
AuthTag AuthTag
}
ServerHello authenticates an admission result or a pre-upgrade rejection.
func ParseServerHello ¶
func ParseServerHello(encoded []byte) (ServerHello, error)
ParseServerHello parses and validates a canonical server hello.
func ReadServerHello ¶
func ReadServerHello(reader io.Reader) (ServerHello, error)
ReadServerHello reads one variable-width server hello from reader.
type ServerHelloResult ¶
type ServerHelloResult uint8
ServerHelloResult distinguishes successful creation, lane acceptance, and rejection.
const ( // ServerSessionCreated accepts a newly created session. ServerSessionCreated ServerHelloResult = iota + 1 // ServerLaneAccepted accepts a joined lane connection generation. ServerLaneAccepted // ServerRejected rejects the client hello with a stable protocol error. ServerRejected )
func (ServerHelloResult) Valid ¶
func (r ServerHelloResult) Valid() bool
Valid reports whether the server hello result is defined by this protocol version.
type SessionCreated ¶
type SessionCreated struct {
SessionID SessionID
SessionSecret SessionSecret
PathGroupID PathGroupID
ReceiveMicros uint64
SendMicros uint64
}
SessionCreated carries session credentials and clock-bootstrap timestamps.
func ParseSessionCreated ¶
func ParseSessionCreated(frame Frame) (SessionCreated, error)
ParseSessionCreated parses a session-created control frame.
type SessionID ¶
type SessionID [SessionIDSize]byte
SessionID identifies one authenticated WireHop session.
func NewSessionID ¶
func NewSessionID() SessionID
NewSessionID returns a cryptographically random session identifier.
func ParseSessionID ¶
ParseSessionID parses a lowercase or uppercase hexadecimal session identifier.
type SessionSecret ¶
type SessionSecret [SessionSecretSize]byte
SessionSecret authorizes lane joins to an established session.
func NewSessionSecret ¶
func NewSessionSecret() SessionSecret
NewSessionSecret returns a cryptographically random ephemeral session secret.
type TimingPing ¶
TimingPing requests one lane-local timing observation.
func ParseTimingPing ¶
func ParseTimingPing(frame Frame) (TimingPing, error)
ParseTimingPing parses a timing ping frame.
type TimingPong ¶
TimingPong responds with receiver timing for a prior ping.
func ParseTimingPong ¶
func ParseTimingPong(frame Frame) (TimingPong, error)
ParseTimingPong parses a timing pong frame.