socket

package
v0.0.0-...-055f8da Latest Latest
Warning

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

Go to latest
Published: Jul 20, 2023 License: Apache-2.0, MIT Imports: 16 Imported by: 1

Documentation

Overview

Package socket implements signed sockets for bootstrap services.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrIgnore causes a message to be dropped silently.
	// It is typically used when filtering out messgaes that
	// originate from the local host.
	ErrIgnore = errors.New("ignore")

	// ErrClosed is returned when performing operations against
	// a closed socket.
	ErrClosed = errors.New("closed")
)
View Source
var EnvelopePayloadType = []byte{0x1f, 0x00}

TODO: register this once stable. https://github.com/multiformats/multicodec/blob/master/table.csv

View Source
var ErrNoListenAddrs = errors.New("no listen addrs")

ErrNoListenAddrs is returned if the host has not exported any listen addresses.

Functions

This section is empty.

Types

type Host

type Host interface {
	ID() peer.ID
	Addrs() []ma.Multiaddr
}

type Option

type Option func(*Socket)

func WithCache

func WithCache(cache *RecordCache) Option

WithCache sets the socket's record cache. If cache == nil, a default cache with 8 slots is used.

func WithErrHandler

func WithErrHandler(h func(*Socket, error)) Option

WithErrHandler sets the socket's error callback. If h == nil, a default error handler is used, which logs errors using the socket's logger.

func WithLogger

func WithLogger(l log.Logger) Option

WithLogger sets the logger instance. If l == nil, a default logger is used.

func WithRateLimiter

func WithRateLimiter(lim *RateLimiter) Option

WithRateLimiter sets the socket's rate-limiter. If lim == nil, a nop limiter is used.

func WithValidator

func WithValidator(v RecordValidator) Option

WithValidator sets the socket's record validator. If v == nil, a default validator is used.

type ProtocolError

type ProtocolError struct {
	Message string
	Cause   error
	Meta    log.F
}

ProtocolError signals a non-fatal error caused either either by a malformed *record.Envelope, or by a *Record containing unexpected values.

The default error callback will log a protocol error at the DEBUG level, using 'Message' as the logging message and the 'Meta' field as a set of structured logging fields. If the 'Cause' field is non-nil, it will be added to 'Meta' before writing the log message.

User-supplied error handlers SHOULD test for ProtocolError via type-assertion and treat any instances as a non-fatal error.

func (ProtocolError) Error

func (pe ProtocolError) Error() string

func (ProtocolError) Is

func (pe ProtocolError) Is(err error) bool

func (ProtocolError) Loggable

func (pe ProtocolError) Loggable() map[string]interface{}

func (ProtocolError) Unwrap

func (pe ProtocolError) Unwrap() error

type RateLimiter

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

RateLimiter provides flow-control for a Socket.

func NewBandwidthLimiter

func NewBandwidthLimiter(r rate.Limit, burst int) *RateLimiter

NewBandwidthLimiter enforces limits over the network bandwidth used by a socket.

NOTE: limit and burst are expressed in *bits* per second and *bits*,

respectively.  Do not confuse this with bytes.

func NewPacketLimiter

func NewPacketLimiter(r rate.Limit, burst int) *RateLimiter

NewPacketLimiter enforces limits over the number of packets sent by a socket. Units are packets/sec and packets, respectively.

func NewRateLimiter

func NewRateLimiter(r rate.Limit, burst int, f func(int) int) *RateLimiter

func (*RateLimiter) Reserve

func (r *RateLimiter) Reserve(ctx context.Context, n int) (err error)

Reserve a slot for an outgoing message of size n bytes.

type Record

type Record boot.Packet

func (Record) Codec

func (r Record) Codec() []byte

