@libp2p/tcp 4.0.1 → 4.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.
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  import net from 'net';
3
- import { CreateListenerOptions, DialOptions, symbol, Transport } from '@libp2p/interface-transport';
3
+ import { CreateListenerOptions, DialOptions, Listener, symbol, Transport } from '@libp2p/interface-transport';
4
4
  import type { AbortOptions, Multiaddr } from '@multiformats/multiaddr';
5
5
  import type { Connection } from '@libp2p/interface-connection';
6
6
  export interface TCPOptions {
@@ -16,6 +16,11 @@ export interface TCPOptions {
16
16
  * When closing a socket, wait this long for it to close gracefully before it is closed more forcibly
17
17
  */
18
18
  socketCloseTimeout?: number;
19
+ /**
20
+ * Set this property to reject connections when the server's connection count gets high.
21
+ * https://nodejs.org/api/net.html#servermaxconnections
22
+ */
23
+ maxConnections?: number;
19
24
  }
20
25
  /**
21
26
  * Expose a subset of net.connect options
@@ -42,7 +47,7 @@ export declare class TCP implements Transport {
42
47
  * anytime a new incoming Connection has been successfully upgraded via
43
48
  * `upgrader.upgradeInbound`.
44
49
  */
45
- createListener(options: TCPCreateListenerOptions): import("@libp2p/interface-transport").Listener;
50
+ createListener(options: TCPCreateListenerOptions): Listener;
46
51
  /**
47
52
  * Takes a list of `Multiaddr`s and returns only valid TCP addresses
48
53
  */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA,OAAO,GAAG,MAAM,KAAK,CAAA;AASrB,OAAO,EAAE,qBAAqB,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAA;AACnG,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAEtE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAA;AAI9D,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,8BAA8B,CAAC,EAAE,MAAM,CAAA;IAEvC;;OAEG;IACH,+BAA+B,CAAC,EAAE,MAAM,CAAA;IAExC;;OAEG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAiB,SAAQ,YAAY;IACpD,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED,MAAM,WAAW,cAAe,SAAQ,WAAW,EAAE,gBAAgB;CAEpE;AAED,MAAM,WAAW,wBAAyB,SAAQ,qBAAqB,EAAE,gBAAgB;CAExF;AAED,qBAAa,GAAI,YAAW,SAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAY;gBAEpB,OAAO,GAAE,UAAe;IAIrC,IAAI,CAAC,MAAM,CAAC,IAAK,IAAI,CAEpB;IAED,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,WAEvB;IAEK,IAAI,CAAE,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC;IAsBlE,QAAQ,CAAE,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,cAAc;IAgEtD;;;;OAIG;IACH,cAAc,CAAE,OAAO,EAAE,wBAAwB;IAQjD;;OAEG;IACH,MAAM,CAAE,UAAU,EAAE,SAAS,EAAE;CAehC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA,OAAO,GAAG,MAAM,KAAK,CAAA;AASrB,OAAO,EAAE,qBAAqB,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAA;AAC7G,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAEtE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAA;AAI9D,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,8BAA8B,CAAC,EAAE,MAAM,CAAA;IAEvC;;OAEG;IACH,+BAA+B,CAAC,EAAE,MAAM,CAAA;IAExC;;OAEG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAE3B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAiB,SAAQ,YAAY;IACpD,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED,MAAM,WAAW,cAAe,SAAQ,WAAW,EAAE,gBAAgB;CAEpE;AAED,MAAM,WAAW,wBAAyB,SAAQ,qBAAqB,EAAE,gBAAgB;CAExF;AAED,qBAAa,GAAI,YAAW,SAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAY;gBAEpB,OAAO,GAAE,UAAe;IAIrC,IAAI,CAAC,MAAM,CAAC,IAAK,IAAI,CAEpB;IAED,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,WAEvB;IAEK,IAAI,CAAE,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC;IAsBlE,QAAQ,CAAE,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,cAAc;IAgEtD;;;;OAIG;IACH,cAAc,CAAE,OAAO,EAAE,wBAAwB,GAAG,QAAQ;IAS5D;;OAEG;IACH,MAAM,CAAE,UAAU,EAAE,SAAS,EAAE,GAAG,SAAS,EAAE;CAe9C"}
package/dist/src/index.js CHANGED
@@ -3,7 +3,7 @@ import * as mafmt from '@multiformats/mafmt';
3
3
  import errCode from 'err-code';
4
4
  import { logger } from '@libp2p/logger';
5
5
  import { toMultiaddrConnection } from './socket-to-conn.js';
6
- import { createListener } from './listener.js';
6
+ import { TCPListener } from './listener.js';
7
7
  import { multiaddrToNetConfig } from './utils.js';
8
8
  import { AbortError } from '@libp2p/interfaces/errors';
9
9
  import { CODE_CIRCUIT, CODE_P2P, CODE_UNIX } from './constants.js';
@@ -92,8 +92,9 @@ export class TCP {
92
92
  * `upgrader.upgradeInbound`.
93
93
  */
94
94
  createListener(options) {
95
- return createListener({
95
+ return new TCPListener({
96
96
  ...options,
97
+ maxConnections: this.opts.maxConnections,
97
98
  socketInactivityTimeout: this.opts.inboundSocketInactivityTimeout,
98
99
  socketCloseTimeout: this.opts.socketCloseTimeout
99
100
  });
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -1,15 +1,26 @@
1
+ import { EventEmitter } from '@libp2p/interfaces/events';
1
2
  import type { Connection } from '@libp2p/interface-connection';
2
- import type { Upgrader, Listener } from '@libp2p/interface-transport';
3
+ import type { Upgrader, Listener, ListenerEvents } from '@libp2p/interface-transport';
4
+ import type { Multiaddr } from '@multiformats/multiaddr';
3
5
  import type { TCPCreateListenerOptions } from './index.js';
4
6
  interface Context extends TCPCreateListenerOptions {
5
7
  handler?: (conn: Connection) => void;
6
8
  upgrader: Upgrader;
7
9
  socketInactivityTimeout?: number;
8
10
  socketCloseTimeout?: number;
11
+ maxConnections?: number;
12
+ }
13
+ export declare class TCPListener extends EventEmitter<ListenerEvents> implements Listener {
14
+ private readonly context;
15
+ private readonly server;
16
+ /** Keep track of open connections to destroy in case of timeout */
17
+ private readonly connections;
18
+ private status;
19
+ constructor(context: Context);
20
+ private onSocket;
21
+ getAddrs(): Multiaddr[];
22
+ listen(ma: Multiaddr): Promise<void>;
23
+ close(): Promise<void>;
9
24
  }
10
- /**
11
- * Create listener
12
- */
13
- export declare function createListener(context: Context): Listener;
14
25
  export {};
15
26
  //# sourceMappingURL=listener.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"listener.d.ts","sourceRoot":"","sources":["../../src/listener.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAuB,UAAU,EAAE,MAAM,8BAA8B,CAAA;AACnF,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAA;AAGrE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAA;AAmB1D,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;CAC5B;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAE,OAAO,EAAE,OAAO,YAgI/C"}
1
+ {"version":3,"file":"listener.d.ts","sourceRoot":"","sources":["../../src/listener.ts"],"names":[],"mappings":"AAQA,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;AAe1D,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;CACxB;AAID,qBAAa,WAAY,SAAQ,YAAY,CAAC,cAAc,CAAE,YAAW,QAAQ;IAOlE,OAAO,CAAC,QAAQ,CAAC,OAAO;IANrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAY;IACnC,mEAAmE;IACnE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAiC;IAE7D,OAAO,CAAC,MAAM,CAA6B;gBAEb,OAAO,EAAE,OAAO;IAoB9C,OAAO,CAAC,QAAQ;IAqDhB,QAAQ;IAgCF,MAAM,CAAE,EAAE,EAAE,SAAS;IAkBrB,KAAK;CAaZ"}
@@ -16,15 +16,27 @@ async function attemptClose(maConn) {
16
16
  log.error('an error occurred closing the connection', err);
17
17
  }
18
18
  }
19
- /**
20
- * Create listener
21
- */
22
- export function createListener(context) {
23
- const { handler, upgrader, socketInactivityTimeout, socketCloseTimeout } = context;
24
- context.keepAlive = context.keepAlive ?? true;
25
- let peerId;
26
- let listeningAddr;
27
- const server = Object.assign(net.createServer(context, socket => {
19
+ export class TCPListener extends EventEmitter {
20
+ constructor(context) {
21
+ super();
22
+ this.context = context;
23
+ /** Keep track of open connections to destroy in case of timeout */
24
+ this.connections = new Set();
25
+ this.status = { started: false };
26
+ context.keepAlive = context.keepAlive ?? true;
27
+ this.server = net.createServer(context, this.onSocket.bind(this));
28
+ // https://nodejs.org/api/net.html#servermaxconnections
29
+ // If set reject connections when the server's connection count gets high
30
+ // Useful to prevent too resource exhaustion via many open connections on high bursts of activity
31
+ if (context.maxConnections !== undefined) {
32
+ this.server.maxConnections = context.maxConnections;
33
+ }
34
+ this.server
35
+ .on('listening', () => this.dispatchEvent(new CustomEvent('listening')))
36
+ .on('error', err => this.dispatchEvent(new CustomEvent('error', { detail: err })))
37
+ .on('close', () => this.dispatchEvent(new CustomEvent('close')));
38
+ }
39
+ onSocket(socket) {
28
40
  // Avoid uncaught errors caused by unstable connections
29
41
  socket.on('error', err => {
30
42
  log('socket error', err);
@@ -32,9 +44,9 @@ export function createListener(context) {
32
44
  let maConn;
33
45
  try {
34
46
  maConn = toMultiaddrConnection(socket, {
35
- listeningAddr,
36
- socketInactivityTimeout,
37
- socketCloseTimeout
47
+ listeningAddr: this.status.started ? this.status.listeningAddr : undefined,
48
+ socketInactivityTimeout: this.context.socketInactivityTimeout,
49
+ socketCloseTimeout: this.context.socketCloseTimeout
38
50
  });
39
51
  }
40
52
  catch (err) {
@@ -43,14 +55,17 @@ export function createListener(context) {
43
55
  }
44
56
  log('new inbound connection %s', maConn.remoteAddr);
45
57
  try {
46
- upgrader.upgradeInbound(maConn)
58
+ this.context.upgrader.upgradeInbound(maConn)
47
59
  .then((conn) => {
48
60
  log('inbound connection %s upgraded', maConn.remoteAddr);
49
- trackConn(server, maConn, socket);
50
- if (handler != null) {
51
- handler(conn);
61
+ this.connections.add(maConn);
62
+ socket.once('close', () => {
63
+ this.connections.delete(maConn);
64
+ });
65
+ if (this.context.handler != null) {
66
+ this.context.handler(conn);
52
67
  }
53
- listener.dispatchEvent(new CustomEvent('connection', { detail: conn }));
68
+ this.dispatchEvent(new CustomEvent('connection', { detail: conn }));
54
69
  })
55
70
  .catch(async (err) => {
56
71
  log.error('inbound connection failed', err);
@@ -67,74 +82,60 @@ export function createListener(context) {
67
82
  log.error('closing inbound connection failed', err);
68
83
  });
69
84
  }
70
- }),
71
- // Keep track of open connections to destroy in case of timeout
72
- { __connections: [] });
73
- const listener = Object.assign(new EventEmitter(), {
74
- getAddrs: () => {
75
- let addrs = [];
76
- const address = server.address();
77
- if (address == null) {
78
- return [];
79
- }
80
- if (typeof address === 'string') {
81
- addrs = [listeningAddr];
82
- }
83
- else {
84
- try {
85
- // Because TCP will only return the IPv6 version
86
- // we need to capture from the passed multiaddr
87
- if (listeningAddr.toString().startsWith('/ip4')) {
88
- addrs = addrs.concat(getMultiaddrs('ip4', address.address, address.port));
89
- }
90
- else if (address.family === 'IPv6') {
91
- addrs = addrs.concat(getMultiaddrs('ip6', address.address, address.port));
92
- }
85
+ }
86
+ getAddrs() {
87
+ if (!this.status.started) {
88
+ return [];
89
+ }
90
+ let addrs = [];
91
+ const address = this.server.address();
92
+ const { listeningAddr, peerId } = this.status;
93
+ if (address == null) {
94
+ return [];
95
+ }
96
+ if (typeof address === 'string') {
97
+ addrs = [listeningAddr];
98
+ }
99
+ else {
100
+ try {
101
+ // Because TCP will only return the IPv6 version
102
+ // we need to capture from the passed multiaddr
103
+ if (listeningAddr.toString().startsWith('/ip4')) {
104
+ addrs = addrs.concat(getMultiaddrs('ip4', address.address, address.port));
93
105
  }
94
- catch (err) {
95
- log.error('could not turn %s:%s into multiaddr', address.address, address.port, err);
106
+ else if (address.family === 'IPv6') {
107
+ addrs = addrs.concat(getMultiaddrs('ip6', address.address, address.port));
96
108
  }
97
109
  }
98
- return addrs.map(ma => peerId != null ? ma.encapsulate(`/p2p/${peerId}`) : ma);
99
- },
100
- listen: async (ma) => {
101
- listeningAddr = ma;
102
- peerId = ma.getPeerId();
103
- if (peerId == null) {
104
- listeningAddr = ma.decapsulateCode(CODE_P2P);
110
+ catch (err) {
111
+ log.error('could not turn %s:%s into multiaddr', address.address, address.port, err);
105
112
  }
106
- return await new Promise((resolve, reject) => {
107
- const options = multiaddrToNetConfig(listeningAddr);
108
- server.listen(options, (err) => {
109
- if (err != null) {
110
- return reject(err);
111
- }
112
- log('Listening on %s', server.address());
113
- resolve();
114
- });
115
- });
116
- },
117
- close: async () => {
118
- if (!server.listening) {
119
- return;
120
- }
121
- await Promise.all(server.__connections.map(async (maConn) => await attemptClose(maConn)));
122
- await new Promise((resolve, reject) => {
123
- server.close(err => (err != null) ? reject(err) : resolve());
113
+ }
114
+ return addrs.map(ma => peerId != null ? ma.encapsulate(`/p2p/${peerId}`) : ma);
115
+ }
116
+ async listen(ma) {
117
+ const peerId = ma.getPeerId();
118
+ const listeningAddr = peerId == null ? ma.decapsulateCode(CODE_P2P) : ma;
119
+ this.status = { started: true, listeningAddr, peerId };
120
+ return await new Promise((resolve, reject) => {
121
+ const options = multiaddrToNetConfig(listeningAddr);
122
+ this.server.listen(options, (err) => {
123
+ if (err != null) {
124
+ return reject(err);
125
+ }
126
+ log('Listening on %s', this.server.address());
127
+ resolve();
124
128
  });
129
+ });
130
+ }
131
+ async close() {
132
+ if (!this.server.listening) {
133
+ return;
125
134
  }
126
- });
127
- server
128
- .on('listening', () => listener.dispatchEvent(new CustomEvent('listening')))
129
- .on('error', err => listener.dispatchEvent(new CustomEvent('error', { detail: err })))
130
- .on('close', () => listener.dispatchEvent(new CustomEvent('close')));
131
- return listener;
132
- }
133
- function trackConn(server, maConn, socket) {
134
- server.__connections.push(maConn);
135
- const untrackConn = () => {
136
- server.__connections = server.__connections.filter(c => c !== maConn);
137
- };
138
- socket.once('close', untrackConn);
135
+ await Promise.all(Array.from(this.connections.values()).map(async (maConn) => await attemptClose(maConn)));
136
+ await new Promise((resolve, reject) => {
137
+ this.server.close(err => (err != null) ? reject(err) : resolve());
138
+ });
139
+ }
139
140
  }
140
141
  //# sourceMappingURL=listener.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"listener.js","sourceRoot":"","sources":["../../src/listener.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"listener.js","sourceRoot":"","sources":["../../src/listener.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@libp2p/tcp",
3
- "version": "4.0.1",
3
+ "version": "4.1.0",
4
4
  "description": "Node.js implementation of the TCP module that libp2p uses, which implements the interface-connection and interface-transport interfaces",
5
5
  "license": "Apache-2.0 OR MIT",
6
6
  "homepage": "https://github.com/libp2p/js-libp2p-tcp#readme",
package/src/index.ts CHANGED
@@ -3,11 +3,11 @@ import * as mafmt from '@multiformats/mafmt'
3
3
  import errCode from 'err-code'
4
4
  import { logger } from '@libp2p/logger'
5
5
  import { toMultiaddrConnection } from './socket-to-conn.js'
6
- import { createListener } from './listener.js'
6
+ import { TCPListener } from './listener.js'
7
7
  import { multiaddrToNetConfig } from './utils.js'
8
8
  import { AbortError } from '@libp2p/interfaces/errors'
9
9
  import { CODE_CIRCUIT, CODE_P2P, CODE_UNIX } from './constants.js'
10
- import { CreateListenerOptions, DialOptions, symbol, Transport } from '@libp2p/interface-transport'
10
+ import { CreateListenerOptions, DialOptions, Listener, symbol, Transport } from '@libp2p/interface-transport'
11
11
  import type { AbortOptions, Multiaddr } from '@multiformats/multiaddr'
12
12
  import type { Socket, IpcSocketConnectOpts, TcpSocketConnectOpts } from 'net'
13
13
  import type { Connection } from '@libp2p/interface-connection'
@@ -29,6 +29,12 @@ export interface TCPOptions {
29
29
  * When closing a socket, wait this long for it to close gracefully before it is closed more forcibly
30
30
  */
31
31
  socketCloseTimeout?: number
32
+
33
+ /**
34
+ * Set this property to reject connections when the server's connection count gets high.
35
+ * https://nodejs.org/api/net.html#servermaxconnections
36
+ */
37
+ maxConnections?: number
32
38
  }
33
39
 
34
40
  /**
@@ -155,9 +161,10 @@ export class TCP implements Transport {
155
161
  * anytime a new incoming Connection has been successfully upgraded via
156
162
  * `upgrader.upgradeInbound`.
157
163
  */
158
- createListener (options: TCPCreateListenerOptions) {
159
- return createListener({
164
+ createListener (options: TCPCreateListenerOptions): Listener {
165
+ return new TCPListener({
160
166
  ...options,
167
+ maxConnections: this.opts.maxConnections,
161
168
  socketInactivityTimeout: this.opts.inboundSocketInactivityTimeout,
162
169
  socketCloseTimeout: this.opts.socketCloseTimeout
163
170
  })
@@ -166,7 +173,7 @@ export class TCP implements Transport {
166
173
  /**
167
174
  * Takes a list of `Multiaddr`s and returns only valid TCP addresses
168
175
  */
169
- filter (multiaddrs: Multiaddr[]) {
176
+ filter (multiaddrs: Multiaddr[]): Multiaddr[] {
170
177
  multiaddrs = Array.isArray(multiaddrs) ? multiaddrs : [multiaddrs]
171
178
 
172
179
  return multiaddrs.filter(ma => {
package/src/listener.ts CHANGED
@@ -8,17 +8,12 @@ import {
8
8
  } from './utils.js'
9
9
  import { EventEmitter, CustomEvent } from '@libp2p/interfaces/events'
10
10
  import type { MultiaddrConnection, Connection } from '@libp2p/interface-connection'
11
- import type { Upgrader, Listener } from '@libp2p/interface-transport'
12
- import type { Server } from 'net'
11
+ import type { Upgrader, Listener, ListenerEvents } from '@libp2p/interface-transport'
13
12
  import type { Multiaddr } from '@multiformats/multiaddr'
14
13
  import type { TCPCreateListenerOptions } from './index.js'
15
14
 
16
15
  const log = logger('libp2p:tcp:listener')
17
16
 
18
- interface ServerWithMultiaddrConnections extends Server {
19
- __connections: MultiaddrConnection[]
20
- }
21
-
22
17
  /**
23
18
  * Attempts to close the given maConn. If a failure occurs, it will be logged
24
19
  */
@@ -35,22 +30,39 @@ interface Context extends TCPCreateListenerOptions {
35
30
  upgrader: Upgrader
36
31
  socketInactivityTimeout?: number
37
32
  socketCloseTimeout?: number
33
+ maxConnections?: number
38
34
  }
39
35
 
40
- /**
41
- * Create listener
42
- */
43
- export function createListener (context: Context) {
44
- const {
45
- handler, upgrader, socketInactivityTimeout, socketCloseTimeout
46
- } = context
36
+ type Status = {started: false} | {started: true, listeningAddr: Multiaddr, peerId: string | null }
37
+
38
+ export class TCPListener extends EventEmitter<ListenerEvents> implements Listener {
39
+ private readonly server: net.Server
40
+ /** Keep track of open connections to destroy in case of timeout */
41
+ private readonly connections = new Set<MultiaddrConnection>()
42
+
43
+ private status: Status = { started: false }
44
+
45
+ constructor (private readonly context: Context) {
46
+ super()
47
+
48
+ context.keepAlive = context.keepAlive ?? true
49
+
50
+ this.server = net.createServer(context, this.onSocket.bind(this))
47
51
 
48
- context.keepAlive = context.keepAlive ?? true
52
+ // https://nodejs.org/api/net.html#servermaxconnections
53
+ // If set reject connections when the server's connection count gets high
54
+ // Useful to prevent too resource exhaustion via many open connections on high bursts of activity
55
+ if (context.maxConnections !== undefined) {
56
+ this.server.maxConnections = context.maxConnections
57
+ }
49
58
 
50
- let peerId: string | null
51
- let listeningAddr: Multiaddr
59
+ this.server
60
+ .on('listening', () => this.dispatchEvent(new CustomEvent('listening')))
61
+ .on('error', err => this.dispatchEvent(new CustomEvent<Error>('error', { detail: err })))
62
+ .on('close', () => this.dispatchEvent(new CustomEvent('close')))
63
+ }
52
64
 
53
- const server: ServerWithMultiaddrConnections = Object.assign(net.createServer(context, socket => {
65
+ private onSocket (socket: net.Socket) {
54
66
  // Avoid uncaught errors caused by unstable connections
55
67
  socket.on('error', err => {
56
68
  log('socket error', err)
@@ -59,9 +71,9 @@ export function createListener (context: Context) {
59
71
  let maConn: MultiaddrConnection
60
72
  try {
61
73
  maConn = toMultiaddrConnection(socket, {
62
- listeningAddr,
63
- socketInactivityTimeout,
64
- socketCloseTimeout
74
+ listeningAddr: this.status.started ? this.status.listeningAddr : undefined,
75
+ socketInactivityTimeout: this.context.socketInactivityTimeout,
76
+ socketCloseTimeout: this.context.socketCloseTimeout
65
77
  })
66
78
  } catch (err) {
67
79
  log.error('inbound connection failed', err)
@@ -70,16 +82,20 @@ export function createListener (context: Context) {
70
82
 
71
83
  log('new inbound connection %s', maConn.remoteAddr)
72
84
  try {
73
- upgrader.upgradeInbound(maConn)
85
+ this.context.upgrader.upgradeInbound(maConn)
74
86
  .then((conn) => {
75
87
  log('inbound connection %s upgraded', maConn.remoteAddr)
76
- trackConn(server, maConn, socket)
88
+ this.connections.add(maConn)
89
+
90
+ socket.once('close', () => {
91
+ this.connections.delete(maConn)
92
+ })
77
93
 
78
- if (handler != null) {
79
- handler(conn)
94
+ if (this.context.handler != null) {
95
+ this.context.handler(conn)
80
96
  }
81
97
 
82
- listener.dispatchEvent(new CustomEvent<Connection>('connection', { detail: conn }))
98
+ this.dispatchEvent(new CustomEvent<Connection>('connection', { detail: conn }))
83
99
  })
84
100
  .catch(async err => {
85
101
  log.error('inbound connection failed', err)
@@ -97,85 +113,69 @@ export function createListener (context: Context) {
97
113
  log.error('closing inbound connection failed', err)
98
114
  })
99
115
  }
100
- }),
101
- // Keep track of open connections to destroy in case of timeout
102
- { __connections: [] })
116
+ }
103
117
 
104
- const listener: Listener = Object.assign(new EventEmitter(), {
105
- getAddrs: () => {
106
- let addrs: Multiaddr[] = []
107
- const address = server.address()
118
+ getAddrs () {
119
+ if (!this.status.started) {
120
+ return []
121
+ }
108
122
 
109
- if (address == null) {
110
- return []
111
- }
123
+ let addrs: Multiaddr[] = []
124
+ const address = this.server.address()
125
+ const { listeningAddr, peerId } = this.status
112
126
 
113
- if (typeof address === 'string') {
114
- addrs = [listeningAddr]
115
- } else {
116
- try {
117
- // Because TCP will only return the IPv6 version
118
- // we need to capture from the passed multiaddr
119
- if (listeningAddr.toString().startsWith('/ip4')) {
120
- addrs = addrs.concat(getMultiaddrs('ip4', address.address, address.port))
121
- } else if (address.family === 'IPv6') {
122
- addrs = addrs.concat(getMultiaddrs('ip6', address.address, address.port))
123
- }
124
- } catch (err) {
125
- log.error('could not turn %s:%s into multiaddr', address.address, address.port, err)
127
+ if (address == null) {
128
+ return []
129
+ }
130
+
131
+ if (typeof address === 'string') {
132
+ addrs = [listeningAddr]
133
+ } else {
134
+ try {
135
+ // Because TCP will only return the IPv6 version
136
+ // we need to capture from the passed multiaddr
137
+ if (listeningAddr.toString().startsWith('/ip4')) {
138
+ addrs = addrs.concat(getMultiaddrs('ip4', address.address, address.port))
139
+ } else if (address.family === 'IPv6') {
140
+ addrs = addrs.concat(getMultiaddrs('ip6', address.address, address.port))
126
141
  }
142
+ } catch (err) {
143
+ log.error('could not turn %s:%s into multiaddr', address.address, address.port, err)
127
144
  }
145
+ }
128
146
 
129
- return addrs.map(ma => peerId != null ? ma.encapsulate(`/p2p/${peerId}`) : ma)
130
- },
131
- listen: async (ma: Multiaddr) => {
132
- listeningAddr = ma
133
- peerId = ma.getPeerId()
147
+ return addrs.map(ma => peerId != null ? ma.encapsulate(`/p2p/${peerId}`) : ma)
148
+ }
134
149
 
135
- if (peerId == null) {
136
- listeningAddr = ma.decapsulateCode(CODE_P2P)
137
- }
150
+ async listen (ma: Multiaddr) {
151
+ const peerId = ma.getPeerId()
152
+ const listeningAddr = peerId == null ? ma.decapsulateCode(CODE_P2P) : ma
138
153
 
139
- return await new Promise<void>((resolve, reject) => {
140
- const options = multiaddrToNetConfig(listeningAddr)
141
- server.listen(options, (err?: any) => {
142
- if (err != null) {
143
- return reject(err)
144
- }
145
- log('Listening on %s', server.address())
146
- resolve()
147
- })
148
- })
149
- },
150
- close: async () => {
151
- if (!server.listening) {
152
- return
153
- }
154
+ this.status = { started: true, listeningAddr, peerId }
154
155
 
155
- await Promise.all(
156
- server.__connections.map(async maConn => await attemptClose(maConn))
157
- )
158
-
159
- await new Promise<void>((resolve, reject) => {
160
- server.close(err => (err != null) ? reject(err) : resolve())
156
+ return await new Promise<void>((resolve, reject) => {
157
+ const options = multiaddrToNetConfig(listeningAddr)
158
+ this.server.listen(options, (err?: any) => {
159
+ if (err != null) {
160
+ return reject(err)
161
+ }
162
+ log('Listening on %s', this.server.address())
163
+ resolve()
161
164
  })
162
- }
163
- })
164
-
165
- server
166
- .on('listening', () => listener.dispatchEvent(new CustomEvent('listening')))
167
- .on('error', err => listener.dispatchEvent(new CustomEvent<Error>('error', { detail: err })))
168
- .on('close', () => listener.dispatchEvent(new CustomEvent('close')))
165
+ })
166
+ }
169
167
 
170
- return listener
171
- }
168
+ async close () {
169
+ if (!this.server.listening) {
170
+ return
171
+ }
172
172
 
173
- function trackConn (server: ServerWithMultiaddrConnections, maConn: MultiaddrConnection, socket: net.Socket) {
174
- server.__connections.push(maConn)
173
+ await Promise.all(
174
+ Array.from(this.connections.values()).map(async maConn => await attemptClose(maConn))
175
+ )
175
176
 
176
- const untrackConn = () => {
177
- server.__connections = server.__connections.filter(c => c !== maConn)
177
+ await new Promise<void>((resolve, reject) => {
178
+ this.server.close(err => (err != null) ? reject(err) : resolve())
179
+ })
178
180
  }
179
-
180
- socket.once('close', untrackConn)
181
181
  }