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

wire

package
v1.0.28 Latest Latest
Warning

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

Go to latest
Published: Oct 24, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package wire is loft overlay protocol 1.0 (0x0100): Hello/Status handshake, mux frames, signed roster/lists, and fleet control. Handshake is auth/Hello/Status, not mux. CmdLeave ends the mux session.

Index

Constants

View Source
const (
	// UplinkBase64 is base64url (old clients and the auth GET).
	UplinkBase64 byte = 0
	// UplinkCookie85 is '~' || Z85(u16be length || blob). ~6% more mux
	// in the same encoded header budget; alphabet is Cookie-safe.
	UplinkCookie85 byte = 1
)
View Source
const (
	FltEnrolReq byte = 1
	FltEnrolOK  byte = 2
	FltEnrolNo  byte = 3
	FltBeat     byte = 4
	FltSlice    byte = 5
	FltDrain    byte = 6
)

Control messages on mux Open ctl:1 (relay trunk only).

View Source
const (
	EnrolUnknown  uint16 = 1
	EnrolForm     uint16 = 2
	EnrolDup      uint16 = 3
	EnrolDisabled uint16 = 4
)

EnrolNo reason codes: unknown id, bad form, duplicate, disabled.

View Source
const (
	CmdOpen   byte = 1
	CmdData   byte = 2
	CmdClose  byte = 3
	CmdPing   byte = 4
	CmdPong   byte = 5
	CmdPad    byte = 6
	CmdReset  byte = 7
	CmdDgram  byte = 8  // UDP datagram: Open-target prefix + payload
	CmdLeave  byte = 9  // end the mux session (stream_id 0, empty payload)
	CmdTune   byte = 10 // front event (client) or budget/inflight set (node)
	CmdReport byte = 11 // GET uplink applied-through seq; stream_id 0
	CmdFront  byte = 12 // which attached front carries bulk mux; stream_id 0
)

Multiplex commands. Handshake (auth, Hello, Status) is not mux.

View Source
const (
	// Header is u16be payload length, u8 cmd, u32be stream id.
	HeaderSize = 7
	MaxPayload = 16 << 10 // 16384; mux payload inside AEAD
)

Frame header is 7 bytes; payload is at most 16 KiB.

View Source
const (
	FrontGET     = "get"
	FrontWS      = "ws"
	FrontQUIC    = "quic"
	FrontH2      = "h2"
	FrontH3      = "h3"
	FrontConnect = "connect"
	FrontL3      = "l3"
)

Front names on the wire and in config. get/ws/quic stay; h2 and h3 are extra. connect is HTTP CONNECT splice (mux-off TCP); it is not in FrontOrder. l3 is HTTP/2 CONNECT carrying IP datagrams; it is not in FrontOrder.

View Source
const (
	// L3IP is one IPv4 or IPv6 datagram. The version nibble of payload[0] selects the family.
	L3IP byte = 0x00
	// L3Batch is repeated u16be length || datagram. Amortizes AEAD on a corked CONNECT.
	L3Batch byte = 0x01
)
View Source
const (
	KindExact  byte = 1
	KindSuffix byte = 2
	KindCIDR   byte = 3
)

Address-list entry kinds: exact domain, suffix, CIDR.

View Source
const (
	Proto    uint16 = 0x0100 // 1.0 until the first release; no bump while stubs remain
	ProtoMin uint16 = 0x0100
)

Protocol version: high byte major, low byte minor. 0x0100 is 1.0.

Major bump = incompatible framing or auth. Minor = new caps, old clients still speak. Handshake picks the highest version in both ranges.

View Source
const (
	HubHost     = "hub"
	HubHTTPPort = "1"
	HubH2Port   = "2"
	CtlHost     = "ctl"
	CtlPort     = "1"
)

Reserved mux Open targets on a relay trunk: hub:1 HTTP/1.1, hub:2 HTTP/2, ctl:1 fleet.

View Source
const (
	TuneSet    byte = 0
	TuneCalm   byte = 1 // H2 GOAWAY ENHANCE_YOUR_CALM
	Tune413    byte = 2
	Tune404    byte = 3
	TuneReset  byte = 4
	Tune429    byte = 5
	TuneGoaway byte = 6 // other GOAWAY
)

