node-rtc-connection 1.0.18 → 2.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/README.md +94 -85
  2. package/dist/index.cjs +20 -5421
  3. package/dist/index.mjs +25 -5413
  4. package/dist/types/crypto/der.d.ts +107 -0
  5. package/dist/types/crypto/x509.d.ts +56 -0
  6. package/dist/types/datachannel/RTCDataChannel.d.ts +179 -0
  7. package/dist/types/dtls/RTCCertificate.d.ts +163 -0
  8. package/dist/types/dtls/cipher.d.ts +81 -0
  9. package/dist/types/dtls/connection.d.ts +81 -0
  10. package/dist/types/dtls/prf.d.ts +29 -0
  11. package/dist/types/dtls/protocol.d.ts +127 -0
  12. package/dist/types/foundation/ByteBufferQueue.d.ts +71 -0
  13. package/dist/types/foundation/RTCError.d.ts +152 -0
  14. package/dist/types/ice/RTCIceCandidate.d.ts +161 -0
  15. package/dist/types/ice/ice-agent.d.ts +154 -0
  16. package/dist/types/ice/stun-message.d.ts +92 -0
  17. package/dist/types/index.d.ts +29 -0
  18. package/dist/types/peerconnection/RTCPeerConnection.d.ts +74 -0
  19. package/dist/types/sctp/association.d.ts +77 -0
  20. package/dist/types/sctp/chunks.d.ts +200 -0
  21. package/dist/types/sctp/crc32c.d.ts +24 -0
  22. package/dist/types/sctp/datachannel-manager.d.ts +51 -0
  23. package/dist/types/sctp/dcep.d.ts +56 -0
  24. package/dist/types/sdp/RTCSessionDescription.d.ts +73 -0
  25. package/dist/types/sdp/sdp-utils.d.ts +103 -0
  26. package/dist/types/stun/stun-client.d.ts +119 -0
  27. package/dist/types/transport-stack.d.ts +68 -0
  28. package/package.json +26 -21
  29. package/src/crypto/der.ts +205 -0
  30. package/src/crypto/x509.ts +146 -0
  31. package/src/datachannel/RTCDataChannel.ts +388 -0
  32. package/src/dtls/RTCCertificate.ts +396 -0
  33. package/src/dtls/cipher.ts +198 -0
  34. package/src/dtls/connection.ts +974 -0
  35. package/src/dtls/prf.ts +62 -0
  36. package/src/dtls/protocol.ts +204 -0
  37. package/src/foundation/{ByteBufferQueue.js → ByteBufferQueue.ts} +74 -72
  38. package/src/foundation/{RTCError.js → RTCError.ts} +110 -60
  39. package/src/ice/{RTCIceCandidate.js → RTCIceCandidate.ts} +140 -92
  40. package/src/ice/ice-agent.ts +609 -0
  41. package/src/ice/stun-message.ts +260 -0
  42. package/src/index.ts +72 -0
  43. package/src/peerconnection/RTCPeerConnection.ts +430 -0
  44. package/src/sctp/association.ts +523 -0
  45. package/src/sctp/chunks.ts +350 -0
  46. package/src/sctp/crc32c.ts +57 -0
  47. package/src/sctp/datachannel-manager.ts +187 -0
  48. package/src/sctp/dcep.ts +94 -0
  49. package/src/sdp/{RTCSessionDescription.js → RTCSessionDescription.ts} +42 -29
  50. package/src/sdp/sdp-utils.ts +229 -0
  51. package/src/stun/stun-client.ts +936 -0
  52. package/src/transport-stack.ts +165 -0
  53. package/dist/index.cjs.map +0 -1
  54. package/dist/index.mjs.map +0 -1
  55. package/src/datachannel/RTCDataChannel.js +0 -354
  56. package/src/dtls/RTCCertificate.js +0 -310
  57. package/src/dtls/RTCDtlsTransport.js +0 -247
  58. package/src/ice/RTCIceTransport.js +0 -998
  59. package/src/index.d.ts +0 -400
  60. package/src/index.js +0 -92
  61. package/src/network/network-transport.js +0 -478
  62. package/src/peerconnection/RTCPeerConnection.js +0 -851
  63. package/src/sctp/RTCSctpTransport.js +0 -253
  64. package/src/sdp/sdp-utils.js +0 -224
  65. package/src/stun/stun-client.js +0 -643
