libp2p 2.9.0 → 2.10.0-a02cb0461

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 (112) hide show
  1. package/dist/index.min.js +13 -17
  2. package/dist/index.min.js.map +4 -4
  3. package/dist/src/address-manager/dns-mappings.d.ts.map +1 -1
  4. package/dist/src/address-manager/dns-mappings.js +2 -3
  5. package/dist/src/address-manager/dns-mappings.js.map +1 -1
  6. package/dist/src/address-manager/index.d.ts.map +1 -1
  7. package/dist/src/address-manager/index.js +1 -3
  8. package/dist/src/address-manager/index.js.map +1 -1
  9. package/dist/src/address-manager/ip-mappings.js +1 -1
  10. package/dist/src/address-manager/ip-mappings.js.map +1 -1
  11. package/dist/src/address-manager/observed-addresses.d.ts.map +1 -1
  12. package/dist/src/address-manager/observed-addresses.js +1 -3
  13. package/dist/src/address-manager/observed-addresses.js.map +1 -1
  14. package/dist/src/address-manager/transport-addresses.d.ts.map +1 -1
  15. package/dist/src/address-manager/transport-addresses.js +1 -3
  16. package/dist/src/address-manager/transport-addresses.js.map +1 -1
  17. package/dist/src/config/connection-gater.browser.js +1 -1
  18. package/dist/src/config/connection-gater.browser.js.map +1 -1
  19. package/dist/src/config.js +1 -1
  20. package/dist/src/config.js.map +1 -1
  21. package/dist/src/connection-manager/address-sorter.d.ts.map +1 -1
  22. package/dist/src/connection-manager/address-sorter.js +1 -2
  23. package/dist/src/connection-manager/address-sorter.js.map +1 -1
  24. package/dist/src/connection-manager/connection-pruner.d.ts.map +1 -1
  25. package/dist/src/connection-manager/connection-pruner.js +1 -2
  26. package/dist/src/connection-manager/connection-pruner.js.map +1 -1
  27. package/dist/src/connection-manager/constants.defaults.d.ts +4 -0
  28. package/dist/src/connection-manager/constants.defaults.d.ts.map +1 -1
  29. package/dist/src/connection-manager/constants.defaults.js +4 -0
  30. package/dist/src/connection-manager/constants.defaults.js.map +1 -1
  31. package/dist/src/connection-manager/dial-queue.d.ts +2 -2
  32. package/dist/src/connection-manager/dial-queue.d.ts.map +1 -1
  33. package/dist/src/connection-manager/dial-queue.js +11 -23
  34. package/dist/src/connection-manager/dial-queue.js.map +1 -1
  35. package/dist/src/connection-manager/index.d.ts +10 -2
  36. package/dist/src/connection-manager/index.d.ts.map +1 -1
  37. package/dist/src/connection-manager/index.js +29 -19
  38. package/dist/src/connection-manager/index.js.map +1 -1
  39. package/dist/src/connection-manager/reconnect-queue.js +1 -1
  40. package/dist/src/connection-manager/reconnect-queue.js.map +1 -1
  41. package/dist/src/connection-manager/utils.d.ts +28 -0
  42. package/dist/src/connection-manager/utils.d.ts.map +1 -1
  43. package/dist/src/connection-manager/utils.js +78 -0
  44. package/dist/src/connection-manager/utils.js.map +1 -1
  45. package/dist/src/connection-monitor.d.ts +1 -1
  46. package/dist/src/connection-monitor.d.ts.map +1 -1
  47. package/dist/src/connection-monitor.js +2 -3
  48. package/dist/src/connection-monitor.js.map +1 -1
  49. package/dist/src/connection.d.ts +62 -0
  50. package/dist/src/connection.d.ts.map +1 -0
  51. package/dist/src/connection.js +239 -0
  52. package/dist/src/connection.js.map +1 -0
  53. package/dist/src/index.d.ts +2 -2
  54. package/dist/src/index.js +2 -2
  55. package/dist/src/libp2p.d.ts.map +1 -1
  56. package/dist/src/libp2p.js +3 -3
  57. package/dist/src/libp2p.js.map +1 -1
  58. package/dist/src/peer-routing.js +1 -1
  59. package/dist/src/peer-routing.js.map +1 -1
  60. package/dist/src/random-walk.d.ts.map +1 -1
  61. package/dist/src/random-walk.js +13 -3
  62. package/dist/src/random-walk.js.map +1 -1
  63. package/dist/src/registrar.d.ts +3 -3
  64. package/dist/src/registrar.d.ts.map +1 -1
  65. package/dist/src/registrar.js +50 -41
  66. package/dist/src/registrar.js.map +1 -1
  67. package/dist/src/transport-manager.js +15 -2
  68. package/dist/src/transport-manager.js.map +1 -1
  69. package/dist/src/upgrader.d.ts +27 -25
  70. package/dist/src/upgrader.d.ts.map +1 -1
  71. package/dist/src/upgrader.js +95 -335
  72. package/dist/src/upgrader.js.map +1 -1
  73. package/dist/src/utils.d.ts +3 -0
  74. package/dist/src/utils.d.ts.map +1 -0
  75. package/dist/src/utils.js +25 -0
  76. package/dist/src/utils.js.map +1 -0
  77. package/dist/src/version.d.ts +1 -1
  78. package/dist/src/version.d.ts.map +1 -1
  79. package/dist/src/version.js +1 -1
  80. package/dist/src/version.js.map +1 -1
  81. package/package.json +26 -30
  82. package/src/address-manager/dns-mappings.ts +2 -3
  83. package/src/address-manager/index.ts +2 -4
  84. package/src/address-manager/ip-mappings.ts +1 -1
  85. package/src/address-manager/observed-addresses.ts +1 -3
  86. package/src/address-manager/transport-addresses.ts +1 -3
  87. package/src/config/connection-gater.browser.ts +1 -1
  88. package/src/config.ts +1 -1
  89. package/src/connection-manager/address-sorter.ts +1 -2
  90. package/src/connection-manager/connection-pruner.ts +1 -2
  91. package/src/connection-manager/constants.defaults.ts +5 -0
  92. package/src/connection-manager/dial-queue.ts +12 -27
  93. package/src/connection-manager/index.ts +44 -21
  94. package/src/connection-manager/reconnect-queue.ts +1 -1
  95. package/src/connection-manager/utils.ts +104 -0
  96. package/src/connection-monitor.ts +3 -4
  97. package/src/connection.ts +316 -0
  98. package/src/index.ts +2 -2
  99. package/src/libp2p.ts +3 -4
  100. package/src/peer-routing.ts +1 -1
  101. package/src/random-walk.ts +13 -3
  102. package/src/registrar.ts +67 -54
  103. package/src/transport-manager.ts +18 -2
  104. package/src/upgrader.ts +141 -420
  105. package/src/utils.ts +31 -0
  106. package/src/version.ts +1 -1
  107. package/dist/src/connection/index.d.ts +0 -84
  108. package/dist/src/connection/index.d.ts.map +0 -1
  109. package/dist/src/connection/index.js +0 -144
  110. package/dist/src/connection/index.js.map +0 -1
  111. package/dist/typedoc-urls.json +0 -24
  112. package/src/connection/index.ts +0 -199