CmdTune payload is 4 bytes. Client event ≠ 0 reports a front break once; node event 0 sets live header_budget / inflight. Zero inflight or budget means leave that field unchanged.

View Source
const FrontBits = CapGET | CapWS | CapQUIC | CapH2 | CapH3 | CapConnect | CapL3

FrontBits is the cap mask of transport fronts (not other features).

View Source
const MemberCaps = NodeCaps &^ CapRelay

MemberCaps is the default Hello offer for loft-front / Supervise. CapRelay is omitted: a member must not self-assert a trunk (hub:* / ctl:1). loft-node in role relay ORs it back via ClientConfig.ExtraCaps. CapHold stays so a path drop still parks the mux (fresh 0x02, same instance_id).

NodeCaps is every capability this implementation advertises on Status. CapRelay stays here so a controller still shows it accepts trunks. Members MUST NOT copy this bit into Hello (see MemberCaps).

Variables

View Source
var (
	ErrTooLarge = errors.New("wire: payload too large")
	ErrShort    = errors.New("wire: short frame")
)

Frame codec errors. Payload above MaxPayload is ErrTooLarge.

FrontOrder is the try-list when both sides list every transport front.

Functions

func DecodeDrain

func DecodeDrain(b []byte) (id string, drain bool)

DecodeDrain reads id and drain flag.

func DecodeEnrolNo

func DecodeEnrolNo(b []byte) (uint16, string)

DecodeEnrolNo reads an EnrolNo. A short blob is EnrolForm with empty reason.

func DecodeFlt

func DecodeFlt(b []byte) (kind byte, body []byte, err error)

DecodeFlt splits u8 type || body.

func DecodeL3 added in v1.0.25

func DecodeL3(plain []byte) (typ byte, payload []byte, err error)

DecodeL3 splits an AEAD plaintext into type and payload.

func DecodeUplink(s string) ([]byte, error)

DecodeUplink accepts base64url or a '~' Z85 value. Empty is nil.

func DefaultFronts added in v1.0.23

func DefaultFronts() []string

DefaultFronts is the public path when config omits fronts: GET only. ws, h2, quic, h3, connect, and l3 stay off until listed.

func EncodeBatch

func EncodeBatch(frames []Frame) ([]byte, error)

EncodeBatch concatenates frames. CmdData larger than MaxPayload is split so a GET front does not drop the whole AEAD batch.

func EncodeDrain

func EncodeDrain(id string, drain bool) []byte

EncodeDrain is id || u8 (1 = drain).

func EncodeEnrolNo

func EncodeEnrolNo(code uint16, reason string) []byte

EncodeEnrolNo is u16be code || reason (u8 length, at most 64 bytes).

func EncodeFlt

func EncodeFlt(kind byte, body []byte) []byte

EncodeFlt is u8 type || body (the outer u32be length is the length-prefixed wrapper).

func EncodeFront added in v1.0.28

func EncodeFront(name string) []byte

EncodeFront is the CmdFront payload: the front name (get, ws, h2, quic, h3).

func EncodeL3 added in v1.0.25

func EncodeL3(typ byte, payload []byte) []byte

EncodeL3 is type || payload. writeMsg already carries the outer length.

func EncodeL3Batch added in v1.0.25

func EncodeL3Batch(pkts [][]byte) []byte

EncodeL3Batch is type 0x01 || {u16be n || datagram}...

func EncodeReport

func EncodeReport(applied uint64) []byte

EncodeReport is u64be applied-through GET seq (server nextSeq-1).

func EncodeTune

func EncodeTune(event, inflight byte, budget uint16) []byte

EncodeTune is event || inflight || u16be budget.

func EncodeUplink(blob []byte, enc byte) string

EncodeUplink is the GET header value for a sealed mux blob.

func Fail

func Fail(c Code, msg string) error

Fail wraps c and msg as an Error.

func IntersectFronts

func IntersectFronts(client, server []string) []string

IntersectFronts keeps client order among fronts the server also lists.

func Negotiate

func Negotiate(peer, node Offer) (selected uint16, err error)

