@libp2p/tcp 6.0.8 → 6.1.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/index.min.js +4 -4
- package/dist/src/constants.d.ts +1 -1
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +1 -1
- package/dist/src/constants.js.map +1 -1
- package/dist/src/index.d.ts +6 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/listener.d.ts +10 -0
- package/dist/src/listener.d.ts.map +1 -1
- package/dist/src/listener.js +63 -14
- package/dist/src/listener.js.map +1 -1
- package/dist/src/socket-to-conn.js +4 -4
- package/dist/src/socket-to-conn.js.map +1 -1
- package/dist/src/utils.d.ts +2 -1
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js.map +1 -1
- package/dist/typedoc-urls.json +1 -0
- package/package.json +2 -3
- package/src/constants.ts +1 -1
- package/src/index.ts +10 -4
- package/src/listener.ts +97 -18
- package/src/socket-to-conn.ts +4 -4
- package/src/utils.ts +3 -1
package/dist/src/index.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import net from 'net';
|
|
2
2
|
import * as mafmt from '@multiformats/mafmt';
|
|
3
|
-
import errCode from 'err-code';
|
|
4
3
|
import { logger } from '@libp2p/logger';
|
|
5
4
|
import { toMultiaddrConnection } from './socket-to-conn.js';
|
|
6
5
|
import { TCPListener } from './listener.js';
|
|
7
6
|
import { multiaddrToNetConfig } from './utils.js';
|
|
8
|
-
import { AbortError } from '@libp2p/interfaces/errors';
|
|
7
|
+
import { AbortError, CodeError } from '@libp2p/interfaces/errors';
|
|
9
8
|
import { CODE_CIRCUIT, CODE_P2P, CODE_UNIX } from './constants.js';
|
|
10
9
|
import { symbol } from '@libp2p/interface-transport';
|
|
11
10
|
const log = logger('libp2p:tcp');
|
|
@@ -78,7 +77,7 @@ class TCP {
|
|
|
78
77
|
const onTimeout = () => {
|
|
79
78
|
log('connection timeout %s', cOptsStr);
|
|
80
79
|
this.metrics?.dialerEvents.increment({ timeout: true });
|
|
81
|
-
const err =
|
|
80
|
+
const err = new CodeError(`connection timeout after ${Date.now() - start}ms`, 'ERR_CONNECT_TIMEOUT');
|
|
82
81
|
// Note: this will result in onError() being called
|
|
83
82
|
rawSocket.emit('error', err);
|
|
84
83
|
};
|
|
@@ -122,6 +121,7 @@ class TCP {
|
|
|
122
121
|
return new TCPListener({
|
|
123
122
|
...options,
|
|
124
123
|
maxConnections: this.opts.maxConnections,
|
|
124
|
+
closeServerOnMaxConnections: this.opts.closeServerOnMaxConnections,
|
|
125
125
|
socketInactivityTimeout: this.opts.inboundSocketInactivityTimeout,
|
|
126
126
|
socketCloseTimeout: this.opts.socketCloseTimeout,
|
|
127
127
|
metrics: this.components.metrics
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,KAAK,CAAA;AACrB,OAAO,KAAK,KAAK,MAAM,qBAAqB,CAAA;AAC5C,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/src/listener.d.ts
CHANGED
|
@@ -4,6 +4,13 @@ import type { Upgrader, Listener, ListenerEvents } from '@libp2p/interface-trans
|
|
|
4
4
|
import type { Multiaddr } from '@multiformats/multiaddr';
|
|
5
5
|
import type { TCPCreateListenerOptions } from './index.js';
|
|
6
6
|
import type { CounterGroup, MetricGroup, Metrics } from '@libp2p/interface-metrics';
|
|
7
|
+
export interface CloseServerOnMaxConnectionsOpts {
|
|
8
|
+
/** Server listens once connection count is less than `listenBelow` */
|
|
9
|
+
listenBelow: number;
|
|
10
|
+
/** Close server once connection count is greater than or equal to `closeAbove` */
|
|
11
|
+
closeAbove: number;
|
|
12
|
+
onListenError?: (err: Error) => void;
|
|
13
|
+
}
|
|
7
14
|
interface Context extends TCPCreateListenerOptions {
|
|
8
15
|
handler?: (conn: Connection) => void;
|
|
9
16
|
upgrader: Upgrader;
|
|
@@ -11,6 +18,7 @@ interface Context extends TCPCreateListenerOptions {
|
|
|
11
18
|
socketCloseTimeout?: number;
|
|
12
19
|
maxConnections?: number;
|
|
13
20
|
metrics?: Metrics;
|
|
21
|
+
closeServerOnMaxConnections?: CloseServerOnMaxConnectionsOpts;
|
|
14
22
|
}
|
|
15
23
|
export interface TCPListenerMetrics {
|
|
16
24
|
status: MetricGroup;
|
|
@@ -30,6 +38,8 @@ export declare class TCPListener extends EventEmitter<ListenerEvents> implements
|
|
|
30
38
|
getAddrs(): Multiaddr[];
|
|
31
39
|
listen(ma: Multiaddr): Promise<void>;
|
|
32
40
|
close(): Promise<void>;
|
|
41
|
+
private netListen;
|
|
42
|
+
private netClose;
|
|
33
43
|
}
|
|
34
44
|
export {};
|
|
35
45
|
//# sourceMappingURL=listener.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"listener.d.ts","sourceRoot":"","sources":["../../src/listener.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"listener.d.ts","sourceRoot":"","sources":["../../src/listener.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,YAAY,EAAe,MAAM,2BAA2B,CAAA;AACrE,OAAO,KAAK,EAAuB,UAAU,EAAE,MAAM,8BAA8B,CAAA;AACnF,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AACrF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAA;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;AAenF,MAAM,WAAW,+BAA+B;IAC9C,sEAAsE;IACtE,WAAW,EAAE,MAAM,CAAA;IACnB,kFAAkF;IAClF,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAA;CACrC;AAED,UAAU,OAAQ,SAAQ,wBAAwB;IAChD,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAA;IACpC,QAAQ,EAAE,QAAQ,CAAA;IAClB,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,2BAA2B,CAAC,EAAE,+BAA+B,CAAA;CAC9D;AAKD,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,WAAW,CAAA;IACnB,MAAM,EAAE,YAAY,CAAA;IACpB,MAAM,EAAE,YAAY,CAAA;CACrB;AASD,qBAAa,WAAY,SAAQ,YAAY,CAAC,cAAc,CAAE,YAAW,QAAQ;IAQlE,OAAO,CAAC,QAAQ,CAAC,OAAO;IAPrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAY;IACnC,mEAAmE;IACnE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAiC;IAC7D,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,OAAO,CAAC,CAAoB;IACpC,OAAO,CAAC,IAAI,CAAQ;gBAEU,OAAO,EAAE,OAAO;IAiF9C,OAAO,CAAC,QAAQ;IAgFhB,QAAQ;IAgCF,MAAM,CAAE,EAAE,EAAE,SAAS;IAkBrB,KAAK;YASG,SAAS;IAgBvB,OAAO,CAAC,QAAQ;CAwBjB"}
|
package/dist/src/listener.js
CHANGED
|
@@ -34,6 +34,12 @@ export class TCPListener extends EventEmitter {
|
|
|
34
34
|
if (context.maxConnections !== undefined) {
|
|
35
35
|
this.server.maxConnections = context.maxConnections;
|
|
36
36
|
}
|
|
37
|
+
if (context.closeServerOnMaxConnections != null) {
|
|
38
|
+
// Sanity check options
|
|
39
|
+
if (context.closeServerOnMaxConnections.closeAbove < context.closeServerOnMaxConnections.listenBelow) {
|
|
40
|
+
throw Error('closeAbove must be >= listenBelow');
|
|
41
|
+
}
|
|
42
|
+
}
|
|
37
43
|
this.server
|
|
38
44
|
.on('listening', () => {
|
|
39
45
|
if (context.metrics != null) {
|
|
@@ -118,10 +124,25 @@ export class TCPListener extends EventEmitter {
|
|
|
118
124
|
this.connections.add(maConn);
|
|
119
125
|
socket.once('close', () => {
|
|
120
126
|
this.connections.delete(maConn);
|
|
127
|
+
if (this.context.closeServerOnMaxConnections != null &&
|
|
128
|
+
this.connections.size < this.context.closeServerOnMaxConnections.listenBelow) {
|
|
129
|
+
// The most likely case of error is if the port taken by this application is binded by
|
|
130
|
+
// another process during the time the server if closed. In that case there's not much
|
|
131
|
+
// we can do. netListen() will be called again every time a connection is dropped, which
|
|
132
|
+
// acts as an eventual retry mechanism. onListenError allows the consumer act on this.
|
|
133
|
+
this.netListen().catch(e => {
|
|
134
|
+
log.error('error attempting to listen server once connection count under limit', e);
|
|
135
|
+
this.context.closeServerOnMaxConnections?.onListenError?.(e);
|
|
136
|
+
});
|
|
137
|
+
}
|
|
121
138
|
});
|
|
122
139
|
if (this.context.handler != null) {
|
|
123
140
|
this.context.handler(conn);
|
|
124
141
|
}
|
|
142
|
+
if (this.context.closeServerOnMaxConnections != null &&
|
|
143
|
+
this.connections.size >= this.context.closeServerOnMaxConnections.closeAbove) {
|
|
144
|
+
this.netClose();
|
|
145
|
+
}
|
|
125
146
|
this.dispatchEvent(new CustomEvent('connection', { detail: conn }));
|
|
126
147
|
})
|
|
127
148
|
.catch(async (err) => {
|
|
@@ -173,28 +194,56 @@ export class TCPListener extends EventEmitter {
|
|
|
173
194
|
return addrs.map(ma => peerId != null ? ma.encapsulate(`/p2p/${peerId}`) : ma);
|
|
174
195
|
}
|
|
175
196
|
async listen(ma) {
|
|
197
|
+
if (this.status.started) {
|
|
198
|
+
throw Error('server is already listening');
|
|
199
|
+
}
|
|
176
200
|
const peerId = ma.getPeerId();
|
|
177
201
|
const listeningAddr = peerId == null ? ma.decapsulateCode(CODE_P2P) : ma;
|
|
178
|
-
this.status = {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
log('Listening on %s', this.server.address());
|
|
186
|
-
resolve();
|
|
187
|
-
});
|
|
188
|
-
});
|
|
202
|
+
this.status = {
|
|
203
|
+
started: true,
|
|
204
|
+
listeningAddr,
|
|
205
|
+
peerId,
|
|
206
|
+
netConfig: multiaddrToNetConfig(listeningAddr)
|
|
207
|
+
};
|
|
208
|
+
await this.netListen();
|
|
189
209
|
}
|
|
190
210
|
async close() {
|
|
191
|
-
|
|
211
|
+
await Promise.all(Array.from(this.connections.values()).map(async (maConn) => await attemptClose(maConn)));
|
|
212
|
+
// netClose already checks if server.listening
|
|
213
|
+
this.netClose();
|
|
214
|
+
}
|
|
215
|
+
async netListen() {
|
|
216
|
+
if (!this.status.started || this.server.listening) {
|
|
192
217
|
return;
|
|
193
218
|
}
|
|
194
|
-
|
|
219
|
+
const netConfig = this.status.netConfig;
|
|
195
220
|
await new Promise((resolve, reject) => {
|
|
196
|
-
|
|
221
|
+
// NOTE: 'listening' event is only fired on success. Any error such as port already binded, is emitted via 'error'
|
|
222
|
+
this.server.once('error', reject);
|
|
223
|
+
this.server.listen(netConfig, resolve);
|
|
197
224
|
});
|
|
225
|
+
log('Listening on %s', this.server.address());
|
|
226
|
+
}
|
|
227
|
+
netClose() {
|
|
228
|
+
if (!this.status.started || !this.server.listening) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
log('Closing server on %s', this.server.address());
|
|
232
|
+
// NodeJS implementation tracks listening status with `this._handle` property.
|
|
233
|
+
// - Server.close() sets this._handle to null immediately. If this._handle is null, ERR_SERVER_NOT_RUNNING is thrown
|
|
234
|
+
// - Server.listening returns `this._handle !== null` https://github.com/nodejs/node/blob/386d761943bb1b217fba27d6b80b658c23009e60/lib/net.js#L1675
|
|
235
|
+
// - Server.listen() if `this._handle !== null` throws ERR_SERVER_ALREADY_LISTEN
|
|
236
|
+
//
|
|
237
|
+
// NOTE: Both listen and close are technically not async actions, so it's not necessary to track
|
|
238
|
+
// states 'pending-close' or 'pending-listen'
|
|
239
|
+
// From docs https://nodejs.org/api/net.html#serverclosecallback
|
|
240
|
+
// Stops the server from accepting new connections and keeps existing connections.
|
|
241
|
+
// 'close' event is emitted only emitted when all connections are ended.
|
|
242
|
+
// The optional callback will be called once the 'close' event occurs.
|
|
243
|
+
//
|
|
244
|
+
// NOTE: Since we want to keep existing connections and have checked `!this.server.listening` it's not necessary
|
|
245
|
+
// to pass a callback to close.
|
|
246
|
+
this.server.close();
|
|
198
247
|
}
|
|
199
248
|
}
|
|
200
249
|
//# sourceMappingURL=listener.js.map
|
package/dist/src/listener.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"listener.js","sourceRoot":"","sources":["../../src/listener.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,KAAK,CAAA;AACrB,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AACvC,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EACL,aAAa,EACb,oBAAoB,
|
|
1
|
+
{"version":3,"file":"listener.js","sourceRoot":"","sources":["../../src/listener.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ import toIterable from 'stream-to-it';
|
|
|
4
4
|
import { ipPortToMultiaddr as toMultiaddr } from '@libp2p/utils/ip-port-to-multiaddr';
|
|
5
5
|
import { CLOSE_TIMEOUT, SOCKET_TIMEOUT } from './constants.js';
|
|
6
6
|
import { multiaddrToNetConfig } from './utils.js';
|
|
7
|
-
import
|
|
7
|
+
import { CodeError } from '@libp2p/interfaces/errors';
|
|
8
8
|
const log = logger('libp2p:tcp:socket');
|
|
9
9
|
/**
|
|
10
10
|
* Convert a socket into a MultiaddrConnection
|
|
@@ -30,7 +30,7 @@ export const toMultiaddrConnection = (socket, options) => {
|
|
|
30
30
|
if (socket.remoteAddress == null || socket.remotePort == null) {
|
|
31
31
|
// this can be undefined if the socket is destroyed (for example, if the client disconnected)
|
|
32
32
|
// https://nodejs.org/dist/latest-v16.x/docs/api/net.html#socketremoteaddress
|
|
33
|
-
throw
|
|
33
|
+
throw new CodeError('Could not determine remote address or port', 'ERR_NO_REMOTE_ADDRESS');
|
|
34
34
|
}
|
|
35
35
|
remoteAddr = toMultiaddr(socket.remoteAddress, socket.remotePort);
|
|
36
36
|
}
|
|
@@ -45,7 +45,7 @@ export const toMultiaddrConnection = (socket, options) => {
|
|
|
45
45
|
// only destroy with an error if the remote has not sent the FIN message
|
|
46
46
|
let err;
|
|
47
47
|
if (socket.readable) {
|
|
48
|
-
err =
|
|
48
|
+
err = new CodeError('Socket read timeout', 'ERR_SOCKET_READ_TIMEOUT');
|
|
49
49
|
}
|
|
50
50
|
// if the socket times out due to inactivity we must manually close the connection
|
|
51
51
|
// https://nodejs.org/dist/latest-v16.x/docs/api/net.html#event-timeout
|
|
@@ -106,7 +106,7 @@ export const toMultiaddrConnection = (socket, options) => {
|
|
|
106
106
|
else {
|
|
107
107
|
log('%s socket close timeout after %dms, destroying it manually', lOptsStr, Date.now() - start);
|
|
108
108
|
// will trigger 'error' and 'close' events that resolves promise
|
|
109
|
-
socket.destroy(
|
|
109
|
+
socket.destroy(new CodeError('Socket close timeout', 'ERR_SOCKET_CLOSE_TIMEOUT'));
|
|
110
110
|
}
|
|
111
111
|
}, closeTimeout).unref();
|
|
112
112
|
socket.once('close', () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"socket-to-conn.js","sourceRoot":"","sources":["../../src/socket-to-conn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AACvC,4BAA4B;AAC5B,OAAO,UAAU,MAAM,cAAc,CAAA;AACrC,OAAO,EAAE,iBAAiB,IAAI,WAAW,EAAE,MAAM,oCAAoC,CAAA;AACrF,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,
|
|
1
|
+
{"version":3,"file":"socket-to-conn.js","sourceRoot":"","sources":["../../src/socket-to-conn.ts"],"names":[],"mappings":"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"}
|
package/dist/src/utils.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import type { Multiaddr } from '@multiformats/multiaddr';
|
|
3
3
|
import type { ListenOptions, IpcSocketConnectOpts, TcpSocketConnectOpts } from 'net';
|
|
4
|
-
export
|
|
4
|
+
export type NetConfig = ListenOptions | (IpcSocketConnectOpts & TcpSocketConnectOpts);
|
|
5
|
+
export declare function multiaddrToNetConfig(addr: Multiaddr): NetConfig;
|
|
5
6
|
export declare function getMultiaddrs(proto: 'ip4' | 'ip6', ip: string, port: number): Multiaddr[];
|
|
6
7
|
export declare function isAnyAddr(ip: string): boolean;
|
|
7
8
|
//# sourceMappingURL=utils.d.ts.map
|
package/dist/src/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,KAAK,CAAA;AAMpF,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,KAAK,CAAA;AAMpF,MAAM,MAAM,SAAS,GAAG,aAAa,GAAG,CAAC,oBAAoB,GAAG,oBAAoB,CAAC,CAAA;AAErF,wBAAgB,oBAAoB,CAAE,IAAI,EAAE,SAAS,GAAG,SAAS,CAehE;AAED,wBAAgB,aAAa,CAAE,KAAK,EAAE,KAAK,GAAG,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,eAG5E;AAED,wBAAgB,SAAS,CAAE,EAAE,EAAE,MAAM,WAEpC"}
|
package/dist/src/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAGnD,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,IAAI,MAAM,MAAM,CAAA;AAEvB,MAAM,WAAW,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAGnD,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,IAAI,MAAM,MAAM,CAAA;AAEvB,MAAM,WAAW,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,CAAA;AAIhD,MAAM,UAAU,oBAAoB,CAAE,IAAe;IACnD,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,CAAA;IAEjC,wBAAwB;IACxB,IAAI,UAAU,IAAI,IAAI,EAAE;QACtB,IAAI,EAAE,CAAC,QAAQ,EAAE,KAAK,OAAO,EAAE;YAC7B,sCAAsC;YACtC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,UAAU,CAAC,EAAE,CAAA;SACxD;aAAM;YACL,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAA;SAC5B;KACF;IAED,gBAAgB;IAChB,OAAO,IAAI,CAAC,SAAS,EAAE,CAAA;AACzB,CAAC;AAED,MAAM,UAAU,aAAa,CAAE,KAAoB,EAAE,EAAU,EAAE,IAAY;IAC3E,MAAM,IAAI,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,IAAI,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAA;IACrE,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;AAC/E,CAAC;AAED,MAAM,UAAU,SAAS,CAAE,EAAU;IACnC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;AACvC,CAAC;AAED,MAAM,QAAQ,GAAG,EAAE,CAAC,iBAAiB,EAAE,CAAA;AAEvC,SAAS,eAAe,CAAE,MAAc;IACtC,MAAM,SAAS,GAAG,EAAE,CAAA;IAEpB,KAAK,MAAM,CAAC,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;QACnD,IAAI,QAAQ,IAAI,IAAI,EAAE;YACpB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;gBAC9B,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE;oBAC7B,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;iBAChC;aACF;SACF;KACF;IAED,OAAO,SAAS,CAAA;AAClB,CAAC"}
|
package/dist/typedoc-urls.json
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
+
"CloseServerOnMaxConnectionsOpts": "https://libp2p.github.io/js-libp2p-tcp/interfaces/_internal_.CloseServerOnMaxConnectionsOpts.html",
|
|
2
3
|
"TCPComponents": "https://libp2p.github.io/js-libp2p-tcp/interfaces/TCPComponents.html",
|
|
3
4
|
"TCPCreateListenerOptions": "https://libp2p.github.io/js-libp2p-tcp/interfaces/TCPCreateListenerOptions.html",
|
|
4
5
|
"TCPDialOptions": "https://libp2p.github.io/js-libp2p-tcp/interfaces/TCPDialOptions.html",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@libp2p/tcp",
|
|
3
|
-
"version": "6.0
|
|
3
|
+
"version": "6.1.0",
|
|
4
4
|
"description": "A TCP transport for libp2p",
|
|
5
5
|
"license": "Apache-2.0 OR MIT",
|
|
6
6
|
"homepage": "https://github.com/libp2p/js-libp2p-tcp#readme",
|
|
@@ -144,12 +144,11 @@
|
|
|
144
144
|
"@libp2p/interface-connection": "^3.0.2",
|
|
145
145
|
"@libp2p/interface-metrics": "^4.0.0",
|
|
146
146
|
"@libp2p/interface-transport": "^2.0.0",
|
|
147
|
-
"@libp2p/interfaces": "^3.0
|
|
147
|
+
"@libp2p/interfaces": "^3.2.0",
|
|
148
148
|
"@libp2p/logger": "^2.0.0",
|
|
149
149
|
"@libp2p/utils": "^3.0.2",
|
|
150
150
|
"@multiformats/mafmt": "^11.0.3",
|
|
151
151
|
"@multiformats/multiaddr": "^11.0.0",
|
|
152
|
-
"err-code": "^3.0.1",
|
|
153
152
|
"stream-to-it": "^0.2.2"
|
|
154
153
|
},
|
|
155
154
|
"devDependencies": {
|
package/src/constants.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import net from 'net'
|
|
2
2
|
import * as mafmt from '@multiformats/mafmt'
|
|
3
|
-
import errCode from 'err-code'
|
|
4
3
|
import { logger } from '@libp2p/logger'
|
|
5
4
|
import { toMultiaddrConnection } from './socket-to-conn.js'
|
|
6
|
-
import { TCPListener } from './listener.js'
|
|
5
|
+
import { CloseServerOnMaxConnectionsOpts, TCPListener } from './listener.js'
|
|
7
6
|
import { multiaddrToNetConfig } from './utils.js'
|
|
8
|
-
import { AbortError } from '@libp2p/interfaces/errors'
|
|
7
|
+
import { AbortError, CodeError } from '@libp2p/interfaces/errors'
|
|
9
8
|
import { CODE_CIRCUIT, CODE_P2P, CODE_UNIX } from './constants.js'
|
|
10
9
|
import { CreateListenerOptions, DialOptions, Listener, symbol, Transport } from '@libp2p/interface-transport'
|
|
11
10
|
import type { AbortOptions, Multiaddr } from '@multiformats/multiaddr'
|
|
@@ -36,6 +35,12 @@ export interface TCPOptions {
|
|
|
36
35
|
* https://nodejs.org/api/net.html#servermaxconnections
|
|
37
36
|
*/
|
|
38
37
|
maxConnections?: number
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Close server (stop listening for new connections) if connections exceed a limit.
|
|
41
|
+
* Open server (start listening for new connections) if connections fall below a limit.
|
|
42
|
+
*/
|
|
43
|
+
closeServerOnMaxConnections?: CloseServerOnMaxConnectionsOpts
|
|
39
44
|
}
|
|
40
45
|
|
|
41
46
|
/**
|
|
@@ -157,7 +162,7 @@ class TCP implements Transport {
|
|
|
157
162
|
log('connection timeout %s', cOptsStr)
|
|
158
163
|
this.metrics?.dialerEvents.increment({ timeout: true })
|
|
159
164
|
|
|
160
|
-
const err =
|
|
165
|
+
const err = new CodeError(`connection timeout after ${Date.now() - start}ms`, 'ERR_CONNECT_TIMEOUT')
|
|
161
166
|
// Note: this will result in onError() being called
|
|
162
167
|
rawSocket.emit('error', err)
|
|
163
168
|
}
|
|
@@ -210,6 +215,7 @@ class TCP implements Transport {
|
|
|
210
215
|
return new TCPListener({
|
|
211
216
|
...options,
|
|
212
217
|
maxConnections: this.opts.maxConnections,
|
|
218
|
+
closeServerOnMaxConnections: this.opts.closeServerOnMaxConnections,
|
|
213
219
|
socketInactivityTimeout: this.opts.inboundSocketInactivityTimeout,
|
|
214
220
|
socketCloseTimeout: this.opts.socketCloseTimeout,
|
|
215
221
|
metrics: this.components.metrics
|
package/src/listener.ts
CHANGED
|
@@ -4,7 +4,8 @@ import { toMultiaddrConnection } from './socket-to-conn.js'
|
|
|
4
4
|
import { CODE_P2P } from './constants.js'
|
|
5
5
|
import {
|
|
6
6
|
getMultiaddrs,
|
|
7
|
-
multiaddrToNetConfig
|
|
7
|
+
multiaddrToNetConfig,
|
|
8
|
+
NetConfig
|
|
8
9
|
} from './utils.js'
|
|
9
10
|
import { EventEmitter, CustomEvent } from '@libp2p/interfaces/events'
|
|
10
11
|
import type { MultiaddrConnection, Connection } from '@libp2p/interface-connection'
|
|
@@ -26,6 +27,14 @@ async function attemptClose (maConn: MultiaddrConnection) {
|
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
29
|
|
|
30
|
+
export interface CloseServerOnMaxConnectionsOpts {
|
|
31
|
+
/** Server listens once connection count is less than `listenBelow` */
|
|
32
|
+
listenBelow: number
|
|
33
|
+
/** Close server once connection count is greater than or equal to `closeAbove` */
|
|
34
|
+
closeAbove: number
|
|
35
|
+
onListenError?: (err: Error) => void
|
|
36
|
+
}
|
|
37
|
+
|
|
29
38
|
interface Context extends TCPCreateListenerOptions {
|
|
30
39
|
handler?: (conn: Connection) => void
|
|
31
40
|
upgrader: Upgrader
|
|
@@ -33,6 +42,7 @@ interface Context extends TCPCreateListenerOptions {
|
|
|
33
42
|
socketCloseTimeout?: number
|
|
34
43
|
maxConnections?: number
|
|
35
44
|
metrics?: Metrics
|
|
45
|
+
closeServerOnMaxConnections?: CloseServerOnMaxConnectionsOpts
|
|
36
46
|
}
|
|
37
47
|
|
|
38
48
|
const SERVER_STATUS_UP = 1
|
|
@@ -44,7 +54,12 @@ export interface TCPListenerMetrics {
|
|
|
44
54
|
events: CounterGroup
|
|
45
55
|
}
|
|
46
56
|
|
|
47
|
-
type Status = {started: false} | {
|
|
57
|
+
type Status = {started: false} | {
|
|
58
|
+
started: true
|
|
59
|
+
listeningAddr: Multiaddr
|
|
60
|
+
peerId: string | null
|
|
61
|
+
netConfig: NetConfig
|
|
62
|
+
}
|
|
48
63
|
|
|
49
64
|
export class TCPListener extends EventEmitter<ListenerEvents> implements Listener {
|
|
50
65
|
private readonly server: net.Server
|
|
@@ -69,6 +84,13 @@ export class TCPListener extends EventEmitter<ListenerEvents> implements Listene
|
|
|
69
84
|
this.server.maxConnections = context.maxConnections
|
|
70
85
|
}
|
|
71
86
|
|
|
87
|
+
if (context.closeServerOnMaxConnections != null) {
|
|
88
|
+
// Sanity check options
|
|
89
|
+
if (context.closeServerOnMaxConnections.closeAbove < context.closeServerOnMaxConnections.listenBelow) {
|
|
90
|
+
throw Error('closeAbove must be >= listenBelow')
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
72
94
|
this.server
|
|
73
95
|
.on('listening', () => {
|
|
74
96
|
if (context.metrics != null) {
|
|
@@ -159,12 +181,33 @@ export class TCPListener extends EventEmitter<ListenerEvents> implements Listene
|
|
|
159
181
|
|
|
160
182
|
socket.once('close', () => {
|
|
161
183
|
this.connections.delete(maConn)
|
|
184
|
+
|
|
185
|
+
if (
|
|
186
|
+
this.context.closeServerOnMaxConnections != null &&
|
|
187
|
+
this.connections.size < this.context.closeServerOnMaxConnections.listenBelow
|
|
188
|
+
) {
|
|
189
|
+
// The most likely case of error is if the port taken by this application is binded by
|
|
190
|
+
// another process during the time the server if closed. In that case there's not much
|
|
191
|
+
// we can do. netListen() will be called again every time a connection is dropped, which
|
|
192
|
+
// acts as an eventual retry mechanism. onListenError allows the consumer act on this.
|
|
193
|
+
this.netListen().catch(e => {
|
|
194
|
+
log.error('error attempting to listen server once connection count under limit', e)
|
|
195
|
+
this.context.closeServerOnMaxConnections?.onListenError?.(e as Error)
|
|
196
|
+
})
|
|
197
|
+
}
|
|
162
198
|
})
|
|
163
199
|
|
|
164
200
|
if (this.context.handler != null) {
|
|
165
201
|
this.context.handler(conn)
|
|
166
202
|
}
|
|
167
203
|
|
|
204
|
+
if (
|
|
205
|
+
this.context.closeServerOnMaxConnections != null &&
|
|
206
|
+
this.connections.size >= this.context.closeServerOnMaxConnections.closeAbove
|
|
207
|
+
) {
|
|
208
|
+
this.netClose()
|
|
209
|
+
}
|
|
210
|
+
|
|
168
211
|
this.dispatchEvent(new CustomEvent<Connection>('connection', { detail: conn }))
|
|
169
212
|
})
|
|
170
213
|
.catch(async err => {
|
|
@@ -220,34 +263,70 @@ export class TCPListener extends EventEmitter<ListenerEvents> implements Listene
|
|
|
220
263
|
}
|
|
221
264
|
|
|
222
265
|
async listen (ma: Multiaddr) {
|
|
266
|
+
if (this.status.started) {
|
|
267
|
+
throw Error('server is already listening')
|
|
268
|
+
}
|
|
269
|
+
|
|
223
270
|
const peerId = ma.getPeerId()
|
|
224
271
|
const listeningAddr = peerId == null ? ma.decapsulateCode(CODE_P2P) : ma
|
|
225
272
|
|
|
226
|
-
this.status = {
|
|
273
|
+
this.status = {
|
|
274
|
+
started: true,
|
|
275
|
+
listeningAddr,
|
|
276
|
+
peerId,
|
|
277
|
+
netConfig: multiaddrToNetConfig(listeningAddr)
|
|
278
|
+
}
|
|
227
279
|
|
|
228
|
-
|
|
229
|
-
const options = multiaddrToNetConfig(listeningAddr)
|
|
230
|
-
this.server.on('error', (err) => {
|
|
231
|
-
reject(err)
|
|
232
|
-
})
|
|
233
|
-
this.server.listen(options, () => {
|
|
234
|
-
log('Listening on %s', this.server.address())
|
|
235
|
-
resolve()
|
|
236
|
-
})
|
|
237
|
-
})
|
|
280
|
+
await this.netListen()
|
|
238
281
|
}
|
|
239
282
|
|
|
240
283
|
async close () {
|
|
241
|
-
if (!this.server.listening) {
|
|
242
|
-
return
|
|
243
|
-
}
|
|
244
|
-
|
|
245
284
|
await Promise.all(
|
|
246
285
|
Array.from(this.connections.values()).map(async maConn => await attemptClose(maConn))
|
|
247
286
|
)
|
|
248
287
|
|
|
288
|
+
// netClose already checks if server.listening
|
|
289
|
+
this.netClose()
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
private async netListen (): Promise<void> {
|
|
293
|
+
if (!this.status.started || this.server.listening) {
|
|
294
|
+
return
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
const netConfig = this.status.netConfig
|
|
298
|
+
|
|
249
299
|
await new Promise<void>((resolve, reject) => {
|
|
250
|
-
|
|
300
|
+
// NOTE: 'listening' event is only fired on success. Any error such as port already binded, is emitted via 'error'
|
|
301
|
+
this.server.once('error', reject)
|
|
302
|
+
this.server.listen(netConfig, resolve)
|
|
251
303
|
})
|
|
304
|
+
|
|
305
|
+
log('Listening on %s', this.server.address())
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
private netClose (): void {
|
|
309
|
+
if (!this.status.started || !this.server.listening) {
|
|
310
|
+
return
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
log('Closing server on %s', this.server.address())
|
|
314
|
+
|
|
315
|
+
// NodeJS implementation tracks listening status with `this._handle` property.
|
|
316
|
+
// - Server.close() sets this._handle to null immediately. If this._handle is null, ERR_SERVER_NOT_RUNNING is thrown
|
|
317
|
+
// - Server.listening returns `this._handle !== null` https://github.com/nodejs/node/blob/386d761943bb1b217fba27d6b80b658c23009e60/lib/net.js#L1675
|
|
318
|
+
// - Server.listen() if `this._handle !== null` throws ERR_SERVER_ALREADY_LISTEN
|
|
319
|
+
//
|
|
320
|
+
// NOTE: Both listen and close are technically not async actions, so it's not necessary to track
|
|
321
|
+
// states 'pending-close' or 'pending-listen'
|
|
322
|
+
|
|
323
|
+
// From docs https://nodejs.org/api/net.html#serverclosecallback
|
|
324
|
+
// Stops the server from accepting new connections and keeps existing connections.
|
|
325
|
+
// 'close' event is emitted only emitted when all connections are ended.
|
|
326
|
+
// The optional callback will be called once the 'close' event occurs.
|
|
327
|
+
//
|
|
328
|
+
// NOTE: Since we want to keep existing connections and have checked `!this.server.listening` it's not necessary
|
|
329
|
+
// to pass a callback to close.
|
|
330
|
+
this.server.close()
|
|
252
331
|
}
|
|
253
332
|
}
|
package/src/socket-to-conn.ts
CHANGED
|
@@ -4,7 +4,7 @@ import toIterable from 'stream-to-it'
|
|
|
4
4
|
import { ipPortToMultiaddr as toMultiaddr } from '@libp2p/utils/ip-port-to-multiaddr'
|
|
5
5
|
import { CLOSE_TIMEOUT, SOCKET_TIMEOUT } from './constants.js'
|
|
6
6
|
import { multiaddrToNetConfig } from './utils.js'
|
|
7
|
-
import
|
|
7
|
+
import { CodeError } from '@libp2p/interfaces/errors'
|
|
8
8
|
import type { Socket } from 'net'
|
|
9
9
|
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
10
10
|
import type { MultiaddrConnection } from '@libp2p/interface-connection'
|
|
@@ -49,7 +49,7 @@ export const toMultiaddrConnection = (socket: Socket, options: ToConnectionOptio
|
|
|
49
49
|
if (socket.remoteAddress == null || socket.remotePort == null) {
|
|
50
50
|
// this can be undefined if the socket is destroyed (for example, if the client disconnected)
|
|
51
51
|
// https://nodejs.org/dist/latest-v16.x/docs/api/net.html#socketremoteaddress
|
|
52
|
-
throw
|
|
52
|
+
throw new CodeError('Could not determine remote address or port', 'ERR_NO_REMOTE_ADDRESS')
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
remoteAddr = toMultiaddr(socket.remoteAddress, socket.remotePort)
|
|
@@ -68,7 +68,7 @@ export const toMultiaddrConnection = (socket: Socket, options: ToConnectionOptio
|
|
|
68
68
|
// only destroy with an error if the remote has not sent the FIN message
|
|
69
69
|
let err: Error | undefined
|
|
70
70
|
if (socket.readable) {
|
|
71
|
-
err =
|
|
71
|
+
err = new CodeError('Socket read timeout', 'ERR_SOCKET_READ_TIMEOUT')
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
// if the socket times out due to inactivity we must manually close the connection
|
|
@@ -140,7 +140,7 @@ export const toMultiaddrConnection = (socket: Socket, options: ToConnectionOptio
|
|
|
140
140
|
log('%s socket close timeout after %dms, destroying it manually', lOptsStr, Date.now() - start)
|
|
141
141
|
|
|
142
142
|
// will trigger 'error' and 'close' events that resolves promise
|
|
143
|
-
socket.destroy(
|
|
143
|
+
socket.destroy(new CodeError('Socket close timeout', 'ERR_SOCKET_CLOSE_TIMEOUT'))
|
|
144
144
|
}
|
|
145
145
|
}, closeTimeout).unref()
|
|
146
146
|
|