infra

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Sep 27, 2026 License: Apache-2.0 Imports: 31 Imported by: 0

Documentation

Index

Constants

View Source
const (
	PriorityDirect uint8 = 100 // e.g. LAN direct connection
	PriorityICE    uint8 = 80  // P2P NAT traversal (STUN)
	PriorityRelay  uint8 = 50  // Relay relay (NATS/Server)
)

Transport priority constants

View Source
const DefaultMTU = 1280
View Source
const PublishesChangedSubject = "lattice.signals.publishes"

PublishesChangedSubject carries the full publish-rule table to any publish gateways. v1 is a flat subject: standalone deployments serve one workspace and gateways filter nothing. There is no initial fetch — gateways keep the last announced table, so they stay empty until the first mutation.

View Source
const RelayFakePort = 51820
View Source
const (
	RelayForward uint8 = 0x02 // Data forwarding
)

Relay protocol constants.

View Source
const StdNetSupportsStickySockets = false

Variables

View Source
var BindInterfaceName string

BindInterfaceName, when set, pins every WG/ICE UDP socket to that physical interface (IP_BOUND_IF). Required inside the macOS NE packet-tunnel provider, which routes its own sockets into its own tunnel otherwise. The engine sets it from the Swift side (pre-tunnel route lookup).

View Source
var ErrPathEchoLost = errors.New("path echo: no reply")

ErrPathEchoLost means no echo reply arrived in time.

Functions

func BindTCPToInterface

func BindTCPToInterface(conn *net.TCPConn, index int) error

BindTCPToInterface is a no-op off darwin.

func BindUDPToInterface

func BindUDPToInterface(conn *net.UDPConn, index int) error

BindUDPToInterface is a no-op off darwin.

func CreateTUN

func CreateTUN(mtu int, logger *log.Logger) (string, tun.Device, error)

func DefaultPhysicalInterface

func DefaultPhysicalInterface() (string, int)

DefaultPhysicalInterface is a no-op off darwin: the self-tunnel capture the darwin variant works around is an NE packet-tunnel provider behavior. index 0 means "not found / no binding needed".

func ExecCommand

func ExecCommand(name string, commands ...string) error

func GetCidrFromIP

func GetCidrFromIP(address string) string

func GetGatewayFromIP

func GetGatewayFromIP(str string) string

func ICEInterfaceAllowed

func ICEInterfaceAllowed(name string) bool

ICEInterfaceAllowed reports whether an interface may contribute ICE candidates. Virtual and tunnel interfaces are excluded: the mesh tunnel (wf0 on Linux, utunN on macOS) cannot carry its own transport, because connectivity checks sent to a mesh address are routed back into WireGuard and die there.

func IDFromPublicKey

func IDFromPublicKey(pubKey string) ([32]byte, error)

func IsRelayFakeAddr

func IsRelayFakeAddr(addr netip.Addr) bool

IsRelayFakeAddr reports whether addr was generated by RelayFakeAddrPort.

func ListenUDP

func ListenUDP(net string, uport uint16) (*net.UDPConn, int, error)

func NetmapChangedSubject

func NetmapChangedSubject(appID string) string

NetmapChangedSubject returns the NATS subject an agent with the given AppID subscribes to for "your netmap changed, refresh now" notifications. Deliberately a different subject than the per-peer ICE-signal channel (lattice.signals.peers.<appID>) so this never collides with signal.SignalPacket parsing on that channel.

func NormalizeAppID

func NormalizeAppID(id string) string

NormalizeAppID collapses a client-supplied AppID into a NATS-safe token. Device names arrive with spaces ("MacBook Pro", "iPhone 15 Pro Max"), which would produce illegal subjects like lattice.signals.peers.MacBook Pro.netmap and silently break per-peer push. Apply identically on the client (before register) and the server (at registration) so both sides derive the same subject for the same device.

func PublishNetmapChanged

func PublishNetmapChanged(ctx context.Context, signal SignalService, appID string) error

PublishNetmapChanged notifies appID's agent that something in its netmap changed, so it should refresh sooner than its next poll/liveness cycle. The payload content doesn't matter today (the agent just re-fetches the full netmap on receipt) — a fixed "changed" body keeps this forward compatible if a reason ever needs to go in it later. A nil signal (e.g. a peerService instance constructed without one, see internal/server/service/token.go) is a silent no-op, not an error.

