mirror of
https://github.com/fluencelabs/js-libp2p
synced 2025-04-25 02:22:14 +00:00
fix: do not allow dial to large number of multiaddrs (#954)
This commit is contained in:
parent
13cf476148
commit
af723b355e
@ -525,6 +525,7 @@ Dialing in libp2p can be configured to limit the rate of dialing, and how long d
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| maxParallelDials | `number` | How many multiaddrs we can dial in parallel. |
|
||||
| maxAddrsToDial | `number` | How many multiaddrs is the dial allowed to dial for a single peer. |
|
||||
| maxDialsPerPeer | `number` | How many multiaddrs we can dial per peer, in parallel. |
|
||||
| dialTimeout | `number` | Second dial timeout per peer in ms. |
|
||||
| resolvers | `object` | Dial [Resolvers](https://github.com/multiformats/js-multiaddr/blob/master/src/resolvers/index.js) for resolving multiaddrs |
|
||||
@ -549,6 +550,7 @@ const node = await Libp2p.create({
|
||||
},
|
||||
dialer: {
|
||||
maxParallelDials: 100,
|
||||
maxAddrsToDial: 25,
|
||||
maxDialsPerPeer: 4,
|
||||
dialTimeout: 30e3,
|
||||
resolvers: {
|
||||
|
@ -4,6 +4,7 @@ module.exports = {
|
||||
DIAL_TIMEOUT: 30e3, // How long in ms a dial attempt is allowed to take
|
||||
MAX_PARALLEL_DIALS: 100, // Maximum allowed concurrent dials
|
||||
MAX_PER_PEER_DIALS: 4, // Allowed parallel dials per DialRequest
|
||||
MAX_ADDRS_TO_DIAL: 25, // Maximum number of allowed addresses to attempt to dial
|
||||
METRICS: {
|
||||
computeThrottleMaxQueueSize: 1000,
|
||||
computeThrottleTimeout: 2000,
|
||||
|
@ -19,7 +19,8 @@ const { codes } = require('../errors')
|
||||
const {
|
||||
DIAL_TIMEOUT,
|
||||
MAX_PARALLEL_DIALS,
|
||||
MAX_PER_PEER_DIALS
|
||||
MAX_PER_PEER_DIALS,
|
||||
MAX_ADDRS_TO_DIAL
|
||||
} = require('../constants')
|
||||
|
||||
/**
|
||||
@ -40,6 +41,7 @@ const {
|
||||
* @typedef {Object} DialerOptions
|
||||
* @property {(addresses: Address[]) => Address[]} [options.addressSorter = publicAddressesFirst] - Sort the known addresses of a peer before trying to dial.
|
||||
* @property {number} [maxParallelDials = MAX_PARALLEL_DIALS] - Number of max concurrent dials.
|
||||
* @property {number} [maxAddrsToDial = MAX_ADDRS_TO_DIAL] - Number of max addresses to dial for a given peer.
|
||||
* @property {number} [maxDialsPerPeer = MAX_PER_PEER_DIALS] - Number of max concurrent dials per peer.
|
||||
* @property {number} [dialTimeout = DIAL_TIMEOUT] - How long a dial attempt is allowed to take.
|
||||
* @property {Record<string, Resolver>} [resolvers = {}] - multiaddr resolvers to use when dialing
|
||||
@ -65,6 +67,7 @@ class Dialer {
|
||||
peerStore,
|
||||
addressSorter = publicAddressesFirst,
|
||||
maxParallelDials = MAX_PARALLEL_DIALS,
|
||||
maxAddrsToDial = MAX_ADDRS_TO_DIAL,
|
||||
dialTimeout = DIAL_TIMEOUT,
|
||||
maxDialsPerPeer = MAX_PER_PEER_DIALS,
|
||||
resolvers = {}
|
||||
@ -73,6 +76,7 @@ class Dialer {
|
||||
this.peerStore = peerStore
|
||||
this.addressSorter = addressSorter
|
||||
this.maxParallelDials = maxParallelDials
|
||||
this.maxAddrsToDial = maxAddrsToDial
|
||||
this.timeout = dialTimeout
|
||||
this.maxDialsPerPeer = maxDialsPerPeer
|
||||
this.tokens = [...new Array(maxParallelDials)].map((_, index) => index)
|
||||
@ -198,6 +202,11 @@ class Dialer {
|
||||
// Multiaddrs not supported by the available transports will be filtered out.
|
||||
const supportedAddrs = addrs.filter(a => this.transportManager.transportForMultiaddr(a))
|
||||
|
||||
if (supportedAddrs.length > this.maxAddrsToDial) {
|
||||
this.peerStore.delete(id)
|
||||
throw errCode(new Error('dial with more addresses than allowed'), codes.ERR_TOO_MANY_ADDRESSES)
|
||||
}
|
||||
|
||||
return {
|
||||
id: id.toB58String(),
|
||||
addrs: supportedAddrs
|
||||
|
@ -16,6 +16,7 @@ exports.codes = {
|
||||
ERR_CONNECTION_FAILED: 'ERR_CONNECTION_FAILED',
|
||||
ERR_NODE_NOT_STARTED: 'ERR_NODE_NOT_STARTED',
|
||||
ERR_ALREADY_ABORTED: 'ERR_ALREADY_ABORTED',
|
||||
ERR_TOO_MANY_ADDRESSES: 'ERR_TOO_MANY_ADDRESSES',
|
||||
ERR_NO_VALID_ADDRESSES: 'ERR_NO_VALID_ADDRESSES',
|
||||
ERR_RELAYED_DIAL: 'ERR_RELAYED_DIAL',
|
||||
ERR_DIALED_SELF: 'ERR_DIALED_SELF',
|
||||
|
@ -177,6 +177,26 @@ describe('Dialing (direct, WebSockets)', () => {
|
||||
.and.to.have.property('code', ErrorCodes.ERR_TIMEOUT)
|
||||
})
|
||||
|
||||
it('should throw when a peer advertises more than the allowed number of peers', async () => {
|
||||
const spy = sinon.spy()
|
||||
const dialer = new Dialer({
|
||||
transportManager: localTM,
|
||||
maxAddrsToDial: 10,
|
||||
peerStore: {
|
||||
delete: spy,
|
||||
addressBook: {
|
||||
add: () => { },
|
||||
getMultiaddrsForPeer: () => Array.from({ length: 11 }, (_, i) => new Multiaddr(`/ip4/127.0.0.1/tcp/1500${i}/ws/p2p/12D3KooWHFKTMzwerBtsVmtz4ZZEQy2heafxzWw6wNn5PPYkBxJ5`))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
await expect(dialer.connectToPeer(remoteAddr))
|
||||
.to.eventually.be.rejected()
|
||||
.and.to.have.property('code', ErrorCodes.ERR_TOO_MANY_ADDRESSES)
|
||||
expect(spy.calledOnce).to.be.true()
|
||||
})
|
||||
|
||||
it('should sort addresses on dial', async () => {
|
||||
const peerMultiaddrs = [
|
||||
new Multiaddr('/ip4/127.0.0.1/tcp/15001/ws'),
|
||||
|
Loading…
x
Reference in New Issue
Block a user