@libp2p/tcp 3.0.2 → 3.0.5

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/README.md CHANGED
@@ -47,9 +47,10 @@ const upgrader = {
47
47
  upgradeOutbound: maConn => maConn
48
48
  }
49
49
 
50
- const tcp = new TCP({ upgrader })
50
+ const tcp = new TCP()
51
51
 
52
52
  const listener = tcp.createListener({
53
+ upgrader,
53
54
  handler: (socket) => {
54
55
  console.log('new connection opened')
55
56
  pipe(
@@ -1,4 +1,5 @@
1
1
  export declare const CODE_P2P = 421;
2
2
  export declare const CODE_CIRCUIT = 290;
3
3
  export declare const CLOSE_TIMEOUT = 2000;
4
+ export declare const SOCKET_TIMEOUT = 30000;
4
5
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,QAAQ,MAAM,CAAA;AAC3B,eAAO,MAAM,YAAY,MAAM,CAAA;AAG/B,eAAO,MAAM,aAAa,OAAO,CAAA"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,QAAQ,MAAM,CAAA;AAC3B,eAAO,MAAM,YAAY,MAAM,CAAA;AAG/B,eAAO,MAAM,aAAa,OAAO,CAAA;AAGjC,eAAO,MAAM,cAAc,QAAQ,CAAA"}
@@ -3,4 +3,6 @@ export const CODE_P2P = 421;
3
3
  export const CODE_CIRCUIT = 290;
4
4
  // Time to wait for a connection to close gracefully before destroying it manually
5
5
  export const CLOSE_TIMEOUT = 2000;
6
+ // Close the socket if there is no activity after this long in ms
7
+ export const SOCKET_TIMEOUT = 30000;
6
8
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,yBAAyB;AACzB,MAAM,CAAC,MAAM,QAAQ,GAAG,GAAG,CAAA;AAC3B,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,CAAA;AAE/B,kFAAkF;AAClF,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAA"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,yBAAyB;AACzB,MAAM,CAAC,MAAM,QAAQ,GAAG,GAAG,CAAA;AAC3B,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,CAAA;AAE/B,kFAAkF;AAClF,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAA;AAEjC,iEAAiE;AACjE,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,CAAA"}
@@ -4,7 +4,23 @@ import { CreateListenerOptions, DialOptions, symbol, Transport } from '@libp2p/i
4
4
  import type { Multiaddr } from '@multiformats/multiaddr';
5
5
  import type { AbortOptions } from '@libp2p/interfaces';
6
6
  import type { Connection } from '@libp2p/interface-connection';
7
+ export interface TCPOptions {
8
+ /**
9
+ * An optional number in ms that is used as an inactivity timeout after which the socket will be closed
10
+ */
11
+ inboundSocketInactivityTimeout?: number;
12
+ /**
13
+ * An optional number in ms that is used as an inactivity timeout after which the socket will be closed
14
+ */
15
+ outboundSocketInactivityTimeout?: number;
16
+ /**
17
+ * When closing a socket, wait this long for it to close gracefully before it is closed more forcibly
18
+ */
19
+ socketCloseTimeout?: number;
20
+ }
7
21
  export declare class TCP implements Transport {
22
+ private readonly opts;
23
+ constructor(options?: TCPOptions);
8
24
  get [symbol](): true;
9
25
  get [Symbol.toStringTag](): string;
10
26
  dial(ma: Multiaddr, options: DialOptions): Promise<Connection>;
@@ -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,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAExD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAA;AAI9D,qBAAa,GAAI,YAAW,SAAS;IACnC,IAAI,CAAC,MAAM,CAAC,IAAK,IAAI,CAEpB;IAED,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,WAEvB;IAEK,IAAI,CAAE,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAe/D,QAAQ,CAAE,EAAE,EAAE,SAAS,EAAE,OAAO,GAAE,YAAiB;IA+DzD;;;;OAIG;IACH,cAAc,CAAE,OAAO,EAAE,qBAAqB;IAI9C;;OAEG;IACH,MAAM,CAAE,UAAU,EAAE,SAAS,EAAE;CAWhC"}
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,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAExD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtD,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,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,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAoB/D,QAAQ,CAAE,EAAE,EAAE,SAAS,EAAE,OAAO,GAAE,YAAiB;IA+DzD;;;;OAIG;IACH,cAAc,CAAE,OAAO,EAAE,qBAAqB;IAQ9C;;OAEG;IACH,MAAM,CAAE,UAAU,EAAE,SAAS,EAAE;CAWhC"}
package/dist/src/index.js CHANGED
@@ -10,6 +10,9 @@ import { CODE_CIRCUIT, CODE_P2P } from './constants.js';
10
10
  import { symbol } from '@libp2p/interface-transport';
11
11
  const log = logger('libp2p:tcp');
12
12
  export class TCP {
13
+ constructor(options = {}) {
14
+ this.opts = options;
15
+ }
13
16
  get [symbol]() {
14
17
  return true;
15
18
  }
@@ -22,7 +25,12 @@ export class TCP {
22
25
  socket.on('error', err => {
23
26
  log('socket error', err);
24
27
  });
25
- const maConn = toMultiaddrConnection(socket, { remoteAddr: ma, signal: options.signal });
28
+ const maConn = toMultiaddrConnection(socket, {
29
+ remoteAddr: ma,
30
+ signal: options.signal,
31
+ socketInactivityTimeout: this.opts.outboundSocketInactivityTimeout,
32
+ socketCloseTimeout: this.opts.socketCloseTimeout
33
+ });
26
34
  log('new outbound connection %s', maConn.remoteAddr);
27
35
  const conn = await options.upgrader.upgradeOutbound(maConn);
28
36
  log('outbound connection %s upgraded', maConn.remoteAddr);
@@ -82,7 +90,11 @@ export class TCP {
82
90
  * `upgrader.upgradeInbound`.
83
91
  */
84
92
  createListener(options) {
85
- return createListener(options);
93
+ return createListener({
94
+ ...options,
95
+ socketInactivityTimeout: this.opts.inboundSocketInactivityTimeout,
96
+ socketCloseTimeout: this.opts.socketCloseTimeout
97
+ });
86
98
  }
87
99
  /**
88
100
  * Takes a list of `Multiaddr`s and returns only valid TCP addresses
@@ -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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"}
@@ -3,6 +3,8 @@ import type { Upgrader, Listener } from '@libp2p/interface-transport';
3
3
  interface Context {
4
4
  handler?: (conn: Connection) => void;
5
5
  upgrader: Upgrader;
6
+ socketInactivityTimeout?: number;
7
+ socketCloseTimeout?: number;
6
8
  }
7
9
  /**
8
10
  * Create listener
@@ -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;AAqBrE,UAAU,OAAO;IACf,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAA;IACpC,QAAQ,EAAE,QAAQ,CAAA;CACnB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAE,OAAO,EAAE,OAAO,YAsH/C"}
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;AAqBrE,UAAU,OAAO;IACf,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,YA0H/C"}
@@ -20,7 +20,7 @@ async function attemptClose(maConn) {
20
20
  * Create listener
21
21
  */
22
22
  export function createListener(context) {
23
- const { handler, upgrader } = context;
23
+ const { handler, upgrader, socketInactivityTimeout, socketCloseTimeout } = context;
24
24
  let peerId;
25
25
  let listeningAddr;
26
26
  const server = Object.assign(net.createServer(socket => {
@@ -30,7 +30,11 @@ export function createListener(context) {
30
30
  });
31
31
  let maConn;
32
32
  try {
33
- maConn = toMultiaddrConnection(socket, { listeningAddr });
33
+ maConn = toMultiaddrConnection(socket, {
34
+ listeningAddr,
35
+ socketInactivityTimeout,
36
+ socketCloseTimeout
37
+ });
34
38
  }
35
39
  catch (err) {
36
40
  log.error('inbound connection failed', err);
@@ -106,9 +110,7 @@ export function createListener(context) {
106
110
  if (!server.listening) {
107
111
  return;
108
112
  }
109
- await Promise.all([
110
- server.__connections.map(async (maConn) => await attemptClose(maConn))
111
- ]);
113
+ await Promise.all(server.__connections.map(async (maConn) => await attemptClose(maConn)));
112
114
  await new Promise((resolve, reject) => {
113
115
  server.close(err => (err != null) ? reject(err) : resolve());
114
116
  });
@@ -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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"}
@@ -6,6 +6,8 @@ interface ToConnectionOptions {
6
6
  remoteAddr?: Multiaddr;
7
7
  localAddr?: Multiaddr;
8
8
  signal?: AbortSignal;
9
+ socketInactivityTimeout?: number;
10
+ socketCloseTimeout?: number;
9
11
  }
10
12
  /**
11
13
  * Convert a socket into a MultiaddrConnection
@@ -1 +1 @@
1
- {"version":3,"file":"socket-to-conn.d.ts","sourceRoot":"","sources":["../../src/socket-to-conn.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,KAAK,CAAA;AACjC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAA;AAIvE,UAAU,mBAAmB;IAC3B,aAAa,CAAC,EAAE,SAAS,CAAA;IACzB,UAAU,CAAC,EAAE,SAAS,CAAA;IACtB,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB,WAAY,MAAM,YAAY,mBAAmB,wBAmGlF,CAAA"}
1
+ {"version":3,"file":"socket-to-conn.d.ts","sourceRoot":"","sources":["../../src/socket-to-conn.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,KAAK,CAAA;AACjC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAA;AAIvE,UAAU,mBAAmB;IAC3B,aAAa,CAAC,EAAE,SAAS,CAAA;IACzB,UAAU,CAAC,EAAE,SAAS,CAAA;IACtB,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB,WAAY,MAAM,YAAY,mBAAmB,wBAoJlF,CAAA"}
@@ -3,7 +3,8 @@ import { logger } from '@libp2p/logger';
3
3
  // @ts-expect-error no types
4
4
  import toIterable from 'stream-to-it';
5
5
  import { ipPortToMultiaddr as toMultiaddr } from '@libp2p/utils/ip-port-to-multiaddr';
6
- import { CLOSE_TIMEOUT } from './constants.js';
6
+ import { CLOSE_TIMEOUT, SOCKET_TIMEOUT } from './constants.js';
7
+ import errCode from 'err-code';
7
8
  const log = logger('libp2p:tcp:socket');
8
9
  /**
9
10
  * Convert a socket into a MultiaddrConnection
@@ -11,6 +12,8 @@ const log = logger('libp2p:tcp:socket');
11
12
  */
12
13
  export const toMultiaddrConnection = (socket, options) => {
13
14
  options = options ?? {};
15
+ const inactivityTimeout = options.socketInactivityTimeout ?? SOCKET_TIMEOUT;
16
+ const closeTimeout = options.socketCloseTimeout ?? CLOSE_TIMEOUT;
14
17
  // Check if we are connected on a unix path
15
18
  if (options.listeningAddr?.getPath() != null) {
16
19
  options.remoteAddr = options.listeningAddr;
@@ -18,20 +21,43 @@ export const toMultiaddrConnection = (socket, options) => {
18
21
  if (options.remoteAddr?.getPath() != null) {
19
22
  options.localAddr = options.remoteAddr;
20
23
  }
24
+ const remoteAddr = options.remoteAddr ?? toMultiaddr(socket.remoteAddress ?? '', socket.remotePort ?? '');
25
+ const { host, port } = remoteAddr.toOptions();
21
26
  const { sink, source } = toIterable.duplex(socket);
27
+ // by default there is no timeout
28
+ // https://nodejs.org/dist/latest-v16.x/docs/api/net.html#socketsettimeouttimeout-callback
29
+ socket.setTimeout(inactivityTimeout, () => {
30
+ log('%s:%s socket read timeout', host, port);
31
+ // only destroy with an error if the remote has not sent the FIN message
32
+ let err;
33
+ if (socket.readable) {
34
+ err = errCode(new Error('Socket read timeout'), 'ERR_SOCKET_READ_TIMEOUT');
35
+ }
36
+ // if the socket times out due to inactivity we must manually close the connection
37
+ // https://nodejs.org/dist/latest-v16.x/docs/api/net.html#event-timeout
38
+ socket.destroy(err);
39
+ });
40
+ socket.once('close', () => {
41
+ log('%s:%s socket closed', host, port);
42
+ // In instances where `close` was not explicitly called,
43
+ // such as an iterable stream ending, ensure we have set the close
44
+ // timeline
45
+ if (maConn.timeline.close == null) {
46
+ maConn.timeline.close = Date.now();
47
+ }
48
+ });
49
+ socket.once('end', () => {
50
+ // the remote sent a FIN packet which means no more data will be sent
51
+ // https://nodejs.org/dist/latest-v16.x/docs/api/net.html#event-end
52
+ log('socket ended', maConn.remoteAddr.toString());
53
+ });
22
54
  const maConn = {
23
55
  async sink(source) {
24
56
  if ((options?.signal) != null) {
25
57
  source = abortableSource(source, options.signal);
26
58
  }
27
59
  try {
28
- await sink((async function* () {
29
- for await (const chunk of source) {
30
- // Convert BufferList to Buffer
31
- // Sink in StreamMuxer define argument as Uint8Array so chunk type infers as number which can't be sliced
32
- yield Buffer.isBuffer(chunk) ? chunk : chunk.slice();
33
- }
34
- })());
60
+ await sink(source);
35
61
  }
36
62
  catch (err) {
37
63
  // If aborted we can safely ignore
@@ -42,53 +68,70 @@ export const toMultiaddrConnection = (socket, options) => {
42
68
  log(err);
43
69
  }
44
70
  }
71
+ // we have finished writing, send the FIN message
72
+ socket.end();
45
73
  },
46
- // Missing Type for "abortable"
47
74
  source: (options.signal != null) ? abortableSource(source, options.signal) : source,
48
75
  // If the remote address was passed, use it - it may have the peer ID encapsulated
49
- remoteAddr: options.remoteAddr ?? toMultiaddr(socket.remoteAddress ?? '', socket.remotePort ?? ''),
76
+ remoteAddr,
50
77
  timeline: { open: Date.now() },
51
78
  async close() {
52
- if (socket.destroyed)
79
+ if (socket.destroyed) {
80
+ log('%s:%s socket was already destroyed when trying to close', host, port);
53
81
  return;
54
- return await new Promise((resolve, reject) => {
82
+ }
83
+ log('%s:%s closing socket', host, port);
84
+ await new Promise((resolve, reject) => {
55
85
  const start = Date.now();
56
86
  // Attempt to end the socket. If it takes longer to close than the
57
87
  // timeout, destroy it manually.
58
88
  const timeout = setTimeout(() => {
59
- const { host, port } = maConn.remoteAddr.toOptions();
60
- log('timeout closing socket to %s:%s after %dms, destroying it manually', host, port, Date.now() - start);
61
89
  if (socket.destroyed) {
62
90
  log('%s:%s is already destroyed', host, port);
91
+ resolve();
63
92
  }
64
93
  else {
65
- socket.destroy();
94
+ log('%s:%s socket close timeout after %dms, destroying it manually', host, port, Date.now() - start);
95
+ // will trigger 'error' and 'close' events that resolves promise
96
+ socket.destroy(errCode(new Error('Socket close timeout'), 'ERR_SOCKET_CLOSE_TIMEOUT'));
66
97
  }
67
- resolve();
68
- }, CLOSE_TIMEOUT).unref();
98
+ }, closeTimeout).unref();
69
99
  socket.once('close', () => {
100
+ log('%s:%s socket closed', host, port);
101
+ // socket completely closed
70
102
  clearTimeout(timeout);
71
103
  resolve();
72
104
  });
73
- socket.end((err) => {
74
- clearTimeout(timeout);
75
- maConn.timeline.close = Date.now();
76
- if (err != null) {
77
- return reject(err);
105
+ socket.once('error', (err) => {
106
+ log('%s:%s socket error', host, port, err);
107
+ // error closing socket
108
+ if (maConn.timeline.close == null) {
109
+ maConn.timeline.close = Date.now();
78
110
  }
79
- resolve();
111
+ if (socket.destroyed) {
112
+ clearTimeout(timeout);
113
+ }
114
+ reject(err);
80
115
  });
116
+ // shorten inactivity timeout
117
+ socket.setTimeout(closeTimeout);
118
+ // close writable end of the socket
119
+ socket.end();
120
+ if (socket.writableLength > 0) {
121
+ // there are outgoing bytes waiting to be sent
122
+ socket.once('drain', () => {
123
+ log('%s:%s socket drained', host, port);
124
+ // all bytes have been sent we can destroy the socket (maybe) before the timeout
125
+ socket.destroy();
126
+ });
127
+ }
128
+ else {
129
+ // nothing to send, destroy immediately
130
+ socket.destroy();
131
+ }
81
132
  });
82
133
  }
83
134
  };
84
- socket.once('close', () => {
85
- // In instances where `close` was not explicitly called,
86
- // such as an iterable stream ending, ensure we have set the close
87
- // timeline
88
- if (maConn.timeline.close == null) {
89
- maConn.timeline.close = Date.now();
90
- }
91
- });
92
135
  return maConn;
93
136
  };
94
137
  //# sourceMappingURL=socket-to-conn.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"socket-to-conn.js","sourceRoot":"","sources":["../../src/socket-to-conn.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"socket-to-conn.js","sourceRoot":"","sources":["../../src/socket-to-conn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,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,OAAO,MAAM,UAAU,CAAA;AAK9B,MAAM,GAAG,GAAG,MAAM,CAAC,mBAAmB,CAAC,CAAA;AAWvC;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,MAAc,EAAE,OAA6B,EAAE,EAAE;IACrF,OAAO,GAAG,OAAO,IAAI,EAAE,CAAA;IACvB,MAAM,iBAAiB,GAAG,OAAO,CAAC,uBAAuB,IAAI,cAAc,CAAA;IAC3E,MAAM,YAAY,GAAG,OAAO,CAAC,kBAAkB,IAAI,aAAa,CAAA;IAEhE,2CAA2C;IAC3C,IAAI,OAAO,CAAC,aAAa,EAAE,OAAO,EAAE,IAAI,IAAI,EAAE;QAC5C,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC,aAAa,CAAA;KAC3C;IAED,IAAI,OAAO,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,IAAI,EAAE;QACzC,OAAO,CAAC,SAAS,GAAG,OAAO,CAAC,UAAU,CAAA;KACvC;IAED,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,WAAW,CAAC,MAAM,CAAC,aAAa,IAAI,EAAE,EAAE,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC,CAAA;IACzG,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,UAAU,CAAC,SAAS,EAAE,CAAA;IAC7C,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IAElD,iCAAiC;IACjC,0FAA0F;IAC1F,MAAM,CAAC,UAAU,CAAC,iBAAiB,EAAE,GAAG,EAAE;QACxC,GAAG,CAAC,2BAA2B,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;QAE5C,wEAAwE;QACxE,IAAI,GAAsB,CAAA;QAC1B,IAAI,MAAM,CAAC,QAAQ,EAAE;YACnB,GAAG,GAAG,OAAO,CAAC,IAAI,KAAK,CAAC,qBAAqB,CAAC,EAAE,yBAAyB,CAAC,CAAA;SAC3E;QAED,kFAAkF;QAClF,uEAAuE;QACvE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IACrB,CAAC,CAAC,CAAA;IAEF,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;QACxB,GAAG,CAAC,qBAAqB,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;QAEtC,wDAAwD;QACxD,kEAAkE;QAClE,WAAW;QACX,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,IAAI,IAAI,EAAE;YACjC,MAAM,CAAC,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;SACnC;IACH,CAAC,CAAC,CAAA;IAEF,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE;QACtB,qEAAqE;QACrE,mEAAmE;QACnE,GAAG,CAAC,cAAc,EAAE,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC,CAAA;IACnD,CAAC,CAAC,CAAA;IAEF,MAAM,MAAM,GAAwB;QAClC,KAAK,CAAC,IAAI,CAAE,MAAM;YAChB,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,IAAI,EAAE;gBAC7B,MAAM,GAAG,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;aACjD;YAED,IAAI;gBACF,MAAM,IAAI,CAAC,MAAM,CAAC,CAAA;aACnB;YAAC,OAAO,GAAQ,EAAE;gBACjB,kCAAkC;gBAClC,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,EAAE;oBAC1B,uEAAuE;oBACvE,gEAAgE;oBAChE,uEAAuE;oBACvE,GAAG,CAAC,GAAG,CAAC,CAAA;iBACT;aACF;YAED,iDAAiD;YACjD,MAAM,CAAC,GAAG,EAAE,CAAA;QACd,CAAC;QAED,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM;QAEnF,kFAAkF;QAClF,UAAU;QAEV,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE;QAE9B,KAAK,CAAC,KAAK;YACT,IAAI,MAAM,CAAC,SAAS,EAAE;gBACpB,GAAG,CAAC,yDAAyD,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;gBAC1E,OAAM;aACP;YAED,GAAG,CAAC,sBAAsB,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;YACvC,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;gBAExB,kEAAkE;gBAClE,gCAAgC;gBAChC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;oBAC9B,IAAI,MAAM,CAAC,SAAS,EAAE;wBACpB,GAAG,CAAC,4BAA4B,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;wBAC7C,OAAO,EAAE,CAAA;qBACV;yBAAM;wBACL,GAAG,CAAC,+DAA+D,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAA;wBAEpG,gEAAgE;wBAChE,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,sBAAsB,CAAC,EAAE,0BAA0B,CAAC,CAAC,CAAA;qBACvF;gBACH,CAAC,EAAE,YAAY,CAAC,CAAC,KAAK,EAAE,CAAA;gBAExB,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;oBACxB,GAAG,CAAC,qBAAqB,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;oBACtC,2BAA2B;oBAC3B,YAAY,CAAC,OAAO,CAAC,CAAA;oBACrB,OAAO,EAAE,CAAA;gBACX,CAAC,CAAC,CAAA;gBACF,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;oBAClC,GAAG,CAAC,oBAAoB,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,CAAA;oBAE1C,uBAAuB;oBACvB,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,IAAI,IAAI,EAAE;wBACjC,MAAM,CAAC,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;qBACnC;oBAED,IAAI,MAAM,CAAC,SAAS,EAAE;wBACpB,YAAY,CAAC,OAAO,CAAC,CAAA;qBACtB;oBAED,MAAM,CAAC,GAAG,CAAC,CAAA;gBACb,CAAC,CAAC,CAAA;gBAEF,6BAA6B;gBAC7B,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,CAAA;gBAE/B,mCAAmC;gBACnC,MAAM,CAAC,GAAG,EAAE,CAAA;gBAEZ,IAAI,MAAM,CAAC,cAAc,GAAG,CAAC,EAAE;oBAC7B,8CAA8C;oBAC9C,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;wBACxB,GAAG,CAAC,sBAAsB,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;wBAEvC,gFAAgF;wBAChF,MAAM,CAAC,OAAO,EAAE,CAAA;oBAClB,CAAC,CAAC,CAAA;iBACH;qBAAM;oBACL,uCAAuC;oBACvC,MAAM,CAAC,OAAO,EAAE,CAAA;iBACjB;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;KACF,CAAA;IAED,OAAO,MAAM,CAAA;AACf,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@libp2p/tcp",
3
- "version": "3.0.2",
3
+ "version": "3.0.5",
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",
@@ -136,7 +136,7 @@
136
136
  "release": "aegir release"
137
137
  },
138
138
  "dependencies": {
139
- "@libp2p/interface-connection": "^2.0.0",
139
+ "@libp2p/interface-connection": "^3.0.1",
140
140
  "@libp2p/interface-transport": "^1.0.0",
141
141
  "@libp2p/interfaces": "^3.0.2",
142
142
  "@libp2p/logger": "^2.0.0",
@@ -148,11 +148,12 @@
148
148
  "stream-to-it": "^0.2.2"
149
149
  },
150
150
  "devDependencies": {
151
- "@libp2p/interface-mocks": "^3.0.1",
152
- "@libp2p/interface-transport-compliance-tests": "^2.0.0",
151
+ "@libp2p/interface-mocks": "^4.0.1",
152
+ "@libp2p/interface-transport-compliance-tests": "^2.0.5",
153
153
  "aegir": "^37.0.4",
154
154
  "it-all": "^1.0.6",
155
155
  "it-pipe": "^2.0.3",
156
+ "p-defer": "^4.0.0",
156
157
  "sinon": "^14.0.0",
157
158
  "uint8arrays": "^3.0.0"
158
159
  }
package/src/constants.ts CHANGED
@@ -4,3 +4,6 @@ export const CODE_CIRCUIT = 290
4
4
 
5
5
  // Time to wait for a connection to close gracefully before destroying it manually
6
6
  export const CLOSE_TIMEOUT = 2000
7
+
8
+ // Close the socket if there is no activity after this long in ms
9
+ export const SOCKET_TIMEOUT = 30000
package/src/index.ts CHANGED
@@ -15,7 +15,30 @@ import type { Connection } from '@libp2p/interface-connection'
15
15
 
16
16
  const log = logger('libp2p:tcp')
17
17
 
18
+ export interface TCPOptions {
19
+ /**
20
+ * An optional number in ms that is used as an inactivity timeout after which the socket will be closed
21
+ */
22
+ inboundSocketInactivityTimeout?: number
23
+
24
+ /**
25
+ * An optional number in ms that is used as an inactivity timeout after which the socket will be closed
26
+ */
27
+ outboundSocketInactivityTimeout?: number
28
+
29
+ /**
30
+ * When closing a socket, wait this long for it to close gracefully before it is closed more forcibly
31
+ */
32
+ socketCloseTimeout?: number
33
+ }
34
+
18
35
  export class TCP implements Transport {
36
+ private readonly opts: TCPOptions
37
+
38
+ constructor (options: TCPOptions = {}) {
39
+ this.opts = options
40
+ }
41
+
19
42
  get [symbol] (): true {
20
43
  return true
21
44
  }
@@ -32,7 +55,12 @@ export class TCP implements Transport {
32
55
  log('socket error', err)
33
56
  })
34
57
 
35
- const maConn = toMultiaddrConnection(socket, { remoteAddr: ma, signal: options.signal })
58
+ const maConn = toMultiaddrConnection(socket, {
59
+ remoteAddr: ma,
60
+ signal: options.signal,
61
+ socketInactivityTimeout: this.opts.outboundSocketInactivityTimeout,
62
+ socketCloseTimeout: this.opts.socketCloseTimeout
63
+ })
36
64
  log('new outbound connection %s', maConn.remoteAddr)
37
65
  const conn = await options.upgrader.upgradeOutbound(maConn)
38
66
  log('outbound connection %s upgraded', maConn.remoteAddr)
@@ -108,7 +136,11 @@ export class TCP implements Transport {
108
136
  * `upgrader.upgradeInbound`.
109
137
  */
110
138
  createListener (options: CreateListenerOptions) {
111
- return createListener(options)
139
+ return createListener({
140
+ ...options,
141
+ socketInactivityTimeout: this.opts.inboundSocketInactivityTimeout,
142
+ socketCloseTimeout: this.opts.socketCloseTimeout
143
+ })
112
144
  }
113
145
 
114
146
  /**
package/src/listener.ts CHANGED
@@ -32,6 +32,8 @@ async function attemptClose (maConn: MultiaddrConnection) {
32
32
  interface Context {
33
33
  handler?: (conn: Connection) => void
34
34
  upgrader: Upgrader
35
+ socketInactivityTimeout?: number
36
+ socketCloseTimeout?: number
35
37
  }
36
38
 
37
39
  /**
@@ -39,7 +41,7 @@ interface Context {
39
41
  */
40
42
  export function createListener (context: Context) {
41
43
  const {
42
- handler, upgrader
44
+ handler, upgrader, socketInactivityTimeout, socketCloseTimeout
43
45
  } = context
44
46
 
45
47
  let peerId: string | null
@@ -53,7 +55,11 @@ export function createListener (context: Context) {
53
55
 
54
56
  let maConn: MultiaddrConnection
55
57
  try {
56
- maConn = toMultiaddrConnection(socket, { listeningAddr })
58
+ maConn = toMultiaddrConnection(socket, {
59
+ listeningAddr,
60
+ socketInactivityTimeout,
61
+ socketCloseTimeout
62
+ })
57
63
  } catch (err) {
58
64
  log.error('inbound connection failed', err)
59
65
  return
@@ -139,9 +145,9 @@ export function createListener (context: Context) {
139
145
  return
140
146
  }
141
147
 
142
- await Promise.all([
148
+ await Promise.all(
143
149
  server.__connections.map(async maConn => await attemptClose(maConn))
144
- ])
150
+ )
145
151
 
146
152
  await new Promise<void>((resolve, reject) => {
147
153
  server.close(err => (err != null) ? reject(err) : resolve())
@@ -3,7 +3,8 @@ import { logger } from '@libp2p/logger'
3
3
  // @ts-expect-error no types
4
4
  import toIterable from 'stream-to-it'
5
5
  import { ipPortToMultiaddr as toMultiaddr } from '@libp2p/utils/ip-port-to-multiaddr'
6
- import { CLOSE_TIMEOUT } from './constants.js'
6
+ import { CLOSE_TIMEOUT, SOCKET_TIMEOUT } from './constants.js'
7
+ import errCode from 'err-code'
7
8
  import type { Socket } from 'net'
8
9
  import type { Multiaddr } from '@multiformats/multiaddr'
9
10
  import type { MultiaddrConnection } from '@libp2p/interface-connection'
@@ -15,6 +16,8 @@ interface ToConnectionOptions {
15
16
  remoteAddr?: Multiaddr
16
17
  localAddr?: Multiaddr
17
18
  signal?: AbortSignal
19
+ socketInactivityTimeout?: number
20
+ socketCloseTimeout?: number
18
21
  }
19
22
 
20
23
  /**
@@ -23,6 +26,8 @@ interface ToConnectionOptions {
23
26
  */
24
27
  export const toMultiaddrConnection = (socket: Socket, options?: ToConnectionOptions) => {
25
28
  options = options ?? {}
29
+ const inactivityTimeout = options.socketInactivityTimeout ?? SOCKET_TIMEOUT
30
+ const closeTimeout = options.socketCloseTimeout ?? CLOSE_TIMEOUT
26
31
 
27
32
  // Check if we are connected on a unix path
28
33
  if (options.listeningAddr?.getPath() != null) {
@@ -33,8 +38,43 @@ export const toMultiaddrConnection = (socket: Socket, options?: ToConnectionOpti
33
38
  options.localAddr = options.remoteAddr
34
39
  }
35
40
 
41
+ const remoteAddr = options.remoteAddr ?? toMultiaddr(socket.remoteAddress ?? '', socket.remotePort ?? '')
42
+ const { host, port } = remoteAddr.toOptions()
36
43
  const { sink, source } = toIterable.duplex(socket)
37
44
 
45
+ // by default there is no timeout
46
+ // https://nodejs.org/dist/latest-v16.x/docs/api/net.html#socketsettimeouttimeout-callback
47
+ socket.setTimeout(inactivityTimeout, () => {
48
+ log('%s:%s socket read timeout', host, port)
49
+
50
+ // only destroy with an error if the remote has not sent the FIN message
51
+ let err: Error | undefined
52
+ if (socket.readable) {
53
+ err = errCode(new Error('Socket read timeout'), 'ERR_SOCKET_READ_TIMEOUT')
54
+ }
55
+
56
+ // if the socket times out due to inactivity we must manually close the connection
57
+ // https://nodejs.org/dist/latest-v16.x/docs/api/net.html#event-timeout
58
+ socket.destroy(err)
59
+ })
60
+
61
+ socket.once('close', () => {
62
+ log('%s:%s socket closed', host, port)
63
+
64
+ // In instances where `close` was not explicitly called,
65
+ // such as an iterable stream ending, ensure we have set the close
66
+ // timeline
67
+ if (maConn.timeline.close == null) {
68
+ maConn.timeline.close = Date.now()
69
+ }
70
+ })
71
+
72
+ socket.once('end', () => {
73
+ // the remote sent a FIN packet which means no more data will be sent
74
+ // https://nodejs.org/dist/latest-v16.x/docs/api/net.html#event-end
75
+ log('socket ended', maConn.remoteAddr.toString())
76
+ })
77
+
38
78
  const maConn: MultiaddrConnection = {
39
79
  async sink (source) {
40
80
  if ((options?.signal) != null) {
@@ -42,13 +82,7 @@ export const toMultiaddrConnection = (socket: Socket, options?: ToConnectionOpti
42
82
  }
43
83
 
44
84
  try {
45
- await sink((async function * () {
46
- for await (const chunk of source) {
47
- // Convert BufferList to Buffer
48
- // Sink in StreamMuxer define argument as Uint8Array so chunk type infers as number which can't be sliced
49
- yield Buffer.isBuffer(chunk) ? chunk : chunk.slice()
50
- }
51
- })())
85
+ await sink(source)
52
86
  } catch (err: any) {
53
87
  // If aborted we can safely ignore
54
88
  if (err.type !== 'aborted') {
@@ -58,66 +92,84 @@ export const toMultiaddrConnection = (socket: Socket, options?: ToConnectionOpti
58
92
  log(err)
59
93
  }
60
94
  }
95
+
96
+ // we have finished writing, send the FIN message
97
+ socket.end()
61
98
  },
62
99
 
63
- // Missing Type for "abortable"
64
100
  source: (options.signal != null) ? abortableSource(source, options.signal) : source,
65
101
 
66
102
  // If the remote address was passed, use it - it may have the peer ID encapsulated
67
- remoteAddr: options.remoteAddr ?? toMultiaddr(socket.remoteAddress ?? '', socket.remotePort ?? ''),
103
+ remoteAddr,
68
104
 
69
105
  timeline: { open: Date.now() },
70
106
 
71
107
  async close () {
72
- if (socket.destroyed) return
108
+ if (socket.destroyed) {
109
+ log('%s:%s socket was already destroyed when trying to close', host, port)
110
+ return
111
+ }
73
112
 
74
- return await new Promise((resolve, reject) => {
113
+ log('%s:%s closing socket', host, port)
114
+ await new Promise<void>((resolve, reject) => {
75
115
  const start = Date.now()
76
116
 
77
117
  // Attempt to end the socket. If it takes longer to close than the
78
118
  // timeout, destroy it manually.
79
119
  const timeout = setTimeout(() => {
80
- const { host, port } = maConn.remoteAddr.toOptions()
81
- log(
82
- 'timeout closing socket to %s:%s after %dms, destroying it manually',
83
- host,
84
- port,
85
- Date.now() - start
86
- )
87
-
88
120
  if (socket.destroyed) {
89
121
  log('%s:%s is already destroyed', host, port)
122
+ resolve()
90
123
  } else {
91
- socket.destroy()
92
- }
124
+ log('%s:%s socket close timeout after %dms, destroying it manually', host, port, Date.now() - start)
93
125
 
94
- resolve()
95
- }, CLOSE_TIMEOUT).unref()
126
+ // will trigger 'error' and 'close' events that resolves promise
127
+ socket.destroy(errCode(new Error('Socket close timeout'), 'ERR_SOCKET_CLOSE_TIMEOUT'))
128
+ }
129
+ }, closeTimeout).unref()
96
130
 
97
131
  socket.once('close', () => {
132
+ log('%s:%s socket closed', host, port)
133
+ // socket completely closed
98
134
  clearTimeout(timeout)
99
135
  resolve()
100
136
  })
101
- socket.end((err?: Error & { code?: string }) => {
102
- clearTimeout(timeout)
103
- maConn.timeline.close = Date.now()
104
- if (err != null) {
105
- return reject(err)
137
+ socket.once('error', (err: Error) => {
138
+ log('%s:%s socket error', host, port, err)
139
+
140
+ // error closing socket
141
+ if (maConn.timeline.close == null) {
142
+ maConn.timeline.close = Date.now()
106
143
  }
107
- resolve()
144
+
145
+ if (socket.destroyed) {
146
+ clearTimeout(timeout)
147
+ }
148
+
149
+ reject(err)
108
150
  })
151
+
152
+ // shorten inactivity timeout
153
+ socket.setTimeout(closeTimeout)
154
+
155
+ // close writable end of the socket
156
+ socket.end()
157
+
158
+ if (socket.writableLength > 0) {
159
+ // there are outgoing bytes waiting to be sent
160
+ socket.once('drain', () => {
161
+ log('%s:%s socket drained', host, port)
162
+
163
+ // all bytes have been sent we can destroy the socket (maybe) before the timeout
164
+ socket.destroy()
165
+ })
166
+ } else {
167
+ // nothing to send, destroy immediately
168
+ socket.destroy()
169
+ }
109
170
  })
110
171
  }
111
172
  }
112
173
 
113
- socket.once('close', () => {
114
- // In instances where `close` was not explicitly called,
115
- // such as an iterable stream ending, ensure we have set the close
116
- // timeline
117
- if (maConn.timeline.close == null) {
118
- maConn.timeline.close = Date.now()
119
- }
120
- })
121
-
122
174
  return maConn
123
175
  }