Negotiate picks a version both speak. Caps in the result are the node's advertised set (what it can do), not the intersection: the client decides what to use. Empty peer (old hello) is treated as 1.0 with unknown caps.

func ParseFront

func ParseFront(s string) (string, error)

ParseFront accepts get/ws/h2/quic/h3/connect/l3. Empty is get. Vendor names are rejected.

func ParseFrontCmd added in v1.0.28

func ParseFrontCmd(p []byte) string

ParseFrontCmd reads a CmdFront payload. Unknown names are empty.

func ParseFronts

func ParseFronts(list []string) ([]string, error)

ParseFronts deduplicates names, preserving order. Empty list is DefaultFronts.

func ParseReport

func ParseReport(p []byte) (uint64, bool)

ParseReport reads a CmdReport payload. Short payloads are ignored.

func Port added in v1.0.5

func Port(s string) uint16

Port parses a TCP/UDP port. Junk or a value outside 0–65535 is 0.

func ProtoString

func ProtoString(v uint16) string

ProtoString formats a protocol version as "major.minor" (0x0100 is "1.0").

func ResetPayload

func ResetPayload(c Code) []byte

ResetPayload is the CmdReset body: u16be code.

func Resin

func Resin(f Frame) bool

Resin frames are held until CmdReport, then retransmitted. Draft frames are sent once: inner TCP or UDP will produce a new frame if the application still needs the bytes. Close/Reset are resin but SplitUplink puts them on their own GET seq after Data so they cannot jump queued Data in the same Cookie.

func SplitL3 added in v1.0.25

func SplitL3(plain []byte) ([][]byte, error)

SplitL3 returns the IP datagrams in one AEAD plaintext (0x00 or 0x01). Unknown types yield a nil slice and no error (ignore).

func SplitUplink(fs []Frame) [][]Frame

SplitUplink cuts one mux Pull into GET seqs: control resin, draft Data, then Close/Reset. A 404 retries only that seq.

func U16 added in v1.0.5

func U16(n int) uint16

U16 clips n into a uint16 so a config int cannot wrap on the wire.

func WriteFrame

func WriteFrame(w io.Writer, f Frame) error

WriteFrame encodes f and writes it to w.

Types

type Addr

type Addr struct {
	Kind byte
	Val  string
}

Addr is one list entry: kind plus value (domain, suffix, or CIDR).

func ParseAddr

func ParseAddr(s string) Addr

ParseAddr classifies a YAML/operator string: CIDR, leading . or *., else exact.

func (Addr) MatchHost

func (a Addr) MatchHost(host string) bool

MatchHost is case-insensitive exact or suffix match. CIDR never matches a host.

func (Addr) MatchIP

func (a Addr) MatchIP(ip net.IP) bool

MatchIP is CIDR containment. Exact and suffix never match an IP.

type AddrList

type AddrList struct {
	Name    string
	Entries []Addr
}

AddrList is one named set of addresses.

type Beat

type Beat struct {
	Load   byte
	Conns  uint32
	Prog   string
	Uptime uint32 // seconds
}

Beat is a relay heartbeat: load, live connections, program name, uptime.

func DecodeBeat

func DecodeBeat(b []byte) (Beat, error)

DecodeBeat reads a Beat. Trailing uptime is optional for older relays.

func (Beat) Encode

func (b Beat) Encode() []byte

Encode is load u8, conns u32be, program, uptime_s u32be.

type Cap

type Cap uint64

Cap is a feature bit advertised on the inner handshake (inside TLS). Only protocol abilities, never build or OS version.