func RelayFakeAddrPort

func RelayFakeAddrPort(remoteId uint64) netip.AddrPort

RelayFakeAddrPort encodes a Relay RemoteId as a fake IPv6 AddrPort. The resulting address looks like fd6c:7270:0000:0:<hi>:<hi>:<lo>:<lo> and is safe to pass to wg show / UAPI because it parses as a valid IP:port.

func RemoteIdFromRelayFakeAddr

func RemoteIdFromRelayFakeAddr(addr netip.Addr) uint64

RemoteIdFromRelayFakeAddr extracts the RemoteId encoded in a fake Relay address.

func TrimCIDR

func TrimCIDR(addr string) string

Types

type BindConfig

type BindConfig struct {
	Logger       *log.Logger
	V4Conn       *net.UDPConn
	V6Conn       *net.UDPConn
	PassThrough  <-chan PassThroughPacket // non-STUN v4 packets from FilteringUDPMux
	PassThrough6 <-chan PassThroughPacket // non-STUN v6 packets from FilteringUDPMux (v6)
	RelayClient  RelayChannel
	KeyManager   KeyManager
}

type ChanPacketConn

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

ChanPacketConn is a channel-backed net.PacketConn.

It is given to UDPMuxDefault (and UniversalUDPMuxDefault) instead of the real UDP socket. The mux's internal connWorker goroutine blocks on ReadFrom, which returns only when FilteringUDPMux.readLoop calls inject() after classifying an incoming packet as STUN. This makes FilteringUDPMux the sole reader of the real socket, eliminating the race between the mux's connWorker and WireGuard's makeReceiveIPv4.

WriteTo is proxied to the real socket so that the mux can send STUN binding responses/requests to the remote peer.

func (*ChanPacketConn) Close

func (c *ChanPacketConn) Close() error

Close signals ReadFrom to return net.ErrClosed, allowing the mux's connWorker to exit cleanly.

func (*ChanPacketConn) LocalAddr

func (c *ChanPacketConn) LocalAddr() net.Addr

func (*ChanPacketConn) ReadFrom

func (c *ChanPacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error)

ReadFrom blocks until a STUN packet is injected or the conn is closed. Called exclusively by the mux's internal connWorker goroutine.

func (*ChanPacketConn) SetDeadline

func (c *ChanPacketConn) SetDeadline(_ time.Time) error

func (*ChanPacketConn) SetReadDeadline

func (c *ChanPacketConn) SetReadDeadline(_ time.Time) error

func (*ChanPacketConn) SetWriteDeadline

func (c *ChanPacketConn) SetWriteDeadline(_ time.Time) error

func (*ChanPacketConn) WriteTo

func (c *ChanPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error)

WriteTo proxies to the real socket so ICE can send STUN responses/requests.

type Config

type Config struct {
	DrpHttpListen string `json:"drp_http_listen"`
}

type ConnectionState

type ConnectionState int
const (
	ConnectionStateNew ConnectionState = iota
	ConnectionStateChecking
	ConnectionStateFailed
	ConnectionStateConnected
	ConnectionStateDisconnected
)

func (ConnectionState) String

func (c ConnectionState) String() string

type ContextKey

type ContextKey int
const (
	UserIDKey ContextKey = iota
	WorkspaceKey
	StrictTenantKey
	SystemRoleKey
	UsernameKey
)

type DefaultBind

type DefaultBind struct {
	PublicKey wgtypes.Key
	// contains filtered or unexported fields
}

DefaultBind implements Bind for all platforms. While Windows has its own Bind (see bind_windows.go), it may fall back to DefaultBind. TODO: RemoveProbe usage of ipv{4,6}.PacketConn when net.UDPConn has comparable methods for sending and receiving multiple datagrams per-syscall. See the proposal in https://github.com/golang/go/issues/45886#issuecomment-1218301564.

func NewBind

func NewBind(cfg *BindConfig) *DefaultBind

func (*DefaultBind) BatchSize

func (b *DefaultBind) BatchSize() int

TODO: When all Binds handle IdealBatchSize, remove this dynamic function and rename the IdealBatchSize constant to BatchSize.

func (*DefaultBind) Close

func (b *DefaultBind) Close() error

