package socket

Import Path
	github.com/tmc/go-iroh/internal/socket (on go.dev)

Dependency Relation
	imports 21 packages, and imported by one package

Involved Source Files custom.go deadline.go ip.go Package socket implements iroh's "magic socket": a single net.PacketConn, driven by quic-go, that multiplexes datagrams across several transports (direct UDP, relay, custom). Because quic-go addresses paths with net.Addr, each non-IP path is represented by a synthetic IPv6 Unique Local Address (RFC 4193) from a private range. These mapped addresses are an internal indirection only — they are never sent on the wire — but the byte scheme matches the Rust implementation (iroh/src/socket/mapped_addrs.rs) for cross-referencing. metrics.go path_selector.go path_state.go path_watcher.go performance_stats.go performance_stats_disabled.go recvbatch.go relay.go relay_actor.go remote_state.go remotemap.go socket.go transport.go transport_gso_linux.go
Code Examples package main import ( "context" "fmt" "net" "net/netip" "github.com/tmc/go-iroh/internal/socket" ) func main() { udp, err := net.ListenUDP("udp", net.UDPAddrFromAddrPort( netip.AddrPortFrom(netip.IPv6Loopback(), 0))) if err != nil { panic(err) } sock := socket.NewSocket() magic := socket.NewMagicConn(sock, udp) ctx, cancel := context.WithCancel(context.Background()) defer cancel() go magic.Serve(ctx) var pc net.PacketConn = magic defer pc.Close() fmt.Println(pc.LocalAddr().Network()) }
Package-Level Type Names (total 45)
/* sort by: | */
Addr is the transport-level address of a network path, internal to the magic socket. It is one of three kinds — IP, relay, or custom — mirroring the Rust transports::Addr enum (iroh/src/socket/transports.rs:795). The zero Addr is an unspecified IPv6 IP address, matching Rust's Default (transports.rs:830). An Addr is never sent on the wire; it is the magic socket's own routing key. Custom returns the custom address and true if a is an [AddrCustom]. IP returns the IP socket address and true if a is an [AddrIP]. Kind reports which variant a is. Relay returns the relay URL, endpoint id, and true if a is an [AddrRelay]. String renders a in a stable "kind:value" form. It is suitable as a map key (two Addrs are equal iff their String values are equal) and for diagnostics. It mirrors the Rust transports::Addr Display (iroh/src/socket/transports.rs). Addr : expvar.Var Addr : fmt.Stringer func CustomAddr(c netaddr.CustomAddr) Addr func IPAddr(ap netip.AddrPort) Addr func RelayAddr(url netaddr.RelayURL, eid key.EndpointID) Addr func BiasedRttPathSelector.Select(current *Addr, candidates []PathCandidate) (Addr, bool) func Connection.RemoteAddr() Addr func PathSelector.Select(current *Addr, candidates []PathCandidate) (selected Addr, ok bool) func (*RemotePathState).Addrs() []Addr func (*RemotePathState).ExpireIdle(now time.Time) []Addr func (*RemotePathState).OpenAddrs() []Addr func (*RemoteStateActor).SelectedPath() (Addr, bool) func (*Socket).PathAddr(remoteID key.EndpointID, ra net.Addr) Addr func BiasedRttPathSelector.Select(current *Addr, candidates []PathCandidate) (Addr, bool) func (*MagicConn).SendAddr(addr Addr, p []byte) bool func PathSelector.Select(current *Addr, candidates []PathCandidate) (selected Addr, ok bool) func (*RemotePathState).Add(addr Addr) func (*RemotePathState).AddWithProvenance(addr Addr, provenance string) func (*RemotePathState).SetClosed(addr Addr, now time.Time) func (*RemotePathState).SetOpen(addr Addr) func (*RemotePathState).SetOpenAt(addr Addr, now time.Time) func (*RemotePathState).SetUnusable(addr Addr) func (*RemotePathState).Status(addr Addr) (PathStatus, bool) func (*Socket).EvictRemote(id key.EndpointID, addrs []Addr)
AddrKind tags the variant of an [Addr]. func Addr.Kind() AddrKind const AddrCustom const AddrIP const AddrRelay
Type Parameters: K: comparable V: comparable AddrMap is a bidirectional map between a key K and a mapped address of value type V, generating a new mapped address on first lookup of a key. It is the Go analog of the Rust AddrMap. Get returns the mapped address for key, generating and recording one if it does not yet exist. Len returns the number of mappings. Intended for tests and metrics. Lookup returns the key that maps to addr, if any. Remove deletes the mapping for key, if any. The next Get of the same key generates a fresh mapped address. func NewAddrMap[K, V](gen func() V, addrOf func(V) netip.Addr) *AddrMap[K, V]
BiasedRttPathSelector is the default [PathSelector]. It sorts paths by (tier, biased RTT): the primary tier always beats the backup tier, and within a tier the lowest biased RTT wins. IPv6 paths receive a [IPv6RttAdvantage] bias. Switching within a tier requires the candidate's biased RTT to be at least [RttSwitchingMin] better than the current path (no flapping); switching across tiers is immediate. It mirrors the Rust BiasedRttPathSelector (iroh/src/socket/biased_rtt_path_selector.rs:135). The zero value is ready to use. Select implements [PathSelector]. It returns the best candidate to use, or ok=false to keep the current selection. The decision follows the Rust single-pass algorithm (biased_rtt_path_selector.rs:136): find the lowest-keyed candidate and the lowest key seen for the current path, then switch across tiers immediately and within a tier only when the improvement meets [RttSwitchingMin]. BiasedRttPathSelector : PathSelector
Connection is the minimal view of a QUIC connection the [RemoteStateActor] needs. The iroh package adapts a qng *quic.Conn to it; tests use a fake. It stays small on purpose: the actor only reads liveness and RTT. SmoothedRTT returns the connection's active-path smoothed RTT. Done is closed when the connection ends. RemoteAddr reports the path the connection is on, so the actor can register it as a candidate path. Done is closed when the connection is closed. RemoteAddr returns the transport address the connection is using. SmoothedRTT returns the smoothed round-trip time of the active path. func (*RemoteMap).AddConnection(remote key.EndpointID, conn Connection) <-chan PathEvent func (*RemoteMap).AddConnectionActor(remote key.EndpointID, conn Connection) (<-chan PathEvent, *RemoteStateActor) func (*RemoteStateActor).AddConnection(conn Connection) (events <-chan PathEvent, ok bool) func (*RemoteStateActor).PathInfos(conn Connection) []PathInfo func (*RemoteStateActor).TriggerHolepunchConn(conn Connection) error
CustomDatagram is one datagram received by a [CustomTransport]. Data []byte HasLocal bool Local netaddr.CustomAddr Remote netaddr.CustomAddr
CustomMappedAddr addresses a remote endpoint via a custom transport path. Addr returns the underlying IPv6 address. AddrPort returns the mapped address with the fixed dummy port. func CustomMappedAddrFromAddr(a netip.Addr) CustomMappedAddr func NewCustomMappedAddr() CustomMappedAddr func (*Socket).CustomMappedAddrFor(c netaddr.CustomAddr) CustomMappedAddr func (*Socket).LookupCustom(m CustomMappedAddr) (netaddr.CustomAddr, bool)
CustomTransport is a pluggable transport backend for custom addresses. It is intentionally small: the transport owns its wire format and reports datagrams as iroh custom addresses for the magic socket to map into qng paths. Send sends p to remote. local is nil when qng did not select a specific local custom address for the path. Serve runs the transport until ctx is done. Each received datagram should be passed to recv. recv reports false when the magic socket is shutting down or its receive queue is full. PacketTransport (interface) func NewMagicConnRelayOnly(sock *Socket, actor *RelayActor, custom ...CustomTransport) *MagicConn func NewMagicConnWithTransports(sock *Socket, udp *net.UDPConn, actor *RelayActor, custom ...CustomTransport) *MagicConn
EndpointIDMappedAddr addresses a remote endpoint via any/all of its paths. It is used for the initial connection, before a path is selected: the socket duplicates datagrams sent here onto every candidate path. Addr returns the underlying IPv6 address. AddrPort returns the mapped address with the fixed dummy port, suitable for handing to quic-go as a path's net.Addr. func EndpointIDMappedAddrFromAddr(a netip.Addr) EndpointIDMappedAddr func NewEndpointIDMappedAddr() EndpointIDMappedAddr func (*Socket).EndpointIDMappedAddrFor(id key.EndpointID) EndpointIDMappedAddr func (*Socket).LookupEndpointID(m EndpointIDMappedAddr) (key.EndpointID, bool)
IpTransport is the direct-UDP transport: it reads datagrams from a net.PacketConn and forwards them to the [MagicConn]'s recv channel, and sends datagrams the magic socket routes to it. It is the Go analog of the Rust IpTransport (iroh/src/socket/transports/ip.rs). Create one with [NewIpTransport] and start its recv loop with [IpTransport.Serve]. LocalAddr returns the bound local address of the underlying socket. Serve runs the receive loop until ctx is cancelled or the socket is closed. Each datagram is delivered to the recv channel tagged with its real remote IP address (canonicalized: an IPv4-mapped IPv6 source becomes plain IPv4, to match iroh/src/socket/transports/ip.rs:221 to_canonical). Empty datagrams and transient errors are skipped; a closed socket ends the loop cleanly. func NewIpTransport(conn *net.UDPConn, recvCh chan<- recvBatch) *IpTransport
MagicConn is the single net.PacketConn handed to a quic-go Transport. It presents every iroh network path — direct IP, relay, custom — as one UDP socket, mapping non-IP paths to synthetic IPv6 ULAs so quic-go can address them. It is the Go analog of the Rust `impl AsyncUdpSocket for Transport` (iroh/src/socket/transports.rs:1067). MagicConn satisfies net.PacketConn. It deliberately does not satisfy quic-go's OOBCapablePacketConn: GRO and ECN receive metadata do not generalize across relay and custom transports. On Linux it exposes a narrower send-message method so qng can use GSO for direct IP destinations and split the same write for other transports. Correctness does not depend on it. Create one with [NewMagicConn] and start it with [MagicConn.Serve]. The zero value is not usable. Close releases the magic socket. It marks the shared [Socket] closed and closes the underlying UDP socket, which ends the receive loop. It implements net.PacketConn. LocalAddr returns the bound local address of the underlying UDP socket. It implements net.PacketConn. Metrics returns a point-in-time copy of magic-socket counters. MetricsSet returns the shared magic-socket counter set. ReadFrom delivers the next datagram from any transport into p, returning its length and the net.Addr quic-go should associate with the path it arrived on. For IP paths that addr is the real remote IP; for relay and custom paths it is the synthetic mapped IPv6 ULA (port 12345). It implements net.PacketConn. RecordRelayHomeChange increments the relay-home change counter. Relay returns the relay transport, or nil if no relay actor was configured. SendAddr routes p to one concrete magic-socket transport address. It is used by RemoteStateActor endpoint-id fanout. Serve runs the magic socket's receive loops until ctx is cancelled or the underlying socket is closed. It blocks; run it in its own goroutine. SetDeadline sets both the read and write deadlines. It implements net.PacketConn. SetEndpointSender sets the callback used for endpoint-id mapped addresses. The callback should route p through the remote endpoint's actor and report whether it accepted the datagram. A nil callback restores blackhole behavior. SetReadBuffer sets the kernel receive buffer size on the underlying UDP socket. quic-go calls it to raise the buffer to its desired size. SetReadDeadline sets the deadline for future ReadFrom calls. It implements net.PacketConn. SetWriteBuffer sets the kernel send buffer size on the underlying UDP socket. SetWriteDeadline sets the deadline for future WriteTo calls. Writes go straight to the underlying socket, so the deadline is applied there. It implements net.PacketConn. SyscallConn returns the underlying UDP socket's raw connection. quic-go uses it to size the kernel receive buffer and to set the Don't Fragment bit on the direct-IP path. Exposing it does not make MagicConn an OOBCapablePacketConn. On Linux qng combines it with MagicConn's send-message method for send-side GSO only. WriteMsgUDP writes a possibly segmented datagram. Direct IP destinations use the kernel's UDP_SEGMENT path. Other transports receive one datagram per segment through the ordinary magic-socket router. WriteTo routes p to the transport addressed by addr and reports success. addr is classified by [Classify]: a real IP routes to the IP transport; the EndpointID, relay, and custom mapped ULAs route to their transports. A send to a path with no live transport, an unknown mapped address, or a closed socket is blackholed — WriteTo still returns (len(p), nil). quic-go observes the send as successful and its loss recovery retransmits the lost datagram, matching the Rust Sender::poll_send blackhole invariant (iroh/src/socket/transports.rs:1176). *MagicConn : github.com/pion/datachannel.ReadDeadliner *MagicConn : github.com/pion/datachannel.WriteDeadliner *MagicConn : github.com/prometheus/common/expfmt.Closer *MagicConn : io.Closer *MagicConn : net.PacketConn *MagicConn : syscall.Conn func NewMagicConn(sock *Socket, udp *net.UDPConn) *MagicConn func NewMagicConnRelayOnly(sock *Socket, actor *RelayActor, custom ...CustomTransport) *MagicConn func NewMagicConnWithRelay(sock *Socket, udp *net.UDPConn, actor *RelayActor) *MagicConn func NewMagicConnWithTransports(sock *Socket, udp *net.UDPConn, actor *RelayActor, custom ...CustomTransport) *MagicConn
MappedKind classifies a netip.Addr as one of the mapped kinds or a real IP. func Classify(addr netip.Addr) MappedKind const KindCustom const KindEndpointID const KindIP const KindRelay
Metrics is the magic socket's datagram counter set. func (*MagicConn).MetricsSet() *Metrics func NewRemoteMapWithMetrics(ctx context.Context, selector PathSelector, resolve ResolveFunc, metrics *Metrics) *RemoteMap
Packet is one custom transport packet whose buffer is owned by the transport. Data []byte Free func() HasLocal bool Local netaddr.CustomAddr Remote netaddr.CustomAddr
PacketTransport is a custom transport that owns received packet buffers. Send sends p to remote. local is nil when qng did not select a specific local custom address for the path. SendPacket sends p to remote. The transport must not retain p after the call returns. Serve runs the transport until ctx is done. Each received datagram should be passed to recv. recv reports false when the magic socket is shutting down or its receive queue is full. ServePackets runs the transport until ctx is done. Received packets are owned by the transport until their Free callback runs. PacketTransport : CustomTransport
PathCandidate is one path offered to a [PathSelector], pairing its [Addr] with the most recent RTT observed for it. It is the Go analog of the Rust PathSelectionData (biased_rtt_path_selector.rs). Addr is the path's transport address. RTT is the smoothed round-trip time observed on the path. qng multipath paths use per-path RTT when available; otherwise the socket layer falls back to connection-level active-path RTT. func BiasedRttPathSelector.Select(current *Addr, candidates []PathCandidate) (Addr, bool) func PathSelector.Select(current *Addr, candidates []PathCandidate) (selected Addr, ok bool)
PathEvent is a lifecycle notification for a network path of a connection. It is the Go analog of the Rust PathEvent enum (path_watcher.rs:55). For Opened, Closed, and Selected, Addr identifies the path. For Lagged, Missed is the number of events the subscriber missed and Addr is the zero value. Addr is the path's transport address (zero for Lagged). Kind is which kind of event this is. Missed is the number of dropped events (only for Lagged). func (*PathWatcher).Subscribe() (<-chan PathEvent, func()) func (*RemoteMap).AddConnection(remote key.EndpointID, conn Connection) <-chan PathEvent func (*RemoteMap).AddConnectionActor(remote key.EndpointID, conn Connection) (<-chan PathEvent, *RemoteStateActor) func (*RemoteStateActor).AddConnection(conn Connection) (events <-chan PathEvent, ok bool) func (*RemoteStateActor).PathEvents() (<-chan PathEvent, func()) func (*PathWatcher).Send(ev PathEvent)
PathEventKind tags the variant of a [PathEvent]. ( PathEventKind) String() string PathEventKind : expvar.Var PathEventKind : fmt.Stringer const PathEventClosed const PathEventLagged const PathEventOpened const PathEventSelected
PathInfo is qng multipath path state observed through a [Connection]. Addr and RTT are set only when qng reports them; socket must not fabricate Addr from the connection's original RemoteAddr. Addr is the path's transport address, when HasAddr is true. BytesInFlight is the path's current application-data bytes in flight, when HasBytesInFlight is true. BytesReceived is the cumulative application-data bytes received on this path, when HasBytesReceived is true. BytesSent is the cumulative application-data bytes sent on this path, when HasBytesSent is true. CongestionWindow is the path's current congestion window, when HasCongestionWindow is true. HasAddr reports whether Addr was observed from qng route metadata. HasBytesInFlight reports whether BytesInFlight was observed from qng per-path state. HasBytesReceived reports whether BytesReceived was observed from qng per-path state. HasBytesSent reports whether BytesSent was observed from qng per-path state. HasCongestionWindow reports whether CongestionWindow was observed from qng per-path state. HasLoss reports whether LostPackets and LostBytes were observed from qng per-path state. HasRTT reports whether RTT was observed from qng per-path state. ID is the QUIC multipath PathID. LostBytes is the number of application-data bytes declared lost on this path, when HasLoss is true. LostPackets is the number of application-data packets declared lost on this path, when HasLoss is true. RTT is the path's smoothed round-trip time, when HasRTT is true. Selected reports whether this path is currently selected for application data transmission. Validated reports whether the path can carry non-probing application data. func (*RemoteStateActor).MultipathPaths() []PathInfo func (*RemoteStateActor).PathInfos(conn Connection) []PathInfo
PathSelector chooses the preferred path among the candidates for a remote endpoint. It is a pure function of the candidate set and the currently selected path. Implementations must not block. It is the Go analog of the Rust PathSelector trait (iroh/src/socket/remote_map/remote_state.rs). The default implementation is [BiasedRttPathSelector]. Select returns the address of the path to use, or ok=false to keep the current selection (including keeping no selection). current is the currently selected path, if any. BiasedRttPathSelector func NewRemoteMap(ctx context.Context, selector PathSelector, resolve ResolveFunc) *RemoteMap func NewRemoteMapWithMetrics(ctx context.Context, selector PathSelector, resolve ResolveFunc, metrics *Metrics) *RemoteMap
PathState is the per-path bookkeeping kept by [RemotePathState]. Status is the current lifecycle status of the path.
PathStatus is the lifecycle status of a candidate path. It mirrors the Rust PathStatus enum (path_state.rs:44). ( PathStatus) String() string PathStatus : expvar.Var PathStatus : fmt.Stringer func (*RemotePathState).Status(addr Addr) (PathStatus, bool) const PathStatusInactive const PathStatusOpen const PathStatusUnknown const PathStatusUnusable
PathWatcher is a drop-oldest broadcast of [PathEvent]s to any number of subscribers. Each subscriber has its own ring buffer of [PathBroadcastCapacity] events; when a subscriber falls behind, the oldest buffered event is dropped and the next event the subscriber receives is a [PathEventLagged] with the running missed count, mirroring tokio::broadcast's lagged-receiver behavior (path_watcher.rs). PathWatcher is safe for concurrent use. The writer calls [PathWatcher.Send]; readers call [PathWatcher.Subscribe] and consume the returned channel. Each subscriber is served by a dedicated delivery goroutine that stops when the subscriber is cancelled or the watcher is closed. Close stops every subscriber's delivery goroutine, closing its channel, and rejects future sends and subscriptions. It is idempotent. It is the analog of dropping the Rust broadcast sender, which ends every outstanding receiver. Send broadcasts ev to every subscriber. A subscriber whose ring buffer is full has its oldest pending event dropped and its missed counter incremented; the next event that subscriber receives is a [PathEventLagged] carrying the missed count. Send never blocks. Subscribe registers a new subscriber and returns the channel its events are delivered on plus a function to unsubscribe and stop delivery. Events sent before Subscribe are not replayed. The channel is closed when the subscriber is cancelled or the watcher is closed. The cancel function should be called when the subscriber is done, like [time.Ticker.Stop]: each subscription runs a delivery goroutine, which cancel stops without waiting for the subscriber to drain. [PathWatcher.Close] stops the goroutine of every remaining subscriber, so an abandoned subscription outlives at most the watcher itself. Events already buffered on the channel stay readable after it is closed; events still pending delivery when a subscriber stops reading are dropped. func NewPathWatcher() *PathWatcher
PerformanceStats contains direct-IP receive counters collected by binaries built with the iroh_performance_stats build tag. UDPDatagramsReceived uint64 UDPGROReads uint64 UDPReceiveSyscalls uint64 func SnapshotPerformanceStats() PerformanceStats
RecvInfo carries the per-datagram metadata a transport reports alongside the payload: the remote [Addr] it came from and, for custom transports, the local custom address that received it. It mirrors the Rust RecvInfo (iroh/src/socket/transports.rs:572). For IP and relay paths Local is the zero value. HasLocal reports whether Local is set (custom transports only). Local netaddr.CustomAddr Remote Addr
RelayActor manages connections to relay servers. It starts one [activeRelay] per relay URL on demand, routes outgoing datagrams to the right one, and surfaces received datagrams on a single queue. It tracks the home relay and publishes its status through a [watch.Value]. It is the Go analog of the Rust RelayActor (iroh/src/socket/transports/relay/actor.rs:855). Create one with [NewRelayActor] and start it with [RelayActor.Run]. HomeRelayStatus returns a watcher over the home relay's connection status. The value is nil until a home relay is set with [RelayActor.SetHomeRelay]. InsertRelay adds or replaces url's relay configuration, returning the previous config when one existed. If there is no home relay, url becomes home. Recv returns the queue of datagrams received from relays. A [RelayTransport] drains it; the channel is closed when the actor stops. RemoveRelay removes url's configuration, returning it when present. Any live non-home connection to url is stopped. If url was the home relay, the next configured relay (if any) becomes home. Run drives the actor until ctx is cancelled. It starts active relays on demand from queued send items. It blocks; run it in its own goroutine. When it returns it has closed the recv channel and stopped all active relays. Send queues item for delivery to its relay. It never blocks: if the queue is full the item is dropped (treated as datagram loss so QUIC's loss recovery retransmits), matching the Rust non-blocking send invariant (iroh/src/socket/transports.rs:1176). Send reports whether the item was queued; a false result is a dropped (lost) datagram, not an error. SetHomeRelay designates url as the home relay, ensuring an [activeRelay] for it (which then never idles out) and demoting any previous home relay. A zero url clears the home relay. It mirrors the Rust on_network_change / set_home_relay path (iroh/src/socket/transports/relay/actor.rs:1126). func NewRelayActor(cfg RelayActorConfig) *RelayActor func NewMagicConnRelayOnly(sock *Socket, actor *RelayActor, custom ...CustomTransport) *MagicConn func NewMagicConnWithRelay(sock *Socket, udp *net.UDPConn, actor *RelayActor) *MagicConn func NewMagicConnWithTransports(sock *Socket, udp *net.UDPConn, actor *RelayActor, custom ...CustomTransport) *MagicConn func NewRelayTransport(sock *Socket, actor *RelayActor, recvCh chan<- recvBatch) *RelayTransport
RelayActorConfig configures a [RelayActor]. SecretKey is required. The zero value is otherwise not usable; build a config and pass it to [NewRelayActor]. Map is the relay map; consulted for per-relay auth tokens. SecretKey is the local endpoint's secret key, used to authenticate to relays. Required. func NewRelayActor(cfg RelayActorConfig) *RelayActor
RelayConnState is the connection state of a relay, published through the home relay watcher. It is the Go analog of the Rust RelayConnectionState (iroh/src/socket/transports/relay/actor.rs:897). ( RelayConnState) String() string RelayConnState : expvar.Var RelayConnState : fmt.Stringer const RelayConnected const RelayConnecting const RelayDisconnected
RelayKey identifies a relay path: a relay URL together with the remote endpoint reached through it. It is the key type of the relay mapped-address table. EID key.EndpointID URL netaddr.RelayURL func (*Socket).LookupRelay(m RelayMappedAddr) (RelayKey, bool)
RelayMappedAddr addresses a remote endpoint via a specific relay path (an (EndpointID, RelayURL) pair). Addr returns the underlying IPv6 address. AddrPort returns the mapped address with the fixed dummy port. func NewRelayMappedAddr() RelayMappedAddr func RelayMappedAddrFromAddr(a netip.Addr) RelayMappedAddr func (*Socket).RelayMappedAddrFor(url netaddr.RelayURL, eid key.EndpointID) RelayMappedAddr func (*RelayTransport).Send(m RelayMappedAddr, p []byte) bool func (*Socket).LookupRelay(m RelayMappedAddr) (RelayKey, bool)
RelayRecvDatagram is a datagram received from a relay. It is the Go analog of the Rust RelayRecvDatagram (iroh/src/socket/transports/relay/actor.rs:1383). Datagrams is the payload. Src is the endpoint that sent it. URL is the relay it arrived on. func (*RelayActor).Recv() <-chan RelayRecvDatagram
RelaySendItem is one or more datagrams to send to a remote endpoint via a relay. It is the Go analog of the Rust RelaySendItem (iroh/src/socket/transports/relay/actor.rs:846). Datagrams is the payload. RemoteEndpoint is the destination endpoint. URL is the relay through which to reach RemoteEndpoint. func (*RelayActor).Send(item RelaySendItem) bool
RelayStatus is the connection status of a single home relay, observed through [RelayActor.HomeRelayStatus]. It is the Go analog of the Rust RelayStatus (iroh/src/endpoint.rs:1832). The zero value reports no home relay; use [RelayActor.HomeRelayStatus] to observe it. LastError is the most recent connection error while disconnected, or nil. State is the current connection state. URL is the home relay URL. IsConnected reports whether the relay is connected.
RelayTransport is the magic socket's relay path: it owns a [RelayActor], forwards datagrams received from relays into the [MagicConn]'s recv channel (tagged so they surface as a [RelayMappedAddr]), and routes outgoing datagrams addressed to a relay mapped address to the right relay connection. It is the Go analog of the Rust RelayTransport (iroh/src/socket/transports/relay.rs:31). Create one with [NewRelayTransport] and start it with [RelayTransport.Serve]. The zero value is not usable. HomeRelayStatus returns a watcher over the home relay's connection status. See [RelayActor.HomeRelayStatus]. InsertRelay adds or replaces a relay config in the underlying actor. RemoveRelay removes a relay config from the underlying actor. Send routes p to the relay addressed by the relay mapped address m. It looks up the (relay url, endpoint id) pair m maps to and queues a datagram to the relay actor. It reports whether the datagram was routed; a false result means the address is unknown or the send queue was full, in which case the datagram is treated as lost (QUIC's loss recovery retransmits), matching the Rust blackhole-on-failure invariant (iroh/src/socket/transports.rs:1176). Serve runs the relay actor and the recv-forwarding loop until ctx is cancelled. It blocks; run it in its own goroutine. SetHomeRelay designates url as the endpoint's home relay. See [RelayActor.SetHomeRelay]. func NewRelayTransport(sock *Socket, actor *RelayActor, recvCh chan<- recvBatch) *RelayTransport func (*MagicConn).Relay() *RelayTransport
RemoteInfo is a snapshot of known addresses for a remote endpoint. Addrs []TransportAddrInfo ID key.EndpointID func (*RemoteMap).RemoteInfo(id key.EndpointID) (RemoteInfo, bool) func (*RemoteStateActor).RemoteInfo() RemoteInfo
RemoteMap is the registry of per-remote [RemoteStateActor]s, keyed by [key.EndpointID]. It spawns an actor on first reference to a remote and removes it when the actor idles out. It is the Go analog of the Rust RemoteMap (iroh/src/socket/remote_map.rs). Actor insertion and idle-teardown deregistration are serialized by a single mutex, and an actor only removes itself if it is still the actor registered under its id. So an AddConnection arriving exactly as the 60s idle timeout fires yields exactly one actor: the teardown either runs first (the next reference spawns a fresh actor) or the AddConnection runs first (which resets the actor's idle timer, so it does not tear down). See [RemoteMap.ResolveRemote] / [RemoteMap.AddConnection] and the onExit closure in [RemoteMap.actor]. RemoteMap is safe for concurrent use. Create one with [NewRemoteMap]. Actor returns the running actor for id, spawning one if none exists. AddConnection registers conn with the actor for remote, spawning the actor if needed, and returns the connection's path-event channel. Registering a connection resets the actor's idle timer, so this can race the idle teardown safely (O12): if the actor is mid-teardown the send observes its done channel and a fresh actor is spawned on the retry. AddConnectionActor is like [RemoteMap.AddConnection], but also returns the actor that accepted conn. AddNATTraversalAddresses reconciles local QNT candidates on currently-active remote actors. It does not spawn actors and ignores per-actor errors, because candidate updates must not make an established endpoint fail. DisableHolepunch stops actors from initiating NAT traversal or direct-path validation on their upgrade tick. Endpoints without IP transports set it: there is no direct path to punch toward, and a traversal round initiated on a relay-only connection stalls its in-flight relay streams. Set it before the first remote is referenced. Len returns the number of registered actors. Intended for tests and metrics. RemoteInfo returns a snapshot for id if a running actor exists. It does not spawn a new actor. ResolveRemote asks the actor for addr.ID to resolve and register more candidate paths, spawning the actor if needed. It returns the lookup error if any. It races idle teardown the same way as [RemoteMap.AddConnection]. SetOnEvict sets f to be called when a remote's actor is reaped with no successor, passing the remote's known path addresses. The endpoint uses it to release the remote's mapped addresses (see [Socket.EvictRemote]), so the mapped-address tables do not grow without bound under peer churn. f is called with the map's internal mutex held and must not call back into the RemoteMap. Set it before the first remote is referenced. func NewRemoteMap(ctx context.Context, selector PathSelector, resolve ResolveFunc) *RemoteMap func NewRemoteMapWithMetrics(ctx context.Context, selector PathSelector, resolve ResolveFunc, metrics *Metrics) *RemoteMap
RemotePathState tracks all candidate paths to a single remote endpoint: direct IP, relay, and custom transport addresses, each with a [PathStatus]. It is the Go analog of the Rust RemotePathState (path_state.rs). Paths added by address lookup start [PathStatusUnknown]; QUIC path events move them through Open and Inactive; failed hole-punches mark them Unusable. The set is bounded by [RemotePathState.Prune], which keeps at most [MaxNonRelayPaths] non-relay paths plus [MaxInactiveNonRelayPaths] inactive non-relay paths. Relay paths are never pruned. RemotePathState is not safe for concurrent use; it is owned by a single [RemoteStateActor] goroutine. Add records a candidate path with [PathStatusUnknown] if it is not already known. A path already present keeps its current status. AddWithProvenance records a candidate path with lookup provenance. Addrs returns the addresses of all known paths in unspecified order. ExpireIdle closes open paths that have not been observed within their path idle timeout. Direct and custom paths use [PathMaxIdleTimeout]; relay paths use [RelayPathMaxIdleTimeout]. IsEmpty reports whether no paths are known. Len returns the number of known paths, including relay paths. OpenAddrs returns the addresses of all currently open paths. Prune bounds the non-relay path set. It is a no-op when there are fewer than [MaxNonRelayPaths] non-relay paths. Otherwise it removes failed (unusable) paths and all but the [MaxInactiveNonRelayPaths] most-recently-closed inactive paths. Open and unknown paths are always kept; relay paths are never pruned or counted. It mirrors prune_non_relay_paths (path_state.rs:254). RemoteAddrs returns all known remote addresses with active/inactive usage. SetClosed transitions addr toward an inactive/unusable status, recording the close time for inactive pruning. It mirrors the Rust remove_path transition (path_state.rs:106): an open or already-inactive path becomes inactive (still considered usable later); an unusable or unknown path becomes unusable. SetOpen marks addr as open, adding it if unknown. It mirrors the Rust add_path / on path-open transition (path_state.rs:90). SetOpenAt marks addr as open with an explicit activity time. It is used by tests and by the actor heartbeat, which already has a shared timestamp for all observed paths. SetUnusable marks addr unusable: a hole-punch was attempted and failed. Status returns the status of addr and whether it is known. func NewRemotePathState() *RemotePathState
RemoteStateActor manages all connection and path state for a single remote endpoint. Exactly one goroutine runs per remote, driven by a single select loop over the inbox (which carries add-connection, resolve, and connection-closed messages) and timers (heartbeat, upgrade, idle teardown). It is the Go analog of the Rust RemoteStateActor (iroh/src/socket/remote_map/remote_state.rs). The actor does not build NAT traversal frames itself. It advertises vetted local candidates and asks qng to start traversal rounds; qng owns probe timers, response matching, and route-bearing path opening. Path selection is driven by qng path observability. Create an actor with the RemoteMap; do not construct one directly. AddConnection registers conn with the actor and returns a channel of path events for it. ok is false if the actor stopped before it could register the connection; the caller should retry with a fresh actor. The returned channel is closed when the connection closes or the actor stops; the subscription's lifetime is managed by the actor, so the caller may simply stop reading. AddNATTraversalAddresses reconciles the full local QNT candidate set for active qng connections. Candidate discovery stays outside this method: callers must pass already-vetted local candidates, such as endpoint-bound direct addresses and QAD reflexive addresses. qng owns QNT state, wire frames, probe timers, and eventual path opening. AddRemoteNATTraversalAddresses seeds remote QNT candidates from an authenticated endpoint address, such as the address used to dial the peer. ID returns the remote endpoint this actor manages. MultipathPaths returns qng multipath path state observed from active connections. Paths with explicit qng route metadata are also registered with RemotePathState by the actor loop and can produce path events. NATTraversalAddresses returns the remote QNT ADD_ADDRESS set observed on active qng connections. Duplicate addresses are removed in first-seen order. PathEvents returns a fresh subscription to this actor's path events and a function to cancel it. PathInfos returns a snapshot of currently open paths for conn. RemoteInfo returns a snapshot of known addresses for this remote endpoint. ResolveRemote asks the actor to resolve more addresses for addr via the [ResolveFunc] and register them as candidate paths as they arrive. It returns once the resolver stream has been started. With no resolver and no addrs it returns nil immediately. SelectedPath returns the actor's currently selected path and whether one is selected. It is safe to call concurrently with the actor loop. SendDatagram routes a datagram toward the remote via send. If a path is selected it sends there; otherwise it sends to every known path. It NEVER returns an error for an unreachable path: an unroutable datagram is treated as lost so QUIC loss recovery handles it (the socket-core blackhole invariant, iroh/src/socket/remote_map/remote_state.rs:782). send's bool result is advisory only. qng addresses datagrams to a concrete path directly through the MagicConn, so this method backs the Mixed-EndpointID send path, which is exercised by unit tests rather than the QUIC data plane in this slice. TriggerHolepunch attempts to open a new direct path by NAT traversal. It is gated on an active qng connection with QNT support: socket advertises its already-known local candidates and asks qng to initiate one NAT traversal round. qng owns QNT frames, probe timers, response matching, and path opening. TriggerHolepunchConn attempts NAT traversal on conn. It returns [context.Canceled] if conn is no longer registered, or [ErrExtensionNotNegotiated] if conn does not support QNT. ValidateDirectPath asks qng to open and validate one ordinary multipath path over the current direct socket. This is the RFC 9000 path-validation path used before or independent of QNT-discovered NAT candidates. func (*RemoteMap).Actor(id key.EndpointID) *RemoteStateActor func (*RemoteMap).AddConnectionActor(remote key.EndpointID, conn Connection) (<-chan PathEvent, *RemoteStateActor)
ResolvedAddr is a transport address plus lookup provenance. Addr netaddr.TransportAddr Provenance string
ResolveFunc streams additional transport addresses for a remote endpoint. It is supplied by the iroh package (which owns the address-lookup services) so the socket package does not import iroh. A nil ResolveFunc disables lookup-driven resolution. It is the hook for the Rust RemoteStateActor::resolve_remote path (remote_state.rs:843), wired in slice G's address lookup. func NewRemoteMap(ctx context.Context, selector PathSelector, resolve ResolveFunc) *RemoteMap func NewRemoteMapWithMetrics(ctx context.Context, selector PathSelector, resolve ResolveFunc, metrics *Metrics) *RemoteMap
Socket holds the magic socket's mapped-address tables: the bidirectional maps between transport addresses and the synthetic IPv6 ULAs that quic-go uses to address paths. It is the Go analog of the Rust Socket's mapped_addrs (iroh/src/socket.rs:332). A Socket is created by [NewSocket] and shared by a [MagicConn] and its [Transports]. It is safe for concurrent use. The zero Socket is not usable; use [NewSocket]. Close marks the socket closed. Subsequent sends are dropped (blackholed) so quic-go's loss recovery handles in-flight datagrams rather than seeing a hard error. It is idempotent. CustomMappedAddrFor returns the custom mapped address for c, allocating one on first use and recording the reverse mapping back to c. EndpointIDMappedAddrFor returns the endpoint-id mapped address for id, allocating one on first use. EvictRemote drops the mapped addresses recorded for a reaped remote: the endpoint-id mapping for id, every relay mapping whose remote endpoint is id, and the custom mappings among addrs (the remote's known transport addresses). Without eviction the tables grow without bound under peer churn (the upstream Rust implementation has the same leak, iroh issue #4293). A mapping is regenerated on the next use of the same key, so evicting a remote that immediately returns only costs a fresh mapped address. IsClosed reports whether the socket has been closed. LookupCustom returns the custom address for a custom mapped address, if known. LookupEndpointID returns the endpoint id for an endpoint-id mapped address, if known. LookupRelay returns the (url, eid) pair for a relay mapped address, if known. PathAddr classifies a QUIC connection's remote net.Addr into the magic socket's transport [Addr]: a real IP becomes an IP path; a relay or custom mapped ULA is reverse-looked-up through the mapped-address tables. An unknown mapped address (or one whose mapping has been forgotten) falls back to an IP path so the per-remote actor still tracks a stable address. remoteID is used for relay paths, which are keyed by (relay url, endpoint id). RelayMappedAddrFor returns the relay mapped address for the (url, eid) pair, allocating one on first use. func NewSocket() *Socket func NewMagicConn(sock *Socket, udp *net.UDPConn) *MagicConn func NewMagicConnRelayOnly(sock *Socket, actor *RelayActor, custom ...CustomTransport) *MagicConn func NewMagicConnWithRelay(sock *Socket, udp *net.UDPConn, actor *RelayActor) *MagicConn func NewMagicConnWithTransports(sock *Socket, udp *net.UDPConn, actor *RelayActor, custom ...CustomTransport) *MagicConn func NewRelayTransport(sock *Socket, actor *RelayActor, recvCh chan<- recvBatch) *RelayTransport
TransportAddrInfo is a remote transport address plus usage metadata. Addr netaddr.TransportAddr Provenance string Usage TransportAddrUsage func (*RemotePathState).RemoteAddrs() []TransportAddrInfo
TransportAddrUsage reports whether a remote transport address is currently active. const TransportAddrActive const TransportAddrInactive
Transports multiplexes the magic socket's network paths: a direct-IP transport plus optional relay and custom transports. It is the Go analog of the Rust Transports struct (iroh/src/socket/transports.rs:47). The IP transport is nil for relay-only endpoints. The relay transport is present when the endpoint has relays configured; otherwise relay-addressed sends are blackholed (reported as success so quic-go's loss recovery retransmits). Custom transports are present only when callers configure them.
Package-Level Functions (total 24)
Classify reports which mapped kind addr belongs to, or KindIP if it is a real address. The order matches the Rust MultipathMappedAddr::from conversion.
CustomAddr returns an [Addr] for a custom-transport path.
CustomMappedAddrFromAddr wraps an existing custom mapped IPv6 address. It is used to reverse-look-up the custom address via [Socket.LookupCustom].
EndpointIDMappedAddrFromAddr wraps an existing endpoint-id mapped IPv6 address. It is used to reverse-look-up the endpoint id via [Socket.LookupEndpointID].
IPAddr returns an [Addr] for a direct IP path. The address is canonicalized so an IPv4-mapped IPv6 address becomes a plain IPv4 address, matching Rust's SocketAddr -> Addr conversion (iroh/src/socket/transports.rs:825).
Type Parameters: K: comparable V: comparable NewAddrMap returns an AddrMap whose missing keys are filled with gen(), keyed in reverse by addrOf(value).
NewCustomMappedAddr allocates a fresh custom mapped address.
NewEndpointIDMappedAddr allocates a fresh endpoint-id mapped address.
NewIpTransport returns an IpTransport over conn that delivers received datagrams to recvCh. The transport does not take ownership of conn; the caller closes it.
NewMagicConn returns a MagicConn whose sole transport is an [IpTransport] bound to udp. sock holds the mapped-address tables shared with the transports. Start the receive loop with [MagicConn.Serve] before handing the MagicConn to a quic-go Transport.
NewMagicConnRelayOnly returns a MagicConn with no direct-IP transport. Relay and custom transports are still available. Start the receive loops with [MagicConn.Serve].
NewMagicConnWithRelay returns a MagicConn with an IP transport over udp and, if actor is non-nil, a relay transport driven by it. Datagrams received from relays surface through [MagicConn.ReadFrom] as a [RelayMappedAddr]; sends to a relay mapped address route to the actor. Start the receive loops with [MagicConn.Serve].
NewMagicConnWithTransports returns a MagicConn with direct IP, optional relay, and optional custom transports.
NewPathWatcher returns an empty broadcast with no subscribers.
NewRelayActor returns a RelayActor ready to be started with [RelayActor.Run].
NewRelayMappedAddr allocates a fresh relay mapped address.
NewRelayTransport returns a RelayTransport that drives actor and delivers received relay datagrams to recvCh. sock supplies the relay mapped-address table shared with the [MagicConn]. The transport does not start the actor; call [RelayTransport.Serve].
NewRemoteMap returns a RemoteMap whose actors live until ctx is cancelled or they idle out. selector is the path selector shared by all actors (nil uses [BiasedRttPathSelector]); resolve is the address-lookup hook (nil disables lookup-driven resolution).
NewRemoteMapWithMetrics is like [NewRemoteMap], but records actor path lifecycle counters in metrics.
NewRemotePathState returns an empty path-state tracker.
NewSocket returns a ready Socket with empty mapped-address tables.
RelayAddr returns an [Addr] for a relay path reaching eid through url.
RelayMappedAddrFromAddr wraps an existing relay mapped IPv6 address. It is used to reverse-look-up the (relay, endpoint) pair an address maps to via [Socket.LookupRelay]; it does not allocate a new mapping.
SnapshotPerformanceStats returns zero counters in an ordinary build.
Package-Level Variables (only one)
ErrExtensionNotNegotiated is returned by hole-punching and other operations that depend on a QUIC extension that is not negotiated on an active connection. Endpoint defaults advertise qng multipath; QNT/DISCO hole-punching is still gated separately.
Package-Level Constants (total 32)
ActorMaxIdleTimeout is how long an actor with no connections stays alive before it exits and deregisters. remote_state.rs:74.
AddrCustom is a custom-transport path.
AddrIP is a direct IP address path.
AddrRelay is a relay path, identified by a relay URL and endpoint id.
GoodEnoughLatency is the RTT at or under which a direct path is considered good enough that the actor does not try to upgrade to a better path.
HeartbeatInterval is how often the actor wakes to keep paths alive and re-evaluate path selection. remote_state.rs HEARTBEAT_INTERVAL / socket.rs.
HolepunchAttemptsInterval throttles hole-punch attempts when the NAT candidate set has not changed. remote_state.rs:52.
IPv6RttAdvantage is how much lower an IPv6 path's biased RTT is made, expressing a default preference for IPv6 over IPv4.
KindCustom is a CustomMappedAddr.
KindEndpointID is an EndpointIDMappedAddr.
KindIP is a real (non-mapped) IP address.
KindRelay is a RelayMappedAddr.
MaxInactiveNonRelayPaths is the maximum number of inactive (previously open, now closed) non-relay paths kept per remote.
MaxNonRelayPaths is the maximum number of non-relay paths kept per remote.
PathBroadcastCapacity is the per-subscriber buffer capacity for path events. A subscriber that falls more than this many events behind is told how many it missed via a [PathEventLagged] event rather than silently dropping. It matches the Rust BROADCAST_CAPACITY (iroh/src/socket/remote_map/remote_state/path_watcher.rs:50).
PathEventClosed reports a closed network path.
PathEventLagged reports that events were dropped before a subscriber read them; Missed carries the count.
PathEventOpened reports a newly-opened network path.
PathEventSelected reports that a path was selected for transmission.
PathMaxIdleTimeout is the idle timeout for a non-relay path. iroh/src/socket.rs PATH_MAX_IDLE_TIMEOUT.
PathStatusInactive is a path that was open at some point but has since closed. The time records when it closed, used to prune oldest-first.
PathStatusOpen is a path that is currently open in QUIC.
PathStatusUnknown is a path that has never been dialed: it was added by an address-lookup mechanism and is only potentially usable.
PathStatusUnusable is a path where hole-punching was attempted and failed.
RelayConnected means the connection is established and handshaked.
RelayConnecting means the actor is dialing or handshaking.
RelayDisconnected means there is no connection: an attempt failed or a previously-established connection was lost.
RelayPathMaxIdleTimeout is the idle timeout for a relay path. iroh/src/socket.rs RELAY_PATH_MAX_IDLE_TIMEOUT.
RttSwitchingMin is the minimum biased-RTT improvement required to switch to a different path in the same tier. It prevents flapping under jitter.
TransportAddrActive means the address is currently used.
TransportAddrInactive means the address is known but not currently used.
UpgradeInterval is how often the actor tries to upgrade to a better path even when a working non-relay route exists. remote_state.rs:66.