const (
	CapMulti     Cap = 1 << iota // several instances on one key
	CapResume                    // ok_resumed + lease_hold
	CapStickyIP                  // reserved overlay IP on the key
	CapVLAN                      // VLAN from the key
	CapRules                     // switch ACL
	CapGET                       // GET + header uplink
	CapWS                        // WebSocket
	CapStatus                    // Hello/Status with Code
	CapTimers                    // keepalive / idle / reconnect in Status
	CapHelloCaps                 // this cap block
	CapReset                     // CmdReset on streams
	CapQUIC                      // QUIC/UDP front (loss recovery, migration)
	CapDgram                     // CmdDgram UDP
	CapClockless                 // auth without client clock
	CapTicket                    // Status ticket is the GET sid for 0x04 attach
	CapDecoy                     // Status lists this node's decoy origins
	CapH2                        // HTTP/2 CONNECT front
	CapH3                        // HTTP/3 (ALPN h3) front
	CapMask                      // decoy mask: borrowed origin cert on loft path
	CapRelay                     // Hello: this session is a relay trunk (ExtraCaps only; not a member default)
	CapRoster                    // Status may carry a signed relay roster
	CapLists                     // Status may advertise address-list serial/hash
	CapP2P                       // peer-to-peer overlay when mesh
	CapDNS                       // Status may carry DNS servers; gateway:53 is a resolver
	CapConnect                   // HTTP/2 CONNECT splice; TCP without inner mux
	CapResin                     // CmdReport + resin/draft GET uplink
	CapHold                      // mux streams survive a brief front drop
	CapQUICMark                  // quic front on a decoy node: the Initial must carry the loft mark
	CapH3Mark                    // h3 front on a decoy node: the Initial must carry the loft mark
	CapL3                        // HTTP/2 CONNECT carrying AEAD IP datagrams (no mux)

)

Capability bits on Hello/Status. SOCKS, TUN, CDN vendor, OS, and origin names are not caps.

func CapForFront

func CapForFront(f string) Cap

CapForFront maps a front name to its capability bit. Unknown names are 0.

func CapsWithFronts

func CapsWithFronts(base Cap, fronts []string) Cap

CapsWithFronts replaces FrontBits on base with the named fronts.

func (Cap) Fronts

func (c Cap) Fronts() []string

Fronts lists enabled transport fronts in FrontOrder, then connect and l3 when those bits are set. connect and l3 are not in the mux try-list; they still have to appear here so a reconnect keeps an advertised extra front. A decoy node sends quic and h3 as quic_mark and h3_mark so a client that cannot mark its QUIC Initial does not try them.

func (Cap) Has

func (c Cap) Has(x Cap) bool

Has reports whether all bits in x are set.

func (Cap) Names

func (c Cap) Names() []string

Names returns the set bit names in protocol order (multi, resume, …).

type Code

type Code uint16

Code is a protocol status. Values are stable; names may grow, numbers do not move.

const (
	OK        Code = 0x0000
	OKResumed Code = 0x0001 // same instance, same IP, fast path

	AuthBadKey        Code = 0x0101
	AuthRevoked       Code = 0x0102
	AuthExpired       Code = 0x0103
	AuthNotAuthorized Code = 0x0104
	AuthLimit         Code = 0x0105 // multi_limit reached
	AuthAlreadyOnline Code = 0x0106 // multi off, another instance holds the key
	AuthInstance      Code = 0x0107
	AuthClock         Code = 0x0108

	NetDisabled Code = 0x0201
	NetUnknown  Code = 0x0202
	Protocol    Code = 0x0203
	RateLimit   Code = 0x0204
	Timeout     Code = 0x0205
	Internal    Code = 0x0206

	IPPool     Code = 0x0301
	IPConflict Code = 0x0302
	VLANDenied Code = 0x0303

	PolicyDrop Code = 0x0401

	StreamRefused Code = 0x0501 // Open: dial failed
	StreamReset   Code = 0x0502 // peer closed with error
)

Assigned Status and stream codes. Numbers do not move.

func ParseReset

func ParseReset(p []byte) Code

ParseReset reads a CmdReset payload. A short payload is Internal.

func (Code) OK

func (c Code) OK() bool

OK reports a successful Status (new lease or same-instance resume).

func (Code) String

func (c Code) String() string

String is the stable protocol name, or "loft 0xNNNN" for unknown codes.

type EnrolReq

type EnrolReq struct {
	ID     string
	URL    string
	Decoy  string
	Fronts []string
}

EnrolReq is a relay asking the controller to publish it.

func DecodeEnrolReq

func DecodeEnrolReq(b []byte) (EnrolReq, error)

DecodeEnrolReq reads an EnrolReq. Empty id or url is an error.

func (EnrolReq) Encode

func (e EnrolReq) Encode() []byte

