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
@@ -1,478 +0,0 @@
1
- /**
2
- * @file network-transport.js
3
- * @description Real UDP/TCP network transport implementation
4
- * @module network/network-transport
5
- *
6
- * Provides real networking capabilities using Node.js net and dgram packages
7
- */
8
-
9
- 'use strict';
10
-
11
- const dgram = require('dgram');
12
- const net = require('net');
13
- const EventEmitter = require('events');
14
- const crypto = require('crypto');
15
-
16
- /**
17
- * Transport protocol types
18
- */
19
- const TransportProtocol = Object.freeze({
20
- UDP: 'udp',
21
- TCP: 'tcp'
22
- });
23
-
24
- /**
25
- * @class NetworkTransport
26
- * @extends EventEmitter
27
- * @description Base class for network transport
28
- *
29
- * Events:
30
- * - 'data': (data, rinfo) - Data received
31
- * - 'error': (error) - Error occurred
32
- * - 'listening': () - Socket is listening
33
- * - 'close': () - Socket closed
34
- */
35
- class NetworkTransport extends EventEmitter {
36
- constructor(protocol = TransportProtocol.UDP) {
37
- super();
38
- this.protocol = protocol;
39
- this.socket = null;
40
- this.localAddress = null;
41
- this.localPort = null;
42
- this.isListening = false;
43
- }
44
-
45
- /**
46
- * Bind to a local address and port
47
- * @param {number} [port=0] - Port to bind (0 for random)
48
- * @param {string} [address='0.0.0.0'] - Address to bind
49
- * @returns {Promise<{address: string, port: number}>}
50
- */
51
- async bind(port = 0, address = '0.0.0.0') {
52
- throw new Error('Must be implemented by subclass');
53
- }
54
-
55
- /**
56
- * Send data to remote address
57
- * @param {Buffer} data - Data to send
58
- * @param {string} address - Remote address
59
- * @param {number} port - Remote port
60
- * @returns {Promise<void>}
61
- */
62
- async send(data, address, port) {
63
- throw new Error('Must be implemented by subclass');
64
- }
65
-
66
- /**
67
- * Close the transport
68
- */
69
- close() {
70
- if (this.socket) {
71
- this.socket.close();
72
- this.socket = null;
73
- }
74
- this.isListening = false;
75
- }
76
- }
77
-
78
- /**
79
- * @class UDPTransport
80
- * @extends NetworkTransport
81
- * @description UDP transport implementation using dgram
82
- */
83
- class UDPTransport extends NetworkTransport {
84
- constructor() {
85
- super(TransportProtocol.UDP);
86
- }
87
-
88
- /**
89
- * Bind to a local address and port
90
- * @param {number} [port=0] - Port to bind (0 for random)
91
- * @param {string} [address='0.0.0.0'] - Address to bind
92
- * @returns {Promise<{address: string, port: number}>}
93
- */
94
- async bind(port = 0, address = '0.0.0.0') {
95
- if (this.socket) {
96
- throw new Error('Already bound');
97
- }
98
-
99
- return new Promise((resolve, reject) => {
100
- this.socket = dgram.createSocket('udp4');
101
-
102
- this.socket.on('message', (msg, rinfo) => {
103
- this.emit('data', msg, rinfo);
104
- });
105
-
106
- this.socket.on('error', (error) => {
107
- this.emit('error', error);
108
- });
109
-
110
- this.socket.on('close', () => {
111
- this.isListening = false;
112
- this.emit('close');
113
- });
114
-
115
- this.socket.bind(port, address, () => {
116
- const addr = this.socket.address();
117
- this.localAddress = addr.address;
118
- this.localPort = addr.port;
119
- this.isListening = true;
120
- this.emit('listening');
121
- resolve({ address: addr.address, port: addr.port });
122
- });
123
- });
124
- }
125
-
126
- /**
127
- * Send data to remote address
128
- * @param {Buffer} data - Data to send
129
- * @param {string} address - Remote address
130
- * @param {number} port - Remote port
131
- * @returns {Promise<void>}
132
- */
133
- async send(data, address, port) {
134
- if (!this.socket) {
135
- throw new Error('Socket not bound');
136
- }
137
-
138
- return new Promise((resolve, reject) => {
139
- this.socket.send(data, port, address, (error) => {
140
- if (error) {
141
- reject(error);
142
- } else {
143
- resolve();
144
- }
145
- });
146
- });
147
- }
148
- }
149
-
150
- /**
151
- * @class TCPTransport
152
- * @extends NetworkTransport
153
- * @description TCP transport implementation using net
154
- * Supports both server (listening) and client (connecting) modes
155
- */
156
- class TCPTransport extends NetworkTransport {
157
- constructor() {
158
- super(TransportProtocol.TCP);
159
- this.server = null;
160
- this.connections = new Map(); // connection id -> socket
161
- this.mode = null; // 'server' or 'client'
162
- }
163
-
164
- /**
165
- * Start listening for connections (server mode)
166
- * @param {number} [port=0] - Port to listen on (0 for random)
167
- * @param {string} [address='0.0.0.0'] - Address to bind
168
- * @returns {Promise<{address: string, port: number}>}
169
- */
170
- async listen(port = 0, address = '0.0.0.0') {
171
- if (this.server) {
172
- throw new Error('Already listening');
173
- }
174
-
175
- this.mode = 'server';
176
-
177
- return new Promise((resolve, reject) => {
178
- this.server = net.createServer((socket) => {
179
- this._handleConnection(socket);
180
- });
181
-
182
- this.server.on('error', (error) => {
183
- this.emit('error', error);
184
- });
185
-
186
- this.server.on('close', () => {
187
- this.isListening = false;
188
- this.emit('close');
189
- });
190
-
191
- this.server.listen(port, address, () => {
192
- const addr = this.server.address();
193
- this.localAddress = addr.address;
194
- this.localPort = addr.port;
195
- this.isListening = true;
196
- this.emit('listening');
197
- resolve({ address: addr.address, port: addr.port });
198
- });
199
- });
200
- }
201
-
202
- /**
203
- * Connect to remote server (client mode)
204
- * @param {string} address - Remote address
205
- * @param {number} port - Remote port
206
- * @returns {Promise<void>}
207
- */
208
- async connect(address, port) {
209
- if (this.mode === 'server') {
210
- throw new Error('Cannot connect in server mode');
211
- }
212
-
213
- this.mode = 'client';
214
-
215
- return new Promise((resolve, reject) => {
216
- const socket = net.connect(port, address, () => {
217
- this._handleConnection(socket);
218
- resolve();
219
- });
220
-
221
- socket.on('error', (error) => {
222
- reject(error);
223
- });
224
- });
225
- }
226
-
227
- /**
228
- * Handle new connection
229
- * @param {net.Socket} socket - TCP socket
230
- * @private
231
- */
232
- _handleConnection(socket) {
233
- const connectionId = crypto.randomBytes(8).toString('hex');
234
- this.connections.set(connectionId, socket);
235
-
236
- const rinfo = {
237
- address: socket.remoteAddress,
238
- port: socket.remotePort,
239
- connectionId
240
- };
241
-
242
- // Handle incoming data
243
- socket.on('data', (data) => {
244
- this.emit('data', data, rinfo);
245
- });
246
-
247
- // Handle socket close
248
- socket.on('close', () => {
249
- this.connections.delete(connectionId);
250
- this.emit('connectionClosed', connectionId);
251
- });
252
-
253
- // Handle errors
254
- socket.on('error', (error) => {
255
- this.emit('error', error);
256
- });
257
-
258
- // Emit connection event
259
- this.emit('connection', connectionId, rinfo);
260
- }
261
-
262
- /**
263
- * Send data to specific connection or address
264
- * @param {Buffer} data - Data to send
265
- * @param {string} addressOrConnectionId - Remote address or connection ID
266
- * @param {number} [port] - Remote port (not needed if using connection ID)
267
- * @returns {Promise<void>}
268
- */
269
- async send(data, addressOrConnectionId, port) {
270
- // If in server mode or already have connection, use connection ID
271
- if (this.connections.has(addressOrConnectionId)) {
272
- const socket = this.connections.get(addressOrConnectionId);
273
- return new Promise((resolve, reject) => {
274
- socket.write(data, (error) => {
275
- if (error) reject(error);
276
- else resolve();
277
- });
278
- });
279
- }
280
-
281
- // Otherwise, send to all connections (broadcast)
282
- if (this.connections.size > 0) {
283
- const promises = [];
284
- for (const socket of this.connections.values()) {
285
- promises.push(
286
- new Promise((resolve, reject) => {
287
- socket.write(data, (error) => {
288
- if (error) reject(error);
289
- else resolve();
290
- });
291
- })
292
- );
293
- }
294
- await Promise.all(promises);
295
- } else {
296
- throw new Error('No active connections');
297
- }
298
- }
299
-
300
- /**
301
- * Close specific connection or all connections
302
- * @param {string} [connectionId] - Connection ID to close (omit to close all)
303
- */
304
- closeConnection(connectionId) {
305
- if (connectionId) {
306
- const socket = this.connections.get(connectionId);
307
- if (socket) {
308
- socket.end();
309
- this.connections.delete(connectionId);
310
- }
311
- } else {
312
- // Close all connections
313
- for (const socket of this.connections.values()) {
314
- socket.end();
315
- }
316
- this.connections.clear();
317
- }
318
- }
319
-
320
- /**
321
- * Close the transport and all connections
322
- */
323
- close() {
324
- // Close all connections
325
- this.closeConnection();
326
-
327
- // Close server
328
- if (this.server) {
329
- this.server.close();
330
- this.server = null;
331
- }
332
-
333
- this.isListening = false;
334
- this.mode = null;
335
- }
336
-
337
- /**
338
- * Bind is an alias for listen in TCP
339
- */
340
- async bind(port, address) {
341
- return this.listen(port, address);
342
- }
343
- }
344
-
345
- /**
346
- * @class DataChannelTransport
347
- * @description High-level transport for data channels using TCP
348
- * Implements message framing with length prefix
349
- */
350
- class DataChannelTransport extends EventEmitter {
351
- constructor() {
352
- super();
353
- this.tcpTransport = new TCPTransport();
354
- this.messageBuffers = new Map(); // connection -> incomplete message buffer
355
-
356
- // Forward events
357
- this.tcpTransport.on('connection', (connectionId, rinfo) => {
358
- this.messageBuffers.set(connectionId, Buffer.alloc(0));
359
- this.emit('connection', connectionId, rinfo);
360
- });
361
-
362
- this.tcpTransport.on('connectionClosed', (connectionId) => {
363
- this.messageBuffers.delete(connectionId);
364
- this.emit('connectionClosed', connectionId);
365
- });
366
-
367
- this.tcpTransport.on('data', (data, rinfo) => {
368
- this._handleData(data, rinfo);
369
- });
370
-
371
- this.tcpTransport.on('error', (error) => {
372
- this.emit('error', error);
373
- });
374
-
375
- this.tcpTransport.on('listening', () => {
376
- this.emit('listening');
377
- });
378
-
379
- this.tcpTransport.on('close', () => {
380
- this.emit('close');
381
- });
382
- }
383
-
384
- /**
385
- * Handle incoming data with message framing
386
- * Message format: [4 bytes length][message data]
387
- * @private
388
- */
389
- _handleData(data, rinfo) {
390
- const connectionId = rinfo.connectionId || 'default';
391
-
392
- // Get existing buffer or create new
393
- let buffer = this.messageBuffers.get(connectionId) || Buffer.alloc(0);
394
- buffer = Buffer.concat([buffer, data]);
395
- this.messageBuffers.set(connectionId, buffer);
396
-
397
- // Process complete messages
398
- while (buffer.length >= 4) {
399
- const messageLength = buffer.readUInt32BE(0);
400
-
401
- if (buffer.length >= 4 + messageLength) {
402
- // Extract complete message
403
- const message = buffer.slice(4, 4 + messageLength);
404
- buffer = buffer.slice(4 + messageLength);
405
- this.messageBuffers.set(connectionId, buffer);
406
-
407
- // Emit message event
408
- this.emit('message', message, rinfo);
409
- } else {
410
- // Incomplete message, wait for more data
411
- break;
412
- }
413
- }
414
- }
415
-
416
- /**
417
- * Send message with length prefix
418
- * @param {Buffer|string} message - Message to send
419
- * @param {string} [connectionId] - Connection ID (for server mode)
420
- * @returns {Promise<void>}
421
- */
422
- async sendMessage(message, connectionId) {
423
- const messageBuffer = Buffer.isBuffer(message) ? message : Buffer.from(message);
424
-
425
- // Create framed message: [length][data]
426
- const frame = Buffer.alloc(4 + messageBuffer.length);
427
- frame.writeUInt32BE(messageBuffer.length, 0);
428
- messageBuffer.copy(frame, 4);
429
-
430
- if (connectionId) {
431
- await this.tcpTransport.send(frame, connectionId);
432
- } else {
433
- // Broadcast to all connections
434
- await this.tcpTransport.send(frame);
435
- }
436
- }
437
-
438
- /**
439
- * Start listening (server mode)
440
- */
441
- async listen(port, address) {
442
- return this.tcpTransport.listen(port, address);
443
- }
444
-
445
- /**
446
- * Connect to remote (client mode)
447
- */
448
- async connect(address, port) {
449
- return this.tcpTransport.connect(address, port);
450
- }
451
-
452
- /**
453
- * Get local address info
454
- */
455
- get localAddress() {
456
- return this.tcpTransport.localAddress;
457
- }
458
-
459
- get localPort() {
460
- return this.tcpTransport.localPort;
461
- }
462
-
463
- /**
464
- * Close transport
465
- */
466
- close() {
467
- this.messageBuffers.clear();
468
- this.tcpTransport.close();
469
- }
470
- }
471
-
472
- module.exports = {
473
- NetworkTransport,
474
- UDPTransport,
475
- TCPTransport,
476
- DataChannelTransport,
477
- TransportProtocol
478
- };