control

package
v0.0.0-...-4449afe Latest Latest
Warning

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

Go to latest
Published: Apr 14, 2025 License: MIT Imports: 19 Imported by: 0

Documentation

Overview

Package control pertains to all code related to contacting, serving, and talking to control.

This package contains (relatively) transport-agnostic code, for the specific http implementation, see controlhttp.

Index

Constants

View Source
const HandshakeReceiveTimeout = time.Second * 10
View Source
const (
	UpgradeProtocol = "toversok-control"
)

Variables

View Source
var (
	ErrSessionDoesNotExist        = errors.New("session does not exist")
	ErrSessionIsNotAuthenticating = errors.New("session is not authenticating")
	ErrNeedsDisconnect            = errors.New("session needs disconnect")
	ErrClientNotConnected         = errors.New("client is not connected")
)
View Source
var ErrClosed = errors.New("client closed")
View Source
var ErrLogonRejected = errors.New("authentication resulted in logon rejected")
View Source
var ErrNeedsLogon = errors.New("needs logon callback")

Functions

This section is empty.

Types

type AcceptAuth

type AcceptAuth struct{}

type AuthURL

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

type Client

type Client struct {
	ControlKey key.ControlPublic

	SessionID *string

	IPv4 netip.Prefix
	IPv6 netip.Prefix

	Expiry time.Time
	// contains filtered or unexported fields
}

func EstablishClient

func EstablishClient(parentCtx context.Context, mc types.MetaConn, brw *bufio.ReadWriter, timeout time.Duration, getPriv func() *key.NodePrivate, getSess func() *key.SessionPrivate, controlKey key.ControlPublic, session *string, logon types.LogonCallback) (*Client, error)

func (*Client) Cancel

func (c *Client) Cancel(err error)

func (*Client) Close

func (c *Client) Close()

func (*Client) Handshake

func (c *Client) Handshake(timeout time.Duration, logon types.LogonCallback) error

func (*Client) Recv

func (c *Client) Recv(ttfbTimeout time.Duration) (msgcontrol.ControlMessage, error)

Recv blocks until it receives a package, it will return (nil, nil) if timeout

func (*Client) Send

func (c *Client) Send(msg msgcontrol.ControlMessage) error

type ClientID

type ClientID key.NodePublic

type Conn

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

func NewConn

func NewConn(ctx context.Context, mc types.MetaConn, brw *bufio.ReadWriter) *Conn

func (*Conn) Expect

func (c *Conn) Expect(to msgcontrol.ControlMessage, ttfbTimeout time.Duration) error

func (*Conn) Read

func (c *Conn) Read(ttfbTimeout time.Duration) (msgcontrol.ControlMessage, error)

Read returns nil, nil if the timeout is reached

func (*Conn) ReadRaw

func (c *Conn) ReadRaw(ttfbTimeout time.Duration) (msgcontrol.ControlMessageType, []byte, error)

func (*Conn) UnmarshalInto

func (c *Conn) UnmarshalInto(data []byte, to msgcontrol.ControlMessage) error

func (*Conn) Write

func (c *Conn) Write(obj msgcontrol.ControlMessage) error

type EdgeGraph

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

func NewEdgeGraph

func NewEdgeGraph() *EdgeGraph

func (*EdgeGraph) GetEdge

func (g *EdgeGraph) GetEdge(from, to ClientID) (retPair *VisibilityPair)

func (*EdgeGraph) GetEdges

func (g *EdgeGraph) GetEdges(node ClientID) map[ClientID]VisibilityPair

GetEdges gets all edges connected to node.

func (*EdgeGraph) RemoveEdge

func (g *EdgeGraph) RemoveEdge(from, to ClientID) error

func (*EdgeGraph) RemoveNode

func (g *EdgeGraph) RemoveNode(node ClientID) error

func (*EdgeGraph) UpsertEdge

func (g *EdgeGraph) UpsertEdge(from, to ClientID, pair *VisibilityPair) error

type PairOperation

type PairOperation struct {
	// Session IDs
	A, B string

	AN, BN key.NodePublic

	// If nil, then its Bye
	*VisibilityPair
}

type PeerDelta

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

func (PeerDelta) Merge

func (p PeerDelta) Merge(o PeerDelta) PeerDelta

type RejectAuth

type RejectAuth struct {
	*msgcontrol.LogonReject
}

type Server

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

func NewServer

func NewServer(privKey key.ControlPrivate, relays []relay.Information) *Server

func (*Server) Accept

func (s *Server) Accept(ctx context.Context, mc types.MetaConn, brw *bufio.ReadWriter, _ netip.AddrPort) error