Encode is id, url, decoy, then at most 16 front names.

type Error

type Error struct {
	Code Code
	Msg  string
}

Error is a Status or stream failure with a stable Code.

func (Error) Error

func (e Error) Error() string

Error is "name" or "name: msg".

type Frame

type Frame struct {
	Cmd      byte
	StreamID uint32
	Payload  []byte
}

Frame is one mux frame: cmd, stream id, payload (at most MaxPayload).

func Decode

func Decode(buf []byte) (Frame, int, error)

Decode reads one frame from buf. n is bytes consumed.

func DecodeBatch

func DecodeBatch(buf []byte) ([]Frame, error)

DecodeBatch reads concatenated frames until buf is empty.

func FrontFrame added in v1.0.28

func FrontFrame(name string) Frame

FrontFrame is CmdFront on stream 0.

func PackResin

func PackResin(fs []Frame) []Frame

PackResin puts control resin first, then draft, then Close/Reset, then Pad.

func ReadFrame

func ReadFrame(r io.Reader) (Frame, error)

ReadFrame reads one length-prefixed frame from r.

func ReportFrame

func ReportFrame(applied uint64) Frame

ReportFrame is CmdReport on stream 0.

func ResinOnly

func ResinOnly(fs []Frame) []Frame

ResinOnly drops draft and Pad.

func SplitFront added in v1.0.28

func SplitFront(fs []Frame) (rest []Frame, last string)

SplitFront pulls CmdFront out of a mux batch. last is the last valid name.

func SplitReport

func SplitReport(fs []Frame) (rest []Frame, applied uint64, ok bool)

SplitReport pulls CmdReport out of a mux batch. applied is the highest contiguous GET seq the peer has ingested.

func SplitTune

func SplitTune(fs []Frame) (rest []Frame, event byte)

SplitTune pulls client events out of a mux batch. One incident per batch.

func TuneFrame

func TuneFrame(event, inflight byte, budget uint16) Frame

TuneFrame is CmdTune on stream 0.

func (Frame) Encode

func (f Frame) Encode() ([]byte, error)

Encode writes u16be length || cmd || u32be stream || payload.

type FrontEP added in v1.0.28

type FrontEP struct {
	Name string
	Path string
	URL  string
}

FrontEP is one Status front: name (get/ws/h2/h3/quic), HTTP path, optional URL. Empty URL is the host:port of the front that did 0x02. quic has an empty path.

type Hello

type Hello struct {
	Version    byte
	MemberID   string
	InstanceID string
	Min        uint16
	Max        uint16
	Caps       Cap
	Program    string // client binary name, e.g. loft
	Software   string // client release, e.g. 1.0.22 — not the protocol
}

Hello is the client's first inner payload after the key proof. Trailing proto/caps are optional: an old blob still decodes.

func DecodeHello

func DecodeHello(b []byte) (Hello, error)

DecodeHello reads a Hello. Trailing proto/caps are optional; unknown bytes are ignored.

func (Hello) Encode

func (h Hello) Encode() []byte

Encode is version, member_id, instance_id, then optional proto/caps/program/software. Strings are u8 length, at most 64 bytes. Max 0 fills ProtoMin–Proto and NodeCaps.

func (Hello) Offer

func (h Hello) Offer() Offer

Offer is this Hello's version range and caps. Max 0 is treated as 1.0.

type Lists

type Lists struct {
	Serial uint64
	Sets   []AddrList
	Pub    []byte
	Sig    []byte
}

Lists is a signed set of named address lists. Names have no protocol meaning; the client maps them to direct / via / drop.

func DecodeLists

func DecodeLists(b []byte) (Lists, error)

DecodeLists reads a signed lists blob. Trailing pub/sig may be omitted.

func ParseListsManifest

func ParseListsManifest(b []byte) (Lists, error)

ParseListsManifest accepts JSON Manifest or a raw Encode blob.

func (Lists) Body

func (l Lists) Body() []byte

Body is the signed fields: serial, at most 255 sets, 65535 entries each.

func (Lists) Encode

func (l Lists) Encode() []byte

Encode is Body || u8 pub_len || pub || u16be sig_len || sig.

func (Lists) Hash