@@ -0,0 +1,92 @@
1
+ /**
2
+ * @file stun-message.ts
3
+ * @description STUN message codec for ICE connectivity checks (RFC 5389 / 8445).
4
+ * @module ice/stun-message
5
+ *
6
+ * Unlike the server-oriented stun-client.js (binding/allocate), this builds and
7
+ * validates the connectivity-check messages browsers require: USERNAME,
8
+ * MESSAGE-INTEGRITY (HMAC-SHA1 keyed by the peer's ice-pwd), FINGERPRINT
9
+ * (CRC-32 of the message Xored with 0x5354554e), PRIORITY, ICE-CONTROLLING/
10
+ * ICE-CONTROLLED, and USE-CANDIDATE.
11
+ */
12
+ export declare const MAGIC_COOKIE = 554869826;
13
+ export declare const METHOD: Readonly<{
14
+ BINDING: 1;
15
+ }>;
16
+ export declare const CLASS: Readonly<{
17
+ REQUEST: 0;
18
+ INDICATION: 16;
19
+ SUCCESS: 256;
20
+ ERROR: 272;
21
+ }>;
22
+ export declare const MSG_TYPE: Readonly<{
23
+ BINDING_REQUEST: 1;
24
+ BINDING_SUCCESS: 257;
25
+ BINDING_ERROR: 273;
26
+ }>;
27
+ export declare const ATTR: Readonly<{
28
+ MAPPED_ADDRESS: 1;
29
+ USERNAME: 6;
30
+ MESSAGE_INTEGRITY: 8;
31
+ ERROR_CODE: 9;
32
+ XOR_MAPPED_ADDRESS: 32;
33
+ PRIORITY: 36;
34
+ USE_CANDIDATE: 37;
35
+ FINGERPRINT: 32808;
36
+ ICE_CONTROLLED: 32809;
37
+ ICE_CONTROLLING: 32810;
38
+ }>;
39
+ /** A single STUN attribute pending serialization. */
40
+ interface StunAttribute {
41
+ type: number;
42
+ value: Buffer;
43
+ }
44
+ /** Shape of a parsed STUN message. */
45
+ export interface ParsedStunMessage {
46
+ type: number;
47
+ transactionId: Buffer;
48
+ attrs: Map<number, Buffer>;
49
+ raw: Buffer;
50
+ }
51
+ export declare function crc32(buf: Buffer): number;
52
+ /**
53
+ * @class StunMessageBuilder
54
+ * @description Incrementally builds a STUN message, then appends
55
+ * MESSAGE-INTEGRITY and FINGERPRINT with the correct length pre-computation.
56
+ */
57
+ export declare class StunMessageBuilder {
58
+ #private;
59
+ type: number;
60
+ transactionId: Buffer;
61
+ attrs: StunAttribute[];
62
+ constructor(type: number, transactionId?: Buffer);
63
+ addAttr(type: number, value: Buffer): this;
64
+ addUsername(username: string): this;
65
+ addPriority(priority: number): this;
66
+ addIceControlling(tieBreaker: Buffer): this;
67
+ addIceControlled(tieBreaker: Buffer): this;
68
+ addUseCandidate(): this;
69
+ addXorMappedAddress(address: string, port: number): this;
70
+ /**
71
+ * Finalize the message, appending MESSAGE-INTEGRITY (keyed by `password`)
72
+ * and FINGERPRINT. Both require the header length to include the attribute
73
+ * being computed, per RFC 5389 §15.4 / §15.5.
74
+ * @param {string} [password] - ICE password for MESSAGE-INTEGRITY
75
+ * @returns {Buffer}
76
+ */
77
+ build(password?: string): Buffer;
78
+ }
79
+ /**
80
+ * Parse a STUN message. Returns null if not a STUN message.
81
+ * @param {Buffer} msg
82
+ * @returns {null|{type:number,transactionId:Buffer,attrs:Map<number,Buffer>,raw:Buffer}}
83
+ */
84
+ export declare function parse(msg: Buffer): ParsedStunMessage | null;
85
+ /**
86
+ * Verify the MESSAGE-INTEGRITY of a parsed message against a password.
87
+ * @param {Buffer} msg - raw message
88
+ * @param {string} password
89
+ * @returns {boolean}
90
+ */
91
+ export declare function verifyIntegrity(msg: Buffer, password: string): boolean;
92
+ export {};
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @fileoverview node-rtc-connection - WebRTC DataChannel implementation for Node.js
3
+ *
4
+ * A from-scratch, pure-Node.js implementation of WebRTC peer connections and
5
+ * data channels (no native dependencies). Interoperates with browsers.
6
+ *
7
+ * This implementation focuses on DataChannel functionality without media streams.
8
+ * Features:
9
+ * - ICE (Interactive Connectivity Establishment), RFC 8445
10
+ * - STUN/TURN support for NAT traversal
11
+ * - DTLS 1.2 encryption (RFC 6347)
12
+ * - SCTP over DTLS + DCEP for data channels (RFC 8831 / 8832)
13
+ * - W3C-compatible RTCPeerConnection / RTCDataChannel API
14
+ *
15
+ * @license MIT
16
+ * @author nmhung1210
17
+ */
18
+ import ByteBufferQueue from './foundation/ByteBufferQueue';
19
+ import RTCError from './foundation/RTCError';
20
+ import RTCIceCandidate from './ice/RTCIceCandidate';
21
+ import RTCCertificate from './dtls/RTCCertificate';
22
+ import { RTCDataChannel, RTCDataChannelState } from './datachannel/RTCDataChannel';
23
+ import { RTCSessionDescription, RTCSdpType } from './sdp/RTCSessionDescription';
24
+ import { RTCPeerConnection, RTCSignalingState, RTCIceGatheringState, RTCPeerConnectionState } from './peerconnection/RTCPeerConnection';
25
+ export { ByteBufferQueue, RTCError, RTCIceCandidate, RTCCertificate, RTCDataChannel, RTCDataChannelState, RTCSessionDescription, RTCSdpType, RTCPeerConnection, RTCSignalingState, RTCIceGatheringState, RTCPeerConnectionState, };
26
+ export declare const version: string;
27
+ export type { RTCDataChannelInit } from './datachannel/RTCDataChannel';
28
+ export type { RTCSessionDescriptionInit } from './sdp/RTCSessionDescription';
29
+ export type { TransportStackOptions } from './transport-stack';
@@ -0,0 +1,74 @@
1
+ /**
2
+ * @file RTCPeerConnection.ts
3
+ * @description WebRTC peer connection driving a real ICE/DTLS/SCTP/DCEP stack.
4
+ * @module peerconnection/RTCPeerConnection
5
+ *
6
+ * This orchestrates signaling (offer/answer + ICE candidate trickle) on top of
7
+ * src/transport-stack.ts, which implements the actual on-the-wire protocols.
8
+ * It interoperates with browser RTCPeerConnection for data channels.
9
+ */
10
+ import { EventEmitter } from 'events';
11
+ import RTCCertificate from '../dtls/RTCCertificate';
12
+ import { RTCSessionDescription, RTCSessionDescriptionInit } from '../sdp/RTCSessionDescription';
13
+ import { RTCDataChannel, RTCDataChannelInit } from '../datachannel/RTCDataChannel';
14
+ import { TransportStack } from '../transport-stack';
15
+ /** Configuration accepted by {@link RTCPeerConnection}. */
16
+ export interface RTCConfiguration {
17
+ iceServers?: unknown[];
18
+ iceTransportPolicy?: 'all' | 'relay';
19
+ certificates?: RTCCertificate[];
20
+ }
21
+ export declare const RTCSignalingState: Readonly<{
22
+ STABLE: "stable";
23
+ HAVE_LOCAL_OFFER: "have-local-offer";
24
+ HAVE_REMOTE_OFFER: "have-remote-offer";
25
+ HAVE_LOCAL_PRANSWER: "have-local-pranswer";
26
+ HAVE_REMOTE_PRANSWER: "have-remote-pranswer";
27
+ CLOSED: "closed";
28
+ }>;
29
+ export declare const RTCIceGatheringState: Readonly<{
30
+ NEW: "new";
31
+ GATHERING: "gathering";
32
+ COMPLETE: "complete";
33
+ }>;
34
+ export declare const RTCPeerConnectionState: Readonly<{
35
+ NEW: "new";
36
+ CONNECTING: "connecting";
37
+ CONNECTED: "connected";
38
+ DISCONNECTED: "disconnected";
39
+ FAILED: "failed";
40
+ CLOSED: "closed";
41
+ }>;
42
+ export declare class RTCPeerConnection extends EventEmitter {
43
+ #private;
44
+ constructor(configuration?: RTCConfiguration);
45
+ createDataChannel(label: string, options?: RTCDataChannelInit): RTCDataChannel;
46
+ createOffer(): Promise<RTCSessionDescription>;
47
+ createAnswer(): Promise<RTCSessionDescription>;
48
+ setLocalDescription(description?: RTCSessionDescriptionInit | RTCSessionDescription): Promise<void>;
49
+ setRemoteDescription(description: RTCSessionDescriptionInit): Promise<void>;
50
+ addIceCandidate(candidate: RTCIceCandidateInit | string): Promise<void>;
51
+ getConfiguration(): RTCConfiguration;
52
+ setConfiguration(configuration: RTCConfiguration): void;
53
+ close(): void;
54
+ get signalingState(): string;
55
+ get iceGatheringState(): string;
56
+ get iceConnectionState(): string;
57
+ get connectionState(): string;
58
+ get localDescription(): RTCSessionDescription | null;
59
+ get remoteDescription(): RTCSessionDescription | null;
60
+ get currentLocalDescription(): RTCSessionDescription | null;
61
+ get currentRemoteDescription(): RTCSessionDescription | null;
62
+ get pendingLocalDescription(): RTCSessionDescription | null;
63
+ get pendingRemoteDescription(): RTCSessionDescription | null;
64
+ get canTrickleIceCandidates(): boolean;
65
+ get sctp(): TransportStack['sctp'];
66
+ }
67
+ /** ICE candidate init shape (subset of the W3C dictionary). */
68
+ interface RTCIceCandidateInit {
69
+ candidate: string;
70
+ sdpMid?: string;
71
+ sdpMLineIndex?: number;
72
+ usernameFragment?: string;
73
+ }
74
+ export {};
@@ -0,0 +1,77 @@
1
+ /**
2
+ * @file association.ts
3
+ * @description Minimal SCTP association over a datagram channel (DTLS), scoped
4
+ * to the WebRTC data channel profile (RFC 8831).
5
+ * @module sctp/association
6
+ *
7
+ * Implements the four-way INIT/INIT-ACK/COOKIE-ECHO/COOKIE-ACK setup, DATA
8
+ * transmit/receive with TSN tracking and SACK, ordered and unordered delivery,
9
+ * and reassembly of fragmented user messages. Congestion control is
10
+ * intentionally simple (stop-and-go style with a generous rwnd) which is
11
+ * adequate for control/data-channel traffic and interoperates with usrsctp
12
+ * (the stack browsers use).
13
+ *
14
+ * The association rides on top of a reliable-ish datagram pipe provided by
15
+ * DTLS; SCTP still provides framing, ordering, multiplexing and ack'ing.
16
+ */
17
+ import { EventEmitter } from 'events';
18
+ declare const SCTP_PORT = 5000;
19
+ declare const STATE: Readonly<{
20
+ CLOSED: "closed";
21
+ COOKIE_WAIT: "cookie-wait";
22
+ COOKIE_ECHOED: "cookie-echoed";
23
+ ESTABLISHED: "established";
24
+ }>;
25
+ type StateValue = (typeof STATE)[keyof typeof STATE];
26
+ /** Options for constructing an {@link SctpAssociation}. */
27
+ export interface SctpAssociationOptions {
28
+ /** the DTLS client initiates SCTP (RFC 8831) */
29
+ isClient?: boolean;
30
+ }
31
+ /** A complete user message surfaced via the 'message' event. */
32
+ export interface SctpMessage {
33
+ streamId: number;
34
+ ppid: number;
35
+ data: Buffer;
36
+ }
37
+ /**
38
+ * @class SctpAssociation
39
+ * @extends EventEmitter
40
+ *
41
+ * Events:
42
+ * - 'established' association is up
43
+ * - 'message' ({streamId, ppid, data}) a complete user message arrived
44
+ * - 'output' (Buffer) an SCTP packet to hand to DTLS
45
+ * - 'close'
46
+ */
47
+ declare class SctpAssociation extends EventEmitter {
48
+ #private;
49
+ isClient: boolean;
50
+ state: StateValue;
51
+ /**
52
+ * @param {Object} opts
53
+ * @param {boolean} opts.isClient - the DTLS client initiates SCTP (RFC 8831)
54
+ */
55
+ constructor(opts?: SctpAssociationOptions);
56
+ /** Start the association (client sends INIT). */
57
+ start(): void;
58
+ /**
59
+ * Feed an inbound SCTP packet (decrypted from DTLS).
60
+ * @param {Buffer} packet
61
+ */
62
+ receivePacket(packet: Buffer): void;
63
+ /**
64
+ * Send a user message on a stream.
65
+ * @param {number} streamId
66
+ * @param {number} ppid
67
+ * @param {Buffer} data
68
+ * @param {Object} [opts]
69
+ * @param {boolean} [opts.unordered=false]
70
+ */
71
+ sendData(streamId: number, ppid: number, data: Buffer, opts?: {
72
+ unordered?: boolean;
73
+ }): void;
74
+ /** Gracefully close the association. */
75
+ shutdown(): void;
76
+ }
77
+ export { SctpAssociation, STATE, SCTP_PORT };
@@ -0,0 +1,200 @@
1
+ /**
2
+ * @file chunks.ts
3
+ * @description SCTP common header and chunk encode/parse (RFC 4960 + RFC 8260
4
+ * for I-DATA is NOT used; classic DATA only). Scoped to the WebRTC profile.
5
+ * @module sctp/chunks
6
+ */
7
+ export declare const CHUNK_TYPE: Readonly<{
8
+ DATA: 0;
9
+ INIT: 1;
10
+ INIT_ACK: 2;
11
+ SACK: 3;
12
+ HEARTBEAT: 4;
13
+ HEARTBEAT_ACK: 5;
14
+ ABORT: 6;
15
+ SHUTDOWN: 7;
16
+ SHUTDOWN_ACK: 8;
17
+ ERROR: 9;
18
+ COOKIE_ECHO: 10;
19
+ COOKIE_ACK: 11;
20
+ SHUTDOWN_COMPLETE: 14;
21
+ FORWARD_TSN: 192;
22
+ }>;
23
+ export declare const PARAM_TYPE: Readonly<{
24
+ HEARTBEAT_INFO: 1;
25
+ STATE_COOKIE: 7;
26
+ UNRECOGNIZED_PARAM: 8;
27
+ COOKIE_PRESERVATIVE: 9;
28
+ SUPPORTED_ADDR_TYPES: 11;
29
+ FORWARD_TSN_SUPPORTED: 49152;
30
+ SUPPORTED_EXTENSIONS: 32776;
31
+ }>;
32
+ export declare const PPID: Readonly<{
33
+ DCEP: 50;
34
+ STRING: 51;
35
+ BINARY: 53;
36
+ STRING_EMPTY: 56;
37
+ BINARY_EMPTY: 57;
38
+ STRING_PARTIAL: 54;
39
+ BINARY_PARTIAL: 52;
40
+ }>;
41
+ export interface CommonHeader {
42
+ srcPort: number;
43
+ dstPort: number;
44
+ verificationTag: number;
45
+ checksum: number;
46
+ }
47
+ export interface ParsedChunk {
48
+ type: number;
49
+ flags: number;
50
+ length: number;
51
+ body: Buffer;
52
+ }
53
+ export interface ParsedParam {
54
+ type: number;
55
+ length: number;
56
+ value: Buffer;
57
+ }
58
+ export interface InitBodyParams {
59
+ initiateTag: number;
60
+ a_rwnd: number;
61
+ outStreams: number;
62
+ inStreams: number;
63
+ initialTSN: number;
64
+ }
65
+ export interface ParsedInitBody {
66
+ initiateTag: number;
67
+ a_rwnd: number;
68
+ outStreams: number;
69
+ inStreams: number;
70
+ initialTSN: number;
71
+ params: ParsedParam[];
72
+ }
73
+ export interface DataBodyParams {
74
+ tsn: number;
75
+ streamId: number;
76
+ streamSeq: number;
77
+ ppid: number;
78
+ userData: Buffer;
79
+ unordered?: boolean;
80
+ beginning?: boolean;
81
+ ending?: boolean;
82
+ }
83
+ export interface EncodedDataBody {
84
+ flags: number;
85
+ body: Buffer;
86
+ }
87
+ export interface ParsedDataBody {
88
+ unordered: boolean;
89
+ beginning: boolean;
90
+ ending: boolean;
91
+ tsn: number;
92
+ streamId: number;
93
+ streamSeq: number;
94
+ ppid: number;
95
+ userData: Buffer;
96
+ }
97
+ export interface SackBodyParams {
98
+ cumulativeTSNAck: number;
99
+ a_rwnd: number;
100
+ gapBlocks?: Array<[number, number]>;
101
+ dupTSNs?: number[];
102
+ }
103
+ export interface ParsedSackBody {
104
+ cumulativeTSNAck: number;
105
+ a_rwnd: number;
106
+ gapBlocks: Array<[number, number]>;
107
+ dupTSNs: number[];
108
+ }
109
+ /** Round a length up to the next 4-byte boundary. */
110
+ export declare function pad4(n: number): number;
111
+ /**
112
+ * Encode the 12-byte SCTP common header (checksum left as 0; filled by crc32c).
113
+ * @param {number} srcPort
114
+ * @param {number} dstPort
115
+ * @param {number} verificationTag
116
+ * @returns {Buffer}
117
+ */
118
+ export declare function encodeCommonHeader(srcPort: number, dstPort: number, verificationTag: number): Buffer;
119
+ /**
120
+ * Parse the common header.
121
+ * @param {Buffer} packet
122
+ * @returns {{srcPort:number,dstPort:number,verificationTag:number,checksum:number}}
123
+ */
124
+ export declare function parseCommonHeader(packet: Buffer): CommonHeader;
125
+ /**
126
+ * Wrap a chunk body with the 4-byte chunk header, padded to 4 bytes.
127
+ * @param {number} type
128
+ * @param {number} flags
129
+ * @param {Buffer} body
130
+ * @returns {Buffer}
131
+ */
132
+ export declare function encodeChunk(type: number, flags: number, body: Buffer): Buffer;
133
+ /**
134
+ * Parse all chunks out of an SCTP packet (after the 12-byte common header).
135
+ * @param {Buffer} packet
136
+ * @returns {Array<{type:number,flags:number,length:number,body:Buffer}>}
137
+ */
138
+ export declare function parseChunks(packet: Buffer): ParsedChunk[];
139
+ /**
140
+ * Encode a TLV parameter, padded to 4 bytes.
141
+ * @param {number} type
142
+ * @param {Buffer} value
143
+ * @returns {Buffer}
144
+ */
145
+ export declare function encodeParam(type: number, value: Buffer): Buffer;
146
+ /**
147
+ * Parse TLV parameters from a buffer.
148
+ * @param {Buffer} buf
149
+ * @returns {Array<{type:number,length:number,value:Buffer}>}
150
+ */
151
+ export declare function parseParams(buf: Buffer): ParsedParam[];
152
+ /**
153
+ * Build an INIT or INIT_ACK fixed body (without parameters).
154
+ * @param {Object} p
155
+ * @param {number} p.initiateTag
156
+ * @param {number} p.a_rwnd - advertised receiver window
157
+ * @param {number} p.outStreams
158
+ * @param {number} p.inStreams
159
+ * @param {number} p.initialTSN
160
+ * @returns {Buffer}
161
+ */
162
+ export declare function encodeInitBody({ initiateTag, a_rwnd, outStreams, inStreams, initialTSN }: InitBodyParams): Buffer;
163
+ /**
164
+ * Parse an INIT/INIT_ACK body.
165
+ * @param {Buffer} body
166
+ * @returns {{initiateTag:number,a_rwnd:number,outStreams:number,inStreams:number,initialTSN:number,params:Array}}
167
+ */
168
+ export declare function parseInitBody(body: Buffer): ParsedInitBody;
169
+ /**
170
+ * Encode a DATA chunk body (RFC 4960 §3.3.1).
171
+ * @param {Object} p
172
+ * @param {number} p.tsn
173
+ * @param {number} p.streamId
174
+ * @param {number} p.streamSeq
175
+ * @param {number} p.ppid
176
+ * @param {Buffer} p.userData
177
+ * @returns {{flags:number, body:Buffer}}
178
+ */
179
+ export declare function encodeDataBody({ tsn, streamId, streamSeq, ppid, userData, unordered, beginning, ending }: DataBodyParams): EncodedDataBody;
180
+ /**
181
+ * Parse a DATA chunk body.
182
+ * @param {number} flags
183
+ * @param {Buffer} body
184
+ */
185
+ export declare function parseDataBody(flags: number, body: Buffer): ParsedDataBody;
186
+ /**
187
+ * Encode a SACK chunk body (cumulative ack only, no gap/dup for simplicity but
188
+ * gap blocks supported via params).
189
+ * @param {Object} p
190
+ * @param {number} p.cumulativeTSNAck
191
+ * @param {number} p.a_rwnd
192
+ * @param {Array<[number,number]>} [p.gapBlocks] - [start,end] offsets from cumAck+1
193
+ * @param {Array<number>} [p.dupTSNs]
194
+ * @returns {Buffer}
195
+ */
196
+ export declare function encodeSackBody({ cumulativeTSNAck, a_rwnd, gapBlocks, dupTSNs }: SackBodyParams): Buffer;
197
+ /**
198
+ * Parse a SACK chunk body.
199
+ */
200
+ export declare function parseSackBody(body: Buffer): ParsedSackBody;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @file crc32c.ts
3
+ * @description CRC-32C (Castagnoli) checksum for SCTP packets (RFC 4960 App. B,
4
+ * polynomial 0x1EDC6F41), reflected input/output, used with the SCTP-specific
5
+ * byte ordering described in RFC 4960 §6.8 / RFC 3309.
6
+ * @module sctp/crc32c
7
+ */
8
+ /**
9
+ * Compute the raw reflected CRC-32C over a buffer.
10
+ * @returns unsigned 32-bit
11
+ */
12
+ export declare function crc32c(buf: Buffer): number;
13
+ /**
14
+ * Insert the SCTP checksum into a packet. The checksum field (bytes 8..11 of
15
+ * the common header) is zeroed, the CRC computed over the whole packet, then
16
+ * written back in little-endian byte order (RFC 4960 §6.8, RFC 3309).
17
+ * @param packet - full SCTP packet (header + chunks)
18
+ * @returns the same packet, checksum filled in
19
+ */
20
+ export declare function applyChecksum(packet: Buffer): Buffer;
21
+ /**
22
+ * Validate the checksum of a received SCTP packet.
23
+ */
24
+ export declare function verifyChecksum(packet: Buffer): boolean;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * @file datachannel-manager.ts
3
+ * @description Bridges SCTP streams + DCEP to RTCDataChannel instances.
4
+ * @module sctp/datachannel-manager
5
+ *
6
+ * Responsibilities:
7
+ * - Allocate SCTP stream IDs per RFC 8832 §6: the DTLS client (a=setup:active)
8
+ * uses even stream IDs, the DTLS server uses odd.
9
+ * - Send DATA_CHANNEL_OPEN and await DATA_CHANNEL_ACK; respond to inbound OPEN.
10
+ * - Map outgoing string/binary sends to the correct PPID, and incoming PPIDs
11
+ * back to string/binary, including the EMPTY variants for zero-length data.
12
+ */
13
+ import { EventEmitter } from 'events';
14
+ import type { SctpAssociation } from './association';
15
+ import { RTCDataChannel } from '../datachannel/RTCDataChannel';
16
+ /** Subset of RTCDataChannelInit used when opening/accepting channels. */
17
+ interface ChannelInit {
18
+ ordered?: boolean;
19
+ maxRetransmits?: number | null;
20
+ maxPacketLifeTime?: number | null;
21
+ protocol?: string;
22
+ }
23
+ /** Information surfaced on the 'open-request' event for an inbound channel. */
24
+ export interface OpenRequestInfo {
25
+ streamId: number;
26
+ label: string;
27
+ protocol: string;
28
+ ordered: boolean;
29
+ channelType: number;
30
+ reliabilityParameter: number;
31
+ }
32
+ declare class DataChannelManager extends EventEmitter {
33
+ #private;
34
+ /**
35
+ * @param {import('./association').SctpAssociation} association
36
+ * @param {boolean} isDtlsClient - true if we are the DTLS client (even IDs)
37
+ */
38
+ constructor(association: SctpAssociation, isDtlsClient: boolean);
39
+ /**
40
+ * Open a channel initiated locally.
41
+ * @param {import('../datachannel/RTCDataChannel').RTCDataChannel} channel
42
+ * @param {Object} init - { ordered, maxRetransmits, maxPacketLifeTime, protocol }
43
+ */
44
+ openChannel(channel: RTCDataChannel, init?: ChannelInit): void;
45
+ /**
46
+ * Register an inbound channel (created in response to 'open-request') and
47
+ * attach its sender.
48
+ */
49
+ acceptChannel(channel: RTCDataChannel, info: OpenRequestInfo): void;
50
+ }
51
+ export { DataChannelManager };
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @file dcep.ts
3
+ * @description Data Channel Establishment Protocol (RFC 8832) message codec.
4
+ * @module sctp/dcep
5
+ *
6
+ * DCEP runs on PPID 50 and negotiates a data channel on an SCTP stream:
7
+ * DATA_CHANNEL_OPEN (0x03) -> DATA_CHANNEL_ACK (0x02)
8
+ */
9
+ export declare const MESSAGE_TYPE: Readonly<{
10
+ DATA_CHANNEL_ACK: 2;
11
+ DATA_CHANNEL_OPEN: 3;
12
+ }>;
13
+ export declare const CHANNEL_TYPE: Readonly<{
14
+ RELIABLE: 0;
15
+ RELIABLE_UNORDERED: 128;
16
+ PARTIAL_RELIABLE_REXMIT: 1;
17
+ PARTIAL_RELIABLE_REXMIT_UNORDERED: 129;
18
+ PARTIAL_RELIABLE_TIMED: 2;
19
+ PARTIAL_RELIABLE_TIMED_UNORDERED: 130;
20
+ }>;
21
+ export interface OpenParams {
22
+ channelType: number;
23
+ priority?: number;
24
+ reliabilityParameter?: number;
25
+ label?: string;
26
+ protocol?: string;
27
+ }
28
+ export interface DecodedOpen {
29
+ channelType: number;
30
+ priority: number;
31
+ reliabilityParameter: number;
32
+ label: string;
33
+ protocol: string;
34
+ unordered: boolean;
35
+ }
36
+ /**
37
+ * Encode a DATA_CHANNEL_OPEN message.
38
+ * @param {Object} p
39
+ * @param {number} p.channelType
40
+ * @param {number} p.priority
41
+ * @param {number} p.reliabilityParameter
42
+ * @param {string} p.label
43
+ * @param {string} p.protocol
44
+ * @returns {Buffer}
45
+ */
46
+ export declare function encodeOpen({ channelType, priority, reliabilityParameter, label, protocol }: OpenParams): Buffer;
47
+ /**
48
+ * Decode a DATA_CHANNEL_OPEN message.
49
+ * @param {Buffer} buf
50
+ * @returns {Object}
51
+ */
52
+ export declare function decodeOpen(buf: Buffer): DecodedOpen;
53
+ /** Encode a DATA_CHANNEL_ACK message. */
54
+ export declare function encodeAck(): Buffer;
55
+ /** Return the message type of a DCEP buffer. */
56
+ export declare function messageType(buf: Buffer): number;
@@ -0,0 +1,73 @@
1
+ /**
2
+ * @file RTCSessionDescription.ts
3
+ * @description Session Description Protocol (SDP) representation
4
+ * @module sdp/RTCSessionDescription
5
+ *
6
+ * Implements the W3C RTCSessionDescription interface
7
+ * (https://www.w3.org/TR/webrtc/#rtcsessiondescription-class).
8
+ */
9
+ /**
10
+ * RTCSdpType - Types of session descriptions
11
+ * @readonly
12
+ * @enum {string}
13
+ */
14
+ export declare const RTCSdpType: Readonly<Record<string, string>>;
15
+ /**
16
+ * Session description init object.
17
+ */
18
+ export interface RTCSessionDescriptionInit {
19
+ type?: string;
20
+ sdp?: string;
21
+ }
22
+ /**
23
+ * JSON representation of an RTCSessionDescription.
24
+ */
25
+ export interface RTCSessionDescriptionJSON {
26
+ type: string | null;
27
+ sdp: string | null;
28
+ }
29
+ /**
30
+ * @class RTCSessionDescription
31
+ * @description Represents a WebRTC session description (offer/answer)
32
+ *
33
+ * @example
34
+ * const desc = new RTCSessionDescription({
35
+ * type: 'offer',
36
+ * sdp: 'v=0\r\no=- 123456 2 IN IP4 127.0.0.1\r\n...'
37
+ * });
38
+ */
39
+ export declare class RTCSessionDescription {
40
+ #private;
41
+ /**
42
+ * Create an RTCSessionDescription instance.
43
+ * @param {Object} [init] - Session description init
44
+ * @param {string} [init.type] - SDP type (offer/answer/pranswer/rollback)
45
+ * @param {string} [init.sdp] - SDP string
46
+ */
47
+ constructor(init?: RTCSessionDescriptionInit);
48
+ /**
49
+ * Get the SDP type.
50
+ * @returns {string|null} SDP type
51
+ */
52
+ get type(): string | null;
53
+ /**
54
+ * Set the SDP type.
55
+ * @param {string} value - SDP type
56
+ */
57
+ set type(value: string | null);
58
+ /**
59
+ * Get the SDP string.
60
+ * @returns {string|null} SDP string
61
+ */
62
+ get sdp(): string | null;
63
+ /**
64
+ * Set the SDP string.
65
+ * @param {string} value - SDP string
66
+ */
67
+ set sdp(value: string | null);
68
+ /**
69
+ * Convert to JSON representation.
70
+ * @returns {Object} JSON representation
71
+ */
72
+ toJSON(): RTCSessionDescriptionJSON;
73
+ }