libp2p 2.3.1 → 2.4.0-5c4a79e5a

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 (69) hide show
  1. package/README.md +9 -25
  2. package/dist/index.min.js +18 -15
  3. package/dist/src/address-manager/dns-mappings.d.ts +20 -0
  4. package/dist/src/address-manager/dns-mappings.d.ts.map +1 -0
  5. package/dist/src/address-manager/dns-mappings.js +139 -0
  6. package/dist/src/address-manager/dns-mappings.js.map +1 -0
  7. package/dist/src/{address-manager.d.ts → address-manager/index.d.ts} +54 -10
  8. package/dist/src/address-manager/index.d.ts.map +1 -0
  9. package/dist/src/address-manager/index.js +264 -0
  10. package/dist/src/address-manager/index.js.map +1 -0
  11. package/dist/src/address-manager/ip-mappings.d.ts +18 -0
  12. package/dist/src/address-manager/ip-mappings.d.ts.map +1 -0
  13. package/dist/src/address-manager/ip-mappings.js +143 -0
  14. package/dist/src/address-manager/ip-mappings.js.map +1 -0
  15. package/dist/src/address-manager/observed-addresses.d.ts +19 -0
  16. package/dist/src/address-manager/observed-addresses.d.ts.map +1 -0
  17. package/dist/src/address-manager/observed-addresses.js +70 -0
  18. package/dist/src/address-manager/observed-addresses.js.map +1 -0
  19. package/dist/src/address-manager/transport-addresses.d.ts +19 -0
  20. package/dist/src/address-manager/transport-addresses.d.ts.map +1 -0
  21. package/dist/src/address-manager/transport-addresses.js +83 -0
  22. package/dist/src/address-manager/transport-addresses.js.map +1 -0
  23. package/dist/src/config/connection-gater.browser.d.ts +7 -3
  24. package/dist/src/config/connection-gater.browser.d.ts.map +1 -1
  25. package/dist/src/config/connection-gater.browser.js +16 -4
  26. package/dist/src/config/connection-gater.browser.js.map +1 -1
  27. package/dist/src/connection-manager/connection-pruner.d.ts.map +1 -1
  28. package/dist/src/connection-manager/connection-pruner.js +4 -3
  29. package/dist/src/connection-manager/connection-pruner.js.map +1 -1
  30. package/dist/src/connection-manager/dial-queue.d.ts +3 -3
  31. package/dist/src/connection-manager/dial-queue.d.ts.map +1 -1
  32. package/dist/src/connection-manager/dial-queue.js +6 -13
  33. package/dist/src/connection-manager/dial-queue.js.map +1 -1
  34. package/dist/src/connection-manager/index.d.ts +1 -0
  35. package/dist/src/connection-manager/index.d.ts.map +1 -1
  36. package/dist/src/connection-manager/index.js +10 -6
  37. package/dist/src/connection-manager/index.js.map +1 -1
  38. package/dist/src/connection-manager/utils.d.ts +13 -1
  39. package/dist/src/connection-manager/utils.d.ts.map +1 -1
  40. package/dist/src/connection-manager/utils.js +33 -1
  41. package/dist/src/connection-manager/utils.js.map +1 -1
  42. package/dist/src/index.d.ts +1 -1
  43. package/dist/src/index.d.ts.map +1 -1
  44. package/dist/src/libp2p.js +1 -1
  45. package/dist/src/libp2p.js.map +1 -1
  46. package/dist/src/version.d.ts +2 -2
  47. package/dist/src/version.d.ts.map +1 -1
  48. package/dist/src/version.js +2 -2
  49. package/dist/src/version.js.map +1 -1
  50. package/package.json +27 -25
  51. package/src/address-manager/dns-mappings.ts +182 -0
  52. package/src/address-manager/index.ts +413 -0
  53. package/src/address-manager/ip-mappings.ts +191 -0
  54. package/src/address-manager/observed-addresses.ts +94 -0
  55. package/src/address-manager/transport-addresses.ts +116 -0
  56. package/src/config/connection-gater.browser.ts +18 -4
  57. package/src/connection-manager/connection-pruner.ts +6 -4
  58. package/src/connection-manager/dial-queue.ts +12 -19
  59. package/src/connection-manager/index.ts +14 -8
  60. package/src/connection-manager/utils.ts +35 -2
  61. package/src/index.ts +1 -1
  62. package/src/libp2p.ts +1 -1
  63. package/src/version.ts +2 -2
  64. package/LICENSE +0 -4
  65. package/dist/src/address-manager.d.ts.map +0 -1
  66. package/dist/src/address-manager.js +0 -214
  67. package/dist/src/address-manager.js.map +0 -1
  68. package/dist/typedoc-urls.json +0 -19
  69. package/src/address-manager.ts +0 -319
