@libp2p/webrtc 5.1.1-ff951f1a0 → 5.2.0-1ab50cc0d
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/dist/index.min.js +18 -18
- package/dist/src/private-to-private/listener.d.ts +1 -0
- package/dist/src/private-to-private/listener.d.ts.map +1 -1
- package/dist/src/private-to-private/listener.js +3 -1
- package/dist/src/private-to-private/listener.js.map +1 -1
- package/dist/src/private-to-public/listener.browser.d.ts +1 -0
- package/dist/src/private-to-public/listener.browser.d.ts.map +1 -1
- package/dist/src/private-to-public/listener.browser.js +2 -0
- package/dist/src/private-to-public/listener.browser.js.map +1 -1
- package/dist/src/private-to-public/listener.d.ts +1 -1
- package/dist/src/private-to-public/listener.d.ts.map +1 -1
- package/dist/src/private-to-public/listener.js +92 -33
- package/dist/src/private-to-public/listener.js.map +1 -1
- package/package.json +9 -9
- package/src/private-to-private/listener.ts +5 -1
- package/src/private-to-public/listener.browser.ts +4 -0
- package/src/private-to-public/listener.ts +119 -37
@@ -15,6 +15,7 @@ export declare class WebRTCPeerListener extends TypedEventEmitter<ListenerEvents
|
|
15
15
|
constructor(components: WebRTCPeerListenerComponents, init: WebRTCPeerListenerInit);
|
16
16
|
listen(): Promise<void>;
|
17
17
|
getAddrs(): Multiaddr[];
|
18
|
+
updateAnnounceAddrs(): void;
|
18
19
|
close(): Promise<void>;
|
19
20
|
}
|
20
21
|
//# sourceMappingURL=listener.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"listener.d.ts","sourceRoot":"","sources":["../../../src/private-to-private/listener.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAGrD,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AACzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAA;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAIxD,MAAM,WAAW,4BAA4B;IAC3C,MAAM,EAAE,MAAM,CAAA;IACd,gBAAgB,EAAE,gBAAgB,CAAA;CACnC;AAED,MAAM,WAAW,sBAAsB;IACrC,kBAAkB,EAAE,eAAe,CAAA;CACpC;AAED,qBAAa,kBAAmB,SAAQ,iBAAiB,CAAC,cAAc,CAAE,YAAW,QAAQ;IAC3F,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAkB;IACnD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAiB;gBAEvC,UAAU,EAAE,4BAA4B,EAAE,IAAI,EAAE,sBAAsB;IAO7E,MAAM,IAAK,OAAO,CAAC,IAAI,CAAC;IAM9B,QAAQ,IAAK,SAAS,EAAE;
|
1
|
+
{"version":3,"file":"listener.d.ts","sourceRoot":"","sources":["../../../src/private-to-private/listener.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAGrD,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AACzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAA;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAIxD,MAAM,WAAW,4BAA4B;IAC3C,MAAM,EAAE,MAAM,CAAA;IACd,gBAAgB,EAAE,gBAAgB,CAAA;CACnC;AAED,MAAM,WAAW,sBAAsB;IACrC,kBAAkB,EAAE,eAAe,CAAA;CACpC;AAED,qBAAa,kBAAmB,SAAQ,iBAAiB,CAAC,cAAc,CAAE,YAAW,QAAQ;IAC3F,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAkB;IACnD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAiB;gBAEvC,UAAU,EAAE,4BAA4B,EAAE,IAAI,EAAE,sBAAsB;IAO7E,MAAM,IAAK,OAAO,CAAC,IAAI,CAAC;IAM9B,QAAQ,IAAK,SAAS,EAAE;IAaxB,mBAAmB,IAAK,IAAI;IAItB,KAAK,IAAK,OAAO,CAAC,IAAI,CAAC;CAM9B"}
|
@@ -18,7 +18,7 @@ export class WebRTCPeerListener extends TypedEventEmitter {
|
|
18
18
|
getAddrs() {
|
19
19
|
return this.transportManager
|
20
20
|
.getListeners()
|
21
|
-
.filter(l => l
|
21
|
+
.filter(l => !(l instanceof WebRTCPeerListener))
|
22
22
|
.map(l => l.getAddrs()
|
23
23
|
.filter(ma => Circuit.exactMatch(ma))
|
24
24
|
.map(ma => {
|
@@ -26,6 +26,8 @@ export class WebRTCPeerListener extends TypedEventEmitter {
|
|
26
26
|
}))
|
27
27
|
.flat();
|
28
28
|
}
|
29
|
+
updateAnnounceAddrs() {
|
30
|
+
}
|
29
31
|
async close() {
|
30
32
|
this.shutdownController.abort();
|
31
33
|
queueMicrotask(() => {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"listener.js","sourceRoot":"","sources":["../../../src/private-to-private/listener.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,EAAE,GAAG,EAAE,MAAM,iCAAiC,CAAA;AACrD,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,uCAAuC,CAAA;AAKpE,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC,CAAA;AAW5D,MAAM,OAAO,kBAAmB,SAAQ,iBAAiC;IACtD,gBAAgB,CAAkB;IAClC,kBAAkB,CAAiB;IAEpD,YAAa,UAAwC,EAAE,IAA4B;QACjF,KAAK,EAAE,CAAA;QAEP,IAAI,CAAC,gBAAgB,GAAG,UAAU,CAAC,gBAAgB,CAAA;QACnD,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,kBAAkB,CAAA;IACnD,CAAC;IAED,KAAK,CAAC,MAAM;QACV,cAAc,CAAC,GAAG,EAAE;YAClB,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAA;QACrC,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,gBAAgB;aACzB,YAAY,EAAE;aACd,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,
|
1
|
+
{"version":3,"file":"listener.js","sourceRoot":"","sources":["../../../src/private-to-private/listener.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,EAAE,GAAG,EAAE,MAAM,iCAAiC,CAAA;AACrD,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,uCAAuC,CAAA;AAKpE,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC,CAAA;AAW5D,MAAM,OAAO,kBAAmB,SAAQ,iBAAiC;IACtD,gBAAgB,CAAkB;IAClC,kBAAkB,CAAiB;IAEpD,YAAa,UAAwC,EAAE,IAA4B;QACjF,KAAK,EAAE,CAAA;QAEP,IAAI,CAAC,gBAAgB,GAAG,UAAU,CAAC,gBAAgB,CAAA;QACnD,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,kBAAkB,CAAA;IACnD,CAAC;IAED,KAAK,CAAC,MAAM;QACV,cAAc,CAAC,GAAG,EAAE;YAClB,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAA;QACrC,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,gBAAgB;aACzB,YAAY,EAAE;aACd,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,kBAAkB,CAAC,CAAC;aAC/C,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE;aACnB,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;aACpC,GAAG,CAAC,EAAE,CAAC,EAAE;YACR,OAAO,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,CAAA;QAClC,CAAC,CAAC,CACH;aACA,IAAI,EAAE,CAAA;IACX,CAAC;IAED,mBAAmB;IAEnB,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,CAAA;QAC/B,cAAc,CAAC,GAAG,EAAE;YAClB,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAA;QACjC,CAAC,CAAC,CAAA;IACJ,CAAC;CACF"}
|
@@ -12,6 +12,7 @@ export interface WebRTCDirectListenerInit {
|
|
12
12
|
export declare class WebRTCDirectListener extends TypedEventEmitter<ListenerEvents> implements Listener {
|
13
13
|
listen(): Promise<void>;
|
14
14
|
getAddrs(): Multiaddr[];
|
15
|
+
updateAnnounceAddrs(): void;
|
15
16
|
close(): Promise<void>;
|
16
17
|
}
|
17
18
|
//# sourceMappingURL=listener.browser.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"listener.browser.d.ts","sourceRoot":"","sources":["../../../src/private-to-public/listener.browser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAErD,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AACzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAA;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAExD,MAAM,WAAW,8BAA8B;IAC7C,MAAM,EAAE,MAAM,CAAA;IACd,gBAAgB,EAAE,gBAAgB,CAAA;CACnC;AAED,MAAM,WAAW,wBAAwB;IACvC,kBAAkB,EAAE,eAAe,CAAA;CACpC;AAED,qBAAa,oBAAqB,SAAQ,iBAAiB,CAAC,cAAc,CAAE,YAAW,QAAQ;IACvF,MAAM,IAAK,OAAO,CAAC,IAAI,CAAC;IAI9B,QAAQ,IAAK,SAAS,EAAE;
|
1
|
+
{"version":3,"file":"listener.browser.d.ts","sourceRoot":"","sources":["../../../src/private-to-public/listener.browser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAErD,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AACzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAA;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAExD,MAAM,WAAW,8BAA8B;IAC7C,MAAM,EAAE,MAAM,CAAA;IACd,gBAAgB,EAAE,gBAAgB,CAAA;CACnC;AAED,MAAM,WAAW,wBAAwB;IACvC,kBAAkB,EAAE,eAAe,CAAA;CACpC;AAED,qBAAa,oBAAqB,SAAQ,iBAAiB,CAAC,cAAc,CAAE,YAAW,QAAQ;IACvF,MAAM,IAAK,OAAO,CAAC,IAAI,CAAC;IAI9B,QAAQ,IAAK,SAAS,EAAE;IAIxB,mBAAmB,IAAK,IAAI;IAItB,KAAK,IAAK,OAAO,CAAC,IAAI,CAAC;CAG9B"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"listener.browser.js","sourceRoot":"","sources":["../../../src/private-to-public/listener.browser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAchD,MAAM,OAAO,oBAAqB,SAAQ,iBAAiC;IACzE,KAAK,CAAC,MAAM;QACV,MAAM,IAAI,kBAAkB,CAAC,gCAAgC,CAAC,CAAA;IAChE,CAAC;IAED,QAAQ;QACN,OAAO,EAAE,CAAA;IACX,CAAC;IAED,KAAK,CAAC,KAAK;IAEX,CAAC;CACF"}
|
1
|
+
{"version":3,"file":"listener.browser.js","sourceRoot":"","sources":["../../../src/private-to-public/listener.browser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAchD,MAAM,OAAO,oBAAqB,SAAQ,iBAAiC;IACzE,KAAK,CAAC,MAAM;QACV,MAAM,IAAI,kBAAkB,CAAC,gCAAgC,CAAC,CAAA;IAChE,CAAC;IAED,QAAQ;QACN,OAAO,EAAE,CAAA;IACX,CAAC;IAED,mBAAmB;IAEnB,CAAC;IAED,KAAK,CAAC,KAAK;IAEX,CAAC;CACF"}
|
@@ -20,7 +20,6 @@ export interface WebRTCListenerMetrics {
|
|
20
20
|
listenerEvents: CounterGroup;
|
21
21
|
}
|
22
22
|
export declare class WebRTCDirectListener extends TypedEventEmitter<ListenerEvents> implements Listener {
|
23
|
-
private readonly servers;
|
24
23
|
private readonly multiaddrs;
|
25
24
|
private certificate?;
|
26
25
|
private readonly connections;
|
@@ -33,6 +32,7 @@ export declare class WebRTCDirectListener extends TypedEventEmitter<ListenerEven
|
|
33
32
|
private startUDPMuxServer;
|
34
33
|
private incomingConnection;
|
35
34
|
getAddrs(): Multiaddr[];
|
35
|
+
updateAnnounceAddrs(multiaddrs: Multiaddr[]): void;
|
36
36
|
close(): Promise<void>;
|
37
37
|
}
|
38
38
|
//# sourceMappingURL=listener.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"listener.d.ts","sourceRoot":"","sources":["../../../src/private-to-public/listener.ts"],"names":[],"mappings":"AAEA,OAAO,
|
1
|
+
{"version":3,"file":"listener.d.ts","sourceRoot":"","sources":["../../../src/private-to-public/listener.ts"],"names":[],"mappings":"AAEA,OAAO,EAAsB,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAUzE,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAG3E,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAU,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC/I,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAWxD,MAAM,WAAW,8BAA8B;IAC7C,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,UAAU,CAAA;IACtB,MAAM,EAAE,eAAe,CAAA;IACvB,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,QAAQ,CAAA;IAClB,YAAY,CAAC,EAAE,oBAAoB,EAAE,CAAA;IACrC,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,WAAW,CAAC,EAAE,kBAAkB,CAAA;IAChC,gBAAgB,CAAC,EAAE,gBAAgB,GAAG,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAA;IAC1F,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,YAAY,CAAA;CAC7B;AAiBD,qBAAa,oBAAqB,SAAQ,iBAAiB,CAAC,cAAc,CAAE,YAAW,QAAQ;IAC7F,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,WAAW,CAAC,CAAsB;IAC1C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAsC;IAClE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;IAC5B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA0B;IAC/C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgC;IAC3D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAuB;gBAEnC,UAAU,EAAE,8BAA8B,EAAE,IAAI,EAAE,wBAAwB;IAoBjF,MAAM,CAAE,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IA6D3C,OAAO,CAAC,iBAAiB;YA2CX,kBAAkB;IAgDhC,QAAQ,IAAK,SAAS,EAAE;IAIxB,mBAAmB,CAAE,UAAU,EAAE,SAAS,EAAE,GAAG,IAAI;IA4B7C,KAAK,IAAK,OAAO,CAAC,IAAI,CAAC;CA0B9B"}
|
@@ -1,8 +1,8 @@
|
|
1
1
|
import { networkInterfaces } from 'node:os';
|
2
2
|
import { isIPv4, isIPv6 } from '@chainsafe/is-ip';
|
3
|
-
import { TypedEventEmitter } from '@libp2p/interface';
|
4
|
-
import { multiaddr, protocols } from '@multiformats/multiaddr';
|
5
|
-
import { IP4 } from '@multiformats/multiaddr-matcher';
|
3
|
+
import { InvalidPeerIdError, TypedEventEmitter } from '@libp2p/interface';
|
4
|
+
import { multiaddr, protocols, fromStringTuples } from '@multiformats/multiaddr';
|
5
|
+
import { IP4, WebRTCDirect } from '@multiformats/multiaddr-matcher';
|
6
6
|
import { Crypto } from '@peculiar/webcrypto';
|
7
7
|
import getPort from 'get-port';
|
8
8
|
import pWaitFor from 'p-wait-for';
|
@@ -15,11 +15,13 @@ const crypto = new Crypto();
|
|
15
15
|
* The time to wait, in milliseconds, for the data channel handshake to complete
|
16
16
|
*/
|
17
17
|
const HANDSHAKE_TIMEOUT_MS = 10_000;
|
18
|
+
const CODEC_WEBRTC_DIRECT = 0x0118;
|
19
|
+
const CODEC_CERTHASH = 0x01d2;
|
18
20
|
const UDP_PROTOCOL = protocols('udp');
|
19
21
|
const IP4_PROTOCOL = protocols('ip4');
|
20
22
|
const IP6_PROTOCOL = protocols('ip6');
|
23
|
+
let UDP_MUX_LISTENERS = [];
|
21
24
|
export class WebRTCDirectListener extends TypedEventEmitter {
|
22
|
-
servers;
|
23
25
|
multiaddrs;
|
24
26
|
certificate;
|
25
27
|
connections;
|
@@ -32,7 +34,6 @@ export class WebRTCDirectListener extends TypedEventEmitter {
|
|
32
34
|
this.init = init;
|
33
35
|
this.components = components;
|
34
36
|
this.multiaddrs = [];
|
35
|
-
this.servers = {};
|
36
37
|
this.connections = new Map();
|
37
38
|
this.log = components.logger.forComponent('libp2p:webrtc-direct:listener');
|
38
39
|
this.certificate = init.certificates?.[0];
|
@@ -67,38 +68,71 @@ export class WebRTCDirectListener extends TypedEventEmitter {
|
|
67
68
|
// single mux listener. This is necessary because libjuice binds to all
|
68
69
|
// interfaces for a given port so we we need to key on just the port number
|
69
70
|
// not the host + the port number
|
70
|
-
|
71
|
-
|
71
|
+
let existingServer = UDP_MUX_LISTENERS.find(s => s.port === port);
|
72
|
+
// if the server has not been started yet, or the port is a wildcard port
|
73
|
+
// and there is already a wildcard port for this address family, start a new
|
74
|
+
// UDP mux server
|
75
|
+
const wildcardPorts = port === 0 && existingServer?.port === 0;
|
76
|
+
const sameAddressFamily = (existingServer?.isIPv4 === true && isIPv4(host)) || (existingServer?.isIPv6 === true && isIPv6(host));
|
77
|
+
let createdMuxServer = false;
|
78
|
+
if (existingServer == null || (wildcardPorts && sameAddressFamily)) {
|
79
|
+
this.log('starting UDP mux server on %s:%p', host, port);
|
80
|
+
existingServer = this.startUDPMuxServer(host, port);
|
81
|
+
UDP_MUX_LISTENERS.push(existingServer);
|
82
|
+
createdMuxServer = true;
|
72
83
|
}
|
73
|
-
|
84
|
+
if (!existingServer.peerId.equals(this.components.peerId)) {
|
85
|
+
// this would have to be another in-process peer so we are likely in a
|
86
|
+
// testing environment
|
87
|
+
throw new InvalidPeerIdError(`Another peer is already performing UDP mux on ${host}:${existingServer.port}`);
|
88
|
+
}
|
89
|
+
const server = await existingServer.server;
|
74
90
|
const address = server.address();
|
91
|
+
if (!createdMuxServer) {
|
92
|
+
this.log('reused existing UDP mux server on %s:%p', host, address.port);
|
93
|
+
}
|
75
94
|
getNetworkAddresses(host, address.port, ipVersion).forEach((ma) => {
|
76
95
|
this.multiaddrs.push(multiaddr(`${ma}/webrtc-direct/certhash/${this.certificate?.certhash}`));
|
77
96
|
});
|
78
97
|
this.safeDispatchEvent('listening');
|
79
98
|
}
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
port
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
99
|
+
startUDPMuxServer(host, port) {
|
100
|
+
return {
|
101
|
+
peerId: this.components.peerId,
|
102
|
+
owner: this,
|
103
|
+
port,
|
104
|
+
isIPv4: isIPv4(host),
|
105
|
+
isIPv6: isIPv6(host),
|
106
|
+
server: Promise.resolve()
|
107
|
+
.then(async () => {
|
108
|
+
// ensure we have a certificate
|
109
|
+
if (this.certificate == null) {
|
110
|
+
this.log.trace('creating TLS certificate');
|
111
|
+
const keyPair = await crypto.subtle.generateKey({
|
112
|
+
name: 'ECDSA',
|
113
|
+
namedCurve: 'P-256'
|
114
|
+
}, true, ['sign', 'verify']);
|
115
|
+
const certificate = await generateTransportCertificate(keyPair, {
|
116
|
+
days: 365 * 10
|
117
|
+
});
|
118
|
+
if (this.certificate == null) {
|
119
|
+
this.certificate = certificate;
|
120
|
+
}
|
121
|
+
}
|
122
|
+
if (port === 0) {
|
123
|
+
// libjuice doesn't map 0 to a random free port so we have to do it
|
124
|
+
// ourselves
|
125
|
+
this.log.trace('searching for free port');
|
126
|
+
port = await getPort();
|
127
|
+
}
|
128
|
+
return stunListener(host, port, this.log, (ufrag, remoteHost, remotePort) => {
|
129
|
+
this.incomingConnection(ufrag, remoteHost, remotePort)
|
130
|
+
.catch(err => {
|
131
|
+
this.log.error('error processing incoming STUN request', err);
|
132
|
+
});
|
133
|
+
});
|
134
|
+
})
|
135
|
+
};
|
102
136
|
}
|
103
137
|
async incomingConnection(ufrag, remoteHost, remotePort) {
|
104
138
|
const key = `${remoteHost}:${remotePort}:${ufrag}`;
|
@@ -145,15 +179,40 @@ export class WebRTCDirectListener extends TypedEventEmitter {
|
|
145
179
|
getAddrs() {
|
146
180
|
return this.multiaddrs;
|
147
181
|
}
|
182
|
+
updateAnnounceAddrs(multiaddrs) {
|
183
|
+
for (let i = 0; i < multiaddrs.length; i++) {
|
184
|
+
let ma = multiaddrs[i];
|
185
|
+
if (!WebRTCDirect.exactMatch(ma)) {
|
186
|
+
continue;
|
187
|
+
}
|
188
|
+
// add the certhash if it is missing
|
189
|
+
const tuples = ma.stringTuples();
|
190
|
+
for (let j = 0; j < tuples.length; j++) {
|
191
|
+
if (tuples[j][0] !== CODEC_WEBRTC_DIRECT) {
|
192
|
+
continue;
|
193
|
+
}
|
194
|
+
const certhashIndex = j + 1;
|
195
|
+
if (tuples[certhashIndex] == null || tuples[certhashIndex][0] !== CODEC_CERTHASH) {
|
196
|
+
tuples.splice(certhashIndex, 0, [CODEC_CERTHASH, this.certificate?.certhash]);
|
197
|
+
ma = fromStringTuples(tuples);
|
198
|
+
multiaddrs[i] = ma;
|
199
|
+
}
|
200
|
+
}
|
201
|
+
}
|
202
|
+
}
|
148
203
|
async close() {
|
149
204
|
for (const connection of this.connections.values()) {
|
150
205
|
connection.close();
|
151
206
|
}
|
152
|
-
// stop
|
153
|
-
await Promise.all(
|
154
|
-
|
207
|
+
// stop our UDP mux listeners
|
208
|
+
await Promise.all(UDP_MUX_LISTENERS
|
209
|
+
.filter(listener => listener.owner === this)
|
210
|
+
.map(async (listener) => {
|
211
|
+
const server = await listener.server;
|
155
212
|
await server.close();
|
156
213
|
}));
|
214
|
+
// remove our stopped UDP mux listeners
|
215
|
+
UDP_MUX_LISTENERS = UDP_MUX_LISTENERS.filter(listener => listener.owner !== this);
|
157
216
|
// RTCPeerConnections will be removed from the connections map when their
|
158
217
|
// connection state changes to 'closed'/'disconnected'/'failed
|
159
218
|
await pWaitFor(() => {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"listener.js","sourceRoot":"","sources":["../../../src/private-to-public/listener.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;
|
1
|
+
{"version":3,"file":"listener.js","sourceRoot":"","sources":["../../../src/private-to-public/listener.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@libp2p/webrtc",
|
3
|
-
"version": "5.
|
3
|
+
"version": "5.2.0-1ab50cc0d",
|
4
4
|
"description": "A libp2p transport using WebRTC connections",
|
5
5
|
"license": "Apache-2.0 OR MIT",
|
6
6
|
"homepage": "https://github.com/libp2p/js-libp2p/tree/main/packages/transport-webrtc#readme",
|
@@ -54,11 +54,11 @@
|
|
54
54
|
"@chainsafe/is-ip": "^2.0.2",
|
55
55
|
"@chainsafe/libp2p-noise": "^16.0.0",
|
56
56
|
"@ipshipyard/node-datachannel": "^0.26.4",
|
57
|
-
"@libp2p/interface": "2.
|
58
|
-
"@libp2p/interface-internal": "2.3.
|
59
|
-
"@libp2p/peer-id": "5.0.
|
60
|
-
"@libp2p/utils": "6.5.
|
61
|
-
"@multiformats/multiaddr": "^12.
|
57
|
+
"@libp2p/interface": "2.6.0-1ab50cc0d",
|
58
|
+
"@libp2p/interface-internal": "2.3.2-1ab50cc0d",
|
59
|
+
"@libp2p/peer-id": "5.0.13-1ab50cc0d",
|
60
|
+
"@libp2p/utils": "6.5.2-1ab50cc0d",
|
61
|
+
"@multiformats/multiaddr": "^12.4.0",
|
62
62
|
"@multiformats/multiaddr-matcher": "^1.6.0",
|
63
63
|
"@peculiar/webcrypto": "^1.5.0",
|
64
64
|
"@peculiar/x509": "^1.11.0",
|
@@ -83,9 +83,9 @@
|
|
83
83
|
"uint8arrays": "^5.1.0"
|
84
84
|
},
|
85
85
|
"devDependencies": {
|
86
|
-
"@libp2p/crypto": "5.0.
|
87
|
-
"@libp2p/interface-compliance-tests": "6.3.
|
88
|
-
"@libp2p/logger": "5.1.
|
86
|
+
"@libp2p/crypto": "5.0.12-1ab50cc0d",
|
87
|
+
"@libp2p/interface-compliance-tests": "6.3.2-1ab50cc0d",
|
88
|
+
"@libp2p/logger": "5.1.9-1ab50cc0d",
|
89
89
|
"@types/sinon": "^17.0.3",
|
90
90
|
"aegir": "^45.0.5",
|
91
91
|
"delay": "^6.0.0",
|
@@ -36,7 +36,7 @@ export class WebRTCPeerListener extends TypedEventEmitter<ListenerEvents> implem
|
|
36
36
|
getAddrs (): Multiaddr[] {
|
37
37
|
return this.transportManager
|
38
38
|
.getListeners()
|
39
|
-
.filter(l => l
|
39
|
+
.filter(l => !(l instanceof WebRTCPeerListener))
|
40
40
|
.map(l => l.getAddrs()
|
41
41
|
.filter(ma => Circuit.exactMatch(ma))
|
42
42
|
.map(ma => {
|
@@ -46,6 +46,10 @@ export class WebRTCPeerListener extends TypedEventEmitter<ListenerEvents> implem
|
|
46
46
|
.flat()
|
47
47
|
}
|
48
48
|
|
49
|
+
updateAnnounceAddrs (): void {
|
50
|
+
|
51
|
+
}
|
52
|
+
|
49
53
|
async close (): Promise<void> {
|
50
54
|
this.shutdownController.abort()
|
51
55
|
queueMicrotask(() => {
|
@@ -1,8 +1,8 @@
|
|
1
1
|
import { networkInterfaces } from 'node:os'
|
2
2
|
import { isIPv4, isIPv6 } from '@chainsafe/is-ip'
|
3
|
-
import { TypedEventEmitter } from '@libp2p/interface'
|
4
|
-
import { multiaddr, protocols } from '@multiformats/multiaddr'
|
5
|
-
import { IP4 } from '@multiformats/multiaddr-matcher'
|
3
|
+
import { InvalidPeerIdError, TypedEventEmitter } from '@libp2p/interface'
|
4
|
+
import { multiaddr, protocols, fromStringTuples } from '@multiformats/multiaddr'
|
5
|
+
import { IP4, WebRTCDirect } from '@multiformats/multiaddr-matcher'
|
6
6
|
import { Crypto } from '@peculiar/webcrypto'
|
7
7
|
import getPort from 'get-port'
|
8
8
|
import pWaitFor from 'p-wait-for'
|
@@ -22,6 +22,8 @@ const crypto = new Crypto()
|
|
22
22
|
* The time to wait, in milliseconds, for the data channel handshake to complete
|
23
23
|
*/
|
24
24
|
const HANDSHAKE_TIMEOUT_MS = 10_000
|
25
|
+
const CODEC_WEBRTC_DIRECT = 0x0118
|
26
|
+
const CODEC_CERTHASH = 0x01d2
|
25
27
|
|
26
28
|
export interface WebRTCDirectListenerComponents {
|
27
29
|
peerId: PeerId
|
@@ -47,8 +49,18 @@ const UDP_PROTOCOL = protocols('udp')
|
|
47
49
|
const IP4_PROTOCOL = protocols('ip4')
|
48
50
|
const IP6_PROTOCOL = protocols('ip6')
|
49
51
|
|
52
|
+
interface UDPMuxServer {
|
53
|
+
server: Promise<StunServer>
|
54
|
+
isIPv4: boolean
|
55
|
+
isIPv6: boolean
|
56
|
+
port: number
|
57
|
+
owner: WebRTCDirectListener
|
58
|
+
peerId: PeerId
|
59
|
+
}
|
60
|
+
|
61
|
+
let UDP_MUX_LISTENERS: UDPMuxServer[] = []
|
62
|
+
|
50
63
|
export class WebRTCDirectListener extends TypedEventEmitter<ListenerEvents> implements Listener {
|
51
|
-
private readonly servers: Record<number, Promise<StunServer>>
|
52
64
|
private readonly multiaddrs: Multiaddr[]
|
53
65
|
private certificate?: TransportCertificate
|
54
66
|
private readonly connections: Map<string, DirectRTCPeerConnection>
|
@@ -63,7 +75,6 @@ export class WebRTCDirectListener extends TypedEventEmitter<ListenerEvents> impl
|
|
63
75
|
this.init = init
|
64
76
|
this.components = components
|
65
77
|
this.multiaddrs = []
|
66
|
-
this.servers = {}
|
67
78
|
this.connections = new Map()
|
68
79
|
this.log = components.logger.forComponent('libp2p:webrtc-direct:listener')
|
69
80
|
this.certificate = init.certificates?.[0]
|
@@ -103,13 +114,35 @@ export class WebRTCDirectListener extends TypedEventEmitter<ListenerEvents> impl
|
|
103
114
|
// single mux listener. This is necessary because libjuice binds to all
|
104
115
|
// interfaces for a given port so we we need to key on just the port number
|
105
116
|
// not the host + the port number
|
106
|
-
|
107
|
-
|
117
|
+
let existingServer = UDP_MUX_LISTENERS.find(s => s.port === port)
|
118
|
+
|
119
|
+
// if the server has not been started yet, or the port is a wildcard port
|
120
|
+
// and there is already a wildcard port for this address family, start a new
|
121
|
+
// UDP mux server
|
122
|
+
const wildcardPorts = port === 0 && existingServer?.port === 0
|
123
|
+
const sameAddressFamily = (existingServer?.isIPv4 === true && isIPv4(host)) || (existingServer?.isIPv6 === true && isIPv6(host))
|
124
|
+
let createdMuxServer = false
|
125
|
+
|
126
|
+
if (existingServer == null || (wildcardPorts && sameAddressFamily)) {
|
127
|
+
this.log('starting UDP mux server on %s:%p', host, port)
|
128
|
+
existingServer = this.startUDPMuxServer(host, port)
|
129
|
+
UDP_MUX_LISTENERS.push(existingServer)
|
130
|
+
createdMuxServer = true
|
108
131
|
}
|
109
132
|
|
110
|
-
|
133
|
+
if (!existingServer.peerId.equals(this.components.peerId)) {
|
134
|
+
// this would have to be another in-process peer so we are likely in a
|
135
|
+
// testing environment
|
136
|
+
throw new InvalidPeerIdError(`Another peer is already performing UDP mux on ${host}:${existingServer.port}`)
|
137
|
+
}
|
138
|
+
|
139
|
+
const server = await existingServer.server
|
111
140
|
const address = server.address()
|
112
141
|
|
142
|
+
if (!createdMuxServer) {
|
143
|
+
this.log('reused existing UDP mux server on %s:%p', host, address.port)
|
144
|
+
}
|
145
|
+
|
113
146
|
getNetworkAddresses(host, address.port, ipVersion).forEach((ma) => {
|
114
147
|
this.multiaddrs.push(multiaddr(`${ma}/webrtc-direct/certhash/${this.certificate?.certhash}`))
|
115
148
|
})
|
@@ -117,31 +150,47 @@ export class WebRTCDirectListener extends TypedEventEmitter<ListenerEvents> impl
|
|
117
150
|
this.safeDispatchEvent('listening')
|
118
151
|
}
|
119
152
|
|
120
|
-
private
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
port
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
153
|
+
private startUDPMuxServer (host: string, port: number): UDPMuxServer {
|
154
|
+
return {
|
155
|
+
peerId: this.components.peerId,
|
156
|
+
owner: this,
|
157
|
+
port,
|
158
|
+
isIPv4: isIPv4(host),
|
159
|
+
isIPv6: isIPv6(host),
|
160
|
+
server: Promise.resolve()
|
161
|
+
.then(async (): Promise<StunServer> => {
|
162
|
+
// ensure we have a certificate
|
163
|
+
if (this.certificate == null) {
|
164
|
+
this.log.trace('creating TLS certificate')
|
165
|
+
const keyPair = await crypto.subtle.generateKey({
|
166
|
+
name: 'ECDSA',
|
167
|
+
namedCurve: 'P-256'
|
168
|
+
}, true, ['sign', 'verify'])
|
169
|
+
|
170
|
+
const certificate = await generateTransportCertificate(keyPair, {
|
171
|
+
days: 365 * 10
|
172
|
+
})
|
173
|
+
|
174
|
+
if (this.certificate == null) {
|
175
|
+
this.certificate = certificate
|
176
|
+
}
|
177
|
+
}
|
178
|
+
|
179
|
+
if (port === 0) {
|
180
|
+
// libjuice doesn't map 0 to a random free port so we have to do it
|
181
|
+
// ourselves
|
182
|
+
this.log.trace('searching for free port')
|
183
|
+
port = await getPort()
|
184
|
+
}
|
185
|
+
|
186
|
+
return stunListener(host, port, this.log, (ufrag, remoteHost, remotePort) => {
|
187
|
+
this.incomingConnection(ufrag, remoteHost, remotePort)
|
188
|
+
.catch(err => {
|
189
|
+
this.log.error('error processing incoming STUN request', err)
|
190
|
+
})
|
191
|
+
})
|
143
192
|
})
|
144
|
-
}
|
193
|
+
}
|
145
194
|
}
|
146
195
|
|
147
196
|
private async incomingConnection (ufrag: string, remoteHost: string, remotePort: number): Promise<void> {
|
@@ -196,19 +245,52 @@ export class WebRTCDirectListener extends TypedEventEmitter<ListenerEvents> impl
|
|
196
245
|
return this.multiaddrs
|
197
246
|
}
|
198
247
|
|
248
|
+
updateAnnounceAddrs (multiaddrs: Multiaddr[]): void {
|
249
|
+
for (let i = 0; i < multiaddrs.length; i++) {
|
250
|
+
let ma = multiaddrs[i]
|
251
|
+
|
252
|
+
if (!WebRTCDirect.exactMatch(ma)) {
|
253
|
+
continue
|
254
|
+
}
|
255
|
+
|
256
|
+
// add the certhash if it is missing
|
257
|
+
const tuples = ma.stringTuples()
|
258
|
+
|
259
|
+
for (let j = 0; j < tuples.length; j++) {
|
260
|
+
if (tuples[j][0] !== CODEC_WEBRTC_DIRECT) {
|
261
|
+
continue
|
262
|
+
}
|
263
|
+
|
264
|
+
const certhashIndex = j + 1
|
265
|
+
|
266
|
+
if (tuples[certhashIndex] == null || tuples[certhashIndex][0] !== CODEC_CERTHASH) {
|
267
|
+
tuples.splice(certhashIndex, 0, [CODEC_CERTHASH, this.certificate?.certhash])
|
268
|
+
|
269
|
+
ma = fromStringTuples(tuples)
|
270
|
+
multiaddrs[i] = ma
|
271
|
+
}
|
272
|
+
}
|
273
|
+
}
|
274
|
+
}
|
275
|
+
|
199
276
|
async close (): Promise<void> {
|
200
277
|
for (const connection of this.connections.values()) {
|
201
278
|
connection.close()
|
202
279
|
}
|
203
280
|
|
204
|
-
// stop
|
281
|
+
// stop our UDP mux listeners
|
205
282
|
await Promise.all(
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
283
|
+
UDP_MUX_LISTENERS
|
284
|
+
.filter(listener => listener.owner === this)
|
285
|
+
.map(async listener => {
|
286
|
+
const server = await listener.server
|
287
|
+
await server.close()
|
288
|
+
})
|
210
289
|
)
|
211
290
|
|
291
|
+
// remove our stopped UDP mux listeners
|
292
|
+
UDP_MUX_LISTENERS = UDP_MUX_LISTENERS.filter(listener => listener.owner !== this)
|
293
|
+
|
212
294
|
// RTCPeerConnections will be removed from the connections map when their
|
213
295
|
// connection state changes to 'closed'/'disconnected'/'failed
|
214
296
|
await pWaitFor(() => {
|