@libp2p/upnp-nat 2.0.12-b248eefc0 → 2.0.12-bc90b4fd5

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.
@@ -9,11 +9,11 @@ export interface ExternalAddressCheckerComponents {
9
9
  export interface ExternalAddressCheckerInit {
10
10
  interval?: number;
11
11
  timeout?: number;
12
- autoConfirmAddress?: boolean;
12
+ onExternalAddressChange?(newExternalAddress: string): void;
13
13
  }
14
14
  export interface ExternalAddress {
15
15
  getPublicIp(options?: AbortOptions): Promise<string> | string;
16
16
  }
17
- export declare function dynamicExternalAddress(components: ExternalAddressCheckerComponents, init?: ExternalAddressCheckerInit): ExternalAddress;
17
+ export declare function dynamicExternalAddress(components: ExternalAddressCheckerComponents, init: ExternalAddressCheckerInit): ExternalAddress;
18
18
  export declare function staticExternalAddress(address: string): ExternalAddress;
19
19
  //# sourceMappingURL=check-external-address.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"check-external-address.d.ts","sourceRoot":"","sources":["../../src/check-external-address.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAA;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAqB,MAAM,mBAAmB,CAAA;AACzF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAIhE,MAAM,WAAW,gCAAgC;IAC/C,MAAM,EAAE,MAAM,CAAA;IACd,cAAc,EAAE,cAAc,CAAA;IAC9B,MAAM,EAAE,eAAe,CAAA;CACxB;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAC7B;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,CAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAA;CAC/D;AAyGD,wBAAgB,sBAAsB,CAAE,UAAU,EAAE,gCAAgC,EAAE,IAAI,GAAE,0BAA+B,GAAG,eAAe,CAE5I;AAED,wBAAgB,qBAAqB,CAAE,OAAO,EAAE,MAAM,GAAG,eAAe,CAIvE"}
1
+ {"version":3,"file":"check-external-address.d.ts","sourceRoot":"","sources":["../../src/check-external-address.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAA;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAqB,MAAM,mBAAmB,CAAA;AACzF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAIhE,MAAM,WAAW,gCAAgC;IAC/C,MAAM,EAAE,MAAM,CAAA;IACd,cAAc,EAAE,cAAc,CAAA;IAC9B,MAAM,EAAE,eAAe,CAAA;CACxB;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,uBAAuB,CAAC,CAAC,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAA;CAC3D;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,CAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAA;CAC/D;AAuFD,wBAAgB,sBAAsB,CAAE,UAAU,EAAE,gCAAgC,EAAE,IAAI,EAAE,0BAA0B,GAAG,eAAe,CAEvI;AAED,wBAAgB,qBAAqB,CAAE,OAAO,EAAE,MAAM,GAAG,eAAe,CAIvE"}
@@ -1,6 +1,5 @@
1
1
  import { NotStartedError, start, stop } from '@libp2p/interface';
2
2
  import { repeatingTask } from '@libp2p/utils/repeating-task';
3
- import { multiaddr } from '@multiformats/multiaddr';
4
3
  import pDefer from 'p-defer';
5
4
  import { raceSignal } from 'race-signal';
6
5
  /**
@@ -14,12 +13,12 @@ class ExternalAddressChecker {
14
13
  lastPublicIp;
15
14
  lastPublicIpPromise;
16
15
  check;
17
- autoConfirmAddress;
18
- constructor(components, init = {}) {
16
+ onExternalAddressChange;
17
+ constructor(components, init) {
19
18
  this.log = components.logger.forComponent('libp2p:upnp-nat:external-address-check');
20
19
  this.client = components.client;
21
20
  this.addressManager = components.addressManager;
22
- this.autoConfirmAddress = init.autoConfirmAddress ?? false;
21
+ this.onExternalAddressChange = init.onExternalAddressChange;
23
22
  this.started = false;
24
23
  this.checkExternalAddress = this.checkExternalAddress.bind(this);
25
24
  this.lastPublicIpPromise = pDefer();
@@ -57,23 +56,8 @@ class ExternalAddressChecker {
57
56
  // check if our public address has changed
58
57
  if (this.lastPublicIp != null && externalAddress !== this.lastPublicIp) {
59
58
  this.log('external address changed from %s to %s', this.lastPublicIp, externalAddress);
60
- for (const ma of this.addressManager.getAddresses()) {
61
- const addrString = ma.toString();
62
- if (!addrString.includes(this.lastPublicIp)) {
63
- continue;
64
- }
65
- // create a new version of the multiaddr with the new public IP
66
- const newAddress = multiaddr(addrString.replace(this.lastPublicIp, externalAddress));
67
- // remove the old address and add the new one
68
- this.addressManager.removeObservedAddr(ma);
69
- this.addressManager.confirmObservedAddr(newAddress);
70
- if (this.autoConfirmAddress) {
71
- this.addressManager.confirmObservedAddr(newAddress);
72
- }
73
- else {
74
- this.addressManager.addObservedAddr(newAddress);
75
- }
76
- }
59
+ // notify listeners that the address has changed
60
+ this.onExternalAddressChange?.(externalAddress);
77
61
  }
78
62
  this.lastPublicIp = externalAddress;
79
63
  this.lastPublicIpPromise.resolve(externalAddress);
@@ -87,7 +71,7 @@ class ExternalAddressChecker {
87
71
  }
88
72
  }
89
73
  }
90
- export function dynamicExternalAddress(components, init = {}) {
74
+ export function dynamicExternalAddress(components, init) {
91
75
  return new ExternalAddressChecker(components, init);
92
76
  }
93
77
  export function staticExternalAddress(address) {
@@ -1 +1 @@
1
- {"version":3,"file":"check-external-address.js","sourceRoot":"","sources":["../../src/check-external-address.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"check-external-address.js","sourceRoot":"","sources":["../../src/check-external-address.ts"],"names":[],"mappings":"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"}
@@ -84,14 +84,6 @@ export interface UPnPNATInit {
84
84
  * Pass a value to use instead of auto-detection
85
85
  */
86
86
  gateway?: string;
87
- /**
88
- * How long in ms to wait before giving up trying to auto-detect a
89
- * `urn:schemas-upnp-org:device:InternetGatewayDevice:1` device on the local
90
- * network
91
- *
92
- * @default 10000
93
- */
94
- gatewayDetectionTimeout?: number;
95
87
  /**
96
88
  * Ports are mapped when the `self:peer:update` event fires, which happens
97
89
  * when the node's addresses change. To avoid starting to map ports while
@@ -106,16 +98,6 @@ export interface UPnPNATInit {
106
98
  * otherwise one will be created
107
99
  */
108
100
  client?: NatAPI;
109
- /**
110
- * Any mapped addresses are added to the observed address list. These
111
- * addresses require additional verification by the `@libp2p/autonat` protocol
112
- * or similar before they are trusted.
113
- *
114
- * To skip this verification and trust them immediately pass `true` here
115
- *
116
- * @default false
117
- */
118
- autoConfirmAddress?: boolean;
119
101
  }
120
102
  export interface UPnPNATComponents {
121
103
  peerId: PeerId;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EAA2B,KAAK,MAAM,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAA;AACzF,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,MAAM,EAAE,cAAc,EAAE,CAAA;AAEtC,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IAExB;;;;;OAKG;IACH,4BAA4B,CAAC,EAAE,MAAM,CAAA;IAErC;;;;;OAKG;IACH,2BAA2B,CAAC,EAAE,MAAM,CAAA;IAEpC;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IAErB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IAEZ;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IAEnB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAEhB;;;;;;OAMG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAEhC;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IAEd;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf;;;;;;;;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,MAAM,EAAE,MAAM,CAAA;CACf;AAED,wBAAgB,OAAO,CAAE,IAAI,GAAE,WAAgB,GAAG,CAAC,UAAU,EAAE,iBAAiB,KAAK,OAAO,CAI3F"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EAA2B,KAAK,MAAM,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAA;AACzF,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,MAAM,EAAE,cAAc,EAAE,CAAA;AAEtC,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IAExB;;;;;OAKG;IACH,4BAA4B,CAAC,EAAE,MAAM,CAAA;IAErC;;;;;OAKG;IACH,2BAA2B,CAAC,EAAE,MAAM,CAAA;IAEpC;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IAErB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IAEZ;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IAEnB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAEhB;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IAEd;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;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,MAAM,EAAE,MAAM,CAAA;CACf;AAED,wBAAgB,OAAO,CAAE,IAAI,GAAE,WAAgB,GAAG,CAAC,UAAU,EAAE,iBAAiB,KAAK,OAAO,CAI3F"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EAAE,OAAO,IAAI,YAAY,EAAoC,MAAM,eAAe,CAAA;AA8GzF,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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EAAE,OAAO,IAAI,YAAY,EAAoC,MAAM,eAAe,CAAA;AA0FzF,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"}
@@ -1,4 +1,4 @@
1
- import { serviceCapabilities, serviceDependencies } from '@libp2p/interface';
1
+ import { serviceCapabilities } from '@libp2p/interface';
2
2
  import type { UPnPNATComponents, UPnPNATInit, UPnPNAT as UPnPNATInterface } from './index.js';
3
3
  import type { NatAPI, MapPortOptions } from '@achingbrain/nat-port-mapper';
4
4
  import type { Startable } from '@libp2p/interface';
@@ -8,21 +8,18 @@ export declare class UPnPNAT implements Startable, UPnPNATInterface {
8
8
  private readonly addressManager;
9
9
  private readonly events;
10
10
  private readonly externalAddress;
11
- private readonly localAddress?;
12
11
  private readonly description;
13
12
  private readonly ttl;
14
13
  private readonly keepAlive;
15
14
  private readonly gateway?;
16
15
  private started;
17
16
  private readonly log;
18
- private readonly gatewayDetectionTimeout;
19
17
  private readonly mappedPorts;
20
18
  private readonly onSelfPeerUpdate;
21
- private readonly autoConfirmAddress;
19
+ private shutdownController?;
22
20
  constructor(components: UPnPNATComponents, init: UPnPNATInit);
23
21
  readonly [Symbol.toStringTag] = "@libp2p/upnp-nat";
24
22
  readonly [serviceCapabilities]: string[];
25
- get [serviceDependencies](): string[];
26
23
  isStarted(): boolean;
27
24
  start(): Promise<void>;
28
25
  /**
@@ -36,5 +33,10 @@ export declare class UPnPNAT implements Startable, UPnPNATInterface {
36
33
  * Some ISPs have double-NATs, there's not much we can do with them
37
34
  */
38
35
  private assertNotBehindDoubleNAT;
36
+ /**
37
+ * Update the local address mappings when the gateway's external interface
38
+ * address changes
39
+ */
40
+ private remapPorts;
39
41
  }
40
42
  //# sourceMappingURL=upnp-nat.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"upnp-nat.d.ts","sourceRoot":"","sources":["../../src/upnp-nat.ts"],"names":[],"mappings":"AAEA,OAAO,EAA0B,mBAAmB,EAAE,mBAAmB,EAAe,MAAM,mBAAmB,CAAA;AAWjH,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAC7F,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAC1E,OAAO,KAAK,EAAwB,SAAS,EAAoB,MAAM,mBAAmB,CAAA;AAO1F,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,CAAA;AAEtC,qBAAa,OAAQ,YAAW,SAAS,EAAE,gBAAgB;IAClD,MAAM,EAAE,MAAM,CAAA;IACrB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgB;IAC/C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgC;IACvD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiB;IACjD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAQ;IACtC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAQ;IACpC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAQ;IACjC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;IAC5B,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAQ;IAChD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmB;IACpD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;gBAE/B,UAAU,EAAE,iBAAiB,EAAE,IAAI,EAAE,WAAW;IA0C7D,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;IAU7B;;OAEG;IACG,IAAI,IAAK,OAAO,CAAC,IAAI,CAAC;IAY5B,iBAAiB,IAAK,IAAI;IAO1B,OAAO,CAAC,oBAAoB;IAyCtB,cAAc,IAAK,OAAO,CAAC,IAAI,CAAC;IAyEtC;;OAEG;IACH,OAAO,CAAC,wBAAwB;CAWjC"}
1
+ {"version":3,"file":"upnp-nat.d.ts","sourceRoot":"","sources":["../../src/upnp-nat.ts"],"names":[],"mappings":"AAEA,OAAO,EAA0B,mBAAmB,EAAgC,MAAM,mBAAmB,CAAA;AAS7G,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAC7F,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAC1E,OAAO,KAAK,EAAwB,SAAS,EAAoB,MAAM,mBAAmB,CAAA;AAO1F,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,CAAA;AAOtC,qBAAa,OAAQ,YAAW,SAAS,EAAE,gBAAgB;IAClD,MAAM,EAAE,MAAM,CAAA;IACrB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgB;IAC/C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgC;IACvD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiB;IACjD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAQ;IACpC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAQ;IACjC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;IAC5B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA0B;IACtD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmB;IACpD,OAAO,CAAC,kBAAkB,CAAC,CAAiB;gBAE/B,UAAU,EAAE,iBAAiB,EAAE,IAAI,EAAE,WAAW;IAuC7D,QAAQ,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,sBAAqB;IAElD,QAAQ,CAAC,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAEvC;IAED,SAAS,IAAK,OAAO;IAIf,KAAK,IAAK,OAAO,CAAC,IAAI,CAAC;IAY7B;;OAEG;IACG,IAAI,IAAK,OAAO,CAAC,IAAI,CAAC;IAa5B,iBAAiB,IAAK,IAAI;IAO1B,OAAO,CAAC,oBAAoB;IAyCtB,cAAc,IAAK,OAAO,CAAC,IAAI,CAAC;IAgEtC;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAYhC;;;OAGG;IACH,OAAO,CAAC,UAAU;CAYnB"}
@@ -1,13 +1,11 @@
1
1
  import { upnpNat } from '@achingbrain/nat-port-mapper';
2
2
  import { isIPv4, isIPv6 } from '@chainsafe/is-ip';
3
- import { InvalidParametersError, serviceCapabilities, serviceDependencies, start, stop } from '@libp2p/interface';
3
+ import { InvalidParametersError, serviceCapabilities, setMaxListeners, start, stop } from '@libp2p/interface';
4
4
  import { debounce } from '@libp2p/utils/debounce';
5
5
  import { isLoopback } from '@libp2p/utils/multiaddr/is-loopback';
6
6
  import { isPrivate } from '@libp2p/utils/multiaddr/is-private';
7
7
  import { isPrivateIp } from '@libp2p/utils/private-ip';
8
- import { multiaddr } from '@multiformats/multiaddr';
9
8
  import { QUICV1, TCP, WebSockets, WebSocketsSecure, WebTransport } from '@multiformats/multiaddr-matcher';
10
- import { raceSignal } from 'race-signal';
11
9
  import { dynamicExternalAddress, staticExternalAddress } from './check-external-address.js';
12
10
  import { DoubleNATError, InvalidIPAddressError } from './errors.js';
13
11
  const DEFAULT_TTL = 7200;
@@ -16,29 +14,24 @@ export class UPnPNAT {
16
14
  addressManager;
17
15
  events;
18
16
  externalAddress;
19
- localAddress;
20
17
  description;
21
18
  ttl;
22
19
  keepAlive;
23
20
  gateway;
24
21
  started;
25
22
  log;
26
- gatewayDetectionTimeout;
27
23
  mappedPorts;
28
24
  onSelfPeerUpdate;
29
- autoConfirmAddress;
25
+ shutdownController;
30
26
  constructor(components, init) {
31
27
  this.log = components.logger.forComponent('libp2p:upnp-nat');
32
28
  this.addressManager = components.addressManager;
33
29
  this.events = components.events;
34
30
  this.started = false;
35
- this.localAddress = init.localAddress;
36
31
  this.description = init.description ?? `${components.nodeInfo.name}@${components.nodeInfo.version} ${components.peerId.toString()}`;
37
32
  this.ttl = init.ttl ?? DEFAULT_TTL;
38
33
  this.keepAlive = init.keepAlive ?? true;
39
34
  this.gateway = init.gateway;
40
- this.gatewayDetectionTimeout = init.gatewayDetectionTimeout ?? 10000;
41
- this.autoConfirmAddress = init.autoConfirmAddress ?? false;
42
35
  this.mappedPorts = new Map();
43
36
  if (this.ttl < DEFAULT_TTL) {
44
37
  throw new InvalidParametersError(`NatManager ttl should be at least ${DEFAULT_TTL} seconds`);
@@ -59,9 +52,9 @@ export class UPnPNAT {
59
52
  addressManager: this.addressManager,
60
53
  logger: components.logger
61
54
  }, {
62
- autoConfirmAddress: init.autoConfirmAddress,
63
55
  interval: init.externalAddressCheckInterval,
64
- timeout: init.externalAddressCheckTimeout
56
+ timeout: init.externalAddressCheckTimeout,
57
+ onExternalAddressChange: this.remapPorts.bind(this)
65
58
  });
66
59
  }
67
60
  }
@@ -69,14 +62,6 @@ export class UPnPNAT {
69
62
  [serviceCapabilities] = [
70
63
  '@libp2p/nat-traversal'
71
64
  ];
72
- get [serviceDependencies]() {
73
- if (!this.autoConfirmAddress) {
74
- return [
75
- '@libp2p/autonat'
76
- ];
77
- }
78
- return [];
79
- }
80
65
  isStarted() {
81
66
  return this.started;
82
67
  }
@@ -85,6 +70,8 @@ export class UPnPNAT {
85
70
  return;
86
71
  }
87
72
  this.started = true;
73
+ this.shutdownController = new AbortController();
74
+ setMaxListeners(Infinity, this.shutdownController.signal);
88
75
  this.events.addEventListener('self:peer:update', this.onSelfPeerUpdate);
89
76
  await start(this.externalAddress, this.onSelfPeerUpdate);
90
77
  }
@@ -98,6 +85,7 @@ export class UPnPNAT {
98
85
  catch (err) {
99
86
  this.log.error(err);
100
87
  }
88
+ this.shutdownController?.abort();
101
89
  this.events.removeEventListener('self:peer:update', this.onSelfPeerUpdate);
102
90
  await stop(this.externalAddress, this.onSelfPeerUpdate);
103
91
  this.started = false;
@@ -127,11 +115,11 @@ export class UPnPNAT {
127
115
  WebTransport.exactMatch(ma))) {
128
116
  continue;
129
117
  }
130
- const { port, family } = ma.toOptions();
118
+ const { port, host, family, transport } = ma.toOptions();
131
119
  if (family !== ipType) {
132
120
  continue;
133
121
  }
134
- if (this.mappedPorts.has(port)) {
122
+ if (this.mappedPorts.has(`${host}-${port}-${transport}`)) {
135
123
  continue;
136
124
  }
137
125
  output.push(ma);
@@ -139,24 +127,18 @@ export class UPnPNAT {
139
127
  return output;
140
128
  }
141
129
  async mapIpAddresses() {
142
- if (this.externalAddress == null) {
143
- this.log('discovering public address');
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`
130
+ const externalHost = await this.externalAddress.getPublicIp({
131
+ signal: this.shutdownController?.signal
150
132
  });
151
133
  let ipType = 4;
152
- if (isIPv4(publicIp)) {
134
+ if (isIPv4(externalHost)) {
153
135
  ipType = 4;
154
136
  }
155
- else if (isIPv6(publicIp)) {
137
+ else if (isIPv6(externalHost)) {
156
138
  ipType = 6;
157
139
  }
158
140
  else {
159
- throw new InvalidIPAddressError(`Public address ${publicIp} was not an IPv4 address`);
141
+ throw new InvalidIPAddressError(`Public address ${externalHost} was not an IPv4 address`);
160
142
  }
161
143
  // filter addresses to get private, non-relay, IP based addresses that we
162
144
  // haven't mapped yet
@@ -165,8 +147,8 @@ export class UPnPNAT {
165
147
  this.log('no private, non-relay, unmapped, IP based addresses found');
166
148
  return;
167
149
  }
168
- this.log('%s public IP %s', this.externalAddress != null ? 'using configured' : 'discovered', publicIp);
169
- this.assertNotBehindDoubleNAT(publicIp);
150
+ this.log('%s public IP %s', this.externalAddress != null ? 'using configured' : 'discovered', externalHost);
151
+ this.assertNotBehindDoubleNAT(externalHost);
170
152
  for (const addr of addresses) {
171
153
  // try to open uPnP ports for each thin waist address
172
154
  const { family, host, port, transport } = addr.toOptions();
@@ -174,24 +156,25 @@ export class UPnPNAT {
174
156
  // only support IPv4 addresses
175
157
  continue;
176
158
  }
177
- if (this.mappedPorts.has(port)) {
159
+ if (this.mappedPorts.has(`${host}-${port}-${transport}`)) {
178
160
  // already mapped this port
179
161
  continue;
180
162
  }
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);
163
+ try {
164
+ this.log(`creating mapping of %s:%s key ${host}-${port}-${transport}`, host, port);
165
+ const externalPort = await this.client.map(port, {
166
+ localAddress: host,
167
+ protocol: transport === 'tcp' ? 'TCP' : 'UDP'
168
+ });
169
+ this.mappedPorts.set(`${host}-${port}-${transport}`, {
170
+ externalHost,
171
+ externalPort
172
+ });
173
+ this.log('created mapping of %s:%s to %s:%s', externalHost, externalPort, host, port);
174
+ this.addressManager.addPublicAddressMapping(host, port, externalHost, externalPort, transport === 'tcp' ? 'tcp' : 'udp');
192
175
  }
193
- else {
194
- this.addressManager.addObservedAddr(ma);
176
+ catch (err) {
177
+ this.log.error('failed to create mapping of %s:%s - %e', host, port, err);
195
178
  }
196
179
  }
197
180
  }
@@ -201,11 +184,22 @@ export class UPnPNAT {
201
184
  assertNotBehindDoubleNAT(publicIp) {
202
185
  const isPrivate = isPrivateIp(publicIp);
203
186
  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`);
187
+ 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`);
205
188
  }
206
189
  if (isPrivate == null) {
207
190
  throw new InvalidParametersError(`${publicIp} is not an IP address`);
208
191
  }
209
192
  }
193
+ /**
194
+ * Update the local address mappings when the gateway's external interface
195
+ * address changes
196
+ */
197
+ remapPorts(newExternalHost) {
198
+ for (const [key, { externalHost, externalPort }] of this.mappedPorts.entries()) {
199
+ const [host, port, transport] = key.split('-');
200
+ this.addressManager.removePublicAddressMapping(host, parseInt(port), externalHost, externalPort, transport === 'tcp' ? 'tcp' : 'udp');
201
+ this.addressManager.addPublicAddressMapping(host, parseInt(port), newExternalHost, externalPort, transport === 'tcp' ? 'tcp' : 'udp');
202
+ }
203
+ }
210
204
  }
211
205
  //# sourceMappingURL=upnp-nat.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"upnp-nat.js","sourceRoot":"","sources":["../../src/upnp-nat.ts"],"names":[],"mappings":"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"}
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,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,eAAe,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAA;AAC7G,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AACjD,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,qBAAqB,EAAE,MAAM,6BAA6B,CAAA;AAC3F,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AASnE,MAAM,WAAW,GAAG,IAAI,CAAA;AASxB,MAAM,OAAO,OAAO;IACX,MAAM,CAAQ;IACJ,cAAc,CAAgB;IAC9B,MAAM,CAAgC;IACtC,eAAe,CAAiB;IAChC,WAAW,CAAQ;IACnB,GAAG,CAAQ;IACX,SAAS,CAAS;IAClB,OAAO,CAAS;IACzB,OAAO,CAAS;IACP,GAAG,CAAQ;IACX,WAAW,CAA0B;IACrC,gBAAgB,CAAmB;IAC5C,kBAAkB,CAAkB;IAE5C,YAAa,UAA6B,EAAE,IAAiB;QAC3D,IAAI,CAAC,GAAG,GAAG,UAAU,CAAC,MAAM,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAA;QAC5D,IAAI,CAAC,cAAc,GAAG,UAAU,CAAC,cAAc,CAAA;QAC/C,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,CAAA;QAC/B,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;QACpB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,IAAI,IAAI,UAAU,CAAC,QAAQ,CAAC,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAA;QACnI,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,WAAW,CAAA;QAClC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAA;QACvC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAA;QAC3B,IAAI,CAAC,WAAW,GAAG,IAAI,GAAG,EAAE,CAAA;QAE5B,IAAI,IAAI,CAAC,GAAG,GAAG,WAAW,EAAE,CAAC;YAC3B,MAAM,IAAI,sBAAsB,CAAC,qCAAqC,WAAW,UAAU,CAAC,CAAA;QAC9F,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC;YACnC,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC,CAAA;QAEF,IAAI,CAAC,gBAAgB,GAAG,QAAQ,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,CAAA;QAEvF,IAAI,OAAO,IAAI,CAAC,eAAe,KAAK,QAAQ,EAAE,CAAC;YAC7C,IAAI,CAAC,eAAe,GAAG,qBAAqB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;QACpE,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,eAAe,GAAG,sBAAsB,CAAC;gBAC5C,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,cAAc,EAAE,IAAI,CAAC,cAAc;gBACnC,MAAM,EAAE,UAAU,CAAC,MAAM;aAC1B,EAAE;gBACD,QAAQ,EAAE,IAAI,CAAC,4BAA4B;gBAC3C,OAAO,EAAE,IAAI,CAAC,2BAA2B;gBACzC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;aACpD,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAEQ,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,kBAAkB,CAAA;IAEzC,CAAC,mBAAmB,CAAC,GAAa;QACzC,uBAAuB;KACxB,CAAA;IAED,SAAS;QACP,OAAO,IAAI,CAAC,OAAO,CAAA;IACrB,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,OAAM;QACR,CAAC;QAED,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;QACnB,IAAI,CAAC,kBAAkB,GAAG,IAAI,eAAe,EAAE,CAAA;QAC/C,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAA;QACzD,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAA;QACvE,MAAM,KAAK,CAAC,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAA;IAC1D,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI;QACR,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,CAAA;QAC5B,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QACrB,CAAC;QAED,IAAI,CAAC,kBAAkB,EAAE,KAAK,EAAE,CAAA;QAChC,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,kBAAkB,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAA;QAC1E,MAAM,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAA;QACvD,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;IACtB,CAAC;IAED,iBAAiB;QACf,IAAI,CAAC,cAAc,EAAE;aAClB,KAAK,CAAC,GAAG,CAAC,EAAE;YACX,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,iCAAiC,EAAE,GAAG,CAAC,CAAA;QACxD,CAAC,CAAC,CAAA;IACN,CAAC;IAEO,oBAAoB,CAAE,UAAuB,EAAE,MAAa;QAClE,MAAM,MAAM,GAAgB,EAAE,CAAA;QAE9B,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;YAC5B,0BAA0B;YAC1B,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC;gBACnB,SAAQ;YACV,CAAC;YAED,kBAAkB;YAClB,IAAI,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC;gBACnB,SAAQ;YACV,CAAC;YAED,0BAA0B;YAC1B,IAAI,CAAC,CACH,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;gBAClB,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBACzB,gBAAgB,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC/B,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;gBACrB,YAAY,CAAC,UAAU,CAAC,EAAE,CAAC,CAC5B,EAAE,CAAC;gBACF,SAAQ;YACV,CAAC;YAED,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,SAAS,EAAE,CAAA;YAExD,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;gBACtB,SAAQ;YACV,CAAC;YAED,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,IAAI,IAAI,IAAI,IAAI,SAAS,EAAE,CAAC,EAAE,CAAC;gBACzD,SAAQ;YACV,CAAC;YAED,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACjB,CAAC;QAED,OAAO,MAAM,CAAA;IACf,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC;YAC1D,MAAM,EAAE,IAAI,CAAC,kBAAkB,EAAE,MAAM;SACxC,CAAC,CAAA;QAEF,IAAI,MAAM,GAAU,CAAC,CAAA;QAErB,IAAI,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC;YACzB,MAAM,GAAG,CAAC,CAAA;QACZ,CAAC;aAAM,IAAI,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC;YAChC,MAAM,GAAG,CAAC,CAAA;QACZ,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,qBAAqB,CAAC,kBAAkB,YAAY,0BAA0B,CAAC,CAAA;QAC3F,CAAC;QAED,yEAAyE;QACzE,qBAAqB;QACrB,MAAM,SAAS,GAAG,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,cAAc,CAAC,YAAY,EAAE,EAAE,MAAM,CAAC,CAAA;QAEvF,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAA;YACrE,OAAM;QACR,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,YAAY,EAAE,YAAY,CAAC,CAAA;QAE3G,IAAI,CAAC,wBAAwB,CAAC,YAAY,CAAC,CAAA;QAE3C,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;YAC7B,qDAAqD;YACrD,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,SAAS,EAAE,CAAA;YAE1D,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;gBACjB,8BAA8B;gBAC9B,SAAQ;YACV,CAAC;YAED,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,IAAI,IAAI,IAAI,IAAI,SAAS,EAAE,CAAC,EAAE,CAAC;gBACzD,2BAA2B;gBAC3B,SAAQ;YACV,CAAC;YAED,IAAI,CAAC;gBACH,IAAI,CAAC,GAAG,CAAC,iCAAiC,IAAI,IAAI,IAAI,IAAI,SAAS,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;gBAElF,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE;oBAC/C,YAAY,EAAE,IAAI;oBAClB,QAAQ,EAAE,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK;iBAC9C,CAAC,CAAA;gBAEF,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,IAAI,IAAI,IAAI,IAAI,SAAS,EAAE,EAAE;oBACnD,YAAY;oBACZ,YAAY;iBACb,CAAC,CAAA;gBAEF,IAAI,CAAC,GAAG,CAAC,mCAAmC,EAAE,YAAY,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;gBAErF,IAAI,CAAC,cAAc,CAAC,uBAAuB,CAAC,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;YAC1H,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,wCAAwC,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,CAAA;YAC3E,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACK,wBAAwB,CAAE,QAAgB;QAChD,MAAM,SAAS,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAA;QAEvC,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YACvB,MAAM,IAAI,cAAc,CAAC,GAAG,QAAQ,qIAAqI,CAAC,CAAA;QAC5K,CAAC;QAED,IAAI,SAAS,IAAI,IAAI,EAAE,CAAC;YACtB,MAAM,IAAI,sBAAsB,CAAC,GAAG,QAAQ,uBAAuB,CAAC,CAAA;QACtE,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,UAAU,CAAE,eAAuB;QACzC,KAAK,MAAM,CAAC,GAAG,EAAE,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC;YAC/E,MAAM,CACJ,IAAI,EACJ,IAAI,EACJ,SAAS,CACV,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YAElB,IAAI,CAAC,cAAc,CAAC,0BAA0B,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;YACrI,IAAI,CAAC,cAAc,CAAC,uBAAuB,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,eAAe,EAAE,YAAY,EAAE,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;QACvI,CAAC;IACH,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@libp2p/upnp-nat",
3
- "version": "2.0.12-b248eefc0",
3
+ "version": "2.0.12-bc90b4fd5",
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": "^2.0.1",
54
54
  "@chainsafe/is-ip": "^2.0.2",
55
- "@libp2p/interface": "2.2.1-b248eefc0",
56
- "@libp2p/interface-internal": "2.1.1-b248eefc0",
57
- "@libp2p/utils": "6.2.1-b248eefc0",
55
+ "@libp2p/interface": "2.2.1-bc90b4fd5",
56
+ "@libp2p/interface-internal": "2.1.1-bc90b4fd5",
57
+ "@libp2p/utils": "6.2.1-bc90b4fd5",
58
58
  "@multiformats/multiaddr": "^12.2.3",
59
59
  "@multiformats/multiaddr-matcher": "^1.4.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-b248eefc0",
65
- "@libp2p/logger": "5.1.4-b248eefc0",
66
- "@libp2p/peer-id": "5.0.8-b248eefc0",
64
+ "@libp2p/crypto": "5.0.7-bc90b4fd5",
65
+ "@libp2p/logger": "5.1.4-bc90b4fd5",
66
+ "@libp2p/peer-id": "5.0.8-bc90b4fd5",
67
67
  "aegir": "^44.0.1",
68
68
  "sinon-ts": "^2.0.0"
69
69
  },
@@ -1,6 +1,5 @@
1
1
  import { NotStartedError, start, stop } from '@libp2p/interface'
2
2
  import { repeatingTask } from '@libp2p/utils/repeating-task'
3
- import { multiaddr } from '@multiformats/multiaddr'
4
3
  import pDefer from 'p-defer'
5
4
  import { raceSignal } from 'race-signal'
6
5
  import type { NatAPI } from '@achingbrain/nat-port-mapper'
@@ -18,7 +17,7 @@ export interface ExternalAddressCheckerComponents {
18
17
  export interface ExternalAddressCheckerInit {
19
18
  interval?: number
20
19
  timeout?: number
21
- autoConfirmAddress?: boolean
20
+ onExternalAddressChange?(newExternalAddress: string): void
22
21
  }
23
22
 
24
23
  export interface ExternalAddress {
@@ -36,13 +35,13 @@ class ExternalAddressChecker implements ExternalAddress, Startable {
36
35
  private lastPublicIp?: string
37
36
  private readonly lastPublicIpPromise: DeferredPromise<string>
38
37
  private readonly check: RepeatingTask
39
- private readonly autoConfirmAddress: boolean
38
+ private readonly onExternalAddressChange?: (newExternalAddress: string) => void
40
39
 
41
- constructor (components: ExternalAddressCheckerComponents, init: ExternalAddressCheckerInit = {}) {
40
+ constructor (components: ExternalAddressCheckerComponents, init: ExternalAddressCheckerInit) {
42
41
  this.log = components.logger.forComponent('libp2p:upnp-nat:external-address-check')
43
42
  this.client = components.client
44
43
  this.addressManager = components.addressManager
45
- this.autoConfirmAddress = init.autoConfirmAddress ?? false
44
+ this.onExternalAddressChange = init.onExternalAddressChange
46
45
  this.started = false
47
46
 
48
47
  this.checkExternalAddress = this.checkExternalAddress.bind(this)
@@ -93,26 +92,8 @@ class ExternalAddressChecker implements ExternalAddress, Startable {
93
92
  if (this.lastPublicIp != null && externalAddress !== this.lastPublicIp) {
94
93
  this.log('external address changed from %s to %s', this.lastPublicIp, externalAddress)
95
94
 
96
- for (const ma of this.addressManager.getAddresses()) {
97
- const addrString = ma.toString()
98
-
99
- if (!addrString.includes(this.lastPublicIp)) {
100
- continue
101
- }
102
-
103
- // create a new version of the multiaddr with the new public IP
104
- const newAddress = multiaddr(addrString.replace(this.lastPublicIp, externalAddress))
105
-
106
- // remove the old address and add the new one
107
- this.addressManager.removeObservedAddr(ma)
108
- this.addressManager.confirmObservedAddr(newAddress)
109
-
110
- if (this.autoConfirmAddress) {
111
- this.addressManager.confirmObservedAddr(newAddress)
112
- } else {
113
- this.addressManager.addObservedAddr(newAddress)
114
- }
115
- }
95
+ // notify listeners that the address has changed
96
+ this.onExternalAddressChange?.(externalAddress)
116
97
  }
117
98
 
118
99
  this.lastPublicIp = externalAddress
@@ -128,7 +109,7 @@ class ExternalAddressChecker implements ExternalAddress, Startable {
128
109
  }
129
110
  }
130
111
 
131
- export function dynamicExternalAddress (components: ExternalAddressCheckerComponents, init: ExternalAddressCheckerInit = {}): ExternalAddress {
112
+ export function dynamicExternalAddress (components: ExternalAddressCheckerComponents, init: ExternalAddressCheckerInit): ExternalAddress {
132
113
  return new ExternalAddressChecker(components, init)
133
114
  }
134
115
 
package/src/index.ts CHANGED
@@ -96,15 +96,6 @@ export interface UPnPNATInit {
96
96
  */
97
97
  gateway?: string
98
98
 
99
- /**
100
- * How long in ms to wait before giving up trying to auto-detect a
101
- * `urn:schemas-upnp-org:device:InternetGatewayDevice:1` device on the local
102
- * network
103
- *
104
- * @default 10000
105
- */
106
- gatewayDetectionTimeout?: number
107
-
108
99
  /**
109
100
  * Ports are mapped when the `self:peer:update` event fires, which happens
110
101
  * when the node's addresses change. To avoid starting to map ports while
@@ -120,17 +111,6 @@ export interface UPnPNATInit {
120
111
  * otherwise one will be created
121
112
  */
122
113
  client?: NatAPI
123
-
124
- /**
125
- * Any mapped addresses are added to the observed address list. These
126
- * addresses require additional verification by the `@libp2p/autonat` protocol
127
- * or similar before they are trusted.
128
- *
129
- * To skip this verification and trust them immediately pass `true` here
130
- *
131
- * @default false
132
- */
133
- autoConfirmAddress?: boolean
134
114
  }
135
115
 
136
116
  export interface UPnPNATComponents {
package/src/upnp-nat.ts CHANGED
@@ -1,13 +1,11 @@
1
1
  import { upnpNat } from '@achingbrain/nat-port-mapper'
2
2
  import { isIPv4, isIPv6 } from '@chainsafe/is-ip'
3
- import { InvalidParametersError, serviceCapabilities, serviceDependencies, start, stop } from '@libp2p/interface'
3
+ import { InvalidParametersError, serviceCapabilities, setMaxListeners, start, stop } from '@libp2p/interface'
4
4
  import { debounce } from '@libp2p/utils/debounce'
5
5
  import { isLoopback } from '@libp2p/utils/multiaddr/is-loopback'
6
6
  import { isPrivate } from '@libp2p/utils/multiaddr/is-private'
7
7
  import { isPrivateIp } from '@libp2p/utils/private-ip'
8
- import { multiaddr } from '@multiformats/multiaddr'
9
8
  import { QUICV1, TCP, WebSockets, WebSocketsSecure, WebTransport } from '@multiformats/multiaddr-matcher'
10
- import { raceSignal } from 'race-signal'
11
9
  import { dynamicExternalAddress, staticExternalAddress } from './check-external-address.js'
12
10
  import { DoubleNATError, InvalidIPAddressError } from './errors.js'
13
11
  import type { ExternalAddress } from './check-external-address.js'
@@ -22,35 +20,35 @@ const DEFAULT_TTL = 7200
22
20
 
23
21
  export type { NatAPI, MapPortOptions }
24
22
 
23
+ interface PortMapping {
24
+ externalHost: string
25
+ externalPort: number
26
+ }
27
+
25
28
  export class UPnPNAT implements Startable, UPnPNATInterface {
26
29
  public client: NatAPI
27
30
  private readonly addressManager: AddressManager
28
31
  private readonly events: TypedEventTarget<Libp2pEvents>
29
32
  private readonly externalAddress: ExternalAddress
30
- private readonly localAddress?: string
31
33
  private readonly description: string
32
34
  private readonly ttl: number
33
35
  private readonly keepAlive: boolean
34
36
  private readonly gateway?: string
35
37
  private started: boolean
36
38
  private readonly log: Logger
37
- private readonly gatewayDetectionTimeout: number
38
- private readonly mappedPorts: Map<number, number>
39
+ private readonly mappedPorts: Map<string, PortMapping>
39
40
  private readonly onSelfPeerUpdate: DebouncedFunction
40
- private readonly autoConfirmAddress: boolean
41
+ private shutdownController?: AbortController
41
42
 
42
43
  constructor (components: UPnPNATComponents, init: UPnPNATInit) {
43
44
  this.log = components.logger.forComponent('libp2p:upnp-nat')
44
45
  this.addressManager = components.addressManager
45
46
  this.events = components.events
46
47
  this.started = false
47
- this.localAddress = init.localAddress
48
48
  this.description = init.description ?? `${components.nodeInfo.name}@${components.nodeInfo.version} ${components.peerId.toString()}`
49
49
  this.ttl = init.ttl ?? DEFAULT_TTL
50
50
  this.keepAlive = init.keepAlive ?? true
51
51
  this.gateway = init.gateway
52
- this.gatewayDetectionTimeout = init.gatewayDetectionTimeout ?? 10000
53
- this.autoConfirmAddress = init.autoConfirmAddress ?? false
54
52
  this.mappedPorts = new Map()
55
53
 
56
54
  if (this.ttl < DEFAULT_TTL) {
@@ -74,9 +72,9 @@ export class UPnPNAT implements Startable, UPnPNATInterface {
74
72
  addressManager: this.addressManager,
75
73
  logger: components.logger
76
74
  }, {
77
- autoConfirmAddress: init.autoConfirmAddress,
78
75
  interval: init.externalAddressCheckInterval,
79
- timeout: init.externalAddressCheckTimeout
76
+ timeout: init.externalAddressCheckTimeout,
77
+ onExternalAddressChange: this.remapPorts.bind(this)
80
78
  })
81
79
  }
82
80
  }
@@ -87,16 +85,6 @@ export class UPnPNAT implements Startable, UPnPNATInterface {
87
85
  '@libp2p/nat-traversal'
88
86
  ]
89
87
 
90
- get [serviceDependencies] (): string[] {
91
- if (!this.autoConfirmAddress) {
92
- return [
93
- '@libp2p/autonat'
94
- ]
95
- }
96
-
97
- return []
98
- }
99
-
100
88
  isStarted (): boolean {
101
89
  return this.started
102
90
  }
@@ -107,6 +95,8 @@ export class UPnPNAT implements Startable, UPnPNATInterface {
107
95
  }
108
96
 
109
97
  this.started = true
98
+ this.shutdownController = new AbortController()
99
+ setMaxListeners(Infinity, this.shutdownController.signal)
110
100
  this.events.addEventListener('self:peer:update', this.onSelfPeerUpdate)
111
101
  await start(this.externalAddress, this.onSelfPeerUpdate)
112
102
  }
@@ -121,6 +111,7 @@ export class UPnPNAT implements Startable, UPnPNATInterface {
121
111
  this.log.error(err)
122
112
  }
123
113
 
114
+ this.shutdownController?.abort()
124
115
  this.events.removeEventListener('self:peer:update', this.onSelfPeerUpdate)
125
116
  await stop(this.externalAddress, this.onSelfPeerUpdate)
126
117
  this.started = false
@@ -158,13 +149,13 @@ export class UPnPNAT implements Startable, UPnPNATInterface {
158
149
  continue
159
150
  }
160
151
 
161
- const { port, family } = ma.toOptions()
152
+ const { port, host, family, transport } = ma.toOptions()
162
153
 
163
154
  if (family !== ipType) {
164
155
  continue
165
156
  }
166
157
 
167
- if (this.mappedPorts.has(port)) {
158
+ if (this.mappedPorts.has(`${host}-${port}-${transport}`)) {
168
159
  continue
169
160
  }
170
161
 
@@ -175,26 +166,18 @@ export class UPnPNAT implements Startable, UPnPNATInterface {
175
166
  }
176
167
 
177
168
  async mapIpAddresses (): Promise<void> {
178
- if (this.externalAddress == null) {
179
- this.log('discovering public address')
180
- }
181
-
182
- const publicIp = await this.externalAddress.getPublicIp({
183
- signal: AbortSignal.timeout(this.gatewayDetectionTimeout)
184
- })
185
-
186
- this.externalAddress ?? await raceSignal(this.client.externalIp(), AbortSignal.timeout(this.gatewayDetectionTimeout), {
187
- 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`
169
+ const externalHost = await this.externalAddress.getPublicIp({
170
+ signal: this.shutdownController?.signal
188
171
  })
189
172
 
190
173
  let ipType: 4 | 6 = 4
191
174
 
192
- if (isIPv4(publicIp)) {
175
+ if (isIPv4(externalHost)) {
193
176
  ipType = 4
194
- } else if (isIPv6(publicIp)) {
177
+ } else if (isIPv6(externalHost)) {
195
178
  ipType = 6
196
179
  } else {
197
- throw new InvalidIPAddressError(`Public address ${publicIp} was not an IPv4 address`)
180
+ throw new InvalidIPAddressError(`Public address ${externalHost} was not an IPv4 address`)
198
181
  }
199
182
 
200
183
  // filter addresses to get private, non-relay, IP based addresses that we
@@ -206,9 +189,9 @@ export class UPnPNAT implements Startable, UPnPNATInterface {
206
189
  return
207
190
  }
208
191
 
209
- this.log('%s public IP %s', this.externalAddress != null ? 'using configured' : 'discovered', publicIp)
192
+ this.log('%s public IP %s', this.externalAddress != null ? 'using configured' : 'discovered', externalHost)
210
193
 
211
- this.assertNotBehindDoubleNAT(publicIp)
194
+ this.assertNotBehindDoubleNAT(externalHost)
212
195
 
213
196
  for (const addr of addresses) {
214
197
  // try to open uPnP ports for each thin waist address
@@ -219,30 +202,29 @@ export class UPnPNAT implements Startable, UPnPNATInterface {
219
202
  continue
220
203
  }
221
204
 
222
- if (this.mappedPorts.has(port)) {
205
+ if (this.mappedPorts.has(`${host}-${port}-${transport}`)) {
223
206
  // already mapped this port
224
207
  continue
225
208
  }
226
209
 
227
- const protocol = transport.toUpperCase()
228
-
229
- this.log(`creating mapping of ${host}:${port}`)
210
+ try {
211
+ this.log(`creating mapping of %s:%s key ${host}-${port}-${transport}`, host, port)
230
212
 
231
- const mappedPort = await this.client.map(port, {
232
- localAddress: host,
233
- protocol: protocol === 'TCP' ? 'TCP' : 'UDP'
234
- })
213
+ const externalPort = await this.client.map(port, {
214
+ localAddress: host,
215
+ protocol: transport === 'tcp' ? 'TCP' : 'UDP'
216
+ })
235
217
 
236
- this.mappedPorts.set(port, mappedPort)
218
+ this.mappedPorts.set(`${host}-${port}-${transport}`, {
219
+ externalHost,
220
+ externalPort
221
+ })
237
222
 
238
- const ma = multiaddr(addr.toString().replace(`/ip${family}/${host}/${transport}/${port}`, `/ip${family}/${publicIp}/${transport}/${mappedPort}`))
223
+ this.log('created mapping of %s:%s to %s:%s', externalHost, externalPort, host, port)
239
224
 
240
- this.log(`created mapping of ${publicIp}:${mappedPort} to ${host}:${port} as %a`, ma)
241
-
242
- if (this.autoConfirmAddress) {
243
- this.addressManager.confirmObservedAddr(ma)
244
- } else {
245
- this.addressManager.addObservedAddr(ma)
225
+ this.addressManager.addPublicAddressMapping(host, port, externalHost, externalPort, transport === 'tcp' ? 'tcp' : 'udp')
226
+ } catch (err) {
227
+ this.log.error('failed to create mapping of %s:%s - %e', host, port, err)
246
228
  }
247
229
  }
248
230
  }
@@ -254,11 +236,28 @@ export class UPnPNAT implements Startable, UPnPNATInterface {
254
236
  const isPrivate = isPrivateIp(publicIp)
255
237
 
256
238
  if (isPrivate === true) {
257
- 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`)
239
+ 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`)
258
240
  }
259
241
 
260
242
  if (isPrivate == null) {
261
243
  throw new InvalidParametersError(`${publicIp} is not an IP address`)
262
244
  }
263
245
  }
246
+
247
+ /**
248
+ * Update the local address mappings when the gateway's external interface
249
+ * address changes
250
+ */
251
+ private remapPorts (newExternalHost: string): void {
252
+ for (const [key, { externalHost, externalPort }] of this.mappedPorts.entries()) {
253
+ const [
254
+ host,
255
+ port,
256
+ transport
257
+ ] = key.split('-')
258
+
259
+ this.addressManager.removePublicAddressMapping(host, parseInt(port), externalHost, externalPort, transport === 'tcp' ? 'tcp' : 'udp')
260
+ this.addressManager.addPublicAddressMapping(host, parseInt(port), newExternalHost, externalPort, transport === 'tcp' ? 'tcp' : 'udp')
261
+ }
262
+ }
264
263
  }