Help us shape the future of Go! Take the 2026 Go Developer Survey

peerconn

package
v0.0.162 Latest Latest
Warning

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

Go to latest
Published: Oct 16, 2026 License: Apache-2.0 Imports: 1 Imported by: 0

Documentation

Overview

Package peerconn exposes a process-wide listener registry for inbound connection lifecycle events across lantern-box protocols.

This is the hook the radiance peer client (Share My Connection) uses to emit per-connection accept/close events to the rest of the application — the globe visualization, abuse-detection aggregation, and metrics that need a stream rather than a snapshot. It deliberately sits outside any individual protocol package so the same listener fires for samizdat today and TLS-masq / algeneva / water as those inbounds gain peer-share support.

Why not adapter.ConnectionTracker? sing-box's tracker abstraction lives behind libbox's internal box.Router, with no public hook for callers constructing a libbox.BoxService to AppendTracker post-creation. A process-wide listener side-steps that: lantern-box inbound code calls Notify directly, the radiance peer client registers a listener before starting libbox.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Notify

func Notify(evt Event)

Notify dispatches a single event to the registered listener if one is set. No-op when nothing is registered — non-peer-share consumers (cmd_run, the standalone CLI, the radiance VPN client) pay zero cost beyond a mutex read. Lower-level entry exposed for future one-shot hooks (byte-counting conn wrappers, periodic flush emitters).

Callers emitting both halves of one connection's lifecycle must use Acquire instead, so the pair cannot be split across two listeners.

func SetListener

func SetListener(l Listener)

SetListener registers (or with a nil argument, unregisters) the global listener. Single-active: a second SetListener call replaces the first. Called from the radiance peer client at Start, cleared at Stop.

Types

type Event

type Event struct {
	State       int
	Source      string
	Destination string
	Rejected    bool
}

Event describes a single connection lifecycle transition surfaced from a lantern-box inbound to the peer-share consumer (radiance peer client).

State        +1 on accept, -1 on close
Source       remote peer's "ip:port" string (empty if unavailable)
Destination  the host:port the remote peer requested through the
             inbound. Always set on +1. Close events leave it empty,
             since the abuse aggregator already pairs each close with
             the prior accept by source identity, except when Rejected
             is set.
Rejected     on -1 only: the router refused the destination by a
             reject rule (the peer's allowlist or an abuse block), as
             opposed to the connection failing or ending normally.
             Destination is repeated so a consumer can tally refusals
             without keeping per-connection state.

Destination carries the load-bearing abuse-detection signal: source IP alone is insufficient (mobile clients change IPs, NAT pools collapse to one address) but the destination distribution per source bucket is highly diagnostic — one source making thousands of port-25 connections is a spam relay; one source making millions of HTTPS connections to a fixed e-commerce list is credential stuffing.

Bucket aggregation lives outside this package (see radiance/peer); the registry just hands raw events off to whoever's listening.

type Listener

type Listener func(evt Event)

Listener receives connection lifecycle notifications from lantern-box inbound protocols. Invoked synchronously on the inbound's accept/close path, so implementations should not block on heavy work — fan out to a buffered channel or goroutine if more than a few microseconds is expected.

func Acquire

func Acquire() Listener

Acquire returns the registered listener, or nil if none is set.

A connection emitting a matched accept/close pair must Acquire once and use the returned listener for both halves. Reading the registry twice lets a SetListener land in between, so the accept reaches one listener and the close reaches another: the first is left holding a connection that never closes, the second sees a close it never opened. Consumers keeping per-connection state — counts, open-connection maps, abuse buckets keyed on the accept — corrupt silently when that happens.

The tradeoff is that a pair already in flight completes against the listener that accepted it, so SetListener(nil) does not cancel the close half. Consumers needing a hard stop must gate inside their own callback.

Jump to

Keyboard shortcuts

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