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.
- package/dist/index.min.js +13 -17
- package/dist/index.min.js.map +4 -4
- package/dist/src/address-manager/dns-mappings.d.ts +1 -2
- package/dist/src/address-manager/dns-mappings.d.ts.map +1 -1
- package/dist/src/address-manager/dns-mappings.js +40 -44
- package/dist/src/address-manager/dns-mappings.js.map +1 -1
- package/dist/src/address-manager/index.d.ts.map +1 -1
- package/dist/src/address-manager/index.js +31 -14
- package/dist/src/address-manager/index.js.map +1 -1
- package/dist/src/address-manager/ip-mappings.d.ts +1 -0
- package/dist/src/address-manager/ip-mappings.d.ts.map +1 -1
- package/dist/src/address-manager/ip-mappings.js +51 -40
- package/dist/src/address-manager/ip-mappings.js.map +1 -1
- package/dist/src/address-manager/observed-addresses.d.ts.map +1 -1
- package/dist/src/address-manager/observed-addresses.js +1 -3
- package/dist/src/address-manager/observed-addresses.js.map +1 -1
- package/dist/src/address-manager/transport-addresses.d.ts.map +1 -1
- package/dist/src/address-manager/transport-addresses.js +6 -8
- package/dist/src/address-manager/transport-addresses.js.map +1 -1
- package/dist/src/config/connection-gater.browser.d.ts.map +1 -1
- package/dist/src/config/connection-gater.browser.js +3 -9
- package/dist/src/config/connection-gater.browser.js.map +1 -1
- package/dist/src/config.js +1 -1
- package/dist/src/config.js.map +1 -1
- package/dist/src/connection-manager/address-sorter.d.ts.map +1 -1
- package/dist/src/connection-manager/address-sorter.js +1 -2
- package/dist/src/connection-manager/address-sorter.js.map +1 -1
- package/dist/src/connection-manager/connection-pruner.d.ts.map +1 -1
- package/dist/src/connection-manager/connection-pruner.js +7 -3
- package/dist/src/connection-manager/connection-pruner.js.map +1 -1
- package/dist/src/connection-manager/constants.defaults.d.ts +4 -0
- package/dist/src/connection-manager/constants.defaults.d.ts.map +1 -1
- package/dist/src/connection-manager/constants.defaults.js +4 -0
- package/dist/src/connection-manager/constants.defaults.js.map +1 -1
- package/dist/src/connection-manager/dial-queue.d.ts +2 -2
- package/dist/src/connection-manager/dial-queue.d.ts.map +1 -1
- package/dist/src/connection-manager/dial-queue.js +13 -25
- package/dist/src/connection-manager/dial-queue.js.map +1 -1
- package/dist/src/connection-manager/index.d.ts +10 -2
- package/dist/src/connection-manager/index.d.ts.map +1 -1
- package/dist/src/connection-manager/index.js +45 -27
- package/dist/src/connection-manager/index.js.map +1 -1
- package/dist/src/connection-manager/reconnect-queue.js +1 -1
- package/dist/src/connection-manager/reconnect-queue.js.map +1 -1
- package/dist/src/connection-manager/utils.d.ts +31 -3
- package/dist/src/connection-manager/utils.d.ts.map +1 -1
- package/dist/src/connection-manager/utils.js +99 -18
- package/dist/src/connection-manager/utils.js.map +1 -1
- package/dist/src/connection-monitor.d.ts +1 -1
- package/dist/src/connection-monitor.d.ts.map +1 -1
- package/dist/src/connection-monitor.js +2 -3
- package/dist/src/connection-monitor.js.map +1 -1
- package/dist/src/connection.d.ts +62 -0
- package/dist/src/connection.d.ts.map +1 -0
- package/dist/src/connection.js +239 -0
- package/dist/src/connection.js.map +1 -0
- package/dist/src/get-peer.js +3 -3
- package/dist/src/get-peer.js.map +1 -1
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.js +2 -2
- package/dist/src/libp2p.d.ts.map +1 -1
- package/dist/src/libp2p.js +5 -5
- package/dist/src/libp2p.js.map +1 -1
- package/dist/src/peer-routing.js +1 -1
- package/dist/src/peer-routing.js.map +1 -1
- package/dist/src/random-walk.d.ts.map +1 -1
- package/dist/src/random-walk.js +13 -3
- package/dist/src/random-walk.js.map +1 -1
- package/dist/src/registrar.d.ts +3 -3
- package/dist/src/registrar.d.ts.map +1 -1
- package/dist/src/registrar.js +50 -41
- package/dist/src/registrar.js.map +1 -1
- package/dist/src/transport-manager.js +15 -2
- package/dist/src/transport-manager.js.map +1 -1
- package/dist/src/upgrader.d.ts +27 -25
- package/dist/src/upgrader.d.ts.map +1 -1
- package/dist/src/upgrader.js +97 -336
- package/dist/src/upgrader.js.map +1 -1
- package/dist/src/utils.d.ts +3 -0
- package/dist/src/utils.d.ts.map +1 -0
- package/dist/src/utils.js +25 -0
- package/dist/src/utils.js.map +1 -0
- 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 +26 -30
- package/src/address-manager/dns-mappings.ts +51 -51
- package/src/address-manager/index.ts +37 -17
- package/src/address-manager/ip-mappings.ts +64 -44
- package/src/address-manager/observed-addresses.ts +1 -3
- package/src/address-manager/transport-addresses.ts +7 -9
- package/src/config/connection-gater.browser.ts +3 -12
- package/src/config.ts +1 -1
- package/src/connection-manager/address-sorter.ts +1 -2
- package/src/connection-manager/connection-pruner.ts +8 -3
- package/src/connection-manager/constants.defaults.ts +5 -0
- package/src/connection-manager/dial-queue.ts +14 -29
- package/src/connection-manager/index.ts +62 -29
- package/src/connection-manager/reconnect-queue.ts +1 -1
- package/src/connection-manager/utils.ts +129 -21
- package/src/connection-monitor.ts +3 -4
- package/src/connection.ts +316 -0
- package/src/get-peer.ts +3 -3
- package/src/index.ts +2 -2
- package/src/libp2p.ts +5 -6
- package/src/peer-routing.ts +1 -1
- package/src/random-walk.ts +13 -3
- package/src/registrar.ts +67 -54
- package/src/transport-manager.ts +18 -2
- package/src/upgrader.ts +143 -421
- package/src/utils.ts +31 -0
- package/src/version.ts +1 -1
- package/dist/src/connection/index.d.ts +0 -84
- package/dist/src/connection/index.d.ts.map +0 -1
- package/dist/src/connection/index.js +0 -144
- package/dist/src/connection/index.js.map +0 -1
- package/dist/typedoc-urls.json +0 -24
- package/src/connection/index.ts +0 -199
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isIPv4 } from '@chainsafe/is-ip'
|
|
2
|
-
import { trackedMap } from '@libp2p/utils
|
|
3
|
-
import {
|
|
2
|
+
import { getNetConfig, isNetworkAddress, trackedMap } from '@libp2p/utils'
|
|
3
|
+
import { CODE_IP4, CODE_IP6, multiaddr } from '@multiformats/multiaddr'
|
|
4
4
|
import type { AddressManagerComponents, AddressManagerInit } from './index.js'
|
|
5
5
|
import type { Logger } from '@libp2p/interface'
|
|
6
6
|
import type { NodeAddress } from '@libp2p/interface-internal'
|
|
@@ -22,11 +22,6 @@ interface PublicAddressMapping {
|
|
|
22
22
|
lastVerified?: number
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
const CODEC_IP4 = 0x04
|
|
26
|
-
const CODEC_IP6 = 0x29
|
|
27
|
-
const CODEC_TCP = 0x06
|
|
28
|
-
const CODEC_UDP = 0x0111
|
|
29
|
-
|
|
30
25
|
export class IPMappings {
|
|
31
26
|
private readonly log: Logger
|
|
32
27
|
private readonly mappings: Map<string, PublicAddressMapping[]>
|
|
@@ -40,11 +35,15 @@ export class IPMappings {
|
|
|
40
35
|
}
|
|
41
36
|
|
|
42
37
|
has (ma: Multiaddr): boolean {
|
|
43
|
-
const
|
|
38
|
+
const config = getNetConfig(ma)
|
|
39
|
+
|
|
40
|
+
if (config.type !== 'ip4' && config.type !== 'ip6') {
|
|
41
|
+
return false
|
|
42
|
+
}
|
|
44
43
|
|
|
45
44
|
for (const mappings of this.mappings.values()) {
|
|
46
45
|
for (const mapping of mappings) {
|
|
47
|
-
if (mapping.externalIp ===
|
|
46
|
+
if (mapping.externalIp === config.host) {
|
|
48
47
|
return true
|
|
49
48
|
}
|
|
50
49
|
}
|
|
@@ -72,18 +71,20 @@ export class IPMappings {
|
|
|
72
71
|
}
|
|
73
72
|
|
|
74
73
|
remove (ma: Multiaddr): boolean {
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
74
|
+
const config = getNetConfig(ma)
|
|
75
|
+
|
|
76
|
+
if (config.type !== 'ip4' && config.type !== 'ip6') {
|
|
77
|
+
return false
|
|
78
|
+
}
|
|
79
|
+
|
|
79
80
|
let wasConfident = false
|
|
80
81
|
|
|
81
82
|
for (const [key, mappings] of this.mappings.entries()) {
|
|
82
83
|
for (let i = 0; i < mappings.length; i++) {
|
|
83
84
|
const mapping = mappings[i]
|
|
84
85
|
|
|
85
|
-
if (mapping.externalIp === host && mapping.externalPort === port && mapping.protocol === protocol) {
|
|
86
|
-
this.log('removing %s:%s to %s:%s %s IP mapping', mapping.externalIp, mapping.externalPort, host, port, protocol)
|
|
86
|
+
if (mapping.externalIp === config.host && mapping.externalPort === config.port && mapping.protocol === config.protocol) {
|
|
87
|
+
this.log('removing %s:%s to %s:%s %s IP mapping', mapping.externalIp, mapping.externalPort, config.host, config.port, config.protocol)
|
|
87
88
|
|
|
88
89
|
wasConfident = wasConfident || mapping.verified
|
|
89
90
|
mappings.splice(i, 1)
|
|
@@ -103,40 +104,38 @@ export class IPMappings {
|
|
|
103
104
|
const ipMappedAddresses: NodeAddress[] = []
|
|
104
105
|
|
|
105
106
|
for (const { multiaddr: ma } of addresses) {
|
|
106
|
-
|
|
107
|
-
|
|
107
|
+
if (!isNetworkAddress(ma)) {
|
|
108
|
+
continue
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const config = getNetConfig(ma)
|
|
112
|
+
|
|
113
|
+
if (config.type !== 'ip4' && config.type !== 'ip6') {
|
|
114
|
+
continue
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
let key: string | undefined
|
|
108
118
|
|
|
109
119
|
// see if the internal host/port/protocol tuple has been mapped externally
|
|
110
|
-
if (
|
|
111
|
-
|
|
112
|
-
} else if (
|
|
113
|
-
|
|
120
|
+
if (config.protocol === 'tcp') {
|
|
121
|
+
key = `${config.host}-${config.port}-tcp`
|
|
122
|
+
} else if (config.protocol === 'udp') {
|
|
123
|
+
key = `${config.host}-${config.port}-udp`
|
|
114
124
|
}
|
|
115
125
|
|
|
116
|
-
if (
|
|
126
|
+
if (key == null) {
|
|
117
127
|
continue
|
|
118
128
|
}
|
|
119
129
|
|
|
120
|
-
const mappings = this.mappings.get(
|
|
130
|
+
const mappings = this.mappings.get(key)
|
|
121
131
|
|
|
122
132
|
if (mappings == null) {
|
|
123
133
|
continue
|
|
124
134
|
}
|
|
125
135
|
|
|
126
136
|
for (const mapping of mappings) {
|
|
127
|
-
tuples[0][0] = mapping.externalFamily === 4 ? CODEC_IP4 : CODEC_IP6
|
|
128
|
-
tuples[0][1] = mapping.externalIp
|
|
129
|
-
tuples[1][1] = `${mapping.externalPort}`
|
|
130
|
-
|
|
131
137
|
ipMappedAddresses.push({
|
|
132
|
-
multiaddr:
|
|
133
|
-
tuples.map(tuple => {
|
|
134
|
-
return [
|
|
135
|
-
protocols(tuple[0]).name,
|
|
136
|
-
tuple[1]
|
|
137
|
-
].join('/')
|
|
138
|
-
}).join('/')
|
|
139
|
-
}`),
|
|
138
|
+
multiaddr: this.maybeOverrideIp(ma, mapping.externalIp, mapping.externalFamily, mapping.protocol, mapping.externalPort),
|
|
140
139
|
verified: mapping.verified,
|
|
141
140
|
type: 'ip-mapping',
|
|
142
141
|
expires: mapping.expires,
|
|
@@ -148,14 +147,34 @@ export class IPMappings {
|
|
|
148
147
|
return ipMappedAddresses
|
|
149
148
|
}
|
|
150
149
|
|
|
150
|
+
private maybeOverrideIp (ma: Multiaddr, externalIp: string, externalFamily: number, protocol: 'tcp' | 'udp', externalPort: number): Multiaddr {
|
|
151
|
+
const components = ma.getComponents()
|
|
152
|
+
|
|
153
|
+
const ipIndex = components.findIndex(c => c.code === CODE_IP4 || c.code === CODE_IP6)
|
|
154
|
+
const portIndex = components.findIndex(c => c.name === protocol)
|
|
155
|
+
|
|
156
|
+
if (ipIndex > -1 && portIndex > -1) {
|
|
157
|
+
components[ipIndex].value = externalIp
|
|
158
|
+
components[ipIndex].code = externalFamily === 4 ? CODE_IP4 : CODE_IP6
|
|
159
|
+
components[portIndex].value = `${externalPort}`
|
|
160
|
+
|
|
161
|
+
return multiaddr(components)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return ma
|
|
165
|
+
}
|
|
166
|
+
|
|
151
167
|
confirm (ma: Multiaddr, ttl: number): boolean {
|
|
152
|
-
|
|
153
|
-
|
|
168
|
+
if (!isNetworkAddress(ma)) {
|
|
169
|
+
return false
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const config = getNetConfig(ma)
|
|
154
173
|
let startingConfidence = false
|
|
155
174
|
|
|
156
175
|
for (const mappings of this.mappings.values()) {
|
|
157
176
|
for (const mapping of mappings) {
|
|
158
|
-
if (mapping.externalIp === host) {
|
|
177
|
+
if (mapping.externalIp === config.host) {
|
|
159
178
|
this.log('marking %s to %s IP mapping as verified', mapping.internalIp, mapping.externalIp)
|
|
160
179
|
startingConfidence = mapping.verified
|
|
161
180
|
mapping.verified = true
|
|
@@ -169,18 +188,19 @@ export class IPMappings {
|
|
|
169
188
|
}
|
|
170
189
|
|
|
171
190
|
unconfirm (ma: Multiaddr, ttl: number): boolean {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
191
|
+
if (!isNetworkAddress(ma)) {
|
|
192
|
+
return false
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const config = getNetConfig(ma)
|
|
176
196
|
let wasConfident = false
|
|
177
197
|
|
|
178
198
|
for (const mappings of this.mappings.values()) {
|
|
179
199
|
for (let i = 0; i < mappings.length; i++) {
|
|
180
200
|
const mapping = mappings[i]
|
|
181
201
|
|
|
182
|
-
if (mapping.externalIp === host && mapping.externalPort === port && mapping.protocol === protocol) {
|
|
183
|
-
this.log('removing verification of %s:%s to %s:%s %s IP mapping', mapping.externalIp, mapping.externalPort, host, port, protocol)
|
|
202
|
+
if (mapping.externalIp === config.host && mapping.externalPort === config.port && mapping.protocol === config.protocol) {
|
|
203
|
+
this.log('removing verification of %s:%s to %s:%s %s IP mapping', mapping.externalIp, mapping.externalPort, config.host, config.port, config.protocol)
|
|
184
204
|
|
|
185
205
|
wasConfident = wasConfident || mapping.verified
|
|
186
206
|
mapping.verified = false
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import { isLinkLocal } from '@libp2p/utils
|
|
2
|
-
import { isPrivate } from '@libp2p/utils/multiaddr/is-private'
|
|
3
|
-
import { trackedMap } from '@libp2p/utils/tracked-map'
|
|
1
|
+
import { isLinkLocal, isPrivate, trackedMap } from '@libp2p/utils'
|
|
4
2
|
import { multiaddr } from '@multiformats/multiaddr'
|
|
5
3
|
import type { AddressManagerComponents, AddressManagerInit } from './index.js'
|
|
6
4
|
import type { Logger } from '@libp2p/interface'
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import { isNetworkAddress } from '@libp2p/utils
|
|
2
|
-
import { isPrivate } from '@libp2p/utils/multiaddr/is-private'
|
|
3
|
-
import { trackedMap } from '@libp2p/utils/tracked-map'
|
|
1
|
+
import { getNetConfig, isNetworkAddress, isPrivate, trackedMap } from '@libp2p/utils'
|
|
4
2
|
import type { AddressManagerComponents, AddressManagerInit } from './index.js'
|
|
5
3
|
import type { Logger } from '@libp2p/interface'
|
|
6
4
|
import type { NodeAddress } from '@libp2p/interface-internal'
|
|
@@ -114,13 +112,13 @@ export class TransportAddresses {
|
|
|
114
112
|
}
|
|
115
113
|
|
|
116
114
|
private toKey (ma: Multiaddr): string {
|
|
117
|
-
if (isNetworkAddress(ma)) {
|
|
118
|
-
|
|
119
|
-
const options = ma.toOptions()
|
|
120
|
-
|
|
121
|
-
return `${options.host}-${options.port}-${options.transport}`
|
|
115
|
+
if (!isNetworkAddress(ma)) {
|
|
116
|
+
return ma.toString()
|
|
122
117
|
}
|
|
123
118
|
|
|
124
|
-
|
|
119
|
+
// only works for dns/ip based addresses
|
|
120
|
+
const config = getNetConfig(ma)
|
|
121
|
+
|
|
122
|
+
return `${config.host}-${config.port}-${config.protocol}`
|
|
125
123
|
}
|
|
126
124
|
}
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isPrivate } from '@libp2p/utils'
|
|
2
2
|
import { WebSockets } from '@multiformats/multiaddr-matcher'
|
|
3
3
|
import type { ConnectionGater } from '@libp2p/interface'
|
|
4
4
|
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
5
5
|
|
|
6
|
-
const CODEC_IP4 = 0x04
|
|
7
|
-
const CODEC_IP6 = 0x29
|
|
8
|
-
|
|
9
6
|
/**
|
|
10
7
|
* Returns a connection gater that disallows dialling private addresses or
|
|
11
8
|
* insecure websockets by default.
|
|
@@ -21,17 +18,11 @@ export function connectionGater (gater: ConnectionGater = {}): ConnectionGater {
|
|
|
21
18
|
denyDialMultiaddr: async (multiaddr: Multiaddr) => {
|
|
22
19
|
// do not connect to insecure websockets by default
|
|
23
20
|
if (WebSockets.matches(multiaddr)) {
|
|
24
|
-
return
|
|
21
|
+
return true
|
|
25
22
|
}
|
|
26
23
|
|
|
27
|
-
const tuples = multiaddr.stringTuples()
|
|
28
|
-
|
|
29
24
|
// do not connect to private addresses by default
|
|
30
|
-
|
|
31
|
-
return Boolean(isPrivateIp(`${tuples[0][1]}`))
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return false
|
|
25
|
+
return isPrivate(multiaddr)
|
|
35
26
|
},
|
|
36
27
|
denyInboundConnection: async () => false,
|
|
37
28
|
denyOutboundConnection: async () => false,
|
package/src/config.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FaultTolerance, InvalidParametersError } from '@libp2p/interface'
|
|
2
|
-
import { mergeOptions } from '@libp2p/utils
|
|
2
|
+
import { mergeOptions } from '@libp2p/utils'
|
|
3
3
|
import { dnsaddrResolver } from './connection-manager/resolvers/dnsaddr.ts'
|
|
4
4
|
import type { Libp2pInit } from './index.js'
|
|
5
5
|
import type { ServiceMap } from '@libp2p/interface'
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { isLoopback } from '@libp2p/utils
|
|
2
|
-
import { isPrivate } from '@libp2p/utils/multiaddr/is-private'
|
|
1
|
+
import { isLoopback, isPrivate } from '@libp2p/utils'
|
|
3
2
|
import { Circuit, WebSockets, WebSocketsSecure, WebRTC, WebRTCDirect, WebTransport, TCP } from '@multiformats/multiaddr-matcher'
|
|
4
3
|
import type { Address } from '@libp2p/interface'
|
|
5
4
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PeerMap } from '@libp2p/peer-collections'
|
|
2
|
-
import {
|
|
3
|
-
import { multiaddrToIpNet } from './utils.js'
|
|
2
|
+
import { getNetConfig, isNetworkAddress } from '@libp2p/utils'
|
|
3
|
+
import { multiaddrToIpNet, safelyCloseConnectionIfUnused } from './utils.js'
|
|
4
4
|
import type { IpNet } from '@chainsafe/netmask'
|
|
5
5
|
import type { Libp2pEvents, Logger, ComponentLogger, PeerStore, Connection } from '@libp2p/interface'
|
|
6
6
|
import type { ConnectionManager } from '@libp2p/interface-internal'
|
|
@@ -103,7 +103,12 @@ export class ConnectionPruner {
|
|
|
103
103
|
this.log('too many connections open - closing a connection to %p', connection.remotePeer)
|
|
104
104
|
// check allow list
|
|
105
105
|
const connectionInAllowList = this.allow.some((ipNet) => {
|
|
106
|
-
|
|
106
|
+
if (isNetworkAddress(connection.remoteAddr)) {
|
|
107
|
+
const config = getNetConfig(connection.remoteAddr)
|
|
108
|
+
return ipNet.contains(config.host)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return true
|
|
107
112
|
})
|
|
108
113
|
|
|
109
114
|
// Connections in the allow list should be excluded from pruning
|
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const DIAL_TIMEOUT = 10_000
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* @see https://libp2p.github.io/js-libp2p/interfaces/index._internal_.ConnectionManagerConfig.html#connectionCloseTimeout
|
|
8
|
+
*/
|
|
9
|
+
export const CONNECTION_CLOSE_TIMEOUT = 1_000
|
|
10
|
+
|
|
6
11
|
/**
|
|
7
12
|
* @see https://libp2p.github.io/js-libp2p/interfaces/index._internal_.ConnectionManagerConfig.html#inboundUpgradeTimeout
|
|
8
13
|
*/
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/* eslint-disable max-depth */
|
|
2
2
|
import { TimeoutError, DialError, AbortError } from '@libp2p/interface'
|
|
3
3
|
import { PeerMap } from '@libp2p/peer-collections'
|
|
4
|
-
import { PriorityQueue } from '@libp2p/utils
|
|
5
|
-
import { multiaddr } from '@multiformats/multiaddr'
|
|
4
|
+
import { PriorityQueue } from '@libp2p/utils'
|
|
5
|
+
import { CODE_P2P, multiaddr } from '@multiformats/multiaddr'
|
|
6
6
|
import { Circuit } from '@multiformats/multiaddr-matcher'
|
|
7
7
|
import { anySignal } from 'any-signal'
|
|
8
8
|
import { setMaxListeners } from 'main-event'
|
|
@@ -20,10 +20,11 @@ import {
|
|
|
20
20
|
LAST_DIAL_SUCCESS_KEY
|
|
21
21
|
} from './constants.js'
|
|
22
22
|
import { resolveMultiaddr, dnsaddrResolver } from './resolvers/index.js'
|
|
23
|
+
import { findExistingConnection } from './utils.ts'
|
|
23
24
|
import { DEFAULT_DIAL_PRIORITY } from './index.js'
|
|
24
25
|
import type { AddressSorter, ComponentLogger, Logger, Connection, ConnectionGater, Metrics, PeerId, Address, PeerStore, PeerRouting, IsDialableOptions, OpenConnectionProgressEvents, MultiaddrResolver } from '@libp2p/interface'
|
|
25
26
|
import type { OpenConnectionOptions, TransportManager } from '@libp2p/interface-internal'
|
|
26
|
-
import type { PriorityQueueJobOptions } from '@libp2p/utils
|
|
27
|
+
import type { PriorityQueueJobOptions } from '@libp2p/utils'
|
|
27
28
|
import type { DNS } from '@multiformats/dns'
|
|
28
29
|
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
29
30
|
import type { ProgressOptions } from 'progress-events'
|
|
@@ -101,9 +102,9 @@ export class DialQueue {
|
|
|
101
102
|
metrics: components.metrics
|
|
102
103
|
})
|
|
103
104
|
// a started job errored
|
|
104
|
-
this.queue.addEventListener('
|
|
105
|
-
if (event.detail?.name !== AbortError.name) {
|
|
106
|
-
this.log.error('error in dial queue - %e', event.detail)
|
|
105
|
+
this.queue.addEventListener('failure', (event) => {
|
|
106
|
+
if (event.detail?.error.name !== AbortError.name) {
|
|
107
|
+
this.log.error('error in dial queue - %e', event.detail.error)
|
|
107
108
|
}
|
|
108
109
|
})
|
|
109
110
|
}
|
|
@@ -136,30 +137,14 @@ export class DialQueue {
|
|
|
136
137
|
async dial (peerIdOrMultiaddr: PeerId | Multiaddr | Multiaddr[], options: OpenConnectionOptions = {}): Promise<Connection> {
|
|
137
138
|
const { peerId, multiaddrs } = getPeerAddress(peerIdOrMultiaddr)
|
|
138
139
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
const existingConnection = Array.from(this.connections.values()).flat().find(conn => {
|
|
142
|
-
if (options.force === true) {
|
|
143
|
-
return false
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
if (conn.limits != null) {
|
|
147
|
-
return false
|
|
148
|
-
}
|
|
140
|
+
if (peerId != null && options.force !== true) {
|
|
141
|
+
const existingConnection = findExistingConnection(peerId, this.connections.get(peerId), multiaddrs)
|
|
149
142
|
|
|
150
|
-
if (
|
|
151
|
-
|
|
143
|
+
if (existingConnection != null) {
|
|
144
|
+
this.log('already connected to %a', existingConnection.remoteAddr)
|
|
145
|
+
options.onProgress?.(new CustomProgressEvent('dial-queue:already-connected'))
|
|
146
|
+
return existingConnection
|
|
152
147
|
}
|
|
153
|
-
|
|
154
|
-
return multiaddrs.find(addr => {
|
|
155
|
-
return addr.equals(conn.remoteAddr)
|
|
156
|
-
})
|
|
157
|
-
})
|
|
158
|
-
|
|
159
|
-
if (existingConnection?.status === 'open') {
|
|
160
|
-
this.log('already connected to %a', existingConnection.remoteAddr)
|
|
161
|
-
options.onProgress?.(new CustomProgressEvent('dial-queue:already-connected'))
|
|
162
|
-
return existingConnection
|
|
163
148
|
}
|
|
164
149
|
|
|
165
150
|
// ready to dial, all async work finished - make sure we don't have any
|
|
@@ -461,7 +446,7 @@ export class DialQueue {
|
|
|
461
446
|
// if the resolved multiaddr has a PeerID but it's the wrong one, ignore it
|
|
462
447
|
// - this can happen with addresses like bootstrap.libp2p.io that resolve
|
|
463
448
|
// to multiple different peers
|
|
464
|
-
const addrPeerId = addr.multiaddr.
|
|
449
|
+
const addrPeerId = addr.multiaddr.getComponents().findLast(c => c.code === CODE_P2P)?.value
|
|
465
450
|
if (peerId != null && addrPeerId != null) {
|
|
466
451
|
return peerId.equals(addrPeerId)
|
|
467
452
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { ConnectionClosedError, InvalidMultiaddrError, InvalidParametersError, InvalidPeerIdError, NotStartedError, start, stop } from '@libp2p/interface'
|
|
2
2
|
import { PeerMap } from '@libp2p/peer-collections'
|
|
3
|
-
import { RateLimiter } from '@libp2p/utils
|
|
3
|
+
import { getNetConfig, isNetworkAddress, RateLimiter } from '@libp2p/utils'
|
|
4
4
|
import { multiaddr } from '@multiformats/multiaddr'
|
|
5
|
+
import { pEvent } from 'p-event'
|
|
5
6
|
import { CustomProgressEvent } from 'progress-events'
|
|
6
7
|
import { getPeerAddress } from '../get-peer.js'
|
|
7
8
|
import { ConnectionPruner } from './connection-pruner.js'
|
|
@@ -9,11 +10,11 @@ import { DIAL_TIMEOUT, INBOUND_CONNECTION_THRESHOLD, MAX_CONNECTIONS, MAX_DIAL_Q
|
|
|
9
10
|
import { DialQueue } from './dial-queue.js'
|
|
10
11
|
import { ReconnectQueue } from './reconnect-queue.js'
|
|
11
12
|
import { dnsaddrResolver } from './resolvers/index.ts'
|
|
12
|
-
import { multiaddrToIpNet } from './utils.js'
|
|
13
|
+
import { findExistingConnection, multiaddrToIpNet } from './utils.js'
|
|
13
14
|
import type { IpNet } from '@chainsafe/netmask'
|
|
14
|
-
import type { PendingDial, AddressSorter, Libp2pEvents, AbortOptions, ComponentLogger, Logger, Connection, MultiaddrConnection, ConnectionGater, Metrics, PeerId, PeerStore, Startable, PendingDialStatus, PeerRouting, IsDialableOptions, MultiaddrResolver } from '@libp2p/interface'
|
|
15
|
+
import type { PendingDial, AddressSorter, Libp2pEvents, AbortOptions, ComponentLogger, Logger, Connection, MultiaddrConnection, ConnectionGater, Metrics, PeerId, PeerStore, Startable, PendingDialStatus, PeerRouting, IsDialableOptions, MultiaddrResolver, Stream, NewStreamOptions } from '@libp2p/interface'
|
|
15
16
|
import type { ConnectionManager, OpenConnectionOptions, TransportManager } from '@libp2p/interface-internal'
|
|
16
|
-
import type { JobStatus } from '@libp2p/utils
|
|
17
|
+
import type { JobStatus } from '@libp2p/utils'
|
|
17
18
|
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
18
19
|
import type { TypedEventTarget } from 'main-event'
|
|
19
20
|
|
|
@@ -65,6 +66,14 @@ export interface ConnectionManagerInit {
|
|
|
65
66
|
*/
|
|
66
67
|
dialTimeout?: number
|
|
67
68
|
|
|
69
|
+
/**
|
|
70
|
+
* How many ms to wait when closing a connection if an abort signal is not
|
|
71
|
+
* passed
|
|
72
|
+
*
|
|
73
|
+
* @default 1_000
|
|
74
|
+
*/
|
|
75
|
+
connectionCloseTimeout?: number
|
|
76
|
+
|
|
68
77
|
/**
|
|
69
78
|
* When a new incoming connection is opened, the upgrade process (e.g.
|
|
70
79
|
* protect, encrypt, multiplex etc) must complete within this number of ms.
|
|
@@ -241,8 +250,8 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
|
|
|
241
250
|
this.onDisconnect = this.onDisconnect.bind(this)
|
|
242
251
|
|
|
243
252
|
// allow/deny lists
|
|
244
|
-
this.allow = (init.allow ?? []).map(str => multiaddrToIpNet(str))
|
|
245
|
-
this.deny = (init.deny ?? []).map(str => multiaddrToIpNet(str))
|
|
253
|
+
this.allow = (init.allow ?? []).map(str => multiaddrToIpNet(multiaddr(str)))
|
|
254
|
+
this.deny = (init.deny ?? []).map(str => multiaddrToIpNet(multiaddr(str)))
|
|
246
255
|
|
|
247
256
|
this.incomingPendingConnections = 0
|
|
248
257
|
this.maxIncomingPendingConnections = init.maxIncomingPendingConnections ?? defaultOptions.maxIncomingPendingConnections
|
|
@@ -399,16 +408,22 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
|
|
|
399
408
|
)
|
|
400
409
|
|
|
401
410
|
// Close all connections we're tracking
|
|
402
|
-
const tasks: Array<Promise<
|
|
411
|
+
const tasks: Array<Promise<any>> = []
|
|
403
412
|
for (const connectionList of this.connections.values()) {
|
|
404
413
|
for (const connection of connectionList) {
|
|
405
|
-
tasks.push(
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
414
|
+
tasks.push(
|
|
415
|
+
Promise.all([
|
|
416
|
+
pEvent(connection, 'close', {
|
|
417
|
+
signal: AbortSignal.timeout(500)
|
|
418
|
+
}),
|
|
419
|
+
connection.close({
|
|
420
|
+
signal: AbortSignal.timeout(500)
|
|
421
|
+
})
|
|
422
|
+
])
|
|
423
|
+
.catch(err => {
|
|
424
|
+
connection.abort(err)
|
|
425
|
+
})
|
|
426
|
+
)
|
|
412
427
|
}
|
|
413
428
|
}
|
|
414
429
|
|
|
@@ -500,11 +515,11 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
|
|
|
500
515
|
|
|
501
516
|
if (filteredPeerConns.length === 0) {
|
|
502
517
|
// trigger disconnect event if no connections remain
|
|
503
|
-
this.log('
|
|
518
|
+
this.log.trace('peer %p disconnected, removing connection map entry', peerId)
|
|
504
519
|
this.connections.delete(peerId)
|
|
505
520
|
|
|
506
521
|
// broadcast disconnect event
|
|
507
|
-
this.events.safeDispatchEvent('peer:disconnect', { detail:
|
|
522
|
+
this.events.safeDispatchEvent('peer:disconnect', { detail: peerId })
|
|
508
523
|
}
|
|
509
524
|
}
|
|
510
525
|
|
|
@@ -536,7 +551,7 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
|
|
|
536
551
|
try {
|
|
537
552
|
options.signal?.throwIfAborted()
|
|
538
553
|
|
|
539
|
-
const { peerId } = getPeerAddress(peerIdOrMultiaddr)
|
|
554
|
+
const { peerId, multiaddrs } = getPeerAddress(peerIdOrMultiaddr)
|
|
540
555
|
|
|
541
556
|
if (this.peerId.equals(peerId)) {
|
|
542
557
|
throw new InvalidPeerIdError('Can not dial self')
|
|
@@ -544,11 +559,10 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
|
|
|
544
559
|
|
|
545
560
|
if (peerId != null && options.force !== true) {
|
|
546
561
|
this.log('dial %p', peerId)
|
|
547
|
-
const existingConnection = this.getConnections(peerId)
|
|
548
|
-
.find(conn => conn.limits == null)
|
|
562
|
+
const existingConnection = findExistingConnection(peerId, this.getConnections(peerId), multiaddrs)
|
|
549
563
|
|
|
550
564
|
if (existingConnection != null) {
|
|
551
|
-
this.log('had an existing
|
|
565
|
+
this.log('had an existing connection to %p as %a', peerId, existingConnection.remoteAddr)
|
|
552
566
|
|
|
553
567
|
options.onProgress?.(new CustomProgressEvent('dial-queue:already-connected'))
|
|
554
568
|
return existingConnection
|
|
@@ -600,13 +614,22 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
|
|
|
600
614
|
}
|
|
601
615
|
}
|
|
602
616
|
|
|
617
|
+
async openStream (peerIdOrMultiaddr: PeerId | Multiaddr | Multiaddr[], protocol: string | string[], options: OpenConnectionOptions & NewStreamOptions = {}): Promise<Stream> {
|
|
618
|
+
const connection = await this.openConnection(peerIdOrMultiaddr, options)
|
|
619
|
+
|
|
620
|
+
return connection.newStream(protocol, options)
|
|
621
|
+
}
|
|
622
|
+
|
|
603
623
|
async closeConnections (peerId: PeerId, options: AbortOptions = {}): Promise<void> {
|
|
604
624
|
const connections = this.connections.get(peerId) ?? []
|
|
605
625
|
|
|
606
626
|
await Promise.all(
|
|
607
627
|
connections.map(async connection => {
|
|
608
628
|
try {
|
|
609
|
-
await
|
|
629
|
+
await Promise.all([
|
|
630
|
+
pEvent(connection, 'close', options),
|
|
631
|
+
connection.close(options)
|
|
632
|
+
])
|
|
610
633
|
} catch (err: any) {
|
|
611
634
|
connection.abort(err)
|
|
612
635
|
}
|
|
@@ -614,10 +637,15 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
|
|
|
614
637
|
)
|
|
615
638
|
}
|
|
616
639
|
|
|
617
|
-
|
|
640
|
+
acceptIncomingConnection (maConn: MultiaddrConnection): boolean {
|
|
618
641
|
// check deny list
|
|
619
|
-
const denyConnection = this.deny.some(
|
|
620
|
-
|
|
642
|
+
const denyConnection = this.deny.some(ipNet => {
|
|
643
|
+
if (isNetworkAddress(maConn.remoteAddr)) {
|
|
644
|
+
const config = getNetConfig(maConn.remoteAddr)
|
|
645
|
+
return ipNet.contains(config.host)
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
return false
|
|
621
649
|
})
|
|
622
650
|
|
|
623
651
|
if (denyConnection) {
|
|
@@ -627,7 +655,12 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
|
|
|
627
655
|
|
|
628
656
|
// check allow list
|
|
629
657
|
const allowConnection = this.allow.some(ipNet => {
|
|
630
|
-
|
|
658
|
+
if (isNetworkAddress(maConn.remoteAddr)) {
|
|
659
|
+
const config = getNetConfig(maConn.remoteAddr)
|
|
660
|
+
return ipNet.contains(config.host)
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
return true
|
|
631
664
|
})
|
|
632
665
|
|
|
633
666
|
if (allowConnection) {
|
|
@@ -642,13 +675,13 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
|
|
|
642
675
|
return false
|
|
643
676
|
}
|
|
644
677
|
|
|
645
|
-
if (maConn.remoteAddr
|
|
646
|
-
const
|
|
678
|
+
if (isNetworkAddress(maConn.remoteAddr)) {
|
|
679
|
+
const config = getNetConfig(maConn.remoteAddr)
|
|
647
680
|
|
|
648
681
|
try {
|
|
649
|
-
|
|
682
|
+
this.inboundConnectionRateLimiter.consume(config.host, 1)
|
|
650
683
|
} catch {
|
|
651
|
-
this.log('connection from %a refused - inboundConnectionThreshold exceeded by host %s', maConn.remoteAddr, host)
|
|
684
|
+
this.log('connection from %a refused - inboundConnectionThreshold exceeded by host %s', maConn.remoteAddr, config.host)
|
|
652
685
|
return false
|
|
653
686
|
}
|
|
654
687
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { KEEP_ALIVE } from '@libp2p/interface'
|
|
2
|
-
import { PeerQueue } from '@libp2p/utils
|
|
2
|
+
import { PeerQueue } from '@libp2p/utils'
|
|
3
3
|
import pRetry from 'p-retry'
|
|
4
4
|
import { MAX_PARALLEL_RECONNECTS } from './constants.js'
|
|
5
5
|
import type { ComponentLogger, Libp2pEvents, Logger, Metrics, Peer, PeerId, PeerStore, Startable } from '@libp2p/interface'
|