node-rtc-connection 1.0.19 → 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 (64) hide show
  1. package/README.md +94 -85
  2. package/dist/index.cjs +20 -5606
  3. package/dist/index.mjs +25 -5598
  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.js → stun-client.ts} +346 -187
  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 -1018
  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 -875
  63. package/src/sctp/RTCSctpTransport.js +0 -253
  64. package/src/sdp/sdp-utils.js +0 -224
@@ -0,0 +1,127 @@
1
+ /**
2
+ * @file protocol.ts
3
+ * @description DTLS 1.2 wire-format constants and TLV/vector encoders.
4
+ * @module dtls/protocol
5
+ *
6
+ * Covers exactly what WebRTC's data channel needs:
7
+ * cipher suite TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xC02B)
8
+ * curve secp256r1, signature scheme ecdsa_secp256r1_sha256.
9
+ *
10
+ * References: RFC 6347 (DTLS 1.2), RFC 5246 (TLS 1.2), RFC 8422 (ECC).
11
+ */
12
+ export declare const DTLS_1_2 = 65277;
13
+ export declare const CONTENT_TYPE: Readonly<{
14
+ CHANGE_CIPHER_SPEC: 20;
15
+ ALERT: 21;
16
+ HANDSHAKE: 22;
17
+ APPLICATION_DATA: 23;
18
+ }>;
19
+ export declare const HANDSHAKE_TYPE: Readonly<{
20
+ HELLO_REQUEST: 0;
21
+ CLIENT_HELLO: 1;
22
+ SERVER_HELLO: 2;
23
+ HELLO_VERIFY_REQUEST: 3;
24
+ CERTIFICATE: 11;
25
+ SERVER_KEY_EXCHANGE: 12;
26
+ CERTIFICATE_REQUEST: 13;
27
+ SERVER_HELLO_DONE: 14;
28
+ CERTIFICATE_VERIFY: 15;
29
+ CLIENT_KEY_EXCHANGE: 16;
30
+ FINISHED: 20;
31
+ }>;
32
+ export declare const ALERT_LEVEL: Readonly<{
33
+ WARNING: 1;
34
+ FATAL: 2;
35
+ }>;
36
+ export declare const ALERT_DESC: Readonly<{
37
+ CLOSE_NOTIFY: 0;
38
+ HANDSHAKE_FAILURE: 40;
39
+ BAD_CERTIFICATE: 42;
40
+ DECRYPT_ERROR: 51;
41
+ INTERNAL_ERROR: 80;
42
+ }>;
43
+ export declare const CIPHER_SUITE = 49195;
44
+ export declare const NAMED_GROUP: Readonly<{
45
+ secp256r1: 23;
46
+ }>;
47
+ export declare const EC_POINT_FORMAT: Readonly<{
48
+ uncompressed: 0;
49
+ }>;
50
+ export declare const HASH_ALG: Readonly<{
51
+ sha256: 4;
52
+ sha384: 5;
53
+ sha512: 6;
54
+ }>;
55
+ export declare const SIG_ALG: Readonly<{
56
+ rsa: 1;
57
+ ecdsa: 3;
58
+ }>;
59
+ export declare const CERT_TYPE: Readonly<{
60
+ ecdsa_sign: 64;
61
+ rsa_sign: 1;
62
+ }>;
63
+ export declare const EXTENSION: Readonly<{
64
+ SUPPORTED_GROUPS: 10;
65
+ EC_POINT_FORMATS: 11;
66
+ SIGNATURE_ALGORITHMS: 13;
67
+ EXTENDED_MASTER_SECRET: 23;
68
+ RENEGOTIATION_INFO: 65281;
69
+ }>;
70
+ export declare const FINISHED_LABEL: Readonly<{
71
+ CLIENT: "client finished";
72
+ SERVER: "server finished";
73
+ }>;
74
+ /** A parsed DTLS record from {@link parseRecords}. */
75
+ export interface Record {
76
+ type: number;
77
+ version: number;
78
+ epoch: number;
79
+ seq: number;
80
+ fragment: Buffer;
81
+ }
82
+ /** A parsed handshake message header from {@link parseHandshake}. */
83
+ export interface Handshake {
84
+ msgType: number;
85
+ length: number;
86
+ messageSeq: number;
87
+ fragmentOffset: number;
88
+ fragmentLength: number;
89
+ body: Buffer;
90
+ }
91
+ /** Encode a uint24 (3 bytes, big-endian). */
92
+ export declare function uint24(n: number): Buffer;
93
+ /** Read a uint24 at offset. */
94
+ export declare function readUint24(buf: Buffer, off: number): number;
95
+ /** Length-prefixed vector with a 1-byte length. */
96
+ export declare function vec8(body: Buffer): Buffer;
97
+ /** Length-prefixed vector with a 2-byte length. */
98
+ export declare function vec16(body: Buffer): Buffer;
99
+ /** Length-prefixed vector with a 3-byte length. */
100
+ export declare function vec24(body: Buffer): Buffer;
101
+ /**
102
+ * Encode a DTLS record (13-byte header + fragment).
103
+ * @param type - CONTENT_TYPE
104
+ * @param epoch
105
+ * @param seq - 48-bit sequence number
106
+ * @param fragment
107
+ * @param version
108
+ */
109
+ export declare function encodeRecord(type: number, epoch: number, seq: number, fragment: Buffer, version?: number): Buffer;
110
+ /**
111
+ * Parse one or more DTLS records from a datagram. Multiple records may be
112
+ * packed into a single UDP packet.
113
+ * @param packet
114
+ */
115
+ export declare function parseRecords(packet: Buffer): Record[];
116
+ /**
117
+ * Encode a DTLS handshake message header + body (unfragmented).
118
+ * @param msgType - HANDSHAKE_TYPE
119
+ * @param messageSeq
120
+ * @param body
121
+ */
122
+ export declare function encodeHandshake(msgType: number, messageSeq: number, body: Buffer): Buffer;
123
+ /**
124
+ * Parse a handshake message header.
125
+ * @param buf - starts at the handshake header
126
+ */
127
+ export declare function parseHandshake(buf: Buffer): Handshake;
@@ -0,0 +1,71 @@
1
+ /**
2
+ * @file ByteBufferQueue - Efficient byte buffer with O(1) append and O(n) read.
3
+ *
4
+ * This class provides efficient management of byte buffers with O(1) append operations
5
+ * and O(n) read operations. Clients can append entire buffers then copy data out across
6
+ * buffer boundaries.
7
+ *
8
+ * @license MIT
9
+ * @author nmhung1210
10
+ */
11
+ /**
12
+ * A ByteBufferQueue manages a queue of byte buffers with efficient operations.
13
+ *
14
+ * Invariants maintained:
15
+ * - size_ = sum of all buffer sizes - frontBufferOffset_
16
+ * - No buffer in the queue is empty
17
+ * - If queue is empty, frontBufferOffset_ = 0
18
+ * - Otherwise, frontBufferOffset_ < front buffer size
19
+ */
20
+ declare class ByteBufferQueue {
21
+ #private;
22
+ constructor();
23
+ /**
24
+ * Number of bytes that can be read.
25
+ * @returns {number}
26
+ */
27
+ get size(): number;
28
+ /**
29
+ * Returns true if no bytes are available to read.
30
+ * @returns {boolean}
31
+ */
32
+ get empty(): boolean;
33
+ /**
34
+ * Copies data into the given buffer. Consumes bytes from the queue.
35
+ * Returns the number of bytes written to bufferOut.
36
+ *
37
+ * @param {Buffer} bufferOut - Destination buffer to read into
38
+ * @returns {number} Number of bytes actually read
39
+ * @throws {TypeError} If bufferOut is not a Buffer
40
+ */
41
+ readInto(bufferOut: Buffer): number;
42
+ /**
43
+ * Appends a buffer to the queue. Takes ownership of the buffer.
44
+ * Empty buffers are ignored.
45
+ *
46
+ * @param {Buffer} buffer - Buffer to append
47
+ * @throws {TypeError} If buffer is not a Buffer
48
+ */
49
+ append(buffer: Buffer): void;
50
+ /**
51
+ * Clears all stored buffers.
52
+ */
53
+ clear(): void;
54
+ /**
55
+ * Reads and consumes exactly n bytes.
56
+ *
57
+ * @param {number} n - Number of bytes to read
58
+ * @returns {Buffer} Buffer containing exactly n bytes
59
+ * @throws {RangeError} If fewer than n bytes are available
60
+ */
61
+ read(n: number): Buffer;
62
+ /**
63
+ * Peeks at data without consuming it.
64
+ *
65
+ * @param {number} [n=this.#size] - Number of bytes to peek
66
+ * @returns {Buffer} Buffer containing up to n bytes (not consumed)
67
+ */
68
+ peek(n?: number): Buffer;
69
+ }
70
+ export default ByteBufferQueue;
71
+ export { ByteBufferQueue };
@@ -0,0 +1,152 @@
1
+ /**
2
+ * @file RTCError - WebRTC-specific error types.
3
+ *
4
+ * Implements the W3C RTCError interface
5
+ * (https://www.w3.org/TR/webrtc/#rtcerror-interface).
6
+ *
7
+ * Provides WebRTC-specific error types extending the standard Error class
8
+ * with additional error detail types and metadata fields.
9
+ *
10
+ * @license MIT
11
+ * @author nmhung1210
12
+ */
13
+ /**
14
+ * RTCErrorDetailType enum - Standardized WebRTC error details.
15
+ * Maps to RTCErrorDetailType from the WebRTC spec.
16
+ *
17
+ * @readonly
18
+ * @enum {string}
19
+ */
20
+ declare const RTCErrorDetailType: Readonly<{
21
+ readonly NONE: "none";
22
+ readonly DATA_CHANNEL_FAILURE: "data-channel-failure";
23
+ readonly DTLS_FAILURE: "dtls-failure";
24
+ readonly FINGERPRINT_FAILURE: "fingerprint-failure";
25
+ readonly SCTP_FAILURE: "sctp-failure";
26
+ readonly SDP_SYNTAX_ERROR: "sdp-syntax-error";
27
+ readonly HARDWARE_ENCODER_NOT_AVAILABLE: "hardware-encoder-not-available";
28
+ readonly HARDWARE_ENCODER_ERROR: "hardware-encoder-error";
29
+ readonly INVALID_STATE: "invalid-state";
30
+ readonly INVALID_MODIFICATION: "invalid-modification";
31
+ readonly INVALID_ACCESS_ERROR: "invalid-access-error";
32
+ readonly OPERATION_ERROR: "operation-error";
33
+ }>;
34
+ /**
35
+ * Error detail type string union.
36
+ */
37
+ type RTCErrorDetail = typeof RTCErrorDetailType[keyof typeof RTCErrorDetailType];
38
+ /**
39
+ * Error initialization dictionary.
40
+ */
41
+ interface RTCErrorInit {
42
+ errorDetail?: string;
43
+ sdpLineNumber?: number | null;
44
+ httpRequestStatusCode?: number | null;
45
+ sctpCauseCode?: number | null;
46
+ receivedAlert?: number | null;
47
+ sentAlert?: number | null;
48
+ }
49
+ /**
50
+ * Native WebRTC error object shape.
51
+ */
52
+ interface NativeRTCError {
53
+ error_detail?: string;
54
+ sctp_cause_code?: number;
55
+ message?: string;
56
+ }
57
+ /**
58
+ * JSON representation of an RTCError.
59
+ */
60
+ interface RTCErrorJSON {
61
+ name: string;
62
+ message: string;
63
+ errorDetail: string;
64
+ sdpLineNumber?: number;
65
+ httpRequestStatusCode?: number;
66
+ sctpCauseCode?: number;
67
+ receivedAlert?: number;
68
+ sentAlert?: number;
69
+ }
70
+ /**
71
+ * RTCError extends Error with WebRTC-specific error details.
72
+ *
73
+ * @extends Error
74
+ */
75
+ declare class RTCError extends Error {
76
+ #private;
77
+ /** Export error detail types as static property */
78
+ static readonly DetailType: Readonly<{
79
+ readonly NONE: "none";
80
+ readonly DATA_CHANNEL_FAILURE: "data-channel-failure";
81
+ readonly DTLS_FAILURE: "dtls-failure";
82
+ readonly FINGERPRINT_FAILURE: "fingerprint-failure";
83
+ readonly SCTP_FAILURE: "sctp-failure";
84
+ readonly SDP_SYNTAX_ERROR: "sdp-syntax-error";
85
+ readonly HARDWARE_ENCODER_NOT_AVAILABLE: "hardware-encoder-not-available";
86
+ readonly HARDWARE_ENCODER_ERROR: "hardware-encoder-error";
87
+ readonly INVALID_STATE: "invalid-state";
88
+ readonly INVALID_MODIFICATION: "invalid-modification";
89
+ readonly INVALID_ACCESS_ERROR: "invalid-access-error";
90
+ readonly OPERATION_ERROR: "operation-error";
91
+ }>;
92
+ /**
93
+ * Creates a new RTCError.
94
+ *
95
+ * @param {RTCErrorInit} [init={}] - Error initialization dictionary
96
+ * @param {string} [init.errorDetail='none'] - Error detail type
97
+ * @param {number} [init.sdpLineNumber] - SDP line number where error occurred
98
+ * @param {number} [init.httpRequestStatusCode] - HTTP status code if relevant
99
+ * @param {number} [init.sctpCauseCode] - SCTP cause code
100
+ * @param {number} [init.receivedAlert] - TLS alert received
101
+ * @param {number} [init.sentAlert] - TLS alert sent
102
+ * @param {string} [message=''] - Error message
103
+ */
104
+ constructor(init?: RTCErrorInit, message?: string);
105
+ /**
106
+ * RTCErrorDetailType - specific error category.
107
+ * @type {string}
108
+ */
109
+ get errorDetail(): string;
110
+ /**
111
+ * SDP line number where the error occurred (if applicable).
112
+ * @type {number|null}
113
+ */
114
+ get sdpLineNumber(): number | null;
115
+ /**
116
+ * HTTP request status code (if applicable).
117
+ * @type {number|null}
118
+ */
119
+ get httpRequestStatusCode(): number | null;
120
+ /**
121
+ * SCTP cause code (if applicable).
122
+ * @type {number|null}
123
+ */
124
+ get sctpCauseCode(): number | null;
125
+ /**
126
+ * TLS alert value received (if applicable).
127
+ * @type {number|null}
128
+ */
129
+ get receivedAlert(): number | null;
130
+ /**
131
+ * TLS alert value sent (if applicable).
132
+ * @type {number|null}
133
+ */
134
+ get sentAlert(): number | null;
135
+ /**
136
+ * Converts error to JSON representation.
137
+ * @returns {Object} JSON representation of the error
138
+ */
139
+ toJSON(): RTCErrorJSON;
140
+ /**
141
+ * Creates RTCError from a native WebRTC error object.
142
+ * @param {Object} nativeError - Native error object
143
+ * @param {string} [nativeError.error_detail] - Error detail type
144
+ * @param {number} [nativeError.sctp_cause_code] - SCTP cause code
145
+ * @param {string} [nativeError.message] - Error message
146
+ * @returns {RTCError}
147
+ */
148
+ static fromNative(nativeError: NativeRTCError): RTCError;
149
+ }
150
+ export default RTCError;
151
+ export { RTCError, RTCErrorDetailType };
152
+ export type { RTCErrorInit, RTCErrorDetail, NativeRTCError, RTCErrorJSON };
@@ -0,0 +1,161 @@
1
+ /**
2
+ * @file RTCIceCandidate - ICE candidate representation.
3
+ *
4
+ * Implements the W3C RTCIceCandidate interface
5
+ * (https://www.w3.org/TR/webrtc/#rtcicecandidate-interface).
6
+ *
7
+ * Represents an ICE (Interactive Connectivity Establishment) candidate that
8
+ * describes a potential way to establish a connection with a peer.
9
+ *
10
+ * @license MIT
11
+ * @author nmhung1210
12
+ */
13
+ /**
14
+ * Initialization dictionary for RTCIceCandidate.
15
+ */
16
+ interface RTCIceCandidateInit {
17
+ candidate?: string;
18
+ sdpMid?: string | null;
19
+ sdpMLineIndex?: number | null;
20
+ usernameFragment?: string | null;
21
+ }
22
+ /**
23
+ * Parsed attributes extracted from an ICE candidate string.
24
+ */
25
+ interface ParsedCandidateAttributes {
26
+ foundation: string | null;
27
+ component: string | null;
28
+ protocol: string | null;
29
+ priority: number | null;
30
+ address: string | null;
31
+ port: number | null;
32
+ type: string | null;
33
+ tcpType: string | null;
34
+ relatedAddress: string | null;
35
+ relatedPort: number | null;
36
+ }
37
+ /**
38
+ * JSON representation of an RTCIceCandidate.
39
+ */
40
+ interface RTCIceCandidateJSON {
41
+ candidate: string;
42
+ sdpMid: string | null;
43
+ sdpMLineIndex: number | null;
44
+ usernameFragment?: string;
45
+ }
46
+ /**
47
+ * RTCIceCandidate represents a potential method for establishing connectivity.
48
+ *
49
+ * ICE candidates are described using SDP (Session Description Protocol) syntax.
50
+ * Each candidate describes a single address/port combination and transport protocol.
51
+ */
52
+ declare class RTCIceCandidate {
53
+ #private;
54
+ /**
55
+ * Creates a new RTCIceCandidate.
56
+ *
57
+ * @param {RTCIceCandidateInit} [candidateInit={}] - Initialization dictionary
58
+ * @param {string} [candidateInit.candidate=''] - SDP candidate string
59
+ * @param {string|null} [candidateInit.sdpMid] - Media stream ID
60
+ * @param {number|null} [candidateInit.sdpMLineIndex] - M-line index
61
+ * @param {string} [candidateInit.usernameFragment] - ICE username fragment
62
+ * @throws {TypeError} If both sdpMid and sdpMLineIndex are null
63
+ */
64
+ constructor(candidateInit?: RTCIceCandidateInit);
65
+ /**
66
+ * SDP candidate attribute containing the candidate description.
67
+ * @type {string}
68
+ */
69
+ get candidate(): string;
70
+ /**
71
+ * Media stream identification tag.
72
+ * @type {string|null}
73
+ */
74
+ get sdpMid(): string | null;
75
+ /**
76
+ * Index of the m-line in the SDP this candidate is associated with.
77
+ * @type {number|null}
78
+ */
79
+ get sdpMLineIndex(): number | null;
80
+ /**
81
+ * ICE username fragment.
82
+ * @type {string|null}
83
+ */
84
+ get usernameFragment(): string | null;
85
+ /**
86
+ * Unique identifier for this candidate.
87
+ * @type {string|null}
88
+ */
89
+ get foundation(): string | null;
90
+ /**
91
+ * Component identifier (rtp=1, rtcp=2).
92
+ * @type {string|null}
93
+ */
94
+ get component(): string | null;
95
+ /**
96
+ * Priority value for this candidate.
97
+ * Higher priority candidates are preferred.
98
+ * @type {number|null}
99
+ */
100
+ get priority(): number | null;
101
+ /**
102
+ * IP address of this candidate.
103
+ * @type {string|null}
104
+ */
105
+ get address(): string | null;
106
+ /**
107
+ * Transport protocol (udp/tcp).
108
+ * @type {string|null}
109
+ */
110
+ get protocol(): string | null;
111
+ /**
112
+ * Port number.
113
+ * @type {number|null}
114
+ */
115
+ get port(): number | null;
116
+ /**
117
+ * Type of candidate (host, srflx, prflx, relay).
118
+ * @type {string|null}
119
+ */
120
+ get type(): string | null;
121
+ /**
122
+ * TCP candidate type (active, passive, so).
123
+ * Only applicable for TCP candidates.
124
+ * @type {string|null}
125
+ */
126
+ get tcpType(): string | null;
127
+ /**
128
+ * Related address for reflexive/relay candidates.
129
+ * @type {string|null}
130
+ */
131
+ get relatedAddress(): string | null;
132
+ /**
133
+ * Related port for reflexive/relay candidates.
134
+ * @type {number|null}
135
+ */
136
+ get relatedPort(): number | null;
137
+ /**
138
+ * Converts candidate to JSON representation.
139
+ * @returns {Object} JSON representation
140
+ */
141
+ toJSON(): RTCIceCandidateJSON;
142
+ /**
143
+ * Creates an RTCIceCandidate from a candidate string.
144
+ *
145
+ * @param {string} candidateStr - ICE candidate string
146
+ * @param {string|null} [sdpMid=null] - Media stream ID
147
+ * @param {number|null} [sdpMLineIndex=0] - M-line index
148
+ * @returns {RTCIceCandidate}
149
+ */
150
+ static fromString(candidateStr: string, sdpMid?: string | null, sdpMLineIndex?: number | null): RTCIceCandidate;
151
+ /**
152
+ * Validates if a string is a valid candidate format.
153
+ *
154
+ * @param {string} candidateStr - String to validate
155
+ * @returns {boolean} True if valid candidate format
156
+ */
157
+ static isValid(candidateStr: string): boolean;
158
+ }
159
+ export default RTCIceCandidate;
160
+ export { RTCIceCandidate };
161
+ export type { RTCIceCandidateInit, ParsedCandidateAttributes, RTCIceCandidateJSON };
@@ -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 };