import { type NetworkInterfaceInfo } from 'node:os'; /** * Default lease TTL: 1 hour. `@achingbrain/nat-port-mapper` takes the TTL in * milliseconds and floors the lease it asks the router for at 3600 s, so a * shorter value here would still lease an hour. */ export declare const DEFAULT_LEASE_TTL_MS: number; /** Default renewal cadence: half the TTL, so two renewals per lease. */ export declare const DEFAULT_REFRESH_MS: number; /** How long to listen for a UPnP gateway's SSDP answer before giving up. */ export declare const GATEWAY_DISCOVERY_TIMEOUT_MS = 10000; /** Bound on one SOAP call to the router (map, unmap, external IP). */ export declare const GATEWAY_OPERATION_TIMEOUT_MS = 10000; /** What `discover()` learned about the router. */ export interface GatewayInfo { /** This machine's address on the router's subnet — the address mappings point at. */ lanAddress: string; /** The router's own LAN address. */ routerHost: string; } export interface PortMapRequest { internalPort: number; protocol: 'tcp' | 'udp'; /** Lease TTL in milliseconds. */ ttlMs: number; } /** Result of a successful map(). */ export interface PortMapResult { /** The external port the router granted — may differ from the internal port. */ externalPort: number; leaseExpiresAt: Date; } /** * Wrapper around the UPnP client. An interface so tests inject a fake instead * of a router. */ export interface PortMapper { /** * Find the router. Resolves null when no gateway answered within the * discovery timeout; throws `NatError('router_unreachable')` when one did but * cannot be used (no local interface shares its subnet). */ discover(): Promise; /** * Ask the router to map `internalPort` to the same external port. The router * may grant another; the returned `externalPort` is the one that counts. * Throws `NatError('mapping_failed')` on refusal. */ map(req: PortMapRequest): Promise; /** Remove a mapping installed by this process. Never throws. */ unmap(internalPort: number, protocol: 'tcp' | 'udp'): Promise; /** The WAN address the router reports, or null when it cannot be asked. */ externalIp(): Promise; /** Release client resources. Does not unmap. Idempotent. */ stop(): Promise; } /** * Pick the IPv4 address of the local interface whose subnet contains the router. * * Not `mapAll`: that maps on every local address and leaves stray mappings for * VPN and container interfaces. The address returned is the one a user is told * to forward to, so it must be the one on the router's own network. */ export declare function pickLanAddress(routerHost: string, interfaces?: Record): string | null; /** * UPnP port mapper over `@achingbrain/nat-port-mapper` v4: `upnpNat()` hands * out a client that discovers gateways; mapping, unmapping and the external IP * live on the discovered `Gateway`. * * The library's auto-refresh stays off: cadre-host renews leases itself so it * can report lease expiry and per-mapping failures. */ export declare class UpnpPortMapper implements PortMapper { private readonly client; private gateway; private lanAddress; constructor(opts?: { description?: string; }); discover(): Promise; map(req: PortMapRequest): Promise; unmap(internalPort: number, _protocol: 'tcp' | 'udp'): Promise; externalIp(): Promise; /** * Forget the gateway. Deliberately not `gateway.stop()`: that deletes every * mapping this process made, and hosted children keep running across a host * restart, so their mappings must outlive this process. */ stop(): Promise; private requireGateway; /** * First IPv4 gateway to answer the SSDP search, or null when none did within * the timeout. * * NOTE: the library searches for `InternetGatewayDevice:2` only (its * `upnp/discovery.js`), and a router that implements only version 1 does not * answer a version-2 search, so such a router reads as "not found". There is * no library option for it; if it shows up on real hosts, the fix is a fork or * another library. */ private findIpv4Gateway; }