Skip to content

Commit

Permalink
fix: limit observed addresses in address manager
Browse files Browse the repository at this point in the history
This is done in the identify protocol but the address manager
should guard itself against misuse.
  • Loading branch information
achingbrain committed Nov 30, 2024
1 parent 99f5f27 commit 9a75560
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 0 deletions.
15 changes: 15 additions & 0 deletions packages/libp2p/src/address-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import type { ComponentLogger, Libp2pEvents, Logger, TypedEventTarget, PeerId, P
import type { AddressManager as AddressManagerInterface, TransportManager } from '@libp2p/interface-internal'
import type { Multiaddr } from '@multiformats/multiaddr'

export const defaultValues = {
maxObservedAddresses: 10
}

export interface AddressManagerInit {
/**
* Pass an function in this field to override the list of addresses
Expand All @@ -32,6 +36,11 @@ export interface AddressManagerInit {
* A list of string multiaddrs to add to the list of announced addresses
*/
appendAnnounce?: string[]

/**
* Limits the number of observed addresses we will store
*/
maxObservedAddresses?: number
}

export interface AddressManagerComponents {
Expand Down Expand Up @@ -103,6 +112,7 @@ export class AddressManager implements AddressManagerInterface {
private readonly announceFilter: AddressFilter
private readonly ipDomainMappings: Map<string, DNSMapping>
private readonly publicAddressMappings: Map<string, PublicAddressMapping[]>
private readonly maxObservedAddresses: number

/**
* Responsible for managing the peer addresses.
Expand All @@ -122,6 +132,7 @@ export class AddressManager implements AddressManagerInterface {
this.ipDomainMappings = new Map()
this.publicAddressMappings = new Map()
this.announceFilter = init.announceFilter ?? defaultAddressFilter
this.maxObservedAddresses = init.maxObservedAddresses ?? defaultValues.maxObservedAddresses

// this method gets called repeatedly on startup when transports start listening so
// debounce it so we don't cause multiple self:peer:update events to be emitted
Expand Down Expand Up @@ -192,6 +203,10 @@ export class AddressManager implements AddressManagerInterface {
* Add peer observed addresses
*/
addObservedAddr (addr: Multiaddr): void {
if (this.observed.size === this.maxObservedAddresses) {
return
}

addr = stripPeerId(addr, this.components.peerId)
const addrString = addr.toString()

Expand Down
20 changes: 20 additions & 0 deletions packages/libp2p/test/addresses/address-manager.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,26 @@ describe('Address Manager', () => {
expect(am.getObservedAddrs()).to.have.lengthOf(1)
})

it('should limit observed addresses', () => {
const am = new AddressManager({
peerId,
transportManager: stubInterface<TransportManager>(),
peerStore,
events,
logger: defaultLogger()
}, {
announceFilter: stubInterface<AddressFilter>()
})

expect(am.getObservedAddrs()).to.be.empty()

for (let i = 0; i < 100; i++) {
am.addObservedAddr(multiaddr(`/ip4/123.123.123.123/tcp/392${i}`))
}

expect(am.getObservedAddrs()).to.have.lengthOf(10)
})

it('should allow duplicate listen addresses', () => {
const ma = multiaddr('/ip4/0.0.0.0/tcp/0')
const am = new AddressManager({
Expand Down

0 comments on commit 9a75560

Please sign in to comment.