func (l Lists) Hash() [32]byte

Hash is SHA-256 of Encode, carried in Status lists_hash.

func (Lists) ManifestJSON

func (l Lists) ManifestJSON() ([]byte, error)

ManifestJSON is the public cover document: {"v":1,"p":"<base64url>"}.

func (Lists) Verify

func (l Lists) Verify() error

Verify checks Ed25519 over Body with a 32-byte pub and 64-byte sig.

type Manifest

type Manifest struct {
	V int    `json:"v"`
	P string `json:"p"`
}

ManifestJSON is the public cover document: looks like a frontend bundle pointer, payload is base64url(Roster.Encode()). No member secrets.

type Offer

type Offer struct {
	Min  uint16
	Max  uint16
	Caps Cap
}

Offer is one side of version+caps. No software identity.

func NodeOffer

func NodeOffer() Offer

NodeOffer is this node's version range (1.0) and full cap set.

type PeerHint

type PeerHint struct {
	IP   string
	Host string
	Port uint16
	VLAN uint16
	Pub  []byte // 32-byte X25519; empty if the peer did not announce
}

PeerHint is one Status p2p hint: overlay IP, TLS-observed host, listen port, VLAN, and the peer's 32-byte X25519 pub for LFT.

type PeerTags added in v1.0.20

type PeerTags struct {
	IP   string
	Tags []string
}

PeerTags is overlay IP → member tags for P2P Allow.

type Policy added in v1.0.20

type Policy struct {
	Present    bool
	OwnTags    []string
	ACLDefault byte // 0 peers/accept, 1 drop
	Rules      []PolicyRule
	Peers      []PeerTags
}

Policy is compact ACL pushed so a client can enforce the same Allow on direct P2P. Present is true when the node sent this tail. Old Status blobs omit it; the client then skips P2P ACL (hub splice still checks).

type PolicyRule added in v1.0.20

type PolicyRule struct {
	Action  byte // 0 drop, 1 accept
	SrcVLAN *uint16
	DstVLAN *uint16
	Src     string
	Dst     string
	SrcTag  string
	DstTag  string
	Proto   byte
	Dport   []uint16
	Sport   []uint16
}

PolicyRule is one compact ACL line. Zero VLAN pointers and empty strings are wildcards. Proto: 0 any, 1 tcp, 2 udp, 3 icmp.

type RelayInfo

type RelayInfo struct {
	ID      string
	URL     string
	Decoy   string
	Fronts  []string
	Drain   bool
	Weight  byte   // 1–255; 0 encodes as 100
	Path    string // get/ws/h2 path; empty = node default
	MaskPub []byte // 32-byte mask pub for this front; empty = none
}

RelayInfo is one advertised front. The controller signs the roster; a relay cannot mint entries.

type Roster

type Roster struct {
	Serial uint64
	Relays []RelayInfo
	Pub    []byte // Ed25519 public, 32 bytes
	Sig    []byte
}

Roster is the controller's signed list of live fronts.

func DecodeRoster

func DecodeRoster(b []byte) (Roster, error)

DecodeRoster reads a signed roster. Trailing pub/sig and newer fields may be omitted.

func ParseManifest

func ParseManifest(b []byte) (Roster, error)

ParseManifest accepts JSON Manifest or a raw Encode blob.

func (Roster) Body

func (r Roster) Body() []byte

Body is the signed fields without pub/sig. At most 255 relays; weight 0 encodes as 100.

func (Roster) Encode

func (r Roster) Encode() []byte

Encode is Body || u8 pub_len || pub || u16be sig_len || sig.

func (Roster) ManifestJSON

func (r Roster) ManifestJSON() ([]byte, error)

ManifestJSON is the public cover document: {"v":1,"p":"<base64url(Roster.Encode())>"}.

func (Roster) Verify

func (r Roster) Verify() error

Verify checks Ed25519 over Body with a 32-byte pub and 64-byte sig.

type Route added in v1.0.20

type Route struct {
	Dst string
	Via string
}

Route is one Status managed CIDR. Via is the overlay IP of the member that owns the prefix, or empty/gateway when the node itself is next hop.

type Slice

