import { type RemoteInfo } from "node:dgram"; import { EventEmitter } from "node:events"; export type UdpDatagram = { data: Buffer; remote: RemoteInfo; }; export type UdpTransportOptions = { host?: string; port?: number; }; /** * A consumer that wants first dibs on inbound datagrams that look like * STUN/TURN (RFC 5389 magic cookie at offset 4). ICE agents and TURN * clients register here so net_crypto/DHT never sees their control * packets, and so TURN DATA-INDICATIONs get unwrapped before the inner * app packet is re-emitted as a normal datagram. * * Return true if the datagram was consumed (stop further dispatch). */ export type StunInterceptor = (data: Buffer, remote: RemoteInfo) => boolean; /** * A TURN route: outbound datagrams addressed to `${host}:${port}` are * handed to `send` instead of going out the raw socket. Used to tunnel * net_crypto traffic through a TURN relay transparently — net_crypto * sets session.remote to the peer's relay address and is none the wiser. */ export type TurnRoute = { send: (data: Buffer) => void; }; export declare class UdpTransport extends EventEmitter { #private; constructor(); get bound(): boolean; start(opts?: UdpTransportOptions): Promise; stop(): Promise; /** * The OS-assigned local UDP port (after bind). Useful so the peer layer * can recognize and skip its own address in friend endpoint candidates * (some toxcore peers echo our address back inside DHT-PK extras). */ localPort(): number | undefined; send(data: Buffer, host: string, port: number): Promise; /** Direct socket send, bypassing TURN routes. ICE/TURN use this so * their own control packets (SEND-INDICATION, binding checks) don't * recurse back through the route table. */ sendDirect(data: Buffer, host: string, port: number): Promise; /** Synchronous fire-and-forget direct send (for hot TURN data path). */ sendDirectSync(data: Buffer, host: string, port: number): void; addStunInterceptor(fn: StunInterceptor): void; removeStunInterceptor(fn: StunInterceptor): void; registerTurnRoute(host: string, port: number, route: TurnRoute): void; unregisterTurnRoute(host: string, port: number): void; }