@libp2p/tcp 3.0.4 → 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 +2 -1
- package/dist/src/constants.d.ts +1 -0
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +2 -0
- package/dist/src/constants.js.map +1 -1
- package/dist/src/index.d.ts +16 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +14 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/listener.d.ts +2 -0
- package/dist/src/listener.d.ts.map +1 -1
- package/dist/src/listener.js +7 -5
- package/dist/src/listener.js.map +1 -1
- package/dist/src/socket-to-conn.d.ts +2 -0
- package/dist/src/socket-to-conn.d.ts.map +1 -1
- package/dist/src/socket-to-conn.js +74 -31
- package/dist/src/socket-to-conn.js.map +1 -1
- package/package.json +2 -1
- package/src/constants.ts +3 -0
- package/src/index.ts +34 -2
- package/src/listener.ts +10 -4
- package/src/socket-to-conn.ts +91 -39
package/README.md
CHANGED
|
@@ -47,9 +47,10 @@ const upgrader = {
|
|
|
47
47
|
upgradeOutbound: maConn => maConn
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
const tcp = new TCP(
|
|
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(
|
package/dist/src/constants.d.ts
CHANGED
|
@@ -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"}
|
package/dist/src/constants.js
CHANGED
|
@@ -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"}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -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>;
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -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;
|
|
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, {
|
|
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(
|
|
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
|
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,OAAO,MAAM,UAAU,CAAA;AAC9B,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AACvC,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AACtD,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACvD,OAAO,EAAsC,MAAM,EAAa,MAAM,6BAA6B,CAAA;AAMnG,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/src/listener.d.ts
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/src/listener.js
CHANGED
|
@@ -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, {
|
|
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
|
});
|
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,EACrB,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AAMrE,MAAM,GAAG,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAA;AAMzC;;GAEG;AACH,KAAK,UAAU,YAAY,CAAE,MAA2B;IACtD,IAAI;QACF,MAAM,MAAM,CAAC,KAAK,EAAE,CAAA;KACrB;IAAC,OAAO,GAAG,EAAE;QACZ,GAAG,CAAC,KAAK,CAAC,0CAA0C,EAAE,GAAG,CAAC,CAAA;KAC3D;AACH,CAAC;
|
|
1
|
+
{"version":3,"file":"listener.js","sourceRoot":"","sources":["../../src/listener.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"socket-to-conn.d.ts","sourceRoot":"","sources":["../../src/socket-to-conn.ts"],"names":[],"mappings":"
|
|
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(
|
|
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
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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.
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (
|
|
77
|
-
|
|
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
|
-
|
|
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":"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,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"socket-to-conn.js","sourceRoot":"","sources":["../../src/socket-to-conn.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@libp2p/tcp",
|
|
3
|
-
"version": "3.0.
|
|
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",
|
|
@@ -153,6 +153,7 @@
|
|
|
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
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, {
|
|
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(
|
|
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, {
|
|
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())
|
package/src/socket-to-conn.ts
CHANGED
|
@@ -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(
|
|
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
|
|
103
|
+
remoteAddr,
|
|
68
104
|
|
|
69
105
|
timeline: { open: Date.now() },
|
|
70
106
|
|
|
71
107
|
async close () {
|
|
72
|
-
if (socket.destroyed)
|
|
108
|
+
if (socket.destroyed) {
|
|
109
|
+
log('%s:%s socket was already destroyed when trying to close', host, port)
|
|
110
|
+
return
|
|
111
|
+
}
|
|
73
112
|
|
|
74
|
-
|
|
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.
|
|
92
|
-
}
|
|
124
|
+
log('%s:%s socket close timeout after %dms, destroying it manually', host, port, Date.now() - start)
|
|
93
125
|
|
|
94
|
-
|
|
95
|
-
|
|
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.
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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
|
-
|
|
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
|
}
|