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.
- package/README.md +94 -85
- package/dist/index.cjs +20 -5421
- package/dist/index.mjs +25 -5413
- package/dist/types/crypto/der.d.ts +107 -0
- package/dist/types/crypto/x509.d.ts +56 -0
- package/dist/types/datachannel/RTCDataChannel.d.ts +179 -0
- package/dist/types/dtls/RTCCertificate.d.ts +163 -0
- package/dist/types/dtls/cipher.d.ts +81 -0
- package/dist/types/dtls/connection.d.ts +81 -0
- package/dist/types/dtls/prf.d.ts +29 -0
- package/dist/types/dtls/protocol.d.ts +127 -0
- package/dist/types/foundation/ByteBufferQueue.d.ts +71 -0
- package/dist/types/foundation/RTCError.d.ts +152 -0
- package/dist/types/ice/RTCIceCandidate.d.ts +161 -0
- package/dist/types/ice/ice-agent.d.ts +154 -0
- package/dist/types/ice/stun-message.d.ts +92 -0
- package/dist/types/index.d.ts +29 -0
- package/dist/types/peerconnection/RTCPeerConnection.d.ts +74 -0
- package/dist/types/sctp/association.d.ts +77 -0
- package/dist/types/sctp/chunks.d.ts +200 -0
- package/dist/types/sctp/crc32c.d.ts +24 -0
- package/dist/types/sctp/datachannel-manager.d.ts +51 -0
- package/dist/types/sctp/dcep.d.ts +56 -0
- package/dist/types/sdp/RTCSessionDescription.d.ts +73 -0
- package/dist/types/sdp/sdp-utils.d.ts +103 -0
- package/dist/types/stun/stun-client.d.ts +119 -0
- package/dist/types/transport-stack.d.ts +68 -0
- package/package.json +26 -21
- package/src/crypto/der.ts +205 -0
- package/src/crypto/x509.ts +146 -0
- package/src/datachannel/RTCDataChannel.ts +388 -0
- package/src/dtls/RTCCertificate.ts +396 -0
- package/src/dtls/cipher.ts +198 -0
- package/src/dtls/connection.ts +974 -0
- package/src/dtls/prf.ts +62 -0
- package/src/dtls/protocol.ts +204 -0
- package/src/foundation/{ByteBufferQueue.js → ByteBufferQueue.ts} +74 -72
- package/src/foundation/{RTCError.js → RTCError.ts} +110 -60
- package/src/ice/{RTCIceCandidate.js → RTCIceCandidate.ts} +140 -92
- package/src/ice/ice-agent.ts +609 -0
- package/src/ice/stun-message.ts +260 -0
- package/src/index.ts +72 -0
- package/src/peerconnection/RTCPeerConnection.ts +430 -0
- package/src/sctp/association.ts +523 -0
- package/src/sctp/chunks.ts +350 -0
- package/src/sctp/crc32c.ts +57 -0
- package/src/sctp/datachannel-manager.ts +187 -0
- package/src/sctp/dcep.ts +94 -0
- package/src/sdp/{RTCSessionDescription.js → RTCSessionDescription.ts} +42 -29
- package/src/sdp/sdp-utils.ts +229 -0
- package/src/stun/stun-client.ts +936 -0
- package/src/transport-stack.ts +165 -0
- package/dist/index.cjs.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/src/datachannel/RTCDataChannel.js +0 -354
- package/src/dtls/RTCCertificate.js +0 -310
- package/src/dtls/RTCDtlsTransport.js +0 -247
- package/src/ice/RTCIceTransport.js +0 -998
- package/src/index.d.ts +0 -400
- package/src/index.js +0 -92
- package/src/network/network-transport.js +0 -478
- package/src/peerconnection/RTCPeerConnection.js +0 -851
- package/src/sctp/RTCSctpTransport.js +0 -253
- package/src/sdp/sdp-utils.js +0 -224
- package/src/stun/stun-client.js +0 -643
|
@@ -1,28 +1,90 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
2
|
+
* @file RTCIceCandidate - ICE candidate representation.
|
|
3
|
+
*
|
|
4
|
+
* Implements the W3C RTCIceCandidate interface
|
|
5
|
+
* (https://www.w3.org/TR/webrtc/#rtcicecandidate-interface).
|
|
6
|
+
*
|
|
7
7
|
* Represents an ICE (Interactive Connectivity Establishment) candidate that
|
|
8
8
|
* describes a potential way to establish a connection with a peer.
|
|
9
|
-
*
|
|
10
|
-
* @license
|
|
9
|
+
*
|
|
10
|
+
* @license MIT
|
|
11
11
|
* @author nmhung1210
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
'use strict';
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Initialization dictionary for RTCIceCandidate.
|
|
18
|
+
*/
|
|
19
|
+
interface RTCIceCandidateInit {
|
|
20
|
+
candidate?: string;
|
|
21
|
+
sdpMid?: string | null;
|
|
22
|
+
sdpMLineIndex?: number | null;
|
|
23
|
+
usernameFragment?: string | null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Parsed attributes extracted from an ICE candidate string.
|
|
28
|
+
*/
|
|
29
|
+
interface ParsedCandidateAttributes {
|
|
30
|
+
foundation: string | null;
|
|
31
|
+
component: string | null;
|
|
32
|
+
protocol: string | null;
|
|
33
|
+
priority: number | null;
|
|
34
|
+
address: string | null;
|
|
35
|
+
port: number | null;
|
|
36
|
+
type: string | null;
|
|
37
|
+
tcpType: string | null;
|
|
38
|
+
relatedAddress: string | null;
|
|
39
|
+
relatedPort: number | null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* JSON representation of an RTCIceCandidate.
|
|
44
|
+
*/
|
|
45
|
+
interface RTCIceCandidateJSON {
|
|
46
|
+
candidate: string;
|
|
47
|
+
sdpMid: string | null;
|
|
48
|
+
sdpMLineIndex: number | null;
|
|
49
|
+
usernameFragment?: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
16
52
|
/**
|
|
17
53
|
* RTCIceCandidate represents a potential method for establishing connectivity.
|
|
18
|
-
*
|
|
54
|
+
*
|
|
19
55
|
* ICE candidates are described using SDP (Session Description Protocol) syntax.
|
|
20
56
|
* Each candidate describes a single address/port combination and transport protocol.
|
|
21
57
|
*/
|
|
22
58
|
class RTCIceCandidate {
|
|
59
|
+
/**
|
|
60
|
+
* SDP candidate string.
|
|
61
|
+
* @private {string}
|
|
62
|
+
*/
|
|
63
|
+
#candidate: string;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Media stream identification.
|
|
67
|
+
* @private {string|null}
|
|
68
|
+
*/
|
|
69
|
+
#sdpMid: string | null;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Media line index (zero-based).
|
|
73
|
+
* @private {number|null}
|
|
74
|
+
*/
|
|
75
|
+
#sdpMLineIndex: number | null;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* ICE username fragment.
|
|
79
|
+
* @private {string|null}
|
|
80
|
+
*/
|
|
81
|
+
#usernameFragment: string | null;
|
|
82
|
+
|
|
83
|
+
#parsedAttributes: ParsedCandidateAttributes;
|
|
84
|
+
|
|
23
85
|
/**
|
|
24
86
|
* Creates a new RTCIceCandidate.
|
|
25
|
-
*
|
|
87
|
+
*
|
|
26
88
|
* @param {RTCIceCandidateInit} [candidateInit={}] - Initialization dictionary
|
|
27
89
|
* @param {string} [candidateInit.candidate=''] - SDP candidate string
|
|
28
90
|
* @param {string|null} [candidateInit.sdpMid] - Media stream ID
|
|
@@ -30,51 +92,35 @@ class RTCIceCandidate {
|
|
|
30
92
|
* @param {string} [candidateInit.usernameFragment] - ICE username fragment
|
|
31
93
|
* @throws {TypeError} If both sdpMid and sdpMLineIndex are null
|
|
32
94
|
*/
|
|
33
|
-
constructor(candidateInit = {}) {
|
|
95
|
+
constructor(candidateInit: RTCIceCandidateInit = {}) {
|
|
34
96
|
// Validate that at least one of sdpMid or sdpMLineIndex is present
|
|
35
97
|
if (candidateInit.sdpMid === null && candidateInit.sdpMLineIndex === null) {
|
|
36
98
|
throw new TypeError('sdpMid and sdpMLineIndex are both null');
|
|
37
99
|
}
|
|
38
100
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
this
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Media stream identification.
|
|
47
|
-
* @private {string|null}
|
|
48
|
-
*/
|
|
49
|
-
this._sdpMid = candidateInit.sdpMid !== undefined ? candidateInit.sdpMid : null;
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Media line index (zero-based).
|
|
53
|
-
* @private {number|null}
|
|
54
|
-
*/
|
|
55
|
-
this._sdpMLineIndex = candidateInit.sdpMLineIndex !== undefined ?
|
|
101
|
+
this.#candidate = candidateInit.candidate || '';
|
|
102
|
+
|
|
103
|
+
this.#sdpMid = candidateInit.sdpMid !== undefined ? candidateInit.sdpMid : null;
|
|
104
|
+
|
|
105
|
+
this.#sdpMLineIndex = candidateInit.sdpMLineIndex !== undefined ?
|
|
56
106
|
candidateInit.sdpMLineIndex : null;
|
|
57
107
|
|
|
58
|
-
|
|
59
|
-
* ICE username fragment.
|
|
60
|
-
* @private {string|null}
|
|
61
|
-
*/
|
|
62
|
-
this._usernameFragment = candidateInit.usernameFragment || null;
|
|
108
|
+
this.#usernameFragment = candidateInit.usernameFragment || null;
|
|
63
109
|
|
|
64
110
|
// Parse candidate string for detailed attributes
|
|
65
|
-
this
|
|
111
|
+
this.#parsedAttributes = this.#parseCandidate(this.#candidate);
|
|
66
112
|
}
|
|
67
113
|
|
|
68
114
|
/**
|
|
69
115
|
* Parses an ICE candidate string to extract attributes.
|
|
70
116
|
* Format: "candidate:foundation component protocol priority address port typ type [raddr reladdr] [rport relport]"
|
|
71
|
-
*
|
|
117
|
+
*
|
|
72
118
|
* @private
|
|
73
119
|
* @param {string} candidateStr - Candidate string to parse
|
|
74
120
|
* @returns {Object} Parsed attributes
|
|
75
121
|
*/
|
|
76
|
-
|
|
77
|
-
const attrs = {
|
|
122
|
+
#parseCandidate(candidateStr: string): ParsedCandidateAttributes {
|
|
123
|
+
const attrs: ParsedCandidateAttributes = {
|
|
78
124
|
foundation: null,
|
|
79
125
|
component: null,
|
|
80
126
|
protocol: null,
|
|
@@ -84,7 +130,7 @@ class RTCIceCandidate {
|
|
|
84
130
|
type: null,
|
|
85
131
|
tcpType: null,
|
|
86
132
|
relatedAddress: null,
|
|
87
|
-
relatedPort: null
|
|
133
|
+
relatedPort: null,
|
|
88
134
|
};
|
|
89
135
|
|
|
90
136
|
if (!candidateStr || !candidateStr.startsWith('candidate:')) {
|
|
@@ -93,35 +139,35 @@ class RTCIceCandidate {
|
|
|
93
139
|
|
|
94
140
|
// Remove "candidate:" prefix
|
|
95
141
|
const parts = candidateStr.substring(10).trim().split(/\s+/);
|
|
96
|
-
|
|
142
|
+
|
|
97
143
|
if (parts.length < 8) {
|
|
98
144
|
return attrs;
|
|
99
145
|
}
|
|
100
146
|
|
|
101
147
|
// Parse fixed fields
|
|
102
|
-
attrs.foundation = parts[0]
|
|
103
|
-
attrs.component = parts[1]
|
|
104
|
-
attrs.protocol = parts[2]
|
|
105
|
-
attrs.priority = parseInt(parts[3]
|
|
106
|
-
attrs.address = parts[4]
|
|
107
|
-
attrs.port = parseInt(parts[5]
|
|
108
|
-
|
|
148
|
+
attrs.foundation = parts[0]!;
|
|
149
|
+
attrs.component = parts[1]!;
|
|
150
|
+
attrs.protocol = parts[2]!.toLowerCase();
|
|
151
|
+
attrs.priority = parseInt(parts[3]!, 10);
|
|
152
|
+
attrs.address = parts[4]!;
|
|
153
|
+
attrs.port = parseInt(parts[5]!, 10);
|
|
154
|
+
|
|
109
155
|
// parts[6] should be "typ"
|
|
110
156
|
if (parts[6] === 'typ') {
|
|
111
|
-
attrs.type = parts[7]
|
|
157
|
+
attrs.type = parts[7]!;
|
|
112
158
|
}
|
|
113
159
|
|
|
114
160
|
// Parse optional attributes
|
|
115
161
|
for (let i = 8; i < parts.length; i += 2) {
|
|
116
162
|
const key = parts[i];
|
|
117
163
|
const value = parts[i + 1];
|
|
118
|
-
|
|
164
|
+
|
|
119
165
|
if (key === 'raddr') {
|
|
120
|
-
attrs.relatedAddress = value
|
|
166
|
+
attrs.relatedAddress = value!;
|
|
121
167
|
} else if (key === 'rport') {
|
|
122
|
-
attrs.relatedPort = parseInt(value
|
|
168
|
+
attrs.relatedPort = parseInt(value!, 10);
|
|
123
169
|
} else if (key === 'tcptype') {
|
|
124
|
-
attrs.tcpType = value
|
|
170
|
+
attrs.tcpType = value!;
|
|
125
171
|
}
|
|
126
172
|
}
|
|
127
173
|
|
|
@@ -132,48 +178,48 @@ class RTCIceCandidate {
|
|
|
132
178
|
* SDP candidate attribute containing the candidate description.
|
|
133
179
|
* @type {string}
|
|
134
180
|
*/
|
|
135
|
-
get candidate() {
|
|
136
|
-
return this
|
|
181
|
+
get candidate(): string {
|
|
182
|
+
return this.#candidate;
|
|
137
183
|
}
|
|
138
184
|
|
|
139
185
|
/**
|
|
140
186
|
* Media stream identification tag.
|
|
141
187
|
* @type {string|null}
|
|
142
188
|
*/
|
|
143
|
-
get sdpMid() {
|
|
144
|
-
return this
|
|
189
|
+
get sdpMid(): string | null {
|
|
190
|
+
return this.#sdpMid;
|
|
145
191
|
}
|
|
146
192
|
|
|
147
193
|
/**
|
|
148
194
|
* Index of the m-line in the SDP this candidate is associated with.
|
|
149
195
|
* @type {number|null}
|
|
150
196
|
*/
|
|
151
|
-
get sdpMLineIndex() {
|
|
152
|
-
return this
|
|
197
|
+
get sdpMLineIndex(): number | null {
|
|
198
|
+
return this.#sdpMLineIndex;
|
|
153
199
|
}
|
|
154
200
|
|
|
155
201
|
/**
|
|
156
202
|
* ICE username fragment.
|
|
157
203
|
* @type {string|null}
|
|
158
204
|
*/
|
|
159
|
-
get usernameFragment() {
|
|
160
|
-
return this
|
|
205
|
+
get usernameFragment(): string | null {
|
|
206
|
+
return this.#usernameFragment;
|
|
161
207
|
}
|
|
162
208
|
|
|
163
209
|
/**
|
|
164
210
|
* Unique identifier for this candidate.
|
|
165
211
|
* @type {string|null}
|
|
166
212
|
*/
|
|
167
|
-
get foundation() {
|
|
168
|
-
return this.
|
|
213
|
+
get foundation(): string | null {
|
|
214
|
+
return this.#parsedAttributes.foundation;
|
|
169
215
|
}
|
|
170
216
|
|
|
171
217
|
/**
|
|
172
218
|
* Component identifier (rtp=1, rtcp=2).
|
|
173
219
|
* @type {string|null}
|
|
174
220
|
*/
|
|
175
|
-
get component() {
|
|
176
|
-
return this.
|
|
221
|
+
get component(): string | null {
|
|
222
|
+
return this.#parsedAttributes.component;
|
|
177
223
|
}
|
|
178
224
|
|
|
179
225
|
/**
|
|
@@ -181,40 +227,40 @@ class RTCIceCandidate {
|
|
|
181
227
|
* Higher priority candidates are preferred.
|
|
182
228
|
* @type {number|null}
|
|
183
229
|
*/
|
|
184
|
-
get priority() {
|
|
185
|
-
return this.
|
|
230
|
+
get priority(): number | null {
|
|
231
|
+
return this.#parsedAttributes.priority;
|
|
186
232
|
}
|
|
187
233
|
|
|
188
234
|
/**
|
|
189
235
|
* IP address of this candidate.
|
|
190
236
|
* @type {string|null}
|
|
191
237
|
*/
|
|
192
|
-
get address() {
|
|
193
|
-
return this.
|
|
238
|
+
get address(): string | null {
|
|
239
|
+
return this.#parsedAttributes.address;
|
|
194
240
|
}
|
|
195
241
|
|
|
196
242
|
/**
|
|
197
243
|
* Transport protocol (udp/tcp).
|
|
198
244
|
* @type {string|null}
|
|
199
245
|
*/
|
|
200
|
-
get protocol() {
|
|
201
|
-
return this.
|
|
246
|
+
get protocol(): string | null {
|
|
247
|
+
return this.#parsedAttributes.protocol;
|
|
202
248
|
}
|
|
203
249
|
|
|
204
250
|
/**
|
|
205
251
|
* Port number.
|
|
206
252
|
* @type {number|null}
|
|
207
253
|
*/
|
|
208
|
-
get port() {
|
|
209
|
-
return this.
|
|
254
|
+
get port(): number | null {
|
|
255
|
+
return this.#parsedAttributes.port;
|
|
210
256
|
}
|
|
211
257
|
|
|
212
258
|
/**
|
|
213
259
|
* Type of candidate (host, srflx, prflx, relay).
|
|
214
260
|
* @type {string|null}
|
|
215
261
|
*/
|
|
216
|
-
get type() {
|
|
217
|
-
return this.
|
|
262
|
+
get type(): string | null {
|
|
263
|
+
return this.#parsedAttributes.type;
|
|
218
264
|
}
|
|
219
265
|
|
|
220
266
|
/**
|
|
@@ -222,39 +268,39 @@ class RTCIceCandidate {
|
|
|
222
268
|
* Only applicable for TCP candidates.
|
|
223
269
|
* @type {string|null}
|
|
224
270
|
*/
|
|
225
|
-
get tcpType() {
|
|
226
|
-
return this.
|
|
271
|
+
get tcpType(): string | null {
|
|
272
|
+
return this.#parsedAttributes.tcpType;
|
|
227
273
|
}
|
|
228
274
|
|
|
229
275
|
/**
|
|
230
276
|
* Related address for reflexive/relay candidates.
|
|
231
277
|
* @type {string|null}
|
|
232
278
|
*/
|
|
233
|
-
get relatedAddress() {
|
|
234
|
-
return this.
|
|
279
|
+
get relatedAddress(): string | null {
|
|
280
|
+
return this.#parsedAttributes.relatedAddress;
|
|
235
281
|
}
|
|
236
282
|
|
|
237
283
|
/**
|
|
238
284
|
* Related port for reflexive/relay candidates.
|
|
239
285
|
* @type {number|null}
|
|
240
286
|
*/
|
|
241
|
-
get relatedPort() {
|
|
242
|
-
return this.
|
|
287
|
+
get relatedPort(): number | null {
|
|
288
|
+
return this.#parsedAttributes.relatedPort;
|
|
243
289
|
}
|
|
244
290
|
|
|
245
291
|
/**
|
|
246
292
|
* Converts candidate to JSON representation.
|
|
247
293
|
* @returns {Object} JSON representation
|
|
248
294
|
*/
|
|
249
|
-
toJSON() {
|
|
250
|
-
const json = {
|
|
251
|
-
candidate: this
|
|
252
|
-
sdpMid: this
|
|
253
|
-
sdpMLineIndex: this
|
|
295
|
+
toJSON(): RTCIceCandidateJSON {
|
|
296
|
+
const json: RTCIceCandidateJSON = {
|
|
297
|
+
candidate: this.#candidate,
|
|
298
|
+
sdpMid: this.#sdpMid,
|
|
299
|
+
sdpMLineIndex: this.#sdpMLineIndex,
|
|
254
300
|
};
|
|
255
301
|
|
|
256
|
-
if (this
|
|
257
|
-
json.usernameFragment = this
|
|
302
|
+
if (this.#usernameFragment) {
|
|
303
|
+
json.usernameFragment = this.#usernameFragment;
|
|
258
304
|
}
|
|
259
305
|
|
|
260
306
|
return json;
|
|
@@ -262,31 +308,31 @@ class RTCIceCandidate {
|
|
|
262
308
|
|
|
263
309
|
/**
|
|
264
310
|
* Creates an RTCIceCandidate from a candidate string.
|
|
265
|
-
*
|
|
311
|
+
*
|
|
266
312
|
* @param {string} candidateStr - ICE candidate string
|
|
267
313
|
* @param {string|null} [sdpMid=null] - Media stream ID
|
|
268
314
|
* @param {number|null} [sdpMLineIndex=0] - M-line index
|
|
269
315
|
* @returns {RTCIceCandidate}
|
|
270
316
|
*/
|
|
271
|
-
static fromString(candidateStr, sdpMid = null, sdpMLineIndex = 0) {
|
|
317
|
+
static fromString(candidateStr: string, sdpMid: string | null = null, sdpMLineIndex: number | null = 0): RTCIceCandidate {
|
|
272
318
|
return new RTCIceCandidate({
|
|
273
319
|
candidate: candidateStr,
|
|
274
320
|
sdpMid,
|
|
275
|
-
sdpMLineIndex
|
|
321
|
+
sdpMLineIndex,
|
|
276
322
|
});
|
|
277
323
|
}
|
|
278
324
|
|
|
279
325
|
/**
|
|
280
326
|
* Validates if a string is a valid candidate format.
|
|
281
|
-
*
|
|
327
|
+
*
|
|
282
328
|
* @param {string} candidateStr - String to validate
|
|
283
329
|
* @returns {boolean} True if valid candidate format
|
|
284
330
|
*/
|
|
285
|
-
static isValid(candidateStr) {
|
|
331
|
+
static isValid(candidateStr: string): boolean {
|
|
286
332
|
if (!candidateStr || typeof candidateStr !== 'string') {
|
|
287
333
|
return false;
|
|
288
334
|
}
|
|
289
|
-
|
|
335
|
+
|
|
290
336
|
// Must start with "candidate:"
|
|
291
337
|
if (!candidateStr.startsWith('candidate:')) {
|
|
292
338
|
return false;
|
|
@@ -298,4 +344,6 @@ class RTCIceCandidate {
|
|
|
298
344
|
}
|
|
299
345
|
}
|
|
300
346
|
|
|
301
|
-
|
|
347
|
+
export default RTCIceCandidate;
|
|
348
|
+
export { RTCIceCandidate };
|
|
349
|
+
export type { RTCIceCandidateInit, ParsedCandidateAttributes, RTCIceCandidateJSON };
|