probe

package
v0.1.4 Latest Latest
Warning

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

Go to latest
Published: May 11, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package probe runs STUN Binding requests against one or more servers and captures mapping behavior (mapped endpoint, RTT, errors).

Index

Constants

This section is empty.

Variables

View Source
var ErrFilteringNotSupported = errors.New("server did not advertise OTHER-ADDRESS")

ErrFilteringNotSupported is returned in FilteringResult.Err when the target server's BindingResponse does not include an OTHER-ADDRESS attribute, so the §4.4 sequence cannot be attempted.

View Source
var ErrTest1Failed = errors.New("initial probe failed; cannot run §4.4 sequence")

ErrTest1Failed wraps the underlying transport / parse error from the initial Binding probe. The §4.4 sequence is skipped when this error is returned.

Functions

This section is empty.

Types

type FilteringResult added in v0.1.2

type FilteringResult struct {
	Server        Server
	Test1Mapped   netip.AddrPort
	Test1Other    netip.AddrPort
	Test2Received bool
	Test3Received bool
	Err           error
}

FilteringResult captures the outcome of an RFC 5780 §4.4 three-step filtering classification. Test1Other.IsValid() == false means the server did not advertise OTHER-ADDRESS; in that case Test2Received and Test3Received are both false and Err wraps ErrFilteringNotSupported.

Server is the target of the §4.4 sequence (echoed from the ProbeFiltering argument so consumers can attribute the result without re-threading state).

func ProbeFiltering added in v0.1.2

func ProbeFiltering(ctx context.Context, server Server, timeout time.Duration) FilteringResult

ProbeFiltering runs RFC 5780 §4.4 against server. Uses one unconnected UDP socket for all three tests so (a) the NAT mapping stays stable across tests and (b) the socket can receive responses from the server's alt-IP/alt-port sources (a connected UDP socket would filter those out). Tests 2/3 are one-shot; "no response within timeout/2" is the verdict, not an error.

ctx governs the initial address resolution only; once resolution completes, per-test SetReadDeadline timers (timeout/2 each) drive the rest. Cancelling ctx mid-call has no effect on in-flight reads.

type HairpinningResult added in v0.1.4

type HairpinningResult struct {
	Server   Server
	Detected *bool
	Err      error
}

HairpinningResult captures the outcome of an RFC 5780 §4.3 hairpinning detection probe. Detected is tri-state:

  • nil: probe could not run end-to-end (socket allocation, DNS, or per-socket STUN probe failed); Err describes the underlying cause. Callers should emit WarnHairpinUntested at the classifier layer.
  • &true: tagged loopback packet arrived on socket B; the NAT supports hairpinning for the (A→mB) path.
  • &false: listen window elapsed with no tagged packet; either no hairpinning or a per-NAT filtering rule suppressed the loopback (spec-acknowledged false-negative case, see docs/design.md §4.3).

Server echoes the input so consumers can attribute the result without re-threading state, mirroring FilteringResult.

func ProbeHairpinning added in v0.1.4

func ProbeHairpinning(ctx context.Context, server Server, timeout time.Duration) HairpinningResult

ProbeHairpinning detects NAT hairpinning using two local UDP sockets:

  1. Allocate sockets A and B, unconnected, address family inherited from the resolved server IP.
  2. STUN-probe each socket in parallel against `server` to learn mapped endpoints mA and mB. Single-shot per probe — no retries. The wall-clock budget below depends on this.
  3. Send a 16-byte random nonce from A to mB.
  4. Listen on B for the nonce. Timeout: T_hairpin (= `timeout`).

Wall-clock budget: STUN phase (parallel) caps at min(timeout/2, 500ms); listen phase consumes up to `timeout`. Total ≤ 1.5 × timeout in the worst case. The caller orchestrates this in parallel with mapping probes; the non-functional target at docs/design.md:303 (<2s cold-start) is preserved for timeout ≤ 1s.

type Prober

type Prober interface {
	Probe(ctx context.Context, s Server) Result
}

Prober performs one STUN Binding probe per call. Implementations must not panic on bad input and must respect context cancellation.

func NewSTUN

func NewSTUN() Prober

NewSTUN returns a Prober backed by pion/stun over UDP. A fresh UDP socket is opened per probe.

type Result

type Result struct {
	Server Server
	Mapped netip.AddrPort
	Other  netip.AddrPort
	RTT    time.Duration
	Err    error
}

Result captures the outcome of a single probe. On success, Mapped and RTT are set and Err is nil. On failure, Err is non-nil and Mapped/RTT are zero.

Other carries the OTHER-ADDRESS attribute (RFC 5780 §7.4) when the server advertised one. Zero-value (Other.IsValid() == false) means the server's response did not include OTHER-ADDRESS, so it does not support the §4.4 filtering classification sequence.

type Server

type Server struct {
	Host string
	Port int
}

Server identifies a STUN server to probe.

Jump to

Keyboard shortcuts

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