libp2p 2.9.0 → 2.10.0-8484de8a2

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 (119) 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 +1 -2
  4. package/dist/src/address-manager/dns-mappings.d.ts.map +1 -1
  5. package/dist/src/address-manager/dns-mappings.js +40 -44
  6. package/dist/src/address-manager/dns-mappings.js.map +1 -1
  7. package/dist/src/address-manager/index.d.ts.map +1 -1
  8. package/dist/src/address-manager/index.js +31 -14
  9. package/dist/src/address-manager/index.js.map +1 -1
  10. package/dist/src/address-manager/ip-mappings.d.ts +1 -0
  11. package/dist/src/address-manager/ip-mappings.d.ts.map +1 -1
  12. package/dist/src/address-manager/ip-mappings.js +51 -40
  13. package/dist/src/address-manager/ip-mappings.js.map +1 -1
  14. package/dist/src/address-manager/observed-addresses.d.ts.map +1 -1
  15. package/dist/src/address-manager/observed-addresses.js +1 -3
  16. package/dist/src/address-manager/observed-addresses.js.map +1 -1
  17. package/dist/src/address-manager/transport-addresses.d.ts.map +1 -1
  18. package/dist/src/address-manager/transport-addresses.js +6 -8
  19. package/dist/src/address-manager/transport-addresses.js.map +1 -1
  20. package/dist/src/config/connection-gater.browser.d.ts.map +1 -1
  21. package/dist/src/config/connection-gater.browser.js +3 -9
  22. package/dist/src/config/connection-gater.browser.js.map +1 -1
  23. package/dist/src/config.js +1 -1
  24. package/dist/src/config.js.map +1 -1
  25. package/dist/src/connection-manager/address-sorter.d.ts.map +1 -1
  26. package/dist/src/connection-manager/address-sorter.js +1 -2
  27. package/dist/src/connection-manager/address-sorter.js.map +1 -1
  28. package/dist/src/connection-manager/connection-pruner.d.ts.map +1 -1
  29. package/dist/src/connection-manager/connection-pruner.js +7 -3
  30. package/dist/src/connection-manager/connection-pruner.js.map +1 -1
  31. package/dist/src/connection-manager/constants.defaults.d.ts +4 -0
  32. package/dist/src/connection-manager/constants.defaults.d.ts.map +1 -1
  33. package/dist/src/connection-manager/constants.defaults.js +4 -0
  34. package/dist/src/connection-manager/constants.defaults.js.map +1 -1
  35. package/dist/src/connection-manager/dial-queue.d.ts +2 -2
  36. package/dist/src/connection-manager/dial-queue.d.ts.map +1 -1
  37. package/dist/src/connection-manager/dial-queue.js +13 -25
  38. package/dist/src/connection-manager/dial-queue.js.map +1 -1
  39. package/dist/src/connection-manager/index.d.ts +10 -2
  40. package/dist/src/connection-manager/index.d.ts.map +1 -1
  41. package/dist/src/connection-manager/index.js +45 -27
  42. package/dist/src/connection-manager/index.js.map +1 -1
  43. package/dist/src/connection-manager/reconnect-queue.js +1 -1
  44. package/dist/src/connection-manager/reconnect-queue.js.map +1 -1
  45. package/dist/src/connection-manager/utils.d.ts +31 -3
  46. package/dist/src/connection-manager/utils.d.ts.map +1 -1
  47. package/dist/src/connection-manager/utils.js +99 -18
  48. package/dist/src/connection-manager/utils.js.map +1 -1
  49. package/dist/src/connection-monitor.d.ts +1 -1
  50. package/dist/src/connection-monitor.d.ts.map +1 -1
  51. package/dist/src/connection-monitor.js +2 -3
  52. package/dist/src/connection-monitor.js.map +1 -1
  53. package/dist/src/connection.d.ts +62 -0
  54. package/dist/src/connection.d.ts.map +1 -0
  55. package/dist/src/connection.js +239 -0
  56. package/dist/src/connection.js.map +1 -0
  57. package/dist/src/get-peer.js +3 -3
  58. package/dist/src/get-peer.js.map +1 -1
  59. package/dist/src/index.d.ts +2 -2
  60. package/dist/src/index.js +2 -2
  61. package/dist/src/libp2p.d.ts.map +1 -1
  62. package/dist/src/libp2p.js +5 -5
  63. package/dist/src/libp2p.js.map +1 -1
  64. package/dist/src/peer-routing.js +1 -1
  65. package/dist/src/peer-routing.js.map +1 -1
  66. package/dist/src/random-walk.d.ts.map +1 -1
  67. package/dist/src/random-walk.js +13 -3
  68. package/dist/src/random-walk.js.map +1 -1
  69. package/dist/src/registrar.d.ts +3 -3
  70. package/dist/src/registrar.d.ts.map +1 -1
  71. package/dist/src/registrar.js +50 -41
  72. package/dist/src/registrar.js.map +1 -1
  73. package/dist/src/transport-manager.js +15 -2
  74. package/dist/src/transport-manager.js.map +1 -1
  75. package/dist/src/upgrader.d.ts +27 -25
  76. package/dist/src/upgrader.d.ts.map +1 -1
  77. package/dist/src/upgrader.js +97 -336
  78. package/dist/src/upgrader.js.map +1 -1
  79. package/dist/src/utils.d.ts +3 -0
  80. package/dist/src/utils.d.ts.map +1 -0
  81. package/dist/src/utils.js +25 -0
  82. package/dist/src/utils.js.map +1 -0
  83. package/dist/src/version.d.ts +1 -1
  84. package/dist/src/version.d.ts.map +1 -1
  85. package/dist/src/version.js +1 -1
  86. package/dist/src/version.js.map +1 -1
  87. package/package.json +26 -30
  88. package/src/address-manager/dns-mappings.ts +51 -51
  89. package/src/address-manager/index.ts +37 -17
  90. package/src/address-manager/ip-mappings.ts +64 -44
  91. package/src/address-manager/observed-addresses.ts +1 -3
  92. package/src/address-manager/transport-addresses.ts +7 -9
  93. package/src/config/connection-gater.browser.ts +3 -12
  94. package/src/config.ts +1 -1
  95. package/src/connection-manager/address-sorter.ts +1 -2
  96. package/src/connection-manager/connection-pruner.ts +8 -3
  97. package/src/connection-manager/constants.defaults.ts +5 -0
  98. package/src/connection-manager/dial-queue.ts +14 -29
  99. package/src/connection-manager/index.ts +62 -29
  100. package/src/connection-manager/reconnect-queue.ts +1 -1
  101. package/src/connection-manager/utils.ts +129 -21
  102. package/src/connection-monitor.ts +3 -4
  103. package/src/connection.ts +316 -0
  104. package/src/get-peer.ts +3 -3
  105. package/src/index.ts +2 -2
  106. package/src/libp2p.ts +5 -6
  107. package/src/peer-routing.ts +1 -1
  108. package/src/random-walk.ts +13 -3
  109. package/src/registrar.ts +67 -54
  110. package/src/transport-manager.ts +18 -2
  111. package/src/upgrader.ts +143 -421
  112. package/src/utils.ts +31 -0
  113. package/src/version.ts +1 -1
  114. package/dist/src/connection/index.d.ts +0 -84
  115. package/dist/src/connection/index.d.ts.map +0 -1
  116. package/dist/src/connection/index.js +0 -144
  117. package/dist/src/connection/index.js.map +0 -1
  118. package/dist/typedoc-urls.json +0 -24
  119. package/src/connection/index.ts +0 -199