func (*DefaultBind) GetPackectConn4

func (b *DefaultBind) GetPackectConn4() net.PacketConn

func (*DefaultBind) GetPackectConn6

func (b *DefaultBind) GetPackectConn6() net.PacketConn

func (*DefaultBind) Open

func (b *DefaultBind) Open(uport uint16) ([]conn.ReceiveFunc, uint16, error)

Open registers ReceiveFunc handlers for WireGuard.

IPv4 receive: reads from passThroughCh, populated by FilteringUDPMux.readLoop (the sole reader of the v4 socket). STUN packets are routed to ICE; all others arrive here. IPv6 receive: reads from passThrough6Ch, populated by a separate FilteringUDPMux.readLoop for v6conn. When ICE over IPv6 is enabled, STUN packets on v6conn are also routed to the ICE mux, and WireGuard packets arrive here via the channel — eliminating the same race that existed on v4.

func (*DefaultBind) ParseEndpoint

func (b *DefaultBind) ParseEndpoint(s string) (conn.Endpoint, error)

func (*DefaultBind) Send

func (b *DefaultBind) Send(bufs [][]byte, endpoint conn.Endpoint) error

func (*DefaultBind) SetMark

func (b *DefaultBind) SetMark(mark uint32) error

type DetailsInfo

type DetailsInfo struct {
	// Node info changes
	AddressChanged  bool `json:"addressChanged,omitempty"`  // IP address change
	KeyChanged      bool `json:"keyChanged,omitempty"`      // key change
	EndpointChanged bool `json:"endpointChanged,omitempty"` // remote endpoint change

	// Network topology changes
	PeersAdded   []*Peer  `json:"peersAdded,omitempty"`   // list of added peers
	PeersRemoved []*Peer  `json:"peersRemoved,omitempty"` // list of removed peers
	PeersUpdated []string `json:"peersUpdated,omitempty"` // list of updated peers

	// Policy changes
	PoliciesAdded   []*Policy `json:"policiesAdded,omitempty"`
	PoliciesRemoved []*Policy `json:"policiesRemoved,omitempty"`
	PoliciesUpdated []*Policy `json:"policiesUpdated,omitempty"`

	// Network config changes
	NetworkJoined        []string `json:"networkJoined,omitempty"`
	NetworkLeft          []string `json:"networkLeft,omitempty"`
	NetworkConfigChanged bool     `json:"networkConfigChanged,omitempty"`

	Reason       []*Entry `json:"reason,omitempty"`       // change reason description
	TotalChanges int      `json:"totalChanges,omitempty"` // total change count
}

func (*DetailsInfo) HasChanges

func (c *DetailsInfo) HasChanges() bool

func (*DetailsInfo) String

func (c *DetailsInfo) String() string

func (*DetailsInfo) Summary

func (c *DetailsInfo) Summary() string

Summary returns a summary of the changes

type DeviceConf

type DeviceConf struct {
	DrpUrl string        `json:"drpUrl,omitempty"` // a drp server user created.
	Device *DeviceConfig `json:"device,omitempty"`
	Nodes  []*Peer       `json:"list,omitempty"`
}

DeviceConf will used to fetchPeers,then config to the device

func (*DeviceConf) Parse

func (d *DeviceConf) Parse(str string) (*DeviceConf, error)

Parse will generate a DeviceConf from a "wg8" get format

func (*DeviceConf) String

func (d *DeviceConf) String() string

String will generate "wg8" get format

type DeviceConfig

type DeviceConfig struct {
	PrivateKey   string `json:"privateKey,omitempty"`
	Address      string `json:"address,omitempty"`
	Fwmark       int    `json:"fwmark,omitempty"`
	ListenPort   int    `json:"listenPort,omitempty"`
	ReplacePeers bool   `json:"replacePeers,omitempty"`
}

DeviceConfig config for this device

func (*DeviceConfig) String

func (d *DeviceConfig) String() string

type Dialer

type Dialer interface {
	// Prepare prepares to send offer to remoteId.
	Prepare(ctx context.Context, remoteId PeerIdentity) error

	// Handle handles incoming signal packets from remoteId.
	Handle(ctx context.Context, remoteId PeerIdentity, packet *signal.SignalPacket) error

	// Dial dials remoteId when offer is received.
	Dial(ctx context.Context) (Transport, error)

	// Close tears down the dialer and releases all resources.
	Close() error

	// Type returns the dialer type.
	Type() DialerType
}

