libp2p 0.37.3 → 0.38.0

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 (189) hide show
  1. package/README.md +1 -2
  2. package/dist/src/address-manager/index.d.ts +2 -2
  3. package/dist/src/address-manager/index.d.ts.map +1 -1
  4. package/dist/src/circuit/auto-relay.d.ts +4 -4
  5. package/dist/src/circuit/auto-relay.d.ts.map +1 -1
  6. package/dist/src/circuit/circuit/hop.d.ts +7 -5
  7. package/dist/src/circuit/circuit/hop.d.ts.map +1 -1
  8. package/dist/src/circuit/circuit/hop.js +8 -4
  9. package/dist/src/circuit/circuit/hop.js.map +1 -1
  10. package/dist/src/circuit/circuit/stop.d.ts +6 -4
  11. package/dist/src/circuit/circuit/stop.d.ts.map +1 -1
  12. package/dist/src/circuit/circuit/stop.js +4 -2
  13. package/dist/src/circuit/circuit/stop.js.map +1 -1
  14. package/dist/src/circuit/circuit/stream-handler.d.ts +3 -2
  15. package/dist/src/circuit/circuit/stream-handler.d.ts.map +1 -1
  16. package/dist/src/circuit/circuit/stream-handler.js +2 -2
  17. package/dist/src/circuit/circuit/stream-handler.js.map +1 -1
  18. package/dist/src/circuit/index.d.ts +4 -12
  19. package/dist/src/circuit/index.d.ts.map +1 -1
  20. package/dist/src/circuit/index.js.map +1 -1
  21. package/dist/src/circuit/listener.d.ts +3 -3
  22. package/dist/src/circuit/listener.d.ts.map +1 -1
  23. package/dist/src/circuit/pb/index.d.ts +5 -4
  24. package/dist/src/circuit/pb/index.d.ts.map +1 -1
  25. package/dist/src/circuit/pb/index.js +107 -11
  26. package/dist/src/circuit/pb/index.js.map +1 -1
  27. package/dist/src/circuit/transport.d.ts +8 -5
  28. package/dist/src/circuit/transport.d.ts.map +1 -1
  29. package/dist/src/circuit/transport.js +81 -59
  30. package/dist/src/circuit/transport.js.map +1 -1
  31. package/dist/src/config.d.ts.map +1 -1
  32. package/dist/src/config.js +27 -4
  33. package/dist/src/config.js.map +1 -1
  34. package/dist/src/connection-manager/auto-dialler.d.ts +1 -1
  35. package/dist/src/connection-manager/auto-dialler.d.ts.map +1 -1
  36. package/dist/src/connection-manager/dialer/auto-dialer.d.ts +2 -2
  37. package/dist/src/connection-manager/dialer/auto-dialer.d.ts.map +1 -1
  38. package/dist/src/connection-manager/dialer/auto-dialer.js +6 -0
  39. package/dist/src/connection-manager/dialer/auto-dialer.js.map +1 -1
  40. package/dist/src/connection-manager/dialer/dial-request.d.ts +1 -1
  41. package/dist/src/connection-manager/dialer/dial-request.d.ts.map +1 -1
  42. package/dist/src/connection-manager/dialer/index.d.ts +9 -9
  43. package/dist/src/connection-manager/dialer/index.d.ts.map +1 -1
  44. package/dist/src/connection-manager/dialer/index.js +11 -11
  45. package/dist/src/connection-manager/dialer/index.js.map +1 -1
  46. package/dist/src/connection-manager/index.d.ts +20 -16
  47. package/dist/src/connection-manager/index.d.ts.map +1 -1
  48. package/dist/src/connection-manager/index.js +185 -65
  49. package/dist/src/connection-manager/index.js.map +1 -1
  50. package/dist/src/constants.d.ts +4 -0
  51. package/dist/src/constants.d.ts.map +1 -1
  52. package/dist/src/constants.js +4 -0
  53. package/dist/src/constants.js.map +1 -1
  54. package/dist/src/content-routing/index.d.ts +4 -4
  55. package/dist/src/content-routing/index.d.ts.map +1 -1
  56. package/dist/src/content-routing/utils.d.ts +2 -2
  57. package/dist/src/content-routing/utils.d.ts.map +1 -1
  58. package/dist/src/dht/dht-content-routing.d.ts +3 -3
  59. package/dist/src/dht/dht-content-routing.d.ts.map +1 -1
  60. package/dist/src/dht/dht-peer-routing.d.ts +5 -5
  61. package/dist/src/dht/dht-peer-routing.d.ts.map +1 -1
  62. package/dist/src/dht/dummy-dht.d.ts +3 -3
  63. package/dist/src/dht/dummy-dht.d.ts.map +1 -1
  64. package/dist/src/dht/dummy-dht.js +1 -1
  65. package/dist/src/dht/dummy-dht.js.map +1 -1
  66. package/dist/src/errors.d.ts +4 -1
  67. package/dist/src/errors.d.ts.map +1 -1
  68. package/dist/src/errors.js +3 -0
  69. package/dist/src/errors.js.map +1 -1
  70. package/dist/src/fetch/index.d.ts +11 -4
  71. package/dist/src/fetch/index.d.ts.map +1 -1
  72. package/dist/src/fetch/index.js +82 -41
  73. package/dist/src/fetch/index.js.map +1 -1
  74. package/dist/src/fetch/pb/proto.d.ts +4 -3
  75. package/dist/src/fetch/pb/proto.d.ts.map +1 -1
  76. package/dist/src/fetch/pb/proto.js +88 -8
  77. package/dist/src/fetch/pb/proto.js.map +1 -1
  78. package/dist/src/get-peer.d.ts +2 -2
  79. package/dist/src/get-peer.d.ts.map +1 -1
  80. package/dist/src/get-peer.js +1 -1
  81. package/dist/src/get-peer.js.map +1 -1
  82. package/dist/src/identify/index.d.ts +8 -8
  83. package/dist/src/identify/index.d.ts.map +1 -1
  84. package/dist/src/identify/index.js +49 -34
  85. package/dist/src/identify/index.js.map +1 -1
  86. package/dist/src/identify/pb/message.d.ts +2 -1
  87. package/dist/src/identify/pb/message.d.ts.map +1 -1
  88. package/dist/src/identify/pb/message.js +94 -10
  89. package/dist/src/identify/pb/message.js.map +1 -1
  90. package/dist/src/index.d.ts +18 -17
  91. package/dist/src/index.d.ts.map +1 -1
  92. package/dist/src/index.js.map +1 -1
  93. package/dist/src/insecure/index.d.ts +2 -2
  94. package/dist/src/insecure/index.d.ts.map +1 -1
  95. package/dist/src/insecure/index.js +8 -4
  96. package/dist/src/insecure/index.js.map +1 -1
  97. package/dist/src/insecure/pb/proto.d.ts +4 -3
  98. package/dist/src/insecure/pb/proto.d.ts.map +1 -1
  99. package/dist/src/insecure/pb/proto.js +89 -9
  100. package/dist/src/insecure/pb/proto.js.map +1 -1
  101. package/dist/src/keychain/index.d.ts +2 -2
  102. package/dist/src/keychain/index.d.ts.map +1 -1
  103. package/dist/src/libp2p.d.ts +14 -14
  104. package/dist/src/libp2p.d.ts.map +1 -1
  105. package/dist/src/libp2p.js +17 -17
  106. package/dist/src/libp2p.js.map +1 -1
  107. package/dist/src/metrics/index.d.ts +4 -5
  108. package/dist/src/metrics/index.d.ts.map +1 -1
  109. package/dist/src/metrics/index.js +9 -6
  110. package/dist/src/metrics/index.js.map +1 -1
  111. package/dist/src/metrics/moving-average.d.ts +1 -1
  112. package/dist/src/metrics/moving-average.d.ts.map +1 -1
  113. package/dist/src/metrics/stats.d.ts +1 -1
  114. package/dist/src/metrics/stats.d.ts.map +1 -1
  115. package/dist/src/nat-manager.d.ts +1 -1
  116. package/dist/src/nat-manager.d.ts.map +1 -1
  117. package/dist/src/peer-record-updater.d.ts +1 -1
  118. package/dist/src/peer-record-updater.d.ts.map +1 -1
  119. package/dist/src/peer-routing.d.ts +4 -4
  120. package/dist/src/peer-routing.d.ts.map +1 -1
  121. package/dist/src/ping/index.d.ts +10 -3
  122. package/dist/src/ping/index.d.ts.map +1 -1
  123. package/dist/src/ping/index.js +32 -9
  124. package/dist/src/ping/index.js.map +1 -1
  125. package/dist/src/pnet/index.d.ts +1 -2
  126. package/dist/src/pnet/index.d.ts.map +1 -1
  127. package/dist/src/pnet/index.js +2 -1
  128. package/dist/src/pnet/index.js.map +1 -1
  129. package/dist/src/pubsub/dummy-pubsub.d.ts +2 -2
  130. package/dist/src/pubsub/dummy-pubsub.d.ts.map +1 -1
  131. package/dist/src/registrar.d.ts +10 -8
  132. package/dist/src/registrar.d.ts.map +1 -1
  133. package/dist/src/registrar.js +63 -44
  134. package/dist/src/registrar.js.map +1 -1
  135. package/dist/src/transport-manager.d.ts +3 -3
  136. package/dist/src/transport-manager.d.ts.map +1 -1
  137. package/dist/src/upgrader.d.ts +12 -6
  138. package/dist/src/upgrader.d.ts.map +1 -1
  139. package/dist/src/upgrader.js +183 -82
  140. package/dist/src/upgrader.js.map +1 -1
  141. package/dist/src/version.d.ts.map +1 -1
  142. package/dist/src/version.js.map +1 -1
  143. package/package.json +66 -42
  144. package/src/address-manager/index.ts +2 -2
  145. package/src/circuit/README.md +2 -2
  146. package/src/circuit/auto-relay.ts +4 -4
  147. package/src/circuit/circuit/hop.ts +20 -11
  148. package/src/circuit/circuit/stop.ts +10 -5
  149. package/src/circuit/circuit/stream-handler.ts +6 -5
  150. package/src/circuit/index.ts +4 -13
  151. package/src/circuit/listener.ts +3 -3
  152. package/src/circuit/pb/index.ts +133 -15
  153. package/src/circuit/transport.ts +92 -63
  154. package/src/config.ts +27 -4
  155. package/src/connection-manager/auto-dialler.ts +1 -1
  156. package/src/connection-manager/dialer/auto-dialer.ts +8 -2
  157. package/src/connection-manager/dialer/dial-request.ts +1 -1
  158. package/src/connection-manager/dialer/index.ts +15 -15
  159. package/src/connection-manager/index.ts +239 -82
  160. package/src/constants.ts +5 -0
  161. package/src/content-routing/index.ts +2 -2
  162. package/src/content-routing/utils.ts +2 -2
  163. package/src/dht/dht-content-routing.ts +2 -2
  164. package/src/dht/dht-peer-routing.ts +3 -3
  165. package/src/dht/dummy-dht.ts +3 -3
  166. package/src/errors.ts +4 -1
  167. package/src/fetch/index.ts +120 -53
  168. package/src/fetch/pb/proto.ts +109 -11
  169. package/src/get-peer.ts +3 -3
  170. package/src/identify/index.ts +64 -47
  171. package/src/identify/pb/message.ts +111 -11
  172. package/src/index.ts +18 -17
  173. package/src/insecure/index.ts +11 -6
  174. package/src/insecure/pb/proto.ts +111 -12
  175. package/src/keychain/index.ts +2 -2
  176. package/src/libp2p.ts +34 -29
  177. package/src/metrics/index.ts +13 -12
  178. package/src/metrics/moving-average.ts +1 -1
  179. package/src/metrics/stats.ts +1 -1
  180. package/src/nat-manager.ts +1 -1
  181. package/src/peer-record-updater.ts +1 -1
  182. package/src/peer-routing.ts +4 -4
  183. package/src/ping/index.ts +48 -15
  184. package/src/pnet/index.ts +3 -2
  185. package/src/pubsub/dummy-pubsub.ts +2 -2
  186. package/src/registrar.ts +79 -55
  187. package/src/transport-manager.ts +3 -3
  188. package/src/upgrader.ts +223 -93
  189. package/src/version.ts +1 -2