func (*Server) AcceptAuthentication

func (s *Server) AcceptAuthentication(id SessID) error

func (*Server) DisconnectClient

func (s *Server) DisconnectClient(id ClientID) error

func (*Server) DisconnectSession

func (s *Server) DisconnectSession(id SessID) error

func (*Server) ForVisible

func (s *Server) ForVisible(fromSess *ServerSession, f func(session *ServerSession))

ForVisible is called by fromSess' Run goroutine, to inform all other sessions it can see of a change (and the likes)

func (*Server) GetClientID

func (s *Server) GetClientID(id SessID) (ClientID, error)

func (*Server) GetConnectedClients

func (s *Server) GetConnectedClients() (map[SessID]ClientID, error)

func (*Server) GetVisibilityPairs

func (s *Server) GetVisibilityPairs(id ClientID) (map[ClientID]VisibilityPair, error)

func (*Server) Logger

func (s *Server) Logger() *slog.Logger

func (*Server) ReEstablishOrMakeSession

func (s *Server) ReEstablishOrMakeSession(cc *Conn, nodeKey key.NodePublic, sessKey key.SessionPublic, sessID *string) (retSess *ServerSession, resumed bool, err error)

func (*Server) RegisterCallbacks

func (s *Server) RegisterCallbacks(cb ServerCallbacks)

func (*Server) RejectAuthentication

func (s *Server) RejectAuthentication(id SessID, reason string) error

func (*Server) RemoveSession

func (s *Server) RemoveSession(sess *ServerSession)

func (*Server) RemoveVisibilityPair

func (s *Server) RemoveVisibilityPair(from, to ClientID) error

func (*Server) Run

func (s *Server) Run()

func (*Server) RunAdditionalSTUN

func (s *Server) RunAdditionalSTUN(publicIPs []netip.Addr, listenHost string, lowPort, highPort uint16) error

func (*Server) SendAuthURL

func (s *Server) SendAuthURL(id SessID, url string) error

func (*Server) UpsertMultiVisibilityPair

func (s *Server) UpsertMultiVisibilityPair(id ClientID, m map[ClientID]VisibilityPair) error

func (*Server) UpsertVisibilityPair

func (s *Server) UpsertVisibilityPair(id, id2 ClientID, pair VisibilityPair) error

type ServerCallbacks

type ServerCallbacks interface {
	// OnSessionCreate is called when a new session is created.
	// Indicates a pending authentication state, which will hang unless resolved;
	// Call ServerLogic.AcceptAuthentication or ServerLogic.RejectAuthentication to end this state.
	OnSessionCreate(SessID, ClientID)
	// OnSessionResume is called when a session is resumed.
	OnSessionResume(SessID, ClientID)

	// OnDeviceKey is called when a device key has been received.
	// Will only happen when session is pending authentication.
	OnDeviceKey(id SessID, key string)

	// OnSessionFinalize is called right after ServerLogic.AcceptAuthentication, but before that message is sent to the client.
	// The client needs to known which virtual IPs it can use, and the expiry time of the authentication,
	// and this function will provide it to the control server.
	OnSessionFinalize(SessID, ClientID) (netip.Prefix, netip.Prefix, time.Time)

	// OnSessionDestroy is called after the client has been disconnected.
	OnSessionDestroy(SessID, ClientID)
}

ServerCallbacks denotes all the functions the corresponding business logic to the control server must implement, to notify the business logic of certain changes and events. See ServerLogic.RegisterCallbacks.

Calling back into any ServerLogic function while being called back is safe. TODO double-check above statement

type ServerLogic

