@libp2p/webrtc 5.2.24-8484de8a2 → 5.2.24-9a9b11fd4
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 +13 -13
- package/dist/index.min.js.map +4 -4
- package/dist/src/constants.d.ts +4 -0
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +4 -0
- package/dist/src/constants.js.map +1 -1
- package/dist/src/index.d.ts +8 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/muxer.d.ts.map +1 -1
- package/dist/src/muxer.js +7 -12
- package/dist/src/muxer.js.map +1 -1
- package/dist/src/private-to-private/initiate-connection.d.ts.map +1 -1
- package/dist/src/private-to-private/initiate-connection.js +15 -1
- package/dist/src/private-to-private/initiate-connection.js.map +1 -1
- package/dist/src/private-to-private/signaling-stream-handler.d.ts.map +1 -1
- package/dist/src/private-to-private/signaling-stream-handler.js +10 -2
- package/dist/src/private-to-private/signaling-stream-handler.js.map +1 -1
- package/dist/src/private-to-private/transport.d.ts +0 -7
- package/dist/src/private-to-private/transport.d.ts.map +1 -1
- package/dist/src/private-to-private/transport.js.map +1 -1
- package/dist/src/private-to-private/util.d.ts +0 -1
- package/dist/src/private-to-private/util.d.ts.map +1 -1
- package/dist/src/private-to-private/util.js +11 -11
- package/dist/src/private-to-private/util.js.map +1 -1
- package/dist/src/private-to-public/transport.d.ts +0 -8
- package/dist/src/private-to-public/transport.d.ts.map +1 -1
- package/dist/src/private-to-public/transport.js.map +1 -1
- package/dist/src/rtcpeerconnection-to-conn.d.ts.map +1 -1
- package/dist/src/rtcpeerconnection-to-conn.js +3 -0
- package/dist/src/rtcpeerconnection-to-conn.js.map +1 -1
- package/dist/src/stream.d.ts +3 -2
- package/dist/src/stream.d.ts.map +1 -1
- package/dist/src/stream.js +100 -68
- package/dist/src/stream.js.map +1 -1
- package/package.json +10 -10
- package/src/constants.ts +5 -0
- package/src/index.ts +9 -0
- package/src/muxer.ts +6 -13
- package/src/private-to-private/initiate-connection.ts +18 -2
- package/src/private-to-private/signaling-stream-handler.ts +12 -2
- package/src/private-to-private/transport.ts +0 -8
- package/src/private-to-private/util.ts +12 -12
- package/src/private-to-public/transport.ts +0 -10
- package/src/rtcpeerconnection-to-conn.ts +4 -0
- package/src/stream.ts +115 -79
package/dist/src/stream.js
CHANGED
@@ -1,11 +1,13 @@
|
|
1
|
-
import { StreamStateError } from '@libp2p/interface';
|
1
|
+
import { StreamResetError, StreamStateError } from '@libp2p/interface';
|
2
2
|
import { AbstractStream } from '@libp2p/utils';
|
3
3
|
import * as lengthPrefixed from 'it-length-prefixed';
|
4
4
|
import { pushable } from 'it-pushable';
|
5
|
+
import { pEvent } from 'p-event';
|
5
6
|
import { raceSignal } from 'race-signal';
|
6
7
|
import { Uint8ArrayList } from 'uint8arraylist';
|
7
|
-
import { MAX_BUFFERED_AMOUNT, MAX_MESSAGE_SIZE, PROTOBUF_OVERHEAD } from './constants.js';
|
8
|
+
import { DEFAULT_FIN_ACK_TIMEOUT, MAX_BUFFERED_AMOUNT, MAX_MESSAGE_SIZE, PROTOBUF_OVERHEAD } from './constants.js';
|
8
9
|
import { Message } from './private-to-public/pb/message.js';
|
10
|
+
import { isFirefox } from './util.js';
|
9
11
|
export class WebRTCStream extends AbstractStream {
|
10
12
|
/**
|
11
13
|
* The data channel used to send and receive data
|
@@ -18,6 +20,7 @@ export class WebRTCStream extends AbstractStream {
|
|
18
20
|
incomingData;
|
19
21
|
maxBufferedAmount;
|
20
22
|
receivedFinAck;
|
23
|
+
finAckTimeout;
|
21
24
|
constructor(init) {
|
22
25
|
super({
|
23
26
|
...init,
|
@@ -27,36 +30,20 @@ export class WebRTCStream extends AbstractStream {
|
|
27
30
|
this.channel.binaryType = 'arraybuffer';
|
28
31
|
this.incomingData = pushable();
|
29
32
|
this.maxBufferedAmount = init.maxBufferedAmount ?? MAX_BUFFERED_AMOUNT;
|
30
|
-
this.
|
31
|
-
// set up initial state
|
32
|
-
switch (this.channel.readyState) {
|
33
|
-
case 'open':
|
34
|
-
break;
|
35
|
-
case 'closed':
|
36
|
-
case 'closing':
|
37
|
-
if (this.timeline.close === undefined || this.timeline.close === 0) {
|
38
|
-
this.timeline.close = Date.now();
|
39
|
-
}
|
40
|
-
break;
|
41
|
-
case 'connecting':
|
42
|
-
// noop
|
43
|
-
break;
|
44
|
-
default:
|
45
|
-
this.log.error('unknown datachannel state %s', this.channel.readyState);
|
46
|
-
throw new StreamStateError('Unknown datachannel state');
|
47
|
-
}
|
33
|
+
this.finAckTimeout = init.finAckTimeout ?? DEFAULT_FIN_ACK_TIMEOUT;
|
48
34
|
// handle RTCDataChannel events
|
49
|
-
this.channel.onclose = (
|
50
|
-
this.log.trace('received
|
35
|
+
this.channel.onclose = () => {
|
36
|
+
this.log.trace('received datachannel close event');
|
51
37
|
this.onRemoteCloseWrite();
|
52
38
|
this.onTransportClosed();
|
53
39
|
};
|
54
40
|
this.channel.onerror = (evt) => {
|
55
|
-
this.log.trace('received onerror event');
|
56
41
|
const err = evt.error;
|
42
|
+
this.log.trace('received datachannel error event - %e', err);
|
57
43
|
this.abort(err);
|
58
44
|
};
|
59
45
|
this.channel.onmessage = async (event) => {
|
46
|
+
this.log('incoming message %d bytes', event.data.byteLength);
|
60
47
|
const { data } = event;
|
61
48
|
if (data === null || data.byteLength === 0) {
|
62
49
|
return;
|
@@ -66,79 +53,123 @@ export class WebRTCStream extends AbstractStream {
|
|
66
53
|
// dispatch drain event when the buffered amount drops to zero
|
67
54
|
this.channel.bufferedAmountLowThreshold = 0;
|
68
55
|
this.channel.onbufferedamountlow = () => {
|
69
|
-
this.
|
56
|
+
if (this.writableNeedsDrain) {
|
57
|
+
this.safeDispatchEvent('drain');
|
58
|
+
}
|
70
59
|
};
|
71
|
-
|
60
|
+
if (this.channel.readyState !== 'open') {
|
61
|
+
this.log('channel ready state is "%s" and not "open", waiting for "open" event before sending data', this.channel.readyState);
|
62
|
+
pEvent(this.channel, 'open', {
|
63
|
+
rejectionEvents: [
|
64
|
+
'close',
|
65
|
+
'error'
|
66
|
+
]
|
67
|
+
})
|
68
|
+
.then(() => {
|
69
|
+
this.log('channel ready state is now "%s", dispatching drain', this.channel.readyState);
|
70
|
+
this.safeDispatchEvent('drain');
|
71
|
+
})
|
72
|
+
.catch(err => {
|
73
|
+
this.abort(err.error ?? err);
|
74
|
+
});
|
75
|
+
}
|
72
76
|
// pipe framed protobuf messages through a length prefixed decoder, and
|
73
77
|
// surface data from the `Message.message` field through a source.
|
74
78
|
Promise.resolve().then(async () => {
|
75
79
|
for await (const buf of lengthPrefixed.decode(this.incomingData)) {
|
76
|
-
|
77
|
-
if (message != null) {
|
78
|
-
self.onData(new Uint8ArrayList(message));
|
79
|
-
}
|
80
|
+
this.processIncomingProtobuf(buf);
|
80
81
|
}
|
81
82
|
})
|
82
83
|
.catch(err => {
|
83
84
|
this.log.error('error processing incoming data channel messages', err);
|
84
85
|
});
|
85
|
-
//
|
86
|
-
const
|
87
|
-
this.channel.
|
86
|
+
// close when both writable ends are closed or an error occurs
|
87
|
+
const cleanUpDatachannelOnClose = () => {
|
88
|
+
if (this.channel.readyState === 'open') {
|
89
|
+
this.log.trace('stream closed, closing underlying datachannel');
|
90
|
+
this.channel.close();
|
91
|
+
}
|
88
92
|
};
|
89
|
-
this.addEventListener('close',
|
93
|
+
this.addEventListener('close', cleanUpDatachannelOnClose);
|
90
94
|
}
|
91
95
|
sendNewStream() {
|
92
96
|
// opening new streams is handled by WebRTC so this is a noop
|
93
97
|
}
|
94
98
|
_sendMessage(data) {
|
95
|
-
if (this.channel.readyState
|
99
|
+
if (this.channel.readyState !== 'open') {
|
96
100
|
throw new StreamStateError(`Invalid datachannel state - ${this.channel.readyState}`);
|
97
101
|
}
|
98
|
-
|
99
|
-
|
100
|
-
//
|
101
|
-
|
102
|
-
|
103
|
-
|
102
|
+
this.log.trace('sending message, channel state "%s"', this.channel.readyState);
|
103
|
+
if (isFirefox) {
|
104
|
+
// TODO: firefox can deliver small messages out of order - remove once a
|
105
|
+
// browser with https://bugzilla.mozilla.org/show_bug.cgi?id=1983831 is
|
106
|
+
// available in playwright-test
|
107
|
+
this.channel.send(data.subarray());
|
108
|
+
return;
|
104
109
|
}
|
105
|
-
|
106
|
-
|
110
|
+
// send message without copying data
|
111
|
+
for (const buf of data) {
|
112
|
+
this.channel.send(buf);
|
107
113
|
}
|
108
114
|
}
|
109
115
|
sendData(data) {
|
110
|
-
|
116
|
+
if (this.channel.readyState !== 'open') {
|
117
|
+
return {
|
118
|
+
sentBytes: 0,
|
119
|
+
canSendMore: false
|
120
|
+
};
|
121
|
+
}
|
122
|
+
// TODO: firefox can deliver small messages out of order - remove once a
|
123
|
+
// browser with https://bugzilla.mozilla.org/show_bug.cgi?id=1983831 is
|
124
|
+
// available in playwright-test
|
125
|
+
// ----
|
126
|
+
// this is also necessary to work with rust-libp2p 0.54 though 0.53 seems ok
|
127
|
+
this._sendMessage(lengthPrefixed.encode.single(Message.encode({
|
111
128
|
message: data.subarray()
|
112
|
-
});
|
113
|
-
|
114
|
-
this
|
129
|
+
})));
|
130
|
+
/*
|
131
|
+
// TODO: enable this when FF and rust-libp2p are not broken
|
132
|
+
// send message without copying data
|
133
|
+
for (const message of data) {
|
134
|
+
this._sendMessage(
|
135
|
+
lengthPrefixed.encode.single(Message.encode({
|
136
|
+
message
|
137
|
+
}))
|
138
|
+
)
|
139
|
+
}
|
140
|
+
}
|
141
|
+
*/
|
115
142
|
return {
|
116
143
|
sentBytes: data.byteLength,
|
117
144
|
canSendMore: this.channel.bufferedAmount < this.maxBufferedAmount
|
118
145
|
};
|
119
146
|
}
|
120
|
-
sendReset() {
|
121
|
-
this.receivedFinAck.resolve();
|
147
|
+
sendReset(err) {
|
122
148
|
try {
|
149
|
+
this.log.error('sending reset - %e', err);
|
123
150
|
this._sendFlag(Message.Flag.RESET);
|
151
|
+
this.receivedFinAck?.reject(err);
|
124
152
|
}
|
125
153
|
catch (err) {
|
126
154
|
this.log.error('failed to send reset - %e', err);
|
127
155
|
}
|
128
|
-
finally {
|
129
|
-
this.channel.close();
|
130
|
-
}
|
131
156
|
}
|
132
157
|
async sendCloseWrite(options) {
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
await
|
158
|
+
this._sendFlag(Message.Flag.FIN);
|
159
|
+
options?.signal?.throwIfAborted();
|
160
|
+
this.receivedFinAck = Promise.withResolvers();
|
161
|
+
await Promise.any([
|
162
|
+
raceSignal(this.receivedFinAck.promise, options?.signal),
|
163
|
+
new Promise(resolve => {
|
164
|
+
AbortSignal.timeout(this.finAckTimeout)
|
165
|
+
.addEventListener('abort', () => {
|
166
|
+
resolve();
|
167
|
+
});
|
168
|
+
})
|
169
|
+
]);
|
137
170
|
}
|
138
171
|
async sendCloseRead(options) {
|
139
|
-
|
140
|
-
this._sendFlag(Message.Flag.STOP_SENDING);
|
141
|
-
}
|
172
|
+
this._sendFlag(Message.Flag.STOP_SENDING);
|
142
173
|
options?.signal?.throwIfAborted();
|
143
174
|
}
|
144
175
|
/**
|
@@ -146,30 +177,31 @@ export class WebRTCStream extends AbstractStream {
|
|
146
177
|
*/
|
147
178
|
processIncomingProtobuf(buffer) {
|
148
179
|
const message = Message.decode(buffer);
|
180
|
+
// ignore data messages if we've closed the readable end already
|
181
|
+
if (message.message != null && (this.readStatus === 'readable' || this.readStatus === 'paused')) {
|
182
|
+
this.onData(new Uint8ArrayList(message.message));
|
183
|
+
}
|
149
184
|
if (message.flag !== undefined) {
|
150
185
|
this.log.trace('incoming flag %s, write status "%s", read status "%s"', message.flag, this.writeStatus, this.readStatus);
|
151
186
|
if (message.flag === Message.Flag.FIN) {
|
152
|
-
//
|
153
|
-
this.onRemoteCloseWrite();
|
187
|
+
// we should expect no more data from the remote, stop reading
|
154
188
|
this._sendFlag(Message.Flag.FIN_ACK);
|
189
|
+
this.onRemoteCloseWrite();
|
155
190
|
}
|
156
191
|
if (message.flag === Message.Flag.RESET) {
|
157
|
-
|
158
|
-
|
192
|
+
// stop reading and writing to the stream immediately
|
193
|
+
this.receivedFinAck?.reject(new StreamResetError('The stream was reset'));
|
159
194
|
this.onRemoteReset();
|
160
195
|
}
|
161
196
|
if (message.flag === Message.Flag.STOP_SENDING) {
|
162
|
-
//
|
197
|
+
// the remote has stopped reading
|
163
198
|
this.onRemoteCloseRead();
|
164
199
|
}
|
165
200
|
if (message.flag === Message.Flag.FIN_ACK) {
|
166
|
-
|
201
|
+
// remote received our FIN
|
202
|
+
this.receivedFinAck?.resolve();
|
167
203
|
}
|
168
204
|
}
|
169
|
-
// ignore data messages if we've closed the readable end already
|
170
|
-
if (this.readStatus === 'readable' || this.readStatus === 'paused') {
|
171
|
-
return message.message;
|
172
|
-
}
|
173
205
|
}
|
174
206
|
_sendFlag(flag) {
|
175
207
|
if (this.channel.readyState !== 'open') {
|
package/dist/src/stream.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../../src/stream.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;
|
1
|
+
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../../src/stream.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.2.24-
|
3
|
+
"version": "5.2.24-9a9b11fd4",
|
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",
|
@@ -45,13 +45,13 @@
|
|
45
45
|
},
|
46
46
|
"dependencies": {
|
47
47
|
"@chainsafe/is-ip": "^2.1.0",
|
48
|
-
"@libp2p/crypto": "5.1.8-
|
49
|
-
"@libp2p/interface": "2.11.0-
|
50
|
-
"@libp2p/interface-internal": "2.3.19-
|
51
|
-
"@libp2p/keychain": "5.2.9-
|
52
|
-
"@libp2p/noise": "16.1.4-
|
53
|
-
"@libp2p/peer-id": "5.1.9-
|
54
|
-
"@libp2p/utils": "6.7.2-
|
48
|
+
"@libp2p/crypto": "5.1.8-9a9b11fd4",
|
49
|
+
"@libp2p/interface": "2.11.0-9a9b11fd4",
|
50
|
+
"@libp2p/interface-internal": "2.3.19-9a9b11fd4",
|
51
|
+
"@libp2p/keychain": "5.2.9-9a9b11fd4",
|
52
|
+
"@libp2p/noise": "16.1.4-9a9b11fd4",
|
53
|
+
"@libp2p/peer-id": "5.1.9-9a9b11fd4",
|
54
|
+
"@libp2p/utils": "6.7.2-9a9b11fd4",
|
55
55
|
"@multiformats/multiaddr": "^13.0.1",
|
56
56
|
"@multiformats/multiaddr-matcher": "^3.0.1",
|
57
57
|
"@peculiar/webcrypto": "^1.5.0",
|
@@ -79,9 +79,9 @@
|
|
79
79
|
"uint8arrays": "^5.1.0"
|
80
80
|
},
|
81
81
|
"devDependencies": {
|
82
|
-
"@libp2p/logger": "5.2.0-
|
82
|
+
"@libp2p/logger": "5.2.0-9a9b11fd4",
|
83
83
|
"@types/sinon": "^17.0.4",
|
84
|
-
"aegir": "^47.0.
|
84
|
+
"aegir": "^47.0.22",
|
85
85
|
"any-signal": "^4.1.1",
|
86
86
|
"datastore-core": "^10.0.4",
|
87
87
|
"delay": "^6.0.0",
|
package/src/constants.ts
CHANGED
@@ -73,6 +73,11 @@ export const PROTOBUF_OVERHEAD = calculateProtobufOverhead()
|
|
73
73
|
*/
|
74
74
|
export const DATA_CHANNEL_DRAIN_TIMEOUT = 30_000
|
75
75
|
|
76
|
+
/**
|
77
|
+
* Wait for the remote to acknowledge our FIN for this long
|
78
|
+
*/
|
79
|
+
export const DEFAULT_FIN_ACK_TIMEOUT = 10_000
|
80
|
+
|
76
81
|
/**
|
77
82
|
* Set as the 'negotiated' muxer protocol name
|
78
83
|
*/
|
package/src/index.ts
CHANGED
@@ -308,6 +308,15 @@ export interface DataChannelOptions {
|
|
308
308
|
* @default 5_000
|
309
309
|
*/
|
310
310
|
openTimeout?: number
|
311
|
+
|
312
|
+
/**
|
313
|
+
* Due to bugs in WebRTC implementations it's necessary for the remote end of
|
314
|
+
* the connection to acknowledge the FIN message we send during stream
|
315
|
+
* closing. A stream will wait for this many ms.
|
316
|
+
*
|
317
|
+
* @default 10_000
|
318
|
+
*/
|
319
|
+
finAckTimeout?: number
|
311
320
|
}
|
312
321
|
|
313
322
|
/**
|
package/src/muxer.ts
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
import { AbstractStreamMuxer } from '@libp2p/utils'
|
2
|
-
import { pEvent } from 'p-event'
|
3
2
|
import { MUXER_PROTOCOL } from './constants.js'
|
4
3
|
import { createStream, WebRTCStream } from './stream.js'
|
5
4
|
import type { DataChannelOptions } from './index.js'
|
@@ -90,11 +89,12 @@ export class DataChannelMuxer extends AbstractStreamMuxer<WebRTCStream> implemen
|
|
90
89
|
* {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/datachannel_event}
|
91
90
|
*/
|
92
91
|
this.peerConnection.ondatachannel = ({ channel }) => {
|
93
|
-
this.log.trace('incoming %s datachannel with channel id %d and status', channel.protocol, channel.id, channel.readyState)
|
92
|
+
this.log.trace('incoming %s datachannel with channel id %d, protocol %s and status %s', channel.protocol, channel.id, channel.protocol, channel.readyState)
|
94
93
|
|
95
|
-
// 'init' channel is only used during connection establishment
|
94
|
+
// 'init' channel is only used during connection establishment, it is
|
95
|
+
// closed by the initiator
|
96
96
|
if (channel.label === 'init') {
|
97
|
-
this.log.trace('closing init channel')
|
97
|
+
this.log.trace('closing init channel %d', channel.id)
|
98
98
|
channel.close()
|
99
99
|
|
100
100
|
return
|
@@ -114,20 +114,13 @@ export class DataChannelMuxer extends AbstractStreamMuxer<WebRTCStream> implemen
|
|
114
114
|
|
115
115
|
async onCreateStream (options?: CreateStreamOptions): Promise<WebRTCStream> {
|
116
116
|
// The spec says the label MUST be an empty string: https://github.com/libp2p/specs/blob/master/webrtc/README.md#rtcdatachannel-label
|
117
|
-
const channel = this.peerConnection.createDataChannel('
|
117
|
+
const channel = this.peerConnection.createDataChannel('', {
|
118
118
|
// TODO: pre-negotiate stream protocol
|
119
|
-
protocol: options?.protocol
|
119
|
+
// protocol: options?.protocol
|
120
120
|
})
|
121
121
|
|
122
122
|
this.log('open channel %d for protocol %s', channel.id, options?.protocol)
|
123
123
|
|
124
|
-
if (channel.readyState !== 'open') {
|
125
|
-
this.log('channel %d state is "%s" and not "open", waiting for "open" event before sending data', channel.id, channel.readyState)
|
126
|
-
await pEvent(channel, 'open', options)
|
127
|
-
|
128
|
-
this.log('channel %d state is now "%s", sending data', channel.id, channel.readyState)
|
129
|
-
}
|
130
|
-
|
131
124
|
const stream = createStream({
|
132
125
|
...options,
|
133
126
|
...this.dataChannelOptions,
|
@@ -94,10 +94,20 @@ export async function initiateConnection ({ rtcConfiguration, dataChannel, signa
|
|
94
94
|
|
95
95
|
// setup callback to write ICE candidates to the remote peer
|
96
96
|
peerConnection.onicecandidate = ({ candidate }) => {
|
97
|
+
if (peerConnection.connectionState === 'connected') {
|
98
|
+
log.trace('ignore new ice candidate as peer connection is already connected')
|
99
|
+
return
|
100
|
+
}
|
101
|
+
|
97
102
|
// a null candidate means end-of-candidates, an empty string candidate
|
98
103
|
// means end-of-candidates for this generation, otherwise this should
|
99
104
|
// be a valid candidate object
|
100
105
|
// see - https://www.w3.org/TR/webrtc/#rtcpeerconnectioniceevent
|
106
|
+
if (candidate == null || candidate?.candidate === '') {
|
107
|
+
log.trace('initiator detected end of ICE candidates')
|
108
|
+
return
|
109
|
+
}
|
110
|
+
|
101
111
|
const data = JSON.stringify(candidate?.toJSON() ?? null)
|
102
112
|
|
103
113
|
log.trace('initiator sending ICE candidate %o', candidate)
|
@@ -178,10 +188,16 @@ export async function initiateConnection ({ rtcConfiguration, dataChannel, signa
|
|
178
188
|
})
|
179
189
|
}
|
180
190
|
|
181
|
-
log.trace('closing init channel
|
182
|
-
|
191
|
+
log.trace('closing init channel')
|
183
192
|
channel.close()
|
184
193
|
|
194
|
+
// wait for init channel to close before proceeding, otherwise the channel
|
195
|
+
// id can be reused before both sides have seen the channel close
|
196
|
+
log.trace('waiting for init channel to close')
|
197
|
+
await pEvent(channel, 'close', {
|
198
|
+
signal
|
199
|
+
})
|
200
|
+
|
185
201
|
onProgress?.(new CustomProgressEvent('webrtc:close-signaling-stream'))
|
186
202
|
|
187
203
|
log.trace('closing signaling channel')
|
@@ -3,7 +3,7 @@ import { multiaddr } from '@multiformats/multiaddr'
|
|
3
3
|
import { SDPHandshakeFailedError } from '../error.js'
|
4
4
|
import { RTCSessionDescription } from '../webrtc/index.js'
|
5
5
|
import { Message } from './pb/message.js'
|
6
|
-
import {
|
6
|
+
import { getRemotePeer, readCandidatesUntilConnected } from './util.js'
|
7
7
|
import type { RTCPeerConnection } from '../webrtc/index.js'
|
8
8
|
import type { AbortOptions, Connection, Logger, PeerId, Stream } from '@libp2p/interface'
|
9
9
|
import type { Multiaddr } from '@multiformats/multiaddr'
|
@@ -21,10 +21,20 @@ export async function handleIncomingStream (stream: Stream, connection: Connecti
|
|
21
21
|
try {
|
22
22
|
// candidate callbacks
|
23
23
|
peerConnection.onicecandidate = ({ candidate }) => {
|
24
|
+
if (peerConnection.connectionState === 'connected') {
|
25
|
+
log.trace('ignore new ice candidate as peer connection is already connected')
|
26
|
+
return
|
27
|
+
}
|
28
|
+
|
24
29
|
// a null candidate means end-of-candidates, an empty string candidate
|
25
30
|
// means end-of-candidates for this generation, otherwise this should
|
26
31
|
// be a valid candidate object
|
27
32
|
// see - https://www.w3.org/TR/webrtc/#rtcpeerconnectioniceevent
|
33
|
+
if (candidate == null || candidate?.candidate === '') {
|
34
|
+
log.trace('recipient detected end of ICE candidates')
|
35
|
+
return
|
36
|
+
}
|
37
|
+
|
28
38
|
const data = JSON.stringify(candidate?.toJSON() ?? null)
|
29
39
|
|
30
40
|
log.trace('recipient sending ICE candidate %s', data)
|
@@ -90,7 +100,7 @@ export async function handleIncomingStream (stream: Stream, connection: Connecti
|
|
90
100
|
log
|
91
101
|
})
|
92
102
|
} catch (err: any) {
|
93
|
-
if (
|
103
|
+
if (peerConnection.connectionState !== 'connected') {
|
94
104
|
log.error('error while handling signaling stream from peer %a', connection.remoteAddr, err)
|
95
105
|
|
96
106
|
peerConnection.close()
|
@@ -31,14 +31,6 @@ export interface WebRTCTransportInit {
|
|
31
31
|
* Any options here will be applied to any RTCDataChannels that are opened.
|
32
32
|
*/
|
33
33
|
dataChannel?: DataChannelOptions
|
34
|
-
|
35
|
-
/**
|
36
|
-
* Inbound connections must complete the upgrade within this many ms
|
37
|
-
*
|
38
|
-
* @default 30_000
|
39
|
-
* @deprecated configure `connectionManager.inboundUpgradeTimeout` instead
|
40
|
-
*/
|
41
|
-
inboundConnectionTimeout?: number
|
42
34
|
}
|
43
35
|
|
44
36
|
export interface WebRTCTransportComponents {
|
@@ -1,7 +1,6 @@
|
|
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 { isFirefox } from '../util.js'
|
5
4
|
import { RTCIceCandidate } from '../webrtc/index.js'
|
6
5
|
import { Message } from './pb/message.js'
|
7
6
|
import type { WebRTCDialEvents } from './transport.js'
|
@@ -28,7 +27,7 @@ export const readCandidatesUntilConnected = async (pc: RTCPeerConnection, stream
|
|
28
27
|
connectedPromise.promise,
|
29
28
|
stream.read({
|
30
29
|
signal: options.signal
|
31
|
-
})
|
30
|
+
})
|
32
31
|
])
|
33
32
|
|
34
33
|
// stream ended or we became connected
|
@@ -63,32 +62,33 @@ export const readCandidatesUntilConnected = async (pc: RTCPeerConnection, stream
|
|
63
62
|
options.onProgress?.(new CustomProgressEvent<string>('webrtc:add-ice-candidate', candidate.candidate))
|
64
63
|
await pc.addIceCandidate(candidate)
|
65
64
|
} catch (err) {
|
66
|
-
options.log.error('%s bad candidate received', options.direction, candidateInit, err)
|
65
|
+
options.log.error('%s bad candidate received %o - %e', options.direction, candidateInit, err)
|
67
66
|
}
|
68
67
|
}
|
69
68
|
} catch (err) {
|
70
|
-
options.log.error('%s error parsing ICE candidate', options.direction, err)
|
69
|
+
options.log.error('%s error parsing ICE candidate - %e', options.direction, err)
|
71
70
|
|
72
|
-
if (options.signal?.aborted === true &&
|
71
|
+
if (options.signal?.aborted === true && pc.connectionState !== 'connected') {
|
73
72
|
throw err
|
74
73
|
}
|
75
74
|
}
|
76
75
|
}
|
77
76
|
|
78
|
-
export function getConnectionState (pc: RTCPeerConnection): string {
|
79
|
-
return isFirefox ? pc.iceConnectionState : pc.connectionState
|
80
|
-
}
|
81
|
-
|
82
77
|
function resolveOnConnected (pc: RTCPeerConnection, promise: DeferredPromise<void>): void {
|
83
|
-
pc
|
84
|
-
|
78
|
+
if (pc.connectionState === 'connected') {
|
79
|
+
promise.resolve()
|
80
|
+
return
|
81
|
+
}
|
82
|
+
|
83
|
+
pc.onconnectionstatechange = (_) => {
|
84
|
+
switch (pc.connectionState) {
|
85
85
|
case 'connected':
|
86
86
|
promise.resolve()
|
87
87
|
break
|
88
88
|
case 'failed':
|
89
89
|
case 'disconnected':
|
90
90
|
case 'closed':
|
91
|
-
promise.reject(new ConnectionFailedError(
|
91
|
+
promise.reject(new ConnectionFailedError(`RTCPeerConnection connection state became "${pc.connectionState}"`))
|
92
92
|
break
|
93
93
|
default:
|
94
94
|
break
|
@@ -51,11 +51,6 @@ export interface WebRTCTransportDirectInit {
|
|
51
51
|
*/
|
52
52
|
dataChannel?: DataChannelOptions
|
53
53
|
|
54
|
-
/**
|
55
|
-
* @deprecated use `certificate` instead - this option will be removed in a future release
|
56
|
-
*/
|
57
|
-
certificates?: TransportCertificate[]
|
58
|
-
|
59
54
|
/**
|
60
55
|
* Use an existing TLS certificate to secure incoming connections or supply
|
61
56
|
* settings to generate one.
|
@@ -68,11 +63,6 @@ export interface WebRTCTransportDirectInit {
|
|
68
63
|
*/
|
69
64
|
certificate?: TransportCertificate
|
70
65
|
|
71
|
-
/**
|
72
|
-
* @deprecated this setting is ignored and will be removed in a future release
|
73
|
-
*/
|
74
|
-
useLibjuice?: boolean
|
75
|
-
|
76
66
|
/**
|
77
67
|
* The key the certificate is stored in the datastore under
|
78
68
|
*
|
@@ -24,6 +24,10 @@ class RTCPeerConnectionMultiaddrConnection extends AbstractMultiaddrConnection {
|
|
24
24
|
if (this.peerConnection.connectionState === 'disconnected' || this.peerConnection.connectionState === 'failed' || this.peerConnection.connectionState === 'closed') {
|
25
25
|
// nothing else to do but close the connection
|
26
26
|
this.onTransportClosed()
|
27
|
+
|
28
|
+
// only necessary with node-datachannel
|
29
|
+
// https://github.com/murat-dogan/node-datachannel/issues/366#issuecomment-3228453155
|
30
|
+
this.peerConnection.close()
|
27
31
|
}
|
28
32
|
}
|
29
33
|
}
|