Go SDK
Package sdk provides the core P2P networking library for Shurli.
This package is the primary SDK surface for Go consumers. External code should depend on the interfaces defined here (PeerNetwork, Resolver, ServiceManager, Authorizer) rather than concrete types where possible.
import "github.com/shurlinet/shurli/pkg/sdk"Architecture
The package is organized around these concepts:
Network: creates and manages a libp2p host with relay, NAT traversal, DHT discovery, and resource limits. Entry point:
New().Services: the plugin system. TCP proxy services (
ExposeService) forward streams to local ports. Plugin services (RegisterHandler) process streams directly. All services are managed throughServiceRegistry.Plugin Policies: transport-aware access control for plugins. By default, all plugins only operate over LAN and Direct connections. Relay transport is excluded unless explicitly allowed per-plugin. See
PluginPolicyandDefaultPluginPolicy.Events: the
EventBusdispatches connection, service, and authorization events to registered handlers.Naming: the
NameResolvermaps human-readable names to peer IDs, with support for fallback resolver chains.Standalone:
NewStandaloneHostandStandaloneResult.ResolveAndConnectprovide a consolidated path for one-shot CLI commands that operate without a running daemon.Bootstrap:
BootstrapAndConnecthandles DHT client-mode bootstrap, peer discovery, and relay circuit fallback.Protocol IDs:
ProtocolIDandMustValidateProtocolIDsenforce valid protocol ID construction at init time.
Relay Separation
Relay server protocols (pairing, admin, MOTD, unseal) live in internal/relay and register directly on the libp2p host. They are architecturally separate from the plugin system in this package. Plugins are peer-to-peer only.
Thread Safety
All exported types are safe for concurrent use. The Network, ServiceRegistry, EventBus, NameResolver, and TransferService use internal locking.
QUIC Transport Performance
Shurli uses QUIC (RFC 9000) over UDP for all peer-to-peer data transport. QUIC performance varies across operating systems due to differences in kernel UDP handling, buffer defaults, and hardware offload support.
See QUIC-TRANSPORT.md for the full reference, including:
- macOS UDP GSO limitation: macOS lacks Generic Segmentation Offload for UDP, causing ~17-27% lower LAN send throughput vs TCP. Measured, profiled, and documented with root cause analysis.
- Linux UDP buffer tuning: default kernel limits are too small for high-throughput QUIC. Configuration guide included.
- macOS Local Network Privacy: silent LAN connection blocking after binary replacement.
- Elimination matrix: every hypothesis tested and the evidence for/against.
Constants
const DHTProtocolPrefix = "/shurli"
const ProtocolPrefix = "/shurli"
const PresenceProtocol = "/shurli/presence/1.0.0"
const RTTProbeProtocol = "/shurli/rtt-probe/1.0.0"Transport Types
const (
TransportLAN TransportType = 1 << iota // private/link-local IP
TransportDirect // public internet, non-relay
TransportRelay // mediated through relay (p2p-circuit)
)
const DefaultTransport = TransportLAN | TransportDirect
const MaxHedgeFanOut = 3DefaultTransport permits LAN and Direct connections. MaxHedgeFanOut caps the number of concurrent hedged stream attempts. Relay is excluded. This is the default for ALL plugins: no data flows through relays unless explicitly allowed per-plugin.
Event Types
const (
EventPeerConnected EventType = iota + 1
EventPeerDisconnected
EventServiceRegistered
EventServiceRemoved
EventStreamOpened
EventStreamClosed
EventAuthAllow
EventAuthDeny
EventTransferPending
)NAT Types
type NATType string
const (
NATNone NATType = "none"
NATFullCone NATType = "full-cone"
NATAddressRestricted NATType = "address-restricted"
NATPortRestricted NATType = "port-restricted"
NATSymmetric NATType = "symmetric"
NATUnknown NATType = "unknown"
)Path Types
type PathType string
const (
PathDirect PathType = "DIRECT"
PathRelayed PathType = "RELAYED"
)Variables
var ErrServiceAlreadyRegistered = errors.New("service already registered")
var ErrServiceNotFound = errors.New("service not found")
var ErrNameNotFound = errors.New("name not found")
var ErrResponseTooLarge = errors.New("response too large")Core Interfaces
type PeerNetwork
type PeerNetwork interface {
PeerID() peer.ID
ExposeService(name, localAddress string, allowedPeers map[peer.ID]struct{}) error
UnexposeService(name string) error
ListServices() []*Service
ConnectToService(peerID peer.ID, serviceName string) (ServiceConn, error)
ConnectToServiceContext(ctx context.Context, peerID peer.ID, serviceName string) (ServiceConn, error)
ResolveName(name string) (peer.ID, error)
RegisterName(name string, peerID peer.ID) error
OnEvent(handler EventHandler) func()
Close() error
}PeerNetwork is the top-level interface for interacting with a Shurli P2P network. Create a concrete *Network with sdk.New().
type Resolver
type Resolver interface {
Resolve(name string) (peer.ID, error)
}Resolver maps human-readable names to peer IDs. Supports chaining: local config, DNS, DHT, custom backends.
type ServiceManager
type ServiceManager interface {
RegisterService(svc *Service) error
UnregisterService(name string) error
GetService(name string) (*Service, bool)
ListServices() []*Service
DialService(ctx context.Context, peerID peer.ID, protocolID string) (ServiceConn, error)
Use(middleware ...StreamMiddleware)
}ServiceManager manages service registration, discovery, and dialing. Supports stream middleware for cross-cutting concerns.
type Authorizer
type Authorizer interface {
IsAuthorized(p peer.ID) bool
}Authorizer makes authorization decisions about peers. Default implementation uses Shurli’s authorized_keys file.
type ServiceConn
type ServiceConn interface {
io.ReadWriteCloser
CloseWrite() error
}ServiceConn is a connection to a remote service. Supports half-close for HTTP-style request/response patterns.
type RelayGrantChecker
type RelayGrantChecker interface {
GrantStatus(relayID peer.ID) (remaining time.Duration, budget int64, sessionDuration time.Duration, ok bool)
HasSufficientBudget(relayID peer.ID, fileSize int64, direction string) bool
TrackCircuitBytes(relayID peer.ID, direction string, n int64)
ResetCircuitCounters(relayID peer.ID)
}RelayGrantChecker provides relay grant information for transfer budget/time checks. Used by the file transfer plugin to verify relay data grants before initiating transfers.
type RelaySource
type RelaySource interface {
RelayAddrs() []string
}RelaySource provides relay addresses for dial racing.
type HalfCloseConn
type HalfCloseConn interface {
io.ReadWriteCloser
CloseWrite() error
}HalfCloseConn is a connection supporting half-close. Used by the proxy subsystem for bidirectional copy.
Type Aliases
type StreamMiddleware func(next network.StreamHandler) network.StreamHandler
type StreamHandler func(serviceName string, s network.Stream)
type EventHandler func(Event)
type EventType int
type TransportType int
type GrantChecker func(peerID peer.ID, service string, transport TransportType) bool
type TokenVerifier func(tokenBase64 string, peerID peer.ID, service string, transport TransportType) bool
type TokenLookup func(peerID peer.ID, service string) string
type ConnectionRecorder func(peerID peer.ID)
type PeerFilter func(peer.ID) bool
type NodeStateProvider func() *NodeAnnouncementNetwork
type Config
type Config struct {
KeyFile string
KeyPassword string
AuthorizedKeys string
Gater *auth.AuthorizedPeerGater
Config *config.Config
UserAgent string
EnableRelay bool
RelayAddrs []string
ForcePrivate bool
EnableNATPortMap bool
EnableHolePunching bool
Namespace string
Resolver Resolver
ResourceLimitsEnabled bool
Metrics *Metrics
BandwidthTracker *BandwidthTracker
}Config holds configuration for creating a new P2P network.
type Network
type Network struct {
// contains unexported fields
}Network is the core P2P host. Implements PeerNetwork. Created with New().
func New
func New(cfg *Config) (*Network, error)New creates a new P2P network instance with the given configuration.
func (*Network) PeerID
func (n *Network) PeerID() peer.IDPeerID returns this node’s peer ID.
func (*Network) Host
func (n *Network) Host() host.HostHost returns the underlying libp2p host.
func (*Network) ExposeService
func (n *Network) ExposeService(name, localAddress string, allowedPeers map[peer.ID]struct{}) errorExposeService exposes a local TCP service over the P2P network.
func (*Network) UnexposeService
func (n *Network) UnexposeService(name string) errorUnexposeService removes a previously exposed service.
func (*Network) ListServices
func (n *Network) ListServices() []*ServiceListServices returns all registered services.
func (*Network) ConnectToService
func (n *Network) ConnectToService(peerID peer.ID, serviceName string) (ServiceConn, error)ConnectToService connects to a remote peer’s exposed service.
func (*Network) ConnectToServiceContext
func (n *Network) ConnectToServiceContext(ctx context.Context, peerID peer.ID, serviceName string) (ServiceConn, error)ConnectToServiceContext connects with a cancellable context.
func (*Network) ResolveName
func (n *Network) ResolveName(name string) (peer.ID, error)ResolveName resolves a human-readable name to a peer ID.
func (*Network) RegisterName
func (n *Network) RegisterName(name string, peerID peer.ID) errorRegisterName registers a name-to-peer-ID mapping.
func (*Network) LoadNames
func (n *Network) LoadNames(names map[string]string) errorLoadNames loads peer name mappings from a string map.
func (*Network) OnEvent
func (n *Network) OnEvent(handler EventHandler) func()OnEvent subscribes to network events. Returns an unsubscribe function.
func (*Network) AddRelayAddressesForPeer
func (n *Network) AddRelayAddressesForPeer(relayAddrs []string, target peer.ID) errorAddRelayAddressesForPeer adds relay circuit addresses for a target peer.
func (*Network) ResetBlackHoles
func (n *Network) ResetBlackHoles()ResetBlackHoles resets the libp2p black hole detectors for both IPv4 and IPv6 UDP, allowing immediate retry after a network change.
func (*Network) ClearDialBackoffs
func (n *Network) ClearDialBackoffs(peers []peer.ID)ClearDialBackoffs clears the swarm’s dial backoff for the given peers, enabling immediate reconnection.
func (*Network) GetPathProtector
func (n *Network) GetPathProtector() *PathProtectorGetPathProtector returns the path protector, if set.
func (*Network) SetPathProtector
func (n *Network) SetPathProtector(pp *PathProtector)SetPathProtector sets the path protector for managed relay connections.
func (*Network) GetLANRegistry
func (n *Network) GetLANRegistry() *LANRegistryGetLANRegistry returns the mDNS-verified LAN registry.
func (*Network) ServiceRegistry
func (n *Network) ServiceRegistry() *ServiceRegistryServiceRegistry returns the network’s service registry.
func (*Network) RegisterHandler
func (n *Network) RegisterHandler(name string, handler StreamHandler, allowedPeers map[peer.ID]struct{}) errorRegisterHandler registers a P2P stream handler for a named service. Uses default plugin policy (LAN + Direct, no relay).
func (*Network) RegisterHandlerRelayAllowed
func (n *Network) RegisterHandlerRelayAllowed(name string, handler StreamHandler, allowedPeers map[peer.ID]struct{}) errorRegisterHandlerRelayAllowed registers a handler that also accepts relay connections.
func (*Network) RegisterServiceQuery
func (n *Network) RegisterServiceQuery() errorRegisterServiceQuery registers the service-query protocol handler for remote service discovery.
func (*Network) OpenPluginStream
func (n *Network) OpenPluginStream(ctx context.Context, peerID peer.ID, serviceName string) (network.Stream, error)OpenPluginStream opens a stream to a remote peer for a plugin service. Applies transport policy and grant verification.
func (*Network) OpenPluginStreamOnConn
func (n *Network) OpenPluginStreamOnConn(ctx context.Context, peerID peer.ID, serviceName string, conn network.Conn) (network.Stream, error)OpenPluginStreamOnConn opens a plugin stream on a specific connection. Used by hedged open to target a particular path.
func (*Network) ReplaceNames
func (n *Network) ReplaceNames(names map[string]string) errorReplaceNames replaces all name mappings atomically.
func (*Network) ListNames
func (n *Network) ListNames() map[string]peer.IDListNames returns all registered name-to-peer-ID mappings.
func (*Network) Events
func (n *Network) Events() *EventBusEvents returns the network’s event bus.
func (*Network) Close
func (n *Network) Close() errorClose shuts down the network and releases resources.
func ParseRelayAddrs
func ParseRelayAddrs(relayAddrs []string) ([]peer.AddrInfo, error)ParseRelayAddrs parses multiaddr relay addresses into AddrInfo. Standalone function, not a Network method.
func DHTProtocolPrefixForNamespace
func DHTProtocolPrefixForNamespace(namespace string) stringDHTProtocolPrefixForNamespace returns DHT protocol prefix for a private namespace.
func HumanizeError
func HumanizeError(err string) stringHumanizeError translates libp2p stream errors into user-friendly messages.
func ValidateServiceName
func ValidateServiceName(name string) errorValidateServiceName checks that a service name is safe for use in protocol IDs.
Service Registry
type Service
type Service struct {
Name string
Protocol string
LocalAddress string
Handler StreamHandler
Enabled bool
AllowedPeers map[peer.ID]struct{}
Policy *PluginPolicy
}Service represents a service exposed over P2P.
type ServiceRegistry
type ServiceRegistry struct {
// contains unexported fields
}ServiceRegistry manages service registration, stream routing, and connection dialing.
func NewServiceRegistry
func NewServiceRegistry(h host.Host, metrics *Metrics) *ServiceRegistryfunc (*ServiceRegistry) RegisterService
func (r *ServiceRegistry) RegisterService(svc *Service) errorfunc (*ServiceRegistry) UnregisterService
func (r *ServiceRegistry) UnregisterService(name string) errorfunc (*ServiceRegistry) GetService
func (r *ServiceRegistry) GetService(name string) (*Service, bool)func (*ServiceRegistry) ListServices
func (r *ServiceRegistry) ListServices() []*Servicefunc (*ServiceRegistry) DialService
func (r *ServiceRegistry) DialService(ctx context.Context, peerID peer.ID, protocolID string) (ServiceConn, error)func (*ServiceRegistry) Seal
func (r *ServiceRegistry) Seal()Seal prevents further service registration. Called after daemon startup.
func (*ServiceRegistry) SetGrantChecker
func (r *ServiceRegistry) SetGrantChecker(checker GrantChecker)func (*ServiceRegistry) SetTokenVerifier
func (r *ServiceRegistry) SetTokenVerifier(v TokenVerifier)func (*ServiceRegistry) SetTokenLookup
func (r *ServiceRegistry) SetTokenLookup(l TokenLookup)func (*ServiceRegistry) SetLANRegistry
func (r *ServiceRegistry) SetLANRegistry(lanReg *LANRegistry)SetLANRegistry sets the LAN registry for mDNS-verified transport classification in stream handlers.
func (*ServiceRegistry) SetRelayGrantChecker
func (r *ServiceRegistry) SetRelayGrantChecker(checker RelayGrantChecker)SetRelayGrantChecker sets the relay grant checker for verifying data access grants on relay streams.
func (*ServiceRegistry) Use
func (r *ServiceRegistry) Use(middleware ...StreamMiddleware)Use adds stream middleware. Middleware wraps every stream handler in the order added (first added = outermost wrapper).
Events
type Event
type Event struct {
Type EventType
PeerID peer.ID
ServiceName string
Detail string
}type EventBus
type EventBus struct {
// contains unexported fields
}func NewEventBus
func NewEventBus() *EventBusfunc (*EventBus) Subscribe
func (b *EventBus) Subscribe(handler EventHandler) func()Subscribe registers an event handler. Returns an unsubscribe function.
func (*EventBus) Emit
func (b *EventBus) Emit(e Event)Emit dispatches event to all registered handlers.
Name Resolution
type NameResolver
type NameResolver struct {
// contains unexported fields
}func NewNameResolver
func NewNameResolver() *NameResolverfunc (*NameResolver) Register
func (r *NameResolver) Register(name string, peerID peer.ID) errorfunc (*NameResolver) Unregister
func (r *NameResolver) Unregister(name string)func (*NameResolver) Resolve
func (r *NameResolver) Resolve(name string) (peer.ID, error)func (*NameResolver) List
func (r *NameResolver) List() map[string]peer.IDfunc (*NameResolver) LoadFromMap
func (r *NameResolver) LoadFromMap(names map[string]string) errorLoadFromMap adds name mappings from string map (additive).
func (*NameResolver) ReplaceFromMap
func (r *NameResolver) ReplaceFromMap(names map[string]string) errorReplaceFromMap replaces all name mappings with the given map.
Byte Size Utilities
func ParseByteSize
func ParseByteSize(s string) (int64, error)ParseByteSize parses a human-readable byte size string (e.g., “500MB”, “1GB”, “unlimited”).
func FormatBytes
func FormatBytes(b int64) stringFormatBytes formats a byte count for user-facing display (e.g. “1.2 GB”, “500 MB”).
Cryptographic Utilities
func Blake3Sum
func Blake3Sum(data []byte) [32]byteBlake3Sum computes the BLAKE3-256 hash of data.
func MerkleRoot
func MerkleRoot(hashes [][32]byte) [32]byteMerkleRoot computes the BLAKE3 Merkle root hash from a list of chunk hashes. Leaf nodes are chunk hashes (already BLAKE3). Internal nodes are BLAKE3(left || right). Odd nodes are promoted unchanged. Single hash is returned as-is. Empty list returns zero hash.
Relay Utilities
func RelayPeerFromAddr
func RelayPeerFromAddr(addr ma.Multiaddr) peer.IDRelayPeerFromAddr extracts the relay peer ID from a circuit relay multiaddr. Returns empty peer.ID if the address is not a circuit relay address.
func RelayPeerFromAddrStr
func RelayPeerFromAddrStr(addrStr string) stringRelayPeerFromAddrStr extracts the relay peer ID string from a circuit relay multiaddr string. Returns empty string if the address is not a relay circuit.
func VerifiedTransport
func VerifiedTransport(s network.Stream, hasVerifiedLANConn func(peer.ID) bool) TransportTypeVerifiedTransport classifies a stream using mDNS-verified LAN detection. Use for any trust-making decision (transport policy, erasure coding, bandwidth budgets).
Precedence: Limited (relay circuit) → TransportRelay; loopback or link-local remote → TransportLAN (cannot traverse routers); hasVerifiedLANConn returns true → TransportLAN; otherwise → TransportDirect.
Unlike ClassifyTransport, routable private IPv4 addresses (RFC 1918 / RFC 6598) are NOT classified as LAN unless mDNS has verified the peer. This avoids false positives from CGNAT, Docker bridge networks, VPN tunnels, and multi-WAN routed-private cross-links - only mDNS multicast (which cannot traverse routers) proves real LAN proximity.
A nil hasVerifiedLANConn callback still classifies loopback and link-local as LAN; for routable addresses it falls back to TransportDirect (conservative).
func (*Network) HasVerifiedLANConn
func (n *Network) HasVerifiedLANConn(id peer.ID) boolNil-safe convenience wrapper over the underlying mDNS-verified LAN registry. Returns true if the peer has at least one live non-relay connection whose remote IP was confirmed via mDNS multicast. This is the authoritative “is this peer on our LAN?” check; use it as the second argument to VerifiedTransport.
Connection Groups & Hedging
type ConnGroup
type ConnGroup struct {
Type string // "DIRECT", "RELAYED", or relay peer ID
Conns []network.Conn
}ConnGroup groups a peer’s connections by transport path. Direct connections (LAN or WAN) are in one group, each relay circuit is its own group.
type HostNetwork
type HostNetwork interface {
Network() network.Network
}HostNetwork is satisfied by host.Host. Used by ConnGroups/AllConnGroups to access connection lists.
func ConnGroups
func ConnGroups(h HostNetwork, peerID peer.ID) []ConnGroupConnGroups groups all connections to a peer by transport type. Direct (non-relay) connections are grouped together; each relay circuit forms a separate group.
func AllConnGroups
func AllConnGroups(h HostNetwork, peerID peer.ID, pp *PathProtector) []ConnGroupAllConnGroups returns connection groups including managed relay connections from the PathProtector that may not appear in the host’s connection list.
func OpenStreamOnConn
func OpenStreamOnConn(ctx context.Context, conn network.Conn, proto protocol.ID) (network.Stream, error)OpenStreamOnConn opens a new stream on a specific connection using protocol negotiation. Used to target a particular network path (e.g., direct vs relay).
func HedgedOpenStream
func HedgedOpenStream(ctx context.Context, n *Network, peerID peer.ID, serviceName string) (network.Stream, error)HedgedOpenStream opens a plugin stream using hedged racing across all available connection groups. Direct groups are tried first, then relay groups with staggered starts. First success wins, losers are cancelled. Capped at MaxHedgeFanOut concurrent attempts.
Path Protection
type PathProtector
type PathProtector struct {
// contains unexported fields
}PathProtector manages protected relay connections for peers. Prevents relay circuits from being garbage-collected by keeping them alive and tracked. Supports connection reaping and deauth callbacks.
const MaxProtectedPeers = 10
const MaxManagedRelayConns = 5type ManagedPathInfo
type ManagedPathInfo struct {
PeerID peer.ID
RelayPeerID peer.ID
RemoteAddr string
Created time.Time
Streams int
Dead bool
}ManagedPathInfo describes a managed relay connection tracked by PathProtector.
LAN Registry
type LANRegistry
type LANRegistry struct {
// contains unexported fields
}LANRegistry tracks which peers have been verified as LAN-local via mDNS multicast. The authoritative source for “is this peer on our LAN?” decisions. Bare RFC 1918 matching is unreliable (CGNAT, Docker, VPN); only mDNS proves link-local proximity.
func StripNonLANAddrs
func StripNonLANAddrs(h host.Host, pid peer.ID, lanReg *LANRegistry)StripNonLANAddrs removes non-LAN addresses from the peerstore for a peer that has a verified LAN connection, preventing mDNS-discovered peers from accumulating stale public addresses.
func IsLANMultiaddr
func IsLANMultiaddr(addr ma.Multiaddr) boolIsLANMultiaddr returns true if the multiaddr points to a LAN address (private IPv4, link-local IPv6, loopback).
Grant Headers
func WriteGrantHeader
func WriteGrantHeader(s network.Stream, tokenBase64 string) errorWriteGrantHeader writes a grant token header onto a stream before the application payload. Used by relay-allowed protocols to present data access credentials.
func ReadGrantHeader
func ReadGrantHeader(s network.Stream) (string, error)ReadGrantHeader reads a grant token header from a stream. Returns the base64-encoded token string.
Plugin Transport Policy
type PluginPolicy
type PluginPolicy struct {
AllowedTransports TransportType
AllowPeers map[peer.ID]struct{}
DenyPeers map[peer.ID]struct{}
}PluginPolicy defines transport restrictions and peer access control for plugin protocols.
func DefaultPluginPolicy
func DefaultPluginPolicy() *PluginPolicyDefaultPluginPolicy returns a policy allowing LAN + Direct, no relay.
func (*PluginPolicy) RelayAllowed
func (p *PluginPolicy) RelayAllowed() boolfunc (*PluginPolicy) PeerAllowed
func (p *PluginPolicy) PeerAllowed(id peer.ID) boolfunc (*PluginPolicy) TransportAllowed
func (p *PluginPolicy) TransportAllowed(t TransportType) boolfunc ClassifyTransport
func ClassifyTransport(s network.Stream) TransportTypeClassifyTransport determines the transport type of a stream. Limited connections are classified as TransportRelay. Private/loopback/link-local IPs are TransportLAN. Everything else is TransportDirect.
Protocol IDs
func ProtocolID
func ProtocolID(name, version string) stringProtocolID constructs a validated Shurli protocol identifier: /shurli/<name>/<version>. Panics on invalid input (intended for init-time registration).
func ValidateProtocolID
func ValidateProtocolID(id string) errorValidateProtocolID checks if a protocol ID is well-formed.
func MustValidateProtocolIDs
func MustValidateProtocolIDs(ids ...string)MustValidateProtocolIDs validates a batch of protocol IDs at init time. Panics if any are malformed.
Bootstrap
type BootstrapConfig
type BootstrapConfig struct {
Namespace string
BootstrapPeers []string
RelayAddrs []string
}func BootstrapAndConnect
func BootstrapAndConnect(ctx context.Context, h host.Host, net *Network, target peer.ID, cfg BootstrapConfig) errorBootstrapAndConnect bootstraps the DHT and connects to a target peer.
Standalone Host
type StandaloneConfig
type StandaloneConfig struct {
ConfigPath string
Password string
UserAgent string
}type StandaloneResult
type StandaloneResult struct {
Network *Network
NodeConfig *config.NodeConfig
ConfigDir string
}func (*StandaloneResult) ResolveAndConnect
func (r *StandaloneResult) ResolveAndConnect(ctx context.Context, target string) (peer.ID, error)ResolveAndConnect resolves a peer name or ID and connects.
func NewStandaloneHost
func NewStandaloneHost(cfg StandaloneConfig) (*StandaloneResult, error)NewStandaloneHost creates a P2P Network from a config file. Used by CLI commands that need a network connection without running the full daemon.
Network Tools
Ping
type PingResult
type PingResult struct {
Seq int `json:"seq"`
PeerID string `json:"peer_id"`
RttMs float64 `json:"rtt_ms"`
Path string `json:"path"`
Error string `json:"error,omitempty"`
}type PingStats
type PingStats struct {
Sent int `json:"sent"`
Received int `json:"received"`
Lost int `json:"lost"`
LossPct float64 `json:"loss_pct"`
MinMs float64 `json:"min_ms"`
AvgMs float64 `json:"avg_ms"`
MaxMs float64 `json:"max_ms"`
}func PingPeer
func PingPeer(ctx context.Context, h host.Host, peerID peer.ID, protocolID string, count int, interval time.Duration) <-chan PingResultPingPeer sends pings to a peer and streams results on the returned channel.
func ComputePingStats
func ComputePingStats(results []PingResult) PingStatsTraceroute
type TraceHop
type TraceHop struct {
Hop int `json:"hop"`
PeerID string `json:"peer_id"`
Name string `json:"name,omitempty"`
Address string `json:"address"`
RttMs float64 `json:"rtt_ms"`
Error string `json:"error,omitempty"`
}type TraceResult
type TraceResult struct {
Target string `json:"target"`
TargetID string `json:"target_id"`
Path string `json:"path"`
Hops []TraceHop `json:"hops"`
}func TracePeer
func TracePeer(ctx context.Context, h host.Host, targetPeerID peer.ID) (*TraceResult, error)TracePeer traces the network path to a peer.
Peer Management
type PeerManager
type PeerManager struct {
// contains unexported fields
}PeerManager maintains connections to watched peers with exponential backoff reconnection.
func NewPeerManager
func NewPeerManager(h host.Host, pd *PathDialer, m *Metrics, onReconnect ConnectionRecorder) *PeerManagerfunc (*PeerManager) Start
func (pm *PeerManager) Start(ctx context.Context)func (*PeerManager) Close
func (pm *PeerManager) Close()func (*PeerManager) SetWatchlist
func (pm *PeerManager) SetWatchlist(peerIDs []peer.ID)func (*PeerManager) OnNetworkChange
func (pm *PeerManager) OnNetworkChange()OnNetworkChange triggers immediate reconnection attempts.
func (*PeerManager) SetPathProtector
func (pm *PeerManager) SetPathProtector(pp *PathProtector)SetPathProtector sets the path protector for managed relay connections.
func (*PeerManager) GetLANRegistry
func (pm *PeerManager) GetLANRegistry() *LANRegistryGetLANRegistry returns the PeerManager’s LAN registry.
func (*PeerManager) ResetPeerBackoff
func (pm *PeerManager) ResetPeerBackoff(pid peer.ID)ResetPeerBackoff clears the reconnection backoff for a specific peer, enabling immediate reconnection.
func (*PeerManager) CloseAllPeerConnections
func (pm *PeerManager) CloseAllPeerConnections()CloseAllPeerConnections closes all connections to all watched peers. Used on network change to force path re-evaluation.
func (*PeerManager) GetManagedPeers
func (pm *PeerManager) GetManagedPeers() []ManagedPeerInfoGetManagedPeers returns a snapshot of all watched peers and their state.
type ManagedPeerInfo
type ManagedPeerInfo struct {
PeerID string `json:"peer_id"`
Connected bool `json:"connected"`
LastSeen string `json:"last_seen"`
LastDialError string `json:"last_dial_error,omitempty"`
ConsecFailures int `json:"consec_failures"`
BackoffUntil string `json:"backoff_until,omitempty"`
}Path Dialer
type PathDialer
type PathDialer struct {
// contains unexported fields
}PathDialer connects to peers using parallel path racing across direct and relay paths.
func NewPathDialer
func NewPathDialer(h host.Host, kdht *dht.IpfsDHT, relaySource RelaySource, m *Metrics) *PathDialerfunc (*PathDialer) DialPeer
func (pd *PathDialer) DialPeer(ctx context.Context, peerID peer.ID) (*DialResult, error)type DialResult
type DialResult struct {
PathType PathType
Duration time.Duration
Address string
}func PeerConnInfo
func PeerConnInfo(h host.Host, peerID peer.ID) (pathType string, addr string)func ClassifyMultiaddr
func ClassifyMultiaddr(addr string) (pathType PathType, transport string, ipVersion string)func AddRelayAddressesForPeerFunc
func AddRelayAddressesForPeerFunc(h host.Host, relayAddrs []string, target peer.ID) errorfunc RelayServiceCID
func RelayServiceCID(namespace string) cid.CidRelayServiceCID returns the DHT content ID used for relay service advertisement in a given namespace.
Path Tracker
type PathTracker
type PathTracker struct {
// contains unexported fields
}PathTracker monitors peer connections and tracks per-peer path quality.
func NewPathTracker
func NewPathTracker(h host.Host, m *Metrics) *PathTrackerfunc (*PathTracker) Start
func (pt *PathTracker) Start(ctx context.Context)func (*PathTracker) UpdateRTT
func (pt *PathTracker) UpdateRTT(pid peer.ID, rttMs float64)func (*PathTracker) GetPeerPath
func (pt *PathTracker) GetPeerPath(pid peer.ID) (*PeerPathInfo, bool)func (*PathTracker) ListPeerPaths
func (pt *PathTracker) ListPeerPaths() []*PeerPathInfotype PeerPathInfo
type PeerPathInfo struct {
PeerID string `json:"peer_id"`
PathType PathType `json:"path_type"`
Address string `json:"address"`
ConnectedAt string `json:"connected_at"`
Transport string `json:"transport"`
IPVersion string `json:"ip_version"`
LastRTTMs float64 `json:"last_rtt_ms"`
}LAN Discovery
type MDNSDiscovery
type MDNSDiscovery struct {
// contains unexported fields
}MDNSDiscovery discovers peers on the local network via mDNS/Zeroconf.
Network Intelligence
type NetIntel
type NetIntel struct {
// contains unexported fields
}NetIntel manages the presence announcement protocol. Peers exchange presence info (NAT type, addresses, capabilities, uptime) at regular intervals.
func NewNetIntel
func NewNetIntel(h host.Host, m *Metrics, pf PeerFilter, sp NodeStateProvider, interval time.Duration) *NetIntelfunc (*NetIntel) Start
func (ni *NetIntel) Start(ctx context.Context)func (*NetIntel) Close
func (ni *NetIntel) Close()func (*NetIntel) AnnounceNow
func (ni *NetIntel) AnnounceNow()AnnounceNow triggers an immediate presence announcement to all connected peers.
func (*NetIntel) GetPeerState
func (ni *NetIntel) GetPeerState(pid peer.ID) *PeerAnnouncementfunc (*NetIntel) GetAllPeerState
func (ni *NetIntel) GetAllPeerState() []PeerAnnouncementtype NodeAnnouncement
type NodeAnnouncement struct {
Version int `json:"version"`
From string `json:"from"`
Grade string `json:"grade"`
NATType string `json:"nat_type"`
HasIPv4 bool `json:"has_ipv4"`
HasIPv6 bool `json:"has_ipv6"`
BehindCGNAT bool `json:"behind_cgnat"`
UptimeSec int64 `json:"uptime_sec"`
PeerCount int `json:"peer_count"`
Timestamp int64 `json:"timestamp"`
Hops int `json:"hops"`
AnonymousMode bool `json:"anonymous_mode"`
ZKPProof []byte `json:"zkp_proof,omitempty"`
}type PeerAnnouncement
type PeerAnnouncement struct {
PeerID peer.ID
Announcement NodeAnnouncement
ReceivedAt time.Time
}Network Monitor
type NetworkMonitor
type NetworkMonitor struct {
// contains unexported fields
}NetworkMonitor watches for OS-level network interface changes (WiFi switches, cable plug/unplug, VPN up/down).
func NewNetworkMonitor
func NewNetworkMonitor(onChange func(*NetworkChange), m *Metrics) *NetworkMonitorfunc (*NetworkMonitor) Run
func (nm *NetworkMonitor) Run(ctx context.Context)type NetworkChange
type NetworkChange struct {
Added []string
Removed []string
IPv6Changed bool
IPv4Changed bool
TunnelChanged bool
GatewayChanged bool
}Interface Discovery
type InterfaceSummary
type InterfaceSummary struct {
Interfaces []InterfaceInfo
HasGlobalIPv6 bool
HasGlobalIPv4 bool
GlobalIPv6Addrs []string
GlobalIPv4Addrs []string
TunnelInterfaces []string
DefaultGateway string
}type InterfaceInfo
type InterfaceInfo struct {
Name string
IPv4Addrs []string
IPv6Addrs []string
IsLoopback bool
}func DiscoverInterfaces
func DiscoverInterfaces() (*InterfaceSummary, error)DiscoverInterfaces enumerates all network interfaces with their addresses, detecting IPv4/IPv6 global addresses, tunnels, and the default gateway.
STUN Prober
type STUNProber
type STUNProber struct {
// contains unexported fields
}STUNProber discovers external addresses via STUN servers and classifies NAT type.
func NewSTUNProber
func NewSTUNProber(servers []string, m *Metrics) *STUNProberfunc (*STUNProber) Probe
func (sp *STUNProber) Probe(ctx context.Context) (*STUNResult, error)func (*STUNProber) Result
func (sp *STUNProber) Result() *STUNResultResult returns the most recent probe result.
type STUNResult
type STUNResult struct {
Probes []ProbeResult
NATType NATType
ExternalAddrs []string
ProbedAt time.Time
BehindCGNAT bool
CGNATNote string
}type ProbeResult
type ProbeResult struct {
ServerAddr string
ExternalAddr string
ExternalIP string
ExternalPort int
Latency time.Duration
Error string
}func (NATType) HolePunchable
func (n NATType) HolePunchable() boolHolePunchable returns true if the NAT type supports hole punching (full-cone, address-restricted, or port-restricted).
Relay Discovery
type RelayDiscovery
type RelayDiscovery struct {
// contains unexported fields
}RelayDiscovery manages static + DHT relay discovery with health-ranked ordering.
func NewRelayDiscovery
func NewRelayDiscovery(staticRelays []peer.AddrInfo, namespace string, m *Metrics) *RelayDiscoveryfunc (*RelayDiscovery) SetBudgetChecker
func (rd *RelayDiscovery) SetBudgetChecker(gc RelayGrantChecker)SetBudgetChecker sets the grant checker for budget-aware relay ranking. Relay addresses are ranked by health score + budget bonus.
type StaticRelaySource
type StaticRelaySource struct {
Addrs []string
}StaticRelaySource wraps a fixed relay address list.
func (*StaticRelaySource) RelayAddrs
func (s *StaticRelaySource) RelayAddrs() []stringRelay Health
type RelayHealth
type RelayHealth struct {
// contains unexported fields
}RelayHealth tracks relay liveness and quality using EWMA-based health scoring.
func NewRelayHealth
func NewRelayHealth(h host.Host, m *Metrics) *RelayHealthPeer Relay
type PeerRelay
type PeerRelay struct {
// contains unexported fields
}PeerRelay auto-enables relay functionality when a node has a public IP.
func NewPeerRelay
func NewPeerRelay(h host.Host, m *Metrics, cfg PeerRelayConfig) *PeerRelayProxy
type TCPListener
type TCPListener struct {
// contains unexported fields
}TCPListener is a TCP listener that forwards connections to a P2P service.
func NewTCPListener
func NewTCPListener(localAddr string, dialFunc func() (ServiceConn, error)) (*TCPListener, error)func (*TCPListener) Serve
func (l *TCPListener) Serve() errorfunc (*TCPListener) Close
func (l *TCPListener) Close() errorfunc (*TCPListener) Addr
func (l *TCPListener) Addr() net.Addrfunc (*TCPListener) ActiveConns
func (l *TCPListener) ActiveConns() intActiveConns returns the number of active proxied connections.
func (*TCPListener) GracefulClose
func (l *TCPListener) GracefulClose(timeout time.Duration)GracefulClose stops accepting new connections, waits for active connections to drain (up to timeout), then closes.
func BidirectionalProxy
func BidirectionalProxy(a, b HalfCloseConn, logPrefix string)BidirectionalProxy copies data between two connections with half-close propagation.
func InstrumentedBidirectionalProxy
func InstrumentedBidirectionalProxy(a, b HalfCloseConn, service string, metrics *Metrics)func ProxyStreamToTCP
func ProxyStreamToTCP(stream network.Stream, tcpAddr string) errorProxyStreamToTCP proxies a libp2p stream to a local TCP address.
func DialWithRetry
func DialWithRetry(dialFunc func() (ServiceConn, error), maxRetries int) func() (ServiceConn, error)DialWithRetry wraps a dial function with exponential backoff retry.
Metrics
type Metrics
type Metrics struct {
Registry *prometheus.Registry
ProxyBytesTotal *prometheus.CounterVec
ProxyConnectionsTotal *prometheus.CounterVec
ProxyActiveConns *prometheus.GaugeVec
ProxyDurationSeconds *prometheus.HistogramVec
AuthDecisionsTotal *prometheus.CounterVec
HolePunchTotal *prometheus.CounterVec
HolePunchDurationSeconds *prometheus.HistogramVec
DaemonRequestsTotal *prometheus.CounterVec
DaemonRequestDurationSeconds *prometheus.HistogramVec
PathDialTotal *prometheus.CounterVec
PathDialDurationSeconds *prometheus.HistogramVec
ConnectedPeers *prometheus.GaugeVec
NetworkChangeTotal *prometheus.CounterVec
STUNProbeTotal *prometheus.CounterVec
MDNSDiscoveredTotal *prometheus.CounterVec
PeerManagerReconnectTotal *prometheus.CounterVec
NetIntelSentTotal *prometheus.CounterVec
NetIntelReceivedTotal *prometheus.CounterVec
InterfaceCount *prometheus.GaugeVec
VaultSealed prometheus.Gauge
VaultSealOpsTotal *prometheus.CounterVec
VaultUnsealTotal *prometheus.CounterVec
VaultUnsealLockedPeers prometheus.Gauge
DepositOpsTotal *prometheus.CounterVec
DepositPending prometheus.Gauge
PairingTotal *prometheus.CounterVec
MacaroonVerifyTotal *prometheus.CounterVec
AdminRequestTotal *prometheus.CounterVec
AdminRequestDurationSeconds *prometheus.HistogramVec
ZKPProveTotal *prometheus.CounterVec
ZKPProveDurationSeconds *prometheus.HistogramVec
ZKPVerifyTotal *prometheus.CounterVec
ZKPVerifyDurationSeconds *prometheus.HistogramVec
ZKPAuthTotal *prometheus.CounterVec
ZKPTreeRebuildTotal *prometheus.CounterVec
ZKPTreeRebuildDurationSeconds *prometheus.HistogramVec
ZKPTreeLeaves prometheus.Gauge
ZKPChallengesPending prometheus.Gauge
ZKPRangeProveTotal *prometheus.CounterVec
ZKPRangeProveDuration *prometheus.HistogramVec
ZKPRangeVerifyTotal *prometheus.CounterVec
ZKPRangeVerifyDuration *prometheus.HistogramVec
ZKPAnonAnnouncementsTotal *prometheus.CounterVec
PeerBandwidthBytesTotal *prometheus.GaugeVec
PeerBandwidthRate *prometheus.GaugeVec
ProtocolBandwidthBytesTotal *prometheus.GaugeVec
BandwidthBytesTotal *prometheus.GaugeVec
RelayHealthScore *prometheus.GaugeVec
RelayProbeTotal *prometheus.CounterVec
BuildInfo *prometheus.GaugeVec
}Metrics holds all custom Shurli Prometheus metrics (50+ counters, gauges, histograms).
func NewMetrics
func NewMetrics(version, goVersion string) *MetricsAudit Logger
type AuditLogger
type AuditLogger struct {
// contains unexported fields
}AuditLogger writes structured audit events for security-relevant actions. Nil-safe: all methods are no-ops on a nil receiver.
func NewAuditLogger
func NewAuditLogger(handler slog.Handler) *AuditLoggerfunc (*AuditLogger) AuthDecision
func (a *AuditLogger) AuthDecision(peerID, direction, result string)func (*AuditLogger) ServiceACLDenied
func (a *AuditLogger) ServiceACLDenied(peerID, service string)func (*AuditLogger) DaemonAPIAccess
func (a *AuditLogger) DaemonAPIAccess(method, path string, status int)func (*AuditLogger) AuthChange
func (a *AuditLogger) AuthChange(action, peerID string)Bandwidth Tracker
type BandwidthTracker
type BandwidthTracker struct {
// contains unexported fields
}BandwidthTracker wraps libp2p’s BandwidthCounter and bridges to Prometheus metrics.
func NewBandwidthTracker
func NewBandwidthTracker(prom *Metrics) *BandwidthTrackerfunc (*BandwidthTracker) Counter
func (bt *BandwidthTracker) Counter() *metrics.BandwidthCounterCounter returns the underlying libp2p bandwidth counter for host construction.
func (*BandwidthTracker) PeerStats
func (bt *BandwidthTracker) PeerStats(p peer.ID) metrics.Statsfunc (*BandwidthTracker) AllPeerStats
func (bt *BandwidthTracker) AllPeerStats() map[peer.ID]metrics.Statsfunc (*BandwidthTracker) ProtocolStats
func (bt *BandwidthTracker) ProtocolStats(proto protocol.ID) metrics.Statsfunc (*BandwidthTracker) Totals
func (bt *BandwidthTracker) Totals() metrics.Statsfunc (*BandwidthTracker) PublishMetrics
func (bt *BandwidthTracker) PublishMetrics()func (*BandwidthTracker) Start
func (bt *BandwidthTracker) Start(ctx context.Context, interval time.Duration)Start begins periodic metric publishing.
Identity Utilities
func LoadOrCreateIdentity
func LoadOrCreateIdentity(path, password string) (crypto.PrivKey, error)LoadOrCreateIdentity loads an Ed25519 private key from the given path, or creates one if it does not exist.
func PeerIDFromKeyFile
func PeerIDFromKeyFile(path, password string) (peer.ID, error)PeerIDFromKeyFile reads a key file and returns the corresponding peer ID without loading the full network.
DNS Seeds
func ResolveDNSSeeds
func ResolveDNSSeeds(ctx context.Context, domain string) []peer.AddrInfoResolveDNSSeeds resolves DNS TXT records for peer bootstrap addresses.
STUN Utilities
func BuildSTUNBindingRequest
func BuildSTUNBindingRequest(txID [12]byte) []byteBuildSTUNBindingRequest constructs a raw STUN Binding Request packet.
func BuildSTUNBindingResponse
func BuildSTUNBindingResponse(txID [12]byte, ip net.IP, port int) []byteBuildSTUNBindingResponse constructs a raw STUN Binding Response packet with an XOR-MAPPED-ADDRESS attribute.
Verification Utilities
func ComputeFingerprint
func ComputeFingerprint(a, b peer.ID) (emoji string, numeric string)ComputeFingerprint computes an OMEMO-style SAS fingerprint (4 emojis + 8 digits) from two peer IDs. Order-independent.
func FingerprintPrefix
func FingerprintPrefix(a, b peer.ID) stringFingerprintPrefix returns the short emoji fingerprint prefix for display in peer status.
Reachability
func ComputeReachabilityGrade
func ComputeReachabilityGrade(ifaces *InterfaceSummary, stun *STUNResult) ReachabilityGradeComputeReachabilityGrade computes a reachability grade (A-F) from interface discovery and STUN results. Grade A = globally reachable, Grade F = no connectivity.
Service Query
func HandleServiceQuery
func HandleServiceQuery(registry *ServiceRegistry) StreamHandlerHandleServiceQuery returns a stream handler for remote service discovery. Peers can query which services a node provides.
Errors
type RemoteError
type RemoteError struct {
Message string
}RemoteError wraps an error message received from a remote peer.
func (*RemoteError) Error
func (e *RemoteError) Error() stringGo Documentation
Full API reference with doc comments is available locally via pkgsite:
go install golang.org/x/pkgsite/cmd/pkgsite@latest
cd /path/to/shurli
pkgsite -open .Then navigate to pkg/sdk and pkg/plugin for browsable documentation with full source links.