@libp2p/webrtc 7.0.0 → 7.0.1-7fa88999d
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 +6 -6
- package/dist/index.min.js.map +4 -4
- package/dist/src/private-to-private/util.d.ts.map +1 -1
- package/dist/src/private-to-private/util.js +17 -5
- package/dist/src/private-to-private/util.js.map +1 -1
- package/dist/src/private-to-public/listener.d.ts.map +1 -1
- package/dist/src/private-to-public/listener.js +14 -15
- package/dist/src/private-to-public/listener.js.map +1 -1
- package/dist/src/private-to-public/utils/stun-listener.d.ts +4 -0
- package/dist/src/private-to-public/utils/stun-listener.d.ts.map +1 -1
- package/dist/src/private-to-public/utils/stun-listener.js +37 -1
- package/dist/src/private-to-public/utils/stun-listener.js.map +1 -1
- package/package.json +11 -12
- package/src/private-to-private/util.ts +18 -6
- package/src/private-to-public/listener.ts +16 -17
- package/src/private-to-public/utils/stun-listener.ts +40 -1
- package/dist/typedoc-urls.json +0 -14
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../src/private-to-private/util.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../src/private-to-private/util.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AACzC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AACpF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAEvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,MAAM,WAAW,qBAAsB,SAAQ,YAAY,EAAE,aAAa,EAAE,eAAe,CAAC,gBAAgB,CAAC;IAC3G,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,eAAO,MAAM,4BAA4B,GAAU,IAAI,iBAAiB,EAAE,QAAQ,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,SAAS,qBAAqB,KAAG,OAAO,CAAC,IAAI,CA+D9J,CAAA;AA4BD,wBAAgB,aAAa,CAAE,EAAE,EAAE,SAAS,GAAG,MAAM,CAcpD"}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { ConnectionFailedError, InvalidMessageError, InvalidMultiaddrError } from '@libp2p/interface';
|
|
2
2
|
import { peerIdFromString } from '@libp2p/peer-id';
|
|
3
3
|
import { CustomProgressEvent } from 'progress-events';
|
|
4
|
+
import { raceSignal } from 'race-signal';
|
|
4
5
|
import { RTCIceCandidate } from "../webrtc/index.js";
|
|
5
6
|
import { Message } from "./pb/message.js";
|
|
6
7
|
export const readCandidatesUntilConnected = async (pc, stream, options) => {
|
|
8
|
+
const connectedPromise = Promise.withResolvers();
|
|
9
|
+
resolveOnConnected(pc, connectedPromise);
|
|
7
10
|
try {
|
|
8
|
-
const connectedPromise = Promise.withResolvers();
|
|
9
|
-
resolveOnConnected(pc, connectedPromise);
|
|
10
11
|
// read candidates until we are connected or we reach the end of the stream
|
|
11
12
|
while (true) {
|
|
12
13
|
// if we connect, stop trying to read from the stream
|
|
@@ -46,9 +47,16 @@ export const readCandidatesUntilConnected = async (pc, stream, options) => {
|
|
|
46
47
|
}
|
|
47
48
|
}
|
|
48
49
|
catch (err) {
|
|
49
|
-
options.log.error('%s error
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
options.log.error('%s error reading ICE candidates - %e', options.direction, err);
|
|
51
|
+
// the signaling stream can end just before the peer connection connects
|
|
52
|
+
if (pc.connectionState !== 'connected') {
|
|
53
|
+
try {
|
|
54
|
+
await raceSignal(connectedPromise.promise, options.signal);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
options.signal?.throwIfAborted();
|
|
58
|
+
throw err;
|
|
59
|
+
}
|
|
52
60
|
}
|
|
53
61
|
}
|
|
54
62
|
};
|
|
@@ -57,6 +65,10 @@ function resolveOnConnected(pc, promise) {
|
|
|
57
65
|
promise.resolve();
|
|
58
66
|
return;
|
|
59
67
|
}
|
|
68
|
+
if (pc.connectionState === 'failed' || pc.connectionState === 'closed') {
|
|
69
|
+
promise.reject(new ConnectionFailedError(`RTCPeerConnection connection state was "${pc.connectionState}"`));
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
60
72
|
pc.onconnectionstatechange = (_) => {
|
|
61
73
|
switch (pc.connectionState) {
|
|
62
74
|
case 'connected':
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../../src/private-to-private/util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAA;AACrG,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAazC,MAAM,CAAC,MAAM,4BAA4B,GAAG,KAAK,EAAE,EAAqB,EAAE,MAAsC,EAAE,OAA8B,EAAiB,EAAE;IACjK,
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../../src/private-to-private/util.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"listener.d.ts","sourceRoot":"","sources":["../../../src/private-to-public/listener.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"listener.d.ts","sourceRoot":"","sources":["../../../src/private-to-public/listener.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,iBAAiB,EAAmB,MAAM,YAAY,CAAA;AAK/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAC3E,OAAO,KAAK,EAAE,sCAAsC,EAAE,MAAM,gBAAgB,CAAA;AAG5E,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,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAElD,MAAM,WAAW,8BAA8B;IAC7C,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,UAAU,CAAA;IACtB,MAAM,EAAE,eAAe,CAAA;IACvB,QAAQ,EAAE,QAAQ,CAAA;IAClB,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,SAAS,EAAE,SAAS,CAAA;IACpB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,MAAM,CAAC,EAAE,YAAY,CAAA;CACtB;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,QAAQ,CAAA;IAClB,WAAW,EAAE,oBAAoB,CAAA;IACjC,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,WAAW,CAAC,EAAE,kBAAkB,CAAA;IAChC,gBAAgB,CAAC,EAAE,gBAAgB,GAAG,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAA;IAC1F,OAAO,EAAE,gBAAgB,CAAC,sCAAsC,CAAC,CAAA;CAClE;AAED,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,YAAY,CAAA;CAC7B;AAaD,qBAAa,oBAAqB,SAAQ,iBAAiB,CAAC,cAAc,CAAE,YAAW,QAAQ;IAC7F,OAAO,CAAC,kBAAkB,CAAC,CAAW;IACtC,OAAO,CAAC,WAAW,CAAsB;IACzC,OAAO,CAAC,UAAU,CAAC,CAAY;IAC/B,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;IAChD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAiB;gBAEvC,UAAU,EAAE,8BAA8B,EAAE,IAAI,EAAE,wBAAwB;IA4BjF,MAAM,CAAE,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IA6C3C,OAAO,CAAC,iBAAiB;YAiCX,kBAAkB;IA4DhC,QAAQ,IAAK,SAAS,EAAE;IAYxB,mBAAmB,CAAE,UAAU,EAAE,SAAS,EAAE,GAAG,IAAI;IAgC7C,KAAK,IAAK,OAAO,CAAC,IAAI,CAAC;CA6B9B"}
|
|
@@ -3,7 +3,6 @@ import { InvalidParametersError } from '@libp2p/interface';
|
|
|
3
3
|
import { getNetConfig, getThinWaistAddresses } from '@libp2p/utils';
|
|
4
4
|
import { CODE_CERTHASH, CODE_WEBRTC_DIRECT, multiaddr } from '@multiformats/multiaddr';
|
|
5
5
|
import { WebRTCDirect } from '@multiformats/multiaddr-matcher';
|
|
6
|
-
import getPort from 'get-port';
|
|
7
6
|
import { TypedEventEmitter, setMaxListeners } from 'main-event';
|
|
8
7
|
import pWaitFor from 'p-wait-for';
|
|
9
8
|
import { connect } from "./utils/connect.js";
|
|
@@ -82,7 +81,7 @@ export class WebRTCDirectListener extends TypedEventEmitter {
|
|
|
82
81
|
this.safeDispatchEvent('listening');
|
|
83
82
|
}
|
|
84
83
|
startUDPMuxServer(host, port, family) {
|
|
85
|
-
|
|
84
|
+
const listener = {
|
|
86
85
|
peerId: this.components.peerId,
|
|
87
86
|
owner: this,
|
|
88
87
|
port,
|
|
@@ -90,13 +89,6 @@ export class WebRTCDirectListener extends TypedEventEmitter {
|
|
|
90
89
|
isIPv6: family === 6,
|
|
91
90
|
server: Promise.resolve()
|
|
92
91
|
.then(async () => {
|
|
93
|
-
if (port === 0) {
|
|
94
|
-
// libjuice doesn't map 0 to a random free port so we have to do it
|
|
95
|
-
// ourselves
|
|
96
|
-
this.log.trace('searching for free port');
|
|
97
|
-
port = await getPort();
|
|
98
|
-
this.log.trace('listening on free port %d', port);
|
|
99
|
-
}
|
|
100
92
|
return stunListener(host, port, this.log, (serverUfrag, clientUfrag, clientPwd, remoteHost, remotePort) => {
|
|
101
93
|
const signal = this.components.upgrader.createInboundAbortSignal(this.shutdownController.signal);
|
|
102
94
|
this.incomingConnection(serverUfrag, clientUfrag, clientPwd, remoteHost, remotePort, signal)
|
|
@@ -108,7 +100,15 @@ export class WebRTCDirectListener extends TypedEventEmitter {
|
|
|
108
100
|
});
|
|
109
101
|
});
|
|
110
102
|
})
|
|
103
|
+
.then(server => {
|
|
104
|
+
listener.port = server.address().port;
|
|
105
|
+
return server;
|
|
106
|
+
}, err => {
|
|
107
|
+
UDP_MUX_LISTENERS = UDP_MUX_LISTENERS.filter(server => server !== listener);
|
|
108
|
+
throw err;
|
|
109
|
+
})
|
|
111
110
|
};
|
|
111
|
+
return listener;
|
|
112
112
|
}
|
|
113
113
|
async incomingConnection(serverUfrag, clientUfrag, clientPwd, remoteHost, remotePort, signal) {
|
|
114
114
|
const key = `${remoteHost}:${remotePort}:${serverUfrag}:${clientUfrag}`;
|
|
@@ -198,21 +198,20 @@ export class WebRTCDirectListener extends TypedEventEmitter {
|
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
200
|
async close() {
|
|
201
|
+
// Stop in-progress incoming dials before waiting for listener startup.
|
|
202
|
+
this.shutdownController.abort();
|
|
201
203
|
// stop our UDP mux listeners
|
|
202
204
|
await Promise.all(UDP_MUX_LISTENERS
|
|
203
205
|
.filter(listener => listener.owner === this)
|
|
204
|
-
.map(
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
}));
|
|
206
|
+
.map(listener => listener.server.then(server => server.close(), () => {
|
|
207
|
+
// listen() reports startup errors; there is no native server to close.
|
|
208
|
+
})));
|
|
208
209
|
// remove our stopped UDP mux listeners
|
|
209
210
|
UDP_MUX_LISTENERS = UDP_MUX_LISTENERS.filter(listener => listener.owner !== this);
|
|
210
211
|
// close existing connections
|
|
211
212
|
for (const connection of this.connections.values()) {
|
|
212
213
|
connection.close();
|
|
213
214
|
}
|
|
214
|
-
// stop any in-progress incoming dials
|
|
215
|
-
this.shutdownController.abort();
|
|
216
215
|
// RTCPeerConnections will be removed from the connections map when their
|
|
217
216
|
// connection state changes to 'closed'/'disconnected'/'failed
|
|
218
217
|
await pWaitFor(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"listener.js","sourceRoot":"","sources":["../../../src/private-to-public/listener.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAC1D,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAA;AACnE,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACtF,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAA;AAC9D,OAAO,
|
|
1
|
+
{"version":3,"file":"listener.js","sourceRoot":"","sources":["../../../src/private-to-public/listener.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,5 +5,9 @@ export interface StunServer {
|
|
|
5
5
|
close(): Promise<void>;
|
|
6
6
|
address(): AddressInfo;
|
|
7
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* How many ephemeral ports to try before giving up
|
|
10
|
+
*/
|
|
11
|
+
export declare const MAX_EPHEMERAL_BIND_ATTEMPTS = 5;
|
|
8
12
|
export declare function stunListener(host: string, port: number, log: Logger, cb: StunRequestCallback): Promise<StunServer>;
|
|
9
13
|
//# sourceMappingURL=stun-listener.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stun-listener.d.ts","sourceRoot":"","sources":["../../../../src/private-to-public/utils/stun-listener.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"stun-listener.d.ts","sourceRoot":"","sources":["../../../../src/private-to-public/utils/stun-listener.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAA;AACpD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAE3C,MAAM,WAAW,UAAU;IACzB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtB,OAAO,IAAI,WAAW,CAAA;CACvB;AAED;;GAEG;AACH,eAAO,MAAM,2BAA2B,IAAI,CAAA;AAE5C,wBAAsB,YAAY,CAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC,CAwCzH"}
|
|
@@ -1,8 +1,30 @@
|
|
|
1
|
+
import { createSocket } from 'node:dgram';
|
|
2
|
+
import { once } from 'node:events';
|
|
1
3
|
import { isIPv4 } from '@chainsafe/is-ip';
|
|
2
4
|
import { IceUdpMuxListener } from 'node-datachannel';
|
|
3
5
|
import { handleStunRequest } from "./stun.js";
|
|
6
|
+
/**
|
|
7
|
+
* How many ephemeral ports to try before giving up
|
|
8
|
+
*/
|
|
9
|
+
export const MAX_EPHEMERAL_BIND_ATTEMPTS = 5;
|
|
4
10
|
export async function stunListener(host, port, log, cb) {
|
|
5
|
-
|
|
11
|
+
let listener;
|
|
12
|
+
for (let attempt = 1;; attempt++) {
|
|
13
|
+
// libjuice cannot allocate an ephemeral port itself. Probe UDP, not TCP.
|
|
14
|
+
const candidate = port === 0 ? await getUDPPort(host) : port;
|
|
15
|
+
try {
|
|
16
|
+
listener = new IceUdpMuxListener(candidate, host);
|
|
17
|
+
port = candidate;
|
|
18
|
+
break;
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
// the probed port can be claimed before the native listener binds it, the
|
|
22
|
+
// native error does not say why so retry any failure on an ephemeral port
|
|
23
|
+
if (port !== 0 || attempt === MAX_EPHEMERAL_BIND_ATTEMPTS) {
|
|
24
|
+
throw err;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
6
28
|
listener.onUnhandledStunRequest(request => {
|
|
7
29
|
// this runs inside a native callback where a throw would crash the process
|
|
8
30
|
try {
|
|
@@ -25,4 +47,18 @@ export async function stunListener(host, port, log, cb) {
|
|
|
25
47
|
}
|
|
26
48
|
};
|
|
27
49
|
}
|
|
50
|
+
// bind the address the native listener will use, a free wildcard port can
|
|
51
|
+
// still be taken on a specific address on Windows
|
|
52
|
+
async function getUDPPort(host) {
|
|
53
|
+
const socket = createSocket(isIPv4(host) ? 'udp4' : 'udp6');
|
|
54
|
+
try {
|
|
55
|
+
const listening = once(socket, 'listening');
|
|
56
|
+
socket.bind(0, host);
|
|
57
|
+
await listening;
|
|
58
|
+
return socket.address().port;
|
|
59
|
+
}
|
|
60
|
+
finally {
|
|
61
|
+
await socket[Symbol.asyncDispose]();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
28
64
|
//# sourceMappingURL=stun-listener.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stun-listener.js","sourceRoot":"","sources":["../../../../src/private-to-public/utils/stun-listener.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAU7C,MAAM,CAAC,KAAK,UAAU,YAAY,CAAE,IAAY,EAAE,IAAY,EAAE,GAAW,EAAE,EAAuB;IAClG,MAAM,QAAQ,GAAG,IAAI,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"stun-listener.js","sourceRoot":"","sources":["../../../../src/private-to-public/utils/stun-listener.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAU7C;;GAEG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAA;AAE5C,MAAM,CAAC,KAAK,UAAU,YAAY,CAAE,IAAY,EAAE,IAAY,EAAE,GAAW,EAAE,EAAuB;IAClG,IAAI,QAA2B,CAAA;IAE/B,KAAK,IAAI,OAAO,GAAG,CAAC,GAAI,OAAO,EAAE,EAAE,CAAC;QAClC,yEAAyE;QACzE,MAAM,SAAS,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QAE5D,IAAI,CAAC;YACH,QAAQ,GAAG,IAAI,iBAAiB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;YACjD,IAAI,GAAG,SAAS,CAAA;YAChB,MAAK;QACP,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,0EAA0E;YAC1E,0EAA0E;YAC1E,IAAI,IAAI,KAAK,CAAC,IAAI,OAAO,KAAK,2BAA2B,EAAE,CAAC;gBAC1D,MAAM,GAAG,CAAA;YACX,CAAC;QACH,CAAC;IACH,CAAC;IACD,QAAQ,CAAC,sBAAsB,CAAC,OAAO,CAAC,EAAE;QACxC,2EAA2E;QAC3E,IAAI,CAAC;YACH,iBAAiB,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC,CAAA;QACrC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,KAAK,CAAC,6CAA6C,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QAC3F,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,OAAO;QACL,KAAK,EAAE,KAAK,IAAI,EAAE;YAChB,QAAQ,CAAC,IAAI,EAAE,CAAA;QACjB,CAAC;QACD,OAAO,EAAE,GAAG,EAAE;YACZ,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;gBACtC,IAAI;aACL,CAAA;QACH,CAAC;KACF,CAAA;AACH,CAAC;AAED,0EAA0E;AAC1E,kDAAkD;AAClD,KAAK,UAAU,UAAU,CAAE,IAAY;IACrC,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;IAE3D,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;QAC3C,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;QACpB,MAAM,SAAS,CAAA;QACf,OAAO,MAAM,CAAC,OAAO,EAAE,CAAC,IAAI,CAAA;IAC9B,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAA;IACrC,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@libp2p/webrtc",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.1-7fa88999d",
|
|
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",
|
|
@@ -46,18 +46,17 @@
|
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"@chainsafe/is-ip": "^2.1.0",
|
|
49
|
-
"@libp2p/crypto": "
|
|
50
|
-
"@libp2p/interface": "
|
|
51
|
-
"@libp2p/interface-internal": "
|
|
52
|
-
"@libp2p/keychain": "
|
|
53
|
-
"@libp2p/noise": "
|
|
54
|
-
"@libp2p/peer-id": "
|
|
55
|
-
"@libp2p/utils": "
|
|
49
|
+
"@libp2p/crypto": "5.2.0-7fa88999d",
|
|
50
|
+
"@libp2p/interface": "3.4.0-7fa88999d",
|
|
51
|
+
"@libp2p/interface-internal": "3.2.1-7fa88999d",
|
|
52
|
+
"@libp2p/keychain": "6.1.10-7fa88999d",
|
|
53
|
+
"@libp2p/noise": "17.0.6-7fa88999d",
|
|
54
|
+
"@libp2p/peer-id": "6.0.18-7fa88999d",
|
|
55
|
+
"@libp2p/utils": "7.4.4-7fa88999d",
|
|
56
56
|
"@multiformats/multiaddr": "^13.0.3",
|
|
57
57
|
"@multiformats/multiaddr-matcher": "^3.0.2",
|
|
58
58
|
"@peculiar/webcrypto": "^1.5.0",
|
|
59
59
|
"@peculiar/x509": "^2.0.0",
|
|
60
|
-
"get-port": "^7.1.0",
|
|
61
60
|
"interface-datastore": "^10.0.1",
|
|
62
61
|
"it-length-prefixed": "^11.0.1",
|
|
63
62
|
"it-protobuf-stream": "^3.0.0",
|
|
@@ -65,9 +64,9 @@
|
|
|
65
64
|
"it-stream-types": "^2.0.2",
|
|
66
65
|
"main-event": "^1.0.5",
|
|
67
66
|
"multiformats": "^14.0.0",
|
|
68
|
-
"node-datachannel": "^0.33.
|
|
67
|
+
"node-datachannel": "^0.33.4",
|
|
69
68
|
"p-defer": "^4.0.1",
|
|
70
|
-
"p-event": "^
|
|
69
|
+
"p-event": "^8.0.1",
|
|
71
70
|
"p-timeout": "^7.0.0",
|
|
72
71
|
"p-wait-for": "^6.0.0",
|
|
73
72
|
"progress-events": "^1.0.1",
|
|
@@ -79,7 +78,7 @@
|
|
|
79
78
|
"uint8arrays": "^6.1.1"
|
|
80
79
|
},
|
|
81
80
|
"devDependencies": {
|
|
82
|
-
"@libp2p/logger": "
|
|
81
|
+
"@libp2p/logger": "6.2.16-7fa88999d",
|
|
83
82
|
"@types/sinon": "^22.0.0",
|
|
84
83
|
"aegir": "^48.1.1",
|
|
85
84
|
"any-signal": "^4.1.1",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ConnectionFailedError, InvalidMessageError, InvalidMultiaddrError } from '@libp2p/interface'
|
|
2
2
|
import { peerIdFromString } from '@libp2p/peer-id'
|
|
3
3
|
import { CustomProgressEvent } from 'progress-events'
|
|
4
|
+
import { raceSignal } from 'race-signal'
|
|
4
5
|
import { RTCIceCandidate } from '../webrtc/index.ts'
|
|
5
6
|
import { Message } from './pb/message.ts'
|
|
6
7
|
import type { WebRTCDialEvents } from './transport.ts'
|
|
@@ -16,10 +17,10 @@ export interface ReadCandidatesOptions extends AbortOptions, LoggerOptions, Prog
|
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
export const readCandidatesUntilConnected = async (pc: RTCPeerConnection, stream: MessageStream<Message, Stream>, options: ReadCandidatesOptions): Promise<void> => {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
resolveOnConnected(pc, connectedPromise)
|
|
20
|
+
const connectedPromise = Promise.withResolvers<void>()
|
|
21
|
+
resolveOnConnected(pc, connectedPromise)
|
|
22
22
|
|
|
23
|
+
try {
|
|
23
24
|
// read candidates until we are connected or we reach the end of the stream
|
|
24
25
|
while (true) {
|
|
25
26
|
// if we connect, stop trying to read from the stream
|
|
@@ -66,10 +67,16 @@ export const readCandidatesUntilConnected = async (pc: RTCPeerConnection, stream
|
|
|
66
67
|
}
|
|
67
68
|
}
|
|
68
69
|
} catch (err) {
|
|
69
|
-
options.log.error('%s error
|
|
70
|
+
options.log.error('%s error reading ICE candidates - %e', options.direction, err)
|
|
70
71
|
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
// the signaling stream can end just before the peer connection connects
|
|
73
|
+
if (pc.connectionState !== 'connected') {
|
|
74
|
+
try {
|
|
75
|
+
await raceSignal(connectedPromise.promise, options.signal)
|
|
76
|
+
} catch {
|
|
77
|
+
options.signal?.throwIfAborted()
|
|
78
|
+
throw err
|
|
79
|
+
}
|
|
73
80
|
}
|
|
74
81
|
}
|
|
75
82
|
}
|
|
@@ -80,6 +87,11 @@ function resolveOnConnected (pc: RTCPeerConnection, promise: DeferredPromise<voi
|
|
|
80
87
|
return
|
|
81
88
|
}
|
|
82
89
|
|
|
90
|
+
if (pc.connectionState === 'failed' || pc.connectionState === 'closed') {
|
|
91
|
+
promise.reject(new ConnectionFailedError(`RTCPeerConnection connection state was "${pc.connectionState}"`))
|
|
92
|
+
return
|
|
93
|
+
}
|
|
94
|
+
|
|
83
95
|
pc.onconnectionstatechange = (_) => {
|
|
84
96
|
switch (pc.connectionState) {
|
|
85
97
|
case 'connected':
|
|
@@ -3,7 +3,6 @@ import { InvalidParametersError } from '@libp2p/interface'
|
|
|
3
3
|
import { getNetConfig, getThinWaistAddresses } from '@libp2p/utils'
|
|
4
4
|
import { CODE_CERTHASH, CODE_WEBRTC_DIRECT, multiaddr } from '@multiformats/multiaddr'
|
|
5
5
|
import { WebRTCDirect } from '@multiformats/multiaddr-matcher'
|
|
6
|
-
import getPort from 'get-port'
|
|
7
6
|
import { TypedEventEmitter, setMaxListeners } from 'main-event'
|
|
8
7
|
import pWaitFor from 'p-wait-for'
|
|
9
8
|
import { connect } from './utils/connect.ts'
|
|
@@ -140,7 +139,7 @@ export class WebRTCDirectListener extends TypedEventEmitter<ListenerEvents> impl
|
|
|
140
139
|
}
|
|
141
140
|
|
|
142
141
|
private startUDPMuxServer (host: string, port: number, family: 4 | 6): UDPMuxServer {
|
|
143
|
-
|
|
142
|
+
const listener: UDPMuxServer = {
|
|
144
143
|
peerId: this.components.peerId,
|
|
145
144
|
owner: this,
|
|
146
145
|
port,
|
|
@@ -148,14 +147,6 @@ export class WebRTCDirectListener extends TypedEventEmitter<ListenerEvents> impl
|
|
|
148
147
|
isIPv6: family === 6,
|
|
149
148
|
server: Promise.resolve()
|
|
150
149
|
.then(async (): Promise<StunServer> => {
|
|
151
|
-
if (port === 0) {
|
|
152
|
-
// libjuice doesn't map 0 to a random free port so we have to do it
|
|
153
|
-
// ourselves
|
|
154
|
-
this.log.trace('searching for free port')
|
|
155
|
-
port = await getPort()
|
|
156
|
-
this.log.trace('listening on free port %d', port)
|
|
157
|
-
}
|
|
158
|
-
|
|
159
150
|
return stunListener(host, port, this.log, (serverUfrag, clientUfrag, clientPwd, remoteHost, remotePort) => {
|
|
160
151
|
const signal = this.components.upgrader.createInboundAbortSignal(this.shutdownController.signal)
|
|
161
152
|
|
|
@@ -168,7 +159,16 @@ export class WebRTCDirectListener extends TypedEventEmitter<ListenerEvents> impl
|
|
|
168
159
|
})
|
|
169
160
|
})
|
|
170
161
|
})
|
|
162
|
+
.then(server => {
|
|
163
|
+
listener.port = server.address().port
|
|
164
|
+
return server
|
|
165
|
+
}, err => {
|
|
166
|
+
UDP_MUX_LISTENERS = UDP_MUX_LISTENERS.filter(server => server !== listener)
|
|
167
|
+
throw err
|
|
168
|
+
})
|
|
171
169
|
}
|
|
170
|
+
|
|
171
|
+
return listener
|
|
172
172
|
}
|
|
173
173
|
|
|
174
174
|
private async incomingConnection (serverUfrag: string, clientUfrag: string, clientPwd: string | undefined, remoteHost: string, remotePort: number, signal: AbortSignal): Promise<void> {
|
|
@@ -276,14 +276,16 @@ export class WebRTCDirectListener extends TypedEventEmitter<ListenerEvents> impl
|
|
|
276
276
|
}
|
|
277
277
|
|
|
278
278
|
async close (): Promise<void> {
|
|
279
|
+
// Stop in-progress incoming dials before waiting for listener startup.
|
|
280
|
+
this.shutdownController.abort()
|
|
281
|
+
|
|
279
282
|
// stop our UDP mux listeners
|
|
280
283
|
await Promise.all(
|
|
281
284
|
UDP_MUX_LISTENERS
|
|
282
285
|
.filter(listener => listener.owner === this)
|
|
283
|
-
.map(
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
})
|
|
286
|
+
.map(listener => listener.server.then(server => server.close(), () => {
|
|
287
|
+
// listen() reports startup errors; there is no native server to close.
|
|
288
|
+
}))
|
|
287
289
|
)
|
|
288
290
|
|
|
289
291
|
// remove our stopped UDP mux listeners
|
|
@@ -294,9 +296,6 @@ export class WebRTCDirectListener extends TypedEventEmitter<ListenerEvents> impl
|
|
|
294
296
|
connection.close()
|
|
295
297
|
}
|
|
296
298
|
|
|
297
|
-
// stop any in-progress incoming dials
|
|
298
|
-
this.shutdownController.abort()
|
|
299
|
-
|
|
300
299
|
// RTCPeerConnections will be removed from the connections map when their
|
|
301
300
|
// connection state changes to 'closed'/'disconnected'/'failed
|
|
302
301
|
await pWaitFor(() => {
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { createSocket } from 'node:dgram'
|
|
2
|
+
import { once } from 'node:events'
|
|
1
3
|
import { isIPv4 } from '@chainsafe/is-ip'
|
|
2
4
|
import { IceUdpMuxListener } from 'node-datachannel'
|
|
3
5
|
import { handleStunRequest } from './stun.ts'
|
|
@@ -10,8 +12,30 @@ export interface StunServer {
|
|
|
10
12
|
address(): AddressInfo
|
|
11
13
|
}
|
|
12
14
|
|
|
15
|
+
/**
|
|
16
|
+
* How many ephemeral ports to try before giving up
|
|
17
|
+
*/
|
|
18
|
+
export const MAX_EPHEMERAL_BIND_ATTEMPTS = 5
|
|
19
|
+
|
|
13
20
|
export async function stunListener (host: string, port: number, log: Logger, cb: StunRequestCallback): Promise<StunServer> {
|
|
14
|
-
|
|
21
|
+
let listener: IceUdpMuxListener
|
|
22
|
+
|
|
23
|
+
for (let attempt = 1; ; attempt++) {
|
|
24
|
+
// libjuice cannot allocate an ephemeral port itself. Probe UDP, not TCP.
|
|
25
|
+
const candidate = port === 0 ? await getUDPPort(host) : port
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
listener = new IceUdpMuxListener(candidate, host)
|
|
29
|
+
port = candidate
|
|
30
|
+
break
|
|
31
|
+
} catch (err) {
|
|
32
|
+
// the probed port can be claimed before the native listener binds it, the
|
|
33
|
+
// native error does not say why so retry any failure on an ephemeral port
|
|
34
|
+
if (port !== 0 || attempt === MAX_EPHEMERAL_BIND_ATTEMPTS) {
|
|
35
|
+
throw err
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
15
39
|
listener.onUnhandledStunRequest(request => {
|
|
16
40
|
// this runs inside a native callback where a throw would crash the process
|
|
17
41
|
try {
|
|
@@ -34,3 +58,18 @@ export async function stunListener (host: string, port: number, log: Logger, cb:
|
|
|
34
58
|
}
|
|
35
59
|
}
|
|
36
60
|
}
|
|
61
|
+
|
|
62
|
+
// bind the address the native listener will use, a free wildcard port can
|
|
63
|
+
// still be taken on a specific address on Windows
|
|
64
|
+
async function getUDPPort (host: string): Promise<number> {
|
|
65
|
+
const socket = createSocket(isIPv4(host) ? 'udp4' : 'udp6')
|
|
66
|
+
|
|
67
|
+
try {
|
|
68
|
+
const listening = once(socket, 'listening')
|
|
69
|
+
socket.bind(0, host)
|
|
70
|
+
await listening
|
|
71
|
+
return socket.address().port
|
|
72
|
+
} finally {
|
|
73
|
+
await socket[Symbol.asyncDispose]()
|
|
74
|
+
}
|
|
75
|
+
}
|
package/dist/typedoc-urls.json
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"DataChannelOptions": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_webrtc.DataChannelOptions.html",
|
|
3
|
-
".:DataChannelOptions": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_webrtc.DataChannelOptions.html",
|
|
4
|
-
"TransportCertificate": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_webrtc.TransportCertificate.html",
|
|
5
|
-
".:TransportCertificate": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_webrtc.TransportCertificate.html",
|
|
6
|
-
"WebRTCDirectTransportComponents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_webrtc.WebRTCDirectTransportComponents.html",
|
|
7
|
-
"WebRTCTransportComponents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_webrtc.WebRTCTransportComponents.html",
|
|
8
|
-
"WebRTCTransportDirectInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_webrtc.WebRTCTransportDirectInit.html",
|
|
9
|
-
"WebRTCTransportInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_webrtc.WebRTCTransportInit.html",
|
|
10
|
-
"webRTC": "https://libp2p.github.io/js-libp2p/functions/_libp2p_webrtc.webRTC.html",
|
|
11
|
-
".:webRTC": "https://libp2p.github.io/js-libp2p/functions/_libp2p_webrtc.webRTC.html",
|
|
12
|
-
"webRTCDirect": "https://libp2p.github.io/js-libp2p/functions/_libp2p_webrtc.webRTCDirect.html",
|
|
13
|
-
".:webRTCDirect": "https://libp2p.github.io/js-libp2p/functions/_libp2p_webrtc.webRTCDirect.html"
|
|
14
|
-
}
|