@libp2p/tcp 1.0.4 → 1.0.7
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 +16 -14
- package/dist/src/index.d.ts +8 -21
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +11 -11
- package/dist/src/index.js.map +1 -1
- package/dist/src/listener.d.ts +2 -17
- package/dist/src/listener.d.ts.map +1 -1
- package/dist/src/listener.js +101 -116
- package/dist/src/listener.js.map +1 -1
- package/package.json +9 -9
- package/src/index.ts +14 -33
- package/src/listener.ts +113 -133
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
[](https://github.com/libp2p/js-libp2p-interfaces/tree/master/src/transport)
|
|
13
13
|
[](https://github.com/libp2p/js-libp2p-interfaces/tree/master/src/connection)
|
|
14
14
|
|
|
15
|
-
> JavaScript implementation of the TCP module for libp2p. It exposes the [interface-transport](https://github.com/libp2p/js-libp2p-interfaces/tree/master/src/transport) for dial/listen. `libp2p-tcp` is a very thin shim that adds support for dialing to a `multiaddr`. This small shim will enable libp2p to use other transports.
|
|
15
|
+
> JavaScript implementation of the TCP module for libp2p. It exposes the [interface-transport](https://github.com/libp2p/js-libp2p-interfaces/tree/master/packages/libp2p-interfaces/src/transport) for dial/listen. `libp2p-tcp` is a very thin shim that adds support for dialing to a `multiaddr`. This small shim will enable libp2p to use other transports.
|
|
16
16
|
|
|
17
17
|
## Table of Contents <!-- omit in toc -->
|
|
18
18
|
|
|
@@ -39,9 +39,9 @@
|
|
|
39
39
|
|
|
40
40
|
```js
|
|
41
41
|
import { TCP } from '@libp2p/tcp'
|
|
42
|
-
import {
|
|
43
|
-
import pipe from 'it-pipe'
|
|
44
|
-
import
|
|
42
|
+
import { multiaddr } from '@multiformats/multiaddr'
|
|
43
|
+
import {pipe} from 'it-pipe'
|
|
44
|
+
import all from 'it-all'
|
|
45
45
|
|
|
46
46
|
// A simple upgrader that just returns the MultiaddrConnection
|
|
47
47
|
const upgrader = {
|
|
@@ -51,12 +51,14 @@ const upgrader = {
|
|
|
51
51
|
|
|
52
52
|
const tcp = new TCP({ upgrader })
|
|
53
53
|
|
|
54
|
-
const listener = tcp.createListener({
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
54
|
+
const listener = tcp.createListener({
|
|
55
|
+
handler: (socket) => {
|
|
56
|
+
console.log('new connection opened')
|
|
57
|
+
pipe(
|
|
58
|
+
['hello', ' ', 'World!'],
|
|
59
|
+
socket
|
|
60
|
+
)
|
|
61
|
+
}
|
|
60
62
|
})
|
|
61
63
|
|
|
62
64
|
const addr = multiaddr('/ip4/127.0.0.1/tcp/9090')
|
|
@@ -66,7 +68,7 @@ console.log('listening')
|
|
|
66
68
|
const socket = await tcp.dial(addr)
|
|
67
69
|
const values = await pipe(
|
|
68
70
|
socket,
|
|
69
|
-
|
|
71
|
+
all
|
|
70
72
|
)
|
|
71
73
|
console.log(`Value: ${values.toString()}`)
|
|
72
74
|
|
|
@@ -79,14 +81,14 @@ Outputs:
|
|
|
79
81
|
```sh
|
|
80
82
|
listening
|
|
81
83
|
new connection opened
|
|
82
|
-
Value: hello
|
|
84
|
+
Value: hello World!
|
|
83
85
|
```
|
|
84
86
|
|
|
85
87
|
## API
|
|
86
88
|
|
|
87
89
|
### Transport
|
|
88
90
|
|
|
89
|
-
[](https://github.com/libp2p/js-libp2p-interfaces/tree/master/src/transport)
|
|
91
|
+
[](https://github.com/libp2p/js-libp2p-interfaces/tree/master/packages/libp2p-interfaces/src/transport)
|
|
90
92
|
|
|
91
93
|
`libp2p-tcp` accepts TCP addresses as both IPFS and non IPFS encapsulated addresses, i.e:
|
|
92
94
|
|
|
@@ -97,7 +99,7 @@ Value: hello
|
|
|
97
99
|
|
|
98
100
|
### Connection
|
|
99
101
|
|
|
100
|
-
[](https://github.com/libp2p/js-libp2p-interfaces/tree/master/src/connection)
|
|
102
|
+
[](https://github.com/libp2p/js-libp2p-interfaces/tree/master/packages/libp2p-interfaces/src/connection)
|
|
101
103
|
|
|
102
104
|
## Contribute
|
|
103
105
|
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,35 +1,22 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import net from 'net';
|
|
3
|
-
import
|
|
3
|
+
import { CreateListenerOptions, DialOptions, symbol, Transport } from '@libp2p/interfaces/transport';
|
|
4
4
|
import type { Multiaddr } from '@multiformats/multiaddr';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
*/
|
|
12
|
-
interface TCPOptions {
|
|
13
|
-
upgrader: Upgrader;
|
|
14
|
-
}
|
|
15
|
-
interface DialOptions {
|
|
16
|
-
signal?: AbortSignal;
|
|
17
|
-
}
|
|
18
|
-
export declare class TCP implements Transport<DialOptions, ListenerOptions> {
|
|
19
|
-
private readonly _upgrader;
|
|
20
|
-
constructor(options: TCPOptions);
|
|
21
|
-
dial(ma: Multiaddr, options?: DialOptions): Promise<import("@libp2p/interfaces/dist/src/connection").Connection>;
|
|
22
|
-
_connect(ma: Multiaddr, options?: DialOptions): Promise<net.Socket>;
|
|
5
|
+
import type { AbortOptions } from '@libp2p/interfaces';
|
|
6
|
+
export declare class TCP implements Transport {
|
|
7
|
+
get [symbol](): true;
|
|
8
|
+
get [Symbol.toStringTag](): string;
|
|
9
|
+
dial(ma: Multiaddr, options: DialOptions): Promise<import("@libp2p/interfaces/dist/src/connection").Connection>;
|
|
10
|
+
_connect(ma: Multiaddr, options?: AbortOptions): Promise<net.Socket>;
|
|
23
11
|
/**
|
|
24
12
|
* Creates a TCP listener. The provided `handler` function will be called
|
|
25
13
|
* anytime a new incoming Connection has been successfully upgraded via
|
|
26
14
|
* `upgrader.upgradeInbound`.
|
|
27
15
|
*/
|
|
28
|
-
createListener(options
|
|
16
|
+
createListener(options: CreateListenerOptions): import("@libp2p/interfaces/transport").Listener;
|
|
29
17
|
/**
|
|
30
18
|
* Takes a list of `Multiaddr`s and returns only valid TCP addresses
|
|
31
19
|
*/
|
|
32
20
|
filter(multiaddrs: Multiaddr[]): Multiaddr[];
|
|
33
21
|
}
|
|
34
|
-
export {};
|
|
35
22
|
//# sourceMappingURL=index.d.ts.map
|
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,
|
|
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,8BAA8B,CAAA;AACpG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAExD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAItD,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;IAezC,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"}
|
package/dist/src/index.js
CHANGED
|
@@ -5,18 +5,18 @@ import { logger } from '@libp2p/logger';
|
|
|
5
5
|
import { toMultiaddrConnection } from './socket-to-conn.js';
|
|
6
6
|
import { createListener } from './listener.js';
|
|
7
7
|
import { multiaddrToNetConfig } from './utils.js';
|
|
8
|
-
import { AbortError } from '
|
|
8
|
+
import { AbortError } from '@libp2p/interfaces/errors';
|
|
9
9
|
import { CODE_CIRCUIT, CODE_P2P } from './constants.js';
|
|
10
|
+
import { symbol } from '@libp2p/interfaces/transport';
|
|
10
11
|
const log = logger('libp2p:tcp');
|
|
11
12
|
export class TCP {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
this._upgrader = upgrader;
|
|
13
|
+
get [symbol]() {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
get [Symbol.toStringTag]() {
|
|
17
|
+
return this.constructor.name;
|
|
18
18
|
}
|
|
19
|
-
async dial(ma, options
|
|
19
|
+
async dial(ma, options) {
|
|
20
20
|
const socket = await this._connect(ma, options);
|
|
21
21
|
// Avoid uncaught errors caused by unstable connections
|
|
22
22
|
socket.on('error', err => {
|
|
@@ -24,7 +24,7 @@ export class TCP {
|
|
|
24
24
|
});
|
|
25
25
|
const maConn = toMultiaddrConnection(socket, { remoteAddr: ma, signal: options.signal });
|
|
26
26
|
log('new outbound connection %s', maConn.remoteAddr);
|
|
27
|
-
const conn = await
|
|
27
|
+
const conn = await options.upgrader.upgradeOutbound(maConn);
|
|
28
28
|
log('outbound connection %s upgraded', maConn.remoteAddr);
|
|
29
29
|
return conn;
|
|
30
30
|
}
|
|
@@ -81,8 +81,8 @@ export class TCP {
|
|
|
81
81
|
* anytime a new incoming Connection has been successfully upgraded via
|
|
82
82
|
* `upgrader.upgradeInbound`.
|
|
83
83
|
*/
|
|
84
|
-
createListener(options
|
|
85
|
-
return createListener(
|
|
84
|
+
createListener(options) {
|
|
85
|
+
return createListener(options);
|
|
86
86
|
}
|
|
87
87
|
/**
|
|
88
88
|
* 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,
|
|
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,27 +1,12 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import net from 'net';
|
|
3
|
-
import { EventEmitter } from '@libp2p/interfaces';
|
|
4
1
|
import type { Connection } from '@libp2p/interfaces/connection';
|
|
5
|
-
import type {
|
|
6
|
-
import type { Multiaddr } from '@multiformats/multiaddr';
|
|
2
|
+
import type { Upgrader, Listener } from '@libp2p/interfaces/transport';
|
|
7
3
|
interface Context {
|
|
8
4
|
handler?: (conn: Connection) => void;
|
|
9
5
|
upgrader: Upgrader;
|
|
10
6
|
}
|
|
11
|
-
declare class TCPListener extends EventEmitter<ListenerEvents> implements Listener {
|
|
12
|
-
private peerId?;
|
|
13
|
-
private listeningAddr?;
|
|
14
|
-
private readonly server;
|
|
15
|
-
private connections;
|
|
16
|
-
constructor(upgrader: Upgrader, handler?: ConnectionHandler);
|
|
17
|
-
getAddrs(): Multiaddr[];
|
|
18
|
-
listen(ma: Multiaddr): Promise<void>;
|
|
19
|
-
close(): Promise<void>;
|
|
20
|
-
trackConn(maConn: MultiaddrConnection, socket: net.Socket): void;
|
|
21
|
-
}
|
|
22
7
|
/**
|
|
23
8
|
* Create listener
|
|
24
9
|
*/
|
|
25
|
-
export declare function createListener(context: Context):
|
|
10
|
+
export declare function createListener(context: Context): Listener;
|
|
26
11
|
export {};
|
|
27
12
|
//# sourceMappingURL=listener.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"listener.d.ts","sourceRoot":"","sources":["../../src/listener.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"listener.d.ts","sourceRoot":"","sources":["../../src/listener.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAA;AAC/D,OAAO,KAAK,EAAuB,QAAQ,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAA;AAqB3F,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"}
|
package/dist/src/listener.js
CHANGED
|
@@ -16,130 +16,115 @@ async function attemptClose(maConn) {
|
|
|
16
16
|
log.error('an error occurred closing the connection', err);
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Create listener
|
|
21
|
+
*/
|
|
22
|
+
export function createListener(context) {
|
|
23
|
+
const { handler, upgrader } = context;
|
|
24
|
+
let peerId;
|
|
25
|
+
let listeningAddr;
|
|
26
|
+
const server = Object.assign(net.createServer(socket => {
|
|
27
|
+
// Avoid uncaught errors caused by unstable connections
|
|
28
|
+
socket.on('error', err => {
|
|
29
|
+
log('socket error', err);
|
|
30
|
+
});
|
|
31
|
+
let maConn;
|
|
32
|
+
try {
|
|
33
|
+
maConn = toMultiaddrConnection(socket, { listeningAddr });
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
log.error('inbound connection failed', err);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
log('new inbound connection %s', maConn.remoteAddr);
|
|
40
|
+
try {
|
|
41
|
+
upgrader.upgradeInbound(maConn)
|
|
42
|
+
.then((conn) => {
|
|
43
|
+
log('inbound connection %s upgraded', maConn.remoteAddr);
|
|
44
|
+
trackConn(server, maConn, socket);
|
|
45
|
+
if (handler != null) {
|
|
46
|
+
handler(conn);
|
|
47
|
+
}
|
|
48
|
+
listener.dispatchEvent(new CustomEvent('connection', { detail: conn }));
|
|
49
|
+
})
|
|
50
|
+
.catch(async (err) => {
|
|
51
|
+
log.error('inbound connection failed', err);
|
|
52
|
+
await attemptClose(maConn);
|
|
53
|
+
})
|
|
54
|
+
.catch(err => {
|
|
55
|
+
log.error('closing inbound connection failed', err);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
log.error('inbound connection failed', err);
|
|
60
|
+
attemptClose(maConn)
|
|
61
|
+
.catch(err => {
|
|
62
|
+
log.error('closing inbound connection failed', err);
|
|
27
63
|
});
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
64
|
+
}
|
|
65
|
+
}),
|
|
66
|
+
// Keep track of open connections to destroy in case of timeout
|
|
67
|
+
{ __connections: [] });
|
|
68
|
+
const listener = Object.assign(new EventEmitter(), {
|
|
69
|
+
getAddrs: () => {
|
|
70
|
+
let addrs = [];
|
|
71
|
+
const address = server.address();
|
|
72
|
+
if (address == null) {
|
|
73
|
+
return [];
|
|
31
74
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
return;
|
|
75
|
+
if (typeof address === 'string') {
|
|
76
|
+
throw new Error('Incorrect server address type');
|
|
35
77
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
log('inbound connection %s upgraded', maConn.remoteAddr);
|
|
41
|
-
this.trackConn(maConn, socket);
|
|
42
|
-
if (handler != null) {
|
|
43
|
-
handler(conn);
|
|
44
|
-
}
|
|
45
|
-
this.dispatchEvent(new CustomEvent('connection', {
|
|
46
|
-
detail: conn
|
|
47
|
-
}));
|
|
48
|
-
})
|
|
49
|
-
.catch(async (err) => {
|
|
50
|
-
log.error('inbound connection failed', err);
|
|
51
|
-
await attemptClose(maConn);
|
|
52
|
-
})
|
|
53
|
-
.catch(err => {
|
|
54
|
-
log.error('closing inbound connection failed', err);
|
|
55
|
-
});
|
|
78
|
+
// Because TCP will only return the IPv6 version
|
|
79
|
+
// we need to capture from the passed multiaddr
|
|
80
|
+
if (listeningAddr.toString().startsWith('/ip4')) {
|
|
81
|
+
addrs = addrs.concat(getMultiaddrs('ip4', address.address, address.port));
|
|
56
82
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
83
|
+
else if (address.family === 'IPv6') {
|
|
84
|
+
addrs = addrs.concat(getMultiaddrs('ip6', address.address, address.port));
|
|
85
|
+
}
|
|
86
|
+
return addrs.map(ma => peerId != null ? ma.encapsulate(`/p2p/${peerId}`) : ma);
|
|
87
|
+
},
|
|
88
|
+
listen: async (ma) => {
|
|
89
|
+
listeningAddr = ma;
|
|
90
|
+
peerId = ma.getPeerId();
|
|
91
|
+
if (peerId == null) {
|
|
92
|
+
listeningAddr = ma.decapsulateCode(CODE_P2P);
|
|
93
|
+
}
|
|
94
|
+
return await new Promise((resolve, reject) => {
|
|
95
|
+
const options = multiaddrToNetConfig(listeningAddr);
|
|
96
|
+
server.listen(options, (err) => {
|
|
97
|
+
if (err != null) {
|
|
98
|
+
return reject(err);
|
|
99
|
+
}
|
|
100
|
+
log('Listening on %s', server.address());
|
|
101
|
+
resolve();
|
|
62
102
|
});
|
|
103
|
+
});
|
|
104
|
+
},
|
|
105
|
+
close: async () => {
|
|
106
|
+
if (!server.listening) {
|
|
107
|
+
return;
|
|
63
108
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
});
|
|
70
|
-
this.server.on('close', () => {
|
|
71
|
-
this.dispatchEvent(new CustomEvent('close'));
|
|
72
|
-
});
|
|
73
|
-
this.server.on('listening', () => {
|
|
74
|
-
this.dispatchEvent(new CustomEvent('listening'));
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
getAddrs() {
|
|
78
|
-
let addrs = [];
|
|
79
|
-
const address = this.server.address();
|
|
80
|
-
if (address == null) {
|
|
81
|
-
throw new Error('Listener is not ready yet');
|
|
82
|
-
}
|
|
83
|
-
if (typeof address === 'string') {
|
|
84
|
-
throw new Error('Incorrect server address type');
|
|
85
|
-
}
|
|
86
|
-
if (this.listeningAddr == null) {
|
|
87
|
-
throw new Error('Listener is not ready yet');
|
|
88
|
-
}
|
|
89
|
-
// Because TCP will only return the IPv6 version
|
|
90
|
-
// we need to capture from the passed multiaddr
|
|
91
|
-
if (this.listeningAddr.toString().startsWith('/ip4')) {
|
|
92
|
-
addrs = addrs.concat(getMultiaddrs('ip4', address.address, address.port));
|
|
93
|
-
}
|
|
94
|
-
else if (address.family === 'IPv6') {
|
|
95
|
-
addrs = addrs.concat(getMultiaddrs('ip6', address.address, address.port));
|
|
96
|
-
}
|
|
97
|
-
return addrs.map(ma => this.peerId != null ? ma.encapsulate(`/p2p/${this.peerId}`) : ma);
|
|
98
|
-
}
|
|
99
|
-
async listen(ma) {
|
|
100
|
-
const peerId = ma.getPeerId();
|
|
101
|
-
if (peerId == null) {
|
|
102
|
-
ma = ma.decapsulateCode(CODE_P2P);
|
|
103
|
-
}
|
|
104
|
-
else {
|
|
105
|
-
this.peerId = peerId;
|
|
106
|
-
}
|
|
107
|
-
this.listeningAddr = ma;
|
|
108
|
-
return await new Promise((resolve, reject) => {
|
|
109
|
-
const options = multiaddrToNetConfig(ma);
|
|
110
|
-
this.server.listen(options, (err) => {
|
|
111
|
-
if (err != null) {
|
|
112
|
-
return reject(err);
|
|
113
|
-
}
|
|
114
|
-
log('Listening on %s', this.server.address());
|
|
115
|
-
resolve();
|
|
109
|
+
await Promise.all([
|
|
110
|
+
server.__connections.map(async (maConn) => await attemptClose(maConn))
|
|
111
|
+
]);
|
|
112
|
+
await new Promise((resolve, reject) => {
|
|
113
|
+
server.close(err => (err != null) ? reject(err) : resolve());
|
|
116
114
|
});
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
async close() {
|
|
120
|
-
if (!this.server.listening) {
|
|
121
|
-
return;
|
|
122
115
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
130
|
-
trackConn(maConn, socket) {
|
|
131
|
-
this.connections.push(maConn);
|
|
132
|
-
const untrackConn = () => {
|
|
133
|
-
this.connections = this.connections.filter(c => c !== maConn);
|
|
134
|
-
};
|
|
135
|
-
socket.once('close', untrackConn);
|
|
136
|
-
}
|
|
116
|
+
});
|
|
117
|
+
server
|
|
118
|
+
.on('listening', () => listener.dispatchEvent(new CustomEvent('listening')))
|
|
119
|
+
.on('error', err => listener.dispatchEvent(new CustomEvent('error', { detail: err })))
|
|
120
|
+
.on('close', () => listener.dispatchEvent(new CustomEvent('close')));
|
|
121
|
+
return listener;
|
|
137
122
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
123
|
+
function trackConn(server, maConn, socket) {
|
|
124
|
+
server.__connections.push(maConn);
|
|
125
|
+
const untrackConn = () => {
|
|
126
|
+
server.__connections = server.__connections.filter(c => c !== maConn);
|
|
127
|
+
};
|
|
128
|
+
socket.once('close', untrackConn);
|
|
144
129
|
}
|
|
145
130
|
//# sourceMappingURL=listener.js.map
|
package/dist/src/listener.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"listener.js","sourceRoot":"","sources":["../../src/listener.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,KAAK,CAAA;AACrB,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AACvC,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EACL,aAAa,EACb,oBAAoB,EACrB,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAM9D,MAAM,GAAG,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAA;
|
|
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": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
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",
|
|
@@ -135,21 +135,21 @@
|
|
|
135
135
|
"release": "semantic-release"
|
|
136
136
|
},
|
|
137
137
|
"dependencies": {
|
|
138
|
-
"@libp2p/logger": "^1.
|
|
139
|
-
"@libp2p/utils": "^1.0.
|
|
140
|
-
"@multiformats/mafmt": "^11.0.
|
|
141
|
-
"@multiformats/multiaddr": "^10.1.
|
|
138
|
+
"@libp2p/logger": "^1.1.2",
|
|
139
|
+
"@libp2p/utils": "^1.0.9",
|
|
140
|
+
"@multiformats/mafmt": "^11.0.2",
|
|
141
|
+
"@multiformats/multiaddr": "^10.1.5",
|
|
142
142
|
"abortable-iterator": "^4.0.2",
|
|
143
143
|
"err-code": "^3.0.1",
|
|
144
144
|
"stream-to-it": "^0.2.2"
|
|
145
145
|
},
|
|
146
146
|
"devDependencies": {
|
|
147
|
-
"@libp2p/interface-compliance-tests": "^1.1.
|
|
148
|
-
"@libp2p/interfaces": "^1.3.
|
|
147
|
+
"@libp2p/interface-compliance-tests": "^1.1.17",
|
|
148
|
+
"@libp2p/interfaces": "^1.3.14",
|
|
149
149
|
"aegir": "^36.1.3",
|
|
150
|
+
"it-all": "^1.0.6",
|
|
150
151
|
"it-pipe": "^2.0.3",
|
|
151
|
-
"sinon": "^13.0.
|
|
152
|
-
"streaming-iterables": "^6.0.0",
|
|
152
|
+
"sinon": "^13.0.1",
|
|
153
153
|
"uint8arrays": "^3.0.0"
|
|
154
154
|
}
|
|
155
155
|
}
|
package/src/index.ts
CHANGED
|
@@ -5,44 +5,25 @@ import { logger } from '@libp2p/logger'
|
|
|
5
5
|
import { toMultiaddrConnection } from './socket-to-conn.js'
|
|
6
6
|
import { createListener } from './listener.js'
|
|
7
7
|
import { multiaddrToNetConfig } from './utils.js'
|
|
8
|
-
import { AbortError } from '
|
|
8
|
+
import { AbortError } from '@libp2p/interfaces/errors'
|
|
9
9
|
import { CODE_CIRCUIT, CODE_P2P } from './constants.js'
|
|
10
|
-
import
|
|
10
|
+
import { CreateListenerOptions, DialOptions, symbol, Transport } from '@libp2p/interfaces/transport'
|
|
11
11
|
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
12
12
|
import type { Socket } from 'net'
|
|
13
|
+
import type { AbortOptions } from '@libp2p/interfaces'
|
|
13
14
|
|
|
14
15
|
const log = logger('libp2p:tcp')
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
* @typedef {import('libp2p-interfaces/src/transport/types').Listener} Listener
|
|
21
|
-
* @typedef {import('net').Socket} Socket
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
interface TCPOptions {
|
|
25
|
-
upgrader: Upgrader
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
interface DialOptions {
|
|
29
|
-
signal?: AbortSignal
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export class TCP implements Transport<DialOptions, ListenerOptions> {
|
|
33
|
-
private readonly _upgrader: Upgrader
|
|
34
|
-
|
|
35
|
-
constructor (options: TCPOptions) {
|
|
36
|
-
const { upgrader } = options
|
|
37
|
-
|
|
38
|
-
if (upgrader == null) {
|
|
39
|
-
throw new Error('An upgrader must be provided. See https://github.com/libp2p/interface-transport#upgrader.')
|
|
40
|
-
}
|
|
17
|
+
export class TCP implements Transport {
|
|
18
|
+
get [symbol] (): true {
|
|
19
|
+
return true
|
|
20
|
+
}
|
|
41
21
|
|
|
42
|
-
|
|
22
|
+
get [Symbol.toStringTag] () {
|
|
23
|
+
return this.constructor.name
|
|
43
24
|
}
|
|
44
25
|
|
|
45
|
-
async dial (ma: Multiaddr, options: DialOptions
|
|
26
|
+
async dial (ma: Multiaddr, options: DialOptions) {
|
|
46
27
|
const socket = await this._connect(ma, options)
|
|
47
28
|
|
|
48
29
|
// Avoid uncaught errors caused by unstable connections
|
|
@@ -52,12 +33,12 @@ export class TCP implements Transport<DialOptions, ListenerOptions> {
|
|
|
52
33
|
|
|
53
34
|
const maConn = toMultiaddrConnection(socket, { remoteAddr: ma, signal: options.signal })
|
|
54
35
|
log('new outbound connection %s', maConn.remoteAddr)
|
|
55
|
-
const conn = await
|
|
36
|
+
const conn = await options.upgrader.upgradeOutbound(maConn)
|
|
56
37
|
log('outbound connection %s upgraded', maConn.remoteAddr)
|
|
57
38
|
return conn
|
|
58
39
|
}
|
|
59
40
|
|
|
60
|
-
async _connect (ma: Multiaddr, options:
|
|
41
|
+
async _connect (ma: Multiaddr, options: AbortOptions = {}) {
|
|
61
42
|
if (options.signal?.aborted === true) {
|
|
62
43
|
throw new AbortError()
|
|
63
44
|
}
|
|
@@ -125,8 +106,8 @@ export class TCP implements Transport<DialOptions, ListenerOptions> {
|
|
|
125
106
|
* anytime a new incoming Connection has been successfully upgraded via
|
|
126
107
|
* `upgrader.upgradeInbound`.
|
|
127
108
|
*/
|
|
128
|
-
createListener (options:
|
|
129
|
-
return createListener(
|
|
109
|
+
createListener (options: CreateListenerOptions) {
|
|
110
|
+
return createListener(options)
|
|
130
111
|
}
|
|
131
112
|
|
|
132
113
|
/**
|
package/src/listener.ts
CHANGED
|
@@ -8,12 +8,16 @@ import {
|
|
|
8
8
|
} from './utils.js'
|
|
9
9
|
import { EventEmitter, CustomEvent } from '@libp2p/interfaces'
|
|
10
10
|
import type { Connection } from '@libp2p/interfaces/connection'
|
|
11
|
-
import type { MultiaddrConnection, Upgrader, Listener
|
|
11
|
+
import type { MultiaddrConnection, Upgrader, Listener } from '@libp2p/interfaces/transport'
|
|
12
12
|
import type { Server } from 'net'
|
|
13
13
|
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
14
14
|
|
|
15
15
|
const log = logger('libp2p:tcp:listener')
|
|
16
16
|
|
|
17
|
+
interface ServerWithMultiaddrConnections extends Server {
|
|
18
|
+
__connections: MultiaddrConnection[]
|
|
19
|
+
}
|
|
20
|
+
|
|
17
21
|
/**
|
|
18
22
|
* Attempts to close the given maConn. If a failure occurs, it will be logged
|
|
19
23
|
*/
|
|
@@ -30,159 +34,135 @@ interface Context {
|
|
|
30
34
|
upgrader: Upgrader
|
|
31
35
|
}
|
|
32
36
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
super()
|
|
41
|
-
|
|
42
|
-
this.connections = []
|
|
43
|
-
|
|
44
|
-
this.server = net.createServer(socket => {
|
|
45
|
-
// Avoid uncaught errors caused by unstable connections
|
|
46
|
-
socket.on('error', err => {
|
|
47
|
-
log('socket error', err)
|
|
48
|
-
})
|
|
37
|
+
/**
|
|
38
|
+
* Create listener
|
|
39
|
+
*/
|
|
40
|
+
export function createListener (context: Context) {
|
|
41
|
+
const {
|
|
42
|
+
handler, upgrader
|
|
43
|
+
} = context
|
|
49
44
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
maConn = toMultiaddrConnection(socket, { listeningAddr: this.listeningAddr })
|
|
53
|
-
} catch (err) {
|
|
54
|
-
log.error('inbound connection failed', err)
|
|
55
|
-
return
|
|
56
|
-
}
|
|
45
|
+
let peerId: string | null
|
|
46
|
+
let listeningAddr: Multiaddr
|
|
57
47
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
log('inbound connection %s upgraded', maConn.remoteAddr)
|
|
63
|
-
|
|
64
|
-
this.trackConn(maConn, socket)
|
|
65
|
-
|
|
66
|
-
if (handler != null) {
|
|
67
|
-
handler(conn)
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
this.dispatchEvent(new CustomEvent('connection', {
|
|
71
|
-
detail: conn
|
|
72
|
-
}))
|
|
73
|
-
})
|
|
74
|
-
.catch(async err => {
|
|
75
|
-
log.error('inbound connection failed', err)
|
|
76
|
-
|
|
77
|
-
await attemptClose(maConn)
|
|
78
|
-
})
|
|
79
|
-
.catch(err => {
|
|
80
|
-
log.error('closing inbound connection failed', err)
|
|
81
|
-
})
|
|
82
|
-
} catch (err) {
|
|
83
|
-
log.error('inbound connection failed', err)
|
|
84
|
-
|
|
85
|
-
attemptClose(maConn)
|
|
86
|
-
.catch(err => {
|
|
87
|
-
log.error('closing inbound connection failed', err)
|
|
88
|
-
})
|
|
89
|
-
}
|
|
90
|
-
})
|
|
91
|
-
this.server.on('error', err => {
|
|
92
|
-
this.dispatchEvent(new CustomEvent('error', {
|
|
93
|
-
detail: err
|
|
94
|
-
}))
|
|
48
|
+
const server: ServerWithMultiaddrConnections = Object.assign(net.createServer(socket => {
|
|
49
|
+
// Avoid uncaught errors caused by unstable connections
|
|
50
|
+
socket.on('error', err => {
|
|
51
|
+
log('socket error', err)
|
|
95
52
|
})
|
|
96
|
-
this.server.on('close', () => {
|
|
97
|
-
this.dispatchEvent(new CustomEvent('close'))
|
|
98
|
-
})
|
|
99
|
-
this.server.on('listening', () => {
|
|
100
|
-
this.dispatchEvent(new CustomEvent('listening'))
|
|
101
|
-
})
|
|
102
|
-
}
|
|
103
53
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
54
|
+
let maConn: MultiaddrConnection
|
|
55
|
+
try {
|
|
56
|
+
maConn = toMultiaddrConnection(socket, { listeningAddr })
|
|
57
|
+
} catch (err) {
|
|
58
|
+
log.error('inbound connection failed', err)
|
|
59
|
+
return
|
|
110
60
|
}
|
|
111
61
|
|
|
112
|
-
|
|
113
|
-
|
|
62
|
+
log('new inbound connection %s', maConn.remoteAddr)
|
|
63
|
+
try {
|
|
64
|
+
upgrader.upgradeInbound(maConn)
|
|
65
|
+
.then((conn) => {
|
|
66
|
+
log('inbound connection %s upgraded', maConn.remoteAddr)
|
|
67
|
+
trackConn(server, maConn, socket)
|
|
68
|
+
|
|
69
|
+
if (handler != null) {
|
|
70
|
+
handler(conn)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
listener.dispatchEvent(new CustomEvent<Connection>('connection', { detail: conn }))
|
|
74
|
+
})
|
|
75
|
+
.catch(async err => {
|
|
76
|
+
log.error('inbound connection failed', err)
|
|
77
|
+
|
|
78
|
+
await attemptClose(maConn)
|
|
79
|
+
})
|
|
80
|
+
.catch(err => {
|
|
81
|
+
log.error('closing inbound connection failed', err)
|
|
82
|
+
})
|
|
83
|
+
} catch (err) {
|
|
84
|
+
log.error('inbound connection failed', err)
|
|
85
|
+
|
|
86
|
+
attemptClose(maConn)
|
|
87
|
+
.catch(err => {
|
|
88
|
+
log.error('closing inbound connection failed', err)
|
|
89
|
+
})
|
|
114
90
|
}
|
|
91
|
+
}),
|
|
92
|
+
// Keep track of open connections to destroy in case of timeout
|
|
93
|
+
{ __connections: [] })
|
|
115
94
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
95
|
+
const listener: Listener = Object.assign(new EventEmitter(), {
|
|
96
|
+
getAddrs: () => {
|
|
97
|
+
let addrs: Multiaddr[] = []
|
|
98
|
+
const address = server.address()
|
|
119
99
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
addrs = addrs.concat(getMultiaddrs('ip4', address.address, address.port))
|
|
124
|
-
} else if (address.family === 'IPv6') {
|
|
125
|
-
addrs = addrs.concat(getMultiaddrs('ip6', address.address, address.port))
|
|
126
|
-
}
|
|
100
|
+
if (address == null) {
|
|
101
|
+
return []
|
|
102
|
+
}
|
|
127
103
|
|
|
128
|
-
|
|
129
|
-
|
|
104
|
+
if (typeof address === 'string') {
|
|
105
|
+
throw new Error('Incorrect server address type')
|
|
106
|
+
}
|
|
130
107
|
|
|
131
|
-
|
|
132
|
-
|
|
108
|
+
// Because TCP will only return the IPv6 version
|
|
109
|
+
// we need to capture from the passed multiaddr
|
|
110
|
+
if (listeningAddr.toString().startsWith('/ip4')) {
|
|
111
|
+
addrs = addrs.concat(getMultiaddrs('ip4', address.address, address.port))
|
|
112
|
+
} else if (address.family === 'IPv6') {
|
|
113
|
+
addrs = addrs.concat(getMultiaddrs('ip6', address.address, address.port))
|
|
114
|
+
}
|
|
133
115
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
116
|
+
return addrs.map(ma => peerId != null ? ma.encapsulate(`/p2p/${peerId}`) : ma)
|
|
117
|
+
},
|
|
118
|
+
listen: async (ma: Multiaddr) => {
|
|
119
|
+
listeningAddr = ma
|
|
120
|
+
peerId = ma.getPeerId()
|
|
139
121
|
|
|
140
|
-
|
|
122
|
+
if (peerId == null) {
|
|
123
|
+
listeningAddr = ma.decapsulateCode(CODE_P2P)
|
|
124
|
+
}
|
|
141
125
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
126
|
+
return await new Promise<void>((resolve, reject) => {
|
|
127
|
+
const options = multiaddrToNetConfig(listeningAddr)
|
|
128
|
+
server.listen(options, (err?: any) => {
|
|
129
|
+
if (err != null) {
|
|
130
|
+
return reject(err)
|
|
131
|
+
}
|
|
132
|
+
log('Listening on %s', server.address())
|
|
133
|
+
resolve()
|
|
134
|
+
})
|
|
150
135
|
})
|
|
151
|
-
}
|
|
152
|
-
|
|
136
|
+
},
|
|
137
|
+
close: async () => {
|
|
138
|
+
if (!server.listening) {
|
|
139
|
+
return
|
|
140
|
+
}
|
|
153
141
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
142
|
+
await Promise.all([
|
|
143
|
+
server.__connections.map(async maConn => await attemptClose(maConn))
|
|
144
|
+
])
|
|
145
|
+
|
|
146
|
+
await new Promise<void>((resolve, reject) => {
|
|
147
|
+
server.close(err => (err != null) ? reject(err) : resolve())
|
|
148
|
+
})
|
|
157
149
|
}
|
|
150
|
+
})
|
|
158
151
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
152
|
+
server
|
|
153
|
+
.on('listening', () => listener.dispatchEvent(new CustomEvent('listening')))
|
|
154
|
+
.on('error', err => listener.dispatchEvent(new CustomEvent<Error>('error', { detail: err })))
|
|
155
|
+
.on('close', () => listener.dispatchEvent(new CustomEvent('close')))
|
|
162
156
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
})
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
trackConn (maConn: MultiaddrConnection, socket: net.Socket) {
|
|
169
|
-
this.connections.push(maConn)
|
|
157
|
+
return listener
|
|
158
|
+
}
|
|
170
159
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
}
|
|
160
|
+
function trackConn (server: ServerWithMultiaddrConnections, maConn: MultiaddrConnection, socket: net.Socket) {
|
|
161
|
+
server.__connections.push(maConn)
|
|
174
162
|
|
|
175
|
-
|
|
163
|
+
const untrackConn = () => {
|
|
164
|
+
server.__connections = server.__connections.filter(c => c !== maConn)
|
|
176
165
|
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Create listener
|
|
181
|
-
*/
|
|
182
|
-
export function createListener (context: Context) {
|
|
183
|
-
const {
|
|
184
|
-
handler, upgrader
|
|
185
|
-
} = context
|
|
186
166
|
|
|
187
|
-
|
|
167
|
+
socket.once('close', untrackConn)
|
|
188
168
|
}
|