@libp2p/upnp-nat 2.0.12-4a85eb033 → 2.0.12-6ab85ea68
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/check-external-address.d.ts +4 -4
- package/dist/src/check-external-address.d.ts.map +1 -1
- package/dist/src/check-external-address.js +10 -26
- package/dist/src/check-external-address.js.map +1 -1
- package/dist/src/constants.d.ts +3 -0
- package/dist/src/constants.d.ts.map +1 -0
- package/dist/src/constants.js +3 -0
- package/dist/src/constants.js.map +1 -0
- package/dist/src/gateway-finder.d.ts +26 -0
- package/dist/src/gateway-finder.d.ts.map +1 -0
- package/dist/src/gateway-finder.js +53 -0
- package/dist/src/gateway-finder.js.map +1 -0
- package/dist/src/index.d.ts +16 -45
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/upnp-nat.d.ts +11 -24
- package/dist/src/upnp-nat.d.ts.map +1 -1
- package/dist/src/upnp-nat.js +56 -175
- package/dist/src/upnp-nat.js.map +1 -1
- package/dist/src/upnp-port-mapper.d.ts +38 -0
- package/dist/src/upnp-port-mapper.d.ts.map +1 -0
- package/dist/src/upnp-port-mapper.js +163 -0
- package/dist/src/upnp-port-mapper.js.map +1 -0
- package/package.json +11 -11
- package/src/check-external-address.ts +14 -34
- package/src/constants.ts +2 -0
- package/src/gateway-finder.ts +75 -0
- package/src/index.ts +17 -50
- package/src/upnp-nat.ts +60 -213
- package/src/upnp-port-mapper.ts +220 -0
- package/LICENSE +0 -4
package/dist/src/upnp-nat.js
CHANGED
|
@@ -1,82 +1,49 @@
|
|
|
1
1
|
import { upnpNat } from '@achingbrain/nat-port-mapper';
|
|
2
|
-
import {
|
|
3
|
-
import { InvalidParametersError, serviceCapabilities, serviceDependencies, start, stop } from '@libp2p/interface';
|
|
2
|
+
import { serviceCapabilities, setMaxListeners, start, stop } from '@libp2p/interface';
|
|
4
3
|
import { debounce } from '@libp2p/utils/debounce';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { isPrivateIp } from '@libp2p/utils/private-ip';
|
|
8
|
-
import { multiaddr } from '@multiformats/multiaddr';
|
|
9
|
-
import { QUICV1, TCP, WebSockets, WebSocketsSecure, WebTransport } from '@multiformats/multiaddr-matcher';
|
|
10
|
-
import { raceSignal } from 'race-signal';
|
|
11
|
-
import { dynamicExternalAddress, staticExternalAddress } from './check-external-address.js';
|
|
12
|
-
import { DoubleNATError, InvalidIPAddressError } from './errors.js';
|
|
13
|
-
const DEFAULT_TTL = 7200;
|
|
4
|
+
import { GatewayFinder } from './gateway-finder.js';
|
|
5
|
+
import { UPnPPortMapper } from './upnp-port-mapper.js';
|
|
14
6
|
export class UPnPNAT {
|
|
15
|
-
client;
|
|
16
|
-
addressManager;
|
|
17
|
-
events;
|
|
18
|
-
externalAddress;
|
|
19
|
-
localAddress;
|
|
20
|
-
description;
|
|
21
|
-
ttl;
|
|
22
|
-
keepAlive;
|
|
23
|
-
gateway;
|
|
24
|
-
started;
|
|
25
7
|
log;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
8
|
+
components;
|
|
9
|
+
init;
|
|
10
|
+
started;
|
|
11
|
+
portMappingClient;
|
|
12
|
+
shutdownController;
|
|
13
|
+
mapIpAddressesDebounced;
|
|
14
|
+
gatewayFinder;
|
|
15
|
+
portMappers;
|
|
30
16
|
constructor(components, init) {
|
|
31
17
|
this.log = components.logger.forComponent('libp2p:upnp-nat');
|
|
32
|
-
this.
|
|
33
|
-
this.
|
|
18
|
+
this.components = components;
|
|
19
|
+
this.init = init;
|
|
34
20
|
this.started = false;
|
|
35
|
-
this.
|
|
36
|
-
this.
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
this.autoConfirmAddress = init.autoConfirmAddress ?? false;
|
|
42
|
-
this.mappedPorts = new Map();
|
|
43
|
-
if (this.ttl < DEFAULT_TTL) {
|
|
44
|
-
throw new InvalidParametersError(`NatManager ttl should be at least ${DEFAULT_TTL} seconds`);
|
|
45
|
-
}
|
|
46
|
-
this.client = init.client ?? upnpNat({
|
|
47
|
-
description: this.description,
|
|
48
|
-
ttl: this.ttl,
|
|
49
|
-
keepAlive: this.keepAlive,
|
|
50
|
-
gateway: this.gateway
|
|
21
|
+
this.portMappers = [];
|
|
22
|
+
this.portMappingClient = init.portMappingClient ?? upnpNat({
|
|
23
|
+
description: init.portMappingDescription ?? `${components.nodeInfo.name}@${components.nodeInfo.version} ${components.peerId.toString()}`,
|
|
24
|
+
ttl: init.portMappingTTL,
|
|
25
|
+
autoRefresh: init.portMappingAutoRefresh,
|
|
26
|
+
refreshThreshold: init.portMappingRefreshThreshold
|
|
51
27
|
});
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
28
|
+
// trigger update when our addresses change
|
|
29
|
+
this.mapIpAddressesDebounced = debounce(async () => {
|
|
30
|
+
try {
|
|
31
|
+
await this.mapIpAddresses();
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
this.log.error('error mapping IP addresses - %e', err);
|
|
35
|
+
}
|
|
36
|
+
}, 5_000);
|
|
37
|
+
// trigger update when we discovery gateways on the network
|
|
38
|
+
this.gatewayFinder = new GatewayFinder(components, {
|
|
39
|
+
portMappingClient: this.portMappingClient
|
|
40
|
+
});
|
|
41
|
+
this.onGatewayDiscovered = this.onGatewayDiscovered.bind(this);
|
|
67
42
|
}
|
|
68
43
|
[Symbol.toStringTag] = '@libp2p/upnp-nat';
|
|
69
44
|
[serviceCapabilities] = [
|
|
70
45
|
'@libp2p/nat-traversal'
|
|
71
46
|
];
|
|
72
|
-
get [serviceDependencies]() {
|
|
73
|
-
if (!this.autoConfirmAddress) {
|
|
74
|
-
return [
|
|
75
|
-
'@libp2p/autonat'
|
|
76
|
-
];
|
|
77
|
-
}
|
|
78
|
-
return [];
|
|
79
|
-
}
|
|
80
47
|
isStarted() {
|
|
81
48
|
return this.started;
|
|
82
49
|
}
|
|
@@ -85,126 +52,40 @@ export class UPnPNAT {
|
|
|
85
52
|
return;
|
|
86
53
|
}
|
|
87
54
|
this.started = true;
|
|
88
|
-
this.
|
|
89
|
-
|
|
55
|
+
this.shutdownController = new AbortController();
|
|
56
|
+
setMaxListeners(Infinity, this.shutdownController.signal);
|
|
57
|
+
this.components.events.addEventListener('self:peer:update', this.mapIpAddressesDebounced);
|
|
58
|
+
this.gatewayFinder.addEventListener('gateway', this.onGatewayDiscovered);
|
|
59
|
+
await start(this.mapIpAddressesDebounced, this.gatewayFinder, ...this.portMappers);
|
|
90
60
|
}
|
|
91
61
|
/**
|
|
92
62
|
* Stops the NAT manager
|
|
93
63
|
*/
|
|
94
64
|
async stop() {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
this.log.error(err);
|
|
100
|
-
}
|
|
101
|
-
this.events.removeEventListener('self:peer:update', this.onSelfPeerUpdate);
|
|
102
|
-
await stop(this.externalAddress, this.onSelfPeerUpdate);
|
|
65
|
+
this.shutdownController?.abort();
|
|
66
|
+
this.components.events.removeEventListener('self:peer:update', this.mapIpAddressesDebounced);
|
|
67
|
+
this.gatewayFinder.removeEventListener('gateway', this.onGatewayDiscovered);
|
|
68
|
+
await stop(this.mapIpAddressesDebounced, this.gatewayFinder, ...this.portMappers);
|
|
103
69
|
this.started = false;
|
|
104
70
|
}
|
|
105
|
-
|
|
106
|
-
this.
|
|
107
|
-
.
|
|
108
|
-
|
|
71
|
+
onGatewayDiscovered(event) {
|
|
72
|
+
const mapper = new UPnPPortMapper(this.components, {
|
|
73
|
+
...this.init,
|
|
74
|
+
gateway: event.detail
|
|
109
75
|
});
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
continue;
|
|
117
|
-
}
|
|
118
|
-
// ignore loopback
|
|
119
|
-
if (isLoopback(ma)) {
|
|
120
|
-
continue;
|
|
121
|
-
}
|
|
122
|
-
// only IP based addresses
|
|
123
|
-
if (!(TCP.exactMatch(ma) ||
|
|
124
|
-
WebSockets.exactMatch(ma) ||
|
|
125
|
-
WebSocketsSecure.exactMatch(ma) ||
|
|
126
|
-
QUICV1.exactMatch(ma) ||
|
|
127
|
-
WebTransport.exactMatch(ma))) {
|
|
128
|
-
continue;
|
|
129
|
-
}
|
|
130
|
-
const { port, family } = ma.toOptions();
|
|
131
|
-
if (family !== ipType) {
|
|
132
|
-
continue;
|
|
133
|
-
}
|
|
134
|
-
if (this.mappedPorts.has(port)) {
|
|
135
|
-
continue;
|
|
136
|
-
}
|
|
137
|
-
output.push(ma);
|
|
138
|
-
}
|
|
139
|
-
return output;
|
|
76
|
+
this.portMappers.push(mapper);
|
|
77
|
+
start(mapper)
|
|
78
|
+
.then(() => {
|
|
79
|
+
this.mapIpAddressesDebounced();
|
|
80
|
+
})
|
|
81
|
+
.catch(() => { });
|
|
140
82
|
}
|
|
141
83
|
async mapIpAddresses() {
|
|
142
|
-
|
|
143
|
-
this.
|
|
144
|
-
}
|
|
145
|
-
const publicIp = await this.externalAddress.getPublicIp({
|
|
146
|
-
signal: AbortSignal.timeout(this.gatewayDetectionTimeout)
|
|
147
|
-
});
|
|
148
|
-
this.externalAddress ?? await raceSignal(this.client.externalIp(), AbortSignal.timeout(this.gatewayDetectionTimeout), {
|
|
149
|
-
errorMessage: `Did not discover a "urn:schemas-upnp-org:device:InternetGatewayDevice:1" device on the local network after ${this.gatewayDetectionTimeout}ms - UPnP may not be configured on your router correctly`
|
|
150
|
-
});
|
|
151
|
-
let ipType = 4;
|
|
152
|
-
if (isIPv4(publicIp)) {
|
|
153
|
-
ipType = 4;
|
|
154
|
-
}
|
|
155
|
-
else if (isIPv6(publicIp)) {
|
|
156
|
-
ipType = 6;
|
|
157
|
-
}
|
|
158
|
-
else {
|
|
159
|
-
throw new InvalidIPAddressError(`Public address ${publicIp} was not an IPv4 address`);
|
|
160
|
-
}
|
|
161
|
-
// filter addresses to get private, non-relay, IP based addresses that we
|
|
162
|
-
// haven't mapped yet
|
|
163
|
-
const addresses = this.getUnmappedAddresses(this.addressManager.getAddresses(), ipType);
|
|
164
|
-
if (addresses.length === 0) {
|
|
165
|
-
this.log('no private, non-relay, unmapped, IP based addresses found');
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
this.log('%s public IP %s', this.externalAddress != null ? 'using configured' : 'discovered', publicIp);
|
|
169
|
-
this.assertNotBehindDoubleNAT(publicIp);
|
|
170
|
-
for (const addr of addresses) {
|
|
171
|
-
// try to open uPnP ports for each thin waist address
|
|
172
|
-
const { family, host, port, transport } = addr.toOptions();
|
|
173
|
-
if (family === 6) {
|
|
174
|
-
// only support IPv4 addresses
|
|
175
|
-
continue;
|
|
176
|
-
}
|
|
177
|
-
if (this.mappedPorts.has(port)) {
|
|
178
|
-
// already mapped this port
|
|
179
|
-
continue;
|
|
180
|
-
}
|
|
181
|
-
const protocol = transport.toUpperCase();
|
|
182
|
-
this.log(`creating mapping of ${host}:${port}`);
|
|
183
|
-
const mappedPort = await this.client.map(port, {
|
|
184
|
-
localAddress: host,
|
|
185
|
-
protocol: protocol === 'TCP' ? 'TCP' : 'UDP'
|
|
186
|
-
});
|
|
187
|
-
this.mappedPorts.set(port, mappedPort);
|
|
188
|
-
const ma = multiaddr(addr.toString().replace(`/ip${family}/${host}/${transport}/${port}`, `/ip${family}/${publicIp}/${transport}/${mappedPort}`));
|
|
189
|
-
this.log(`created mapping of ${publicIp}:${mappedPort} to ${host}:${port} as %a`, ma);
|
|
190
|
-
if (this.autoConfirmAddress) {
|
|
191
|
-
this.addressManager.confirmObservedAddr(ma);
|
|
192
|
-
}
|
|
193
|
-
else {
|
|
194
|
-
this.addressManager.addObservedAddr(ma);
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* Some ISPs have double-NATs, there's not much we can do with them
|
|
200
|
-
*/
|
|
201
|
-
assertNotBehindDoubleNAT(publicIp) {
|
|
202
|
-
const isPrivate = isPrivateIp(publicIp);
|
|
203
|
-
if (isPrivate === true) {
|
|
204
|
-
throw new DoubleNATError(`${publicIp} is private - please set config.nat.externalIp to an externally routable IP or ensure you are not behind a double NAT`);
|
|
84
|
+
try {
|
|
85
|
+
await Promise.all(this.portMappers.map(async (mapper) => mapper.mapIpAddresses()));
|
|
205
86
|
}
|
|
206
|
-
|
|
207
|
-
|
|
87
|
+
catch (err) {
|
|
88
|
+
this.log.error('error mapping IP addresses - %e', err);
|
|
208
89
|
}
|
|
209
90
|
}
|
|
210
91
|
}
|
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,
|
|
1
|
+
{"version":3,"file":"upnp-nat.js","sourceRoot":"","sources":["../../src/upnp-nat.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Gateway } from '@achingbrain/nat-port-mapper';
|
|
2
|
+
import type { ComponentLogger } from '@libp2p/interface';
|
|
3
|
+
import type { AddressManager } from '@libp2p/interface-internal';
|
|
4
|
+
export interface UPnPPortMapperInit {
|
|
5
|
+
gateway: Gateway;
|
|
6
|
+
externalAddressCheckInterval?: number;
|
|
7
|
+
externalAddressCheckTimeout?: number;
|
|
8
|
+
}
|
|
9
|
+
export interface UPnPPortMapperComponents {
|
|
10
|
+
logger: ComponentLogger;
|
|
11
|
+
addressManager: AddressManager;
|
|
12
|
+
}
|
|
13
|
+
export declare class UPnPPortMapper {
|
|
14
|
+
private readonly gateway;
|
|
15
|
+
private readonly externalAddress;
|
|
16
|
+
private readonly addressManager;
|
|
17
|
+
private readonly log;
|
|
18
|
+
private readonly mappedPorts;
|
|
19
|
+
private started;
|
|
20
|
+
constructor(components: UPnPPortMapperComponents, init: UPnPPortMapperInit);
|
|
21
|
+
start(): Promise<void>;
|
|
22
|
+
stop(): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Update the local address mappings when the gateway's external interface
|
|
25
|
+
* address changes
|
|
26
|
+
*/
|
|
27
|
+
private remapPorts;
|
|
28
|
+
/**
|
|
29
|
+
* Return any eligible multiaddrs that are not mapped on the detected gateway
|
|
30
|
+
*/
|
|
31
|
+
private getUnmappedAddresses;
|
|
32
|
+
mapIpAddresses(): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Some ISPs have double-NATs, there's not much we can do with them
|
|
35
|
+
*/
|
|
36
|
+
private assertNotBehindDoubleNAT;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=upnp-port-mapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upnp-port-mapper.d.ts","sourceRoot":"","sources":["../../src/upnp-port-mapper.ts"],"names":[],"mappings":"AAUA,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;AAGhE,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,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;IAkDtB,cAAc,IAAK,OAAO,CAAC,IAAI,CAAC;IAsDtC;;OAEG;IACH,OAAO,CAAC,wBAAwB;CAWjC"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { isIPv4 } from '@chainsafe/is-ip';
|
|
2
|
+
import { InvalidParametersError, start, stop } from '@libp2p/interface';
|
|
3
|
+
import { isLinkLocal } from '@libp2p/utils/multiaddr/is-link-local';
|
|
4
|
+
import { isLoopback } from '@libp2p/utils/multiaddr/is-loopback';
|
|
5
|
+
import { isPrivate } from '@libp2p/utils/multiaddr/is-private';
|
|
6
|
+
import { isPrivateIp } from '@libp2p/utils/private-ip';
|
|
7
|
+
import { QUICV1, TCP, WebSockets, WebSocketsSecure, WebTransport } from '@multiformats/multiaddr-matcher';
|
|
8
|
+
import { dynamicExternalAddress } from './check-external-address.js';
|
|
9
|
+
import { DoubleNATError } from './errors.js';
|
|
10
|
+
export class UPnPPortMapper {
|
|
11
|
+
gateway;
|
|
12
|
+
externalAddress;
|
|
13
|
+
addressManager;
|
|
14
|
+
log;
|
|
15
|
+
mappedPorts;
|
|
16
|
+
started;
|
|
17
|
+
constructor(components, init) {
|
|
18
|
+
this.log = components.logger.forComponent(`libp2p:upnp-nat:gateway:${init.gateway.id}`);
|
|
19
|
+
this.addressManager = components.addressManager;
|
|
20
|
+
this.gateway = init.gateway;
|
|
21
|
+
this.externalAddress = dynamicExternalAddress({
|
|
22
|
+
gateway: this.gateway,
|
|
23
|
+
addressManager: this.addressManager,
|
|
24
|
+
logger: components.logger
|
|
25
|
+
}, {
|
|
26
|
+
interval: init.externalAddressCheckInterval,
|
|
27
|
+
timeout: init.externalAddressCheckTimeout,
|
|
28
|
+
onExternalAddressChange: this.remapPorts.bind(this)
|
|
29
|
+
});
|
|
30
|
+
this.gateway = init.gateway;
|
|
31
|
+
this.mappedPorts = new Map();
|
|
32
|
+
this.started = false;
|
|
33
|
+
}
|
|
34
|
+
async start() {
|
|
35
|
+
if (this.started) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
await start(this.externalAddress);
|
|
39
|
+
this.started = true;
|
|
40
|
+
}
|
|
41
|
+
async stop() {
|
|
42
|
+
try {
|
|
43
|
+
const shutdownTimeout = AbortSignal.timeout(1000);
|
|
44
|
+
await this.gateway.stop({
|
|
45
|
+
signal: shutdownTimeout
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
this.log.error('error closing gateway - %e', err);
|
|
50
|
+
}
|
|
51
|
+
await stop(this.externalAddress);
|
|
52
|
+
this.started = false;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Update the local address mappings when the gateway's external interface
|
|
56
|
+
* address changes
|
|
57
|
+
*/
|
|
58
|
+
remapPorts(newExternalHost) {
|
|
59
|
+
for (const [key, { externalHost, externalPort }] of this.mappedPorts.entries()) {
|
|
60
|
+
const [host, port, transport] = key.split('-');
|
|
61
|
+
this.addressManager.removePublicAddressMapping(host, parseInt(port), externalHost, externalPort, transport === 'tcp' ? 'tcp' : 'udp');
|
|
62
|
+
this.addressManager.addPublicAddressMapping(host, parseInt(port), newExternalHost, externalPort, transport === 'tcp' ? 'tcp' : 'udp');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Return any eligible multiaddrs that are not mapped on the detected gateway
|
|
67
|
+
*/
|
|
68
|
+
getUnmappedAddresses(multiaddrs, publicAddresses) {
|
|
69
|
+
const output = [];
|
|
70
|
+
for (const ma of multiaddrs) {
|
|
71
|
+
const stringTuples = ma.stringTuples();
|
|
72
|
+
const address = `${stringTuples[0][1]}`;
|
|
73
|
+
// ignore public IPv4 addresses
|
|
74
|
+
if (isIPv4(address) && !isPrivate(ma)) {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
// ignore any addresses that match the interface on the network gateway
|
|
78
|
+
if (publicAddresses.includes(address)) {
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
// ignore loopback
|
|
82
|
+
if (isLoopback(ma)) {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
// ignore link-local addresses
|
|
86
|
+
if (isLinkLocal(ma)) {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
// only IP based addresses
|
|
90
|
+
if (!(TCP.exactMatch(ma) ||
|
|
91
|
+
WebSockets.exactMatch(ma) ||
|
|
92
|
+
WebSocketsSecure.exactMatch(ma) ||
|
|
93
|
+
QUICV1.exactMatch(ma) ||
|
|
94
|
+
WebTransport.exactMatch(ma))) {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
const { port, transport } = ma.toOptions();
|
|
98
|
+
if (this.mappedPorts.has(`${port}-${transport}`)) {
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
output.push(ma);
|
|
102
|
+
}
|
|
103
|
+
return output;
|
|
104
|
+
}
|
|
105
|
+
async mapIpAddresses() {
|
|
106
|
+
try {
|
|
107
|
+
const externalHost = await this.externalAddress.getPublicIp();
|
|
108
|
+
// filter addresses to get private, non-relay, IP based addresses that we
|
|
109
|
+
// haven't mapped yet
|
|
110
|
+
const addresses = this.getUnmappedAddresses(this.addressManager.getAddresses(), [externalHost]);
|
|
111
|
+
if (addresses.length === 0) {
|
|
112
|
+
this.log('no private, non-relay, unmapped, IP based addresses found');
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
this.log('discovered public IP %s', externalHost);
|
|
116
|
+
this.assertNotBehindDoubleNAT(externalHost);
|
|
117
|
+
for (const addr of addresses) {
|
|
118
|
+
// try to open uPnP ports for each thin waist address
|
|
119
|
+
const { port, host, transport, family } = addr.toOptions();
|
|
120
|
+
// don't try to open port on IPv6 host via IPv4 gateway
|
|
121
|
+
if (family === 4 && this.gateway.family !== 'IPv4') {
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
// don't try to open port on IPv4 host via IPv6 gateway
|
|
125
|
+
if (family === 6 && this.gateway.family !== 'IPv6') {
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
const key = `${host}-${port}-${transport}`;
|
|
129
|
+
if (this.mappedPorts.has(key)) {
|
|
130
|
+
// already mapped this port
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
try {
|
|
134
|
+
const mapping = await this.gateway.map(port, host, {
|
|
135
|
+
protocol: transport === 'tcp' ? 'TCP' : 'UDP'
|
|
136
|
+
});
|
|
137
|
+
this.mappedPorts.set(key, mapping);
|
|
138
|
+
this.addressManager.addPublicAddressMapping(mapping.internalHost, mapping.internalPort, mapping.externalHost, mapping.externalPort, transport === 'tcp' ? 'tcp' : 'udp');
|
|
139
|
+
this.log('created mapping of %s:%s to %s:%s for protocol %s', mapping.internalHost, mapping.internalPort, mapping.externalHost, mapping.externalPort, transport);
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
this.log.error('failed to create mapping for %s:%d for protocol - %e', host, port, transport, err);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
this.log.error('error finding gateways - %e', err);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Some ISPs have double-NATs, there's not much we can do with them
|
|
152
|
+
*/
|
|
153
|
+
assertNotBehindDoubleNAT(publicIp) {
|
|
154
|
+
const isPrivate = isPrivateIp(publicIp);
|
|
155
|
+
if (isPrivate === true) {
|
|
156
|
+
throw new DoubleNATError(`${publicIp} is private - please init uPnPNAT with 'externalAddress' set to an externally routable IP or ensure you are not behind a double NAT`);
|
|
157
|
+
}
|
|
158
|
+
if (isPrivate == null) {
|
|
159
|
+
throw new InvalidParametersError(`${publicIp} is not an IP address`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=upnp-port-mapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upnp-port-mapper.js","sourceRoot":"","sources":["../../src/upnp-port-mapper.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@libp2p/upnp-nat",
|
|
3
|
-
"version": "2.0.12-
|
|
3
|
+
"version": "2.0.12-6ab85ea68",
|
|
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",
|
|
@@ -50,21 +50,21 @@
|
|
|
50
50
|
"test:electron-main": "aegir test -t electron-main"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@achingbrain/nat-port-mapper": "^
|
|
53
|
+
"@achingbrain/nat-port-mapper": "^4.0.0",
|
|
54
54
|
"@chainsafe/is-ip": "^2.0.2",
|
|
55
|
-
"@libp2p/interface": "2.2.1-
|
|
56
|
-
"@libp2p/interface-internal": "2.1.1-
|
|
57
|
-
"@libp2p/utils": "6.2.1-
|
|
58
|
-
"@multiformats/multiaddr": "^12.
|
|
59
|
-
"@multiformats/multiaddr-matcher": "^1.
|
|
55
|
+
"@libp2p/interface": "2.2.1-6ab85ea68",
|
|
56
|
+
"@libp2p/interface-internal": "2.1.1-6ab85ea68",
|
|
57
|
+
"@libp2p/utils": "6.2.1-6ab85ea68",
|
|
58
|
+
"@multiformats/multiaddr": "^12.3.3",
|
|
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.7-
|
|
65
|
-
"@libp2p/logger": "5.1.4-
|
|
66
|
-
"@libp2p/peer-id": "5.0.8-
|
|
67
|
-
"aegir": "^
|
|
64
|
+
"@libp2p/crypto": "5.0.7-6ab85ea68",
|
|
65
|
+
"@libp2p/logger": "5.1.4-6ab85ea68",
|
|
66
|
+
"@libp2p/peer-id": "5.0.8-6ab85ea68",
|
|
67
|
+
"aegir": "^45.0.5",
|
|
68
68
|
"sinon-ts": "^2.0.0"
|
|
69
69
|
},
|
|
70
70
|
"sideEffects": false
|