udpmux

package
v0.83.1 Latest Latest
Warning

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

Go to latest
Published: Nov 13, 2026 License: BSD-3-Clause Imports: 19 Imported by: 0

Documentation

Overview

Package udpmux provides a custom implementation of a UDP multiplexer that allows multiple logical ICE connections to share a single underlying UDP socket. This is based on Pion's ICE library, with modifications for NetBird's requirements.

Background

In WebRTC and NAT traversal scenarios, ICE (Interactive Connectivity Establishment) is responsible for discovering candidate network paths and maintaining connectivity between peers. Each ICE connection normally requires a dedicated UDP socket. However, using one socket per candidate can be inefficient and difficult to manage.

This package introduces SingleSocketUDPMux, which allows multiple ICE candidate connections (muxed connections) to share a single UDP socket. It handles demultiplexing of packets based on ICE ufrag values, STUN attributes, and candidate IDs.

Usage

The typical flow is:

  1. Create a UDP socket (net.PacketConn).
  2. Construct Params with the socket and optional logger/net stack.
  3. Call NewSingleSocketUDPMux(params).
  4. For each ICE candidate ufrag, call GetConn(ufrag, addr, candidateID) to obtain a logical PacketConn.
  5. Use the returned PacketConn just like a normal UDP connection.

STUN Message Routing Logic

	When a STUN packet arrives, the mux decides which connection should
	receive it using this routing logic:

	Primary Routing: Candidate Pair ID
	  - Extract the candidate pair ID from the STUN message using
	    ice.CandidatePairIDFromSTUN(msg)
   - The target candidate is the locally generated candidate that
     corresponds to the connection that should handle this STUN message
	  - If found, use the target candidate ID to lookup the specific
	    connection in candidateConnMap
	  - Route the message directly to that connection

	Fallback Routing: Broadcasting
	  When candidate pair ID is not available or lookup fails:
	  - Collect connections from addressMap based on source address
	  - Find connection using username attribute (ufrag) from STUN message
	  - Remove duplicate connections from the list
	  - Send the STUN message to all collected connections

Peer Reflexive Candidate Discovery

When a remote peer sends a STUN message from an unknown source address
(from a candidate that has not been exchanged via signal), the ICE
library will:
  - Generate a new peer reflexive candidate for this source address
  - Extract or assign a candidate ID based on the STUN message attributes
  - Create a mapping between the new peer reflexive candidate ID and
    the appropriate local connection

This discovery mechanism ensures that STUN messages from newly discovered
peer reflexive candidates can be properly routed to the correct local
connection without requiring fallback broadcasting.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Params

type Params struct {
	Logger  logging.LeveledLogger
	UDPConn net.PacketConn

	// Required for gathering local addresses
	// in case a un UDPConn is passed which does not
	// bind to a specific local address.
	Net             transport.Net
	InterfaceFilter func(interfaceName string) bool
}

Params are parameters for UDPMux.

type SingleSocketUDPMux

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

SingleSocketUDPMux is an implementation of the interface

func NewSingleSocketUDPMux

func NewSingleSocketUDPMux(params Params) *SingleSocketUDPMux

NewSingleSocketUDPMux creates an implementation of UDPMux

func (*SingleSocketUDPMux) Close

func (m *SingleSocketUDPMux) Close() error

Close the mux, no further connections could be created

func (*SingleSocketUDPMux) GetConn

func (m *SingleSocketUDPMux) GetConn(ufrag string, addr net.Addr, candidateID string) (net.PacketConn, error)

GetConn returns a PacketConn given the connection's ufrag and network address creates the connection if an existing one can't be found

func (*SingleSocketUDPMux) GetListenAddresses

func (m *SingleSocketUDPMux) GetListenAddresses() []net.Addr

GetListenAddresses returns the list of addresses that this mux is listening on

func (*SingleSocketUDPMux) HandleSTUNMessage

func (m *SingleSocketUDPMux) HandleSTUNMessage(msg *stun.Message, addr net.Addr) error

HandleSTUNMessage handles STUN packets and forwards them to underlying pion/ice library

func (*SingleSocketUDPMux) IsClosed

func (m *SingleSocketUDPMux) IsClosed() bool

