reticulum-js
    Preparing search index...

    Reticulum interface that listens for inbound WebSocket connections.

    Each accepted connection spawns a WebSocketClientInterface (adopting the accepted socket), announced via a connection event so the transport can register it. Like TCPServerInterface, the server itself never carries packets — its readable/writable accessors throw.

    Hierarchy

    • Interface
      • WebSocketServerInterface
    Index
    _closed: boolean

    Whether a terminal closed event has already been dispatched for the current connection episode (dedupe guard).

    _packetWriter: WritableStreamDefaultWriter<any> | null
    _reconnectAbort: AbortController | null

    AbortController for the current reconnect wait, so disconnect() can cancel an in-flight backoff immediately.

    _reconnectAttempts: number

    Reconnect attempt counter for the current drop episode. Reset to 0 at the start of each Interface._runReconnectLoop run.

    _reconnecting: boolean

    Single-flight guard: only one reconnect loop runs at a time.

    announceBurstCount: number

    Times an announce burst has latched on this interface.

    arFreqDecay: number
    autoconfigureMtu: boolean

    Whether the hardware MTU is autoconfigured from the nominal bitrate by optimiseMtu (matching the Python reference's AUTOCONFIGURE_MTU). Off on the base class; transport-grade interfaces (Local, TCP, Backbone) opt in.

    autoReconnect: boolean

    Whether automatic reconnection is enabled for this initiator interface.

    bitrate: number

    Nominal physical bitrate of this interface in bits per second (default 62500). Each interface overrides this with its medium's rate.

    Used by TransportCore.prioritizeInterfaces() to order the interface set highest-bitrate-first; the per-bitrate link-timeout and announce-rate-limit behaviours that also build on it are tracked as Phase 2 of work doc #20. Configured bitrates below Reticulum.MINIMUM_BITRATE are ignored.

    certFile: string | null

    Path to a PEM certificate chain.

    connectTimeout: number

    Per-dial connect timeout in seconds.

    created: number

    Epoch milliseconds when the interface was constructed.

    DEFAULT_IFAC_SIZE: number

    Per-interface default IFAC size (bytes) when IFAC is enabled but no explicit ifacSize was given. Subclasses override (16 for Auto/Backbone, 8 for AX.25 in the reference implementations); the base default of 16 matches the common case.

    detached: boolean

    Permanent stop signal read by the reconnect loop. Set by disconnect().

    framing: "raw" | "kiss"
    gravity: number | null

    Per-interface path preference weight (default 0 via Reticulum.defaultGravity). When the same announce reaches this node over multiple interfaces, the path table prefers the entry learned via the higher-gravity interface (e.g. a wired backbone over a slow radio link). null means "no preference" — import("../core/reticulum.js").Reticulum substitutes its defaultGravity at addInterface time.

    heldAnnounceDrops: number

    Announces dropped (not held) because the held table was at its cap.

    heldAnnounceReleases: number

    Held announces released back into the inbound pipeline.

    heldAnnounces: Map<string, Packet>

    Announces held while an ingress burst is latched, keyed by destination hash hex. Drained by processHeldAnnounces on the transport sweep.

    hwMtu: number | null

    The hardware MTU of this interface in bytes — the largest frame the medium can carry in one piece (HW_MTU in the reference implementations; None/null means unbounded/unknown).

    Unlike the Python reference (a class-level constant re-optimised per instance), this is an instance field set by optimiseMtu or the subclass constructor; interfaces with a fixed medium MTU initialize it directly (e.g. RNode's 508).

    iaFreqDeque: number[]

    Incoming-announce timestamp ring (seconds).

    icBurstActivated: number
    icBurstActive: boolean
    icBurstFreq: number
    icBurstFreqNew: number
    icBurstHold: number
    icBurstPenalty: number
    icHeldRelease: number

    Earliest held-announce release time (seconds); set on burst activation.

    icHeldReleaseInterval: number
    icMaxHeldAnnounces: number
    icNewTime: number
    icPrBurstActivated: number
    icPrBurstActive: boolean
    icPrBurstCooldown: number

    Remaining quiet evaluations before a latched PR burst unlatches.

    icPrBurstFreq: number
    icPrBurstFreqNew: number
    ifacIdentity: Identity | null

    Derived IFAC Ed25519 identity (only its signing ability is used). Populated lazily by _ensureIfacMaterial; null while IFAC is disabled or before first use.

    ifacKey: Uint8Array<ArrayBufferLike> | null

    Derived 64-byte IFAC key (HKDF over import("../core/ifac.js").IFAC_SALT).

    ifacNetkey: string | null

    Shared passphrase enabling IFAC (ifac_netkey). See ifacNetname.

    ifacNetname: string | null

    Shared network name enabling IFAC (ifac_netname). When set together with ifacNetkey (or alone), packets on this interface are authenticated and obfuscated. Both endpoints must share the same value.

    ifacSignature: Uint8Array<ArrayBufferLike> | null

    IFAC signature of fullHash(ifacKey), published in the discovery announce.

    ifacSize: number

    IFAC field size in bytes. When a network name / passphrase is set this auto-defaults to DEFAULT_IFAC_SIZE; 0 with no shared secret disables IFAC entirely.

    ifacViolations: number

    IFAC-specific violations: missing/invalid/short IFAC fields.

    ingressControl: boolean

    Whether ingress burst control is enabled on this interface. Disabling makes shouldIngressLimit and shouldIngressLimitPr always return false.

    initiator: boolean

    Whether this interface is the initiator (the outbound dialer). Only initiators reconnect; adopted/server-spawned sockets never do.

    ipFreqDeque: number[]

    Incoming path-request timestamp ring (seconds).

    keyFile: string | null

    Path to a PEM private key.

    listenIp: string
    listenPort: number
    maxReconnectTries: number

    Maximum reconnection attempts per drop. Infinity retries forever.

    name: string
    oaFreqDeque: number[]

    Outgoing-announce timestamp ring (seconds).

    online: boolean

    Whether the interface is currently open/online.

    opFreqDeque: number[]

    Outgoing path-request timestamp ring (seconds).

    packetFilterHits: number

    Inbound packet-filter (dedup) hits.

    prBurstCount: number

    Times a path? burst has latched on this interface.

    prBurstDrops: number

    Unique-tag path requests dropped while a PR burst was latched.

    prFreqDecay: number
    protocolViolations: number

    Generic protocol violations: malformed packets, bad signatures, etc.

    reconnectWait: number

    Seconds to wait between reconnection attempts.

    rxb: number

    Total bytes received on this interface. Counted as the deserialized RNS packet length, so it reflects the on-the-wire RNS payload, not framing overhead. Apps derive a transfer rate by sampling this counter over time.

    server: WebSocketServer | null
    socket: Socket | null

    The underlying socket, when this interface is backed by a Node.js stream.

    spawnedInterfaces: Set<WebSocketClientInterface>
    ssl: boolean

    Terminate TLS (wss://).

    tlsServer: Server<typeof IncomingMessage, typeof ServerResponse> | null

    The underlying HTTPS server we create when terminating TLS ourselves. null in the plain ws:// case (where ws owns the HTTP server).

    txb: number

    Total bytes transmitted on this interface.

    ANNOUNCE_FREQ_DECAY: number

    Seconds after which an unanswered announce sample decays out of the deque (AR_FREQ_DECAY = 1/AR_MINFREQ_HZ = 10 s).

    FREQ_SAMPLES: number

    Rolling-sample cap for the announce/PR frequency deques (48 samples, shared across announce and PR tracking).

    IC_BURST_FREQ: number

    Announce burst threshold for established interfaces, Hz (IC_BURST_FREQ).

    IC_BURST_FREQ_NEW: number

    Announce burst threshold for new interfaces, Hz (IC_BURST_FREQ_NEW).

    IC_BURST_HOLD_SECS: number

    Seconds a burst stays latched after activation (IC_BURST_HOLD_SECS).

    IC_BURST_PENALTY_SECS: number

    Seconds before held announces may release after a burst (IC_BURST_PENALTY_SECS).

    IC_DEQUE_MIN_SAMPLE: number

    Minimum deque samples before a frequency is reported (IC_DEQUE_MIN_SAMPLE = 2 — i.e. > 2 samples).

    IC_HELD_RELEASE_INTERVAL_SECS: number

    Seconds between held-announce releases once draining (IC_HELD_RELEASE_INTERVAL_SECS).

    IC_NEW_TIME_SECS: number

    Interface age in seconds below which the stricter "new interface" burst thresholds apply (IC_NEW_TIME_SECS = 2 h).

    IC_PR_BURST_COOLDOWN_SECS: number

    Quiet evaluations required to unlatch a PR burst after the hold (ic_pr_burst_cooldown = 3; any above-threshold evaluation resets it). Anti-flapping hysteresis added upstream in "Improved PR ingress limiter" — the announce limiter has no cooldown.

    IC_PR_BURST_FREQ: number

    Path-request burst threshold for established interfaces, Hz (IC_PR_BURST_FREQ).

    IC_PR_BURST_FREQ_NEW: number

    Path-request burst threshold for new interfaces, Hz (IC_PR_BURST_FREQ_NEW).

    MAX_HELD_ANNOUNCES: number

    Maximum held announces buffered per interface while an announce burst is latched (MAX_HELD_ANNOUNCES). A held table at this size silently drops further announces for destinations not already held.

    PR_FREQ_DECAY: number

    Seconds after which a PR sample decays (PR_FREQ_DECAY = 10 s).

    • get ifacEnabled(): boolean

      Whether IFAC is enabled on this interface (a shared secret is configured).

      Returns boolean

    • Protected

      Signals the reconnect loop to stop and cancels any in-flight backoff. Client subclasses call this at the top of their disconnect().

      Returns void

    • Protected

      Dispatches a terminal closed event exactly once per connection episode.

      Returns void

    • Protected

      Counts an inbound packet against rxb and dispatches the "packet" event, the single inbound chokepoint each interface's read loop funnels through.

      Uses the deserialized packet's cached raw bytes when available (set by Packet.deserialize), avoiding a re-serialize. RNodeInterface dispatches its own packets (it counts the IFAC-inclusive payload) and does not call this.

      Parameters

      • packet: Packet

      Returns void

    • Protected

      Derives and caches the IFAC key/identity/signature from the configured ifacNetname / ifacNetkey. No-op (resolves false) when IFAC is disabled. Memoised so the HKDF + Ed25519 key load runs at most once.

      Returns Promise<boolean>

      true if IFAC material is available.

    • Protected

      Dials the peer and sets up the RNS streams, resolving once connected and dispatching connected. Implemented by reconnect-capable client subclasses; used both for the initial connection and each reconnect attempt by the shared Interface._runReconnectLoop.

      Returns Promise<void>

    • Protected

      Called when the underlying connection drops (the inbound stream ends or errors). For an initiator with auto-reconnect enabled and not deliberately detached, dispatches disconnected and kicks off the reconnect loop; otherwise dispatches a terminal closed event — matching the Python reference, which reconnects the initiator on any termination and tears down (non-reconnecting) everyone else.

      Returns void

    • Protected

      Initializes shared reconnect state from constructor options. Called by client interface subclasses (TCP, WebSocket) that support reconnection.

      Subclasses must also set Interface.initiator: true for an outbound dialer, false for an adopted/server-spawned socket.

      Parameters

      • options: ReconnectOptions

      Returns void

    • Protected

      Verifies and unseals inbound raw wire bytes.

      Enforces the flag-presence rules: an IFAC-enabled interface drops a flag-clear packet, and a plain interface drops a flag-set packet — both return null (silent drop). For an IFAC interface it then unmasks, strips the IFAC and verifies it by re-signing; a mismatch also yields null. Subclasses/interfaces call this at the chokepoint where a frame has been unframed to bytes, just before Packet.deserialize.

      Parameters

      • raw: Uint8Array

        Sealed or plain wire bytes straight off the medium.

      Returns Promise<Uint8Array<ArrayBufferLike> | null>

      The unsealed bytes, or null to drop.

    • Protected

      Records an outbound packet against txb. Subclasses (or the interface's outbound stream write callback) call this at the point a packet is handed to the medium — the single chokepoint where every transmitted packet passes, whether sent via send, the transport router, or a broadcast.

      RNodeInterface overrides its own counting (it measures the IFAC-inclusive wire payload) and does not call this.

      Parameters

      • packet: Packet

      Returns void

    • Protected

      Runs the single-flight reconnect loop. Repeatedly waits reconnectWait seconds then attempts to re-establish the connection via the subclass _establishConnection() hook, until it succeeds, the interface is detached, or maxReconnectTries is exceeded (terminal closed).

      Each attempt fires a reconnecting event with the upcoming attempt number, the wait, and the cap, for observability. A successful reconnect fires connected (via _establishConnection).

      Returns Promise<void>

    • Protected

      Seals raw (un-IFACed) wire bytes for transmit. No-op passthrough when IFAC is disabled; otherwise derives the IFAC material on first use, then signs, sets the ifac_flag, inserts the IFAC field and XOR-masks the packet. Subclasses/interfaces call this at the chokepoint where a packet is serialised to bytes, just before framing.

      Parameters

      • raw: Uint8Array

        Serialised, unsealed wire bytes.

      Returns Promise<Uint8Array<ArrayBufferLike>>

      The bytes to put on the medium.

    • Protected

      Resolves after ms, or immediately if signal aborts. Used so disconnect() can cancel an in-flight reconnect backoff at once.

      Parameters

      • ms: number
      • signal: AbortSignal

      Returns Promise<void>

    • The addEventListener() method of the EventTarget interface sets up a function that will be called whenever the specified event is delivered to the target.

      MDN Reference

      Parameters

      • type: string
      • callback: EventListenerOrEventListenerObject | null
      • Optionaloptions: boolean | AddEventListenerOptions

      Returns void

    • Age of this interface in seconds.

      Returns number

    • Applies node-global ingress-control overrides to this interface (the reference implementations apply node-level ic_* defaults to every interface — there is no per-interface config for these). Only keys present in overrides are assigned; absent keys keep the class constants. Called by import("../core/reticulum.js").Reticulum#addInterface when the node was constructed with an ingressControl config block. These are deliberately not constructor options / interface schema properties: they scope to the whole node.

      Parameters

      • overrides: Partial<IngressControlConfig>

      Returns void

    • Optional hook invoked by import("../transport/transport.js").TransportCore#addInterface with the transport that owns this interface, right after the interface is attached.

      The base implementation is a no-op. Interfaces that spawn sub-interfaces dynamically — notably AutoInterface, which discovers peers and spawns one per peer — override it to remember the transport so the spawned peers can be auto-registered without a separate Reticulum global (the reference implementations use their global Transport registry for this).

      Overriders should also register any peers spawned before the transport was attached, so the addInterface/connect call order doesn't matter.

      Parameters

      • _transport: TransportCore

      Returns void

    • The dispatchEvent() method of the EventTarget sends an Event to the object, (synchronously) invoking the affected event listeners in the appropriate order. The normal event processing rules (including the capturing and optional bubbling phase) also apply to events dispatched manually with dispatchEvent().

      MDN Reference

      Parameters

      • event: Event

      Returns boolean

    • Returns a snapshot of traffic and link statistics for this interface, for observability and UIs.

      Subclasses that carry medium-specific telemetry (notably import("./rnode.js").RNodeInterface, which exposes RNode airtime, channel load and signal quality) override this to extend the snapshot.

      Returns InterfaceStats

    • Buffers an announce for delayed processing while an ingress burst is latched. Announces at or beyond PATHFINDER_M - 1 (127) hops are dropped rather than held; a destination already in the table always replaces its entry (newest emission wins); beyond icMaxHeldAnnounces distinct destinations, new ones are silently dropped.

      Parameters

      • packet: Packet

        Validated announce.

      Returns void

    • Records an IFAC (interface authentication code) violation on this interface: missing IFAC flag, insufficient packet size for the IFAC field, or an IFAC that fails re-verification. Increments ifacViolations, logs at DEBUG, returns null.

      Parameters

      • Optionaldescription: string | null

      Returns null

    • Incoming announce rate in Hz over the current sample window. Returns 0 with fewer than Interface.IC_DEQUE_MIN_SAMPLE+1 samples; a sample older than arFreqDecay decays out of the window.

      Returns number

    • Incoming path? request rate in Hz. Same sampling rules as incomingAnnounceFrequency, with the PR decay window.

      Returns number

    • Autoconfigures hwMtu from the nominal bitrate when autoconfigureMtu is set, using the reference implementations' bitrate→MTU table (faster media amortize framing overhead over larger frames). With autoconfiguration off this is a no-op — a subclass that set a fixed hwMtu keeps it.

      Called by interface constructors and by the node setup once the configured bitrate is known (the Python reference calls optimise_mtu() from Reticulum._add_interface and per-connection spawn sites).

      Returns void

    • Outgoing announce rate in Hz. Needs more than one sample.

      Returns number

    • Outgoing path? request rate in Hz. Needs more than one sample.

      Returns number

    • Records a packet-filter (dedup) hit on this interface: an inbound non-announce packet whose hash is already in the dedup ring. Increments packetFilterHits, returns null.

      Returns null

    • Releases one held announce if conditions allow: at most one announce per icHeldReleaseInterval, never before icHeldRelease, and only while the incoming announce frequency is back below the burst threshold. Selection prefers the lowest hop count (nearest destinations converge first). The caller re-injects the returned packet into the normal inbound pipeline.

      Returns Packet | null

      The announce to re-inject, or null when nothing is releasable.

    • Records a generic protocol violation on this interface: malformed packets, invalid announce signatures, tagless / oversized path requests, undecodable MTU signalling, inbound processing exceptions. Increments protocolViolations, logs at DEBUG, and returns null so it chains as the return value at every drop site.

      Parameters

      • Optionaldescription: string | null

        Optional human-readable detail.

      Returns null

    • Records an inbound announce into iaFreqDeque. Spawned interfaces propagate the sample to their parent so bursts are detected at the medium level.

      Parameters

      • OptionalfromSpawned: boolean

        Internal: true when called on a parent.

      Returns void

    • Records an inbound path? request into ipFreqDeque. Spawned interfaces propagate to their parent.

      Parameters

      • OptionalfromSpawned: boolean

        Internal: true when called on a parent.

      Returns void

    • The removeEventListener() method of the EventTarget interface removes an event listener previously registered with EventTarget.addEventListener() from the target. The event listener to be removed is identified using a combination of the event type, the event listener function itself, and various optional options that may affect the matching process; see Matching event listeners for removal.

      MDN Reference

      Parameters

      • type: string
      • callback: EventListenerOrEventListenerObject | null
      • Optionaloptions: boolean | EventListenerOptions

      Returns void

    • Sends bytes wrapped in KISS framing

      Parameters

      • packet: Packet

      Returns Promise<void>

    • Records an outbound announce into oaFreqDeque; counted by TransportCore.broadcast at the transmit chokepoint, and surfaced as outgoingAnnounceFrequency for the future announce-rate-table work (#31 step 6).

      Parameters

      • OptionalfromSpawned: boolean

        Internal: true when called on a parent.

      Returns void

    • Records an outbound path? request into opFreqDeque; consumed by egress PR limiting (work doc #31 step 4).

      Parameters

      • OptionalfromSpawned: boolean

        Internal: true when called on a parent.

      Returns void

    • Whether announce ingress should be limited right now. Latches a burst when the incoming announce frequency exceeds the threshold for the interface's age — stricter (icBurstFreqNew) during the first icNewTime seconds. Once latched, stays limiting for at least icBurstHold seconds and until the frequency drops back below the threshold; the call that unlatches still reports true (mirroring the Python reference: the next packet after it flows normally).

      Consumers: held-announce buffering for unknown destinations (work doc #31 step 3). The announce frequency side effects (latching plus arming icHeldRelease with the icBurstPenalty) keep the state correct when the announce-rate-table work lands.

      Returns boolean

    • Whether path? request ingress should be limited right now (including cooldown hysteresis). Latches when the incoming PR frequency exceeds the age-dependent threshold (icPrBurstFreqNew during the first icNewTime seconds, icPrBurstFreq after). Once latched, stays limiting for at least icBurstHold seconds; after the hold, unlatching takes Interface.IC_PR_BURST_COOLDOWN_SECS+1 consecutive below-threshold evaluations — any above-threshold evaluation resets the cooldown (anti-flapping at the boundary). Consumers: TransportCore drops unique-tag path requests while a burst is latched (work doc #31 step 2 — the inline-processing equivalent of an ingress-limited traffic-class demotion).

      Returns boolean

    • Returns the JSON Schema describing the constructor options.

      Returns Record<string, any>