node-rtc-connection 1.0.19 → 2.0.5

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 (47) hide show
  1. package/README.md +94 -85
  2. package/index.cjs +1 -0
  3. package/index.mjs +1 -0
  4. package/package.json +14 -46
  5. package/types/crypto/der.d.ts +107 -0
  6. package/types/crypto/x509.d.ts +56 -0
  7. package/types/datachannel/RTCDataChannel.d.ts +179 -0
  8. package/types/dtls/RTCCertificate.d.ts +163 -0
  9. package/types/dtls/cipher.d.ts +81 -0
  10. package/types/dtls/connection.d.ts +81 -0
  11. package/types/dtls/prf.d.ts +29 -0
  12. package/types/dtls/protocol.d.ts +127 -0
  13. package/types/foundation/ByteBufferQueue.d.ts +71 -0
  14. package/types/foundation/RTCError.d.ts +152 -0
  15. package/types/ice/RTCIceCandidate.d.ts +161 -0
  16. package/types/ice/ice-agent.d.ts +154 -0
  17. package/types/ice/stun-message.d.ts +92 -0
  18. package/types/index.d.ts +29 -0
  19. package/types/peerconnection/RTCPeerConnection.d.ts +74 -0
  20. package/types/sctp/association.d.ts +77 -0
  21. package/types/sctp/chunks.d.ts +200 -0
  22. package/types/sctp/crc32c.d.ts +24 -0
  23. package/types/sctp/datachannel-manager.d.ts +51 -0
  24. package/types/sctp/dcep.d.ts +56 -0
  25. package/types/sdp/RTCSessionDescription.d.ts +73 -0
  26. package/types/sdp/sdp-utils.d.ts +103 -0
  27. package/types/stun/stun-client.d.ts +119 -0
  28. package/types/transport-stack.d.ts +68 -0
  29. package/dist/index.cjs +0 -5618
  30. package/dist/index.cjs.map +0 -1
  31. package/dist/index.mjs +0 -5616
  32. package/dist/index.mjs.map +0 -1
  33. package/src/datachannel/RTCDataChannel.js +0 -354
  34. package/src/dtls/RTCCertificate.js +0 -310
  35. package/src/dtls/RTCDtlsTransport.js +0 -247
  36. package/src/foundation/ByteBufferQueue.js +0 -235
  37. package/src/foundation/RTCError.js +0 -226
  38. package/src/ice/RTCIceCandidate.js +0 -301
  39. package/src/ice/RTCIceTransport.js +0 -1018
  40. package/src/index.d.ts +0 -400
  41. package/src/index.js +0 -92
  42. package/src/network/network-transport.js +0 -478
  43. package/src/peerconnection/RTCPeerConnection.js +0 -875
  44. package/src/sctp/RTCSctpTransport.js +0 -253
  45. package/src/sdp/RTCSessionDescription.js +0 -102
  46. package/src/sdp/sdp-utils.js +0 -224
  47. package/src/stun/stun-client.js +0 -777
