@libp2p/autonat-v2 0.0.0-2d6079bc1

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.
@@ -0,0 +1,191 @@
1
+ import { ProtocolError } from '@libp2p/interface';
2
+ import { isPrivateIp } from '@libp2p/utils/private-ip';
3
+ import { CODE_IP4, CODE_IP6, multiaddr } from '@multiformats/multiaddr';
4
+ import { pbStream } from 'it-protobuf-stream';
5
+ import { setMaxListeners } from 'main-event';
6
+ import { MAX_INBOUND_STREAMS, MAX_MESSAGE_SIZE, MAX_OUTBOUND_STREAMS, TIMEOUT } from "./constants.js";
7
+ import { DialBack, DialBackResponse, DialResponse, DialStatus, Message } from "./pb/index.js";
8
+ import { randomNumber } from "./utils.js";
9
+ export class AutoNATv2Server {
10
+ components;
11
+ dialRequestProtocol;
12
+ dialBackProtocol;
13
+ timeout;
14
+ maxInboundStreams;
15
+ maxOutboundStreams;
16
+ maxMessageSize;
17
+ started;
18
+ log;
19
+ constructor(components, init) {
20
+ this.components = components;
21
+ this.log = components.logger.forComponent('libp2p:auto-nat-v2:server');
22
+ this.started = false;
23
+ this.dialRequestProtocol = init.dialRequestProtocol;
24
+ this.dialBackProtocol = init.dialBackProtocol;
25
+ this.timeout = init.timeout ?? TIMEOUT;
26
+ this.maxInboundStreams = init.maxInboundStreams ?? MAX_INBOUND_STREAMS;
27
+ this.maxOutboundStreams = init.maxOutboundStreams ?? MAX_OUTBOUND_STREAMS;
28
+ this.maxMessageSize = init.maxMessageSize ?? MAX_MESSAGE_SIZE;
29
+ }
30
+ async start() {
31
+ if (this.started) {
32
+ return;
33
+ }
34
+ // AutoNat server
35
+ await this.components.registrar.handle(this.dialRequestProtocol, (data) => {
36
+ void this.handleDialRequestStream(data)
37
+ .catch(err => {
38
+ this.log.error('error handling incoming autonat stream - %e', err);
39
+ });
40
+ }, {
41
+ maxInboundStreams: this.maxInboundStreams,
42
+ maxOutboundStreams: this.maxOutboundStreams
43
+ });
44
+ this.started = true;
45
+ }
46
+ async stop() {
47
+ await this.components.registrar.unhandle(this.dialRequestProtocol);
48
+ this.started = false;
49
+ }
50
+ /**
51
+ * Handle an incoming AutoNAT request
52
+ */
53
+ async handleDialRequestStream(data) {
54
+ const signal = AbortSignal.timeout(this.timeout);
55
+ setMaxListeners(Infinity, signal);
56
+ const messages = pbStream(data.stream, {
57
+ maxDataLength: this.maxMessageSize
58
+ }).pb(Message);
59
+ try {
60
+ const connectionIp = getIpAddress(data.connection.remoteAddr);
61
+ if (connectionIp == null) {
62
+ throw new ProtocolError(`Could not find IP address in connection address "${data.connection.remoteAddr}"`);
63
+ }
64
+ const { dialRequest } = await messages.read({
65
+ signal
66
+ });
67
+ if (dialRequest == null) {
68
+ throw new ProtocolError('Did not receive DialRequest message on incoming dial request stream');
69
+ }
70
+ if (dialRequest.addrs.length === 0) {
71
+ throw new ProtocolError('Did not receive any addresses to dial');
72
+ }
73
+ for (let i = 0; i < dialRequest.addrs.length; i++) {
74
+ try {
75
+ const ma = multiaddr(dialRequest.addrs[i]);
76
+ const isDialable = await this.components.connectionManager.isDialable(ma, {
77
+ signal
78
+ });
79
+ if (!isDialable) {
80
+ await messages.write({
81
+ dialResponse: {
82
+ addrIdx: i,
83
+ status: DialResponse.ResponseStatus.E_DIAL_REFUSED,
84
+ dialStatus: DialStatus.UNUSED
85
+ }
86
+ }, {
87
+ signal
88
+ });
89
+ continue;
90
+ }
91
+ const ip = getIpAddress(ma);
92
+ if (ip == null) {
93
+ throw new ProtocolError(`Could not find IP address in requested address "${ma}"`);
94
+ }
95
+ if (isPrivateIp(ip)) {
96
+ throw new ProtocolError(`Requested address had private IP "${ma}"`);
97
+ }
98
+ if (ip !== connectionIp) {
99
+ // amplification attack protection - request the client sends us a
100
+ // random number of bytes before we'll dial the address
101
+ await this.preventAmplificationAttack(messages, i, {
102
+ signal
103
+ });
104
+ }
105
+ const dialStatus = await this.dialClientBack(ma, dialRequest.nonce, {
106
+ signal
107
+ });
108
+ await messages.write({
109
+ dialResponse: {
110
+ addrIdx: i,
111
+ status: DialResponse.ResponseStatus.OK,
112
+ dialStatus
113
+ }
114
+ }, {
115
+ signal
116
+ });
117
+ }
118
+ catch (err) {
119
+ this.log.error('could not parse multiaddr - %e', err);
120
+ }
121
+ }
122
+ await data.stream.close({
123
+ signal
124
+ });
125
+ }
126
+ catch (err) {
127
+ this.log.error('error handling incoming autonat stream - %e', err);
128
+ data.stream.abort(err);
129
+ }
130
+ }
131
+ async preventAmplificationAttack(messages, index, options) {
132
+ const numBytes = randomNumber(30_000, 100_000);
133
+ await messages.write({
134
+ dialDataRequest: {
135
+ addrIdx: index,
136
+ numBytes: BigInt(numBytes)
137
+ }
138
+ }, options);
139
+ let received = 0;
140
+ while (received < numBytes) {
141
+ const { dialDataResponse } = await messages.read(options);
142
+ if (dialDataResponse == null) {
143
+ throw new ProtocolError('Did not receive DialDataResponse message on incoming dial request stream');
144
+ }
145
+ received += dialDataResponse.data.byteLength;
146
+ }
147
+ }
148
+ async dialClientBack(ma, nonce, options) {
149
+ let connection;
150
+ try {
151
+ connection = await this.components.connectionManager.openConnection(ma, {
152
+ force: true,
153
+ ...options
154
+ });
155
+ }
156
+ catch (err) {
157
+ this.log.error('failed to open connection to %a - %e', err, ma);
158
+ return DialStatus.E_DIAL_ERROR;
159
+ }
160
+ try {
161
+ const stream = await connection.newStream(this.dialBackProtocol, options);
162
+ const dialBackMessages = pbStream(stream, {
163
+ maxDataLength: this.maxMessageSize
164
+ });
165
+ await dialBackMessages.write({
166
+ nonce
167
+ }, DialBack, options);
168
+ const response = await dialBackMessages.read(DialBackResponse);
169
+ if (response.status !== DialBackResponse.DialBackStatus.OK) {
170
+ throw new ProtocolError('DialBackResponse status was not OK');
171
+ }
172
+ await connection.close(options);
173
+ }
174
+ catch (err) {
175
+ this.log.error('could not perform dial back - %e', err);
176
+ connection.abort(err);
177
+ return DialStatus.E_DIAL_BACK_ERROR;
178
+ }
179
+ // dial back was successful
180
+ return DialStatus.OK;
181
+ }
182
+ }
183
+ function getIpAddress(ma) {
184
+ return ma.getComponents()
185
+ .filter(component => {
186
+ return component.code === CODE_IP4 || component.code === CODE_IP6;
187
+ })
188
+ .map(component => component.value)
189
+ .pop();
190
+ }
191
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function randomNumber(min: number, max: number): number;
2
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,YAAY,CAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAE9D"}
@@ -0,0 +1,4 @@
1
+ export function randomNumber(min, max) {
2
+ return Math.round(Math.random() * (max - min) + min);
3
+ }
4
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,YAAY,CAAE,GAAW,EAAE,GAAW;IACpD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAA;AACtD,CAAC"}
package/package.json ADDED
@@ -0,0 +1,75 @@
1
+ {
2
+ "name": "@libp2p/autonat-v2",
3
+ "version": "0.0.0-2d6079bc1",
4
+ "description": "Implementation of the AutoNAT Protocol v2",
5
+ "license": "Apache-2.0 OR MIT",
6
+ "homepage": "https://github.com/libp2p/js-libp2p/tree/main/packages/protocol-autonat-v2#readme",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/libp2p/js-libp2p.git"
10
+ },
11
+ "bugs": {
12
+ "url": "https://github.com/libp2p/js-libp2p/issues"
13
+ },
14
+ "publishConfig": {
15
+ "access": "public",
16
+ "provenance": true
17
+ },
18
+ "type": "module",
19
+ "types": "./dist/src/index.d.ts",
20
+ "files": [
21
+ "src",
22
+ "dist",
23
+ "!dist/test",
24
+ "!**/*.tsbuildinfo"
25
+ ],
26
+ "exports": {
27
+ ".": {
28
+ "types": "./dist/src/index.d.ts",
29
+ "import": "./dist/src/index.js"
30
+ }
31
+ },
32
+ "scripts": {
33
+ "start": "node dist/src/main.js",
34
+ "build": "aegir build",
35
+ "test": "aegir test",
36
+ "clean": "aegir clean",
37
+ "generate": "protons ./src/pb/index.proto",
38
+ "lint": "aegir lint",
39
+ "test:chrome": "aegir test -t browser --cov",
40
+ "test:chrome-webworker": "aegir test -t webworker",
41
+ "test:firefox": "aegir test -t browser -- --browser firefox",
42
+ "test:firefox-webworker": "aegir test -t webworker -- --browser firefox",
43
+ "test:node": "aegir test -t node --cov",
44
+ "dep-check": "aegir dep-check",
45
+ "doc-check": "aegir doc-check"
46
+ },
47
+ "dependencies": {
48
+ "@libp2p/interface": "2.10.4-2d6079bc1",
49
+ "@libp2p/interface-internal": "2.3.17-2d6079bc1",
50
+ "@libp2p/peer-collections": "6.0.33-2d6079bc1",
51
+ "@libp2p/utils": "6.7.0-2d6079bc1",
52
+ "@multiformats/multiaddr": "^12.4.4",
53
+ "any-signal": "^4.1.1",
54
+ "it-protobuf-stream": "^2.0.2",
55
+ "main-event": "^1.0.1",
56
+ "protons-runtime": "^5.5.0",
57
+ "uint8arraylist": "^2.4.8",
58
+ "uint8arrays": "^5.1.0"
59
+ },
60
+ "devDependencies": {
61
+ "@libp2p/crypto": "5.1.6-2d6079bc1",
62
+ "@libp2p/logger": "5.1.20-2d6079bc1",
63
+ "@libp2p/peer-id": "5.1.7-2d6079bc1",
64
+ "aegir": "^47.0.14",
65
+ "it-all": "^3.0.8",
66
+ "it-length-prefixed": "^10.0.1",
67
+ "it-pipe": "^3.0.1",
68
+ "it-pushable": "^3.2.3",
69
+ "p-retry": "^6.2.1",
70
+ "protons": "^7.6.1",
71
+ "sinon": "^20.0.0",
72
+ "sinon-ts": "^2.0.0"
73
+ },
74
+ "sideEffects": false
75
+ }
package/src/autonat.ts ADDED
@@ -0,0 +1,47 @@
1
+ import { serviceCapabilities, serviceDependencies, start, stop } from '@libp2p/interface'
2
+ import { AutoNATv2Client } from './client.ts'
3
+ import { DIAL_BACK, DIAL_REQUEST, PROTOCOL_NAME, PROTOCOL_PREFIX, PROTOCOL_VERSION } from './constants.ts'
4
+ import { AutoNATv2Server } from './server.ts'
5
+ import type { AutoNATv2Components, AutoNATv2ServiceInit } from './index.ts'
6
+ import type { Startable } from '@libp2p/interface'
7
+
8
+ export class AutoNATv2Service implements Startable {
9
+ private readonly client: AutoNATv2Client
10
+ private readonly server: AutoNATv2Server
11
+
12
+ constructor (components: AutoNATv2Components, init: AutoNATv2ServiceInit) {
13
+ const dialRequestProtocol = `/${init.protocolPrefix ?? PROTOCOL_PREFIX}/${PROTOCOL_NAME}/${PROTOCOL_VERSION}/${DIAL_REQUEST}`
14
+ const dialBackProtocol = `/${init.protocolPrefix ?? PROTOCOL_PREFIX}/${PROTOCOL_NAME}/${PROTOCOL_VERSION}/${DIAL_BACK}`
15
+
16
+ this.client = new AutoNATv2Client(components, {
17
+ ...init,
18
+ dialRequestProtocol,
19
+ dialBackProtocol
20
+ })
21
+ this.server = new AutoNATv2Server(components, {
22
+ ...init,
23
+ dialRequestProtocol,
24
+ dialBackProtocol
25
+ })
26
+ }
27
+
28
+ readonly [Symbol.toStringTag] = '@libp2p/autonat-v2'
29
+
30
+ readonly [serviceCapabilities]: string[] = [
31
+ '@libp2p/autonat'
32
+ ]
33
+
34
+ get [serviceDependencies] (): string[] {
35
+ return [
36
+ '@libp2p/identify'
37
+ ]
38
+ }
39
+
40
+ async start (): Promise<void> {
41
+ await start(this.client, this.server)
42
+ }
43
+
44
+ async stop (): Promise<void> {
45
+ await stop(this.client, this.server)
46
+ }
47
+ }