libp2p 2.10.0 → 3.0.0-049bfa0fa

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 (121) hide show
  1. package/README.md +39 -37
  2. package/dist/index.min.js +14 -17
  3. package/dist/index.min.js.map +4 -4
  4. package/dist/src/address-manager/dns-mappings.d.ts +1 -2
  5. package/dist/src/address-manager/dns-mappings.d.ts.map +1 -1
  6. package/dist/src/address-manager/dns-mappings.js +39 -43
  7. package/dist/src/address-manager/dns-mappings.js.map +1 -1
  8. package/dist/src/address-manager/index.d.ts.map +1 -1
  9. package/dist/src/address-manager/index.js +31 -14
  10. package/dist/src/address-manager/index.js.map +1 -1
  11. package/dist/src/address-manager/ip-mappings.d.ts +1 -0
  12. package/dist/src/address-manager/ip-mappings.d.ts.map +1 -1
  13. package/dist/src/address-manager/ip-mappings.js +51 -40
  14. package/dist/src/address-manager/ip-mappings.js.map +1 -1
  15. package/dist/src/address-manager/observed-addresses.d.ts.map +1 -1
  16. package/dist/src/address-manager/observed-addresses.js +1 -3
  17. package/dist/src/address-manager/observed-addresses.js.map +1 -1
  18. package/dist/src/address-manager/transport-addresses.d.ts.map +1 -1
  19. package/dist/src/address-manager/transport-addresses.js +6 -8
  20. package/dist/src/address-manager/transport-addresses.js.map +1 -1
  21. package/dist/src/config/connection-gater.browser.d.ts.map +1 -1
  22. package/dist/src/config/connection-gater.browser.js +8 -22
  23. package/dist/src/config/connection-gater.browser.js.map +1 -1
  24. package/dist/src/config/connection-gater.d.ts.map +1 -1
  25. package/dist/src/config/connection-gater.js +1 -12
  26. package/dist/src/config/connection-gater.js.map +1 -1
  27. package/dist/src/config.d.ts.map +1 -1
  28. package/dist/src/config.js +3 -22
  29. package/dist/src/config.js.map +1 -1
  30. package/dist/src/connection-manager/address-sorter.d.ts.map +1 -1
  31. package/dist/src/connection-manager/address-sorter.js +1 -2
  32. package/dist/src/connection-manager/address-sorter.js.map +1 -1
  33. package/dist/src/connection-manager/connection-pruner.d.ts.map +1 -1
  34. package/dist/src/connection-manager/connection-pruner.js +7 -3
  35. package/dist/src/connection-manager/connection-pruner.js.map +1 -1
  36. package/dist/src/connection-manager/constants.defaults.d.ts +4 -0
  37. package/dist/src/connection-manager/constants.defaults.d.ts.map +1 -1
  38. package/dist/src/connection-manager/constants.defaults.js +4 -0
  39. package/dist/src/connection-manager/constants.defaults.js.map +1 -1
  40. package/dist/src/connection-manager/dial-queue.d.ts +2 -2
  41. package/dist/src/connection-manager/dial-queue.d.ts.map +1 -1
  42. package/dist/src/connection-manager/dial-queue.js +11 -23
  43. package/dist/src/connection-manager/dial-queue.js.map +1 -1
  44. package/dist/src/connection-manager/index.d.ts +10 -18
  45. package/dist/src/connection-manager/index.d.ts.map +1 -1
  46. package/dist/src/connection-manager/index.js +44 -26
  47. package/dist/src/connection-manager/index.js.map +1 -1
  48. package/dist/src/connection-manager/reconnect-queue.js +1 -1
  49. package/dist/src/connection-manager/reconnect-queue.js.map +1 -1
  50. package/dist/src/connection-manager/utils.d.ts +31 -3
  51. package/dist/src/connection-manager/utils.d.ts.map +1 -1
  52. package/dist/src/connection-manager/utils.js +99 -18
  53. package/dist/src/connection-manager/utils.js.map +1 -1
  54. package/dist/src/connection-monitor.d.ts +1 -1
  55. package/dist/src/connection-monitor.d.ts.map +1 -1
  56. package/dist/src/connection-monitor.js +2 -3
  57. package/dist/src/connection-monitor.js.map +1 -1
  58. package/dist/src/connection.d.ts +14 -9
  59. package/dist/src/connection.d.ts.map +1 -1
  60. package/dist/src/connection.js +118 -139
  61. package/dist/src/connection.js.map +1 -1
  62. package/dist/src/get-peer.js +3 -3
  63. package/dist/src/get-peer.js.map +1 -1
  64. package/dist/src/index.d.ts +2 -2
  65. package/dist/src/index.js +2 -2
  66. package/dist/src/libp2p.d.ts +3 -1
  67. package/dist/src/libp2p.d.ts.map +1 -1
  68. package/dist/src/libp2p.js +13 -7
  69. package/dist/src/libp2p.js.map +1 -1
  70. package/dist/src/peer-routing.js +1 -1
  71. package/dist/src/peer-routing.js.map +1 -1
  72. package/dist/src/random-walk.d.ts.map +1 -1
  73. package/dist/src/random-walk.js +13 -3
  74. package/dist/src/random-walk.js.map +1 -1
  75. package/dist/src/registrar.d.ts +8 -4
  76. package/dist/src/registrar.d.ts.map +1 -1
  77. package/dist/src/registrar.js +66 -46
  78. package/dist/src/registrar.js.map +1 -1
  79. package/dist/src/transport-manager.js +15 -2
  80. package/dist/src/transport-manager.js.map +1 -1
  81. package/dist/src/upgrader.d.ts +26 -16
  82. package/dist/src/upgrader.d.ts.map +1 -1
  83. package/dist/src/upgrader.js +88 -122
  84. package/dist/src/upgrader.js.map +1 -1
  85. package/dist/src/utils.d.ts +3 -0
  86. package/dist/src/utils.d.ts.map +1 -0
  87. package/dist/src/utils.js +25 -0
  88. package/dist/src/utils.js.map +1 -0
  89. package/dist/src/version.d.ts +1 -1
  90. package/dist/src/version.d.ts.map +1 -1
  91. package/dist/src/version.js +1 -1
  92. package/dist/src/version.js.map +1 -1
  93. package/package.json +27 -30
  94. package/src/address-manager/dns-mappings.ts +50 -50
  95. package/src/address-manager/index.ts +37 -17
  96. package/src/address-manager/ip-mappings.ts +64 -44
  97. package/src/address-manager/observed-addresses.ts +1 -3
  98. package/src/address-manager/transport-addresses.ts +7 -9
  99. package/src/config/connection-gater.browser.ts +8 -24
  100. package/src/config/connection-gater.ts +1 -12
  101. package/src/config.ts +3 -25
  102. package/src/connection-manager/address-sorter.ts +1 -2
  103. package/src/connection-manager/connection-pruner.ts +8 -3
  104. package/src/connection-manager/constants.defaults.ts +5 -0
  105. package/src/connection-manager/dial-queue.ts +12 -27
  106. package/src/connection-manager/index.ts +60 -45
  107. package/src/connection-manager/reconnect-queue.ts +1 -1
  108. package/src/connection-manager/utils.ts +129 -21
  109. package/src/connection-monitor.ts +3 -4
  110. package/src/connection.ts +142 -179
  111. package/src/get-peer.ts +3 -3
  112. package/src/index.ts +2 -2
  113. package/src/libp2p.ts +16 -9
  114. package/src/peer-routing.ts +1 -1
  115. package/src/random-walk.ts +13 -3
  116. package/src/registrar.ts +87 -61
  117. package/src/transport-manager.ts +18 -2
  118. package/src/upgrader.ts +132 -149
  119. package/src/utils.ts +31 -0
  120. package/src/version.ts +1 -1
  121. package/dist/typedoc-urls.json +0 -24
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "libp2p",
3
- "version": "2.10.0",
3
+ "version": "3.0.0-049bfa0fa",
4
4
  "description": "JavaScript implementation of libp2p, a modular peer to peer network stack",
