libp2p 2.1.3 → 2.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.min.js +10 -10
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +1 -3
- package/dist/src/config.js.map +1 -1
- package/dist/src/connection/index.d.ts.map +1 -1
- package/dist/src/connection/index.js +4 -6
- package/dist/src/connection/index.js.map +1 -1
- package/dist/src/connection-manager/address-sorter.d.ts +25 -0
- package/dist/src/connection-manager/address-sorter.d.ts.map +1 -0
- package/dist/src/connection-manager/address-sorter.js +112 -0
- package/dist/src/connection-manager/address-sorter.js.map +1 -0
- package/dist/src/connection-manager/connection-pruner.d.ts +4 -1
- package/dist/src/connection-manager/connection-pruner.d.ts.map +1 -1
- package/dist/src/connection-manager/connection-pruner.js +13 -7
- package/dist/src/connection-manager/connection-pruner.js.map +1 -1
- package/dist/src/connection-manager/dial-queue.d.ts +1 -1
- package/dist/src/connection-manager/dial-queue.d.ts.map +1 -1
- package/dist/src/connection-manager/dial-queue.js +4 -5
- package/dist/src/connection-manager/dial-queue.js.map +1 -1
- package/dist/src/connection-manager/index.d.ts +0 -1
- package/dist/src/connection-manager/index.d.ts.map +1 -1
- package/dist/src/connection-manager/index.js +30 -40
- package/dist/src/connection-manager/index.js.map +1 -1
- package/dist/src/upgrader.d.ts.map +1 -1
- package/dist/src/upgrader.js +23 -21
- package/dist/src/upgrader.js.map +1 -1
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/package.json +12 -12
- package/src/config.ts +1 -3
- package/src/connection/index.ts +5 -11
- package/src/connection-manager/address-sorter.ts +137 -0
- package/src/connection-manager/connection-pruner.ts +16 -8
- package/src/connection-manager/dial-queue.ts +5 -6
- package/src/connection-manager/index.ts +38 -40
- package/src/upgrader.ts +25 -16
- package/src/version.ts +1 -1
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { isPrivate } from '@libp2p/utils/multiaddr/is-private'
|
|
2
|
+
import { Circuit, WebSockets, WebSocketsSecure, WebRTC, WebRTCDirect, WebTransport, TCP } from '@multiformats/multiaddr-matcher'
|
|
3
|
+
import type { Address } from '@libp2p/interface'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Sorts addresses by order of reliability, where they have presented the fewest
|
|
7
|
+
* problems:
|
|
8
|
+
*
|
|
9
|
+
* TCP -> WebSockets/Secure -> WebRTC -> WebRTCDirect -> WebTransport
|
|
10
|
+
*/
|
|
11
|
+
// eslint-disable-next-line complexity
|
|
12
|
+
export function reliableTransportsFirst (a: Address, b: Address): -1 | 0 | 1 {
|
|
13
|
+
const isATCP = TCP.exactMatch(a.multiaddr)
|
|
14
|
+
const isBTCP = TCP.exactMatch(b.multiaddr)
|
|
15
|
+
|
|
16
|
+
if (isATCP && !isBTCP) {
|
|
17
|
+
return -1
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (!isATCP && isBTCP) {
|
|
21
|
+
return 1
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const isAWebSocketSecure = WebSocketsSecure.exactMatch(a.multiaddr)
|
|
25
|
+
const isBWebSocketSecure = WebSocketsSecure.exactMatch(b.multiaddr)
|
|
26
|
+
|
|
27
|
+
if (isAWebSocketSecure && !isBWebSocketSecure) {
|
|
28
|
+
return -1
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (!isAWebSocketSecure && isBWebSocketSecure) {
|
|
32
|
+
return 1
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const isAWebSocket = WebSockets.exactMatch(a.multiaddr)
|
|
36
|
+
const isBWebSocket = WebSockets.exactMatch(b.multiaddr)
|
|
37
|
+
|
|
38
|
+
if (isAWebSocket && !isBWebSocket) {
|
|
39
|
+
return -1
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (!isAWebSocket && isBWebSocket) {
|
|
43
|
+
return 1
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const isAWebRTC = WebRTC.exactMatch(a.multiaddr)
|
|
47
|
+
const isBWebRTC = WebRTC.exactMatch(b.multiaddr)
|
|
48
|
+
|
|
49
|
+
if (isAWebRTC && !isBWebRTC) {
|
|
50
|
+
return -1
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (!isAWebRTC && isBWebRTC) {
|
|
54
|
+
return 1
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const isAWebRTCDirect = WebRTCDirect.exactMatch(a.multiaddr)
|
|
58
|
+
const isBWebRTCDirect = WebRTCDirect.exactMatch(b.multiaddr)
|
|
59
|
+
|
|
60
|
+
if (isAWebRTCDirect && !isBWebRTCDirect) {
|
|
61
|
+
return -1
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (!isAWebRTCDirect && isBWebRTCDirect) {
|
|
65
|
+
return 1
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const isAWebTransport = WebTransport.exactMatch(a.multiaddr)
|
|
69
|
+
const isBWebTransport = WebTransport.exactMatch(b.multiaddr)
|
|
70
|
+
|
|
71
|
+
if (isAWebTransport && !isBWebTransport) {
|
|
72
|
+
return -1
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (!isAWebTransport && isBWebTransport) {
|
|
76
|
+
return 1
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// ... everything else
|
|
80
|
+
return 0
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Compare function for array.sort() that moves public addresses to the start
|
|
85
|
+
* of the array.
|
|
86
|
+
*/
|
|
87
|
+
export function publicAddressesFirst (a: Address, b: Address): -1 | 0 | 1 {
|
|
88
|
+
const isAPrivate = isPrivate(a.multiaddr)
|
|
89
|
+
const isBPrivate = isPrivate(b.multiaddr)
|
|
90
|
+
|
|
91
|
+
if (isAPrivate && !isBPrivate) {
|
|
92
|
+
return 1
|
|
93
|
+
} else if (!isAPrivate && isBPrivate) {
|
|
94
|
+
return -1
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return 0
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Compare function for array.sort() that moves certified addresses to the start
|
|
102
|
+
* of the array.
|
|
103
|
+
*/
|
|
104
|
+
export function certifiedAddressesFirst (a: Address, b: Address): -1 | 0 | 1 {
|
|
105
|
+
if (a.isCertified && !b.isCertified) {
|
|
106
|
+
return -1
|
|
107
|
+
} else if (!a.isCertified && b.isCertified) {
|
|
108
|
+
return 1
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return 0
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Compare function for array.sort() that moves circuit relay addresses to the
|
|
116
|
+
* end of the array.
|
|
117
|
+
*/
|
|
118
|
+
export function circuitRelayAddressesLast (a: Address, b: Address): -1 | 0 | 1 {
|
|
119
|
+
const isACircuit = Circuit.exactMatch(a.multiaddr)
|
|
120
|
+
const isBCircuit = Circuit.exactMatch(b.multiaddr)
|
|
121
|
+
|
|
122
|
+
if (isACircuit && !isBCircuit) {
|
|
123
|
+
return 1
|
|
124
|
+
} else if (!isACircuit && isBCircuit) {
|
|
125
|
+
return -1
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return 0
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export function defaultAddressSorter (addresses: Address[]): Address[] {
|
|
132
|
+
return addresses
|
|
133
|
+
.sort(reliableTransportsFirst)
|
|
134
|
+
.sort(certifiedAddressesFirst)
|
|
135
|
+
.sort(circuitRelayAddressesLast)
|
|
136
|
+
.sort(publicAddressesFirst)
|
|
137
|
+
}
|
|
@@ -40,21 +40,29 @@ export class ConnectionPruner {
|
|
|
40
40
|
this.peerStore = components.peerStore
|
|
41
41
|
this.events = components.events
|
|
42
42
|
this.log = components.logger.forComponent('libp2p:connection-manager:connection-pruner')
|
|
43
|
+
this.maybePruneConnections = this.maybePruneConnections.bind(this)
|
|
44
|
+
}
|
|
43
45
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
start (): void {
|
|
47
|
+
this.events.addEventListener('connection:open', this.maybePruneConnections)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
stop (): void {
|
|
51
|
+
this.events.removeEventListener('connection:open', this.maybePruneConnections)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
maybePruneConnections (): void {
|
|
55
|
+
this._maybePruneConnections()
|
|
56
|
+
.catch(err => {
|
|
57
|
+
this.log.error('error while pruning connections %e', err)
|
|
58
|
+
})
|
|
51
59
|
}
|
|
52
60
|
|
|
53
61
|
/**
|
|
54
62
|
* If we have more connections than our maximum, select some excess connections
|
|
55
63
|
* to prune based on peer value
|
|
56
64
|
*/
|
|
57
|
-
async
|
|
65
|
+
private async _maybePruneConnections (): Promise<void> {
|
|
58
66
|
const connections = this.connectionManager.getConnections()
|
|
59
67
|
const numConnections = connections.length
|
|
60
68
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/* eslint-disable max-depth */
|
|
2
2
|
import { TimeoutError, DialError, setMaxListeners, AbortError } from '@libp2p/interface'
|
|
3
3
|
import { PeerMap } from '@libp2p/peer-collections'
|
|
4
|
-
import { defaultAddressSort } from '@libp2p/utils/address-sort'
|
|
5
4
|
import { PriorityQueue, type PriorityQueueJobOptions } from '@libp2p/utils/priority-queue'
|
|
6
5
|
import { type Multiaddr, type Resolver, resolvers, multiaddr } from '@multiformats/multiaddr'
|
|
7
6
|
import { dnsaddrResolver } from '@multiformats/multiaddr/resolvers'
|
|
@@ -11,6 +10,7 @@ import { CustomProgressEvent } from 'progress-events'
|
|
|
11
10
|
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
|
|
12
11
|
import { DialDeniedError, NoValidAddressesError } from '../errors.js'
|
|
13
12
|
import { getPeerAddress } from '../get-peer.js'
|
|
13
|
+
import { defaultAddressSorter } from './address-sorter.js'
|
|
14
14
|
import {
|
|
15
15
|
DIAL_TIMEOUT,
|
|
16
16
|
MAX_PARALLEL_DIALS,
|
|
@@ -47,7 +47,6 @@ interface DialerInit {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
const defaultOptions = {
|
|
50
|
-
addressSorter: defaultAddressSort,
|
|
51
50
|
maxParallelDials: MAX_PARALLEL_DIALS,
|
|
52
51
|
maxDialQueueLength: MAX_DIAL_QUEUE_LENGTH,
|
|
53
52
|
maxPeerAddrsToDial: MAX_PEER_ADDRS_TO_DIAL,
|
|
@@ -71,7 +70,7 @@ interface DialQueueComponents {
|
|
|
71
70
|
export class DialQueue {
|
|
72
71
|
public queue: PriorityQueue<Connection, DialQueueJobOptions>
|
|
73
72
|
private readonly components: DialQueueComponents
|
|
74
|
-
private readonly addressSorter
|
|
73
|
+
private readonly addressSorter?: AddressSorter
|
|
75
74
|
private readonly maxPeerAddrsToDial: number
|
|
76
75
|
private readonly maxDialQueueLength: number
|
|
77
76
|
private readonly dialTimeout: number
|
|
@@ -80,7 +79,7 @@ export class DialQueue {
|
|
|
80
79
|
private readonly log: Logger
|
|
81
80
|
|
|
82
81
|
constructor (components: DialQueueComponents, init: DialerInit = {}) {
|
|
83
|
-
this.addressSorter = init.addressSorter
|
|
82
|
+
this.addressSorter = init.addressSorter
|
|
84
83
|
this.maxPeerAddrsToDial = init.maxPeerAddrsToDial ?? defaultOptions.maxPeerAddrsToDial
|
|
85
84
|
this.maxDialQueueLength = init.maxDialQueueLength ?? defaultOptions.maxDialQueueLength
|
|
86
85
|
this.dialTimeout = init.dialTimeout ?? defaultOptions.dialTimeout
|
|
@@ -153,7 +152,7 @@ export class DialQueue {
|
|
|
153
152
|
})
|
|
154
153
|
})
|
|
155
154
|
|
|
156
|
-
if (existingConnection
|
|
155
|
+
if (existingConnection?.status === 'open') {
|
|
157
156
|
this.log('already connected to %a', existingConnection.remoteAddr)
|
|
158
157
|
options.onProgress?.(new CustomProgressEvent('dial-queue:already-connected'))
|
|
159
158
|
return existingConnection
|
|
@@ -467,7 +466,7 @@ export class DialQueue {
|
|
|
467
466
|
gatedAdrs.push(addr)
|
|
468
467
|
}
|
|
469
468
|
|
|
470
|
-
const sortedGatedAddrs = gatedAdrs.sort(this.addressSorter)
|
|
469
|
+
const sortedGatedAddrs = this.addressSorter == null ? defaultAddressSorter(gatedAdrs) : gatedAdrs.sort(this.addressSorter)
|
|
471
470
|
|
|
472
471
|
// make sure we actually have some addresses to dial
|
|
473
472
|
if (sortedGatedAddrs.length === 0) {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { InvalidMultiaddrError, InvalidParametersError, InvalidPeerIdError, NotStartedError, start, stop } from '@libp2p/interface'
|
|
1
|
+
import { ConnectionClosedError, InvalidMultiaddrError, InvalidParametersError, InvalidPeerIdError, NotStartedError, start, stop } from '@libp2p/interface'
|
|
2
2
|
import { PeerMap } from '@libp2p/peer-collections'
|
|
3
|
-
import { defaultAddressSort } from '@libp2p/utils/address-sort'
|
|
4
3
|
import { RateLimiter } from '@libp2p/utils/rate-limiter'
|
|
5
4
|
import { type Multiaddr, type Resolver, multiaddr } from '@multiformats/multiaddr'
|
|
6
5
|
import { dnsaddrResolver } from '@multiformats/multiaddr/resolvers'
|
|
@@ -214,8 +213,6 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
|
|
|
214
213
|
|
|
215
214
|
this.onConnect = this.onConnect.bind(this)
|
|
216
215
|
this.onDisconnect = this.onDisconnect.bind(this)
|
|
217
|
-
this.events.addEventListener('connection:open', this.onConnect)
|
|
218
|
-
this.events.addEventListener('connection:close', this.onDisconnect)
|
|
219
216
|
|
|
220
217
|
// allow/deny lists
|
|
221
218
|
this.allow = (init.allow ?? []).map(ma => multiaddr(ma))
|
|
@@ -242,7 +239,7 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
|
|
|
242
239
|
})
|
|
243
240
|
|
|
244
241
|
this.dialQueue = new DialQueue(components, {
|
|
245
|
-
addressSorter: init.addressSorter
|
|
242
|
+
addressSorter: init.addressSorter,
|
|
246
243
|
maxParallelDials: init.maxParallelDials ?? MAX_PARALLEL_DIALS,
|
|
247
244
|
maxDialQueueLength: init.maxDialQueueLength ?? MAX_DIAL_QUEUE_LENGTH,
|
|
248
245
|
maxPeerAddrsToDial: init.maxPeerAddrsToDial ?? MAX_PEER_ADDRS_TO_DIAL,
|
|
@@ -268,10 +265,6 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
|
|
|
268
265
|
|
|
269
266
|
readonly [Symbol.toStringTag] = '@libp2p/connection-manager'
|
|
270
267
|
|
|
271
|
-
isStarted (): boolean {
|
|
272
|
-
return this.started
|
|
273
|
-
}
|
|
274
|
-
|
|
275
268
|
/**
|
|
276
269
|
* Starts the Connection Manager. If Metrics are not enabled on libp2p
|
|
277
270
|
* only event loop and connection limits will be monitored.
|
|
@@ -288,11 +281,7 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
|
|
|
288
281
|
|
|
289
282
|
for (const conns of this.connections.values()) {
|
|
290
283
|
for (const conn of conns) {
|
|
291
|
-
|
|
292
|
-
metric.inbound++
|
|
293
|
-
} else {
|
|
294
|
-
metric.outbound++
|
|
295
|
-
}
|
|
284
|
+
metric[conn.direction]++
|
|
296
285
|
}
|
|
297
286
|
}
|
|
298
287
|
|
|
@@ -356,9 +345,13 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
|
|
|
356
345
|
}
|
|
357
346
|
})
|
|
358
347
|
|
|
348
|
+
this.events.addEventListener('connection:open', this.onConnect)
|
|
349
|
+
this.events.addEventListener('connection:close', this.onDisconnect)
|
|
350
|
+
|
|
359
351
|
await start(
|
|
360
352
|
this.dialQueue,
|
|
361
|
-
this.reconnectQueue
|
|
353
|
+
this.reconnectQueue,
|
|
354
|
+
this.connectionPruner
|
|
362
355
|
)
|
|
363
356
|
|
|
364
357
|
this.started = true
|
|
@@ -369,9 +362,13 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
|
|
|
369
362
|
* Stops the Connection Manager
|
|
370
363
|
*/
|
|
371
364
|
async stop (): Promise<void> {
|
|
365
|
+
this.events.removeEventListener('connection:open', this.onConnect)
|
|
366
|
+
this.events.removeEventListener('connection:close', this.onDisconnect)
|
|
367
|
+
|
|
372
368
|
await stop(
|
|
373
369
|
this.reconnectQueue,
|
|
374
|
-
this.dialQueue
|
|
370
|
+
this.dialQueue,
|
|
371
|
+
this.connectionPruner
|
|
375
372
|
)
|
|
376
373
|
|
|
377
374
|
// Close all connections we're tracking
|
|
@@ -413,17 +410,19 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
|
|
|
413
410
|
return
|
|
414
411
|
}
|
|
415
412
|
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
if (storedConns != null) {
|
|
421
|
-
storedConns.push(connection)
|
|
422
|
-
} else {
|
|
423
|
-
isNewPeer = true
|
|
424
|
-
this.connections.set(peerId, [connection])
|
|
413
|
+
if (connection.status !== 'open') {
|
|
414
|
+
// this can happen when the remote closes the connection immediately after
|
|
415
|
+
// opening
|
|
416
|
+
return
|
|
425
417
|
}
|
|
426
418
|
|
|
419
|
+
const peerId = connection.remotePeer
|
|
420
|
+
const isNewPeer = !this.connections.has(peerId)
|
|
421
|
+
const storedConns = this.connections.get(peerId) ?? []
|
|
422
|
+
storedConns.push(connection)
|
|
423
|
+
|
|
424
|
+
this.connections.set(peerId, storedConns)
|
|
425
|
+
|
|
427
426
|
// only need to store RSA public keys, all other types are embedded in the peer id
|
|
428
427
|
if (peerId.publicKey != null && peerId.type === 'RSA') {
|
|
429
428
|
await this.peerStore.patch(peerId, {
|
|
@@ -441,20 +440,21 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
|
|
|
441
440
|
*/
|
|
442
441
|
onDisconnect (evt: CustomEvent<Connection>): void {
|
|
443
442
|
const { detail: connection } = evt
|
|
443
|
+
const peerId = connection.remotePeer
|
|
444
|
+
const peerConns = this.connections.get(peerId) ?? []
|
|
444
445
|
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
return
|
|
448
|
-
}
|
|
446
|
+
// remove closed connection
|
|
447
|
+
const filteredPeerConns = peerConns.filter(conn => conn.id !== connection.id)
|
|
449
448
|
|
|
450
|
-
|
|
451
|
-
|
|
449
|
+
// update peer connections
|
|
450
|
+
this.connections.set(peerId, filteredPeerConns)
|
|
452
451
|
|
|
453
|
-
if (
|
|
454
|
-
|
|
455
|
-
this.connections
|
|
456
|
-
} else if (storedConn != null) {
|
|
452
|
+
if (filteredPeerConns.length === 0) {
|
|
453
|
+
// trigger disconnect event if no connections remain
|
|
454
|
+
this.log('onDisconnect remove all connections for peer %p', peerId)
|
|
457
455
|
this.connections.delete(peerId)
|
|
456
|
+
|
|
457
|
+
// broadcast disconnect event
|
|
458
458
|
this.events.safeDispatchEvent('peer:disconnect', { detail: connection.remotePeer })
|
|
459
459
|
}
|
|
460
460
|
}
|
|
@@ -478,7 +478,7 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
|
|
|
478
478
|
}
|
|
479
479
|
|
|
480
480
|
async openConnection (peerIdOrMultiaddr: PeerId | Multiaddr | Multiaddr[], options: OpenConnectionOptions = {}): Promise<Connection> {
|
|
481
|
-
if (!this.
|
|
481
|
+
if (!this.started) {
|
|
482
482
|
throw new NotStartedError('Not started')
|
|
483
483
|
}
|
|
484
484
|
|
|
@@ -508,10 +508,8 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
|
|
|
508
508
|
priority: options.priority ?? DEFAULT_DIAL_PRIORITY
|
|
509
509
|
})
|
|
510
510
|
|
|
511
|
-
if (connection.
|
|
512
|
-
|
|
513
|
-
connection.abort(err)
|
|
514
|
-
throw err
|
|
511
|
+
if (connection.status !== 'open') {
|
|
512
|
+
throw new ConnectionClosedError('Remote closed connection during opening')
|
|
515
513
|
}
|
|
516
514
|
|
|
517
515
|
let peerConnections = this.connections.get(connection.remotePeer)
|
package/src/upgrader.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { InvalidMultiaddrError, TooManyInboundProtocolStreamsError, TooManyOutboundProtocolStreamsError, LimitedConnectionError, setMaxListeners } from '@libp2p/interface'
|
|
1
|
+
import { InvalidMultiaddrError, TooManyInboundProtocolStreamsError, TooManyOutboundProtocolStreamsError, LimitedConnectionError, setMaxListeners, InvalidPeerIdError } from '@libp2p/interface'
|
|
2
2
|
import * as mss from '@libp2p/multistream-select'
|
|
3
3
|
import { peerIdFromString } from '@libp2p/peer-id'
|
|
4
4
|
import { anySignal } from 'any-signal'
|
|
@@ -304,6 +304,14 @@ export class DefaultUpgrader implements Upgrader {
|
|
|
304
304
|
remotePeer = remotePeerId
|
|
305
305
|
}
|
|
306
306
|
|
|
307
|
+
// this can happen if we dial a multiaddr without a peer id, we only find
|
|
308
|
+
// out the identity of the remote after the connection is encrypted
|
|
309
|
+
if (remotePeer.equals(this.components.peerId)) {
|
|
310
|
+
const err = new InvalidPeerIdError('Can not dial self')
|
|
311
|
+
maConn.abort(err)
|
|
312
|
+
throw err
|
|
313
|
+
}
|
|
314
|
+
|
|
307
315
|
upgradedConn = encryptedConn
|
|
308
316
|
if (opts?.muxerFactory != null) {
|
|
309
317
|
muxerFactory = opts.muxerFactory
|
|
@@ -326,6 +334,8 @@ export class DefaultUpgrader implements Upgrader {
|
|
|
326
334
|
} catch (err: any) {
|
|
327
335
|
maConn.log.error('failed to upgrade inbound connection %s %a - %e', direction === 'inbound' ? 'from' : 'to', maConn.remoteAddr, err)
|
|
328
336
|
throw err
|
|
337
|
+
} finally {
|
|
338
|
+
signal.clear()
|
|
329
339
|
}
|
|
330
340
|
|
|
331
341
|
await this.shouldBlockConnection(direction === 'inbound' ? 'denyInboundUpgradedConnection' : 'denyOutboundUpgradedConnection', remotePeer, maConn)
|
|
@@ -538,7 +548,7 @@ export class DefaultUpgrader implements Upgrader {
|
|
|
538
548
|
const _timeline = maConn.timeline
|
|
539
549
|
maConn.timeline = new Proxy(_timeline, {
|
|
540
550
|
set: (...args) => {
|
|
541
|
-
if (
|
|
551
|
+
if (args[1] === 'close' && args[2] != null && _timeline.close == null) {
|
|
542
552
|
// Wait for close to finish before notifying of the closure
|
|
543
553
|
(async () => {
|
|
544
554
|
try {
|
|
@@ -546,14 +556,14 @@ export class DefaultUpgrader implements Upgrader {
|
|
|
546
556
|
await connection.close()
|
|
547
557
|
}
|
|
548
558
|
} catch (err: any) {
|
|
549
|
-
connection.log.error('error closing connection after timeline close', err)
|
|
559
|
+
connection.log.error('error closing connection after timeline close %e', err)
|
|
550
560
|
} finally {
|
|
551
561
|
this.events.safeDispatchEvent('connection:close', {
|
|
552
562
|
detail: connection
|
|
553
563
|
})
|
|
554
564
|
}
|
|
555
565
|
})().catch(err => {
|
|
556
|
-
connection.log.error('error thrown while dispatching connection:close event', err)
|
|
566
|
+
connection.log.error('error thrown while dispatching connection:close event %e', err)
|
|
557
567
|
})
|
|
558
568
|
}
|
|
559
569
|
|
|
@@ -578,25 +588,21 @@ export class DefaultUpgrader implements Upgrader {
|
|
|
578
588
|
limits,
|
|
579
589
|
logger: this.components.logger,
|
|
580
590
|
newStream: newStream ?? errConnectionNotMultiplexed,
|
|
581
|
-
getStreams: () => {
|
|
591
|
+
getStreams: () => {
|
|
592
|
+
return muxer?.streams ?? []
|
|
593
|
+
},
|
|
582
594
|
close: async (options?: AbortOptions) => {
|
|
583
|
-
//
|
|
584
|
-
|
|
585
|
-
connection.log.trace('close muxer')
|
|
586
|
-
await muxer.close(options)
|
|
587
|
-
}
|
|
595
|
+
// ensure remaining streams are closed gracefully
|
|
596
|
+
await muxer?.close(options)
|
|
588
597
|
|
|
589
|
-
connection.log.trace('close maconn')
|
|
590
598
|
// close the underlying transport
|
|
591
599
|
await maConn.close(options)
|
|
592
|
-
connection.log.trace('closed maconn')
|
|
593
600
|
},
|
|
594
601
|
abort: (err) => {
|
|
595
602
|
maConn.abort(err)
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
}
|
|
603
|
+
|
|
604
|
+
// ensure remaining streams are aborted
|
|
605
|
+
muxer?.abort(err)
|
|
600
606
|
}
|
|
601
607
|
})
|
|
602
608
|
|
|
@@ -604,6 +610,9 @@ export class DefaultUpgrader implements Upgrader {
|
|
|
604
610
|
detail: connection
|
|
605
611
|
})
|
|
606
612
|
|
|
613
|
+
// @ts-expect-error nah
|
|
614
|
+
connection.__maConnTimeline = _timeline
|
|
615
|
+
|
|
607
616
|
return connection
|
|
608
617
|
}
|
|
609
618
|
|
package/src/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const version = '2.1.
|
|
1
|
+
export const version = '2.1.4'
|
|
2
2
|
export const name = 'libp2p'
|