Codec is a binary identifier for this type of record, ideally a registered multicodec (see https://github.com/multiformats/multicodec). When a Record is put into an Envelope (see record.Seal), the Codec value will be used as the Envelope's PayloadType. When the Envelope is later unsealed, the PayloadType will be used to lookup the correct Record type to unmarshal the Envelope payload into.

func (Record) Domain

func (r Record) Domain() string

Domain is the "signature domain" used when signing and verifying a particular Record type. The Domain string should be unique to your Record type, and all instances of the Record type must have the same Domain string.

func (Record) MarshalRecord

func (r Record) MarshalRecord() ([]byte, error)

MarshalRecord converts a Record instance to a []byte, so that it can be used as an Envelope payload.

func (Record) Namespace

func (r Record) Namespace() (string, error)

func (Record) Peer

func (r Record) Peer() (id peer.ID, err error)

func (Record) Type

func (r Record) Type() RecordType

func (*Record) UnmarshalRecord

func (r *Record) UnmarshalRecord(b []byte) error

UnmarshalRecord unmarshals a []byte payload into an instance of a particular Record type.

type RecordCache

type RecordCache lru.TwoQueueCache[key, *record.Envelope]

RecordCache is a thread-safe, fixed-size cache that tracks both least-frequently-used and most-recently-accessed records. It is used to amortize the cost of signing discovery packets.

func NewCache

func NewCache(size int) *RecordCache

NewCache creates a new RecordCache with the given size. The cache uses twin queues algorithm that tracks both recently-added entries and recently-evicted ("ghost") entries, in order to reduce churn.

The cache MUST have a maximum size of at least 2. If size < 2, a default size of 8 is used.

func (*RecordCache) LoadRequest

func (c *RecordCache) LoadRequest(seal Sealer, id peer.ID, ns string) (*record.Envelope, error)

LoadRequest searches the cache for a signed request packet for ns and returns it, if found. Else, it creates and signs a new packet and adds it to the cache.

func (*RecordCache) LoadResponse

func (c *RecordCache) LoadResponse(seal Sealer, h Host, ns string) (*record.Envelope, error)

LoadResponse searches the cache for a signed response packet for ns and returns it, if found. Else, it creates and signs a new response packet and adds it to the cache.

func (*RecordCache) LoadSurveyRequest

func (c *RecordCache) LoadSurveyRequest(seal Sealer, id peer.ID, ns string, dist uint8) (*record.Envelope, error)

LoadSurveyRequest searches the cache for a signed survey packet with distance 'dist', and returns it if found. Else, it creates and signs a new survey-request packet and adds it to the cache.

func (*RecordCache) Reset

func (c *RecordCache) Reset()

Reset invalidates previous entries.

type RecordType

type RecordType = boot.Packet_Which
const (
	EnvelopeDomain = "casm-boot-record"

	TypeRequest  RecordType = boot.Packet_Which_request
	TypeSurvey   RecordType = boot.Packet_Which_survey
	TypeResponse RecordType = boot.Packet_Which_response
)

type RecordValidator

type RecordValidator func(*record.Envelope, *Record) error

func BasicValidator

func BasicValidator(self peer.ID) RecordValidator

type Request

type Request struct {
	Record
	NS   string
	From net.Addr
}

func (Request) Distance

func (r Request) Distance() (dist uint8)

func (Request) IsSurvey

func (r Request) IsSurvey() bool

func (Request) Loggable

func (r Request) Loggable() map[string]interface{}

type RequestHandler

type RequestHandler func(Request) error

type Response

type Response struct {
	Record
	NS   string
	From net.Addr
}

func (Response) Addrs

func (r Response) Addrs() ([]ma.Multiaddr, error)

func (Response) Bind

func (r Response) Bind(info *peer.AddrInfo) (err error)

func (Response) Loggable

func (r Response) Loggable() map[string]interface{}

type Sealer

type Sealer func(record.Record) (*record.Envelope, error)

Sealer is a higher-order function capable of sealing a record for a specific peer. It prevents the cache from having to manage private keys.

type Socket

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

Socket is a a packet-oriented network interface that exchanges signed messages.

func New

func New(conn net.PacketConn, opt ...Option) *Socket

New socket. The wrapped PacketConn implementation MUST flush its send buffer in a timely manner. It must also provide unreliable delivery semantics; if the underlying transport is reliable, it MUST suppress any errors due to failed connections or delivery. The standard net.PacketConn implementations satisfy these condiitions

func (*Socket) Bind

func (s *Socket) Bind(h RequestHandler)

Bind the handler to the socket and begin servicing incoming requests. Bind MUST NOT be called more than once.

func (*Socket) Close

func (s *Socket) Close() (err error)

func (*Socket) Done

func (s *Socket) Done() <-chan struct{}

func (*Socket) Log

func (s *Socket) Log() log.Logger

func (*Socket) Send

func (s *Socket) Send(ctx context.Context, e *record.Envelope, addr net.Addr) error

func (*Socket) SendRequest

func (s *Socket) SendRequest(ctx context.Context, seal Sealer, addr net.Addr, id peer.ID, ns string) error

func (*Socket) SendResponse

func (s *Socket) SendResponse(seal Sealer, h Host, to net.Addr, ns string) error

func (*Socket) SendSurveyRequest

func (s *Socket) SendSurveyRequest(ctx context.Context, seal Sealer, id peer.ID, ns string, dist uint8) error

func (*Socket) SendSurveyResponse

func (s *Socket) SendSurveyResponse(seal Sealer, h Host, ns string) error

func (*Socket) Subscribe

func (s *Socket) Subscribe(ns string, limit int) (<-chan peer.AddrInfo, func())

func (*Socket) Track

func (s *Socket) Track(ns string, ttl time.Duration) (err error)

type ValidationError

type ValidationError struct {
	Cause error
	From  net.Addr
}

ValidationError signals that a packet contains the expected data, but that its authenticity and provenance could not be proven.

The default error callback will log validation errors at the DEBUG level. In high-security environments, it MAY be adviseable to log such events at the WARN level, and to take further action.

func (ValidationError) Error

func (ve ValidationError) Error() string

func (ValidationError) Is

func (ve ValidationError) Is(err error) bool

func (ValidationError) Loggable

func (ve ValidationError) Loggable() map[string]interface{}

func (ValidationError) Unwrap

func (ve ValidationError) Unwrap() error

Jump to

Keyboard shortcuts

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