type DialerType

type DialerType string
const (
	ICE_DIALER   DialerType = "ICE_DIALER"
	Relay_DIALER DialerType = "Relay_DIALER"
)

type Entry

type Entry struct {
	Type    string `json:"type"`
	Action  string `json:"action"`
	Message string `json:"message"`
}

type EventType

type EventType int
const (
	EventTypeJoinNetwork EventType = iota
	EventTypeLeaveNetwork
	EventTypeNodeUpdate
	EventTypeNodeAdd
	EventTypeNodeRemove
	EventTypeIPChange
	EventTypeKeyChanged
	EventTypeNetworkChanged
	EventTypePolicyChanged
	EventTypeNone
)

func (EventType) String

func (e EventType) String() string

type FilteringUDPMux

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

FilteringUDPMux wraps UniversalUDPMuxDefault and becomes the sole reader of the shared UDP socket. It classifies every incoming packet:

  • STUN packet → injected into ChanPacketConn → mux's connWorker dispatches it to the correct ICE muxedConn by ufrag.
  • Non-STUN packet → sent to passThroughCh → WireGuard's DefaultBind reads it.

This eliminates the race between UDPMuxDefault.connWorker and WireGuard's makeReceiveIPv4, which previously both read the same socket.

func NewFilteringMux

func NewFilteringMux(conn net.PacketConn, showLog bool) *FilteringUDPMux

NewFilteringMux creates a FilteringUDPMux that wraps conn as the sole UDP reader. When showLog is true the ICE subsystem logs at DEBUG level. Call SetPassThrough then Start on the returned mux before creating ICE agents.

func NewFilteringUDPMux

func NewFilteringUDPMux(realConn net.PacketConn, logger logging.LeveledLogger) *FilteringUDPMux

NewFilteringUDPMux constructs the wrapper. realConn is the shared UDP socket. logger may be nil (ICE log disabled). Call SetPassThrough then Start before creating any ICE agents.

func (*FilteringUDPMux) Close

func (f *FilteringUDPMux) Close() error

Close stops the readLoop, drains the mux, and shuts down chanConn.

func (*FilteringUDPMux) DroppedCount

func (f *FilteringUDPMux) DroppedCount() uint64

DroppedCount returns the number of pass-through packets dropped due to a full channel. Useful for monitoring NAT overload conditions.

func (*FilteringUDPMux) Ping

func (f *FilteringUDPMux) Ping(ctx context.Context, addr *net.UDPAddr, timeout time.Duration) (time.Duration, error)

Ping sends an echo request to addr over the shared socket and waits for the reply, returning the round-trip time. It fails when no reply arrives within timeout or ctx ends. A reply proves the path works both ways, which is what a WireGuard endpoint alone cannot show.

func (*FilteringUDPMux) SetPassThrough

func (f *FilteringUDPMux) SetPassThrough(ch chan<- PassThroughPacket)

SetPassThrough registers the channel that receives non-STUN (WireGuard) packets. Must be called before Start.

func (*FilteringUDPMux) Start

func (f *FilteringUDPMux) Start()

Start launches the sole-reader goroutine. Must be called after SetPassThrough and before any ICE agent is created.

func (*FilteringUDPMux) UDPMux

func (f *FilteringUDPMux) UDPMux() ice.UDPMux

UDPMux returns the UDPMux interface for ice.WithUDPMux (host candidates). Listen addresses of interfaces rejected by ICEInterfaceAllowed are hidden.

func (*FilteringUDPMux) UDPMuxSrflx

func (f *FilteringUDPMux) UDPMuxSrflx() ice.UniversalUDPMux

UDPMuxSrflx returns the UniversalUDPMux interface for ice.WithUDPMuxSrflx (server-reflexive candidates), with the same address filtering as UDPMux.

type FirewallRule

type FirewallRule struct {
	Platform   string        `json:"platform"`
	PolicyName string        `json:"policyName"`
	Ingress    []TrafficRule `json:"ingress,omitempty"`
	Egress     []TrafficRule `json:"egress,omitempty"`
}

type FlowController

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

type KeyManager