@@ -1,50 +1,15 @@
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
+ import { CODE_P2P } from '@multiformats/multiaddr';
5
6
  import { anySignal } from 'any-signal';
6
7
  import { setMaxListeners } from 'main-event';
7
8
  import { CustomProgressEvent } from 'progress-events';
8
9
  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';
10
+ import { PROTOCOL_NEGOTIATION_TIMEOUT, INBOUND_UPGRADE_TIMEOUT, CONNECTION_CLOSE_TIMEOUT } from './connection-manager/constants.js';
11
+ import { createConnection } from './connection.js';
11
12
  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
13
  export class Upgrader {
49
14
  components;
50
15
  connectionEncrypters;
@@ -54,6 +19,7 @@ export class Upgrader {
54
19
  outboundStreamProtocolNegotiationTimeout;
55
20
  events;
56
21
  metrics;
22
+ connectionCloseTimeout;
57
23
  constructor(components, init) {
58
24
  this.components = components;
59
25
  this.connectionEncrypters = trackedMap({
@@ -73,6 +39,7 @@ export class Upgrader {
73
39
  this.inboundUpgradeTimeout = init.inboundUpgradeTimeout ?? INBOUND_UPGRADE_TIMEOUT;
74
40
  this.inboundStreamProtocolNegotiationTimeout = init.inboundStreamProtocolNegotiationTimeout ?? PROTOCOL_NEGOTIATION_TIMEOUT;
75
41
  this.outboundStreamProtocolNegotiationTimeout = init.outboundStreamProtocolNegotiationTimeout ?? PROTOCOL_NEGOTIATION_TIMEOUT;
42
+ this.connectionCloseTimeout = init.connectionCloseTimeout ?? CONNECTION_CLOSE_TIMEOUT;
76
43
  this.events = components.events;
77
44
  this.metrics = {
78
45
  dials: components.metrics?.registerCounterGroup('libp2p_connection_manager_dials_total'),
@@ -100,9 +67,6 @@ export class Upgrader {
100
67
  setMaxListeners(Infinity, output);
101
68
  return output;
102
69
  }
103
- /**
104
- * Upgrades an inbound connection
105
- */
106
70
  async upgradeInbound(maConn, opts) {
107
71
  let accepted = false;
108
72
  // always apply upgrade timeout for incoming upgrades
@@ -111,7 +75,7 @@ export class Upgrader {
111
75
  this.metrics.dials?.increment({
112
76
  inbound: true
113
77
  });
114
- accepted = await raceSignal(this.components.connectionManager.acceptIncomingConnection(maConn), signal);
78
+ accepted = this.components.connectionManager.acceptIncomingConnection(maConn);
115
79
  if (!accepted) {
116
80
  throw new ConnectionDeniedError('Connection denied');
117
81
  }
@@ -137,15 +101,12 @@ export class Upgrader {
137
101
  }
138
102
  }
139
103
  }
140
- /**
141
- * Upgrades an outbound connection
142
- */
143
104
  async upgradeOutbound(maConn, opts) {
144
105
  try {
145
106
  this.metrics.dials?.increment({
146
107
  outbound: true
147
108
  });
148
- const idStr = maConn.remoteAddr.getPeerId();
109
+ const idStr = maConn.remoteAddr.getComponents().findLast(c => c.code === CODE_P2P)?.value;
149
110
  let remotePeerId;
150
111
  if (idStr != null) {
151
112
  remotePeerId = peerIdFromString(idStr);
@@ -169,49 +130,53 @@ export class Upgrader {
169
130
  }
170
131
  }
171
132
  async _performUpgrade(maConn, direction, opts) {
172
- let encryptedConn;
133
+ let stream = maConn;
173
134
  let remotePeer;
174
- let upgradedConn;
175
135
  let muxerFactory;
136
+ let muxer;
176
137
  let cryptoProtocol;
138
+ const id = `${(parseInt(String(Math.random() * 1e9))).toString(36)}${Date.now()}`;
139
+ maConn.log = maConn.log.newScope(`${direction}:${id}`);
177
140
  this.components.metrics?.trackMultiaddrConnection(maConn);
178
141
  maConn.log.trace('starting the %s connection upgrade', direction);
179
142
  // Protect
180
- let protectedConn = maConn;
181
143
  if (opts?.skipProtection !== true) {
182
144
  const protector = this.components.connectionProtector;
183
145
  if (protector != null) {
184
146
  maConn.log('protecting the %s connection', direction);
185
- protectedConn = await protector.protect(maConn, opts);
147
+ stream = await protector.protect(stream, opts);
186
148
  }
187
149
  }
188
150
  try {
189
151
  // Encrypt the connection
190
- encryptedConn = protectedConn;
191
- if (opts?.skipEncryption !== true) {
152
+ if (isEncryptionSkipped(opts)) {
153
+ if (opts.remotePeer == null) {
154
+ throw new InvalidMultiaddrError(`${direction} connection that skipped encryption must have a peer id`);
155
+ }
156
+ cryptoProtocol = 'native';
157
+ remotePeer = opts.remotePeer;
158
+ }
159
+ else {
160
+ const peerIdString = maConn.remoteAddr.getComponents().findLast(c => c.code === CODE_P2P)?.value;
161
+ let remotePeerFromMultiaddr;
162
+ if (peerIdString != null) {
163
+ remotePeerFromMultiaddr = peerIdFromString(peerIdString);
164
+ }
192
165
  opts?.onProgress?.(new CustomProgressEvent(`upgrader:encrypt-${direction}-connection`));
193
166
  ({
194
- conn: encryptedConn,
167
+ connection: stream,
195
168
  remotePeer,
196
169
  protocol: cryptoProtocol,
197
170
  streamMuxer: muxerFactory
198
171
  } = 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;
172
+ ? this._encryptInbound(stream, {
173
+ ...opts,
174
+ remotePeer: remotePeerFromMultiaddr
175
+ })
176
+ : this._encryptOutbound(stream, {
177
+ ...opts,
178
+ remotePeer: remotePeerFromMultiaddr
179
+ })));
215
180
  }
216
181
  // this can happen if we dial a multiaddr without a peer id, we only find
217
182
  // out the identity of the remote after the connection is encrypted
@@ -220,287 +185,84 @@ export class Upgrader {
220
185
  maConn.abort(err);
221
186
  throw err;
222
187
  }
223
- upgradedConn = encryptedConn;
188
+ // stream.pause()
189
+ await this.shouldBlockConnection(direction === 'inbound' ? 'denyInboundEncryptedConnection' : 'denyOutboundEncryptedConnection', remotePeer, maConn);
190
+ // stream.resume()
224
191
  if (opts?.muxerFactory != null) {
225
192
  muxerFactory = opts.muxerFactory;
226
193
  }
227
194
  else if (muxerFactory == null && this.streamMuxers.size > 0) {
228
195
  opts?.onProgress?.(new CustomProgressEvent(`upgrader:multiplex-${direction}-connection`));
229
196
  // 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;
197
+ muxerFactory = await (direction === 'inbound'
198
+ ? this._multiplexInbound(stream, this.streamMuxers, opts)
199
+ : this._multiplexOutbound(stream, this.streamMuxers, opts));
241
200
  }
242
201
  }
243
202
  catch (err) {
244
- maConn.log.error('failed to upgrade inbound connection %s %a - %e', direction === 'inbound' ? 'from' : 'to', maConn.remoteAddr, err);
203
+ maConn.log.error('failed to upgrade %s connection %s %a - %e', direction, direction === 'inbound' ? 'from' : 'to', maConn.remoteAddr, err);
245
204
  throw err;
246
205
  }
206
+ // create the connection muxer if one is configured
207
+ if (muxerFactory != null) {
208
+ maConn.log('create muxer %s', muxerFactory.protocol);
209
+ muxer = muxerFactory.createStreamMuxer(stream);
210
+ }
211
+ // stream.pause()
247
212
  await this.shouldBlockConnection(direction === 'inbound' ? 'denyInboundUpgradedConnection' : 'denyOutboundUpgradedConnection', remotePeer, maConn);
248
- maConn.log('successfully upgraded %s connection', direction);
249
- return this._createConnection({
213
+ const conn = this._createConnection({
214
+ id,
250
215
  cryptoProtocol,
251
216
  direction,
252
217
  maConn,
253
- upgradedConn,
254
- muxerFactory,
218
+ stream,
219
+ muxer,
255
220
  remotePeer,
256
- limits: opts?.limits
221
+ limits: opts?.limits,
222
+ closeTimeout: this.connectionCloseTimeout
257
223
  });
224
+ conn.log('successfully upgraded connection');
225
+ // stream.resume()
226
+ return conn;
258
227
  }
259
228
  /**
260
229
  * A convenience method for generating a new `Connection`
261
230
  */
262
231
  _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
232
  // 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
- }
233
+ const connection = createConnection(this.components, {
234
+ ...opts,
235
+ outboundStreamProtocolNegotiationTimeout: this.outboundStreamProtocolNegotiationTimeout,
236
+ inboundStreamProtocolNegotiationTimeout: this.inboundStreamProtocolNegotiationTimeout
237
+ });
238
+ connection.addEventListener('close', () => {
239
+ this.events.safeDispatchEvent('connection:close', {
240
+ detail: connection
241
+ });
463
242
  });
464
243
  this.events.safeDispatchEvent('connection:open', {
465
244
  detail: connection
466
245
  });
467
- // @ts-expect-error nah
468
- connection.__maConnTimeline = _timeline;
469
246
  return connection;
470
247
  }
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
248
  /**
483
249
  * Attempts to encrypt the incoming `connection` with the provided `cryptos`
484
250
  */
485
251
  async _encryptInbound(connection, options) {
486
252
  const protocols = Array.from(this.connectionEncrypters.keys());
487
253
  try {
488
- const { stream, protocol } = await mss.handle(connection, protocols, {
489
- ...options,
490
- log: connection.log
491
- });
254
+ const protocol = await mss.handle(connection, protocols, options);
492
255
  const encrypter = this.connectionEncrypters.get(protocol);
493
256
  if (encrypter == null) {
494
257
  throw new EncryptionFailedError(`no crypto module found for ${protocol}`);
495
258
  }
496
- connection.log('encrypting inbound connection to %a using %s', connection.remoteAddr, protocol);
259
+ connection.log('encrypting inbound connection using %s', protocol);
497
260
  return {
498
- ...await encrypter.secureInbound(stream, options),
261
+ ...await encrypter.secureInbound(connection, options),
499
262
  protocol
500
263
  };
501
264
  }
502
265
  catch (err) {
503
- connection.log.error('encrypting inbound connection from %a failed', connection.remoteAddr, err);
504
266
  throw new EncryptionFailedError(err.message);
505
267
  }
506
268
  }
@@ -512,23 +274,18 @@ export class Upgrader {
512
274
  const protocols = Array.from(this.connectionEncrypters.keys());
513
275
  try {
514
276
  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
- });
277
+ const protocol = await mss.select(connection, protocols, options);
520
278
  const encrypter = this.connectionEncrypters.get(protocol);
521
279
  if (encrypter == null) {
522
280
  throw new EncryptionFailedError(`no crypto module found for ${protocol}`);
523
281
  }
524
- connection.log('encrypting outbound connection to %a using %s', connection.remoteAddr, protocol);
282
+ connection.log('encrypting outbound connection using %s', protocol);
525
283
  return {
526
- ...await encrypter.secureOutbound(stream, options),
284
+ ...await encrypter.secureOutbound(connection, options),
527
285
  protocol
528
286
  };
529
287
  }
530
288
  catch (err) {
531
- connection.log.error('encrypting outbound connection to %a failed', connection.remoteAddr, err);
532
289
  throw new EncryptionFailedError(err.message);
533
290
  }
534
291
  }
@@ -536,22 +293,21 @@ export class Upgrader {
536
293
  * Selects one of the given muxers via multistream-select. That
537
294
  * muxer will be used for all future streams on the connection.
538
295
  */
539
- async _multiplexOutbound(connection, muxers, options) {
296
+ async _multiplexOutbound(maConn, muxers, options) {
540
297
  const protocols = Array.from(muxers.keys());
541
- connection.log('outbound selecting muxer %s', protocols);
298
+ maConn.log('outbound selecting muxer %s', protocols);
542
299
  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);
300
+ maConn.log.trace('selecting stream muxer from %s', protocols);
301
+ const protocol = await mss.select(maConn, protocols, options);
550
302
  const muxerFactory = muxers.get(protocol);
551
- return { stream, muxerFactory };
303
+ if (muxerFactory == null) {
304
+ throw new MuxerUnavailableError(`No muxer configured for protocol "${protocol}"`);
305
+ }
306
+ maConn.log('selected %s as muxer protocol', protocol);
307
+ return muxerFactory;
552
308
  }
553
309
  catch (err) {
554
- connection.log.error('error multiplexing outbound connection', err);
310
+ maConn.log.error('error multiplexing outbound connection', err);
555
311
  throw new MuxerUnavailableError(String(err));
556
312
  }
557
313
  }
@@ -559,20 +315,22 @@ export class Upgrader {
559
315
  * Registers support for one of the given muxers via multistream-select. The
560
316
  * selected muxer will be used for all future streams on the connection.
561
317
  */
562
- async _multiplexInbound(connection, muxers, options) {
318
+ async _multiplexInbound(maConn, muxers, options) {
563
319
  const protocols = Array.from(muxers.keys());
564
- connection.log('inbound handling muxers %s', protocols);
320
+ maConn.log('inbound handling muxers %s', protocols);
565
321
  try {
566
- const { stream, protocol } = await mss.handle(connection, protocols, {
567
- ...options,
568
- log: connection.log
569
- });
322
+ maConn.log.trace('selecting stream muxer from %s', protocols);
323
+ const protocol = await mss.handle(maConn, protocols, options);
570
324
  const muxerFactory = muxers.get(protocol);
571
- return { stream, muxerFactory };
325
+ if (muxerFactory == null) {
326
+ throw new MuxerUnavailableError(`No muxer configured for protocol "${protocol}"`);
327
+ }
328
+ maConn.log('selected %s as muxer protocol', protocol);
329
+ return muxerFactory;
572
330
  }
573
331
  catch (err) {
574
- connection.log.error('error multiplexing inbound connection', err);
575
- throw new MuxerUnavailableError(String(err));
332
+ maConn.log.error('error multiplexing inbound connection', err);
333
+ throw err;
576
334
  }
577
335
  }
578
336
  getConnectionEncrypters() {
@@ -582,4 +340,7 @@ export class Upgrader {
582
340
  return this.streamMuxers;
583
341
  }
584
342
  }
343
+ function isEncryptionSkipped(opts) {
344
+ return opts.skipEncryption === true;
345
+ }
585
346
  //# sourceMappingURL=upgrader.js.map