5
5
  "license": "Apache-2.0 OR MIT",
6
6
  "homepage": "https://github.com/libp2p/js-libp2p/tree/main/packages/libp2p#readme",
@@ -80,47 +80,44 @@
80
80
  "dependencies": {
81
81
  "@chainsafe/is-ip": "^2.1.0",
82
82
  "@chainsafe/netmask": "^2.0.0",
83
- "@libp2p/crypto": "^5.1.8",
84
- "@libp2p/interface": "^2.11.0",
85
- "@libp2p/interface-internal": "^2.3.19",
86
- "@libp2p/logger": "^5.2.0",
87
- "@libp2p/multistream-select": "^6.0.29",
88
- "@libp2p/peer-collections": "^6.0.35",
89
- "@libp2p/peer-id": "^5.1.9",
90
- "@libp2p/peer-store": "^11.2.7",
91
- "@libp2p/utils": "^6.7.2",
83
+ "@libp2p/crypto": "5.1.9-049bfa0fa",
84
+ "@libp2p/interface": "3.0.0-049bfa0fa",
85
+ "@libp2p/interface-internal": "3.0.0-049bfa0fa",
86
+ "@libp2p/logger": "6.0.0-049bfa0fa",
87
+ "@libp2p/multistream-select": "7.0.0-049bfa0fa",
88
+ "@libp2p/peer-collections": "7.0.0-049bfa0fa",
89
+ "@libp2p/peer-id": "6.0.0-049bfa0fa",
90
+ "@libp2p/peer-store": "12.0.0-049bfa0fa",
91
+ "@libp2p/utils": "7.0.0-049bfa0fa",
92
92
  "@multiformats/dns": "^1.0.6",
93
- "@multiformats/multiaddr": "^12.4.4",
94
- "@multiformats/multiaddr-matcher": "^2.0.0",
93
+ "@multiformats/multiaddr": "^13.0.1",
94
+ "@multiformats/multiaddr-matcher": "^3.0.1",
95
95
  "any-signal": "^4.1.1",
96
- "datastore-core": "^10.0.2",
97
- "interface-datastore": "^8.3.1",
98
- "it-byte-stream": "^2.0.2",
99
- "it-merge": "^3.0.11",
100
- "it-parallel": "^3.0.11",
96
+ "datastore-core": "^10.0.4",
97
+ "interface-datastore": "^8.3.2",
98
+ "it-merge": "^3.0.12",
99
+ "it-parallel": "^3.0.13",
101
100
  "main-event": "^1.0.1",
102
- "multiformats": "^13.3.6",
101
+ "multiformats": "^13.4.0",
103
102
  "p-defer": "^4.0.1",
104
- "p-retry": "^6.2.1",
103
+ "p-event": "^6.0.1",
104
+ "p-retry": "^7.0.0",
105
105
  "progress-events": "^1.0.1",
106
- "race-event": "^1.3.0",
107
- "race-signal": "^1.1.3",
106
+ "race-signal": "^2.0.0",
108
107
  "uint8arrays": "^5.1.0"
109
108
  },