package/src/upgrader.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { logger } from '@libp2p/logger'
2
2
  import errCode from 'err-code'
3
- import { Dialer, Listener } from '@libp2p/multistream-select'
3
+ import * as mss from '@libp2p/multistream-select'
4
4
  import { pipe } from 'it-pipe'
5
5
  // @ts-expect-error mutable-proxy does not export types
6
6
  import mutableProxy from 'mutable-proxy'
@@ -8,14 +8,19 @@ import { codes } from './errors.js'
8
8
  import { createConnection } from '@libp2p/connection'
9
9
  import { CustomEvent, EventEmitter } from '@libp2p/interfaces/events'
10
10
  import { peerIdFromString } from '@libp2p/peer-id'
11
- import type { Connection, ProtocolStream, Stream } from '@libp2p/interfaces/connection'
12
- import type { ConnectionEncrypter, SecuredConnection } from '@libp2p/interfaces/connection-encrypter'
13
- import type { StreamMuxer, StreamMuxerFactory } from '@libp2p/interfaces/stream-muxer'
14
- import type { PeerId } from '@libp2p/interfaces/peer-id'
15
- import type { MultiaddrConnection, Upgrader, UpgraderEvents } from '@libp2p/interfaces/transport'
11
+ import type { MultiaddrConnection, Connection, Stream } from '@libp2p/interface-connection'
12
+ import type { ConnectionEncrypter, SecuredConnection } from '@libp2p/interface-connection-encrypter'
13
+ import type { StreamMuxer, StreamMuxerFactory } from '@libp2p/interface-stream-muxer'
14
+ import type { PeerId } from '@libp2p/interface-peer-id'
15
+ import type { Upgrader, UpgraderEvents } from '@libp2p/interface-transport'
16
16
  import type { Duplex } from 'it-stream-types'