type KeyManager interface {
	// UpdateKey updates the private key used for encryption.
	UpdateKey(privateKey wgtypes.Key)
	// GetKey retrieves the current private key.
	GetKey() wgtypes.Key
	// GetPublicKey retrieves the public key derived from the current private key.
	GetPublicKey() wgtypes.Key
}

KeyManager manage the device keys

func NewKeyManager

func NewKeyManager(privateKey wgtypes.Key) KeyManager

type ManagementClient

type ManagementClient interface {
	GetNetMap(token string) (*Message, error)
	Register(ctx context.Context, token, interfaceName, publicKey string) (*Peer, error)
	AddPeer(p *Peer) error
}

type Message

type Message struct {
	EventType     EventType         `json:"eventType"`               // main event type
	ConfigVersion string            `json:"configVersion"`           // version number
	Timestamp     int64             `json:"timestamp"`               // timestamp
	Changes       *DetailsInfo      `json:"changes"`                 // config change details
	Current       *Peer             `json:"peer"`                    // current node info
	Network       *Network          `json:"network"`                 // current node network info
	Policies      []*Policy         `json:"policies,omitempty"`      // current node's policies
	ComputedPeers []*Peer           `json:"computedpeers,omitempty"` // peers to connect to, computed by controller and returned to lattice
	ComputedRules *FirewallRule     `json:"computedrules,omitempty"`
	Labels        map[string]string `json:"labels,omitempty"`
}

Message is the message which is sent to connected peers

func NewMessage

func NewMessage() *Message

func (*Message) Equal

func (m *Message) Equal(b *Message) bool

func (*Message) FullConfig

func (m *Message) FullConfig() string

FullConfig returns the full configuration

func (*Message) String

func (m *Message) String() string

func (*Message) WithEventType

func (m *Message) WithEventType(eventType EventType) *Message

func (*Message) WithNetwork

func (m *Message) WithNetwork(network *Network) *Message

func (*Message) WithNode

func (m *Message) WithNode(node *Peer) *Message

func (*Message) WithPolicies

func (m *Message) WithPolicies(policies []*Policy) *Message

type Network

type Network struct {
	Address     string   `json:"address"`
	AllowedIps  []string `json:"allowedIps"`
	Port        int      `json:"port"`
	NetworkId   string   `json:"NetworkId"`
	NetworkName string   `json:"networkName"`
	Peers       []*Peer  `json:"peers"`
}

Network is the network information, contains all peers/policies in the network

type NodeInterface

type NodeInterface interface {
	// Start the engine
	Start(ctx context.Context) error

	GetDeviceName() string

	// Stop the engine
	Stop() error

	// AddPeer adds a peer to the WireGuard device, add peer from contrl client, then will start connect to peer
	AddPeer(peer *Peer) error

	// RemovePeer removes a peer from the WireGuard device
	RemovePeer(peer *Peer) error

	RemoveAllPeers()

	// PrunePeersExcept removes every known peer whose AppID is not in keep
	// (peers that dropped out of the current netmap must not linger in the
	// manager/wg — stale entries kept probing and polluting peer states).
	PrunePeersExcept(keep map[string]struct{})
}

NodeInterface is the interface for managing WireGuard devices.

type PassThroughPacket

type PassThroughPacket struct {
	Data []byte
	Addr *net.UDPAddr
}

PassThroughPacket carries a non-STUN UDP packet forwarded from FilteringUDPMux to WireGuard's receive path.

type Peer