@@ -1,50 +1,14 @@
1
- import { InvalidMultiaddrError, TooManyInboundProtocolStreamsError, TooManyOutboundProtocolStreamsError, LimitedConnectionError, InvalidPeerIdError } from '@libp2p/interface';
1
+ import { InvalidMultiaddrError, InvalidPeerIdError } from '@libp2p/interface';
2
2
  import * as mss from '@libp2p/multistream-select';
3
3
  import { peerIdFromString } from '@libp2p/peer-id';
4
- import { trackedMap } from '@libp2p/utils/tracked-map';
4
+ import { trackedMap } from '@libp2p/utils';
5
5
  import { anySignal } from 'any-signal';
6
6
  import { setMaxListeners } from 'main-event';
7
7
  import { CustomProgressEvent } from 'progress-events';
8
8
  import { raceSignal } from 'race-signal';
9
- import { createConnection } from './connection/index.js';
10
- import { PROTOCOL_NEGOTIATION_TIMEOUT, INBOUND_UPGRADE_TIMEOUT } from './connection-manager/constants.js';
9
+ import { PROTOCOL_NEGOTIATION_TIMEOUT, INBOUND_UPGRADE_TIMEOUT, CONNECTION_CLOSE_TIMEOUT } from './connection-manager/constants.js';
10
+ import { createConnection } from './connection.js';
11
11
  import { ConnectionDeniedError, ConnectionInterceptedError, EncryptionFailedError, MuxerUnavailableError } from './errors.js';