type Slice struct {
	Serial  uint64
	ID      string
	URL     string
	Decoy   string
	Fronts  []string
	Drain   bool
	Weight  byte
	BeatMS  uint32
	Expires int64
	Pub     []byte
	Sig     []byte
}

Slice is the controller's signed config for one relay.

func DecodeSlice

func DecodeSlice(b []byte) (Slice, error)

DecodeSlice reads a signed slice. Trailing pub/sig may be omitted.

func (Slice) Body

func (s Slice) Body() []byte

Body is the signed slice fields without pub/sig. Weight 0 encodes as 100.

func (Slice) Encode

func (s Slice) Encode() []byte

Encode is Body || u8 pub_len || pub || u16be sig_len || sig.

func (Slice) Verify

func (s Slice) Verify() error

Verify checks Ed25519 over Body and rejects a past Expires.

type Status

type Status struct {
	Code         Code
	IP           string
	Gateway      string
	InstanceID   string
	MTU          uint16
	VLAN         uint16
	LeaseSec     uint32
	KeepaliveMS  uint32
	IdleMS       uint32
	ReMinMS      uint32
	ReMaxMS      uint32
	ReFastN      uint16
	ReFastForMS  uint32
	Proto        uint16   // selected protocol version
	Min          uint16   // node protocol min
	Max          uint16   // node protocol max
	Caps         Cap      // what this node implements
	Program      string   // node binary name, e.g. loft-node
	Software     string   // node release — not the protocol
	Ticket       []byte   // GET sid; other fronts present it in 0x04 to attach
	Decoy        []string // this node's splice origins; first is identity (SNI); empty = off
	MaskPub      []byte   // 32-byte X25519 public for decoy mask; empty = mask off
	Replicas     []string // extra node host:port for failover; empty = this addr only
	CanaryFlags  byte     // bit0 fat hello, bit1 split ClientHello
	CanaryPad    uint16   // extra ClientHello padding
	Roster       []byte   // signed controller roster; empty = none
	ListsSerial  uint64   // 0 = no address lists
	ListsHash    []byte   // SHA-256 of signed lists blob; 32 bytes
	Peers        byte     // 0 hub, 1 mesh, 2 vlan
	P2P          byte     // 1 = node allows p2p
	PeerHints    []PeerHint
	DNS          []string  // resolver IPs for the client TUN; empty = do not change OS DNS
	IP6          string    // overlay IPv6; empty = IPv4-only (optional tail)
	Gateway6     string    // overlay IPv6 gateway; empty = none
	HeaderBudget uint16    // GET encoded Cookie budget; 0 = client keeps its own
	Inflight     uint8     // GET inflight; 0 = client keeps its own
	H2Conns      uint8     // GET HTTP/2 connections (1–4); 0 = client keeps one
	UplinkEnc    uint8     // 0 base64url, 1 Cookie Z85; 0 = client keeps base64url
	GapHoldMS    uint32    // mux/stream hold after a front drop; 0 = client default
	Routes       []Route   // managed CIDRs (lab LAN behind a member); empty = none
	Policy       Policy    // compact ACL for P2P; omitted when empty
	SessionTTLMS uint32    // live session max; 0 = off. Distinct from LeaseSec (IP hold).
	RateBPS      uint32    // bulk Data/Dgram cap, both ways; 0 = off
	Fronts       []FrontEP // mux fronts this node accepts; empty = client keeps URI/defaults
}

Status is the node's reply: code, lease, timers, protocol offer.

func DecodeStatus

func DecodeStatus(b []byte) (Status, error)

DecodeStatus reads a Status. Trailing unknown fields MUST be ignored; old blobs still decode.

func (Status) Encode

func (s Status) Encode() []byte

Encode writes Status fields in protocol order. IPv6 is omitted when both addresses are empty.

type Tune

type Tune struct {
	Event    byte
	Inflight byte
	Budget   uint16 // encoded Cookie / header budget, bytes
	H2Conns  byte   // optional 5th byte; 0 = leave unchanged
}

Tune is one CmdTune payload.

func ParseTune

func ParseTune(p []byte) (Tune, bool)

ParseTune reads a CmdTune payload. Short payloads are ignored.

Jump to

Keyboard shortcuts

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