type ServerLogic interface {
	// RegisterCallbacks with custom business logic
	RegisterCallbacks(ServerCallbacks)

	// GetClientID will get the client ID corresponding to a particular session ID.
	// Will error if session does not exist.
	GetClientID(SessID) (ClientID, error)

	// GetConnectedClients returns all connected session and their client IDs.
	GetConnectedClients() (map[SessID]ClientID, error)

	// SendAuthURL will send the authentication URL to the indicated session ID.
	// Must only be called once, will error on a second time.
	// Will error if the session is not pending authentication.
	SendAuthURL(id SessID, url string) error
	// AcceptAuthentication will accept the pending authentication of the indicated session ID.
	// Must be called, or RejectAuthentication must be called.
	// Second time argument dictates for how long the
	// Will error if the session is not pending authentication.
	AcceptAuthentication(SessID) error
	// RejectAuthentication will reject the pending authentication of the indicated session ID.
	// Must be called, or AcceptAuthentication must be called.
	// Will error if the session is not pending authentication.
	RejectAuthentication(id SessID, reason string) error

	// DisconnectSession will disconnect a running client session (and invalidate its ID), if it exists.
	// Will error if session does not exist.
	DisconnectSession(id SessID) error
	// DisconnectClient will disconnect a running session per client (and invalidate its ID), if its connected.
	// Will error if client is not connected.
	DisconnectClient(id ClientID) error

	// GetVisibilityPairs gets all pairs of a particular ClientID.
	// Will error if client ID does not have any pairs, or if client ID is unknown.
	GetVisibilityPairs(ClientID) (map[ClientID]VisibilityPair, error)
	// UpsertVisibilityPair will insert or update a VisibilityPair for a pair of clients.
	UpsertVisibilityPair(ClientID, ClientID, VisibilityPair) error
	// UpsertMultiVisibilityPair will insert or update multiple VisibilityPair's for pairs of clients.
	UpsertMultiVisibilityPair(ClientID, map[ClientID]VisibilityPair) error
	// RemoveVisibilityPair will delete a VisibilityPair between clients.
	// Idempotent, will not error if no pair exists.
	RemoveVisibilityPair(ClientID, ClientID) error
}

ServerLogic denotes exposed functions that a control server must provide for any business logic to interface with it.

type ServerSession

type ServerSession struct {
	ID   string
	Peer key.NodePublic
	Sess key.SessionPublic

	IPv4 netip.Prefix
	IPv6 netip.Prefix

	HomeRelay int64

	CurrentEndpoints []netip.AddrPort

	Ctx context.Context
	Ccc context.CancelCauseFunc

	Expiry time.Time
	// contains filtered or unexported fields
}

func NewSession

func NewSession(cc *Conn, nodeKey key.NodePublic, sessKey key.SessionPublic, server *Server) *ServerSession

func (*ServerSession) AuthAndStart

func (s *ServerSession) AuthAndStart() error

func (*ServerSession) AuthenticateAccept

func (s *ServerSession) AuthenticateAccept() (err error)

func (*ServerSession) Bye

func (s *ServerSession) Bye(peer key.NodePublic)

Bye to another session, send PeerRemove

func (*ServerSession) Greet

func (s *ServerSession) Greet(otherSess *ServerSession, prop msgcontrol.Properties)

Greet another session, send PeerAddition

func (*ServerSession) Greeted

func (s *ServerSession) Greeted(sess key.SessionPublic) bool

func (*ServerSession) Knock

func (s *ServerSession) Knock() (dangling bool)

Knock asks the session goroutine/connection to "knock" (send ping, await pong) the session, to make sure it is still alive.

Will return true if the session is now transitioned to dangling.

func (*ServerSession) Resume

func (s *ServerSession) Resume(_ *Conn, _ key.SessionPublic)

func (*ServerSession) Run

func (s *ServerSession) Run()

func (*ServerSession) SendRelays

func (s *ServerSession) SendRelays() error

SendRelays sends all relay information to the client. This is not ran on Resume.

func (*ServerSession) Slog

func (s *ServerSession) Slog() *slog.Logger

func (*ServerSession) UpdateEndpoints

func (s *ServerSession) UpdateEndpoints(peer key.NodePublic, endpoints []netip.AddrPort)

func (*ServerSession) UpdateHomeRelay

func (s *ServerSession) UpdateHomeRelay(peer key.NodePublic, homeRelay int64)

func (*ServerSession) UpdateProperties

func (s *ServerSession) UpdateProperties(peer key.NodePublic, prop msgcontrol.Properties)

func (*ServerSession) UpdateSessKey

func (s *ServerSession) UpdateSessKey(peer key.NodePublic, sessKey key.SessionPublic)

type ServerSessionState

type ServerSessionState byte
const (
	Authenticate ServerSessionState = iota
	Greet
	Established
	Dangling
	ReEstablishing
	Deconstructing
)

type SessID

type SessID string

type VisibilityPair

type VisibilityPair struct {
	// One of the two ClientID's, or nil
	// Will quarantine all incoming connections FROM the referenced ClientID
	Quarantine *ClientID

	MDNS bool
}

func (*VisibilityPair) PropertiesFor

func (vp *VisibilityPair) PropertiesFor(peer key.NodePublic) msgcontrol.Properties

Directories

Path Synopsis
Package controlhttp pertains to implementing control interfaces in a HTTP client/dialer and server handler.
Package controlhttp pertains to implementing control interfaces in a HTTP client/dialer and server handler.

Jump to

Keyboard shortcuts

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