type Peer struct {
	Name                string            `json:"name,omitempty"`
	InterfaceName       string            `json:"interfaceName,omitempty"`
	Platform            string            `json:"platform,omitempty"`
	Description         string            `json:"description,omitempty"`
	NetworkId           string            `json:"NetworkId,omitempty"` // belong to which group
	CreatedBy           string            `json:"createdBy,omitempty"` // ownerID
	UserId              uint64            `json:"userId,omitempty"`
	Hostname            string            `json:"hostname,omitempty"`
	AppID               string            `json:"appId,omitempty"`
	Address             *string           `json:"address,omitempty"`
	Endpoint            string            `json:"endpoint,omitempty"`
	Remove              bool              `json:"remove,omitempty"` // whether to remove node
	PresharedKey        string            `json:"presharedKey,omitempty"`
	PersistentKeepalive int               `json:"persistentKeepalive,omitempty"`
	PrivateKey          string            `json:"privateKey,omitempty"`
	PublicKey           string            `json:"publicKey,omitempty"`
	PeerID              uint64            `json:"peerId,omitempty"`
	AllowedIPs          string            `json:"allowedIps,omitempty"`
	ReplacePeers        bool              `json:"replacePeers,omitempty"` // whether to replace all peers when updating this node
	Port                int               `json:"port"`
	GroupName           string            `json:"groupName"`
	Version             uint64            `json:"version"`
	LastUpdatedAt       string            `json:"lastUpdatedAt"`
	Token               string            `json:"token,omitempty"`
	RelayURL            string            `json:"lrpUrl,omitempty"`         // wire name kept as lrpUrl for old-server compatibility
	EnforcerMode        string            `json:"enforcerMode,omitempty"`   // user personal setting from registration
	Tier                string            `json:"tier,omitempty"`           // account tier from registration: community or pro
	ApprovalStatus      string            `json:"approvalStatus,omitempty"` // pending / approved / revoked (ADR-0003)
	Labels              map[string]string `json:"labels,omitempty"`
	// AdvertisedRoutes is this peer's own route advertisement (exit-node /
	// subnet-gateway role). The server fills it on every netmap entry so the
	// owning agent can install the corresponding forwarding rules.
	AdvertisedRoutes []string `json:"advertisedRoutes,omitempty"`
}

Peer is the information of a lattice peer, contains all the information of a peer

func (*Peer) String

func (p *Peer) String() string

type PeerID

type PeerID [8]byte

PeerID is a compact 8-byte identifier derived from the first 8 bytes of a WireGuard public key. It is used only for NATS subject routing and wire-protocol sender IDs.

func FromKey

func FromKey(key wgtypes.Key) PeerID

func FromUint64

func FromUint64(id uint64) PeerID

func (PeerID) String

func (id PeerID) String() string

func (PeerID) ToUint64

func (p PeerID) ToUint64() uint64

type PeerIdentity

type PeerIdentity struct {
	AppID     string
	PublicKey wgtypes.Key
}

PeerIdentity unifies the logical identity (AppID) and cryptographic identity (WireGuard public key). The management layer looks up by AppID, the transport layer configures WireGuard by PublicKey, and the two layers convert via this struct.

func NewPeerIdentity

func NewPeerIdentity(appId string, pubKey wgtypes.Key) PeerIdentity

func (PeerIdentity) ID

func (p PeerIdentity) ID() PeerID

ID returns the compact PeerID used for NATS routing.

func (PeerIdentity) String

func (p PeerIdentity) String() string

String returns a string consistent with PeerID, used for NATS subject construction.

type PeerManager

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

PeerManager stores peer metadata indexed by AppID (primary) and PeerID (secondary). Both indexes are maintained in sync for O(1) lookup from either key.

func NewPeerManager

func NewPeerManager() *PeerManager

func (*PeerManager) AddPeer

func (p *PeerManager) AddPeer(appId string, peer *Peer)

AddPeer stores a peer under its AppID (primary index) and WireGuard public key (secondary index). If the incoming peer carries key material (private key or preshared key), a copy with it cleared is stored instead: peers held by this manager are serialized into signaling payloads sent to remote peers (SYN/ACK PeerInfo, OFFER Current via json.Marshal), so any key material stored here would be broadcast on the wire. The caller's own struct is never mutated — the local node legitimately holds its private key there; it just must not live in the shared, serialized cache.

func (*PeerManager) GetAll

func (p *PeerManager) GetAll() []*Peer

GetAll returns a snapshot of all known peers.

func (*PeerManager) GetByPeerID

func (p *PeerManager) GetByPeerID(peerID PeerID) *Peer

GetByPeerID looks up a peer by WireGuard-derived PeerID. O(1).

func (*PeerManager) GetIdentity

func (p *PeerManager) GetIdentity(peerID PeerID) (PeerIdentity, bool)

GetIdentity resolves a PeerID to a full PeerIdentity. Used at the NATS boundary where only PeerID is available from the packet.

func (*PeerManager) GetPeer

func (p *PeerManager) GetPeer(appId string) *Peer

func (*PeerManager) RemovePeer

func (p *PeerManager) RemovePeer(appId string)

