// 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.
package socketimport ()// The mapped-address scheme. See iroh/src/socket/mapped_addrs.rs.const (// addrPrefixL is the first byte of every Unique Local Address (RFC 4193). addrPrefixL = 0xfd// mappedPort is the fixed dummy port for all mapped socket addresses; the // port plays no role in addressing. mappedPort = 12345)// addrGlobalID is n0's 40-bit ULA global id (bytes 1..6).var addrGlobalID = [5]byte{0x15, 0x07, 0x0a, 0x51, 0x0b}// Subnet ids (bytes 6..8) distinguish the mapped-address kinds.var ( subnetEndpointID = [2]byte{0x00, 0x00} // fd15:70a:510b::/64 subnetRelay = [2]byte{0x00, 0x01} // fd15:70a:510b:1::/64 subnetCustom = [2]byte{0x00, 0x03} // fd15:70a:510b:3::/64)// Per-kind counters; the low 8 bytes of each mapped address. They start at 1,// matching the Rust AtomicU64::new(1) (the first Add(1) yields 1).var ( endpointIDCounter atomic.Uint64 relayCounter atomic.Uint64 customCounter atomic.Uint64)// mappedAddr builds a mapped IPv6 address for the given subnet and counter.func mappedAddr( [2]byte, uint64) netip.Addr {var [16]byte [0] = addrPrefixLcopy([1:6], addrGlobalID[:])copy([6:8], [:])binary.BigEndian.PutUint64([8:16], )returnnetip.AddrFrom16()}// hasMappedPrefix reports whether addr is in n0's mapped ULA range with the// given subnet id.func hasMappedPrefix( netip.Addr, [2]byte) bool {if !.Is6() || .Is4In6() {returnfalse } := .As16()return [0] == addrPrefixL && [1] == addrGlobalID[0] && [2] == addrGlobalID[1] && [3] == addrGlobalID[2] && [4] == addrGlobalID[3] && [5] == addrGlobalID[4] && [6] == [0] && [7] == [1]}// 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.typeEndpointIDMappedAddrstruct{ a netip.Addr }// RelayMappedAddr addresses a remote endpoint via a specific relay path// (an (EndpointID, RelayURL) pair).typeRelayMappedAddrstruct{ a netip.Addr }// CustomMappedAddr addresses a remote endpoint via a custom transport path.typeCustomMappedAddrstruct{ a netip.Addr }// NewEndpointIDMappedAddr allocates a fresh endpoint-id mapped address.func () EndpointIDMappedAddr {returnEndpointIDMappedAddr{mappedAddr(subnetEndpointID, endpointIDCounter.Add(1))}}// NewRelayMappedAddr allocates a fresh relay mapped address.func () RelayMappedAddr {returnRelayMappedAddr{mappedAddr(subnetRelay, relayCounter.Add(1))}}// 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.func ( netip.Addr) RelayMappedAddr { returnRelayMappedAddr{a: } }// NewCustomMappedAddr allocates a fresh custom mapped address.func () CustomMappedAddr {returnCustomMappedAddr{mappedAddr(subnetCustom, customCounter.Add(1))}}// Addr returns the underlying IPv6 address.func ( EndpointIDMappedAddr) () netip.Addr { return .a }// EndpointIDMappedAddrFromAddr wraps an existing endpoint-id mapped IPv6// address. It is used to reverse-look-up the endpoint id via// [Socket.LookupEndpointID].func ( netip.Addr) EndpointIDMappedAddr {returnEndpointIDMappedAddr{a: }}// Addr returns the underlying IPv6 address.func ( RelayMappedAddr) () netip.Addr { return .a }// Addr returns the underlying IPv6 address.func ( CustomMappedAddr) () netip.Addr { return .a }// CustomMappedAddrFromAddr wraps an existing custom mapped IPv6 address. It is// used to reverse-look-up the custom address via [Socket.LookupCustom].func ( netip.Addr) CustomMappedAddr { returnCustomMappedAddr{a: } }// AddrPort returns the mapped address with the fixed dummy port, suitable for// handing to quic-go as a path's net.Addr.func ( EndpointIDMappedAddr) () netip.AddrPort { returnmappedAddrPort(.a) }// AddrPort returns the mapped address with the fixed dummy port.func ( RelayMappedAddr) () netip.AddrPort { returnmappedAddrPort(.a) }// AddrPort returns the mapped address with the fixed dummy port.func ( CustomMappedAddr) () netip.AddrPort { returnmappedAddrPort(.a) }func mappedAddrPort( netip.Addr) netip.AddrPort {returnnetip.AddrPortFrom(, mappedPort)}// MappedKind classifies a netip.Addr as one of the mapped kinds or a real IP.typeMappedKindintconst (// KindIP is a real (non-mapped) IP address.KindIPMappedKind = iota// KindEndpointID is an EndpointIDMappedAddr.KindEndpointID// KindRelay is a RelayMappedAddr.KindRelay// KindCustom is a CustomMappedAddr.KindCustom)// Classify reports which mapped kind addr belongs to, or KindIP if it is a real// address. The order matches the Rust MultipathMappedAddr::from conversion.func ( netip.Addr) MappedKind {switch {casehasMappedPrefix(, subnetEndpointID):returnKindEndpointIDcasehasMappedPrefix(, subnetRelay):returnKindRelaycasehasMappedPrefix(, subnetCustom):returnKindCustomdefault:returnKindIP }}// 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.typeAddrMap[ comparable, comparable] struct { gen func() addrOf func() netip.Addr mu sync.Mutex fwd map[] rev map[netip.Addr]}// NewAddrMap returns an AddrMap whose missing keys are filled with gen(), keyed// in reverse by addrOf(value).func [ comparable, comparable]( func() , func() netip.Addr) *AddrMap[, ] {return &AddrMap[, ]{gen: ,addrOf: ,fwd: make(map[]),rev: make(map[netip.Addr]), }}// Get returns the mapped address for key, generating and recording one if it// does not yet exist.func ( *AddrMap[, ]) ( ) { .mu.Lock()defer .mu.Unlock()if , := .fwd[]; {return } := .gen() .fwd[] = .rev[.addrOf()] = return}// Lookup returns the key that maps to addr, if any.func ( *AddrMap[, ]) ( netip.Addr) (, bool) { .mu.Lock()defer .mu.Unlock() , := .rev[]return , }// Remove deletes the mapping for key, if any. The next Get of the same key// generates a fresh mapped address.func ( *AddrMap[, ]) ( ) { .mu.Lock()defer .mu.Unlock() , := .fwd[]if ! {return }delete(.fwd, )delete(.rev, .addrOf())}// Len returns the number of mappings. Intended for tests and metrics.func ( *AddrMap[, ]) () int { .mu.Lock()defer .mu.Unlock()returnlen(.fwd)}
The pages are generated with Goldsv0.8.4. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.