/** * @file transport-stack.ts * @description Composes ICE -> DTLS -> SCTP -> DCEP into one transport, the * real WebRTC data-channel pipeline. * @module transport-stack * * Wiring: * IceAgent emits 'data' (non-STUN datagrams) -> DtlsConnection.handlePacket * DtlsConnection.output -> IceAgent.send * DtlsConnection 'data' (app records) -> SctpAssociation.receivePacket * SctpAssociation 'output' -> DtlsConnection.send * SctpAssociation + DataChannelManager -> RTCDataChannel * * The DTLS client/server role follows the negotiated a=setup; the SCTP client * (INIT initiator) is the DTLS client, per RFC 8832. */ import { EventEmitter } from 'events'; import { IceAgent } from './ice/ice-agent'; import { DtlsConnection } from './dtls/connection'; import { SctpAssociation } from './sctp/association'; import { DataChannelManager, OpenRequestInfo } from './sctp/datachannel-manager'; import type { RTCDataChannel, RTCDataChannelInit } from './datachannel/RTCDataChannel'; import type { KeyObject } from 'crypto'; export interface TransportStackOptions { /** ICE controlling vs controlled (offerer is controlling). */ iceRole: 'controlling' | 'controlled'; /** DTLS role from a=setup (active=client). */ dtlsRole: 'client' | 'server'; localUfrag: string; localPwd: string; certDer: Buffer; privateKey: KeyObject; verifyFingerprint?: (fp: { algorithm: string; value: string; }) => boolean; } export declare class TransportStack extends EventEmitter { #private; ice: IceAgent; dtls: DtlsConnection | null; sctp: SctpAssociation | null; dcm: DataChannelManager | null; constructor(opts: TransportStackOptions); /** * Begin gathering local candidates. * @param opts - { iceServers, iceTransportPolicy } forwarded to ICE. */ gather(opts?: { iceServers?: unknown[]; iceTransportPolicy?: 'all' | 'relay'; }): Promise; getLocalCandidates(): ReturnType; /** Provide the peer's ICE credentials and start checks when ready. */ setRemote(ufrag: string, pwd: string): void; addRemoteCandidate(cand: { address: string; port: number; type?: string; priority?: number; }): void; /** Open a locally-initiated data channel once SCTP is established. */ openChannel(channel: RTCDataChannel, init: RTCDataChannelInit): void; /** Accept an inbound channel created from a 'datachannel-request'. */ acceptChannel(channel: RTCDataChannel, info: OpenRequestInfo): void; isReady(): boolean; close(): void; }