110
109
  "devDependencies": {
111
- "aegir": "^47.0.14",
110
+ "aegir": "^47.0.22",
112
111
  "delay": "^6.0.0",
113
- "it-all": "^3.0.8",
114
- "it-drain": "^3.0.9",
112
+ "it-all": "^3.0.9",
113
+ "it-drain": "^3.0.10",
115
114
  "it-length-prefixed": "^10.0.1",
116
- "it-map": "^3.1.3",
117
- "it-pair": "^2.0.6",
118
- "it-pipe": "^3.0.1",
119
- "it-take": "^3.0.8",
120
- "p-event": "^6.0.1",
115
+ "it-map": "^3.1.4",
116
+ "it-take": "^3.0.9",
121
117
  "p-wait-for": "^5.0.2",
122
- "sinon": "^20.0.0",
118
+ "sinon": "^21.0.0",
123
119
  "sinon-ts": "^2.0.0",
120
+ "uint8arraylist": "^2.4.8",
124
121
  "wherearewe": "^2.0.1"
125
122
  },
126
123
  "browser": {
@@ -1,10 +1,9 @@
1
- import { isPrivateIp } from '@libp2p/utils/private-ip'
2
- import { trackedMap } from '@libp2p/utils/tracked-map'
3
- import { multiaddr, protocols } from '@multiformats/multiaddr'
1
+ import { getNetConfig, isNetworkAddress, isPrivateIp, trackedMap } from '@libp2p/utils'
2
+ import { CODE_SNI, CODE_TLS, multiaddr } from '@multiformats/multiaddr'
4
3
  import type { AddressManagerComponents, AddressManagerInit } from './index.js'
5
4
  import type { Logger } from '@libp2p/interface'
6
5
  import type { NodeAddress } from '@libp2p/interface-internal'
7
- import type { Multiaddr, StringTuple } from '@multiformats/multiaddr'
6
+ import type { Multiaddr } from '@multiformats/multiaddr'
8
7
 
9
8
  const MAX_DATE = 8_640_000_000_000_000
10
9
 
@@ -19,13 +18,6 @@ interface DNSMapping {
19
18
  lastVerified?: number
20
19
  }
21
20
 
22
- const CODEC_TLS = 0x01c0
23
- const CODEC_SNI = 0x01c1
24
- const CODEC_DNS = 0x35
25
- const CODEC_DNS4 = 0x36
26
- const CODEC_DNS6 = 0x37
27
- const CODEC_DNSADDR = 0x38
28
-
29
21
  export class DNSMappings {
30
22
  private readonly log: Logger
31
23
  private readonly mappings: Map<string, DNSMapping>
@@ -39,7 +31,12 @@ export class DNSMappings {
39
31
  }
40
32
 
41
33
  has (ma: Multiaddr): boolean {
42
- const host = this.findHost(ma)
34
+ const config = getNetConfig(ma)
35
+ let host = config.host
36
+
37
+ if ((config.type === 'ip4' || config.type === 'ip6') && config.sni != null) {
38
+ host = config.sni
39
+ }
43
40
 
44
41
  for (const mapping of this.mappings.values()) {
45
42
  if (mapping.domain === host) {
@@ -67,11 +64,16 @@ export class DNSMappings {
67
64
  }
68
65
 
69
66
  remove (ma: Multiaddr): boolean {
70
- const host = this.findHost(ma)
67
+ const config = getNetConfig(ma)
68
+
69
+ if (config.type !== 'ip4' && config.type !== 'ip6') {
70
+ return false
71
+ }
72
+
71
73
  let wasConfident = false
72
74
 
73
75
  for (const [ip, mapping] of this.mappings.entries()) {
74
- if (mapping.domain === host) {
76
+ if (mapping.domain === config.sni) {
75
77
  this.log('removing %s to %s DNS mapping %e', ip, mapping.domain)
76
78
  this.mappings.delete(ip)
77
79
  wasConfident = wasConfident || mapping.verified
@@ -85,37 +87,30 @@ export class DNSMappings {
85
87
  const dnsMappedAddresses: NodeAddress[] = []
86
88
 
87
89
  for (let i = 0; i < addresses.length; i++) {
88
- const address = addresses[i]
89
- const tuples = address.multiaddr.stringTuples()
90
- const host = tuples[0][1]
90
+ const address = addresses[i].multiaddr
91
91
 
92
- if (host == null) {
92
+ if (!isNetworkAddress(address)) {
93
93
  continue
94
94
  }
95
95
 
96
+ const config = getNetConfig(address)
97
+
96
98
  for (const [ip, mapping] of this.mappings.entries()) {
97
- if (host !== ip) {
99
+ if (config.host !== ip) {
98
100
  continue
99
101
  }
100
102
 
101
103
  // insert SNI tuple after TLS tuple, if one is present
102
- const mappedIp = this.maybeAddSNITuple(tuples, mapping.domain)
104
+ const maWithSni = this.maybeAddSNIComponent(address, mapping.domain)
103
105
 
104
- if (mappedIp) {
106
+ if (maWithSni != null) {
105
107
  // remove the address and replace it with the version that includes
106
108
  // the SNI tuple
107
109
  addresses.splice(i, 1)
108
110
  i--
109
111
 
110
112
  dnsMappedAddresses.push({
111
- multiaddr: multiaddr(`/${
112
- tuples.map(tuple => {
113
- return [
114
- protocols(tuple[0]).name,
115
- tuple[1]
116
- ].join('/')
117
- }).join('/')
118
- }`),
113
+ multiaddr: maWithSni,
119
114
  verified: mapping.verified,
120
115
  type: 'dns-mapping',
121
116
  expires: mapping.expires,
@@ -128,19 +123,30 @@ export class DNSMappings {
128
123
  return dnsMappedAddresses
129
124
  }
130
125
 
131
- private maybeAddSNITuple (tuples: StringTuple[], domain: string): boolean {
132
- for (let j = 0; j < tuples.length; j++) {
133
- if (tuples[j][0] === CODEC_TLS && tuples[j + 1]?.[0] !== CODEC_SNI) {
134
- tuples.splice(j + 1, 0, [CODEC_SNI, domain])
135
- return true
126
+ private maybeAddSNIComponent (ma: Multiaddr, domain: string): Multiaddr | undefined {
127
+ const components = ma.getComponents()
128
+
129
+ for (let j = 0; j < components.length; j++) {
130
+ if (components[j].code === CODE_TLS && components[j + 1]?.code !== CODE_SNI) {
131
+ components.splice(j + 1, 0, {
132
+ name: 'sni',
133
+ code: CODE_SNI,
134
+ value: domain
135
+ })
136
+
137
+ return multiaddr(components)
136
138
  }
137
139
  }
138
-
139
- return false
140
140
  }
141
141
 
142
142
  confirm (ma: Multiaddr, ttl: number): boolean {
143
- const host = this.findHost(ma)
143
+ const config = getNetConfig(ma)
144
+ let host = config.host
145
+
146
+ if ((config.type === 'ip4' || config.type === 'ip6') && config.sni != null) {
147
+ host = config.sni
148
+ }
149
+
144
150
  let startingConfidence = false
145
151
 
146
152
  for (const [ip, mapping] of this.mappings.entries()) {
@@ -157,7 +163,13 @@ export class DNSMappings {
157
163
  }
158
164
 
159
165
  unconfirm (ma: Multiaddr, ttl: number): boolean {
160
- const host = this.findHost(ma)
166
+ const config = getNetConfig(ma)
167
+
168
+ if (config.type !== 'ip4' && config.type !== 'ip6') {
169
+ return false
170
+ }
171
+
172
+ const host = config.sni ?? config.host
161
173
  let wasConfident = false
162
174
 
163
175
  for (const [ip, mapping] of this.mappings.entries()) {
@@ -171,16 +183,4 @@ export class DNSMappings {
171
183
 
172
184
  return wasConfident
173
185
  }
174
-
175
- private findHost (ma: Multiaddr): string | undefined {
176
- for (const tuple of ma.stringTuples()) {
177
- if (tuple[0] === CODEC_SNI) {
178
- return tuple[1]
179
- }
180
-
181
- if (tuple[0] === CODEC_DNS || tuple[0] === CODEC_DNS4 || tuple[0] === CODEC_DNS6 || tuple[0] === CODEC_DNSADDR) {
182
- return tuple[1]
183
- }
184
- }
185
- }
186
186
  }
@@ -1,10 +1,8 @@
1
1
  /* eslint-disable complexity */
2
2
  import { isIPv4 } from '@chainsafe/is-ip'
3
3
  import { peerIdFromString } from '@libp2p/peer-id'
4
- import { debounce } from '@libp2p/utils/debounce'
5
- import { createScalableCuckooFilter } from '@libp2p/utils/filters'
6
- import { isPrivateIp } from '@libp2p/utils/private-ip'
7
- import { multiaddr } from '@multiformats/multiaddr'
4
+ import { debounce, createScalableCuckooFilter, isPrivateIp, getNetConfig, isNetworkAddress, isLoopback } from '@libp2p/utils'
5
+ import { CODE_P2P, multiaddr } from '@multiformats/multiaddr'
8
6
  import { QUIC_V1, TCP, WebSockets, WebSocketsSecure } from '@multiformats/multiaddr-matcher'
9
7
  import { DNSMappings } from './dns-mappings.js'
10
8
  import { IPMappings } from './ip-mappings.js'
@@ -12,7 +10,7 @@ import { ObservedAddresses } from './observed-addresses.js'
12
10
  import { TransportAddresses } from './transport-addresses.js'
13
11
  import type { ComponentLogger, Libp2pEvents, Logger, PeerId, PeerStore, Metrics } from '@libp2p/interface'
14
12
  import type { AddressManager as AddressManagerInterface, TransportManager, NodeAddress, ConfirmAddressOptions } from '@libp2p/interface-internal'
15
- import type { Filter } from '@libp2p/utils/filters'
13
+ import type { Filter } from '@libp2p/utils'
16
14
  import type { Multiaddr } from '@multiformats/multiaddr'
17
15
  import type { TypedEventTarget } from 'main-event'
18
16
 
@@ -101,7 +99,7 @@ const defaultAddressFilter = (addrs: Multiaddr[]): Multiaddr[] => addrs
101
99
  * If the passed multiaddr contains the passed peer id, remove it
102
100
  */
103
101
  function stripPeerId (ma: Multiaddr, peerId: PeerId): Multiaddr {
104
- const observedPeerIdStr = ma.getPeerId()
102
+ const observedPeerIdStr = ma.getComponents().findLast(c => c.code === CODE_P2P)?.value
105
103
 
106
104
  // strip our peer id if it has been passed
107
105
  if (observedPeerIdStr != null) {
@@ -177,7 +175,7 @@ export class AddressManager implements AddressManagerInterface {
177
175
  const addrs = this.getAddresses()
178
176
  .map(ma => {
179
177
  // strip our peer id if it is present
180
- if (ma.getPeerId() === this.components.peerId.toString()) {
178
+ if (ma.getComponents().findLast(c => c.code === CODE_P2P)?.value === this.components.peerId.toString()) {
181
179
  return ma.decapsulate(`/p2p/${this.components.peerId.toString()}`)
182
180
  }
183
181
 
@@ -224,8 +222,22 @@ export class AddressManager implements AddressManagerInterface {
224
222
  * Add peer observed addresses
225
223
  */
226
224
  addObservedAddr (addr: Multiaddr): void {
227
- const tuples = addr.stringTuples()
228
- const socketAddress = `${tuples[0][1]}:${tuples[1][1]}`
225
+ const config = getNetConfig(addr)
226
+ let socketAddress: string
227
+
228
+ switch (config.type) {
229
+ case 'ip4': {
230
+ socketAddress = `${config.host}:${config.port}`
231
+ break
232
+ }
233
+ case 'ip6': {
234
+ socketAddress = `[${config.host}]:${config.port}`
235
+ break
236
+ }
237
+ default: {
238
+ return
239
+ }
240
+ }
229
241
 
230
242
  // ignore if this address if it's been observed before
231
243
  if (this.observedAddressFilter.has(socketAddress)) {
@@ -477,10 +489,14 @@ export class AddressManager implements AddressManagerInterface {
477
489
  return false
478
490
  }
479
491
 
480
- const maOptions = ma.toOptions()
492
+ if (!isNetworkAddress(ma)) {
493
+ return false
494
+ }
495
+
496
+ const config = getNetConfig(ma)
481
497
 
482
498
  // only public IPv4 addresses
483
- if (maOptions.family === 6 || maOptions.host === '127.0.0.1' || isPrivateIp(maOptions.host) === true) {
499
+ if (config.type !== 'ip4' || isPrivateIp(config.host) === true) {
484
500
  return false
485
501
  }
486
502
 
@@ -502,7 +518,7 @@ export class AddressManager implements AddressManagerInterface {
502
518
  const transportListeners = listeners.filter(listener => {
503
519
  return listener.getAddrs().filter(ma => {
504
520
  // only IPv4 addresses of the matcher type
505
- return ma.toOptions().family === 4 && matcher(ma)
521
+ return getNetConfig(ma).type === 'ip4' && matcher(ma)
506
522
  }).length > 0
507
523
  })
508
524
 
@@ -516,23 +532,27 @@ export class AddressManager implements AddressManagerInterface {
516
532
  // we have one listener which listens on one port so whatever the external
517
533
  // NAT port mapping is, it should be for this listener
518
534
  const linkLocalAddr = transportListeners[0].getAddrs().filter(ma => {
519
- return ma.toOptions().host !== '127.0.0.1'
535
+ return !isLoopback(ma)
520
536
  }).pop()
521
537
 
522
538
  if (linkLocalAddr == null) {
523
539
  continue
524
540
  }
525
541
 
526
- const linkLocalOptions = linkLocalAddr.toOptions()
542
+ const linkLocalOptions = getNetConfig(linkLocalAddr)
543
+
544
+ if (linkLocalOptions.port == null) {
545
+ return false
546
+ }
527
547
 
528
548
  // upgrade observed address to IP mapping
529
549
  this.observed.remove(ma)
530
550
  this.ipMappings.add(
531
551
  linkLocalOptions.host,
532
552
  linkLocalOptions.port,
533
- maOptions.host,
534
- maOptions.port,
535
- maOptions.transport
553
+ config.host,
554
+ config.port,
555
+ config.protocol
536
556
  )
537
557
 
538
558
  return true
@@ -1,6 +1,6 @@
1
1
  import { isIPv4 } from '@chainsafe/is-ip'
2
- import { trackedMap } from '@libp2p/utils/tracked-map'
3
- import { multiaddr, protocols } from '@multiformats/multiaddr'
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 tuples = ma.stringTuples()
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 === tuples[0][1]) {
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 tuples = ma.stringTuples()
76
- const host = tuples[0][1] ?? ''
77
- const protocol = tuples[1][0] === CODEC_TCP ? 'tcp' : 'udp'
78
- const port = parseInt(tuples[1][1] ?? '0')
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
- const tuples = ma.stringTuples()
107
- let tuple: string | undefined
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 ((tuples[0][0] === CODEC_IP4 || tuples[0][0] === CODEC_IP6) && tuples[1][0] === CODEC_TCP) {
111
- tuple = `${tuples[0][1]}-${tuples[1][1]}-tcp`
112
- } else if ((tuples[0][0] === CODEC_IP4 || tuples[0][0] === CODEC_IP6) && tuples[1][0] === CODEC_UDP) {
113
- tuple = `${tuples[0][1]}-${tuples[1][1]}-udp`
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 (tuple == null) {
126
+ if (key == null) {
117
127
  continue
118
128
  }
119
129
 
120
- const mappings = this.mappings.get(tuple)
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: 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
- const tuples = ma.stringTuples()
153
- const host = tuples[0][1]
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
- const tuples = ma.stringTuples()
173
- const host = tuples[0][1] ?? ''
174
- const protocol = tuples[1][0] === CODEC_TCP ? 'tcp' : 'udp'
175
- const port = parseInt(tuples[1][1] ?? '0')
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/multiaddr/is-link-local'
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/multiaddr/is-network-address'
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
- // only works for dns/ip based addresses
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
- return ma.toString()
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 { isPrivateIp } from '@libp2p/utils/private-ip'
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.
@@ -16,30 +13,17 @@ const CODEC_IP6 = 0x29
16
13
  * confusion.
17
14
  */
18
15
  export function connectionGater (gater: ConnectionGater = {}): ConnectionGater {
19
- return {
20
- denyDialPeer: async () => false,
21
- denyDialMultiaddr: async (multiaddr: Multiaddr) => {
16
+ if (gater.denyDialMultiaddr == null) {
17
+ gater.denyDialMultiaddr = (multiaddr: Multiaddr) => {
22
18
  // do not connect to insecure websockets by default
23
19
  if (WebSockets.matches(multiaddr)) {
24
- return false
20
+ return true
25
21
  }
26
22
 
27
- const tuples = multiaddr.stringTuples()
28
-
29
23
  // do not connect to private addresses by default
30
- if (tuples[0][0] === CODEC_IP4 || tuples[0][0] === CODEC_IP6) {
31
- return Boolean(isPrivateIp(`${tuples[0][1]}`))
32
- }
33
-
34
- return false
35
- },
36
- denyInboundConnection: async () => false,
37
- denyOutboundConnection: async () => false,
38
- denyInboundEncryptedConnection: async () => false,
39
- denyOutboundEncryptedConnection: async () => false,
40
- denyInboundUpgradedConnection: async () => false,
41
- denyOutboundUpgradedConnection: async () => false,
42
- filterMultiaddrForPeer: async () => true,
43
- ...gater
24
+ return isPrivate(multiaddr)
25
+ }
44
26
  }
27
+
28
+ return gater
45
29
  }