@@ -0,0 +1,154 @@
1
+ /**
2
+ * @file ice-agent.ts
3
+ * @description A small but RFC 8445-compliant ICE agent for a single data
4
+ * component, with browser-compatible connectivity checks and TURN relay.
5
+ * @module ice/ice-agent
6
+ *
7
+ * Responsibilities:
8
+ * - Gather UDP host candidates, server-reflexive (srflx) candidates via STUN,
9
+ * and relay candidates via TURN (RFC 5766 ALLOCATE).
10
+ * - Send/answer STUN Binding connectivity checks carrying USERNAME,
11
+ * MESSAGE-INTEGRITY (keyed by the remote/local ice-pwd), PRIORITY, the
12
+ * ICE-CONTROLLING/CONTROLLED role attribute, and USE-CANDIDATE.
13
+ * - Nominate a candidate pair and expose it as the selected path.
14
+ * - Demultiplex inbound datagrams per RFC 7983: STUN (first byte 0-3) is
15
+ * handled internally; everything else (DTLS records, first byte 20-63) is
16
+ * emitted as 'data' for the upper stack.
17
+ *
18
+ * Each local candidate carries a `transport` with a uniform interface so the
19
+ * connectivity-check and data paths are identical whether the candidate is a
20
+ * host socket or a TURN relay:
21
+ * transport.send(buf, remoteAddress, remotePort)
22
+ * transport.onMessage = (buf, {address, port}) => ...
23
+ */
24
+ import { EventEmitter } from 'events';
25
+ /** Remote info accompanying an inbound datagram. */
26
+ interface RemoteInfo {
27
+ address: string;
28
+ port: number;
29
+ }
30
+ /**
31
+ * Uniform transport abstraction shared by host sockets and TURN relays.
32
+ */
33
+ interface Transport {
34
+ kind: string;
35
+ send(buf: Buffer, address: string, port: number): void;
36
+ onMessage: ((msg: Buffer, rinfo: RemoteInfo) => void) | null;
37
+ close(): void;
38
+ }
39
+ /** A local ICE candidate. */
40
+ interface LocalCandidate {
41
+ foundation: string;
42
+ component: number;
43
+ protocol: string;
44
+ priority: number;
45
+ address: string;
46
+ port: number;
47
+ type: string;
48
+ transport: Transport;
49
+ sdp: string;
50
+ }
51
+ /** A remote ICE candidate (parsed from an a=candidate line or object). */
52
+ interface RemoteCandidate {
53
+ address: string;
54
+ port: number;
55
+ priority?: number;
56
+ type?: string;
57
+ }
58
+ /** A candidate pair under connectivity checking. */
59
+ interface CandidatePair {
60
+ key?: string;
61
+ local: {
62
+ transport: Transport;
63
+ } & Partial<LocalCandidate>;
64
+ remote: {
65
+ address: string;
66
+ port: number;
67
+ } & Partial<RemoteCandidate>;
68
+ state?: string;
69
+ nominated?: boolean;
70
+ }
71
+ /** Description of a single ICE server entry. */
72
+ interface IceServer {
73
+ urls: string | string[];
74
+ username?: string;
75
+ credential?: string;
76
+ }
77
+ /** Options accepted by {@link IceAgent#gather}. */
78
+ interface GatherOptions {
79
+ iceServers?: IceServer[];
80
+ iceTransportPolicy?: 'all' | 'relay';
81
+ }
82
+ /** Parsed query parameters from a STUN/TURN URL. */
83
+ type IceServerParams = Record<string, string | true>;
84
+ /** Result of {@link parseIceServerUrl}. */
85
+ interface ParsedIceServerUrl {
86
+ scheme: string;
87
+ protocol: string;
88
+ host: string;
89
+ port: number;
90
+ transport: string;
91
+ params: IceServerParams;
92
+ }
93
+ /** Options accepted by the {@link IceAgent} constructor. */
94
+ interface IceAgentOptions {
95
+ role: 'controlling' | 'controlled';
96
+ localUfrag: string;
97
+ localPwd: string;
98
+ }
99
+ /**
100
+ * Compute an ICE candidate priority (RFC 8445 §5.1.2.1).
101
+ */
102
+ declare function candidatePriority(type: string, localPref?: number, componentId?: number): number;
103
+ /**
104
+ * Parse a STUN/TURN server URL: (stun|turn|turns):host[:port][?key=val&...].
105
+ * Query parameters are returned in `params`; a flag without a value (e.g.
106
+ * "?secure") is recorded as `true`, an empty value ("?transport=") as "".
107
+ * @param {string} url
108
+ * @returns {{scheme:string, protocol:string, host:string, port:number,
109
+ * transport:string, params:Object}|null} null if the URL is invalid.
110
+ */
111
+ declare function parseIceServerUrl(url: string): ParsedIceServerUrl | null;
112
+ declare class IceAgent extends EventEmitter {
113
+ #private;
114
+ role: 'controlling' | 'controlled';
115
+ localUfrag: string;
116
+ localPwd: string;
117
+ remoteUfrag: string | null;
118
+ remotePwd: string | null;
119
+ /**
120
+ * @param {Object} opts
121
+ * @param {'controlling'|'controlled'} opts.role
122
+ * @param {string} opts.localUfrag
123
+ * @param {string} opts.localPwd
124
+ */
125
+ constructor(opts: IceAgentOptions);
126
+ /**
127
+ * Gather candidates. Host candidates always; srflx/relay when iceServers are
128
+ * given. With iceTransportPolicy 'relay', only relay candidates are kept.
129
+ * @param {Object} [opts]
130
+ * @param {Array<{urls:string|string[],username?:string,credential?:string}>} [opts.iceServers]
131
+ * @param {'all'|'relay'} [opts.iceTransportPolicy='all']
132
+ */
133
+ gather(opts?: GatherOptions): Promise<void>;
134
+ getLocalCandidates(): LocalCandidate[];
135
+ /** Set remote ICE credentials (from the peer's SDP). */
136
+ setRemoteCredentials(ufrag: string, pwd: string): void;
137
+ /**
138
+ * Add a remote candidate (parsed from an a=candidate line or object).
139
+ * @param {{address:string, port:number, priority?:number, type?:string}} cand
140
+ */
141
+ addRemoteCandidate(cand: RemoteCandidate): void;
142
+ /** Begin connectivity checks (call once remote creds + candidates exist). */
143
+ start(): void;
144
+ /**
145
+ * Send application (DTLS) data over the selected path.
146
+ * @param {Buffer} data
147
+ */
148
+ send(data: Buffer): void;
149
+ getSelectedPair(): CandidatePair | null;
150
+ /** Type of the selected local candidate ('host'|'srflx'|'relay'|'prflx'). */
151
+ getSelectedCandidateType(): string | null | undefined;
152
+ close(): void;
153
+ }
154
+ export { IceAgent, candidatePriority, parseIceServerUrl };
@@ -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;