12
- import { DEFAULT_MAX_INBOUND_STREAMS, DEFAULT_MAX_OUTBOUND_STREAMS } from './registrar.js';
13
- function findIncomingStreamLimit(protocol, registrar) {
14
- try {
15
- const { options } = registrar.getHandler(protocol);
16
- return options.maxInboundStreams;
17
- }
18
- catch (err) {
19
- if (err.name !== 'UnhandledProtocolError') {
20
- throw err;
21
- }
22
- }
23
- return DEFAULT_MAX_INBOUND_STREAMS;
24
- }
25
- function findOutgoingStreamLimit(protocol, registrar, options = {}) {
26
- try {
27
- const { options } = registrar.getHandler(protocol);
28
- if (options.maxOutboundStreams != null) {
29
- return options.maxOutboundStreams;
30
- }
31
- }
32
- catch (err) {
33
- if (err.name !== 'UnhandledProtocolError') {
34
- throw err;
35
- }
36
- }
37
- return options.maxOutboundStreams ?? DEFAULT_MAX_OUTBOUND_STREAMS;
38
- }
39
- function countStreams(protocol, direction, connection) {
40
- let streamCount = 0;
41
- connection.streams.forEach(stream => {
42
- if (stream.direction === direction && stream.protocol === protocol) {
43
- streamCount++;
44
- }
45
- });
46
- return streamCount;
47
- }
48
12
  export class Upgrader {
49
13
  components;
50
14
  connectionEncrypters;
@@ -54,6 +18,7 @@ export class Upgrader {
54
18
  outboundStreamProtocolNegotiationTimeout;
55
19
  events;
56
20
  metrics;
21
+ connectionCloseTimeout;
57
22
  constructor(components, init) {
58
23
  this.components = components;
59
24
  this.connectionEncrypters = trackedMap({
@@ -73,6 +38,7 @@ export class Upgrader {
73
38
  this.inboundUpgradeTimeout = init.inboundUpgradeTimeout ?? INBOUND_UPGRADE_TIMEOUT;
74
39
  this.inboundStreamProtocolNegotiationTimeout = init.inboundStreamProtocolNegotiationTimeout ?? PROTOCOL_NEGOTIATION_TIMEOUT;
75
40
  this.outboundStreamProtocolNegotiationTimeout = init.outboundStreamProtocolNegotiationTimeout ?? PROTOCOL_NEGOTIATION_TIMEOUT;
41
+ this.connectionCloseTimeout = init.connectionCloseTimeout ?? CONNECTION_CLOSE_TIMEOUT;
76
42
  this.events = components.events;
77
43
  this.metrics = {
78
44
  dials: components.metrics?.registerCounterGroup('libp2p_connection_manager_dials_total'),
@@ -100,9 +66,6 @@ export class Upgrader {
100
66
  setMaxListeners(Infinity, output);
101
67
  return output;
102
68
  }
103
- /**
104
- * Upgrades an inbound connection
105
- */
106
69
  async upgradeInbound(maConn, opts) {
107
70
  let accepted = false;
108
71
  // always apply upgrade timeout for incoming upgrades
@@ -111,7 +74,7 @@ export class Upgrader {
111
74
  this.metrics.dials?.increment({
112
75
  inbound: true
113
76
  });
114
- accepted = await raceSignal(this.components.connectionManager.acceptIncomingConnection(maConn), signal);
77
+ accepted = this.components.connectionManager.acceptIncomingConnection(maConn);
115
78
  if (!accepted) {
116
79
  throw new ConnectionDeniedError('Connection denied');
117
80
  }
@@ -137,9 +100,6 @@ export class Upgrader {
137
100
  }
138
101
  }
139
102
  }
140
- /**
141
- * Upgrades an outbound connection
142
- */
143
103
  async upgradeOutbound(maConn, opts) {
144
104
  try {
145
105
  this.metrics.dials?.increment({
@@ -169,49 +129,53 @@ export class Upgrader {
169
129
  }
170
130
  }
171
131
  async _performUpgrade(maConn, direction, opts) {
172
- let encryptedConn;
132
+ let stream = maConn;
173
133
  let remotePeer;
174
- let upgradedConn;
175
134
  let muxerFactory;
135
+ let muxer;
176
136
  let cryptoProtocol;
137
+ const id = `${(parseInt(String(Math.random() * 1e9))).toString(36)}${Date.now()}`;
138
+ maConn.log = maConn.log.newScope(`${direction}:${id}`);
177
139
  this.components.metrics?.trackMultiaddrConnection(maConn);
178
140
  maConn.log.trace('starting the %s connection upgrade', direction);
179
141
  // Protect
180
- let protectedConn = maConn;
181
142
  if (opts?.skipProtection !== true) {
182
143
  const protector = this.components.connectionProtector;
183
144
  if (protector != null) {
184
145
  maConn.log('protecting the %s connection', direction);
185
- protectedConn = await protector.protect(maConn, opts);
146
+ stream = await protector.protect(stream, opts);
186
147
  }
187
148
  }
188
149
  try {
189
150
  // Encrypt the connection
190
- encryptedConn = protectedConn;
191
- if (opts?.skipEncryption !== true) {
151
+ if (isEncryptionSkipped(opts)) {
152
+ if (opts.remotePeer == null) {
153
+ throw new InvalidMultiaddrError(`${direction} connection that skipped encryption must have a peer id`);
154
+ }
155
+ cryptoProtocol = 'native';
156
+ remotePeer = opts.remotePeer;
157
+ }
158
+ else {
159
+ const peerIdString = maConn.remoteAddr.getPeerId();
160
+ let remotePeerFromMultiaddr;
161
+ if (peerIdString != null) {
162
+ remotePeerFromMultiaddr = peerIdFromString(peerIdString);
163
+ }
192
164
  opts?.onProgress?.(new CustomProgressEvent(`upgrader:encrypt-${direction}-connection`));
193
165
  ({
194
- conn: encryptedConn,
166
+ connection: stream,
195
167
  remotePeer,
196
168
  protocol: cryptoProtocol,
197
169
  streamMuxer: muxerFactory
198
170
  } = await (direction === 'inbound'
199
- ? this._encryptInbound(protectedConn, opts)
200
- : this._encryptOutbound(protectedConn, opts)));
201
- const maConn = {
202
- ...protectedConn,
203
- ...encryptedConn
204
- };
205
- await this.shouldBlockConnection(direction === 'inbound' ? 'denyInboundEncryptedConnection' : 'denyOutboundEncryptedConnection', remotePeer, maConn);
206
- }
207
- else {
208
- const idStr = maConn.remoteAddr.getPeerId();
209
- if (idStr == null) {
210
- throw new InvalidMultiaddrError(`${direction} connection that skipped encryption must have a peer id`);
211
- }
212
- const remotePeerId = peerIdFromString(idStr);
213
- cryptoProtocol = 'native';
214
- remotePeer = remotePeerId;
171
+ ? this._encryptInbound(stream, {
172
+ ...opts,
173
+ remotePeer: remotePeerFromMultiaddr
174
+ })
175
+ : this._encryptOutbound(stream, {
176
+ ...opts,
177
+ remotePeer: remotePeerFromMultiaddr
178
+ })));
215
179
  }
216
180
  // this can happen if we dial a multiaddr without a peer id, we only find
217
181
  // out the identity of the remote after the connection is encrypted
@@ -220,287 +184,84 @@ export class Upgrader {
220
184
  maConn.abort(err);
221
185
  throw err;
222
186
  }
223
- upgradedConn = encryptedConn;
187
+ // stream.pause()
188
+ await this.shouldBlockConnection(direction === 'inbound' ? 'denyInboundEncryptedConnection' : 'denyOutboundEncryptedConnection', remotePeer, maConn);
189
+ // stream.resume()
224
190
  if (opts?.muxerFactory != null) {
225
191
  muxerFactory = opts.muxerFactory;
226
192
  }
227
193
  else if (muxerFactory == null && this.streamMuxers.size > 0) {
228
194
  opts?.onProgress?.(new CustomProgressEvent(`upgrader:multiplex-${direction}-connection`));
229
195
  // Multiplex the connection
230
- const multiplexed = await (direction === 'inbound'
231
- ? this._multiplexInbound({
232
- ...protectedConn,
233
- ...encryptedConn
234
- }, this.streamMuxers, opts)
235
- : this._multiplexOutbound({
236
- ...protectedConn,
237
- ...encryptedConn
238
- }, this.streamMuxers, opts));
239
- muxerFactory = multiplexed.muxerFactory;
240
- upgradedConn = multiplexed.stream;
196
+ muxerFactory = await (direction === 'inbound'
197
+ ? this._multiplexInbound(stream, this.streamMuxers, opts)
198
+ : this._multiplexOutbound(stream, this.streamMuxers, opts));
241
199
  }
242
200
  }
243
201
  catch (err) {
244
- maConn.log.error('failed to upgrade inbound connection %s %a - %e', direction === 'inbound' ? 'from' : 'to', maConn.remoteAddr, err);
202
+ maConn.log.error('failed to upgrade %s connection %s %a - %e', direction, direction === 'inbound' ? 'from' : 'to', maConn.remoteAddr, err);
245
203
  throw err;
246
204
  }
205
+ // create the connection muxer if one is configured
206
+ if (muxerFactory != null) {
207
+ maConn.log('create muxer %s', muxerFactory.protocol);
208
+ muxer = muxerFactory.createStreamMuxer(stream);
209
+ }
210
+ // stream.pause()
247
211
  await this.shouldBlockConnection(direction === 'inbound' ? 'denyInboundUpgradedConnection' : 'denyOutboundUpgradedConnection', remotePeer, maConn);
248
- maConn.log('successfully upgraded %s connection', direction);
249
- return this._createConnection({
212
+ const conn = this._createConnection({
213
+ id,
250
214
  cryptoProtocol,
251
215
  direction,
252
216
  maConn,
253
- upgradedConn,
254
- muxerFactory,
217
+ stream,
218
+ muxer,
255
219
  remotePeer,
256
- limits: opts?.limits
220
+ limits: opts?.limits,
221
+ closeTimeout: this.connectionCloseTimeout
257
222
  });
223
+ conn.log('successfully upgraded connection');
224
+ // stream.resume()
225
+ return conn;
258
226
  }
259
227
  /**
260
228
  * A convenience method for generating a new `Connection`
261
229
  */
262
230
  _createConnection(opts) {
263
- const { cryptoProtocol, direction, maConn, upgradedConn, remotePeer, muxerFactory, limits } = opts;
264
- let muxer;
265
- let newStream;
266
- let connection; // eslint-disable-line prefer-const
267
- if (muxerFactory != null) {
268
- // Create the muxer
269
- muxer = muxerFactory.createStreamMuxer({
270
- direction,
271
- // Run anytime a remote stream is created
272
- onIncomingStream: muxedStream => {
273
- if (connection == null) {
274
- return;
275
- }
276
- const signal = AbortSignal.timeout(this.inboundStreamProtocolNegotiationTimeout);
277
- setMaxListeners(Infinity, signal);
278
- void Promise.resolve()
279
- .then(async () => {
280
- const protocols = this.components.registrar.getProtocols();
281
- const { stream, protocol } = await mss.handle(muxedStream, protocols, {
282
- signal,
283
- log: muxedStream.log,
284
- yieldBytes: false
285
- });
286
- if (connection == null) {
287
- return;
288
- }
289
- connection.log('incoming stream opened on %s', protocol);
290
- const incomingLimit = findIncomingStreamLimit(protocol, this.components.registrar);
291
- const streamCount = countStreams(protocol, 'inbound', connection);
292
- if (streamCount === incomingLimit) {
293
- const err = new TooManyInboundProtocolStreamsError(`Too many inbound protocol streams for protocol "${protocol}" - limit ${incomingLimit}`);
294
- muxedStream.abort(err);
295
- throw err;
296
- }
297
- // after the handshake the returned stream can have early data so override
298
- // the source/sink
299
- muxedStream.source = stream.source;
300
- muxedStream.sink = stream.sink;
301
- muxedStream.protocol = protocol;
302
- // allow closing the write end of a not-yet-negotiated stream
303
- if (stream.closeWrite != null) {
304
- muxedStream.closeWrite = stream.closeWrite;
305
- }
306
- // allow closing the read end of a not-yet-negotiated stream
307
- if (stream.closeRead != null) {
308
- muxedStream.closeRead = stream.closeRead;
309
- }
310
- // make sure we don't try to negotiate a stream we are closing
311
- if (stream.close != null) {
312
- muxedStream.close = stream.close;
313
- }
314
- // If a protocol stream has been successfully negotiated and is to be passed to the application,
315
- // the peer store should ensure that the peer is registered with that protocol
316
- await this.components.peerStore.merge(remotePeer, {
317
- protocols: [protocol]
318
- }, {
319
- signal
320
- });
321
- this.components.metrics?.trackProtocolStream(muxedStream, connection);
322
- this._onStream({ connection, stream: muxedStream, protocol });
323
- })
324
- .catch(async (err) => {
325
- connection.log.error('error handling incoming stream id %s - %e', muxedStream.id, err);
326
- if (muxedStream.timeline.close == null) {
327
- await muxedStream.close({
328
- signal
329
- })
330
- .catch(err => muxedStream.abort(err));
331
- }
332
- });
333
- }
334
- });
335
- newStream = async (protocols, options = {}) => {
336
- if (muxer == null) {
337
- throw new MuxerUnavailableError('Connection is not multiplexed');
338
- }
339
- connection.log.trace('starting new stream for protocols %s', protocols);
340
- const muxedStream = await muxer.newStream();
341
- connection.log.trace('started new stream %s for protocols %s', muxedStream.id, protocols);
342
- try {
343
- if (options.signal == null) {
344
- muxedStream.log('no abort signal was passed while trying to negotiate protocols %s falling back to default timeout', protocols);
345
- const signal = AbortSignal.timeout(this.outboundStreamProtocolNegotiationTimeout);
346
- setMaxListeners(Infinity, signal);
347
- options = {
348
- ...options,
349
- signal
350
- };
351
- }
352
- muxedStream.log.trace('selecting protocol from protocols %s', protocols);
353
- const { stream, protocol } = await mss.select(muxedStream, protocols, {
354
- ...options,
355
- log: muxedStream.log,
356
- yieldBytes: true
357
- });
358
- muxedStream.log.trace('selected protocol %s', protocol);
359
- const outgoingLimit = findOutgoingStreamLimit(protocol, this.components.registrar, options);
360
- const streamCount = countStreams(protocol, 'outbound', connection);
361
- if (streamCount >= outgoingLimit) {
362
- const err = new TooManyOutboundProtocolStreamsError(`Too many outbound protocol streams for protocol "${protocol}" - ${streamCount}/${outgoingLimit}`);
363
- muxedStream.abort(err);
364
- throw err;
365
- }
366
- // If a protocol stream has been successfully negotiated and is to be passed to the application,
367
- // the peer store should ensure that the peer is registered with that protocol
368
- await this.components.peerStore.merge(remotePeer, {
369
- protocols: [protocol]
370
- });
371
- // after the handshake the returned stream can have early data so override
372
- // the source/sink
373
- muxedStream.source = stream.source;
374
- muxedStream.sink = stream.sink;
375
- muxedStream.protocol = protocol;
376
- // allow closing the write end of a not-yet-negotiated stream
377
- if (stream.closeWrite != null) {
378
- muxedStream.closeWrite = stream.closeWrite;
379
- }
380
- // allow closing the read end of a not-yet-negotiated stream
381
- if (stream.closeRead != null) {
382
- muxedStream.closeRead = stream.closeRead;
383
- }
384
- // make sure we don't try to negotiate a stream we are closing
385
- if (stream.close != null) {
386
- muxedStream.close = stream.close;
387
- }
388
- this.components.metrics?.trackProtocolStream(muxedStream, connection);
389
- return muxedStream;
390
- }
391
- catch (err) {
392
- connection.log.error('could not create new outbound stream on connection %s %a for protocols %s - %e', direction === 'inbound' ? 'from' : 'to', opts.maConn.remoteAddr, protocols, err);
393
- if (muxedStream.timeline.close == null) {
394
- muxedStream.abort(err);
395
- }
396
- throw err;
397
- }
398
- };
399
- // Pipe all data through the muxer
400
- void Promise.all([
401
- muxer.sink(upgradedConn.source),
402
- upgradedConn.sink(muxer.source)
403
- ]).catch(err => {
404
- connection.log.error('error piping data through muxer - %e', err);
405
- });
406
- }
407
- const _timeline = maConn.timeline;
408
- maConn.timeline = new Proxy(_timeline, {
409
- set: (...args) => {
410
- if (args[1] === 'close' && args[2] != null && _timeline.close == null) {
411
- // Wait for close to finish before notifying of the closure
412
- (async () => {
413
- try {
414
- if (connection.status === 'open') {
415
- await connection.close();
416
- }
417
- }
418
- catch (err) {
419
- connection.log.error('error closing connection after timeline close %e', err);
420
- }
421
- finally {
422
- this.events.safeDispatchEvent('connection:close', {
423
- detail: connection
424
- });
425
- }
426
- })().catch(err => {
427
- connection.log.error('error thrown while dispatching connection:close event %e', err);
428
- });
429
- }
430
- return Reflect.set(...args);
431
- }
432
- });
433
- maConn.timeline.upgraded = Date.now();
434
- const errConnectionNotMultiplexed = () => {
435
- throw new MuxerUnavailableError('Connection is not multiplexed');
436
- };
437
231
  // Create the connection
438
- connection = createConnection({
439
- remoteAddr: maConn.remoteAddr,
440
- remotePeer,
441
- status: 'open',
442
- direction,
443
- timeline: maConn.timeline,
444
- multiplexer: muxer?.protocol,
445
- encryption: cryptoProtocol,
446
- limits,
447
- logger: this.components.logger,
448
- newStream: newStream ?? errConnectionNotMultiplexed,
449
- getStreams: () => {
450
- return muxer?.streams ?? [];
451
- },
452
- close: async (options) => {
453
- // ensure remaining streams are closed gracefully
454
- await muxer?.close(options);
455
- // close the underlying transport
456
- await maConn.close(options);
457
- },
458
- abort: (err) => {
459
- maConn.abort(err);
460
- // ensure remaining streams are aborted
461
- muxer?.abort(err);
462
- }
232
+ const connection = createConnection(this.components, {
233
+ ...opts,
234
+ outboundStreamProtocolNegotiationTimeout: this.outboundStreamProtocolNegotiationTimeout,
235
+ inboundStreamProtocolNegotiationTimeout: this.inboundStreamProtocolNegotiationTimeout
236
+ });
237
+ connection.addEventListener('close', () => {
238
+ this.events.safeDispatchEvent('connection:close', {
239
+ detail: connection
240
+ });
463
241
  });
464
242
  this.events.safeDispatchEvent('connection:open', {
465
243
  detail: connection
466
244
  });
467
- // @ts-expect-error nah
468
- connection.__maConnTimeline = _timeline;
469
245
  return connection;
470
246
  }
471
- /**
472
- * Routes incoming streams to the correct handler
473
- */
474
- _onStream(opts) {
475
- const { connection, stream, protocol } = opts;
476
- const { handler, options } = this.components.registrar.getHandler(protocol);
477
- if (connection.limits != null && options.runOnLimitedConnection !== true) {
478
- throw new LimitedConnectionError('Cannot open protocol stream on limited connection');
479
- }
480
- handler({ connection, stream });
481
- }
482
247
  /**
483
248
  * Attempts to encrypt the incoming `connection` with the provided `cryptos`
484
249
  */
485
250
  async _encryptInbound(connection, options) {
486
251
  const protocols = Array.from(this.connectionEncrypters.keys());
487
252
  try {
488
- const { stream, protocol } = await mss.handle(connection, protocols, {
489
- ...options,
490
- log: connection.log
491
- });
253
+ const protocol = await mss.handle(connection, protocols, options);
492
254
  const encrypter = this.connectionEncrypters.get(protocol);
493
255
  if (encrypter == null) {
494
256
  throw new EncryptionFailedError(`no crypto module found for ${protocol}`);
495
257
  }
496
- connection.log('encrypting inbound connection to %a using %s', connection.remoteAddr, protocol);
258
+ connection.log('encrypting inbound connection using %s', protocol);
497
259
  return {
498
- ...await encrypter.secureInbound(stream, options),
260
+ ...await encrypter.secureInbound(connection, options),
499
261
  protocol
500
262
  };
501
263
  }
502
264
  catch (err) {
503
- connection.log.error('encrypting inbound connection from %a failed', connection.remoteAddr, err);
504
265
  throw new EncryptionFailedError(err.message);
505
266
  }
506
267
  }
@@ -512,23 +273,18 @@ export class Upgrader {
512
273
  const protocols = Array.from(this.connectionEncrypters.keys());
513
274
  try {
514
275
  connection.log.trace('selecting encrypter from %s', protocols);
515
- const { stream, protocol } = await mss.select(connection, protocols, {
516
- ...options,
517
- log: connection.log,
518
- yieldBytes: true
519
- });
276
+ const protocol = await mss.select(connection, protocols, options);
520
277
  const encrypter = this.connectionEncrypters.get(protocol);
521
278
  if (encrypter == null) {
522
279
  throw new EncryptionFailedError(`no crypto module found for ${protocol}`);
523
280
  }
524
- connection.log('encrypting outbound connection to %a using %s', connection.remoteAddr, protocol);
281
+ connection.log('encrypting outbound connection using %s', protocol);
525
282
  return {
526
- ...await encrypter.secureOutbound(stream, options),
283
+ ...await encrypter.secureOutbound(connection, options),
527
284
  protocol
528
285
  };
529
286
  }
530
287
  catch (err) {
531
- connection.log.error('encrypting outbound connection to %a failed', connection.remoteAddr, err);
532
288
  throw new EncryptionFailedError(err.message);
533
289
  }
534
290
  }
@@ -536,22 +292,21 @@ export class Upgrader {
536
292
  * Selects one of the given muxers via multistream-select. That
537
293
  * muxer will be used for all future streams on the connection.
538
294
  */
539
- async _multiplexOutbound(connection, muxers, options) {
295
+ async _multiplexOutbound(maConn, muxers, options) {
540
296
  const protocols = Array.from(muxers.keys());
541
- connection.log('outbound selecting muxer %s', protocols);
297
+ maConn.log('outbound selecting muxer %s', protocols);
542
298
  try {
543
- connection.log.trace('selecting stream muxer from %s', protocols);
544
- const { stream, protocol } = await mss.select(connection, protocols, {
545
- ...options,
546
- log: connection.log,
547
- yieldBytes: true
548
- });
549
- connection.log('selected %s as muxer protocol', protocol);
299
+ maConn.log.trace('selecting stream muxer from %s', protocols);
300
+ const protocol = await mss.select(maConn, protocols, options);
550
301
  const muxerFactory = muxers.get(protocol);
551
- return { stream, muxerFactory };
302
+ if (muxerFactory == null) {
303
+ throw new MuxerUnavailableError(`No muxer configured for protocol "${protocol}"`);
304
+ }
305
+ maConn.log('selected %s as muxer protocol', protocol);
306
+ return muxerFactory;
552
307
  }
553
308
  catch (err) {
554
- connection.log.error('error multiplexing outbound connection', err);
309
+ maConn.log.error('error multiplexing outbound connection', err);
555
310
  throw new MuxerUnavailableError(String(err));
556
311
  }
557
312
  }
@@ -559,20 +314,22 @@ export class Upgrader {
559
314
  * Registers support for one of the given muxers via multistream-select. The
560
315
  * selected muxer will be used for all future streams on the connection.
561
316
  */
562
- async _multiplexInbound(connection, muxers, options) {
317
+ async _multiplexInbound(maConn, muxers, options) {
563
318
  const protocols = Array.from(muxers.keys());
564
- connection.log('inbound handling muxers %s', protocols);
319
+ maConn.log('inbound handling muxers %s', protocols);
565
320
  try {
566
- const { stream, protocol } = await mss.handle(connection, protocols, {
567
- ...options,
568
- log: connection.log
569
- });
321
+ maConn.log.trace('selecting stream muxer from %s', protocols);
322
+ const protocol = await mss.handle(maConn, protocols, options);
570
323
  const muxerFactory = muxers.get(protocol);
571
- return { stream, muxerFactory };
324
+ if (muxerFactory == null) {
325
+ throw new MuxerUnavailableError(`No muxer configured for protocol "${protocol}"`);
326
+ }
327
+ maConn.log('selected %s as muxer protocol', protocol);
328
+ return muxerFactory;
572
329
  }
573
330
  catch (err) {
574
- connection.log.error('error multiplexing inbound connection', err);
575
- throw new MuxerUnavailableError(String(err));
331
+ maConn.log.error('error multiplexing inbound connection', err);
332
+ throw err;
576
333
  }
577
334
  }
578
335
  getConnectionEncrypters() {
@@ -582,4 +339,7 @@ export class Upgrader {
582
339
  return this.streamMuxers;
583
340
  }
584
341
  }
342
+ function isEncryptionSkipped(opts) {
343
+ return opts.skipEncryption === true;
344
+ }
585
345
  //# sourceMappingURL=upgrader.js.map