17
- import type { Components } from '@libp2p/interfaces/components'
17
+ import { Components, isInitializable } from '@libp2p/components'
18
18
  import type { AbortOptions } from '@libp2p/interfaces'
19
+ import type { Registrar } from '@libp2p/interface-registrar'
20
+ import { DEFAULT_MAX_INBOUND_STREAMS, DEFAULT_MAX_OUTBOUND_STREAMS } from './registrar.js'
21
+ import { TimeoutController } from 'timeout-abort-controller'
22
+ import { abortableDuplex } from 'abortable-iterator'
23
+ import { setMaxListeners } from 'events'
19
24
 
20
25
  const log = logger('libp2p:upgrader')
21
26
 
@@ -41,12 +46,59 @@ export interface CryptoResult extends SecuredConnection {
41
46
  export interface UpgraderInit {
42
47
  connectionEncryption: ConnectionEncrypter[]
43
48
  muxers: StreamMuxerFactory[]
49
+
50
+ /**
51
+ * An amount of ms by which an inbound connection upgrade
52
+ * must complete
53
+ */
54
+ inboundUpgradeTimeout: number
55
+ }
56
+
57
+ function findIncomingStreamLimit (protocol: string, registrar: Registrar) {
58
+ try {
59
+ const { options } = registrar.getHandler(protocol)
60
+
61
+ return options.maxInboundStreams
62
+ } catch (err: any) {
63
+ if (err.code !== codes.ERR_NO_HANDLER_FOR_PROTOCOL) {
64
+ throw err
65
+ }
66
+ }
67
+
68
+ return DEFAULT_MAX_INBOUND_STREAMS
69
+ }
70
+
71
+ function findOutgoingStreamLimit (protocol: string, registrar: Registrar) {
72
+ try {
73
+ const { options } = registrar.getHandler(protocol)
74
+
75
+ return options.maxOutboundStreams
76
+ } catch (err: any) {
77
+ if (err.code !== codes.ERR_NO_HANDLER_FOR_PROTOCOL) {
78
+ throw err
79
+ }
80
+ }
81
+
82
+ return DEFAULT_MAX_OUTBOUND_STREAMS
83
+ }
84
+
85
+ function countStreams (protocol: string, direction: 'inbound' | 'outbound', connection: Connection) {
86
+ let streamCount = 0
87
+
88
+ connection.streams.forEach(stream => {
89
+ if (stream.stat.direction === direction && stream.stat.protocol === protocol) {
90
+ streamCount++
91
+ }
92
+ })
93
+
94
+ return streamCount
44
95
  }
45
96
 
46
97
  export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upgrader {
47
98
  private readonly components: Components
48
99
  private readonly connectionEncryption: Map<string, ConnectionEncrypter>
49
100
  private readonly muxers: Map<string, StreamMuxerFactory>
101
+ private readonly inboundUpgradeTimeout: number
50
102
 
51
103
  constructor (components: Components, init: UpgraderInit) {
52
104
  super()
@@ -63,6 +115,8 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
63
115
  init.muxers.forEach(muxer => {
64
116
  this.muxers.set(muxer.protocol, muxer)
65
117
  })
118
+
119
+ this.inboundUpgradeTimeout = init.inboundUpgradeTimeout
66
120
  }
67
121
 
68
122
  /**
@@ -78,82 +132,97 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
78
132
  let proxyPeer
79
133
  const metrics = this.components.getMetrics()
80
134
 
81
- if (await this.components.getConnectionGater().denyInboundConnection(maConn)) {
82
- throw errCode(new Error('The multiaddr connection is blocked by gater.acceptConnection'), codes.ERR_CONNECTION_INTERCEPTED)
83
- }
135
+ const timeoutController = new TimeoutController(this.inboundUpgradeTimeout)
84
136
 
85
- if (metrics != null) {
86
- ({ setTarget: setPeer, proxy: proxyPeer } = mutableProxy())
87
- const idString = `${(Math.random() * 1e9).toString(36)}${Date.now()}`
88
- setPeer({ toString: () => idString })
89
- maConn = metrics.trackStream({ stream: maConn, remotePeer: proxyPeer })
90
- }
137
+ try {
138
+ // fails on node < 15.4
139
+ setMaxListeners?.(Infinity, timeoutController.signal)
140
+ } catch {}
91
141
 
92
- log('starting the inbound connection upgrade')
142
+ try {
143
+ const abortableStream = abortableDuplex(maConn, timeoutController.signal)
144
+ maConn.source = abortableStream.source
145
+ maConn.sink = abortableStream.sink
93
146
 
94
- // Protect
95
- let protectedConn = maConn
96
- const protector = this.components.getConnectionProtector()
147
+ if (await this.components.getConnectionGater().denyInboundConnection(maConn)) {
148
+ throw errCode(new Error('The multiaddr connection is blocked by gater.acceptConnection'), codes.ERR_CONNECTION_INTERCEPTED)
149
+ }
97
150
 
98
- if (protector != null) {
99
- log('protecting the inbound connection')
100
- protectedConn = await protector.protect(maConn)
101
- }
151
+ if (metrics != null) {
152
+ ({ setTarget: setPeer, proxy: proxyPeer } = mutableProxy())
153
+ const idString = `${(Math.random() * 1e9).toString(36)}${Date.now()}`
154
+ setPeer({ toString: () => idString })
155
+ metrics.trackStream({ stream: maConn, remotePeer: proxyPeer })
156
+ }
102
157
 
103
- try {
104
- // Encrypt the connection
105
- ({
106
- conn: encryptedConn,
107
- remotePeer,
108
- protocol: cryptoProtocol
109
- } = await this._encryptInbound(protectedConn))
158
+ log('starting the inbound connection upgrade')
110
159
 
111
- if (await this.components.getConnectionGater().denyInboundEncryptedConnection(remotePeer, {
160
+ // Protect
161
+ let protectedConn = maConn
162
+ const protector = this.components.getConnectionProtector()
163
+
164
+ if (protector != null) {
165
+ log('protecting the inbound connection')
166
+ protectedConn = await protector.protect(maConn)
167
+ }
168
+
169
+ try {
170
+ // Encrypt the connection
171
+ ({
172
+ conn: encryptedConn,
173
+ remotePeer,
174
+ protocol: cryptoProtocol
175
+ } = await this._encryptInbound(protectedConn))
176
+
177
+ if (await this.components.getConnectionGater().denyInboundEncryptedConnection(remotePeer, {
178
+ ...protectedConn,
179
+ ...encryptedConn
180
+ })) {
181
+ throw errCode(new Error('The multiaddr connection is blocked by gater.acceptEncryptedConnection'), codes.ERR_CONNECTION_INTERCEPTED)
182
+ }
183
+
184
+ // Multiplex the connection
185
+ if (this.muxers.size > 0) {
186
+ const multiplexed = await this._multiplexInbound({
187
+ ...protectedConn,
188
+ ...encryptedConn
189
+ }, this.muxers)
190
+ muxerFactory = multiplexed.muxerFactory
191
+ upgradedConn = multiplexed.stream
192
+ } else {
193
+ upgradedConn = encryptedConn
194
+ }
195
+ } catch (err: any) {
196
+ log.error('Failed to upgrade inbound connection', err)
197
+ await maConn.close(err)
198
+ throw err
199
+ }
200
+
201
+ if (await this.components.getConnectionGater().denyInboundUpgradedConnection(remotePeer, {
112
202
  ...protectedConn,
113
203
  ...encryptedConn
114
204
  })) {
115
205
  throw errCode(new Error('The multiaddr connection is blocked by gater.acceptEncryptedConnection'), codes.ERR_CONNECTION_INTERCEPTED)
116
206
  }
117
207
 
118
- // Multiplex the connection
119
- if (this.muxers.size > 0) {
120
- const multiplexed = await this._multiplexInbound({
121
- ...protectedConn,
122
- ...encryptedConn
123
- }, this.muxers)
124
- muxerFactory = multiplexed.muxerFactory
125
- upgradedConn = multiplexed.stream
126
- } else {
127
- upgradedConn = encryptedConn
208
+ if (metrics != null) {
209
+ metrics.updatePlaceholder(proxyPeer, remotePeer)
210
+ setPeer(remotePeer)
128
211
  }
129
- } catch (err: any) {
130
- log.error('Failed to upgrade inbound connection', err)
131
- await maConn.close(err)
132
- throw err
133
- }
134
212
 
135
- if (await this.components.getConnectionGater().denyInboundUpgradedConnection(remotePeer, {
136
- ...protectedConn,
137
- ...encryptedConn
138
- })) {
139
- throw errCode(new Error('The multiaddr connection is blocked by gater.acceptEncryptedConnection'), codes.ERR_CONNECTION_INTERCEPTED)
140
- }
213
+ log('Successfully upgraded inbound connection')
141
214
 
142
- if (metrics != null) {
143
- metrics.updatePlaceholder(proxyPeer, remotePeer)
144
- setPeer(remotePeer)
215
+ return this._createConnection({
216
+ cryptoProtocol,
217
+ direction: 'inbound',
218
+ maConn,
219
+ upgradedConn,
220
+ muxerFactory,
221
+ remotePeer
222
+ })
223
+ } finally {
224
+ timeoutController.clear()
145
225
  }
146
-
147
- log('Successfully upgraded inbound connection')
148
-
149
- return this._createConnection({
150
- cryptoProtocol,
151
- direction: 'inbound',
152
- maConn,
153
- upgradedConn,
154
- muxerFactory,
155
- remotePeer
156
- })
157
226
  }
158
227
 
159
228
  /**
@@ -184,7 +253,7 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
184
253
  ({ setTarget: setPeer, proxy: proxyPeer } = mutableProxy())
185
254
  const idString = `${(Math.random() * 1e9).toString(36)}${Date.now()}`
186
255
  setPeer({ toB58String: () => idString })
187
- maConn = metrics.trackStream({ stream: maConn, remotePeer: proxyPeer })
256
+ metrics.trackStream({ stream: maConn, remotePeer: proxyPeer })
188
257
  }
189
258
 
190
259
  log('Starting the outbound connection upgrade')
@@ -267,12 +336,13 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
267
336
  } = opts
268
337
 
269
338
  let muxer: StreamMuxer | undefined
270
- let newStream: ((multicodecs: string[], options?: AbortOptions) => Promise<ProtocolStream>) | undefined
339
+ let newStream: ((multicodecs: string[], options?: AbortOptions) => Promise<Stream>) | undefined
271
340
  let connection: Connection // eslint-disable-line prefer-const
272
341
 
273
342
  if (muxerFactory != null) {
274
343
  // Create the muxer
275
- muxer = muxerFactory.createStreamMuxer(this.components, {
344
+ muxer = muxerFactory.createStreamMuxer({
345
+ direction,
276
346
  // Run anytime a remote stream is created
277
347
  onIncomingStream: muxedStream => {
278
348
  if (connection == null) {
@@ -281,9 +351,8 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
281
351
 
282
352
  void Promise.resolve()
283
353
  .then(async () => {
284
- const mss = new Listener(muxedStream)
285
354
  const protocols = this.components.getRegistrar().getProtocols()
286
- const { stream, protocol } = await mss.handle(protocols)
355
+ const { stream, protocol } = await mss.handle(muxedStream, protocols)
287
356
  log('%s: incoming stream opened on %s', direction, protocol)
288
357
 
289
358
  const metrics = this.components.getMetrics()
@@ -296,13 +365,28 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
296
365
  return
297
366
  }
298
367
 
299
- connection.addStream(muxedStream, { protocol })
368
+ const incomingLimit = findIncomingStreamLimit(protocol, this.components.getRegistrar())
369
+ const streamCount = countStreams(protocol, 'inbound', connection)
370
+
371
+ if (streamCount === incomingLimit) {
372
+ muxedStream.abort(errCode(new Error(`Too many inbound protocol streams for protocol "${protocol}" - limit ${incomingLimit}`), codes.ERR_TOO_MANY_INBOUND_PROTOCOL_STREAMS))
373
+
374
+ return
375
+ }
376
+
377
+ muxedStream.stat.protocol = protocol
378
+
379
+ // If a protocol stream has been successfully negotiated and is to be passed to the application,
380
+ // the peerstore should ensure that the peer is registered with that protocol
381
+ this.components.getPeerStore().protoBook.add(remotePeer, [protocol]).catch(err => log.error(err))
382
+
383
+ connection.addStream(muxedStream)
300
384
  this._onStream({ connection, stream: { ...muxedStream, ...stream }, protocol })
301
385
  })
302
386
  .catch(err => {
303
387
  log.error(err)
304
388
 
305
- if (muxedStream.timeline.close == null) {
389
+ if (muxedStream.stat.timeline.close == null) {
306
390
  muxedStream.close()
307
391
  }
308
392
  })
@@ -313,28 +397,67 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
313
397
  }
314
398
  })
315
399
 
316
- newStream = async (protocols: string[], options: AbortOptions = {}): Promise<ProtocolStream> => {
400
+ if (isInitializable(muxer)) {
401
+ muxer.init(this.components)
402
+ }
403
+
404
+ newStream = async (protocols: string[], options: AbortOptions = {}): Promise<Stream> => {
317
405
  if (muxer == null) {
318
406
  throw errCode(new Error('Stream is not multiplexed'), codes.ERR_MUXER_UNAVAILABLE)
319
407
  }
320
408
 
321
409
  log('%s: starting new stream on %s', direction, protocols)
322
410
  const muxedStream = muxer.newStream()
323
- const mss = new Dialer(muxedStream)
324
411
  const metrics = this.components.getMetrics()
412
+ let controller: TimeoutController | undefined
325
413
 
326
414
  try {
327
- let { stream, protocol } = await mss.select(protocols, options)
415
+ if (options.signal == null) {
416
+ log('No abort signal was passed while trying to negotiate protocols %s falling back to default timeout', protocols)
417
+
418
+ controller = new TimeoutController(30000)
419
+ options.signal = controller.signal
420
+
421
+ try {
422
+ // fails on node < 15.4
423
+ setMaxListeners?.(Infinity, controller.signal)
424
+ } catch {}
425
+ }
426
+
427
+ const { stream, protocol } = await mss.select(muxedStream, protocols, options)
328
428
 
329
429
  if (metrics != null) {
330
- stream = metrics.trackStream({ stream, remotePeer, protocol })
430
+ metrics.trackStream({ stream, remotePeer, protocol })
331
431
  }
332
432
 
333
- return { stream: { ...muxedStream, ...stream }, protocol }
433
+ const outgoingLimit = findOutgoingStreamLimit(protocol, this.components.getRegistrar())
434
+ const streamCount = countStreams(protocol, 'outbound', connection)
435
+
436
+ if (streamCount === outgoingLimit) {
437
+ const err = errCode(new Error(`Too many outbound protocol streams for protocol "${protocol}" - limit ${outgoingLimit}`), codes.ERR_TOO_MANY_OUTBOUND_PROTOCOL_STREAMS)
438
+ muxedStream.abort(err)
439
+
440
+ throw err
441
+ }
442
+
443
+ muxedStream.stat.protocol = protocol
444
+
445
+ // If a protocol stream has been successfully negotiated and is to be passed to the application,
446
+ // the peerstore should ensure that the peer is registered with that protocol
447
+ this.components.getPeerStore().protoBook.add(remotePeer, [protocol]).catch(err => log.error(err))
448
+
449
+ return {
450
+ ...muxedStream,
451
+ ...stream,
452
+ stat: {
453
+ ...muxedStream.stat,
454
+ protocol
455
+ }
456
+ }
334
457
  } catch (err: any) {
335
458
  log.error('could not create new stream', err)
336
459
 
337
- if (muxedStream.timeline.close == null) {
460
+ if (muxedStream.stat.timeline.close == null) {
338
461
  muxedStream.close()
339
462
  }
340
463
 
@@ -343,6 +466,10 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
343
466
  }
344
467
 
345
468
  throw errCode(err, codes.ERR_UNSUPPORTED_PROTOCOL)
469
+ } finally {
470
+ if (controller != null) {
471
+ controller.clear()
472
+ }
346
473
  }
347
474
  }
348
475
 
@@ -398,9 +525,7 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
398
525
  await maConn.close()
399
526
  // Ensure remaining streams are closed
400
527
  if (muxer != null) {
401
- await Promise.all(muxer.streams.map(async stream => {
402
- await stream.close()
403
- }))
528
+ muxer.close()
404
529
  }
405
530
  }
406
531
  })
@@ -417,20 +542,22 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
417
542
  */
418
543
  _onStream (opts: OnStreamOptions): void {
419
544
  const { connection, stream, protocol } = opts
420
- const handler = this.components.getRegistrar().getHandler(protocol)
421
- handler({ connection, stream, protocol })
545
+ const { handler } = this.components.getRegistrar().getHandler(protocol)
546
+
547
+ handler({ connection, stream })
422
548
  }
423
549
 
424
550
  /**
425
551
  * Attempts to encrypt the incoming `connection` with the provided `cryptos`
426
552
  */
427
553
  async _encryptInbound (connection: Duplex<Uint8Array>): Promise<CryptoResult> {
428
- const mss = new Listener(connection)
429
554
  const protocols = Array.from(this.connectionEncryption.keys())
430
555
  log('handling inbound crypto protocol selection', protocols)
431
556
 
432
557
  try {
433
- const { stream, protocol } = await mss.handle(protocols)
558
+ const { stream, protocol } = await mss.handle(connection, protocols, {
559
+ writeBytes: true
560
+ })
434
561
  const encrypter = this.connectionEncryption.get(protocol)
435
562
 
436
563
  if (encrypter == null) {
@@ -453,12 +580,13 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
453
580
  * The first `ConnectionEncrypter` module to succeed will be used
454
581
  */
455
582
  async _encryptOutbound (connection: MultiaddrConnection, remotePeerId: PeerId): Promise<CryptoResult> {
456
- const mss = new Dialer(connection)
457
583
  const protocols = Array.from(this.connectionEncryption.keys())
458
584
  log('selecting outbound crypto protocol', protocols)
459
585
 
460
586
  try {
461
- const { stream, protocol } = await mss.select(protocols)
587
+ const { stream, protocol } = await mss.select(connection, protocols, {
588
+ writeBytes: true
589
+ })
462
590
  const encrypter = this.connectionEncryption.get(protocol)
463
591
 
464
592
  if (encrypter == null) {
@@ -481,11 +609,12 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
481
609
  * muxer will be used for all future streams on the connection.
482
610
  */
483
611
  async _multiplexOutbound (connection: MultiaddrConnection, muxers: Map<string, StreamMuxerFactory>): Promise<{ stream: Duplex<Uint8Array>, muxerFactory?: StreamMuxerFactory}> {
484
- const dialer = new Dialer(connection)
485
612
  const protocols = Array.from(muxers.keys())
486
613
  log('outbound selecting muxer %s', protocols)
487
614
  try {
488
- const { stream, protocol } = await dialer.select(protocols)
615
+ const { stream, protocol } = await mss.select(connection, protocols, {
616
+ writeBytes: true
617
+ })
489
618
  log('%s selected as muxer protocol', protocol)
490
619
  const muxerFactory = muxers.get(protocol)
491
620
  return { stream, muxerFactory }
@@ -500,11 +629,12 @@ export class DefaultUpgrader extends EventEmitter<UpgraderEvents> implements Upg
500
629
  * selected muxer will be used for all future streams on the connection.
501
630
  */
502
631
  async _multiplexInbound (connection: MultiaddrConnection, muxers: Map<string, StreamMuxerFactory>): Promise<{ stream: Duplex<Uint8Array>, muxerFactory?: StreamMuxerFactory}> {
503
- const listener = new Listener(connection)
504
632
  const protocols = Array.from(muxers.keys())
505
633
  log('inbound handling muxers %s', protocols)
506
634
  try {
507
- const { stream, protocol } = await listener.handle(protocols)
635
+ const { stream, protocol } = await mss.handle(connection, protocols, {
636
+ writeBytes: true
637
+ })
508
638
  const muxerFactory = muxers.get(protocol)
509
639
  return { stream, muxerFactory }
510
640
  } catch (err: any) {
package/src/version.ts CHANGED
@@ -1,3 +1,2 @@
1
-
2
- export const version = '0.0.0'
1
+ export const version = '0.38.0'
3
2
  export const name = 'libp2p'