@libp2p/upnp-nat 2.0.12-f8da60e73 → 3.0.0
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.
- package/dist/src/index.d.ts +10 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/upnp-nat.d.ts +3 -1
- package/dist/src/upnp-nat.d.ts.map +1 -1
- package/dist/src/upnp-nat.js +14 -2
- package/dist/src/upnp-nat.js.map +1 -1
- package/dist/src/upnp-port-mapper.d.ts +5 -1
- package/dist/src/upnp-port-mapper.d.ts.map +1 -1
- package/dist/src/upnp-port-mapper.js +24 -8
- package/dist/src/upnp-port-mapper.js.map +1 -1
- package/dist/typedoc-urls.json +12 -0
- package/package.json +7 -7
- package/src/index.ts +11 -0
- package/src/upnp-nat.ts +16 -2
- package/src/upnp-port-mapper.ts +34 -12
package/dist/src/index.d.ts
CHANGED
|
@@ -87,6 +87,16 @@ export interface UPnPNATInit {
|
|
|
87
87
|
* otherwise one will be created
|
|
88
88
|
*/
|
|
89
89
|
portMappingClient?: UPnPNATClient;
|
|
90
|
+
/**
|
|
91
|
+
* Any mapped addresses are added to the observed address list. These
|
|
92
|
+
* addresses require additional verification by the `@libp2p/autonat` protocol
|
|
93
|
+
* or similar before they are trusted.
|
|
94
|
+
*
|
|
95
|
+
* To skip this verification and trust them immediately pass `true` here
|
|
96
|
+
*
|
|
97
|
+
* @default false
|
|
98
|
+
*/
|
|
99
|
+
autoConfirmAddress?: boolean;
|
|
90
100
|
}
|
|
91
101
|
export interface UPnPNATComponents {
|
|
92
102
|
peerId: PeerId;
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAGH,OAAO,KAAK,EAAE,OAAO,IAAI,aAAa,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAC5F,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAC1G,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAEhE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,CAAA;AAE7C,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B;;;;;OAKG;IACH,4BAA4B,CAAC,EAAE,MAAM,CAAA;IAErC;;;;;OAKG;IACH,2BAA2B,CAAC,EAAE,MAAM,CAAA;IAEpC;;OAEG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAE/B;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IAEvB;;;;;OAKG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAEhC;;;;OAIG;IACH,2BAA2B,CAAC,EAAE,MAAM,CAAA;IAEpC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAGH,OAAO,KAAK,EAAE,OAAO,IAAI,aAAa,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAC5F,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAC1G,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAEhE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,CAAA;AAE7C,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B;;;;;OAKG;IACH,4BAA4B,CAAC,EAAE,MAAM,CAAA;IAErC;;;;;OAKG;IACH,2BAA2B,CAAC,EAAE,MAAM,CAAA;IAEpC;;OAEG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAE/B;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IAEvB;;;;;OAKG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAEhC;;;;OAIG;IACH,2BAA2B,CAAC,EAAE,MAAM,CAAA;IAEpC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,aAAa,CAAA;IAEjC;;;;;;;;OAQG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,QAAQ,CAAA;IAClB,MAAM,EAAE,eAAe,CAAA;IACvB,cAAc,EAAE,cAAc,CAAA;IAC9B,MAAM,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAA;CACvC;AAED,MAAM,WAAW,OAAO;IACtB,iBAAiB,EAAE,aAAa,CAAA;CACjC;AAED,wBAAgB,OAAO,CAAE,IAAI,GAAE,WAAgB,GAAG,CAAC,UAAU,EAAE,iBAAiB,KAAK,OAAO,CAI3F"}
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,eAAe,CAAA;AAwFvD,MAAM,UAAU,OAAO,CAAE,OAAoB,EAAE;IAC7C,OAAO,CAAC,UAA6B,EAAE,EAAE;QACvC,OAAO,IAAI,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC,CAAA;IAC3C,CAAC,CAAA;AACH,CAAC"}
|
package/dist/src/upnp-nat.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { serviceCapabilities } from '@libp2p/interface';
|
|
1
|
+
import { serviceCapabilities, serviceDependencies } from '@libp2p/interface';
|
|
2
2
|
import type { UPnPNATComponents, UPnPNATInit, UPnPNAT as UPnPNATInterface } from './index.js';
|
|
3
3
|
import type { Gateway, UPnPNAT as UPnPNATClient } from '@achingbrain/nat-port-mapper';
|
|
4
4
|
import type { Startable } from '@libp2p/interface';
|
|
@@ -12,9 +12,11 @@ export declare class UPnPNAT implements Startable, UPnPNATInterface {
|
|
|
12
12
|
private readonly mapIpAddressesDebounced;
|
|
13
13
|
private readonly gatewayFinder;
|
|
14
14
|
private readonly portMappers;
|
|
15
|
+
private readonly autoConfirmAddress;
|
|
15
16
|
constructor(components: UPnPNATComponents, init: UPnPNATInit);
|
|
16
17
|
readonly [Symbol.toStringTag] = "@libp2p/upnp-nat";
|
|
17
18
|
readonly [serviceCapabilities]: string[];
|
|
19
|
+
get [serviceDependencies](): string[];
|
|
18
20
|
isStarted(): boolean;
|
|
19
21
|
start(): Promise<void>;
|
|
20
22
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upnp-nat.d.ts","sourceRoot":"","sources":["../../src/upnp-nat.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAgC,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"upnp-nat.d.ts","sourceRoot":"","sources":["../../src/upnp-nat.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAgC,MAAM,mBAAmB,CAAA;AAI1G,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAC7F,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,8BAA8B,CAAA;AACrF,OAAO,KAAK,EAAU,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAG1D,qBAAa,OAAQ,YAAW,SAAS,EAAE,gBAAgB;IACzD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;IAC5B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAmB;IAC9C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,OAAO,CAAS;IACjB,iBAAiB,EAAE,aAAa,CAAA;IACvC,OAAO,CAAC,kBAAkB,CAAC,CAAiB;IAC5C,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAmB;IAC3D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAe;IAC7C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAkB;IAC9C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;gBAE/B,UAAU,EAAE,iBAAiB,EAAE,IAAI,EAAE,WAAW;IAgC7D,QAAQ,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,sBAAqB;IAElD,QAAQ,CAAC,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAEvC;IAED,IAAI,CAAC,mBAAmB,CAAC,IAAK,MAAM,EAAE,CAQrC;IAED,SAAS,IAAK,OAAO;IAIf,KAAK,IAAK,OAAO,CAAC,IAAI,CAAC;IAa7B;;OAEG;IACG,IAAI,IAAK,OAAO,CAAC,IAAI,CAAC;IAQ5B,mBAAmB,CAAE,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,GAAG,IAAI;IAejD,cAAc,IAAK,OAAO,CAAC,IAAI,CAAC;CAWvC"}
|
package/dist/src/upnp-nat.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { upnpNat } from '@achingbrain/nat-port-mapper';
|
|
2
|
-
import { serviceCapabilities, setMaxListeners, start, stop } from '@libp2p/interface';
|
|
2
|
+
import { serviceCapabilities, serviceDependencies, setMaxListeners, start, stop } from '@libp2p/interface';
|
|
3
3
|
import { debounce } from '@libp2p/utils/debounce';
|
|
4
4
|
import { GatewayFinder } from './gateway-finder.js';
|
|
5
5
|
import { UPnPPortMapper } from './upnp-port-mapper.js';
|
|
@@ -13,12 +13,14 @@ export class UPnPNAT {
|
|
|
13
13
|
mapIpAddressesDebounced;
|
|
14
14
|
gatewayFinder;
|
|
15
15
|
portMappers;
|
|
16
|
+
autoConfirmAddress;
|
|
16
17
|
constructor(components, init) {
|
|
17
18
|
this.log = components.logger.forComponent('libp2p:upnp-nat');
|
|
18
19
|
this.components = components;
|
|
19
20
|
this.init = init;
|
|
20
21
|
this.started = false;
|
|
21
22
|
this.portMappers = [];
|
|
23
|
+
this.autoConfirmAddress = init.autoConfirmAddress ?? false;
|
|
22
24
|
this.portMappingClient = init.portMappingClient ?? upnpNat({
|
|
23
25
|
description: init.portMappingDescription ?? `${components.nodeInfo.name}@${components.nodeInfo.version} ${components.peerId.toString()}`,
|
|
24
26
|
ttl: init.portMappingTTL,
|
|
@@ -44,6 +46,14 @@ export class UPnPNAT {
|
|
|
44
46
|
[serviceCapabilities] = [
|
|
45
47
|
'@libp2p/nat-traversal'
|
|
46
48
|
];
|
|
49
|
+
get [serviceDependencies]() {
|
|
50
|
+
if (!this.autoConfirmAddress) {
|
|
51
|
+
return [
|
|
52
|
+
'@libp2p/autonat'
|
|
53
|
+
];
|
|
54
|
+
}
|
|
55
|
+
return [];
|
|
56
|
+
}
|
|
47
57
|
isStarted() {
|
|
48
58
|
return this.started;
|
|
49
59
|
}
|
|
@@ -82,7 +92,9 @@ export class UPnPNAT {
|
|
|
82
92
|
}
|
|
83
93
|
async mapIpAddresses() {
|
|
84
94
|
try {
|
|
85
|
-
await Promise.all(this.portMappers.map(async (mapper) => mapper.mapIpAddresses(
|
|
95
|
+
await Promise.all(this.portMappers.map(async (mapper) => mapper.mapIpAddresses({
|
|
96
|
+
autoConfirmAddress: this.autoConfirmAddress
|
|
97
|
+
})));
|
|
86
98
|
}
|
|
87
99
|
catch (err) {
|
|
88
100
|
this.log.error('error mapping IP addresses - %e', err);
|
package/dist/src/upnp-nat.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upnp-nat.js","sourceRoot":"","sources":["../../src/upnp-nat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAA;AACtD,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"upnp-nat.js","sourceRoot":"","sources":["../../src/upnp-nat.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,6 +10,9 @@ export interface UPnPPortMapperComponents {
|
|
|
10
10
|
logger: ComponentLogger;
|
|
11
11
|
addressManager: AddressManager;
|
|
12
12
|
}
|
|
13
|
+
export interface MapPortsOptions {
|
|
14
|
+
autoConfirmAddress?: boolean;
|
|
15
|
+
}
|
|
13
16
|
export declare class UPnPPortMapper {
|
|
14
17
|
private readonly gateway;
|
|
15
18
|
private readonly externalAddress;
|
|
@@ -29,10 +32,11 @@ export declare class UPnPPortMapper {
|
|
|
29
32
|
* Return any eligible multiaddrs that are not mapped on the detected gateway
|
|
30
33
|
*/
|
|
31
34
|
private getUnmappedAddresses;
|
|
32
|
-
mapIpAddresses(): Promise<void>;
|
|
35
|
+
mapIpAddresses(options?: MapPortsOptions): Promise<void>;
|
|
33
36
|
/**
|
|
34
37
|
* Some ISPs have double-NATs, there's not much we can do with them
|
|
35
38
|
*/
|
|
36
39
|
private assertNotBehindDoubleNAT;
|
|
40
|
+
private isIPAddress;
|
|
37
41
|
}
|
|
38
42
|
//# sourceMappingURL=upnp-port-mapper.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upnp-port-mapper.d.ts","sourceRoot":"","sources":["../../src/upnp-port-mapper.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"upnp-port-mapper.d.ts","sourceRoot":"","sources":["../../src/upnp-port-mapper.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAA;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAU,MAAM,mBAAmB,CAAA;AAChE,OAAO,KAAK,EAAE,cAAc,EAAe,MAAM,4BAA4B,CAAA;AAK7E,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAA;IAChB,4BAA4B,CAAC,EAAE,MAAM,CAAA;IACrC,2BAA2B,CAAC,EAAE,MAAM,CAAA;CACrC;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,eAAe,CAAA;IACvB,cAAc,EAAE,cAAc,CAAA;CAC/B;AAOD,MAAM,WAAW,eAAe;IAC9B,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAC7B;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiB;IACjD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgB;IAC/C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;IAC5B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA0B;IACtD,OAAO,CAAC,OAAO,CAAS;gBAEX,UAAU,EAAE,wBAAwB,EAAE,IAAI,EAAE,kBAAkB;IAkBrE,KAAK,IAAK,OAAO,CAAC,IAAI,CAAC;IASvB,IAAI,IAAK,OAAO,CAAC,IAAI,CAAC;IAe5B;;;OAGG;IACH,OAAO,CAAC,UAAU;IAalB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAiDtB,cAAc,CAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IA8D/D;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAYhC,OAAO,CAAC,WAAW;CAOpB"}
|
|
@@ -4,9 +4,11 @@ import { isLinkLocal } from '@libp2p/utils/multiaddr/is-link-local';
|
|
|
4
4
|
import { isLoopback } from '@libp2p/utils/multiaddr/is-loopback';
|
|
5
5
|
import { isPrivate } from '@libp2p/utils/multiaddr/is-private';
|
|
6
6
|
import { isPrivateIp } from '@libp2p/utils/private-ip';
|
|
7
|
+
import { multiaddr } from '@multiformats/multiaddr';
|
|
7
8
|
import { QUICV1, TCP, WebSockets, WebSocketsSecure, WebTransport } from '@multiformats/multiaddr-matcher';
|
|
8
9
|
import { dynamicExternalAddress } from './check-external-address.js';
|
|
9
10
|
import { DoubleNATError } from './errors.js';
|
|
11
|
+
const MAX_DATE = 8_640_000_000_000_000;
|
|
10
12
|
export class UPnPPortMapper {
|
|
11
13
|
gateway;
|
|
12
14
|
externalAddress;
|
|
@@ -67,7 +69,11 @@ export class UPnPPortMapper {
|
|
|
67
69
|
*/
|
|
68
70
|
getUnmappedAddresses(multiaddrs, publicAddresses) {
|
|
69
71
|
const output = [];
|
|
70
|
-
for (const ma of multiaddrs) {
|
|
72
|
+
for (const { multiaddr: ma, type } of multiaddrs) {
|
|
73
|
+
// only consider transport addresses, ignore mapped/observed addrs
|
|
74
|
+
if (type !== 'transport') {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
71
77
|
const stringTuples = ma.stringTuples();
|
|
72
78
|
const address = `${stringTuples[0][1]}`;
|
|
73
79
|
// ignore public IPv4 addresses
|
|
@@ -87,11 +93,7 @@ export class UPnPPortMapper {
|
|
|
87
93
|
continue;
|
|
88
94
|
}
|
|
89
95
|
// only IP based addresses
|
|
90
|
-
if (!
|
|
91
|
-
WebSockets.exactMatch(ma) ||
|
|
92
|
-
WebSocketsSecure.exactMatch(ma) ||
|
|
93
|
-
QUICV1.exactMatch(ma) ||
|
|
94
|
-
WebTransport.exactMatch(ma))) {
|
|
96
|
+
if (!this.isIPAddress(ma)) {
|
|
95
97
|
continue;
|
|
96
98
|
}
|
|
97
99
|
const { port, transport } = ma.toOptions();
|
|
@@ -102,12 +104,12 @@ export class UPnPPortMapper {
|
|
|
102
104
|
}
|
|
103
105
|
return output;
|
|
104
106
|
}
|
|
105
|
-
async mapIpAddresses() {
|
|
107
|
+
async mapIpAddresses(options) {
|
|
106
108
|
try {
|
|
107
109
|
const externalHost = await this.externalAddress.getPublicIp();
|
|
108
110
|
// filter addresses to get private, non-relay, IP based addresses that we
|
|
109
111
|
// haven't mapped yet
|
|
110
|
-
const addresses = this.getUnmappedAddresses(this.addressManager.
|
|
112
|
+
const addresses = this.getUnmappedAddresses(this.addressManager.getAddressesWithMetadata(), [externalHost]);
|
|
111
113
|
if (addresses.length === 0) {
|
|
112
114
|
this.log('no private, non-relay, unmapped, IP based addresses found');
|
|
113
115
|
return;
|
|
@@ -137,6 +139,13 @@ export class UPnPPortMapper {
|
|
|
137
139
|
this.mappedPorts.set(key, mapping);
|
|
138
140
|
this.addressManager.addPublicAddressMapping(mapping.internalHost, mapping.internalPort, mapping.externalHost, mapping.externalPort, transport === 'tcp' ? 'tcp' : 'udp');
|
|
139
141
|
this.log('created mapping of %s:%s to %s:%s for protocol %s', mapping.internalHost, mapping.internalPort, mapping.externalHost, mapping.externalPort, transport);
|
|
142
|
+
if (options?.autoConfirmAddress === true) {
|
|
143
|
+
const ma = multiaddr(`/ip${family}/${host}/${transport}/${port}`);
|
|
144
|
+
this.log('auto-confirming IP address %a', ma);
|
|
145
|
+
this.addressManager.confirmObservedAddr(ma, {
|
|
146
|
+
ttl: MAX_DATE - Date.now()
|
|
147
|
+
});
|
|
148
|
+
}
|
|
140
149
|
}
|
|
141
150
|
catch (err) {
|
|
142
151
|
this.log.error('failed to create mapping for %s:%d for protocol - %e', host, port, transport, err);
|
|
@@ -159,5 +168,12 @@ export class UPnPPortMapper {
|
|
|
159
168
|
throw new InvalidParametersError(`${publicIp} is not an IP address`);
|
|
160
169
|
}
|
|
161
170
|
}
|
|
171
|
+
isIPAddress(ma) {
|
|
172
|
+
return TCP.exactMatch(ma) ||
|
|
173
|
+
WebSockets.exactMatch(ma) ||
|
|
174
|
+
WebSocketsSecure.exactMatch(ma) ||
|
|
175
|
+
QUICV1.exactMatch(ma) ||
|
|
176
|
+
WebTransport.exactMatch(ma);
|
|
177
|
+
}
|
|
162
178
|
}
|
|
163
179
|
//# sourceMappingURL=upnp-port-mapper.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upnp-port-mapper.js","sourceRoot":"","sources":["../../src/upnp-port-mapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,sBAAsB,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAA;AACvE,OAAO,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAA;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAA;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAA;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AACtD,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAA;AACzG,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"upnp-port-mapper.js","sourceRoot":"","sources":["../../src/upnp-port-mapper.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"PMPOptions": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_upnp_nat.PMPOptions.html",
|
|
3
|
+
".:PMPOptions": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_upnp_nat.PMPOptions.html",
|
|
4
|
+
"UPnPNAT": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_upnp_nat.UPnPNAT.html",
|
|
5
|
+
".:UPnPNAT": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_upnp_nat.UPnPNAT.html",
|
|
6
|
+
"UPnPNATComponents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_upnp_nat.UPnPNATComponents.html",
|
|
7
|
+
".:UPnPNATComponents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_upnp_nat.UPnPNATComponents.html",
|
|
8
|
+
"UPnPNATInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_upnp_nat.UPnPNATInit.html",
|
|
9
|
+
".:UPnPNATInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_upnp_nat.UPnPNATInit.html",
|
|
10
|
+
"uPnPNAT": "https://libp2p.github.io/js-libp2p/functions/_libp2p_upnp_nat.uPnPNAT-1.html",
|
|
11
|
+
".:uPnPNAT": "https://libp2p.github.io/js-libp2p/functions/_libp2p_upnp_nat.uPnPNAT-1.html"
|
|
12
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@libp2p/upnp-nat",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "UPnP NAT hole punching",
|
|
5
5
|
"license": "Apache-2.0 OR MIT",
|
|
6
6
|
"homepage": "https://github.com/libp2p/js-libp2p/tree/main/packages/upnp-nat#readme",
|
|
@@ -52,18 +52,18 @@
|
|
|
52
52
|
"dependencies": {
|
|
53
53
|
"@achingbrain/nat-port-mapper": "^4.0.0",
|
|
54
54
|
"@chainsafe/is-ip": "^2.0.2",
|
|
55
|
-
"@libp2p/interface": "2.
|
|
56
|
-
"@libp2p/interface-internal": "2.
|
|
57
|
-
"@libp2p/utils": "6.
|
|
55
|
+
"@libp2p/interface": "^2.3.0",
|
|
56
|
+
"@libp2p/interface-internal": "^2.2.0",
|
|
57
|
+
"@libp2p/utils": "^6.3.0",
|
|
58
58
|
"@multiformats/multiaddr": "^12.3.3",
|
|
59
59
|
"@multiformats/multiaddr-matcher": "^1.6.0",
|
|
60
60
|
"p-defer": "^4.0.1",
|
|
61
61
|
"race-signal": "^1.1.0"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
|
-
"@libp2p/crypto": "5.0.
|
|
65
|
-
"@libp2p/logger": "5.1.
|
|
66
|
-
"@libp2p/peer-id": "5.0.
|
|
64
|
+
"@libp2p/crypto": "^5.0.8",
|
|
65
|
+
"@libp2p/logger": "^5.1.5",
|
|
66
|
+
"@libp2p/peer-id": "^5.0.9",
|
|
67
67
|
"aegir": "^45.0.5",
|
|
68
68
|
"sinon-ts": "^2.0.0"
|
|
69
69
|
},
|
package/src/index.ts
CHANGED
|
@@ -98,6 +98,17 @@ export interface UPnPNATInit {
|
|
|
98
98
|
* otherwise one will be created
|
|
99
99
|
*/
|
|
100
100
|
portMappingClient?: UPnPNATClient
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Any mapped addresses are added to the observed address list. These
|
|
104
|
+
* addresses require additional verification by the `@libp2p/autonat` protocol
|
|
105
|
+
* or similar before they are trusted.
|
|
106
|
+
*
|
|
107
|
+
* To skip this verification and trust them immediately pass `true` here
|
|
108
|
+
*
|
|
109
|
+
* @default false
|
|
110
|
+
*/
|
|
111
|
+
autoConfirmAddress?: boolean
|
|
101
112
|
}
|
|
102
113
|
|
|
103
114
|
export interface UPnPNATComponents {
|
package/src/upnp-nat.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { upnpNat } from '@achingbrain/nat-port-mapper'
|
|
2
|
-
import { serviceCapabilities, setMaxListeners, start, stop } from '@libp2p/interface'
|
|
2
|
+
import { serviceCapabilities, serviceDependencies, setMaxListeners, start, stop } from '@libp2p/interface'
|
|
3
3
|
import { debounce } from '@libp2p/utils/debounce'
|
|
4
4
|
import { GatewayFinder } from './gateway-finder.js'
|
|
5
5
|
import { UPnPPortMapper } from './upnp-port-mapper.js'
|
|
@@ -18,6 +18,7 @@ export class UPnPNAT implements Startable, UPnPNATInterface {
|
|
|
18
18
|
private readonly mapIpAddressesDebounced: DebouncedFunction
|
|
19
19
|
private readonly gatewayFinder: GatewayFinder
|
|
20
20
|
private readonly portMappers: UPnPPortMapper[]
|
|
21
|
+
private readonly autoConfirmAddress: boolean
|
|
21
22
|
|
|
22
23
|
constructor (components: UPnPNATComponents, init: UPnPNATInit) {
|
|
23
24
|
this.log = components.logger.forComponent('libp2p:upnp-nat')
|
|
@@ -25,6 +26,7 @@ export class UPnPNAT implements Startable, UPnPNATInterface {
|
|
|
25
26
|
this.init = init
|
|
26
27
|
this.started = false
|
|
27
28
|
this.portMappers = []
|
|
29
|
+
this.autoConfirmAddress = init.autoConfirmAddress ?? false
|
|
28
30
|
|
|
29
31
|
this.portMappingClient = init.portMappingClient ?? upnpNat({
|
|
30
32
|
description: init.portMappingDescription ?? `${components.nodeInfo.name}@${components.nodeInfo.version} ${components.peerId.toString()}`,
|
|
@@ -56,6 +58,16 @@ export class UPnPNAT implements Startable, UPnPNATInterface {
|
|
|
56
58
|
'@libp2p/nat-traversal'
|
|
57
59
|
]
|
|
58
60
|
|
|
61
|
+
get [serviceDependencies] (): string[] {
|
|
62
|
+
if (!this.autoConfirmAddress) {
|
|
63
|
+
return [
|
|
64
|
+
'@libp2p/autonat'
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return []
|
|
69
|
+
}
|
|
70
|
+
|
|
59
71
|
isStarted (): boolean {
|
|
60
72
|
return this.started
|
|
61
73
|
}
|
|
@@ -102,7 +114,9 @@ export class UPnPNAT implements Startable, UPnPNATInterface {
|
|
|
102
114
|
async mapIpAddresses (): Promise<void> {
|
|
103
115
|
try {
|
|
104
116
|
await Promise.all(
|
|
105
|
-
this.portMappers.map(async mapper => mapper.mapIpAddresses(
|
|
117
|
+
this.portMappers.map(async mapper => mapper.mapIpAddresses({
|
|
118
|
+
autoConfirmAddress: this.autoConfirmAddress
|
|
119
|
+
}))
|
|
106
120
|
)
|
|
107
121
|
} catch (err: any) {
|
|
108
122
|
this.log.error('error mapping IP addresses - %e', err)
|
package/src/upnp-port-mapper.ts
CHANGED
|
@@ -4,15 +4,18 @@ import { isLinkLocal } from '@libp2p/utils/multiaddr/is-link-local'
|
|
|
4
4
|
import { isLoopback } from '@libp2p/utils/multiaddr/is-loopback'
|
|
5
5
|
import { isPrivate } from '@libp2p/utils/multiaddr/is-private'
|
|
6
6
|
import { isPrivateIp } from '@libp2p/utils/private-ip'
|
|
7
|
+
import { multiaddr } from '@multiformats/multiaddr'
|
|
7
8
|
import { QUICV1, TCP, WebSockets, WebSocketsSecure, WebTransport } from '@multiformats/multiaddr-matcher'
|
|
8
9
|
import { dynamicExternalAddress } from './check-external-address.js'
|
|
9
10
|
import { DoubleNATError } from './errors.js'
|
|
10
11
|
import type { ExternalAddress } from './check-external-address.js'
|
|
11
12
|
import type { Gateway } from '@achingbrain/nat-port-mapper'
|
|
12
13
|
import type { ComponentLogger, Logger } from '@libp2p/interface'
|
|
13
|
-
import type { AddressManager } from '@libp2p/interface-internal'
|
|
14
|
+
import type { AddressManager, NodeAddress } from '@libp2p/interface-internal'
|
|
14
15
|
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
15
16
|
|
|
17
|
+
const MAX_DATE = 8_640_000_000_000_000
|
|
18
|
+
|
|
16
19
|
export interface UPnPPortMapperInit {
|
|
17
20
|
gateway: Gateway
|
|
18
21
|
externalAddressCheckInterval?: number
|
|
@@ -29,6 +32,10 @@ interface PortMapping {
|
|
|
29
32
|
externalPort: number
|
|
30
33
|
}
|
|
31
34
|
|
|
35
|
+
export interface MapPortsOptions {
|
|
36
|
+
autoConfirmAddress?: boolean
|
|
37
|
+
}
|
|
38
|
+
|
|
32
39
|
export class UPnPPortMapper {
|
|
33
40
|
private readonly gateway: Gateway
|
|
34
41
|
private readonly externalAddress: ExternalAddress
|
|
@@ -99,10 +106,15 @@ export class UPnPPortMapper {
|
|
|
99
106
|
/**
|
|
100
107
|
* Return any eligible multiaddrs that are not mapped on the detected gateway
|
|
101
108
|
*/
|
|
102
|
-
private getUnmappedAddresses (multiaddrs:
|
|
109
|
+
private getUnmappedAddresses (multiaddrs: NodeAddress[], publicAddresses: string[]): Multiaddr[] {
|
|
103
110
|
const output: Multiaddr[] = []
|
|
104
111
|
|
|
105
|
-
for (const ma of multiaddrs) {
|
|
112
|
+
for (const { multiaddr: ma, type } of multiaddrs) {
|
|
113
|
+
// only consider transport addresses, ignore mapped/observed addrs
|
|
114
|
+
if (type !== 'transport') {
|
|
115
|
+
continue
|
|
116
|
+
}
|
|
117
|
+
|
|
106
118
|
const stringTuples = ma.stringTuples()
|
|
107
119
|
const address = `${stringTuples[0][1]}`
|
|
108
120
|
|
|
@@ -127,13 +139,7 @@ export class UPnPPortMapper {
|
|
|
127
139
|
}
|
|
128
140
|
|
|
129
141
|
// only IP based addresses
|
|
130
|
-
if (!(
|
|
131
|
-
TCP.exactMatch(ma) ||
|
|
132
|
-
WebSockets.exactMatch(ma) ||
|
|
133
|
-
WebSocketsSecure.exactMatch(ma) ||
|
|
134
|
-
QUICV1.exactMatch(ma) ||
|
|
135
|
-
WebTransport.exactMatch(ma)
|
|
136
|
-
)) {
|
|
142
|
+
if (!this.isIPAddress(ma)) {
|
|
137
143
|
continue
|
|
138
144
|
}
|
|
139
145
|
|
|
@@ -149,13 +155,13 @@ export class UPnPPortMapper {
|
|
|
149
155
|
return output
|
|
150
156
|
}
|
|
151
157
|
|
|
152
|
-
async mapIpAddresses (): Promise<void> {
|
|
158
|
+
async mapIpAddresses (options?: MapPortsOptions): Promise<void> {
|
|
153
159
|
try {
|
|
154
160
|
const externalHost = await this.externalAddress.getPublicIp()
|
|
155
161
|
|
|
156
162
|
// filter addresses to get private, non-relay, IP based addresses that we
|
|
157
163
|
// haven't mapped yet
|
|
158
|
-
const addresses = this.getUnmappedAddresses(this.addressManager.
|
|
164
|
+
const addresses = this.getUnmappedAddresses(this.addressManager.getAddressesWithMetadata(), [externalHost])
|
|
159
165
|
|
|
160
166
|
if (addresses.length === 0) {
|
|
161
167
|
this.log('no private, non-relay, unmapped, IP based addresses found')
|
|
@@ -194,6 +200,14 @@ export class UPnPPortMapper {
|
|
|
194
200
|
this.mappedPorts.set(key, mapping)
|
|
195
201
|
this.addressManager.addPublicAddressMapping(mapping.internalHost, mapping.internalPort, mapping.externalHost, mapping.externalPort, transport === 'tcp' ? 'tcp' : 'udp')
|
|
196
202
|
this.log('created mapping of %s:%s to %s:%s for protocol %s', mapping.internalHost, mapping.internalPort, mapping.externalHost, mapping.externalPort, transport)
|
|
203
|
+
|
|
204
|
+
if (options?.autoConfirmAddress === true) {
|
|
205
|
+
const ma = multiaddr(`/ip${family}/${host}/${transport}/${port}`)
|
|
206
|
+
this.log('auto-confirming IP address %a', ma)
|
|
207
|
+
this.addressManager.confirmObservedAddr(ma, {
|
|
208
|
+
ttl: MAX_DATE - Date.now()
|
|
209
|
+
})
|
|
210
|
+
}
|
|
197
211
|
} catch (err) {
|
|
198
212
|
this.log.error('failed to create mapping for %s:%d for protocol - %e', host, port, transport, err)
|
|
199
213
|
}
|
|
@@ -217,4 +231,12 @@ export class UPnPPortMapper {
|
|
|
217
231
|
throw new InvalidParametersError(`${publicIp} is not an IP address`)
|
|
218
232
|
}
|
|
219
233
|
}
|
|
234
|
+
|
|
235
|
+
private isIPAddress (ma: Multiaddr): boolean {
|
|
236
|
+
return TCP.exactMatch(ma) ||
|
|
237
|
+
WebSockets.exactMatch(ma) ||
|
|
238
|
+
WebSocketsSecure.exactMatch(ma) ||
|
|
239
|
+
QUICV1.exactMatch(ma) ||
|
|
240
|
+
WebTransport.exactMatch(ma)
|
|
241
|
+
}
|
|
220
242
|
}
|