IsClosed returns true if the mux had been closed

func (*SingleSocketUDPMux) LocalAddr

func (m *SingleSocketUDPMux) LocalAddr() net.Addr

LocalAddr returns the listening address of this SingleSocketUDPMux

func (*SingleSocketUDPMux) RemoveConnByUfrag

func (m *SingleSocketUDPMux) RemoveConnByUfrag(ufrag string)

RemoveConnByUfrag stops and removes the muxed packet connection

type UDPConn

type UDPConn struct {
	net.PacketConn
	// contains filtered or unexported fields
}

UDPConn is a wrapper around UDPMux conn that overrides WriteTo to drop packets destined for the overlay subnet.

func (*UDPConn) GetPacketConn

func (u *UDPConn) GetPacketConn() net.PacketConn

GetPacketConn returns the underlying PacketConn

func (*UDPConn) WriteTo

func (u *UDPConn) WriteTo(b []byte, addr net.Addr) (int, error)

type UniversalUDPMuxDefault

type UniversalUDPMuxDefault struct {
	*SingleSocketUDPMux
	// contains filtered or unexported fields
}

UniversalUDPMuxDefault handles STUN and TURN servers packets by wrapping the original UDPConn It then passes packets to the UDPMux that does the actual connection muxing.

func NewUniversalUDPMuxDefault

func NewUniversalUDPMuxDefault(params UniversalUDPMuxParams) *UniversalUDPMuxDefault

NewUniversalUDPMuxDefault creates an implementation of UniversalUDPMux embedding UDPMux

func (*UniversalUDPMuxDefault) GetConnForURL

func (m *UniversalUDPMuxDefault) GetConnForURL(ufrag string, url string, addr net.Addr, candidateID string) (net.PacketConn, error)

GetConnForURL add uniques to the muxed connection by concatenating ufrag and URL (e.g. STUN URL) to be able to support multiple STUN/TURN servers and return a unique connection per server.

func (*UniversalUDPMuxDefault) GetListenAddresses

func (m *UniversalUDPMuxDefault) GetListenAddresses() []net.Addr

GetListenAddresses returns the listen addr of this UDP

func (*UniversalUDPMuxDefault) GetRelayedAddr

func (m *UniversalUDPMuxDefault) GetRelayedAddr(turnAddr net.Addr, deadline time.Duration) (*net.Addr, error)

GetRelayedAddr creates relayed connection to the given TURN service and returns the relayed addr. Not implemented yet.

func (*UniversalUDPMuxDefault) GetSharedConn

func (m *UniversalUDPMuxDefault) GetSharedConn() net.PacketConn

GetSharedConn returns the shared udp conn

func (*UniversalUDPMuxDefault) GetXORMappedAddr

func (m *UniversalUDPMuxDefault) GetXORMappedAddr(serverAddr net.Addr, deadline time.Duration) (*stun.XORMappedAddress, error)

GetXORMappedAddr returns *stun.XORMappedAddress if already present for a given STUN server. Makes a STUN binding request to discover mapped address otherwise. Blocks until the stun.XORMappedAddress has been discovered or deadline. Method is safe for concurrent use.

func (*UniversalUDPMuxDefault) HandleSTUNMessage

func (m *UniversalUDPMuxDefault) HandleSTUNMessage(msg *stun.Message, addr net.Addr) error

HandleSTUNMessage discovers STUN packets that carry a XOR mapped address from a STUN server. All other STUN packets will be forwarded to the UDPMux

func (*UniversalUDPMuxDefault) ReadFromConn

func (m *UniversalUDPMuxDefault) ReadFromConn(ctx context.Context)

ReadFromConn reads from the m.params.UDPConn provided upon the creation. It expects STUN packets only, however, will just ignore other packets printing an warning message. It is a blocking method, consider running in a go routine.

type UniversalUDPMuxParams

type UniversalUDPMuxParams struct {
	Logger                logging.LeveledLogger
	UDPConn               net.PacketConn
	XORMappedAddrCacheTTL time.Duration
	Net                   transport.Net
	WGAddress             wgaddr.Address
	MTU                   uint16
}

UniversalUDPMuxParams are parameters for UniversalUDPMux server reflexive.

Jump to

Keyboard shortcuts

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