@@ -0,0 +1,182 @@
1
+ import { isPrivateIp } from '@libp2p/utils/private-ip'
2
+ import { multiaddr, protocols } from '@multiformats/multiaddr'
3
+ import type { AddressManagerComponents, AddressManagerInit } from './index.js'
4
+ import type { Logger } from '@libp2p/interface'
5
+ import type { NodeAddress } from '@libp2p/interface-internal'
6
+ import type { Multiaddr, StringTuple } from '@multiformats/multiaddr'
7
+
8
+ const MAX_DATE = 8_640_000_000_000_000
9
+
10
+ export const defaultValues = {
11
+ maxObservedAddresses: 10
12
+ }
13
+
14
+ interface DNSMapping {
15
+ domain: string
16
+ verified: boolean
17
+ expires: number
18
+ lastVerified?: number
19
+ }
20
+
21
+ const CODEC_TLS = 0x01c0
22
+ const CODEC_SNI = 0x01c1
23
+ const CODEC_DNS = 0x35
24
+ const CODEC_DNS4 = 0x36
25
+ const CODEC_DNS6 = 0x37
26
+ const CODEC_DNSADDR = 0x38
27
+
28
+ export class DNSMappings {
29
+ private readonly log: Logger
30
+ private readonly mappings: Map<string, DNSMapping>
31
+
32
+ constructor (components: AddressManagerComponents, init: AddressManagerInit = {}) {
33
+ this.log = components.logger.forComponent('libp2p:address-manager:dns-mappings')
34
+ this.mappings = new Map()
35
+ }
36
+
37
+ has (ma: Multiaddr): boolean {
38
+ const host = this.findHost(ma)
39
+
40
+ for (const mapping of this.mappings.values()) {
41
+ if (mapping.domain === host) {
42
+ return true
43
+ }
44
+ }
45
+
46
+ return false
47
+ }
48
+
49
+ add (domain: string, addresses: string[]): void {
50
+ addresses.forEach(ip => {
51
+ this.log('add DNS mapping %s to %s', ip, domain)
52
+ // we are only confident if this is an local domain mapping, otherwise
53
+ // we will require external validation
54
+ const verified = isPrivateIp(ip) === true
55
+
56
+ this.mappings.set(ip, {
57
+ domain,
58
+ verified,
59
+ expires: verified ? MAX_DATE - Date.now() : 0,
60
+ lastVerified: verified ? MAX_DATE - Date.now() : undefined
61
+ })
62
+ })
63
+ }
64
+
65
+ remove (ma: Multiaddr): boolean {
66
+ const host = this.findHost(ma)
67
+ let wasConfident = false
68
+
69
+ for (const [ip, mapping] of this.mappings.entries()) {
70
+ if (mapping.domain === host) {
71
+ this.log('removing %s to %s DNS mapping %e', ip, mapping.domain, new Error('where'))
72
+ this.mappings.delete(ip)
73
+ wasConfident = wasConfident || mapping.verified
74
+ }
75
+ }
76
+
77
+ return wasConfident
78
+ }
79
+
80
+ getAll (addresses: NodeAddress[]): NodeAddress[] {
81
+ const dnsMappedAddresses: NodeAddress[] = []
82
+
83
+ for (let i = 0; i < addresses.length; i++) {
84
+ const address = addresses[i]
85
+ const tuples = address.multiaddr.stringTuples()
86
+ const host = tuples[0][1]
87
+
88
+ if (host == null) {
89
+ continue
90
+ }
91
+
92
+ for (const [ip, mapping] of this.mappings.entries()) {
93
+ if (host !== ip) {
94
+ continue
95
+ }
96
+
97
+ // insert SNI tuple after TLS tuple, if one is present
98
+ const mappedIp = this.maybeAddSNITuple(tuples, mapping.domain)
99
+
100
+ if (mappedIp) {
101
+ // remove the address and replace it with the version that includes
102
+ // the SNI tuple
103
+ addresses.splice(i, 1)
104
+ i--
105
+
106
+ dnsMappedAddresses.push({
107
+ multiaddr: multiaddr(`/${
108
+ tuples.map(tuple => {
109
+ return [
110
+ protocols(tuple[0]).name,
111
+ tuple[1]
112
+ ].join('/')
113
+ }).join('/')
114
+ }`),
115
+ verified: mapping.verified,
116
+ type: 'dns-mapping',
117
+ expires: mapping.expires,
118
+ lastVerified: mapping.lastVerified
119
+ })
120
+ }
121
+ }
122
+ }
123
+
124
+ return dnsMappedAddresses
125
+ }
126
+
127
+ private maybeAddSNITuple (tuples: StringTuple[], domain: string): boolean {
128
+ for (let j = 0; j < tuples.length; j++) {
129
+ if (tuples[j][0] === CODEC_TLS && tuples[j + 1]?.[0] !== CODEC_SNI) {
130
+ tuples.splice(j + 1, 0, [CODEC_SNI, domain])
131
+ return true
132
+ }
133
+ }
134
+
135
+ return false
136
+ }
137
+
138
+ confirm (ma: Multiaddr, ttl: number): boolean {
139
+ const host = this.findHost(ma)
140
+ let startingConfidence = false
141
+
142
+ for (const [ip, mapping] of this.mappings.entries()) {
143
+ if (mapping.domain === host) {
144
+ this.log('marking %s to %s DNS mapping as verified', ip, mapping.domain)
145
+ startingConfidence = mapping.verified
146
+ mapping.verified = true
147
+ mapping.expires = Date.now() + ttl
148
+ mapping.lastVerified = Date.now()
149
+ }
150
+ }
151
+
152
+ return startingConfidence
153
+ }
154
+
155
+ unconfirm (ma: Multiaddr, ttl: number): boolean {
156
+ const host = this.findHost(ma)
157
+ let wasConfident = false
158
+
159
+ for (const [ip, mapping] of this.mappings.entries()) {
160
+ if (mapping.domain === host) {
161
+ this.log('removing verification of %s to %s DNS mapping', ip, mapping.domain)
162
+ wasConfident = wasConfident || mapping.verified
163
+ mapping.verified = false
164
+ mapping.expires = Date.now() + ttl
165
+ }
166
+ }
167
+
168
+ return wasConfident
169
+ }
170
+
171
+ private findHost (ma: Multiaddr): string | undefined {
172
+ for (const tuple of ma.stringTuples()) {
173
+ if (tuple[0] === CODEC_SNI) {
174
+ return tuple[1]
175
+ }
176
+
177
+ if (tuple[0] === CODEC_DNS || tuple[0] === CODEC_DNS4 || tuple[0] === CODEC_DNS6 || tuple[0] === CODEC_DNSADDR) {
178
+ return tuple[1]
179
+ }
180
+ }
181
+ }
182
+ }
@@ -0,0 +1,413 @@
1
+ /* eslint-disable complexity */
2
+ import { isIPv4 } from '@chainsafe/is-ip'
3
+ import { peerIdFromString } from '@libp2p/peer-id'
4
+ import { debounce } from '@libp2p/utils/debounce'
5
+ import { createScalableCuckooFilter } from '@libp2p/utils/filters'
6
+ import { multiaddr } from '@multiformats/multiaddr'
7
+ import { DNSMappings } from './dns-mappings.js'
8
+ import { IPMappings } from './ip-mappings.js'
9
+ import { ObservedAddresses } from './observed-addresses.js'
10
+ import { TransportAddresses } from './transport-addresses.js'
11
+ import type { ComponentLogger, Libp2pEvents, Logger, TypedEventTarget, PeerId, PeerStore } from '@libp2p/interface'
12
+ import type { AddressManager as AddressManagerInterface, TransportManager, NodeAddress, ConfirmAddressOptions } from '@libp2p/interface-internal'
13
+ import type { Filter } from '@libp2p/utils/filters'
14
+ import type { Multiaddr } from '@multiformats/multiaddr'
15
+
16
+ const ONE_MINUTE = 60_000
17
+
18
+ export const defaultValues = {
19
+ maxObservedAddresses: 10,
20
+ addressVerificationTTL: ONE_MINUTE * 10,
21
+ addressVerificationRetry: ONE_MINUTE * 5
22
+ }
23
+
24
+ export interface AddressManagerInit {
25
+ /**
26
+ * Pass an function in this field to override the list of addresses
27
+ * that are announced to the network
28
+ */
29
+ announceFilter?: AddressFilter
30
+
31
+ /**
32
+ * A list of string multiaddrs to listen on
33
+ */
34
+ listen?: string[]
35
+
36
+ /**
37
+ * A list of string multiaddrs to use instead of those reported by transports
38
+ */
39
+ announce?: string[]
40
+
41
+ /**
42
+ * A list of string multiaddrs string to never announce
43
+ */
44
+ noAnnounce?: string[]
45
+
46
+ /**
47
+ * A list of string multiaddrs to add to the list of announced addresses
48
+ */
49
+ appendAnnounce?: string[]
50
+
51
+ /**
52
+ * Limits the number of observed addresses we will store
53
+ */
54
+ maxObservedAddresses?: number
55
+
56
+ /**
57
+ * How long before each public address should be reverified in ms.
58
+ *
59
+ * Requires `@libp2p/autonat` or some other verification method to be
60
+ * configured.
61
+ *
62
+ * @default 600_000
63
+ */
64
+ addressVerificationTTL?: number
65
+
66
+ /**
67
+ * After a transport or mapped address has failed to verify, how long to wait
68
+ * before retrying it in ms
69
+ *
70
+ * Requires `@libp2p/autonat` or some other verification method to be
71
+ * configured.
72
+ *
73
+ * @default 300_000
74
+ */
75
+ addressVerificationRetry?: number
76
+ }
77
+
78
+ export interface AddressManagerComponents {
79
+ peerId: PeerId
80
+ transportManager: TransportManager
81
+ peerStore: PeerStore
82
+ events: TypedEventTarget<Libp2pEvents>
83
+ logger: ComponentLogger
84
+ }
85
+
86
+ /**
87
+ * A function that takes a list of multiaddrs and returns a list
88
+ * to announce
89
+ */
90
+ export interface AddressFilter {
91
+ (addrs: Multiaddr[]): Multiaddr[]
92
+ }
93
+
94
+ const defaultAddressFilter = (addrs: Multiaddr[]): Multiaddr[] => addrs
95
+
96
+ /**
97
+ * If the passed multiaddr contains the passed peer id, remove it
98
+ */
99
+ function stripPeerId (ma: Multiaddr, peerId: PeerId): Multiaddr {
100
+ const observedPeerIdStr = ma.getPeerId()
101
+
102
+ // strip our peer id if it has been passed
103
+ if (observedPeerIdStr != null) {
104
+ const observedPeerId = peerIdFromString(observedPeerIdStr)
105
+
106
+ // use same encoding for comparison
107
+ if (observedPeerId.equals(peerId)) {
108
+ ma = ma.decapsulate(multiaddr(`/p2p/${peerId.toString()}`))
109
+ }
110
+ }
111
+
112
+ return ma
113
+ }
114
+
115
+ export class AddressManager implements AddressManagerInterface {
116
+ private readonly log: Logger
117
+ private readonly components: AddressManagerComponents
118
+ // this is an array to allow for duplicates, e.g. multiples of `/ip4/0.0.0.0/tcp/0`
119
+ private readonly listen: string[]
120
+ private readonly announce: Set<string>
121
+ private readonly appendAnnounce: Set<string>
122
+ private readonly announceFilter: AddressFilter
123
+ private readonly observed: ObservedAddresses
124
+ private readonly dnsMappings: DNSMappings
125
+ private readonly ipMappings: IPMappings
126
+ private readonly transportAddresses: TransportAddresses
127
+ private readonly observedAddressFilter: Filter
128
+ private readonly addressVerificationTTL: number
129
+ private readonly addressVerificationRetry: number
130
+
131
+ /**
132
+ * Responsible for managing the peer addresses.
133
+ * Peers can specify their listen and announce addresses.
134
+ * The listen addresses will be used by the libp2p transports to listen for new connections,
135
+ * while the announce addresses will be used for the peer addresses' to other peers in the network.
136
+ */
137
+ constructor (components: AddressManagerComponents, init: AddressManagerInit = {}) {
138
+ const { listen = [], announce = [], appendAnnounce = [] } = init
139
+
140
+ this.components = components
141
+ this.log = components.logger.forComponent('libp2p:address-manager')
142
+ this.listen = listen.map(ma => ma.toString())
143
+ this.announce = new Set(announce.map(ma => ma.toString()))
144
+ this.appendAnnounce = new Set(appendAnnounce.map(ma => ma.toString()))
145
+ this.observed = new ObservedAddresses(components, init)
146
+ this.dnsMappings = new DNSMappings(components, init)
147
+ this.ipMappings = new IPMappings(components, init)
148
+ this.transportAddresses = new TransportAddresses(components, init)
149
+ this.announceFilter = init.announceFilter ?? defaultAddressFilter
150
+ this.observedAddressFilter = createScalableCuckooFilter(1024)
151
+ this.addressVerificationTTL = init.addressVerificationTTL ?? defaultValues.addressVerificationTTL
152
+ this.addressVerificationRetry = init.addressVerificationRetry ?? defaultValues.addressVerificationRetry
153
+
154
+ // this method gets called repeatedly on startup when transports start listening so
155
+ // debounce it so we don't cause multiple self:peer:update events to be emitted
156
+ this._updatePeerStoreAddresses = debounce(this._updatePeerStoreAddresses.bind(this), 1000)
157
+
158
+ // update our stored addresses when new transports listen
159
+ components.events.addEventListener('transport:listening', () => {
160
+ this._updatePeerStoreAddresses()
161
+ })
162
+ // update our stored addresses when existing transports stop listening
163
+ components.events.addEventListener('transport:close', () => {
164
+ this._updatePeerStoreAddresses()
165
+ })
166
+ }
167
+
168
+ readonly [Symbol.toStringTag] = '@libp2p/address-manager'
169
+
170
+ _updatePeerStoreAddresses (): void {
171
+ // if announce addresses have been configured, ensure they make it into our peer
172
+ // record for things like identify
173
+ const addrs = this.getAddresses()
174
+ .map(ma => {
175
+ // strip our peer id if it is present
176
+ if (ma.getPeerId() === this.components.peerId.toString()) {
177
+ return ma.decapsulate(`/p2p/${this.components.peerId.toString()}`)
178
+ }
179
+
180
+ return ma
181
+ })
182
+
183
+ this.components.peerStore.patch(this.components.peerId, {
184
+ multiaddrs: addrs
185
+ })
186
+ .catch(err => {
187
+ this.log.error('error updating addresses', err)
188
+ })
189
+ }
190
+
191
+ /**
192
+ * Get peer listen multiaddrs
193
+ */
194
+ getListenAddrs (): Multiaddr[] {
195
+ return Array.from(this.listen).map((a) => multiaddr(a))
196
+ }
197
+
198
+ /**
199
+ * Get peer announcing multiaddrs
200
+ */
201
+ getAnnounceAddrs (): Multiaddr[] {
202
+ return Array.from(this.announce).map((a) => multiaddr(a))
203
+ }
204
+
205
+ /**
206
+ * Get peer announcing multiaddrs
207
+ */
208
+ getAppendAnnounceAddrs (): Multiaddr[] {
209
+ return Array.from(this.appendAnnounce).map((a) => multiaddr(a))
210
+ }
211
+
212
+ /**
213
+ * Get observed multiaddrs
214
+ */
215
+ getObservedAddrs (): Multiaddr[] {
216
+ return this.observed.getAll().map(addr => addr.multiaddr)
217
+ }
218
+
219
+ /**
220
+ * Add peer observed addresses
221
+ */
222
+ addObservedAddr (addr: Multiaddr): void {
223
+ const tuples = addr.stringTuples()
224
+ const socketAddress = `${tuples[0][1]}:${tuples[1][1]}`
225
+
226
+ // ignore if this address if it's been observed before
227
+ if (this.observedAddressFilter.has(socketAddress)) {
228
+ return
229
+ }
230
+
231
+ this.observedAddressFilter.add(socketAddress)
232
+
233
+ addr = stripPeerId(addr, this.components.peerId)
234
+
235
+ // ignore observed address if it is an IP mapping
236
+ if (this.ipMappings.has(addr)) {
237
+ return
238
+ }
239
+
240
+ // ignore observed address if it is a DNS mapping
241
+ if (this.dnsMappings.has(addr)) {
242
+ return
243
+ }
244
+
245
+ this.observed.add(addr)
246
+ }
247
+
248
+ confirmObservedAddr (addr: Multiaddr, options?: ConfirmAddressOptions): void {
249
+ addr = stripPeerId(addr, this.components.peerId)
250
+ let startingConfidence = true
251
+
252
+ if (options?.type === 'observed' || this.observed.has(addr)) {
253
+ startingConfidence = this.observed.confirm(addr, options?.ttl ?? this.addressVerificationTTL)
254
+ }
255
+
256
+ if (options?.type === 'transport' || this.transportAddresses.has(addr)) {
257
+ startingConfidence = this.transportAddresses.confirm(addr, options?.ttl ?? this.addressVerificationTTL)
258
+ }
259
+
260
+ if (options?.type === 'dns-mapping' || this.dnsMappings.has(addr)) {
261
+ startingConfidence = this.dnsMappings.confirm(addr, options?.ttl ?? this.addressVerificationTTL)
262
+ }
263
+
264
+ if (options?.type === 'ip-mapping' || this.ipMappings.has(addr)) {
265
+ startingConfidence = this.ipMappings.confirm(addr, options?.ttl ?? this.addressVerificationTTL)
266
+ }
267
+
268
+ // only trigger the 'self:peer:update' event if our confidence in an address has changed
269
+ if (!startingConfidence) {
270
+ this._updatePeerStoreAddresses()
271
+ }
272
+ }
273
+
274
+ removeObservedAddr (addr: Multiaddr, options?: ConfirmAddressOptions): void {
275
+ addr = stripPeerId(addr, this.components.peerId)
276
+
277
+ let startingConfidence = false
278
+
279
+ if (this.observed.has(addr)) {
280
+ startingConfidence = this.observed.remove(addr)
281
+ }
282
+
283
+ if (this.transportAddresses.has(addr)) {
284
+ startingConfidence = this.transportAddresses.unconfirm(addr, options?.ttl ?? this.addressVerificationRetry)
285
+ }
286
+
287
+ if (this.dnsMappings.has(addr)) {
288
+ startingConfidence = this.dnsMappings.unconfirm(addr, options?.ttl ?? this.addressVerificationRetry)
289
+ }
290
+
291
+ if (this.ipMappings.has(addr)) {
292
+ startingConfidence = this.ipMappings.unconfirm(addr, options?.ttl ?? this.addressVerificationRetry)
293
+ }
294
+
295
+ // only trigger the 'self:peer:update' event if our confidence in an address has changed
296
+ if (startingConfidence) {
297
+ this._updatePeerStoreAddresses()
298
+ }
299
+ }
300
+
301
+ getAddresses (): Multiaddr[] {
302
+ const addresses = new Set<string>()
303
+
304
+ const multiaddrs = this.getAddressesWithMetadata()
305
+ .filter(addr => {
306
+ if (!addr.verified) {
307
+ return false
308
+ }
309
+
310
+ const maStr = addr.multiaddr.toString()
311
+
312
+ if (addresses.has(maStr)) {
313
+ return false
314
+ }
315
+
316
+ addresses.add(maStr)
317
+
318
+ return true
319
+ })
320
+ .map(address => address.multiaddr)
321
+
322
+ // filter addressees before returning
323
+ return this.announceFilter(
324
+ multiaddrs.map(str => {
325
+ const ma = multiaddr(str)
326
+
327
+ // do not append our peer id to a path multiaddr as it will become invalid
328
+ if (ma.protos().pop()?.path === true) {
329
+ return ma
330
+ }
331
+
332
+ if (ma.getPeerId() === this.components.peerId.toString()) {
333
+ return ma
334
+ }
335
+
336
+ return ma.encapsulate(`/p2p/${this.components.peerId.toString()}`)
337
+ })
338
+ )
339
+ }
340
+
341
+ getAddressesWithMetadata (): NodeAddress[] {
342
+ const announceMultiaddrs = this.getAnnounceAddrs()
343
+
344
+ if (announceMultiaddrs.length > 0) {
345
+ return announceMultiaddrs.map(multiaddr => ({
346
+ multiaddr,
347
+ verified: true,
348
+ type: 'announce',
349
+ expires: Date.now() + this.addressVerificationTTL,
350
+ lastVerified: Date.now()
351
+ }))
352
+ }
353
+
354
+ let addresses: NodeAddress[] = []
355
+
356
+ // add transport addresses
357
+ addresses = addresses.concat(
358
+ this.components.transportManager.getAddrs()
359
+ .map(multiaddr => this.transportAddresses.get(multiaddr, this.addressVerificationTTL))
360
+ )
361
+
362
+ // add append announce addresses
363
+ addresses = addresses.concat(
364
+ this.getAppendAnnounceAddrs().map(multiaddr => ({
365
+ multiaddr,
366
+ verified: true,
367
+ type: 'announce',
368
+ expires: Date.now() + this.addressVerificationTTL,
369
+ lastVerified: Date.now()
370
+ }))
371
+ )
372
+
373
+ // add observed addresses
374
+ addresses = addresses.concat(
375
+ this.observed.getAll()
376
+ )
377
+
378
+ // add ip mapped addresses
379
+ addresses = addresses.concat(
380
+ this.ipMappings.getAll(addresses)
381
+ )
382
+
383
+ // add ip->domain mappings, must be done after IP mappings
384
+ addresses = addresses.concat(
385
+ this.dnsMappings.getAll(addresses)
386
+ )
387
+
388
+ return addresses
389
+ }
390
+
391
+ addDNSMapping (domain: string, addresses: string[]): void {
392
+ this.dnsMappings.add(domain, addresses)
393
+ }
394
+
395
+ removeDNSMapping (domain: string): void {
396
+ if (this.dnsMappings.remove(multiaddr(`/dns/${domain}`))) {
397
+ this._updatePeerStoreAddresses()
398
+ }
399
+ }
400
+
401
+ addPublicAddressMapping (internalIp: string, internalPort: number, externalIp: string, externalPort: number = internalPort, protocol: 'tcp' | 'udp' = 'tcp'): void {
402
+ this.ipMappings.add(internalIp, internalPort, externalIp, externalPort, protocol)
403
+
404
+ // remove duplicate observed addresses
405
+ this.observed.removePrefixed(`/ip${isIPv4(externalIp) ? 4 : 6}/${externalIp}/${protocol}/${externalPort}`)
406
+ }
407
+
408
+ removePublicAddressMapping (internalIp: string, internalPort: number, externalIp: string, externalPort: number = internalPort, protocol: 'tcp' | 'udp' = 'tcp'): void {
409
+ if (this.ipMappings.remove(multiaddr(`/ip${isIPv4(externalIp) ? 4 : 6}/${externalIp}/${protocol}/${externalPort}`))) {
410
+ this._updatePeerStoreAddresses()
411
+ }
412
+ }
413
+ }