type Policy

type Policy struct {
	PolicyName string  `json:"policyName"`
	Action     string  `json:"action,omitempty"` // "ALLOW" or "DENY"
	Ingress    []*Rule `json:"ingress"`
	Egress     []*Rule `json:"egress"`
}

type Probe

type Probe interface {
	Start(ctx context.Context, remoteId PeerIdentity) error

	Handle(ctx context.Context, remoteId PeerIdentity, packet *signal.SignalPacket) error

	// 2. Health check: periodically send probe packets after the connection is established
	Ping(ctx context.Context) error
}

Probe manages the connection lifecycle to a single remote peer. Both Handle and Start receive the full PeerIdentity so implementations can access the AppID for PeerManager lookups and PublicKey for WireGuard config.

type RelayChannel

type RelayChannel interface {
	ReceiveFunc() conn.ReceiveFunc
	Send(ctx context.Context, remoteId uint64, relayType uint8, data []byte) error
	Connect() error
	// Connected reports whether a relay session is currently up, so callers can
	// decide whether relaying a signaling packet is worth trying.
	Connected() bool
	RemoteAddr() net.Addr
	Close() error
}

type RelayEndpoint

type RelayEndpoint struct {
	// Physical layer info (for standard UDP/ICE)
	Addr netip.AddrPort

	// Protocol layer info (for Relay)
	RemoteId uint64

	// Flag: which path to use currently
	TransportType TransportType
}

1. Define a minimal custom Endpoint

func (*RelayEndpoint) Clear

func (e *RelayEndpoint) Clear()

func (*RelayEndpoint) ClearSrc

func (e *RelayEndpoint) ClearSrc()

func (*RelayEndpoint) DstIP

func (e *RelayEndpoint) DstIP() netip.Addr

func (*RelayEndpoint) DstToBytes

func (e *RelayEndpoint) DstToBytes() []byte

func (*RelayEndpoint) DstToString

func (e *RelayEndpoint) DstToString() string

func (*RelayEndpoint) SrcIP

func (e *RelayEndpoint) SrcIP() netip.Addr

func (*RelayEndpoint) SrcToString

func (e *RelayEndpoint) SrcToString() string

type Rule

type Rule struct {
	PeerNames    []string `json:"peerNames"`
	CIDRs        []string `json:"cidrs,omitempty"`        // from IPBlock
	IdentityRefs []string `json:"identityRefs,omitempty"` // from PeerIdentity
	Protocol     string   `json:"protocol"`
	Port         int      `json:"port"`
	Action       string   `json:"action,omitempty"` // "ALLOW" or "DENY"
}

type SignalService

type SignalService interface {
	// Send routes a packet to the peer identified by PeerID (NATS subject level).
	// PeerID is sufficient here — full PeerIdentity is not needed for routing.
	Send(ctx context.Context, peerId PeerID, data []byte) error

	// Publish sends a raw payload to an arbitrary subject, for control-plane-
	// initiated notifications that don't fit the peer-to-peer Send() pattern
	// (e.g. "your netmap changed, refresh now").
	Publish(ctx context.Context, subject string, data []byte) error

	//req/resp
	Request(ctx context.Context, subject, method string, data []byte) ([]byte, error)

	// server service
	Service(subject, queue string, service func(data []byte) ([]byte, error))

	Flush() error

	// Close drains in-flight messages and closes the underlying connection.
	Close() error
}

SignalService only used for sending signal byte packet

type Status

type Status string
const (
	Active   Status = "Active"
	Inactive Status = "Inactive"
)

type TrafficRule

type TrafficRule struct {
	ChainName string   `json:"chainName"`
	Peers     []string `json:"peers,omitempty"` // ip list
	Protocol  string   `json:"protocol,omitempty"`
	Port      int      `json:"port,omitempty"`
	Action    string   `json:"action,omitempty"` // Accept or drop
}

type Transport

type Transport interface {
	Write(data []byte) error
	Read(buff []byte) (int, error)
	RemoteAddr() string
	Type() TransportType
	Close() error
	Priority() uint8
}

Transport using from read/write data from/to wire

type TransportType

type TransportType int
const (
	ICE TransportType = iota
	Relay
)

func (TransportType) String

func (t TransportType) String() string

Jump to

Keyboard shortcuts

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