libp2p 0.44.0-e3deaa40 → 0.44.0-ef7a5f67
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 +17 -17
- package/dist/src/address-manager/index.d.ts +4 -0
- package/dist/src/address-manager/index.d.ts.map +1 -1
- package/dist/src/address-manager/index.js +32 -4
- package/dist/src/address-manager/index.js.map +1 -1
- package/dist/src/address-manager/utils.d.ts +2 -0
- package/dist/src/address-manager/utils.d.ts.map +1 -0
- package/dist/src/address-manager/utils.js +12 -0
- package/dist/src/address-manager/utils.js.map +1 -0
- package/dist/src/autonat/constants.d.ts +16 -2
- package/dist/src/autonat/constants.d.ts.map +1 -1
- package/dist/src/autonat/constants.js +16 -2
- package/dist/src/autonat/constants.js.map +1 -1
- package/dist/src/autonat/index.d.ts +9 -30
- package/dist/src/autonat/index.d.ts.map +1 -1
- package/dist/src/autonat/index.js +22 -18
- package/dist/src/autonat/index.js.map +1 -1
- package/dist/src/circuit-relay/server/index.d.ts.map +1 -1
- package/dist/src/circuit-relay/server/index.js +3 -0
- package/dist/src/circuit-relay/server/index.js.map +1 -1
- package/dist/src/circuit-relay/transport/discovery.js +2 -2
- package/dist/src/circuit-relay/transport/discovery.js.map +1 -1
- package/dist/src/circuit-relay/transport/index.d.ts.map +1 -1
- package/dist/src/circuit-relay/transport/index.js +4 -6
- package/dist/src/circuit-relay/transport/index.js.map +1 -1
- package/dist/src/circuit-relay/transport/listener.d.ts +0 -3
- package/dist/src/circuit-relay/transport/listener.d.ts.map +1 -1
- package/dist/src/circuit-relay/transport/listener.js +27 -24
- package/dist/src/circuit-relay/transport/listener.js.map +1 -1
- package/dist/src/circuit-relay/transport/reservation-store.d.ts +2 -4
- package/dist/src/circuit-relay/transport/reservation-store.d.ts.map +1 -1
- package/dist/src/circuit-relay/transport/reservation-store.js +28 -26
- package/dist/src/circuit-relay/transport/reservation-store.js.map +1 -1
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +0 -55
- package/dist/src/config.js.map +1 -1
- package/dist/src/connection-manager/dial-queue.d.ts.map +1 -1
- package/dist/src/connection-manager/dial-queue.js +11 -0
- package/dist/src/connection-manager/dial-queue.js.map +1 -1
- package/dist/src/identify/identify.d.ts +53 -0
- package/dist/src/identify/identify.d.ts.map +1 -0
- package/dist/src/identify/identify.js +405 -0
- package/dist/src/identify/identify.js.map +1 -0
- package/dist/src/identify/index.d.ts +1 -15
- package/dist/src/identify/index.d.ts.map +1 -1
- package/dist/src/identify/index.js +2 -387
- package/dist/src/identify/index.js.map +1 -1
- package/dist/src/index.d.ts +2 -6
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/libp2p.d.ts.map +1 -1
- package/dist/src/libp2p.js +0 -1
- package/dist/src/libp2p.js.map +1 -1
- package/dist/src/peer-routing.d.ts +1 -38
- package/dist/src/peer-routing.d.ts.map +1 -1
- package/dist/src/peer-routing.js +0 -60
- package/dist/src/peer-routing.js.map +1 -1
- package/dist/src/transport-manager.d.ts +5 -5
- package/dist/src/transport-manager.d.ts.map +1 -1
- package/dist/src/transport-manager.js +14 -21
- package/dist/src/transport-manager.js.map +1 -1
- package/dist/src/upgrader.d.ts.map +1 -1
- package/dist/src/upgrader.js +3 -2
- package/dist/src/upgrader.js.map +1 -1
- package/dist/src/upnp-nat/index.d.ts +2 -2
- package/dist/src/upnp-nat/index.d.ts.map +1 -1
- package/dist/src/upnp-nat/index.js +1 -1
- package/dist/src/upnp-nat/index.js.map +1 -1
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.d.ts.map +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/version.js.map +1 -1
- package/package.json +5 -5
- package/src/address-manager/index.ts +42 -4
- package/src/address-manager/utils.ts +14 -0
- package/src/autonat/constants.ts +17 -2
- package/src/autonat/index.ts +37 -30
- package/src/circuit-relay/server/index.ts +4 -0
- package/src/circuit-relay/transport/discovery.ts +2 -2
- package/src/circuit-relay/transport/index.ts +4 -7
- package/src/circuit-relay/transport/listener.ts +35 -29
- package/src/circuit-relay/transport/reservation-store.ts +21 -15
- package/src/config.ts +0 -55
- package/src/connection-manager/dial-queue.ts +11 -0
- package/src/identify/identify.ts +518 -0
- package/src/identify/index.ts +5 -505
- package/src/index.ts +2 -7
- package/src/libp2p.ts +0 -1
- package/src/peer-routing.ts +1 -103
- package/src/transport-manager.ts +17 -25
- package/src/upgrader.ts +3 -3
- package/src/upnp-nat/index.ts +2 -2
- package/src/version.ts +1 -1
package/src/autonat/index.ts
CHANGED
|
@@ -20,7 +20,9 @@ import parallel from 'it-parallel'
|
|
|
20
20
|
import { pipe } from 'it-pipe'
|
|
21
21
|
import isPrivateIp from 'private-ip'
|
|
22
22
|
import {
|
|
23
|
-
|
|
23
|
+
MAX_INBOUND_STREAMS,
|
|
24
|
+
MAX_OUTBOUND_STREAMS,
|
|
25
|
+
PROTOCOL_NAME, PROTOCOL_PREFIX, PROTOCOL_VERSION, REFRESH_INTERVAL, STARTUP_DELAY, TIMEOUT
|
|
24
26
|
} from './constants.js'
|
|
25
27
|
import { Message } from './pb/index.js'
|
|
26
28
|
import { anySignal } from 'any-signal'
|
|
@@ -32,45 +34,39 @@ const log = logger('libp2p:autonat')
|
|
|
32
34
|
// https://github.com/libp2p/specs/blob/master/autonat/README.md#autonat-protocol
|
|
33
35
|
const REQUIRED_SUCCESSFUL_DIALS = 4
|
|
34
36
|
|
|
35
|
-
// Wait this long before we start to query autonat nodes
|
|
36
|
-
const AUTONAT_STARTUP_DELAY = 5000
|
|
37
|
-
|
|
38
|
-
// Only try to verify our external address this often
|
|
39
|
-
const AUTONAT_REFRESH_INTERVAL = 60000
|
|
40
|
-
|
|
41
37
|
export interface AutonatServiceInit {
|
|
42
38
|
/**
|
|
43
39
|
* Allows overriding the protocol prefix used
|
|
44
40
|
*/
|
|
45
|
-
protocolPrefix
|
|
41
|
+
protocolPrefix?: string
|
|
46
42
|
|
|
47
43
|
/**
|
|
48
44
|
* How long we should wait for a remote peer to verify our external address
|
|
49
45
|
*/
|
|
50
|
-
timeout
|
|
46
|
+
timeout?: number
|
|
51
47
|
|
|
52
48
|
/**
|
|
53
49
|
* How long to wait after startup before trying to verify our external address
|
|
54
50
|
*/
|
|
55
|
-
startupDelay
|
|
51
|
+
startupDelay?: number
|
|
56
52
|
|
|
57
53
|
/**
|
|
58
54
|
* Verify our external addresses this often
|
|
59
55
|
*/
|
|
60
|
-
refreshInterval
|
|
56
|
+
refreshInterval?: number
|
|
61
57
|
|
|
62
58
|
/**
|
|
63
59
|
* How many parallel inbound autonat streams we allow per-connection
|
|
64
60
|
*/
|
|
65
|
-
maxInboundStreams
|
|
61
|
+
maxInboundStreams?: number
|
|
66
62
|
|
|
67
63
|
/**
|
|
68
64
|
* How many parallel outbound autonat streams we allow per-connection
|
|
69
65
|
*/
|
|
70
|
-
maxOutboundStreams
|
|
66
|
+
maxOutboundStreams?: number
|
|
71
67
|
}
|
|
72
68
|
|
|
73
|
-
export interface
|
|
69
|
+
export interface AutonatComponents {
|
|
74
70
|
registrar: Registrar
|
|
75
71
|
addressManager: AddressManager
|
|
76
72
|
transportManager: TransportManager
|
|
@@ -79,21 +75,26 @@ export interface DefaultAutonatComponents {
|
|
|
79
75
|
peerRouting: PeerRouting
|
|
80
76
|
}
|
|
81
77
|
|
|
82
|
-
|
|
83
|
-
private readonly components:
|
|
84
|
-
private readonly _init: AutonatServiceInit
|
|
78
|
+
class DefaultAutonatService implements Startable {
|
|
79
|
+
private readonly components: AutonatComponents
|
|
85
80
|
private readonly startupDelay: number
|
|
86
81
|
private readonly refreshInterval: number
|
|
82
|
+
private readonly protocol: string
|
|
83
|
+
private readonly timeout: number
|
|
84
|
+
private readonly maxInboundStreams: number
|
|
85
|
+
private readonly maxOutboundStreams: number
|
|
87
86
|
private verifyAddressTimeout?: ReturnType<typeof setTimeout>
|
|
88
87
|
private started: boolean
|
|
89
88
|
|
|
90
|
-
constructor (components:
|
|
89
|
+
constructor (components: AutonatComponents, init: AutonatServiceInit) {
|
|
91
90
|
this.components = components
|
|
92
91
|
this.started = false
|
|
93
|
-
this.
|
|
94
|
-
this.
|
|
95
|
-
this.
|
|
96
|
-
|
|
92
|
+
this.protocol = `/${init.protocolPrefix ?? PROTOCOL_PREFIX}/${PROTOCOL_NAME}/${PROTOCOL_VERSION}`
|
|
93
|
+
this.timeout = init.timeout ?? TIMEOUT
|
|
94
|
+
this.maxInboundStreams = init.maxInboundStreams ?? MAX_INBOUND_STREAMS
|
|
95
|
+
this.maxOutboundStreams = init.maxOutboundStreams ?? MAX_OUTBOUND_STREAMS
|
|
96
|
+
this.startupDelay = init.startupDelay ?? STARTUP_DELAY
|
|
97
|
+
this.refreshInterval = init.refreshInterval ?? REFRESH_INTERVAL
|
|
97
98
|
this._verifyExternalAddresses = this._verifyExternalAddresses.bind(this)
|
|
98
99
|
}
|
|
99
100
|
|
|
@@ -106,14 +107,14 @@ export class AutonatService implements Startable {
|
|
|
106
107
|
return
|
|
107
108
|
}
|
|
108
109
|
|
|
109
|
-
await this.components.registrar.handle(
|
|
110
|
+
await this.components.registrar.handle(this.protocol, (data) => {
|
|
110
111
|
void this.handleIncomingAutonatStream(data)
|
|
111
112
|
.catch(err => {
|
|
112
113
|
log.error(err)
|
|
113
114
|
})
|
|
114
115
|
}, {
|
|
115
|
-
maxInboundStreams: this.
|
|
116
|
-
maxOutboundStreams: this.
|
|
116
|
+
maxInboundStreams: this.maxInboundStreams,
|
|
117
|
+
maxOutboundStreams: this.maxOutboundStreams
|
|
117
118
|
})
|
|
118
119
|
|
|
119
120
|
this.verifyAddressTimeout = setTimeout(this._verifyExternalAddresses, this.startupDelay)
|
|
@@ -122,7 +123,7 @@ export class AutonatService implements Startable {
|
|
|
122
123
|
}
|
|
123
124
|
|
|
124
125
|
async stop (): Promise<void> {
|
|
125
|
-
await this.components.registrar.unhandle(
|
|
126
|
+
await this.components.registrar.unhandle(this.protocol)
|
|
126
127
|
clearTimeout(this.verifyAddressTimeout)
|
|
127
128
|
|
|
128
129
|
this.started = false
|
|
@@ -132,7 +133,7 @@ export class AutonatService implements Startable {
|
|
|
132
133
|
* Handle an incoming autonat request
|
|
133
134
|
*/
|
|
134
135
|
async handleIncomingAutonatStream (data: IncomingStreamData): Promise<void> {
|
|
135
|
-
const signal = anySignal([AbortSignal.timeout(this.
|
|
136
|
+
const signal = anySignal([AbortSignal.timeout(this.timeout)])
|
|
136
137
|
|
|
137
138
|
// this controller may be used while dialing lots of peers so prevent MaxListenersExceededWarning
|
|
138
139
|
// appearing in the console
|
|
@@ -403,7 +404,7 @@ export class AutonatService implements Startable {
|
|
|
403
404
|
return
|
|
404
405
|
}
|
|
405
406
|
|
|
406
|
-
const signal = AbortSignal.timeout(this.
|
|
407
|
+
const signal = AbortSignal.timeout(this.timeout)
|
|
407
408
|
|
|
408
409
|
// this controller may be used while dialing lots of peers so prevent MaxListenersExceededWarning
|
|
409
410
|
// appearing in the console
|
|
@@ -433,7 +434,7 @@ export class AutonatService implements Startable {
|
|
|
433
434
|
const results: Record<string, { success: number, failure: number }> = {}
|
|
434
435
|
const networkSegments: string[] = []
|
|
435
436
|
|
|
436
|
-
|
|
437
|
+
const verifyAddress = async (peer: PeerInfo): Promise<Message.DialResponse | undefined> => {
|
|
437
438
|
try {
|
|
438
439
|
log('Asking %p to verify multiaddr', peer.id)
|
|
439
440
|
|
|
@@ -441,7 +442,7 @@ export class AutonatService implements Startable {
|
|
|
441
442
|
signal
|
|
442
443
|
})
|
|
443
444
|
|
|
444
|
-
const stream = await connection.newStream(
|
|
445
|
+
const stream = await connection.newStream(this.protocol, {
|
|
445
446
|
signal
|
|
446
447
|
})
|
|
447
448
|
const source = abortableDuplex(stream, signal)
|
|
@@ -563,3 +564,9 @@ export class AutonatService implements Startable {
|
|
|
563
564
|
}
|
|
564
565
|
}
|
|
565
566
|
}
|
|
567
|
+
|
|
568
|
+
export function autonatService (init: AutonatServiceInit = {}): (components: AutonatComponents) => {} {
|
|
569
|
+
return (components) => {
|
|
570
|
+
return new DefaultAutonatService(components, init)
|
|
571
|
+
}
|
|
572
|
+
}
|
|
@@ -287,6 +287,10 @@ class CircuitRelayServer extends EventEmitter<RelayServerEvents> implements Star
|
|
|
287
287
|
const addrs = []
|
|
288
288
|
|
|
289
289
|
for (const relayAddr of this.addressManager.getAddresses()) {
|
|
290
|
+
if (relayAddr.toString().includes('/p2p-circuit')) {
|
|
291
|
+
continue
|
|
292
|
+
}
|
|
293
|
+
|
|
290
294
|
addrs.push(relayAddr.bytes)
|
|
291
295
|
}
|
|
292
296
|
|
|
@@ -91,7 +91,7 @@ export class RelayDiscovery extends EventEmitter<RelayDiscoveryEvents> implement
|
|
|
91
91
|
log('searching peer store for relays')
|
|
92
92
|
const peers = (await this.peerStore.all())
|
|
93
93
|
// filter by a list of peers supporting RELAY_V2_HOP and ones we are not listening on
|
|
94
|
-
.filter(({
|
|
94
|
+
.filter(({ protocols }) => protocols.includes(RELAY_V2_HOP_CODEC))
|
|
95
95
|
.sort(() => Math.random() - 0.5)
|
|
96
96
|
|
|
97
97
|
for (const peer of peers) {
|
|
@@ -112,11 +112,11 @@ export class RelayDiscovery extends EventEmitter<RelayDiscoveryEvents> implement
|
|
|
112
112
|
const peerId = provider.id
|
|
113
113
|
|
|
114
114
|
found++
|
|
115
|
-
log('found relay peer %p in content routing', peerId)
|
|
116
115
|
await this.peerStore.merge(peerId, {
|
|
117
116
|
multiaddrs: provider.multiaddrs
|
|
118
117
|
})
|
|
119
118
|
|
|
119
|
+
log('found relay peer %p in content routing', peerId)
|
|
120
120
|
this.safeDispatchEvent('relay:discover', { detail: peerId })
|
|
121
121
|
}
|
|
122
122
|
}
|
|
@@ -84,7 +84,6 @@ class CircuitRelayTransport implements Transport {
|
|
|
84
84
|
private readonly upgrader: Upgrader
|
|
85
85
|
private readonly addressManager: AddressManager
|
|
86
86
|
private readonly connectionGater: ConnectionGater
|
|
87
|
-
private readonly events: EventEmitter<Libp2pEvents>
|
|
88
87
|
private readonly reservationStore: ReservationStore
|
|
89
88
|
private started: boolean
|
|
90
89
|
|
|
@@ -96,7 +95,6 @@ class CircuitRelayTransport implements Transport {
|
|
|
96
95
|
this.upgrader = components.upgrader
|
|
97
96
|
this.addressManager = components.addressManager
|
|
98
97
|
this.connectionGater = components.connectionGater
|
|
99
|
-
this.events = components.events
|
|
100
98
|
|
|
101
99
|
if (init.discoverRelays != null && init.discoverRelays > 0) {
|
|
102
100
|
this.discovery = new RelayDiscovery(components)
|
|
@@ -170,7 +168,7 @@ class CircuitRelayTransport implements Transport {
|
|
|
170
168
|
const destinationId = destinationAddr.getPeerId()
|
|
171
169
|
|
|
172
170
|
if (relayId == null || destinationId == null) {
|
|
173
|
-
const errMsg =
|
|
171
|
+
const errMsg = `Circuit relay dial to ${ma.toString()} failed as address did not have peer ids`
|
|
174
172
|
log.error(errMsg)
|
|
175
173
|
throw new CodeError(errMsg, codes.ERR_RELAYED_DIAL)
|
|
176
174
|
}
|
|
@@ -203,7 +201,7 @@ class CircuitRelayTransport implements Transport {
|
|
|
203
201
|
disconnectOnFailure
|
|
204
202
|
})
|
|
205
203
|
} catch (err: any) {
|
|
206
|
-
log.error(
|
|
204
|
+
log.error(`Circuit relay dial to destination ${destinationPeer.toString()} via relay ${relayPeer.toString()} failed`, err)
|
|
207
205
|
disconnectOnFailure && await relayConnection.close()
|
|
208
206
|
throw err
|
|
209
207
|
}
|
|
@@ -244,7 +242,7 @@ class CircuitRelayTransport implements Transport {
|
|
|
244
242
|
log('new outbound connection %s', maConn.remoteAddr)
|
|
245
243
|
return await this.upgrader.upgradeOutbound(maConn)
|
|
246
244
|
} catch (err) {
|
|
247
|
-
log.error(
|
|
245
|
+
log.error(`Circuit relay dial to destination ${destinationPeer.toString()} via relay ${connection.remotePeer.toString()} failed`, err)
|
|
248
246
|
disconnectOnFailure && await connection.close()
|
|
249
247
|
throw err
|
|
250
248
|
}
|
|
@@ -256,8 +254,7 @@ class CircuitRelayTransport implements Transport {
|
|
|
256
254
|
createListener (options: CreateListenerOptions): Listener {
|
|
257
255
|
return createListener({
|
|
258
256
|
connectionManager: this.connectionManager,
|
|
259
|
-
relayStore: this.reservationStore
|
|
260
|
-
events: this.events
|
|
257
|
+
relayStore: this.reservationStore
|
|
261
258
|
})
|
|
262
259
|
}
|
|
263
260
|
|
|
@@ -7,47 +7,57 @@ import type { ReservationStore } from './reservation-store.js'
|
|
|
7
7
|
import type { PeerId } from '@libp2p/interface-peer-id'
|
|
8
8
|
import { PeerMap } from '@libp2p/peer-collections'
|
|
9
9
|
import { logger } from '@libp2p/logger'
|
|
10
|
-
import
|
|
10
|
+
import { peerIdFromString } from '@libp2p/peer-id'
|
|
11
|
+
import type { Connection } from '@libp2p/interface-connection'
|
|
12
|
+
import { CodeError } from '@libp2p/interfaces/errors'
|
|
11
13
|
|
|
12
14
|
const log = logger('libp2p:circuit-relay:transport:listener')
|
|
13
15
|
|
|
14
16
|
export interface CircuitRelayTransportListenerComponents {
|
|
15
17
|
connectionManager: ConnectionManager
|
|
16
18
|
relayStore: ReservationStore
|
|
17
|
-
events: EventEmitter<Libp2pEvents>
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
class CircuitRelayTransportListener extends EventEmitter<ListenerEvents> implements Listener {
|
|
21
22
|
private readonly connectionManager: ConnectionManager
|
|
22
23
|
private readonly relayStore: ReservationStore
|
|
23
|
-
private readonly listeningAddrs: PeerMap<Multiaddr>
|
|
24
|
-
private readonly events: EventEmitter<Libp2pEvents>
|
|
24
|
+
private readonly listeningAddrs: PeerMap<Multiaddr[]>
|
|
25
25
|
|
|
26
26
|
constructor (components: CircuitRelayTransportListenerComponents) {
|
|
27
27
|
super()
|
|
28
28
|
|
|
29
29
|
this.connectionManager = components.connectionManager
|
|
30
30
|
this.relayStore = components.relayStore
|
|
31
|
-
this.events = components.events
|
|
32
31
|
this.listeningAddrs = new PeerMap()
|
|
33
32
|
|
|
34
33
|
// remove listening addrs when a relay is removed
|
|
35
34
|
this.relayStore.addEventListener('relay:removed', (evt) => {
|
|
36
35
|
this.#removeRelayPeer(evt.detail)
|
|
37
36
|
})
|
|
38
|
-
|
|
39
|
-
// remove listening addrs when a peer disconnects
|
|
40
|
-
this.events.addEventListener('connection:close', (evt) => {
|
|
41
|
-
this.#removeRelayPeer(evt.detail.remotePeer)
|
|
42
|
-
})
|
|
43
37
|
}
|
|
44
38
|
|
|
45
39
|
async listen (addr: Multiaddr): Promise<void> {
|
|
46
40
|
log('listen on %s', addr)
|
|
47
41
|
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
42
|
+
const relayPeerStr = addr.getPeerId()
|
|
43
|
+
let relayConn: Connection | undefined
|
|
44
|
+
|
|
45
|
+
// check if we already have a connection to the relay
|
|
46
|
+
if (relayPeerStr != null) {
|
|
47
|
+
const relayPeer = peerIdFromString(relayPeerStr)
|
|
48
|
+
const connections = this.connectionManager.getConnectionsMap().get(relayPeer) ?? []
|
|
49
|
+
|
|
50
|
+
if (connections.length > 0) {
|
|
51
|
+
relayConn = connections[0]
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// open a new connection as we don't already have one
|
|
56
|
+
if (relayConn == null) {
|
|
57
|
+
const addrString = addr.toString().split('/p2p-circuit').find(a => a !== '')
|
|
58
|
+
const ma = multiaddr(addrString)
|
|
59
|
+
relayConn = await this.connectionManager.openConnection(ma)
|
|
60
|
+
}
|
|
51
61
|
|
|
52
62
|
if (!this.relayStore.hasReservation(relayConn.remotePeer)) {
|
|
53
63
|
// addRelay calls transportManager.listen which calls this listen method
|
|
@@ -55,31 +65,27 @@ class CircuitRelayTransportListener extends EventEmitter<ListenerEvents> impleme
|
|
|
55
65
|
return
|
|
56
66
|
}
|
|
57
67
|
|
|
68
|
+
const reservation = this.relayStore.getReservation(relayConn.remotePeer)
|
|
69
|
+
|
|
70
|
+
if (reservation == null) {
|
|
71
|
+
throw new CodeError('Did not have reservation after making reservation', 'ERR_NO_RESERVATION')
|
|
72
|
+
}
|
|
73
|
+
|
|
58
74
|
if (this.listeningAddrs.has(relayConn.remotePeer)) {
|
|
59
75
|
log('already listening on relay %p', relayConn.remotePeer)
|
|
60
76
|
return
|
|
61
77
|
}
|
|
62
78
|
|
|
63
|
-
|
|
79
|
+
// add all addresses from the relay reservation
|
|
80
|
+
this.listeningAddrs.set(relayConn.remotePeer, reservation.addrs.map(buf => {
|
|
81
|
+
return multiaddr(buf).encapsulate('/p2p-circuit')
|
|
82
|
+
}))
|
|
83
|
+
|
|
64
84
|
this.safeDispatchEvent('listening', {})
|
|
65
85
|
}
|
|
66
86
|
|
|
67
|
-
/**
|
|
68
|
-
* Get fixed up multiaddrs
|
|
69
|
-
*
|
|
70
|
-
* NOTE: This method will grab the peers multiaddrs and expand them such that:
|
|
71
|
-
*
|
|
72
|
-
* a) If it's an existing /p2p-circuit address for a specific relay i.e.
|
|
73
|
-
* `/ip4/0.0.0.0/tcp/0/ipfs/QmRelay/p2p-circuit` this method will expand the
|
|
74
|
-
* address to `/ip4/0.0.0.0/tcp/0/ipfs/QmRelay/p2p-circuit/ipfs/QmPeer` where
|
|
75
|
-
* `QmPeer` is this peers id
|
|
76
|
-
* b) If it's not a /p2p-circuit address, it will encapsulate the address as a /p2p-circuit
|
|
77
|
-
* addr, such when dialing over a relay with this address, it will create the circuit using
|
|
78
|
-
* the encapsulated transport address. This is useful when for example, a peer should only
|
|
79
|
-
* be dialed over TCP rather than any other transport
|
|
80
|
-
*/
|
|
81
87
|
getAddrs (): Multiaddr[] {
|
|
82
|
-
return [...this.listeningAddrs.values()]
|
|
88
|
+
return [...this.listeningAddrs.values()].flat()
|
|
83
89
|
}
|
|
84
90
|
|
|
85
91
|
async close (): Promise<void> {
|
|
@@ -96,8 +96,8 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
|
|
|
96
96
|
// When a peer disconnects, if we had a reservation on that peer
|
|
97
97
|
// remove the reservation and multiaddr and maybe trigger search
|
|
98
98
|
// for new relays
|
|
99
|
-
this.events.addEventListener('
|
|
100
|
-
this
|
|
99
|
+
this.events.addEventListener('peer:disconnect', (evt) => {
|
|
100
|
+
this.#removeRelay(evt.detail)
|
|
101
101
|
})
|
|
102
102
|
}
|
|
103
103
|
|
|
@@ -125,15 +125,15 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
|
|
|
125
125
|
* on the remote peer
|
|
126
126
|
*/
|
|
127
127
|
async addRelay (peerId: PeerId, type: RelayType): Promise<void> {
|
|
128
|
-
|
|
128
|
+
if (this.peerId.equals(peerId)) {
|
|
129
|
+
log('not trying to use self as relay')
|
|
130
|
+
return
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
log('add relay %p', peerId)
|
|
129
134
|
|
|
130
135
|
await this.reserveQueue.add(async () => {
|
|
131
136
|
try {
|
|
132
|
-
if (this.peerId.equals(peerId)) {
|
|
133
|
-
log('not trying to use self as relay')
|
|
134
|
-
return
|
|
135
|
-
}
|
|
136
|
-
|
|
137
137
|
// allow refresh of an existing reservation if it is about to expire
|
|
138
138
|
const existingReservation = this.reservations.get(peerId)
|
|
139
139
|
|
|
@@ -181,6 +181,7 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
|
|
|
181
181
|
})
|
|
182
182
|
}, timeoutDuration)
|
|
183
183
|
|
|
184
|
+
// we've managed to create a reservation successfully
|
|
184
185
|
this.reservations.set(peerId, {
|
|
185
186
|
timeout,
|
|
186
187
|
reservation,
|
|
@@ -197,13 +198,13 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
|
|
|
197
198
|
}
|
|
198
199
|
})
|
|
199
200
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
return multiaddr(ma).encapsulate('/p2p-circuit')
|
|
203
|
-
})
|
|
204
|
-
)
|
|
201
|
+
// listen on multiaddr that only the circuit transport is listening for
|
|
202
|
+
await this.transportManager.listen([multiaddr(`/p2p/${peerId.toString()}/p2p-circuit`)])
|
|
205
203
|
} catch (err) {
|
|
206
204
|
log.error('could not reserve slot on %p', peerId, err)
|
|
205
|
+
|
|
206
|
+
// if listening failed, remove the reservation
|
|
207
|
+
this.reservations.delete(peerId)
|
|
207
208
|
}
|
|
208
209
|
})
|
|
209
210
|
}
|
|
@@ -212,6 +213,10 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
|
|
|
212
213
|
return this.reservations.has(peerId)
|
|
213
214
|
}
|
|
214
215
|
|
|
216
|
+
getReservation (peerId: PeerId): Reservation | undefined {
|
|
217
|
+
return this.reservations.get(peerId)?.reservation
|
|
218
|
+
}
|
|
219
|
+
|
|
215
220
|
async #createReservation (connection: Connection): Promise<Reservation> {
|
|
216
221
|
log('requesting reservation from %s', connection.remotePeer)
|
|
217
222
|
const stream = await connection.newStream(RELAY_V2_HOP_CODEC)
|
|
@@ -243,14 +248,14 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
|
|
|
243
248
|
/**
|
|
244
249
|
* Remove listen relay
|
|
245
250
|
*/
|
|
246
|
-
removeRelay (peerId: PeerId): void {
|
|
251
|
+
#removeRelay (peerId: PeerId): void {
|
|
247
252
|
const existingReservation = this.reservations.get(peerId)
|
|
248
253
|
|
|
249
254
|
if (existingReservation == null) {
|
|
250
255
|
return
|
|
251
256
|
}
|
|
252
257
|
|
|
253
|
-
log('
|
|
258
|
+
log('connection to relay %p closed, removing reservation from local store', peerId)
|
|
254
259
|
|
|
255
260
|
clearTimeout(existingReservation.timeout)
|
|
256
261
|
this.reservations.delete(peerId)
|
|
@@ -258,6 +263,7 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
|
|
|
258
263
|
this.safeDispatchEvent('relay:removed', { detail: peerId })
|
|
259
264
|
|
|
260
265
|
if (this.reservations.size < this.maxDiscoveredRelays) {
|
|
266
|
+
log('not enough relays %d/%d', this.reservations.size, this.maxDiscoveredRelays)
|
|
261
267
|
this.safeDispatchEvent('relay:not-enough-relays', {})
|
|
262
268
|
}
|
|
263
269
|
}
|
package/src/config.ts
CHANGED
|
@@ -24,62 +24,7 @@ const DefaultConfig: Partial<Libp2pInit> = {
|
|
|
24
24
|
},
|
|
25
25
|
transportManager: {
|
|
26
26
|
faultTolerance: FaultTolerance.FATAL_ALL
|
|
27
|
-
},
|
|
28
|
-
peerRouting: {
|
|
29
|
-
refreshManager: {
|
|
30
|
-
enabled: true,
|
|
31
|
-
interval: 6e5,
|
|
32
|
-
bootDelay: 10e3
|
|
33
|
-
}
|
|
34
27
|
}
|
|
35
|
-
/*
|
|
36
|
-
|
|
37
|
-
nat: {
|
|
38
|
-
enabled: true,
|
|
39
|
-
ttl: 7200,
|
|
40
|
-
keepAlive: true
|
|
41
|
-
},
|
|
42
|
-
identify: {
|
|
43
|
-
protocolPrefix: 'ipfs',
|
|
44
|
-
host: {
|
|
45
|
-
agentVersion: AGENT_VERSION
|
|
46
|
-
},
|
|
47
|
-
// https://github.com/libp2p/go-libp2p/blob/8d2e54e1637041d5cf4fac1e531287560bd1f4ac/p2p/protocol/identify/id.go#L48
|
|
48
|
-
timeout: 60000,
|
|
49
|
-
maxInboundStreams: 1,
|
|
50
|
-
maxOutboundStreams: 1,
|
|
51
|
-
maxPushIncomingStreams: 1,
|
|
52
|
-
maxPushOutgoingStreams: 1,
|
|
53
|
-
maxObservedAddresses: 10
|
|
54
|
-
},
|
|
55
|
-
ping: {
|
|
56
|
-
protocolPrefix: 'ipfs',
|
|
57
|
-
// See https://github.com/libp2p/specs/blob/d4b5fb0152a6bb86cfd9ea/ping/ping.md?plain=1#L38-L43
|
|
58
|
-
// The dialing peer MUST NOT keep more than one outbound stream for the ping protocol per peer.
|
|
59
|
-
// The listening peer SHOULD accept at most two streams per peer since cross-stream behavior is
|
|
60
|
-
// non-linear and stream writes occur asynchronously. The listening peer may perceive the
|
|
61
|
-
// dialing peer closing and opening the wrong streams (for instance, closing stream B and
|
|
62
|
-
// opening stream A even though the dialing peer is opening stream B and closing stream A).
|
|
63
|
-
maxInboundStreams: 2,
|
|
64
|
-
maxOutboundStreams: 1,
|
|
65
|
-
timeout: 10000
|
|
66
|
-
},
|
|
67
|
-
fetch: {
|
|
68
|
-
protocolPrefix: 'libp2p',
|
|
69
|
-
maxInboundStreams: 1,
|
|
70
|
-
maxOutboundStreams: 1,
|
|
71
|
-
timeout: 10000
|
|
72
|
-
},
|
|
73
|
-
autonat: {
|
|
74
|
-
protocolPrefix: 'libp2p',
|
|
75
|
-
maxInboundStreams: 1,
|
|
76
|
-
maxOutboundStreams: 1,
|
|
77
|
-
timeout: 30000,
|
|
78
|
-
startupDelay: 5000,
|
|
79
|
-
refreshInterval: 60000
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
*/
|
|
83
28
|
}
|
|
84
29
|
|
|
85
30
|
export function validateConfig <T extends ServiceMap = {}> (opts: RecursivePartial<Libp2pInit<T>>): Libp2pInit<T> {
|
|
@@ -23,6 +23,7 @@ import { combineSignals, resolveMultiaddrs } from './utils.js'
|
|
|
23
23
|
import pDefer from 'p-defer'
|
|
24
24
|
import { ClearableSignal, anySignal } from 'any-signal'
|
|
25
25
|
import type { AddressSorter } from '@libp2p/interface-libp2p'
|
|
26
|
+
import { setMaxListeners } from 'events'
|
|
26
27
|
|
|
27
28
|
const log = logger('libp2p:connection-manager:dial-queue')
|
|
28
29
|
|
|
@@ -100,6 +101,11 @@ export class DialQueue {
|
|
|
100
101
|
this.transportManager = components.transportManager
|
|
101
102
|
this.shutDownController = new AbortController()
|
|
102
103
|
|
|
104
|
+
try {
|
|
105
|
+
// This emitter gets listened to a lot
|
|
106
|
+
setMaxListeners?.(Infinity, this.shutDownController.signal)
|
|
107
|
+
} catch {}
|
|
108
|
+
|
|
103
109
|
this.pendingDialCount = components.metrics?.registerMetric('libp2p_dialler_pending_dials')
|
|
104
110
|
this.inProgressDialCount = components.metrics?.registerMetric('libp2p_dialler_in_progress_dials')
|
|
105
111
|
this.pendingDials = []
|
|
@@ -258,6 +264,11 @@ export class DialQueue {
|
|
|
258
264
|
]
|
|
259
265
|
)
|
|
260
266
|
|
|
267
|
+
try {
|
|
268
|
+
// This emitter gets listened to a lot
|
|
269
|
+
setMaxListeners?.(Infinity, signal)
|
|
270
|
+
} catch {}
|
|
271
|
+
|
|
261
272
|
return signal
|
|
262
273
|
}
|
|
263
274
|
|