Comparing version 2.3.1-0862522fe to 2.3.1-2c182d2e2
@@ -50,2 +50,3 @@ import type { ComponentLogger, Libp2pEvents, TypedEventTarget, PeerId, PeerStore } from '@libp2p/interface'; | ||
private readonly ipDomainMappings; | ||
private readonly publicAddressMappings; | ||
/** | ||
@@ -85,3 +86,5 @@ * Responsible for managing the peer addresses. | ||
removeDNSMapping(domain: string): void; | ||
addPublicAddressMapping(internalIp: string, internalPort: number, externalIp: string, externalPort?: number, protocol?: 'tcp' | 'udp'): void; | ||
removePublicAddressMapping(internalIp: string, internalPort: number, externalIp: string, externalPort?: number, protocol?: 'tcp' | 'udp'): void; | ||
} | ||
//# sourceMappingURL=address-manager.d.ts.map |
@@ -0,1 +1,2 @@ | ||
import { isIPv4 } from '@chainsafe/is-ip'; | ||
import { peerIdFromString } from '@libp2p/peer-id'; | ||
@@ -24,2 +25,4 @@ import { debounce } from '@libp2p/utils/debounce'; | ||
const CODEC_DNS6 = 0x37; | ||
const CODEC_TCP = 0x06; | ||
const CODEC_UDP = 0x0111; | ||
export class AddressManager { | ||
@@ -35,2 +38,3 @@ log; | ||
ipDomainMappings; | ||
publicAddressMappings; | ||
/** | ||
@@ -51,2 +55,3 @@ * Responsible for managing the peer addresses. | ||
this.ipDomainMappings = new Map(); | ||
this.publicAddressMappings = new Map(); | ||
this.announceFilter = init.announceFilter ?? defaultAddressFilter; | ||
@@ -69,7 +74,4 @@ // this method gets called repeatedly on startup when transports start listening so | ||
// record for things like identify | ||
const addrs = this.getAnnounceAddrs() | ||
.concat(this.components.transportManager.getAddrs()) | ||
.concat([...this.observed.entries()] | ||
.filter(([_, metadata]) => metadata.confident) | ||
.map(([str]) => multiaddr(str))).map(ma => { | ||
const addrs = this.getAddresses() | ||
.map(ma => { | ||
// strip our peer id if it is present | ||
@@ -84,3 +86,5 @@ if (ma.getPeerId() === this.components.peerId.toString()) { | ||
}) | ||
.catch(err => { this.log.error('error updating addresses', err); }); | ||
.catch(err => { | ||
this.log.error('error updating addresses', err); | ||
}); | ||
} | ||
@@ -159,8 +163,43 @@ /** | ||
.map(([ma]) => multiaddr(ma))); | ||
const mappedMultiaddrs = []; | ||
// add public addresses | ||
const ipMappedMultiaddrs = []; | ||
multiaddrs.forEach(ma => { | ||
const tuples = ma.stringTuples(); | ||
let tuple; | ||
// see if the internal host/port/protocol tuple has been mapped externally | ||
if ((tuples[0][0] === CODEC_IP4 || tuples[0][0] === CODEC_IP6) && tuples[1][0] === CODEC_TCP) { | ||
tuple = `${tuples[0][1]}-${tuples[1][1]}-tcp`; | ||
} | ||
else if ((tuples[0][0] === CODEC_IP4 || tuples[0][0] === CODEC_IP6) && tuples[1][0] === CODEC_UDP) { | ||
tuple = `${tuples[0][1]}-${tuples[1][1]}-udp`; | ||
} | ||
if (tuple == null) { | ||
return; | ||
} | ||
const mappings = this.publicAddressMappings.get(tuple); | ||
if (mappings == null) { | ||
return; | ||
} | ||
for (const mapping of mappings) { | ||
tuples[0][0] = isIPv4(mapping.externalIp) ? CODEC_IP4 : CODEC_IP6; | ||
tuples[0][1] = mapping.externalIp; | ||
tuples[1][1] = `${mapping.externalPort}`; | ||
ipMappedMultiaddrs.push(multiaddr(`/${tuples.map(tuple => { | ||
return [ | ||
protocols(tuple[0]).name, | ||
tuple[1] | ||
].join('/'); | ||
}).join('/')}`)); | ||
} | ||
}); | ||
multiaddrs = multiaddrs.concat(ipMappedMultiaddrs); | ||
// add ip->domain mappings | ||
const dnsMappedMultiaddrs = []; | ||
for (const ma of multiaddrs) { | ||
const tuples = [...ma.stringTuples()]; | ||
const tuples = ma.stringTuples(); | ||
let mappedIp = false; | ||
for (const [ip, domain] of this.ipDomainMappings.entries()) { | ||
for (const [ip, mapping] of this.ipDomainMappings.entries()) { | ||
if (!mapping.confident) { | ||
continue; | ||
} | ||
for (let i = 0; i < tuples.length; i++) { | ||
@@ -172,3 +211,3 @@ if (tuples[i][1] !== ip) { | ||
tuples[i][0] = CODEC_DNS4; | ||
tuples[i][1] = domain; | ||
tuples[i][1] = mapping.domain; | ||
mappedIp = true; | ||
@@ -178,3 +217,3 @@ } | ||
tuples[i][0] = CODEC_DNS6; | ||
tuples[i][1] = domain; | ||
tuples[i][1] = mapping.domain; | ||
mappedIp = true; | ||
@@ -185,3 +224,3 @@ } | ||
if (mappedIp) { | ||
mappedMultiaddrs.push(multiaddr(`/${tuples.map(tuple => { | ||
dnsMappedMultiaddrs.push(multiaddr(`/${tuples.map(tuple => { | ||
return [ | ||
@@ -194,3 +233,3 @@ protocols(tuple[0]).name, | ||
} | ||
multiaddrs = multiaddrs.concat(mappedMultiaddrs); | ||
multiaddrs = multiaddrs.concat(dnsMappedMultiaddrs); | ||
// dedupe multiaddrs | ||
@@ -222,13 +261,55 @@ const addrSet = new Set(); | ||
addresses.forEach(ip => { | ||
this.ipDomainMappings.set(ip, domain); | ||
this.log('add DNS mapping %s to %s', ip, domain); | ||
// check ip/public ip mappings to see if we think we are contactable | ||
const confident = [...this.publicAddressMappings.entries()].some(([key, mappings]) => { | ||
return mappings.some(mapping => mapping.externalIp === ip); | ||
}); | ||
this.ipDomainMappings.set(ip, { | ||
domain, | ||
confident | ||
}); | ||
}); | ||
this._updatePeerStoreAddresses(); | ||
} | ||
removeDNSMapping(domain) { | ||
for (const [key, value] of this.ipDomainMappings.entries()) { | ||
if (value === domain) { | ||
for (const [key, mapping] of this.ipDomainMappings.entries()) { | ||
if (mapping.domain === domain) { | ||
this.log('remove DNS mapping for %s', domain); | ||
this.ipDomainMappings.delete(key); | ||
} | ||
} | ||
this._updatePeerStoreAddresses(); | ||
} | ||
addPublicAddressMapping(internalIp, internalPort, externalIp, externalPort = internalPort, protocol = 'tcp') { | ||
const key = `${internalIp}-${internalPort}-${protocol}`; | ||
const mappings = this.publicAddressMappings.get(key) ?? []; | ||
mappings.push({ | ||
externalIp, | ||
externalPort | ||
}); | ||
this.publicAddressMappings.set(key, mappings); | ||
// update domain mappings to indicate we are now confident that any matching | ||
// ip/domain combination can now be resolved externally | ||
for (const [key, mapping] of this.ipDomainMappings.entries()) { | ||
if (key === externalIp) { | ||
mapping.confident = true; | ||
this.ipDomainMappings.set(key, mapping); | ||
} | ||
} | ||
this._updatePeerStoreAddresses(); | ||
} | ||
removePublicAddressMapping(internalIp, internalPort, externalIp, externalPort = internalPort, protocol = 'tcp') { | ||
const key = `${internalIp}-${internalPort}-${protocol}`; | ||
const mappings = (this.publicAddressMappings.get(key) ?? []).filter(mapping => { | ||
return mapping.externalIp !== externalIp && mapping.externalPort !== externalPort; | ||
}); | ||
if (mappings.length === 0) { | ||
this.publicAddressMappings.delete(key); | ||
} | ||
else { | ||
this.publicAddressMappings.set(key, mappings); | ||
} | ||
this._updatePeerStoreAddresses(); | ||
} | ||
} | ||
//# sourceMappingURL=address-manager.js.map |
import type { ConnectionGater } from '@libp2p/interface'; | ||
/** | ||
* Returns a connection gater that disallows dialling private addresses by | ||
* default. Browsers are severely limited in their resource usage so don't | ||
* waste time trying to dial undiallable addresses. | ||
* Returns a connection gater that disallows dialling private addresses or | ||
* insecure websockets by default. | ||
* | ||
* Browsers are severely limited in their resource usage so don't waste time | ||
* trying to dial undiallable addresses, and they also print verbose error | ||
* messages when making connections over insecure transports which causes | ||
* confusion. | ||
*/ | ||
export declare function connectionGater(gater?: ConnectionGater): ConnectionGater; | ||
//# sourceMappingURL=connection-gater.browser.d.ts.map |
import { isPrivateIp } from '@libp2p/utils/private-ip'; | ||
import { WebSockets } from '@multiformats/multiaddr-matcher'; | ||
const CODEC_IP4 = 0x04; | ||
const CODEC_IP6 = 0x29; | ||
/** | ||
* Returns a connection gater that disallows dialling private addresses by | ||
* default. Browsers are severely limited in their resource usage so don't | ||
* waste time trying to dial undiallable addresses. | ||
* Returns a connection gater that disallows dialling private addresses or | ||
* insecure websockets by default. | ||
* | ||
* Browsers are severely limited in their resource usage so don't waste time | ||
* trying to dial undiallable addresses, and they also print verbose error | ||
* messages when making connections over insecure transports which causes | ||
* confusion. | ||
*/ | ||
@@ -11,4 +18,9 @@ export function connectionGater(gater = {}) { | ||
denyDialMultiaddr: async (multiaddr) => { | ||
// do not connect to insecure websockets by default | ||
if (WebSockets.matches(multiaddr)) { | ||
return false; | ||
} | ||
const tuples = multiaddr.stringTuples(); | ||
if (tuples[0][0] === 4 || tuples[0][0] === 41) { | ||
// do not connect to private addresses by default | ||
if (tuples[0][0] === CODEC_IP4 || tuples[0][0] === CODEC_IP6) { | ||
return Boolean(isPrivateIp(`${tuples[0][1]}`)); | ||
@@ -15,0 +27,0 @@ } |
import { PeerMap } from '@libp2p/peer-collections'; | ||
import { PriorityQueue, type PriorityQueueJobOptions } from '@libp2p/utils/priority-queue'; | ||
import { type Multiaddr, type Resolver } from '@multiformats/multiaddr'; | ||
import { PriorityQueue } from '@libp2p/utils/priority-queue'; | ||
import type { AddressSorter, ComponentLogger, Connection, ConnectionGater, Metrics, PeerId, PeerStore, PeerRouting, IsDialableOptions, OpenConnectionProgressEvents } from '@libp2p/interface'; | ||
import type { OpenConnectionOptions, TransportManager } from '@libp2p/interface-internal'; | ||
import type { PriorityQueueJobOptions } from '@libp2p/utils/priority-queue'; | ||
import type { DNS } from '@multiformats/dns'; | ||
import type { Multiaddr, Resolver } from '@multiformats/multiaddr'; | ||
import type { ProgressOptions } from 'progress-events'; | ||
@@ -64,3 +65,2 @@ export interface PendingDialTarget { | ||
dial(peerIdOrMultiaddr: PeerId | Multiaddr | Multiaddr[], options?: OpenConnectionOptions): Promise<Connection>; | ||
private createDialAbortController; | ||
private calculateMultiaddrs; | ||
@@ -67,0 +67,0 @@ isDialable(multiaddr: Multiaddr | Multiaddr[], options?: IsDialableOptions): Promise<boolean>; |
@@ -141,3 +141,7 @@ /* eslint-disable max-depth */ | ||
// we may be about to resolve a dns addr which can time out | ||
const signal = this.createDialAbortController(options?.signal); | ||
const signal = anySignal([ | ||
this.shutDownController.signal, | ||
options.signal | ||
]); | ||
setMaxListeners(Infinity, signal); | ||
let addrsToDial; | ||
@@ -226,17 +230,6 @@ try { | ||
multiaddrs: new Set(multiaddrs.map(ma => ma.toString())), | ||
signal: options.signal, | ||
signal: options.signal ?? AbortSignal.timeout(this.dialTimeout), | ||
onProgress: options.onProgress | ||
}); | ||
} | ||
createDialAbortController(userSignal) { | ||
// let any signal abort the dial | ||
const signal = anySignal([ | ||
AbortSignal.timeout(this.dialTimeout), | ||
this.shutDownController.signal, | ||
userSignal | ||
]); | ||
// This emitter gets listened to a lot | ||
setMaxListeners(Infinity, signal); | ||
return signal; | ||
} | ||
// eslint-disable-next-line complexity | ||
@@ -243,0 +236,0 @@ async calculateMultiaddrs(peerId, multiaddrs = new Set(), options = {}) { |
@@ -1,3 +0,3 @@ | ||
export declare const version = "2.3.1-0862522fe"; | ||
export declare const name = "libp2p"; | ||
export declare const version = "2.3.1-2c182d2e2"; | ||
export declare const name = "js-libp2p"; | ||
//# sourceMappingURL=version.d.ts.map |
@@ -1,3 +0,3 @@ | ||
export const version = '2.3.1-0862522fe'; | ||
export const name = 'libp2p'; | ||
export const version = '2.3.1-2c182d2e2'; | ||
export const name = 'js-libp2p'; | ||
//# sourceMappingURL=version.js.map |
{ | ||
"name": "libp2p", | ||
"version": "2.3.1-0862522fe", | ||
"version": "2.3.1-2c182d2e2", | ||
"description": "JavaScript implementation of libp2p, a modular peer to peer network stack", | ||
@@ -88,31 +88,32 @@ "license": "Apache-2.0 OR MIT", | ||
"dependencies": { | ||
"@libp2p/crypto": "5.0.7-0862522fe", | ||
"@libp2p/interface": "2.2.1-0862522fe", | ||
"@libp2p/interface-internal": "2.1.1-0862522fe", | ||
"@libp2p/logger": "5.1.4-0862522fe", | ||
"@libp2p/multistream-select": "6.0.9-0862522fe", | ||
"@libp2p/peer-collections": "6.0.12-0862522fe", | ||
"@libp2p/peer-id": "5.0.8-0862522fe", | ||
"@libp2p/peer-store": "11.0.12-0862522fe", | ||
"@libp2p/utils": "6.2.1-0862522fe", | ||
"@chainsafe/is-ip": "^2.0.2", | ||
"@libp2p/crypto": "5.0.7-2c182d2e2", | ||
"@libp2p/interface": "2.2.1-2c182d2e2", | ||
"@libp2p/interface-internal": "2.1.1-2c182d2e2", | ||
"@libp2p/logger": "5.1.4-2c182d2e2", | ||
"@libp2p/multistream-select": "6.0.9-2c182d2e2", | ||
"@libp2p/peer-collections": "6.0.12-2c182d2e2", | ||
"@libp2p/peer-id": "5.0.8-2c182d2e2", | ||
"@libp2p/peer-store": "11.0.12-2c182d2e2", | ||
"@libp2p/utils": "6.2.1-2c182d2e2", | ||
"@multiformats/dns": "^1.0.6", | ||
"@multiformats/multiaddr": "^12.2.3", | ||
"@multiformats/multiaddr-matcher": "^1.2.1", | ||
"@multiformats/multiaddr": "^12.3.3", | ||
"@multiformats/multiaddr-matcher": "^1.6.0", | ||
"any-signal": "^4.1.1", | ||
"datastore-core": "^10.0.0", | ||
"interface-datastore": "^8.3.0", | ||
"it-byte-stream": "^1.0.12", | ||
"datastore-core": "^10.0.2", | ||
"interface-datastore": "^8.3.1", | ||
"it-byte-stream": "^1.1.0", | ||
"it-merge": "^3.0.5", | ||
"it-parallel": "^3.0.7", | ||
"it-parallel": "^3.0.8", | ||
"merge-options": "^3.0.4", | ||
"multiformats": "^13.1.0", | ||
"multiformats": "^13.3.1", | ||
"p-defer": "^4.0.1", | ||
"p-retry": "^6.2.0", | ||
"progress-events": "^1.0.0", | ||
"p-retry": "^6.2.1", | ||
"progress-events": "^1.0.1", | ||
"race-event": "^1.3.0", | ||
"race-signal": "^1.0.2", | ||
"race-signal": "^1.1.0", | ||
"uint8arrays": "^5.1.0" | ||
}, | ||
"devDependencies": { | ||
"aegir": "^44.0.1", | ||
"aegir": "^45.0.5", | ||
"delay": "^6.0.0", | ||
@@ -122,9 +123,9 @@ "it-all": "^3.0.6", | ||
"it-length-prefixed": "^9.1.0", | ||
"it-map": "^3.1.0", | ||
"it-map": "^3.1.1", | ||
"it-pair": "^2.0.6", | ||
"it-stream-types": "^2.0.1", | ||
"it-take": "^3.0.5", | ||
"it-stream-types": "^2.0.2", | ||
"it-take": "^3.0.6", | ||
"p-event": "^6.0.1", | ||
"p-wait-for": "^5.0.2", | ||
"sinon": "^18.0.0", | ||
"sinon": "^19.0.2", | ||
"sinon-ts": "^2.0.0", | ||
@@ -131,0 +132,0 @@ "uint8arraylist": "^2.4.8" |
@@ -5,28 +5,12 @@ <h1 align="center"> | ||
<h3 align="center">The JavaScript implementation of the libp2p Networking Stack.</h3> | ||
<h3 align="center">The JavaScript implementation of the libp2p Networking Stack</h3> | ||
<p align="center"> | ||
<a href="http://protocol.ai"><img src="https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square" /></a> | ||
<a href="http://libp2p.io/"><img src="https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square" /></a> | ||
<a href="http://webchat.freenode.net/?channels=%23libp2p"><img src="https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square" /></a> | ||
<a href="https://riot.im/app/#/room/#libp2p:matrix.org"><img src="https://img.shields.io/badge/matrix-%23libp2p%3Apermaweb.io-blue.svg?style=flat-square" /> </a> | ||
<a href="https://discord.gg/ipfs"><img src="https://img.shields.io/discord/806902334369824788?color=blueviolet&label=discord&style=flat-square" /></a> | ||
<a href="https://discuss.libp2p.io"><img src="https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg" /></a> | ||
<a href="https://www.npmjs.com/package/libp2p"><img src="https://img.shields.io/npm/dm/libp2p.svg" /></a> | ||
<a href="https://www.jsdelivr.com/package/npm/libp2p"><img src="https://data.jsdelivr.com/v1/package/npm/libp2p/badge"/></a> | ||
</p> | ||
[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) | ||
[![npm](https://img.shields.io/npm/dm/libp2p.svg?style=flat-square)](https://www.npmjs.com/package/libp2p) | ||
[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) | ||
[![Matrix](https://img.shields.io/badge/matrix-%23libp2p--implementers%3Aipfs.io-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) | ||
[![Discord](https://img.shields.io/discord/806902334369824788?color=blueviolet&label=discord&style=flat-square)](https://discord.com/invite/Ae4TbahHaT) | ||
[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) | ||
[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/main.yml?branch=main\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/main.yml?query=branch%3Amain) | ||
<p align="center"> | ||
<a href="https://github.com/libp2p/js-libp2p/actions?query=branch%3Amaster+workflow%3Aci+"><img src="https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/main.yml?branch=main&label=ci&style=flat-square" /></a> | ||
<a href="https://codecov.io/gh/libp2p/js-libp2p"><img src="https://img.shields.io/codecov/c/github/libp2p/js-libp2p/master.svg?style=flat-square"></a> | ||
<br> | ||
<a href="https://github.com/feross/standard"><img src="https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square"></a> | ||
<a href="https://github.com/RichardLitt/standard-readme"><img src="https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square" /></a> | ||
<a href=""><img src="https://img.shields.io/badge/npm-%3E%3D7.0.0-orange.svg?style=flat-square" /></a> | ||
<a href=""><img src="https://img.shields.io/badge/Node.js-%3E%3D15.0.0-orange.svg?style=flat-square" /></a> | ||
<br> | ||
</p> | ||
> JavaScript implementation of libp2p, a modular peer to peer network stack | ||
# About | ||
@@ -33,0 +17,0 @@ |
@@ -0,1 +1,2 @@ | ||
import { isIPv4 } from '@chainsafe/is-ip' | ||
import { peerIdFromString } from '@libp2p/peer-id' | ||
@@ -81,3 +82,15 @@ import { debounce } from '@libp2p/utils/debounce' | ||
const CODEC_DNS6 = 0x37 | ||
const CODEC_TCP = 0x06 | ||
const CODEC_UDP = 0x0111 | ||
interface PublicAddressMapping { | ||
externalIp: string | ||
externalPort: number | ||
} | ||
interface DNSMapping { | ||
domain: string | ||
confident: boolean | ||
} | ||
export class AddressManager implements AddressManagerInterface { | ||
@@ -92,3 +105,4 @@ private readonly log: Logger | ||
private readonly announceFilter: AddressFilter | ||
private readonly ipDomainMappings: Map<string, string> | ||
private readonly ipDomainMappings: Map<string, DNSMapping> | ||
private readonly publicAddressMappings: Map<string, PublicAddressMapping[]> | ||
@@ -111,2 +125,3 @@ /** | ||
this.ipDomainMappings = new Map() | ||
this.publicAddressMappings = new Map() | ||
this.announceFilter = init.announceFilter ?? defaultAddressFilter | ||
@@ -133,9 +148,4 @@ | ||
// record for things like identify | ||
const addrs = this.getAnnounceAddrs() | ||
.concat(this.components.transportManager.getAddrs()) | ||
.concat( | ||
[...this.observed.entries()] | ||
.filter(([_, metadata]) => metadata.confident) | ||
.map(([str]) => multiaddr(str)) | ||
).map(ma => { | ||
const addrs = this.getAddresses() | ||
.map(ma => { | ||
// strip our peer id if it is present | ||
@@ -152,3 +162,5 @@ if (ma.getPeerId() === this.components.peerId.toString()) { | ||
}) | ||
.catch(err => { this.log.error('error updating addresses', err) }) | ||
.catch(err => { | ||
this.log.error('error updating addresses', err) | ||
}) | ||
} | ||
@@ -247,10 +259,55 @@ | ||
const mappedMultiaddrs: Multiaddr[] = [] | ||
// add public addresses | ||
const ipMappedMultiaddrs: Multiaddr[] = [] | ||
multiaddrs.forEach(ma => { | ||
const tuples = ma.stringTuples() | ||
let tuple: string | undefined | ||
// see if the internal host/port/protocol tuple has been mapped externally | ||
if ((tuples[0][0] === CODEC_IP4 || tuples[0][0] === CODEC_IP6) && tuples[1][0] === CODEC_TCP) { | ||
tuple = `${tuples[0][1]}-${tuples[1][1]}-tcp` | ||
} else if ((tuples[0][0] === CODEC_IP4 || tuples[0][0] === CODEC_IP6) && tuples[1][0] === CODEC_UDP) { | ||
tuple = `${tuples[0][1]}-${tuples[1][1]}-udp` | ||
} | ||
if (tuple == null) { | ||
return | ||
} | ||
const mappings = this.publicAddressMappings.get(tuple) | ||
if (mappings == null) { | ||
return | ||
} | ||
for (const mapping of mappings) { | ||
tuples[0][0] = isIPv4(mapping.externalIp) ? CODEC_IP4 : CODEC_IP6 | ||
tuples[0][1] = mapping.externalIp | ||
tuples[1][1] = `${mapping.externalPort}` | ||
ipMappedMultiaddrs.push( | ||
multiaddr(`/${ | ||
tuples.map(tuple => { | ||
return [ | ||
protocols(tuple[0]).name, | ||
tuple[1] | ||
].join('/') | ||
}).join('/') | ||
}`) | ||
) | ||
} | ||
}) | ||
multiaddrs = multiaddrs.concat(ipMappedMultiaddrs) | ||
// add ip->domain mappings | ||
const dnsMappedMultiaddrs: Multiaddr[] = [] | ||
for (const ma of multiaddrs) { | ||
const tuples = [...ma.stringTuples()] | ||
const tuples = ma.stringTuples() | ||
let mappedIp = false | ||
for (const [ip, domain] of this.ipDomainMappings.entries()) { | ||
for (const [ip, mapping] of this.ipDomainMappings.entries()) { | ||
if (!mapping.confident) { | ||
continue | ||
} | ||
for (let i = 0; i < tuples.length; i++) { | ||
@@ -263,3 +320,3 @@ if (tuples[i][1] !== ip) { | ||
tuples[i][0] = CODEC_DNS4 | ||
tuples[i][1] = domain | ||
tuples[i][1] = mapping.domain | ||
mappedIp = true | ||
@@ -270,3 +327,3 @@ } | ||
tuples[i][0] = CODEC_DNS6 | ||
tuples[i][1] = domain | ||
tuples[i][1] = mapping.domain | ||
mappedIp = true | ||
@@ -278,3 +335,3 @@ } | ||
if (mappedIp) { | ||
mappedMultiaddrs.push( | ||
dnsMappedMultiaddrs.push( | ||
multiaddr(`/${ | ||
@@ -291,5 +348,4 @@ tuples.map(tuple => { | ||
} | ||
multiaddrs = multiaddrs.concat(dnsMappedMultiaddrs) | ||
multiaddrs = multiaddrs.concat(mappedMultiaddrs) | ||
// dedupe multiaddrs | ||
@@ -331,13 +387,64 @@ const addrSet = new Set<string>() | ||
addresses.forEach(ip => { | ||
this.ipDomainMappings.set(ip, domain) | ||
this.log('add DNS mapping %s to %s', ip, domain) | ||
// check ip/public ip mappings to see if we think we are contactable | ||
const confident = [...this.publicAddressMappings.entries()].some(([key, mappings]) => { | ||
return mappings.some(mapping => mapping.externalIp === ip) | ||
}) | ||
this.ipDomainMappings.set(ip, { | ||
domain, | ||
confident | ||
}) | ||
}) | ||
this._updatePeerStoreAddresses() | ||
} | ||
removeDNSMapping (domain: string): void { | ||
for (const [key, value] of this.ipDomainMappings.entries()) { | ||
if (value === domain) { | ||
for (const [key, mapping] of this.ipDomainMappings.entries()) { | ||
if (mapping.domain === domain) { | ||
this.log('remove DNS mapping for %s', domain) | ||
this.ipDomainMappings.delete(key) | ||
} | ||
} | ||
this._updatePeerStoreAddresses() | ||
} | ||
addPublicAddressMapping (internalIp: string, internalPort: number, externalIp: string, externalPort: number = internalPort, protocol: 'tcp' | 'udp' = 'tcp'): void { | ||
const key = `${internalIp}-${internalPort}-${protocol}` | ||
const mappings = this.publicAddressMappings.get(key) ?? [] | ||
mappings.push({ | ||
externalIp, | ||
externalPort | ||
}) | ||
this.publicAddressMappings.set(key, mappings) | ||
// update domain mappings to indicate we are now confident that any matching | ||
// ip/domain combination can now be resolved externally | ||
for (const [key, mapping] of this.ipDomainMappings.entries()) { | ||
if (key === externalIp) { | ||
mapping.confident = true | ||
this.ipDomainMappings.set(key, mapping) | ||
} | ||
} | ||
this._updatePeerStoreAddresses() | ||
} | ||
removePublicAddressMapping (internalIp: string, internalPort: number, externalIp: string, externalPort: number = internalPort, protocol: 'tcp' | 'udp' = 'tcp'): void { | ||
const key = `${internalIp}-${internalPort}-${protocol}` | ||
const mappings = (this.publicAddressMappings.get(key) ?? []).filter(mapping => { | ||
return mapping.externalIp !== externalIp && mapping.externalPort !== externalPort | ||
}) | ||
if (mappings.length === 0) { | ||
this.publicAddressMappings.delete(key) | ||
} else { | ||
this.publicAddressMappings.set(key, mappings) | ||
} | ||
this._updatePeerStoreAddresses() | ||
} | ||
} |
import { isPrivateIp } from '@libp2p/utils/private-ip' | ||
import { WebSockets } from '@multiformats/multiaddr-matcher' | ||
import type { ConnectionGater } from '@libp2p/interface' | ||
import type { Multiaddr } from '@multiformats/multiaddr' | ||
const CODEC_IP4 = 0x04 | ||
const CODEC_IP6 = 0x29 | ||
/** | ||
* Returns a connection gater that disallows dialling private addresses by | ||
* default. Browsers are severely limited in their resource usage so don't | ||
* waste time trying to dial undiallable addresses. | ||
* Returns a connection gater that disallows dialling private addresses or | ||
* insecure websockets by default. | ||
* | ||
* Browsers are severely limited in their resource usage so don't waste time | ||
* trying to dial undiallable addresses, and they also print verbose error | ||
* messages when making connections over insecure transports which causes | ||
* confusion. | ||
*/ | ||
@@ -14,5 +22,11 @@ export function connectionGater (gater: ConnectionGater = {}): ConnectionGater { | ||
denyDialMultiaddr: async (multiaddr: Multiaddr) => { | ||
// do not connect to insecure websockets by default | ||
if (WebSockets.matches(multiaddr)) { | ||
return false | ||
} | ||
const tuples = multiaddr.stringTuples() | ||
if (tuples[0][0] === 4 || tuples[0][0] === 41) { | ||
// do not connect to private addresses by default | ||
if (tuples[0][0] === CODEC_IP4 || tuples[0][0] === CODEC_IP6) { | ||
return Boolean(isPrivateIp(`${tuples[0][1]}`)) | ||
@@ -19,0 +33,0 @@ } |
/* eslint-disable max-depth */ | ||
import { TimeoutError, DialError, setMaxListeners, AbortError } from '@libp2p/interface' | ||
import { PeerMap } from '@libp2p/peer-collections' | ||
import { PriorityQueue, type PriorityQueueJobOptions } from '@libp2p/utils/priority-queue' | ||
import { type Multiaddr, type Resolver, resolvers, multiaddr } from '@multiformats/multiaddr' | ||
import { PriorityQueue } from '@libp2p/utils/priority-queue' | ||
import { resolvers, multiaddr } from '@multiformats/multiaddr' | ||
import { dnsaddrResolver } from '@multiformats/multiaddr/resolvers' | ||
import { Circuit } from '@multiformats/multiaddr-matcher' | ||
import { type ClearableSignal, anySignal } from 'any-signal' | ||
import { anySignal } from 'any-signal' | ||
import { CustomProgressEvent } from 'progress-events' | ||
@@ -26,3 +26,5 @@ import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' | ||
import type { OpenConnectionOptions, TransportManager } from '@libp2p/interface-internal' | ||
import type { PriorityQueueJobOptions } from '@libp2p/utils/priority-queue' | ||
import type { DNS } from '@multiformats/dns' | ||
import type { Multiaddr, Resolver } from '@multiformats/multiaddr' | ||
import type { ProgressOptions } from 'progress-events' | ||
@@ -208,3 +210,8 @@ | ||
// we may be about to resolve a dns addr which can time out | ||
const signal = this.createDialAbortController(options?.signal) | ||
const signal = anySignal([ | ||
this.shutDownController.signal, | ||
options.signal | ||
]) | ||
setMaxListeners(Infinity, signal) | ||
let addrsToDial: Address[] | ||
@@ -304,3 +311,3 @@ | ||
multiaddrs: new Set(multiaddrs.map(ma => ma.toString())), | ||
signal: options.signal, | ||
signal: options.signal ?? AbortSignal.timeout(this.dialTimeout), | ||
onProgress: options.onProgress | ||
@@ -310,16 +317,2 @@ }) | ||
private createDialAbortController (userSignal?: AbortSignal): ClearableSignal { | ||
// let any signal abort the dial | ||
const signal = anySignal([ | ||
AbortSignal.timeout(this.dialTimeout), | ||
this.shutDownController.signal, | ||
userSignal | ||
]) | ||
// This emitter gets listened to a lot | ||
setMaxListeners(Infinity, signal) | ||
return signal | ||
} | ||
// eslint-disable-next-line complexity | ||
@@ -326,0 +319,0 @@ private async calculateMultiaddrs (peerId?: PeerId, multiaddrs: Set<string> = new Set<string>(), options: OpenConnectionOptions = {}): Promise<Address[]> { |
@@ -1,2 +0,2 @@ | ||
export const version = '2.3.1-0862522fe' | ||
export const name = 'libp2p' | ||
export const version = '2.3.1-2c182d2e2' | ||
export const name = 'js-libp2p' |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 1 instance in 1 package
901730
0
100
10884
27
138
191
+ Added@chainsafe/is-ip@^2.0.2
+ Added@libp2p/crypto@5.0.7-2c182d2e2(transitive)
+ Added@libp2p/interface@2.2.1-2c182d2e2(transitive)
+ Added@libp2p/interface-internal@2.1.1-2c182d2e2(transitive)
+ Added@libp2p/logger@5.1.4-2c182d2e2(transitive)
+ Added@libp2p/multistream-select@6.0.9-2c182d2e2(transitive)
+ Added@libp2p/peer-collections@6.0.12-2c182d2e2(transitive)
+ Added@libp2p/peer-id@5.0.8-2c182d2e2(transitive)
+ Added@libp2p/peer-record@8.0.12-2c182d2e2(transitive)
+ Added@libp2p/peer-store@11.0.12-2c182d2e2(transitive)
+ Added@libp2p/utils@6.2.1-2c182d2e2(transitive)
- Removed@libp2p/crypto@5.0.7-0862522fe(transitive)
- Removed@libp2p/interface@2.2.1-0862522fe(transitive)
- Removed@libp2p/interface-internal@2.1.1-0862522fe(transitive)
- Removed@libp2p/logger@5.1.4-0862522fe(transitive)
- Removed@libp2p/multistream-select@6.0.9-0862522fe(transitive)
- Removed@libp2p/peer-collections@6.0.12-0862522fe(transitive)
- Removed@libp2p/peer-id@5.0.8-0862522fe(transitive)
- Removed@libp2p/peer-record@8.0.12-0862522fe(transitive)
- Removed@libp2p/peer-store@11.0.12-0862522fe(transitive)
- Removed@libp2p/utils@6.2.1-0862522fe(transitive)
Updateddatastore-core@^10.0.2
Updatedinterface-datastore@^8.3.1
Updatedit-byte-stream@^1.1.0
Updatedit-parallel@^3.0.8
Updatedmultiformats@^13.3.1
Updatedp-retry@^6.2.1
Updatedprogress-events@^1.0.1
Updatedrace-signal@^1.1.0