handoff

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Nov 7, 2026 License: Apache-2.0 Imports: 22 Imported by: 0

Documentation

Overview

Package handoff is fiberd side of connection handoff. It accepts a caller's TLS connection, reads the routing key from the ClientHello's server name without consuming or decrypting anything, and passes the socket to the fiber the key belongs to. It also derives the TLS identity a grant's fibers serve with.

Index

Constants

View Source
const (
	DefaultHelloTimeout = time.Second
	DefaultMaxPending   = 1024
)

Defaults for Router.

View Source
const MaxHello = 5 + 16384

MaxHello is the most fiberd reads of a ClientHello. That is one TLS record, its header plus the largest plaintext a record may carry.

View Source
const Suffix = ".fiberd"

Suffix ends every server name a caller sends, as in <routing_key>.fiberd.

Variables

View Source
var (
	// ErrShort means the bytes end before the ClientHello does. Read more.
	ErrShort = errors.New("handoff: ClientHello incomplete")
	// ErrNotTLS means the connection does not start with a TLS handshake
	// record.
	ErrNotTLS = errors.New("handoff: not a TLS ClientHello")
	// ErrMalformed means a length or field in the ClientHello is
	// inconsistent, or the ClientHello does not fit in its first record.
	ErrMalformed = errors.New("handoff: malformed ClientHello")
	// ErrNoServerName means the ClientHello names no server.
	ErrNoServerName = errors.New("handoff: ClientHello has no server name")
	// ErrUnknownRoute means the server name is not a routing key fiberd
	// handed out, or the fiber behind it is gone.
	ErrUnknownRoute = errors.New("handoff: unknown routing key")
	// ErrKeyMismatch means the fiber's TLS key is not the one the home
	// pinned for it.
	ErrKeyMismatch = errors.New("handoff: fiber key does not match its pin")
)

Functions

func ClientConfig

func ClientConfig(routingKey, serverKeySHA256 string, cert tls.Certificate) *tls.Config

ClientConfig is a caller's TLS configuration for a handoff fiber. It names the fiber by its routing key and presents cert, the certificate the grant is bound to. The fiber refuses any other. It accepts only the server key whose pin the home returned with the clone.

func KeyPin

func KeyPin(spki []byte) string

KeyPin is the pin of a DER SubjectPublicKeyInfo, as Identity.KeySHA256.

func ServerName

func ServerName(b []byte) (string, error)

ServerName returns the host name in the server name extension of the TLS ClientHello at the start of b. It reads only the record header, the handshake header and the extensions. ErrShort means b ends before the ClientHello does. The ClientHello must fit in its first record.

Types

type Identity

type Identity struct {
	CertPEM []byte // self-signed, for *.fiberd
	Cert    []byte // the same certificate as DER, CloneResponse server_cert
	KeyPEM  []byte // PKCS #8 Ed25519 private key
	// KeySHA256 is the base64url SHA-256 of the certificate's
	// SubjectPublicKeyInfo. Callers pin it (CloneResponse
	// server_key_sha256).
	KeySHA256 string
}

Identity is the TLS identity a grant's handoff fibers serve with.

func Derive

func Derive(master []byte, grantUID string) (Identity, error)

Derive makes the grant's identity from the home's handoff key. Every home with the same key derives the same identity for the same grant, so a session resumed on another home still holds the key its caller pinned.

type Router

type Router struct {
	// Advertise is the address callers dial (tcp://host:port).
	Advertise string
	// Deliver passes a connected socket to the fiber. The router closes
	// its own copy afterwards.
	Deliver func(fiberID string, conn *os.File) error
	// HelloTimeout bounds how long a connection may take to send its
	// ClientHello (DefaultHelloTimeout when zero).
	HelloTimeout time.Duration
	// MaxPending bounds connections waiting for their ClientHello. Beyond
	// it, new ones are closed at once (DefaultMaxPending when zero).
	MaxPending int
	// contains filtered or unexported fields
}

Router owns the home's handoff listener. Routing keys live in memory only. A fiberd restart ends every fiber, so no key outlives fiberd.

func (*Router) Add

func (r *Router) Add(fiberID string) (string, error)

Add gives a fiber a fresh routing key and returns it.

func (*Router) Key

func (r *Router) Key(fiberID string) (string, bool)

Key returns a fiber's routing key.

func (*Router) Remove

func (r *Router) Remove(fiberID string)

Remove forgets a fiber's routing key.

func (*Router) Serve

func (r *Router) Serve(l net.Listener) error

Serve accepts on l until it is closed.

func (*Router) Stats

func (r *Router) Stats() Stats

type Stats

type Stats struct {
	Routed, Refused uint64
}

Stats counts connections passed to a fiber and connections closed without one.

Jump to

Keyboard shortcuts

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