Documentation
¶
Index ¶
- Constants
- Variables
- func BindTCPToInterface(conn *net.TCPConn, index int) error
- func BindUDPToInterface(conn *net.UDPConn, index int) error
- func CreateTUN(mtu int, logger *log.Logger) (string, tun.Device, error)
- func DefaultPhysicalInterface() (string, int)
- func ExecCommand(name string, commands ...string) error
- func GetCidrFromIP(address string) string
- func GetGatewayFromIP(str string) string
- func ICEInterfaceAllowed(name string) bool
- func IDFromPublicKey(pubKey string) ([32]byte, error)
- func IsRelayFakeAddr(addr netip.Addr) bool
- func ListenUDP(net string, uport uint16) (*net.UDPConn, int, error)
- func NetmapChangedSubject(appID string) string
- func NormalizeAppID(id string) string
- func PublishNetmapChanged(ctx context.Context, signal SignalService, appID string) error
- func RelayFakeAddrPort(remoteId uint64) netip.AddrPort
- func RemoteIdFromRelayFakeAddr(addr netip.Addr) uint64
- func TrimCIDR(addr string) string
- type BindConfig
- type ChanPacketConn
- func (c *ChanPacketConn) Close() error
- func (c *ChanPacketConn) LocalAddr() net.Addr
- func (c *ChanPacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error)
- func (c *ChanPacketConn) SetDeadline(_ time.Time) error
- func (c *ChanPacketConn) SetReadDeadline(_ time.Time) error
- func (c *ChanPacketConn) SetWriteDeadline(_ time.Time) error
- func (c *ChanPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error)
- type Config
- type ConnectionState
- type ContextKey
- type DefaultBind
- func (b *DefaultBind) BatchSize() int
- func (b *DefaultBind) Close() error
- func (b *DefaultBind) GetPackectConn4() net.PacketConn
- func (b *DefaultBind) GetPackectConn6() net.PacketConn
- func (b *DefaultBind) Open(uport uint16) ([]conn.ReceiveFunc, uint16, error)
- func (b *DefaultBind) ParseEndpoint(s string) (conn.Endpoint, error)
- func (b *DefaultBind) Send(bufs [][]byte, endpoint conn.Endpoint) error
- func (b *DefaultBind) SetMark(mark uint32) error
- type DetailsInfo
- type DeviceConf
- type DeviceConfig
- type Dialer
- type DialerType
- type Entry
- type EventType
- type FilteringUDPMux
- func (f *FilteringUDPMux) Close() error
- func (f *FilteringUDPMux) DroppedCount() uint64
- func (f *FilteringUDPMux) Ping(ctx context.Context, addr *net.UDPAddr, timeout time.Duration) (time.Duration, error)
- func (f *FilteringUDPMux) SetPassThrough(ch chan<- PassThroughPacket)
- func (f *FilteringUDPMux) Start()
- func (f *FilteringUDPMux) UDPMux() ice.UDPMux
- func (f *FilteringUDPMux) UDPMuxSrflx() ice.UniversalUDPMux
- type FirewallRule
- type FlowController
- type KeyManager
- type ManagementClient
- type Message
- func (m *Message) Equal(b *Message) bool
- func (m *Message) FullConfig() string
- func (m *Message) String() string
- func (m *Message) WithEventType(eventType EventType) *Message
- func (m *Message) WithNetwork(network *Network) *Message
- func (m *Message) WithNode(node *Peer) *Message
- func (m *Message) WithPolicies(policies []*Policy) *Message
- type Network
- type NodeInterface
- type PassThroughPacket
- type Peer
- type PeerID
- type PeerIdentity
- type PeerManager
- func (p *PeerManager) AddPeer(appId string, peer *Peer)
- func (p *PeerManager) GetAll() []*Peer
- func (p *PeerManager) GetByPeerID(peerID PeerID) *Peer
- func (p *PeerManager) GetIdentity(peerID PeerID) (PeerIdentity, bool)
- func (p *PeerManager) GetPeer(appId string) *Peer
- func (p *PeerManager) RemovePeer(appId string)
- type Policy
- type Probe
- type RelayChannel
- type RelayEndpoint
- type Rule
- type SignalService
- type Status
- type TrafficRule
- type Transport
- type TransportType
Constants ¶
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
const DefaultMTU = 1280
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.
const RelayFakePort = 51820
const (
RelayForward uint8 = 0x02 // Data forwarding
)
Relay protocol constants.
const StdNetSupportsStickySockets = false
Variables ¶
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).
var ErrPathEchoLost = errors.New("path echo: no reply")
ErrPathEchoLost means no echo reply arrived in time.
Functions ¶
func BindTCPToInterface ¶
BindTCPToInterface is a no-op off darwin.
func BindUDPToInterface ¶
BindUDPToInterface is a no-op off darwin.
func DefaultPhysicalInterface ¶
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 GetCidrFromIP ¶
func GetGatewayFromIP ¶
func ICEInterfaceAllowed ¶
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 IsRelayFakeAddr ¶
IsRelayFakeAddr reports whether addr was generated by RelayFakeAddrPort.
func NetmapChangedSubject ¶
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 ¶
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 ¶
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 ¶
RemoteIdFromRelayFakeAddr extracts the RemoteId encoded in a fake Relay address.
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 ¶
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
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 ¶
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) 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 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 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) FullConfig ¶
FullConfig returns the full configuration
func (*Message) WithEventType ¶
func (*Message) WithNetwork ¶
func (*Message) WithPolicies ¶
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 ¶
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
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
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 FromUint64 ¶
type PeerIdentity ¶
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 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 TrafficRule ¶
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