From 1adf73db4e88e0c196766588a2972a3a6e28e69a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Oct 2022 14:39:35 +0100 Subject: [PATCH 01/29] chore(deps)!: bump @libp2p/interface-transport from 1.0.4 to 2.0.0 (#215) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b82570b..5bc9c58 100644 --- a/package.json +++ b/package.json @@ -137,7 +137,7 @@ }, "dependencies": { "@libp2p/interface-connection": "^3.0.2", - "@libp2p/interface-transport": "^1.0.4", + "@libp2p/interface-transport": "^2.0.0", "@libp2p/interfaces": "^3.0.3", "@libp2p/logger": "^2.0.0", "@libp2p/utils": "^3.0.2", From 77ae659fc315b9308e1d365ce82156e8772277f2 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 7 Oct 2022 13:46:01 +0000 Subject: [PATCH 02/29] chore(release): 4.0.0 [skip ci] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [4.0.0](https://github.com/libp2p/js-libp2p-tcp/compare/v3.1.2...v4.0.0) (2022-10-07) ### ⚠ BREAKING CHANGES * **deps:** bump @libp2p/interface-transport from 1.0.4 to 2.0.0 (#215) ### Trivial Changes * **deps:** bump @libp2p/interface-transport from 1.0.4 to 2.0.0 ([#215](https://github.com/libp2p/js-libp2p-tcp/issues/215)) ([1adf73d](https://github.com/libp2p/js-libp2p-tcp/commit/1adf73db4e88e0c196766588a2972a3a6e28e69a)) --- CHANGELOG.md | 11 +++++++++++ package.json | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e2e2eb..61abc68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +## [4.0.0](https://github.com/libp2p/js-libp2p-tcp/compare/v3.1.2...v4.0.0) (2022-10-07) + + +### ⚠ BREAKING CHANGES + +* **deps:** bump @libp2p/interface-transport from 1.0.4 to 2.0.0 (#215) + +### Trivial Changes + +* **deps:** bump @libp2p/interface-transport from 1.0.4 to 2.0.0 ([#215](https://github.com/libp2p/js-libp2p-tcp/issues/215)) ([1adf73d](https://github.com/libp2p/js-libp2p-tcp/commit/1adf73db4e88e0c196766588a2972a3a6e28e69a)) + ## [3.1.2](https://github.com/libp2p/js-libp2p-tcp/compare/v3.1.1...v3.1.2) (2022-09-24) diff --git a/package.json b/package.json index 5bc9c58..dd6a97a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@libp2p/tcp", - "version": "3.1.2", + "version": "4.0.0", "description": "Node.js implementation of the TCP module that libp2p uses, which implements the interface-connection and interface-transport interfaces", "license": "Apache-2.0 OR MIT", "homepage": "https://github.com/libp2p/js-libp2p-tcp#readme", From f224a5a0e8b497317b2b9410bb60433647a3185a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Oct 2022 17:14:06 +0100 Subject: [PATCH 03/29] chore(deps-dev): bump @libp2p/interface-mocks from 4.0.3 to 6.0.0 (#216) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dd6a97a..584d36b 100644 --- a/package.json +++ b/package.json @@ -148,7 +148,7 @@ "stream-to-it": "^0.2.2" }, "devDependencies": { - "@libp2p/interface-mocks": "^4.0.3", + "@libp2p/interface-mocks": "^6.0.0", "@libp2p/interface-transport-compliance-tests": "^2.0.6", "aegir": "^37.5.3", "it-all": "^1.0.6", From 493219c4b0f96e7d7eda1b8e8c1272527d6e91fb Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 7 Oct 2022 16:18:32 +0000 Subject: [PATCH 04/29] chore(release): 4.0.1 [skip ci] ## [4.0.1](https://github.com/libp2p/js-libp2p-tcp/compare/v4.0.0...v4.0.1) (2022-10-07) ### Trivial Changes * **deps-dev:** bump @libp2p/interface-mocks from 4.0.3 to 6.0.0 ([#216](https://github.com/libp2p/js-libp2p-tcp/issues/216)) ([f224a5a](https://github.com/libp2p/js-libp2p-tcp/commit/f224a5a0e8b497317b2b9410bb60433647a3185a)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 61abc68..8aa6db7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [4.0.1](https://github.com/libp2p/js-libp2p-tcp/compare/v4.0.0...v4.0.1) (2022-10-07) + + +### Trivial Changes + +* **deps-dev:** bump @libp2p/interface-mocks from 4.0.3 to 6.0.0 ([#216](https://github.com/libp2p/js-libp2p-tcp/issues/216)) ([f224a5a](https://github.com/libp2p/js-libp2p-tcp/commit/f224a5a0e8b497317b2b9410bb60433647a3185a)) + ## [4.0.0](https://github.com/libp2p/js-libp2p-tcp/compare/v3.1.2...v4.0.0) (2022-10-07) diff --git a/package.json b/package.json index 584d36b..eec8cfe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@libp2p/tcp", - "version": "4.0.0", + "version": "4.0.1", "description": "Node.js implementation of the TCP module that libp2p uses, which implements the interface-connection and interface-transport interfaces", "license": "Apache-2.0 OR MIT", "homepage": "https://github.com/libp2p/js-libp2p-tcp#readme", From af7b8e2bf48ec0c9f01e087e76bc9570dca05783 Mon Sep 17 00:00:00 2001 From: Lion - dapplion <35266934+dapplion@users.noreply.github.com> Date: Tue, 11 Oct 2022 09:43:36 +0200 Subject: [PATCH 05/29] fix: port listener to ES6 class syntax (#214) Co-authored-by: achingbrain --- src/index.ts | 10 +-- src/listener.ts | 176 +++++++++++++++++++++++------------------------- 2 files changed, 89 insertions(+), 97 deletions(-) diff --git a/src/index.ts b/src/index.ts index f790055..066ee13 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,11 +3,11 @@ import * as mafmt from '@multiformats/mafmt' import errCode from 'err-code' import { logger } from '@libp2p/logger' import { toMultiaddrConnection } from './socket-to-conn.js' -import { createListener } from './listener.js' +import { TCPListener } from './listener.js' import { multiaddrToNetConfig } from './utils.js' import { AbortError } from '@libp2p/interfaces/errors' import { CODE_CIRCUIT, CODE_P2P, CODE_UNIX } from './constants.js' -import { CreateListenerOptions, DialOptions, symbol, Transport } from '@libp2p/interface-transport' +import { CreateListenerOptions, DialOptions, Listener, symbol, Transport } from '@libp2p/interface-transport' import type { AbortOptions, Multiaddr } from '@multiformats/multiaddr' import type { Socket, IpcSocketConnectOpts, TcpSocketConnectOpts } from 'net' import type { Connection } from '@libp2p/interface-connection' @@ -155,8 +155,8 @@ export class TCP implements Transport { * anytime a new incoming Connection has been successfully upgraded via * `upgrader.upgradeInbound`. */ - createListener (options: TCPCreateListenerOptions) { - return createListener({ + createListener (options: TCPCreateListenerOptions): Listener { + return new TCPListener({ ...options, socketInactivityTimeout: this.opts.inboundSocketInactivityTimeout, socketCloseTimeout: this.opts.socketCloseTimeout @@ -166,7 +166,7 @@ export class TCP implements Transport { /** * Takes a list of `Multiaddr`s and returns only valid TCP addresses */ - filter (multiaddrs: Multiaddr[]) { + filter (multiaddrs: Multiaddr[]): Multiaddr[] { multiaddrs = Array.isArray(multiaddrs) ? multiaddrs : [multiaddrs] return multiaddrs.filter(ma => { diff --git a/src/listener.ts b/src/listener.ts index d850016..0bd2d74 100644 --- a/src/listener.ts +++ b/src/listener.ts @@ -8,17 +8,12 @@ import { } from './utils.js' import { EventEmitter, CustomEvent } from '@libp2p/interfaces/events' import type { MultiaddrConnection, Connection } from '@libp2p/interface-connection' -import type { Upgrader, Listener } from '@libp2p/interface-transport' -import type { Server } from 'net' +import type { Upgrader, Listener, ListenerEvents } from '@libp2p/interface-transport' import type { Multiaddr } from '@multiformats/multiaddr' import type { TCPCreateListenerOptions } from './index.js' const log = logger('libp2p:tcp:listener') -interface ServerWithMultiaddrConnections extends Server { - __connections: MultiaddrConnection[] -} - /** * Attempts to close the given maConn. If a failure occurs, it will be logged */ @@ -37,20 +32,29 @@ interface Context extends TCPCreateListenerOptions { socketCloseTimeout?: number } -/** - * Create listener - */ -export function createListener (context: Context) { - const { - handler, upgrader, socketInactivityTimeout, socketCloseTimeout - } = context +type Status = {started: false} | {started: true, listeningAddr: Multiaddr, peerId: string | null } + +export class TCPListener extends EventEmitter implements Listener { + private readonly server: net.Server + /** Keep track of open connections to destroy in case of timeout */ + private readonly connections = new Set() - context.keepAlive = context.keepAlive ?? true + private status: Status = { started: false } - let peerId: string | null - let listeningAddr: Multiaddr + constructor (private readonly context: Context) { + super() + + context.keepAlive = context.keepAlive ?? true + + this.server = net.createServer(context, this.onSocket.bind(this)) + + this.server + .on('listening', () => this.dispatchEvent(new CustomEvent('listening'))) + .on('error', err => this.dispatchEvent(new CustomEvent('error', { detail: err }))) + .on('close', () => this.dispatchEvent(new CustomEvent('close'))) + } - const server: ServerWithMultiaddrConnections = Object.assign(net.createServer(context, socket => { + private onSocket (socket: net.Socket) { // Avoid uncaught errors caused by unstable connections socket.on('error', err => { log('socket error', err) @@ -59,9 +63,9 @@ export function createListener (context: Context) { let maConn: MultiaddrConnection try { maConn = toMultiaddrConnection(socket, { - listeningAddr, - socketInactivityTimeout, - socketCloseTimeout + listeningAddr: this.status.started ? this.status.listeningAddr : undefined, + socketInactivityTimeout: this.context.socketInactivityTimeout, + socketCloseTimeout: this.context.socketCloseTimeout }) } catch (err) { log.error('inbound connection failed', err) @@ -70,16 +74,20 @@ export function createListener (context: Context) { log('new inbound connection %s', maConn.remoteAddr) try { - upgrader.upgradeInbound(maConn) + this.context.upgrader.upgradeInbound(maConn) .then((conn) => { log('inbound connection %s upgraded', maConn.remoteAddr) - trackConn(server, maConn, socket) + this.connections.add(maConn) - if (handler != null) { - handler(conn) + socket.once('close', () => { + this.connections.delete(maConn) + }) + + if (this.context.handler != null) { + this.context.handler(conn) } - listener.dispatchEvent(new CustomEvent('connection', { detail: conn })) + this.dispatchEvent(new CustomEvent('connection', { detail: conn })) }) .catch(async err => { log.error('inbound connection failed', err) @@ -97,85 +105,69 @@ export function createListener (context: Context) { log.error('closing inbound connection failed', err) }) } - }), - // Keep track of open connections to destroy in case of timeout - { __connections: [] }) + } - const listener: Listener = Object.assign(new EventEmitter(), { - getAddrs: () => { - let addrs: Multiaddr[] = [] - const address = server.address() + getAddrs () { + if (!this.status.started) { + return [] + } - if (address == null) { - return [] - } + let addrs: Multiaddr[] = [] + const address = this.server.address() + const { listeningAddr, peerId } = this.status - if (typeof address === 'string') { - addrs = [listeningAddr] - } else { - try { - // Because TCP will only return the IPv6 version - // we need to capture from the passed multiaddr - if (listeningAddr.toString().startsWith('/ip4')) { - addrs = addrs.concat(getMultiaddrs('ip4', address.address, address.port)) - } else if (address.family === 'IPv6') { - addrs = addrs.concat(getMultiaddrs('ip6', address.address, address.port)) - } - } catch (err) { - log.error('could not turn %s:%s into multiaddr', address.address, address.port, err) + if (address == null) { + return [] + } + + if (typeof address === 'string') { + addrs = [listeningAddr] + } else { + try { + // Because TCP will only return the IPv6 version + // we need to capture from the passed multiaddr + if (listeningAddr.toString().startsWith('/ip4')) { + addrs = addrs.concat(getMultiaddrs('ip4', address.address, address.port)) + } else if (address.family === 'IPv6') { + addrs = addrs.concat(getMultiaddrs('ip6', address.address, address.port)) } + } catch (err) { + log.error('could not turn %s:%s into multiaddr', address.address, address.port, err) } + } - return addrs.map(ma => peerId != null ? ma.encapsulate(`/p2p/${peerId}`) : ma) - }, - listen: async (ma: Multiaddr) => { - listeningAddr = ma - peerId = ma.getPeerId() - - if (peerId == null) { - listeningAddr = ma.decapsulateCode(CODE_P2P) - } + return addrs.map(ma => peerId != null ? ma.encapsulate(`/p2p/${peerId}`) : ma) + } - return await new Promise((resolve, reject) => { - const options = multiaddrToNetConfig(listeningAddr) - server.listen(options, (err?: any) => { - if (err != null) { - return reject(err) - } - log('Listening on %s', server.address()) - resolve() - }) - }) - }, - close: async () => { - if (!server.listening) { - return - } + async listen (ma: Multiaddr) { + const peerId = ma.getPeerId() + const listeningAddr = peerId == null ? ma.decapsulateCode(CODE_P2P) : ma - await Promise.all( - server.__connections.map(async maConn => await attemptClose(maConn)) - ) + this.status = { started: true, listeningAddr, peerId } - await new Promise((resolve, reject) => { - server.close(err => (err != null) ? reject(err) : resolve()) + return await new Promise((resolve, reject) => { + const options = multiaddrToNetConfig(listeningAddr) + this.server.listen(options, (err?: any) => { + if (err != null) { + return reject(err) + } + log('Listening on %s', this.server.address()) + resolve() }) - } - }) - - server - .on('listening', () => listener.dispatchEvent(new CustomEvent('listening'))) - .on('error', err => listener.dispatchEvent(new CustomEvent('error', { detail: err }))) - .on('close', () => listener.dispatchEvent(new CustomEvent('close'))) + }) + } - return listener -} + async close () { + if (!this.server.listening) { + return + } -function trackConn (server: ServerWithMultiaddrConnections, maConn: MultiaddrConnection, socket: net.Socket) { - server.__connections.push(maConn) + await Promise.all( + Array.from(this.connections.values()).map(async maConn => await attemptClose(maConn)) + ) - const untrackConn = () => { - server.__connections = server.__connections.filter(c => c !== maConn) + await new Promise((resolve, reject) => { + this.server.close(err => (err != null) ? reject(err) : resolve()) + }) } - - socket.once('close', untrackConn) } From 5dea7d307422586fa9075962dabda00291b77930 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 11 Oct 2022 07:48:09 +0000 Subject: [PATCH 06/29] chore(release): 4.0.2 [skip ci] ## [4.0.2](https://github.com/libp2p/js-libp2p-tcp/compare/v4.0.1...v4.0.2) (2022-10-11) ### Bug Fixes * port listener to ES6 class syntax ([#214](https://github.com/libp2p/js-libp2p-tcp/issues/214)) ([af7b8e2](https://github.com/libp2p/js-libp2p-tcp/commit/af7b8e2bf48ec0c9f01e087e76bc9570dca05783)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8aa6db7..8d170ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [4.0.2](https://github.com/libp2p/js-libp2p-tcp/compare/v4.0.1...v4.0.2) (2022-10-11) + + +### Bug Fixes + +* port listener to ES6 class syntax ([#214](https://github.com/libp2p/js-libp2p-tcp/issues/214)) ([af7b8e2](https://github.com/libp2p/js-libp2p-tcp/commit/af7b8e2bf48ec0c9f01e087e76bc9570dca05783)) + ## [4.0.1](https://github.com/libp2p/js-libp2p-tcp/compare/v4.0.0...v4.0.1) (2022-10-07) diff --git a/package.json b/package.json index eec8cfe..c54fcc0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@libp2p/tcp", - "version": "4.0.1", + "version": "4.0.2", "description": "Node.js implementation of the TCP module that libp2p uses, which implements the interface-connection and interface-transport interfaces", "license": "Apache-2.0 OR MIT", "homepage": "https://github.com/libp2p/js-libp2p-tcp#readme", From 99e88a4d3122c46f06f69cfbe3f72a2279e2329f Mon Sep 17 00:00:00 2001 From: Lion - dapplion <35266934+dapplion@users.noreply.github.com> Date: Tue, 11 Oct 2022 09:55:33 +0200 Subject: [PATCH 07/29] feat: add server.maxConnections option (#213) https://nodejs.org/api/net.html#servermaxconnections If set reject connections when the server's connection count gets high Useful to prevent too resource exhaustion via many open connections on high bursts of activity Co-authored-by: achingbrain --- src/index.ts | 7 ++++ src/listener.ts | 8 ++++ test/max-connections.spec.ts | 79 ++++++++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+) create mode 100644 test/max-connections.spec.ts diff --git a/src/index.ts b/src/index.ts index 066ee13..d0ab4fd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -29,6 +29,12 @@ export interface TCPOptions { * When closing a socket, wait this long for it to close gracefully before it is closed more forcibly */ socketCloseTimeout?: number + + /** + * Set this property to reject connections when the server's connection count gets high. + * https://nodejs.org/api/net.html#servermaxconnections + */ + maxConnections?: number } /** @@ -158,6 +164,7 @@ export class TCP implements Transport { createListener (options: TCPCreateListenerOptions): Listener { return new TCPListener({ ...options, + maxConnections: this.opts.maxConnections, socketInactivityTimeout: this.opts.inboundSocketInactivityTimeout, socketCloseTimeout: this.opts.socketCloseTimeout }) diff --git a/src/listener.ts b/src/listener.ts index 0bd2d74..63dafed 100644 --- a/src/listener.ts +++ b/src/listener.ts @@ -30,6 +30,7 @@ interface Context extends TCPCreateListenerOptions { upgrader: Upgrader socketInactivityTimeout?: number socketCloseTimeout?: number + maxConnections?: number } type Status = {started: false} | {started: true, listeningAddr: Multiaddr, peerId: string | null } @@ -48,6 +49,13 @@ export class TCPListener extends EventEmitter implements Listene this.server = net.createServer(context, this.onSocket.bind(this)) + // https://nodejs.org/api/net.html#servermaxconnections + // If set reject connections when the server's connection count gets high + // Useful to prevent too resource exhaustion via many open connections on high bursts of activity + if (context.maxConnections !== undefined) { + this.server.maxConnections = context.maxConnections + } + this.server .on('listening', () => this.dispatchEvent(new CustomEvent('listening'))) .on('error', err => this.dispatchEvent(new CustomEvent('error', { detail: err }))) diff --git a/test/max-connections.spec.ts b/test/max-connections.spec.ts new file mode 100644 index 0000000..d0c28e7 --- /dev/null +++ b/test/max-connections.spec.ts @@ -0,0 +1,79 @@ +import { expect } from 'aegir/chai' +import net from 'node:net' +import { promisify } from 'node:util' +import { mockUpgrader } from '@libp2p/interface-mocks' +import { multiaddr } from '@multiformats/multiaddr' +import { TCP } from '../src/index.js' + +describe('maxConnections', () => { + const afterEachCallbacks: Array<() => Promise | any> = [] + afterEach(async () => { + await Promise.all(afterEachCallbacks.map(fn => fn())) + afterEachCallbacks.length = 0 + }) + + it('reject dial of connection above maxConnections', async () => { + const maxConnections = 2 + const socketCount = 4 + const port = 9900 + + const seenRemoteConnections = new Set() + const tcp = new TCP({ maxConnections }) + + const upgrader = mockUpgrader() + const listener = tcp.createListener({ upgrader }) + // eslint-disable-next-line @typescript-eslint/promise-function-async + afterEachCallbacks.push(() => listener.close()) + await listener.listen(multiaddr(`/ip4/127.0.0.1/tcp/${port}`)) + + listener.addEventListener('connection', (conn) => { + seenRemoteConnections.add(conn.detail.remoteAddr.toString()) + }) + + const sockets: net.Socket[] = [] + + for (let i = 0; i < socketCount; i++) { + const socket = net.connect({ port }) + sockets.push(socket) + + // eslint-disable-next-line @typescript-eslint/promise-function-async + afterEachCallbacks.unshift(async () => { + if (!socket.destroyed) { + socket.destroy() + await new Promise((resolve) => socket.on('close', resolve)) + } + }) + + // Wait for connection so the order of sockets is stable, sockets expected to be alive are always [0,1] + await new Promise((resolve, reject) => { + socket.on('connect', () => { + resolve() + }) + socket.on('error', (err) => { + reject(err) + }) + }) + } + + // With server.maxConnections the TCP socket is created and the initial handshake is completed + // Then in the server handler NodeJS javascript code will call socket.emit('drop') if over the limit + // https://github.com/nodejs/node/blob/fddc701d3c0eb4520f2af570876cc987ae6b4ba2/lib/net.js#L1706 + + // Wait for some time for server to drop all sockets above limit + await promisify(setTimeout)(250) + + expect(seenRemoteConnections.size).equals(maxConnections, 'wrong serverConnections') + + for (let i = 0; i < socketCount; i++) { + const socket = sockets[i] + + if (i < maxConnections) { + // Assert socket connected + expect(socket.destroyed).equals(false, `socket ${i} under limit must not be destroyed`) + } else { + // Assert socket ended + expect(socket.destroyed).equals(true, `socket ${i} above limit must be destroyed`) + } + } + }) +}) From adf01aca69c7cf48d7c5c287a1db3e6754966424 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 11 Oct 2022 08:00:26 +0000 Subject: [PATCH 08/29] chore(release): 4.1.0 [skip ci] ## [4.1.0](https://github.com/libp2p/js-libp2p-tcp/compare/v4.0.2...v4.1.0) (2022-10-11) ### Features * add server.maxConnections option ([#213](https://github.com/libp2p/js-libp2p-tcp/issues/213)) ([99e88a4](https://github.com/libp2p/js-libp2p-tcp/commit/99e88a4d3122c46f06f69cfbe3f72a2279e2329f)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d170ce..7eed726 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [4.1.0](https://github.com/libp2p/js-libp2p-tcp/compare/v4.0.2...v4.1.0) (2022-10-11) + + +### Features + +* add server.maxConnections option ([#213](https://github.com/libp2p/js-libp2p-tcp/issues/213)) ([99e88a4](https://github.com/libp2p/js-libp2p-tcp/commit/99e88a4d3122c46f06f69cfbe3f72a2279e2329f)) + ## [4.0.2](https://github.com/libp2p/js-libp2p-tcp/compare/v4.0.1...v4.0.2) (2022-10-11) diff --git a/package.json b/package.json index c54fcc0..bae5c23 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@libp2p/tcp", - "version": "4.0.2", + "version": "4.1.0", "description": "Node.js implementation of the TCP module that libp2p uses, which implements the interface-connection and interface-transport interfaces", "license": "Apache-2.0 OR MIT", "homepage": "https://github.com/libp2p/js-libp2p-tcp#readme", From be2dbc3f674e9bce534dc92d93ad2739ed6d2bef Mon Sep 17 00:00:00 2001 From: Alex Potsides Date: Wed, 12 Oct 2022 15:43:32 +0100 Subject: [PATCH 09/29] fix!: remove @libp2p/components (#219) `@libp2p/components` is a choke-point for our dependency graph as it depends on every interface, meaning when one interface revs a major `@libp2p/components` major has to change too which means every module depending on it also needs a major. Switch instead to constructor injection of simple objects that let modules declare their dependencies on interfaces directly instead of indirectly via `@libp2p/components` Refs https://github.com/libp2p/js-libp2p-components/issues/6 BREAKING CHANGE: modules no longer implement `Initializable` instead switching to constructor injection --- README.md | 12 ++++---- package.json | 6 ++-- src/index.ts | 8 +++++- test/compliance.spec.ts | 6 ++-- test/connection.spec.ts | 16 +++++------ test/filter.spec.ts | 11 +++---- test/listen-dial.spec.ts | 56 ++++++++++++++++++------------------ test/max-connections.spec.ts | 6 ++-- 8 files changed, 64 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index ecb13ae..4cd2d81 100644 --- a/README.md +++ b/README.md @@ -36,9 +36,9 @@ $ npm i @libp2p/tcp ## Usage ```js -import { TCP } from '@libp2p/tcp' +import { tcp } from '@libp2p/tcp' import { multiaddr } from '@multiformats/multiaddr' -import {pipe} from 'it-pipe' +import { pipe } from 'it-pipe' import all from 'it-all' // A simple upgrader that just returns the MultiaddrConnection @@ -47,9 +47,9 @@ const upgrader = { upgradeOutbound: async maConn => maConn } -const tcp = new TCP() +const transport = tcp()() -const listener = tcp.createListener({ +const listener = transport.createListener({ upgrader, handler: (socket) => { console.log('new connection opened') @@ -64,7 +64,7 @@ const addr = multiaddr('/ip4/127.0.0.1/tcp/9090') await listener.listen(addr) console.log('listening') -const socket = await tcp.dial(addr, { upgrader }) +const socket = await transport.dial(addr, { upgrader }) const values = await pipe( socket, all @@ -89,7 +89,7 @@ Value: hello World! [![](https://raw.githubusercontent.com/libp2p/js-libp2p-interfaces/master/packages/libp2p-interfaces/src/transport/img/badge.png)](https://github.com/libp2p/js-libp2p-interfaces/tree/master/packages/libp2p-interfaces/src/transport) -`libp2p-tcp` accepts TCP addresses as both IPFS and non IPFS encapsulated addresses, i.e: +`@libp2p/tcp` accepts TCP addresses as both IPFS and non IPFS encapsulated addresses, i.e: `/ip4/127.0.0.1/tcp/4001` `/ip4/127.0.0.1/tcp/4001/ipfs/QmHash` diff --git a/package.json b/package.json index bae5c23..f69fdc0 100644 --- a/package.json +++ b/package.json @@ -148,13 +148,13 @@ "stream-to-it": "^0.2.2" }, "devDependencies": { - "@libp2p/interface-mocks": "^6.0.0", - "@libp2p/interface-transport-compliance-tests": "^2.0.6", + "@libp2p/interface-mocks": "^7.0.1", + "@libp2p/interface-transport-compliance-tests": "^3.0.0", "aegir": "^37.5.3", "it-all": "^1.0.6", "it-pipe": "^2.0.3", "p-defer": "^4.0.0", "sinon": "^14.0.0", - "uint8arrays": "^3.0.0" + "uint8arrays": "^4.0.2" } } diff --git a/src/index.ts b/src/index.ts index d0ab4fd..7b2930f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -55,7 +55,7 @@ export interface TCPCreateListenerOptions extends CreateListenerOptions, TCPSock } -export class TCP implements Transport { +class TCP implements Transport { private readonly opts: TCPOptions constructor (options: TCPOptions = {}) { @@ -189,3 +189,9 @@ export class TCP implements Transport { }) } } + +export function tcp (init: TCPOptions = {}): (components?: any) => Transport { + return () => { + return new TCP(init) + } +} diff --git a/test/compliance.spec.ts b/test/compliance.spec.ts index 674e9ce..ed50c9c 100644 --- a/test/compliance.spec.ts +++ b/test/compliance.spec.ts @@ -2,12 +2,12 @@ import sinon from 'sinon' import tests from '@libp2p/interface-transport-compliance-tests' import { multiaddr } from '@multiformats/multiaddr' import net from 'net' -import { TCP } from '../src/index.js' +import { tcp } from '../src/index.js' describe('interface-transport compliance', () => { tests({ async setup () { - const tcp = new TCP() + const transport = tcp()() const addrs = [ multiaddr('/ip4/127.0.0.1/tcp/9091'), multiaddr('/ip4/127.0.0.1/tcp/9092'), @@ -35,7 +35,7 @@ describe('interface-transport compliance', () => { } } - return { transport: tcp, addrs, connector } + return { transport, addrs, connector } }, async teardown () {} }) diff --git a/test/connection.spec.ts b/test/connection.spec.ts index dafaac0..254826a 100644 --- a/test/connection.spec.ts +++ b/test/connection.spec.ts @@ -1,16 +1,16 @@ import { expect } from 'aegir/chai' -import { TCP } from '../src/index.js' +import { tcp } from '../src/index.js' import { multiaddr } from '@multiformats/multiaddr' import { mockUpgrader } from '@libp2p/interface-mocks' import type { Connection } from '@libp2p/interface-connection' -import type { Upgrader } from '@libp2p/interface-transport' +import type { Transport, Upgrader } from '@libp2p/interface-transport' describe('valid localAddr and remoteAddr', () => { - let tcp: TCP + let transport: Transport let upgrader: Upgrader beforeEach(() => { - tcp = new TCP() + transport = tcp()() upgrader = mockUpgrader() }) @@ -24,7 +24,7 @@ describe('valid localAddr and remoteAddr', () => { const handler = (conn: Connection) => handled(conn) // Create a listener with the handler - const listener = tcp.createListener({ + const listener = transport.createListener({ handler, upgrader }) @@ -36,7 +36,7 @@ describe('valid localAddr and remoteAddr', () => { expect(localAddrs.length).to.equal(1) // Dial to that address - await tcp.dial(localAddrs[0], { + await transport.dial(localAddrs[0], { upgrader }) @@ -55,7 +55,7 @@ describe('valid localAddr and remoteAddr', () => { const handler = (conn: Connection) => handled(conn) // Create a listener with the handler - const listener = tcp.createListener({ + const listener = transport.createListener({ handler, upgrader }) @@ -67,7 +67,7 @@ describe('valid localAddr and remoteAddr', () => { expect(localAddrs.length).to.equal(1) // Dial to that address - const dialerConn = await tcp.dial(localAddrs[0], { + const dialerConn = await transport.dial(localAddrs[0], { upgrader }) diff --git a/test/filter.spec.ts b/test/filter.spec.ts index 4d3feec..5c4fbb4 100644 --- a/test/filter.spec.ts +++ b/test/filter.spec.ts @@ -1,15 +1,16 @@ import { expect } from 'aegir/chai' -import { TCP } from '../src/index.js' +import { tcp } from '../src/index.js' import { multiaddr } from '@multiformats/multiaddr' +import type { Transport } from '@libp2p/interface-transport' describe('filter addrs', () => { const base = '/ip4/127.0.0.1' const ipfs = '/ipfs/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw' - let tcp: TCP + let transport: Transport before(() => { - tcp = new TCP() + transport = tcp()() }) it('filter valid addrs for this transport', () => { @@ -22,7 +23,7 @@ describe('filter addrs', () => { const ma7 = multiaddr('/dns4/libp2p.io/tcp/9090') const ma8 = multiaddr('/dnsaddr/libp2p.io/tcp/9090') - const valid = tcp.filter([ma1, ma2, ma3, ma4, ma5, ma6, ma7, ma8]) + const valid = transport.filter([ma1, ma2, ma3, ma4, ma5, ma6, ma7, ma8]) expect(valid.length).to.equal(4) expect(valid[0]).to.deep.equal(ma1) expect(valid[1]).to.deep.equal(ma4) @@ -31,7 +32,7 @@ describe('filter addrs', () => { it('filter a single addr for this transport', () => { const ma1 = multiaddr(base + '/tcp/9090') - const valid = tcp.filter([ma1]) + const valid = transport.filter([ma1]) expect(valid.length).to.equal(1) expect(valid[0]).to.eql(ma1) }) diff --git a/test/listen-dial.spec.ts b/test/listen-dial.spec.ts index d3e7491..7a9e720 100644 --- a/test/listen-dial.spec.ts +++ b/test/listen-dial.spec.ts @@ -1,5 +1,5 @@ import { expect } from 'aegir/chai' -import { TCP } from '../src/index.js' +import { tcp } from '../src/index.js' import os from 'os' import path from 'path' import { multiaddr } from '@multiformats/multiaddr' @@ -7,17 +7,17 @@ import { pipe } from 'it-pipe' import all from 'it-all' import { mockRegistrar, mockUpgrader } from '@libp2p/interface-mocks' import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' -import type { Upgrader } from '@libp2p/interface-transport' +import type { Transport, Upgrader } from '@libp2p/interface-transport' const isCI = process.env.CI describe('listen', () => { - let tcp: TCP + let transport: Transport let listener: any let upgrader: Upgrader beforeEach(() => { - tcp = new TCP() + transport = tcp()() upgrader = mockUpgrader() }) afterEach(async () => { @@ -33,7 +33,7 @@ describe('listen', () => { it('listen on path', async () => { const mh = multiaddr(`/unix/${path.resolve(os.tmpdir(), `/tmp/p2pd-${Date.now()}.sock`)}`) - listener = tcp.createListener({ + listener = transport.createListener({ upgrader }) await listener.listen(mh) @@ -41,7 +41,7 @@ describe('listen', () => { it('listen on port 0', async () => { const mh = multiaddr('/ip4/127.0.0.1/tcp/0') - listener = tcp.createListener({ + listener = transport.createListener({ upgrader }) await listener.listen(mh) @@ -52,7 +52,7 @@ describe('listen', () => { return } const mh = multiaddr('/ip6/::/tcp/9090') - listener = tcp.createListener({ + listener = transport.createListener({ upgrader }) await listener.listen(mh) @@ -60,7 +60,7 @@ describe('listen', () => { it('listen on any Interface', async () => { const mh = multiaddr('/ip4/0.0.0.0/tcp/9090') - listener = tcp.createListener({ + listener = transport.createListener({ upgrader }) await listener.listen(mh) @@ -68,7 +68,7 @@ describe('listen', () => { it('getAddrs', async () => { const mh = multiaddr('/ip4/127.0.0.1/tcp/9090') - listener = tcp.createListener({ + listener = transport.createListener({ upgrader }) await listener.listen(mh) @@ -80,7 +80,7 @@ describe('listen', () => { it('getAddrs on port 0 listen', async () => { const mh = multiaddr('/ip4/127.0.0.1/tcp/0') - listener = tcp.createListener({ + listener = transport.createListener({ upgrader }) await listener.listen(mh) @@ -91,7 +91,7 @@ describe('listen', () => { it('getAddrs from listening on 0.0.0.0', async () => { const mh = multiaddr('/ip4/0.0.0.0/tcp/9090') - listener = tcp.createListener({ + listener = transport.createListener({ upgrader }) await listener.listen(mh) @@ -103,7 +103,7 @@ describe('listen', () => { it('getAddrs from listening on 0.0.0.0 and port 0', async () => { const mh = multiaddr('/ip4/0.0.0.0/tcp/0') - listener = tcp.createListener({ + listener = transport.createListener({ upgrader }) await listener.listen(mh) @@ -115,7 +115,7 @@ describe('listen', () => { it('getAddrs from listening on ip6 \'::\'', async () => { const mh = multiaddr('/ip6/::/tcp/9090') - listener = tcp.createListener({ + listener = transport.createListener({ upgrader }) await listener.listen(mh) @@ -127,7 +127,7 @@ describe('listen', () => { it('getAddrs preserves IPFS Id', async () => { const mh = multiaddr('/ip4/127.0.0.1/tcp/9090/ipfs/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw') - listener = tcp.createListener({ + listener = transport.createListener({ upgrader }) await listener.listen(mh) @@ -140,7 +140,7 @@ describe('listen', () => { describe('dial', () => { const protocol = '/echo/1.0.0' - let tcp: TCP + let transport: Transport let upgrader: Upgrader beforeEach(async () => { @@ -155,17 +155,17 @@ describe('dial', () => { registrar }) - tcp = new TCP() + transport = tcp()() }) it('dial on IPv4', async () => { const ma = multiaddr('/ip4/127.0.0.1/tcp/9090') - const listener = tcp.createListener({ + const listener = transport.createListener({ upgrader }) await listener.listen(ma) - const conn = await tcp.dial(ma, { + const conn = await transport.dial(ma, { upgrader }) const stream = await conn.newStream([protocol]) @@ -187,11 +187,11 @@ describe('dial', () => { } const ma = multiaddr('/ip6/::/tcp/9090') - const listener = tcp.createListener({ + const listener = transport.createListener({ upgrader }) await listener.listen(ma) - const conn = await tcp.dial(ma, { + const conn = await transport.dial(ma, { upgrader }) const stream = await conn.newStream([protocol]) @@ -209,11 +209,11 @@ describe('dial', () => { it('dial on path', async () => { const ma = multiaddr(`/unix/${path.resolve(os.tmpdir(), `/tmp/p2pd-${Date.now()}.sock`)}`) - const listener = tcp.createListener({ + const listener = transport.createListener({ upgrader }) await listener.listen(ma) - const conn = await tcp.dial(ma, { + const conn = await transport.dial(ma, { upgrader }) const stream = await conn.newStream([protocol]) @@ -235,7 +235,7 @@ describe('dial', () => { const ma = multiaddr('/ip6/::/tcp/9090') - const listener = tcp.createListener({ + const listener = transport.createListener({ handler: (conn) => { // let multistream select finish before closing setTimeout(() => { @@ -249,7 +249,7 @@ describe('dial', () => { await listener.listen(ma) const addrs = listener.getAddrs() - const conn = await tcp.dial(addrs[0], { + const conn = await transport.dial(addrs[0], { upgrader }) const stream = await conn.newStream([protocol]) @@ -270,7 +270,7 @@ describe('dial', () => { const ma = multiaddr('/ip6/::/tcp/9090') - const listener = tcp.createListener({ + const listener = transport.createListener({ handler: () => { handled() }, @@ -279,7 +279,7 @@ describe('dial', () => { await listener.listen(ma) const addrs = listener.getAddrs() - const conn = await tcp.dial(addrs[0], { + const conn = await transport.dial(addrs[0], { upgrader }) @@ -290,12 +290,12 @@ describe('dial', () => { it('dials on IPv4 with IPFS Id', async () => { const ma = multiaddr('/ip4/127.0.0.1/tcp/9090/ipfs/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw') - const listener = tcp.createListener({ + const listener = transport.createListener({ upgrader }) await listener.listen(ma) - const conn = await tcp.dial(ma, { + const conn = await transport.dial(ma, { upgrader }) const stream = await conn.newStream([protocol]) diff --git a/test/max-connections.spec.ts b/test/max-connections.spec.ts index d0c28e7..19f4bbf 100644 --- a/test/max-connections.spec.ts +++ b/test/max-connections.spec.ts @@ -3,7 +3,7 @@ import net from 'node:net' import { promisify } from 'node:util' import { mockUpgrader } from '@libp2p/interface-mocks' import { multiaddr } from '@multiformats/multiaddr' -import { TCP } from '../src/index.js' +import { tcp } from '../src/index.js' describe('maxConnections', () => { const afterEachCallbacks: Array<() => Promise | any> = [] @@ -18,10 +18,10 @@ describe('maxConnections', () => { const port = 9900 const seenRemoteConnections = new Set() - const tcp = new TCP({ maxConnections }) + const trasnport = tcp({ maxConnections })() const upgrader = mockUpgrader() - const listener = tcp.createListener({ upgrader }) + const listener = trasnport.createListener({ upgrader }) // eslint-disable-next-line @typescript-eslint/promise-function-async afterEachCallbacks.push(() => listener.close()) await listener.listen(multiaddr(`/ip4/127.0.0.1/tcp/${port}`)) From f5c6d00973e01ecc0c082335611b7b1d81c094b2 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 12 Oct 2022 14:50:55 +0000 Subject: [PATCH 10/29] chore(release): 5.0.0 [skip ci] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [5.0.0](https://github.com/libp2p/js-libp2p-tcp/compare/v4.1.0...v5.0.0) (2022-10-12) ### ⚠ BREAKING CHANGES * modules no longer implement `Initializable` instead switching to constructor injection ### Bug Fixes * remove @libp2p/components ([#219](https://github.com/libp2p/js-libp2p-tcp/issues/219)) ([be2dbc3](https://github.com/libp2p/js-libp2p-tcp/commit/be2dbc3f674e9bce534dc92d93ad2739ed6d2bef)) --- CHANGELOG.md | 11 +++++++++++ package.json | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7eed726..6ae70bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +## [5.0.0](https://github.com/libp2p/js-libp2p-tcp/compare/v4.1.0...v5.0.0) (2022-10-12) + + +### ⚠ BREAKING CHANGES + +* modules no longer implement `Initializable` instead switching to constructor injection + +### Bug Fixes + +* remove @libp2p/components ([#219](https://github.com/libp2p/js-libp2p-tcp/issues/219)) ([be2dbc3](https://github.com/libp2p/js-libp2p-tcp/commit/be2dbc3f674e9bce534dc92d93ad2739ed6d2bef)) + ## [4.1.0](https://github.com/libp2p/js-libp2p-tcp/compare/v4.0.2...v4.1.0) (2022-10-11) diff --git a/package.json b/package.json index f69fdc0..0138ab1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@libp2p/tcp", - "version": "4.1.0", + "version": "5.0.0", "description": "Node.js implementation of the TCP module that libp2p uses, which implements the interface-connection and interface-transport interfaces", "license": "Apache-2.0 OR MIT", "homepage": "https://github.com/libp2p/js-libp2p-tcp#readme", From fddebdff3ab2056da78f9ec665e5005a659e9045 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Oct 2022 13:52:19 +0100 Subject: [PATCH 11/29] chore(deps-dev): bump it-all from 1.0.6 to 2.0.0 (#222) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0138ab1..863e2ab 100644 --- a/package.json +++ b/package.json @@ -151,7 +151,7 @@ "@libp2p/interface-mocks": "^7.0.1", "@libp2p/interface-transport-compliance-tests": "^3.0.0", "aegir": "^37.5.3", - "it-all": "^1.0.6", + "it-all": "^2.0.0", "it-pipe": "^2.0.3", "p-defer": "^4.0.0", "sinon": "^14.0.0", From 2778c3850195a9cb598fcadf825bc18b01805134 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 17 Oct 2022 12:56:47 +0000 Subject: [PATCH 12/29] chore(release): 5.0.1 [skip ci] ## [5.0.1](https://github.com/libp2p/js-libp2p-tcp/compare/v5.0.0...v5.0.1) (2022-10-17) ### Trivial Changes * **deps-dev:** bump it-all from 1.0.6 to 2.0.0 ([#222](https://github.com/libp2p/js-libp2p-tcp/issues/222)) ([fddebdf](https://github.com/libp2p/js-libp2p-tcp/commit/fddebdff3ab2056da78f9ec665e5005a659e9045)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ae70bb..6c799e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.0.1](https://github.com/libp2p/js-libp2p-tcp/compare/v5.0.0...v5.0.1) (2022-10-17) + + +### Trivial Changes + +* **deps-dev:** bump it-all from 1.0.6 to 2.0.0 ([#222](https://github.com/libp2p/js-libp2p-tcp/issues/222)) ([fddebdf](https://github.com/libp2p/js-libp2p-tcp/commit/fddebdff3ab2056da78f9ec665e5005a659e9045)) + ## [5.0.0](https://github.com/libp2p/js-libp2p-tcp/compare/v4.1.0...v5.0.0) (2022-10-12) diff --git a/package.json b/package.json index 863e2ab..0563038 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@libp2p/tcp", - "version": "5.0.0", + "version": "5.0.1", "description": "Node.js implementation of the TCP module that libp2p uses, which implements the interface-connection and interface-transport interfaces", "license": "Apache-2.0 OR MIT", "homepage": "https://github.com/libp2p/js-libp2p-tcp#readme", From 4125e9eaa4d531dbcb0f2777149d1ca8fa9460a5 Mon Sep 17 00:00:00 2001 From: Alex Potsides Date: Sat, 5 Nov 2022 14:29:11 +0000 Subject: [PATCH 13/29] fix: handle listen error (#224) The `net.Server` `.listen` callback is not a node-style callback that gets passed an error, it's a listener for the `listen` event. To handle errors when `.listen`ing, one must listen for the `error` event, so update the code to do that and add a test to prevent regressions. --- src/listener.ts | 8 ++++---- test/listen-dial.spec.ts | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/listener.ts b/src/listener.ts index 63dafed..05e31dc 100644 --- a/src/listener.ts +++ b/src/listener.ts @@ -155,10 +155,10 @@ export class TCPListener extends EventEmitter implements Listene return await new Promise((resolve, reject) => { const options = multiaddrToNetConfig(listeningAddr) - this.server.listen(options, (err?: any) => { - if (err != null) { - return reject(err) - } + this.server.on('error', (err) => { + reject(err) + }) + this.server.listen(options, () => { log('Listening on %s', this.server.address()) resolve() }) diff --git a/test/listen-dial.spec.ts b/test/listen-dial.spec.ts index 7a9e720..59bfb3a 100644 --- a/test/listen-dial.spec.ts +++ b/test/listen-dial.spec.ts @@ -47,6 +47,22 @@ describe('listen', () => { await listener.listen(mh) }) + it('errors when listening on busy port', async () => { + const mh = multiaddr('/ip4/127.0.0.1/tcp/0') + listener = transport.createListener({ + upgrader + }) + await listener.listen(mh) + + const listener2 = transport.createListener({ + upgrader + }) + + const mh2 = listener.getAddrs()[0] + await expect(listener2.listen(mh2)).to.eventually.be.rejected() + .with.property('code', 'EADDRINUSE') + }) + it('listen on IPv6 addr', async () => { if (isCI != null) { return From 73240c42dd30d2f7b8362baabffd71f4bae130b6 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sat, 5 Nov 2022 14:34:47 +0000 Subject: [PATCH 14/29] chore(release): 5.0.2 [skip ci] ## [5.0.2](https://github.com/libp2p/js-libp2p-tcp/compare/v5.0.1...v5.0.2) (2022-11-05) ### Bug Fixes * handle listen error ([#224](https://github.com/libp2p/js-libp2p-tcp/issues/224)) ([4125e9e](https://github.com/libp2p/js-libp2p-tcp/commit/4125e9eaa4d531dbcb0f2777149d1ca8fa9460a5)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c799e7..40202c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.0.2](https://github.com/libp2p/js-libp2p-tcp/compare/v5.0.1...v5.0.2) (2022-11-05) + + +### Bug Fixes + +* handle listen error ([#224](https://github.com/libp2p/js-libp2p-tcp/issues/224)) ([4125e9e](https://github.com/libp2p/js-libp2p-tcp/commit/4125e9eaa4d531dbcb0f2777149d1ca8fa9460a5)) + ## [5.0.1](https://github.com/libp2p/js-libp2p-tcp/compare/v5.0.0...v5.0.1) (2022-10-17) diff --git a/package.json b/package.json index 0563038..ebe277e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@libp2p/tcp", - "version": "5.0.1", + "version": "5.0.2", "description": "Node.js implementation of the TCP module that libp2p uses, which implements the interface-connection and interface-transport interfaces", "license": "Apache-2.0 OR MIT", "homepage": "https://github.com/libp2p/js-libp2p-tcp#readme", From c0043577777181545eef925b50e28743cfd7a29d Mon Sep 17 00:00:00 2001 From: Alex Potsides Date: Sat, 5 Nov 2022 18:12:04 +0000 Subject: [PATCH 15/29] feat!: add metrics (#223) Uses new metrics interface from https://github.com/libp2p/js-libp2p-interfaces/pull/310 to report useful connection metrics. Similar to #217 but it adds the listening host/port to the metrics name to allow multiple TCP listeners to report metrics separately. BREAKING CHANGE: requires metrics interface v4 --- package.json | 1 + src/index.ts | 44 ++++++++++++++++++++++---- src/listener.ts | 72 ++++++++++++++++++++++++++++++++++++++++--- src/socket-to-conn.ts | 9 ++++-- 4 files changed, 113 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index ebe277e..b042edf 100644 --- a/package.json +++ b/package.json @@ -148,6 +148,7 @@ "stream-to-it": "^0.2.2" }, "devDependencies": { + "@libp2p/interface-metrics": "^4.0.0", "@libp2p/interface-mocks": "^7.0.1", "@libp2p/interface-transport-compliance-tests": "^3.0.0", "aegir": "^37.5.3", diff --git a/src/index.ts b/src/index.ts index 7b2930f..a57d4ef 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,6 +11,7 @@ import { CreateListenerOptions, DialOptions, Listener, symbol, Transport } from import type { AbortOptions, Multiaddr } from '@multiformats/multiaddr' import type { Socket, IpcSocketConnectOpts, TcpSocketConnectOpts } from 'net' import type { Connection } from '@libp2p/interface-connection' +import type { CounterGroup, Metrics } from '@libp2p/interface-metrics' const log = logger('libp2p:tcp') @@ -55,11 +56,36 @@ export interface TCPCreateListenerOptions extends CreateListenerOptions, TCPSock } +export interface TCPComponents { + metrics?: Metrics +} + +export interface TCPMetrics { + dialerEvents: CounterGroup + listenerEvents: CounterGroup +} + class TCP implements Transport { private readonly opts: TCPOptions + private readonly metrics?: TCPMetrics + private readonly components: TCPComponents - constructor (options: TCPOptions = {}) { + constructor (components: TCPComponents, options: TCPOptions = {}) { this.opts = options + this.components = components + + if (components.metrics != null) { + this.metrics = { + dialerEvents: components.metrics.registerCounterGroup('libp2p_tcp_dialer_errors_total', { + label: 'event', + help: 'Total count of TCP dialer errors by error type' + }), + listenerEvents: components.metrics.registerCounterGroup('libp2p_tcp_listener_errors_total', { + label: 'event', + help: 'Total count of TCP listener errors by error type' + }) + } + } } get [symbol] (): true { @@ -84,7 +110,8 @@ class TCP implements Transport { remoteAddr: ma, signal: options.signal, socketInactivityTimeout: this.opts.outboundSocketInactivityTimeout, - socketCloseTimeout: this.opts.socketCloseTimeout + socketCloseTimeout: this.opts.socketCloseTimeout, + metrics: this.metrics?.dialerEvents }) log('new outbound connection %s', maConn.remoteAddr) const conn = await options.upgrader.upgradeOutbound(maConn) @@ -107,12 +134,14 @@ class TCP implements Transport { const onError = (err: Error) => { err.message = `connection error ${cOptsStr}: ${err.message}` + this.metrics?.dialerEvents.increment({ error: true }) done(err) } const onTimeout = () => { log('connection timeout %s', cOptsStr) + this.metrics?.dialerEvents.increment({ timeout: true }) const err = errCode(new Error(`connection timeout after ${Date.now() - start}ms`), 'ERR_CONNECT_TIMEOUT') // Note: this will result in onError() being called @@ -121,11 +150,13 @@ class TCP implements Transport { const onConnect = () => { log('connection opened %j', cOpts) + this.metrics?.dialerEvents.increment({ connect: true }) done() } const onAbort = () => { log('connection aborted %j', cOpts) + this.metrics?.dialerEvents.increment({ abort: true }) rawSocket.destroy() done(new AbortError()) } @@ -166,7 +197,8 @@ class TCP implements Transport { ...options, maxConnections: this.opts.maxConnections, socketInactivityTimeout: this.opts.inboundSocketInactivityTimeout, - socketCloseTimeout: this.opts.socketCloseTimeout + socketCloseTimeout: this.opts.socketCloseTimeout, + metrics: this.components.metrics }) } @@ -190,8 +222,8 @@ class TCP implements Transport { } } -export function tcp (init: TCPOptions = {}): (components?: any) => Transport { - return () => { - return new TCP(init) +export function tcp (init: TCPOptions = {}): (components?: TCPComponents) => Transport { + return (components: TCPComponents = {}) => { + return new TCP(components, init) } } diff --git a/src/listener.ts b/src/listener.ts index 05e31dc..8546084 100644 --- a/src/listener.ts +++ b/src/listener.ts @@ -11,6 +11,7 @@ import type { MultiaddrConnection, Connection } from '@libp2p/interface-connecti import type { Upgrader, Listener, ListenerEvents } from '@libp2p/interface-transport' import type { Multiaddr } from '@multiformats/multiaddr' import type { TCPCreateListenerOptions } from './index.js' +import type { CounterGroup, Metric, Metrics } from '@libp2p/interface-metrics' const log = logger('libp2p:tcp:listener') @@ -31,6 +32,16 @@ interface Context extends TCPCreateListenerOptions { socketInactivityTimeout?: number socketCloseTimeout?: number maxConnections?: number + metrics?: Metrics +} + +const SERVER_STATUS_UP = 1 +const SERVER_STATUS_DOWN = 0 + +export interface TCPListenerMetrics { + status: Metric + errors: CounterGroup + events: CounterGroup } type Status = {started: false} | {started: true, listeningAddr: Multiaddr, peerId: string | null } @@ -39,8 +50,8 @@ export class TCPListener extends EventEmitter implements Listene private readonly server: net.Server /** Keep track of open connections to destroy in case of timeout */ private readonly connections = new Set() - private status: Status = { started: false } + private metrics?: TCPListenerMetrics constructor (private readonly context: Context) { super() @@ -57,15 +68,62 @@ export class TCPListener extends EventEmitter implements Listene } this.server - .on('listening', () => this.dispatchEvent(new CustomEvent('listening'))) - .on('error', err => this.dispatchEvent(new CustomEvent('error', { detail: err }))) - .on('close', () => this.dispatchEvent(new CustomEvent('close'))) + .on('listening', () => { + if (context.metrics != null) { + // we are listening, register metrics for our port + const address = this.server.address() + let addr: string + + if (address == null) { + addr = 'unknown' + } else if (typeof address === 'string') { + // unix socket + addr = address + } else { + addr = `${address.address}:${address.port}` + } + + context.metrics?.registerMetric(`libp2p_tcp_connections_${addr}_count`, { + help: 'Current active connections in TCP listener', + calculate: () => { + return this.connections.size + } + }) + + this.metrics = { + status: context.metrics.registerMetric(`libp2p_tcp_${addr}_server_status`, { + help: 'Current status of the TCP server' + }), + errors: context.metrics.registerCounterGroup(`libp2p_tcp_${addr}_server_errors_total`, { + label: 'error', + help: 'Total count of TCP listener errors by error type' + }), + events: context.metrics.registerCounterGroup(`libp2p_tcp_$${addr}_socket_events`, { + label: 'event', + help: 'Total count of TCP socket events by event' + }) + } + + this.metrics?.status.update(SERVER_STATUS_UP) + } + + this.dispatchEvent(new CustomEvent('listening')) + }) + .on('error', err => { + this.metrics?.errors.increment({ listen_error: true }) + this.dispatchEvent(new CustomEvent('error', { detail: err })) + }) + .on('close', () => { + this.metrics?.status.update(SERVER_STATUS_DOWN) + this.dispatchEvent(new CustomEvent('close')) + }) } private onSocket (socket: net.Socket) { // Avoid uncaught errors caused by unstable connections socket.on('error', err => { log('socket error', err) + this.metrics?.events.increment({ error: true }) }) let maConn: MultiaddrConnection @@ -73,10 +131,12 @@ export class TCPListener extends EventEmitter implements Listene maConn = toMultiaddrConnection(socket, { listeningAddr: this.status.started ? this.status.listeningAddr : undefined, socketInactivityTimeout: this.context.socketInactivityTimeout, - socketCloseTimeout: this.context.socketCloseTimeout + socketCloseTimeout: this.context.socketCloseTimeout, + metrics: this.metrics?.events }) } catch (err) { log.error('inbound connection failed', err) + this.metrics?.errors.increment({ inbound_to_connection: true }) return } @@ -99,6 +159,7 @@ export class TCPListener extends EventEmitter implements Listene }) .catch(async err => { log.error('inbound connection failed', err) + this.metrics?.errors.increment({ inbound_upgrade: true }) await attemptClose(maConn) }) @@ -111,6 +172,7 @@ export class TCPListener extends EventEmitter implements Listene attemptClose(maConn) .catch(err => { log.error('closing inbound connection failed', err) + this.metrics?.errors.increment({ inbound_closing_failed: true }) }) } } diff --git a/src/socket-to-conn.ts b/src/socket-to-conn.ts index c390f46..a8230cc 100644 --- a/src/socket-to-conn.ts +++ b/src/socket-to-conn.ts @@ -9,6 +9,7 @@ import errCode from 'err-code' import type { Socket } from 'net' import type { Multiaddr } from '@multiformats/multiaddr' import type { MultiaddrConnection } from '@libp2p/interface-connection' +import type { CounterGroup } from '@libp2p/interface-metrics' const log = logger('libp2p:tcp:socket') @@ -19,14 +20,15 @@ interface ToConnectionOptions { signal?: AbortSignal socketInactivityTimeout?: number socketCloseTimeout?: number + metrics?: CounterGroup } /** * Convert a socket into a MultiaddrConnection * https://github.com/libp2p/interface-transport#multiaddrconnection */ -export const toMultiaddrConnection = (socket: Socket, options?: ToConnectionOptions) => { - options = options ?? {} +export const toMultiaddrConnection = (socket: Socket, options: ToConnectionOptions) => { + const metrics = options.metrics const inactivityTimeout = options.socketInactivityTimeout ?? SOCKET_TIMEOUT const closeTimeout = options.socketCloseTimeout ?? CLOSE_TIMEOUT @@ -61,6 +63,7 @@ export const toMultiaddrConnection = (socket: Socket, options?: ToConnectionOpti // https://nodejs.org/dist/latest-v16.x/docs/api/net.html#socketsettimeouttimeout-callback socket.setTimeout(inactivityTimeout, () => { log('%s socket read timeout', lOptsStr) + metrics?.increment({ timeout: true }) // only destroy with an error if the remote has not sent the FIN message let err: Error | undefined @@ -75,6 +78,7 @@ export const toMultiaddrConnection = (socket: Socket, options?: ToConnectionOpti socket.once('close', () => { log('%s socket read timeout', lOptsStr) + metrics?.increment({ close: true }) // In instances where `close` was not explicitly called, // such as an iterable stream ending, ensure we have set the close @@ -88,6 +92,7 @@ export const toMultiaddrConnection = (socket: Socket, options?: ToConnectionOpti // the remote sent a FIN packet which means no more data will be sent // https://nodejs.org/dist/latest-v16.x/docs/api/net.html#event-end log('socket ended', maConn.remoteAddr.toString()) + metrics?.increment({ end: true }) }) const maConn: MultiaddrConnection = { From 92e144211784bb9c21f799c4c5fcab9c72ef5d8a Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sat, 5 Nov 2022 18:16:30 +0000 Subject: [PATCH 16/29] chore(release): 6.0.0 [skip ci] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [6.0.0](https://github.com/libp2p/js-libp2p-tcp/compare/v5.0.2...v6.0.0) (2022-11-05) ### ⚠ BREAKING CHANGES * requires metrics interface v4 ### Features * add metrics ([#223](https://github.com/libp2p/js-libp2p-tcp/issues/223)) ([c004357](https://github.com/libp2p/js-libp2p-tcp/commit/c0043577777181545eef925b50e28743cfd7a29d)), closes [#217](https://github.com/libp2p/js-libp2p-tcp/issues/217) --- CHANGELOG.md | 11 +++++++++++ package.json | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 40202c8..f7451a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +## [6.0.0](https://github.com/libp2p/js-libp2p-tcp/compare/v5.0.2...v6.0.0) (2022-11-05) + + +### ⚠ BREAKING CHANGES + +* requires metrics interface v4 + +### Features + +* add metrics ([#223](https://github.com/libp2p/js-libp2p-tcp/issues/223)) ([c004357](https://github.com/libp2p/js-libp2p-tcp/commit/c0043577777181545eef925b50e28743cfd7a29d)), closes [#217](https://github.com/libp2p/js-libp2p-tcp/issues/217) + ## [5.0.2](https://github.com/libp2p/js-libp2p-tcp/compare/v5.0.1...v5.0.2) (2022-11-05) diff --git a/package.json b/package.json index b042edf..580f4ce 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@libp2p/tcp", - "version": "5.0.2", + "version": "6.0.0", "description": "Node.js implementation of the TCP module that libp2p uses, which implements the interface-connection and interface-transport interfaces", "license": "Apache-2.0 OR MIT", "homepage": "https://github.com/libp2p/js-libp2p-tcp#readme", From 2822db31775fcdf78b69e58f711199a279edb4a7 Mon Sep 17 00:00:00 2001 From: web3-bot <81333946+web3-bot@users.noreply.github.com> Date: Mon, 14 Nov 2022 16:11:48 +0100 Subject: [PATCH 17/29] update .github/workflows/js-test-and-release.yml (#227) --- .github/workflows/js-test-and-release.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/js-test-and-release.yml b/.github/workflows/js-test-and-release.yml index 65d30bd..ed17349 100644 --- a/.github/workflows/js-test-and-release.yml +++ b/.github/workflows/js-test-and-release.yml @@ -7,8 +7,6 @@ on: branches: - master # with #262 - ${{{ github.default_branch }}} pull_request: - branches: - - master # with #262 - ${{{ github.default_branch }}} jobs: From a271056c8d8d179dd95399f9621d790a0f18b84a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Nov 2022 15:58:51 +0000 Subject: [PATCH 18/29] chore(deps-dev): bump @libp2p/interface-mocks from 7.1.0 to 8.0.1 (#225) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 580f4ce..b8f24e5 100644 --- a/package.json +++ b/package.json @@ -149,7 +149,7 @@ }, "devDependencies": { "@libp2p/interface-metrics": "^4.0.0", - "@libp2p/interface-mocks": "^7.0.1", + "@libp2p/interface-mocks": "^8.0.1", "@libp2p/interface-transport-compliance-tests": "^3.0.0", "aegir": "^37.5.3", "it-all": "^2.0.0", From 3aadf43c70b7d03f23c8de96dee20dafc9f71743 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 16 Nov 2022 16:05:11 +0000 Subject: [PATCH 19/29] chore(release): 6.0.1 [skip ci] ## [6.0.1](https://github.com/libp2p/js-libp2p-tcp/compare/v6.0.0...v6.0.1) (2022-11-16) ### Trivial Changes * **deps-dev:** bump @libp2p/interface-mocks from 7.1.0 to 8.0.1 ([#225](https://github.com/libp2p/js-libp2p-tcp/issues/225)) ([a271056](https://github.com/libp2p/js-libp2p-tcp/commit/a271056c8d8d179dd95399f9621d790a0f18b84a)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f7451a0..3f2020f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [6.0.1](https://github.com/libp2p/js-libp2p-tcp/compare/v6.0.0...v6.0.1) (2022-11-16) + + +### Trivial Changes + +* **deps-dev:** bump @libp2p/interface-mocks from 7.1.0 to 8.0.1 ([#225](https://github.com/libp2p/js-libp2p-tcp/issues/225)) ([a271056](https://github.com/libp2p/js-libp2p-tcp/commit/a271056c8d8d179dd95399f9621d790a0f18b84a)) + ## [6.0.0](https://github.com/libp2p/js-libp2p-tcp/compare/v5.0.2...v6.0.0) (2022-11-05) diff --git a/package.json b/package.json index b8f24e5..4f7b1d0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@libp2p/tcp", - "version": "6.0.0", + "version": "6.0.1", "description": "Node.js implementation of the TCP module that libp2p uses, which implements the interface-connection and interface-transport interfaces", "license": "Apache-2.0 OR MIT", "homepage": "https://github.com/libp2p/js-libp2p-tcp#readme", From 24c5b37ab64429972f29af6ae4516c18232d1ff3 Mon Sep 17 00:00:00 2001 From: Alex Potsides Date: Thu, 17 Nov 2022 12:44:35 +0200 Subject: [PATCH 20/29] fix: update metric names to follow prometheus naming guide (#228) The [Prometheus metric naming guidelines](https://prometheus.io/docs/practices/naming/) say they should have suffixes like `_total` for unit-less counts and `_info` for metadata. --- src/listener.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/listener.ts b/src/listener.ts index 8546084..d7611d4 100644 --- a/src/listener.ts +++ b/src/listener.ts @@ -83,7 +83,7 @@ export class TCPListener extends EventEmitter implements Listene addr = `${address.address}:${address.port}` } - context.metrics?.registerMetric(`libp2p_tcp_connections_${addr}_count`, { + context.metrics?.registerMetric(`libp2p_tcp_connections_${addr}_total`, { help: 'Current active connections in TCP listener', calculate: () => { return this.connections.size @@ -91,14 +91,14 @@ export class TCPListener extends EventEmitter implements Listene }) this.metrics = { - status: context.metrics.registerMetric(`libp2p_tcp_${addr}_server_status`, { + status: context.metrics.registerMetric(`libp2p_tcp_${addr}_server_status_info`, { help: 'Current status of the TCP server' }), errors: context.metrics.registerCounterGroup(`libp2p_tcp_${addr}_server_errors_total`, { label: 'error', help: 'Total count of TCP listener errors by error type' }), - events: context.metrics.registerCounterGroup(`libp2p_tcp_$${addr}_socket_events`, { + events: context.metrics.registerCounterGroup(`libp2p_tcp_${addr}_socket_events_total`, { label: 'event', help: 'Total count of TCP socket events by event' }) From efcfbb28a77192a489834c8b8ad832337539d62b Mon Sep 17 00:00:00 2001 From: Alex Potsides Date: Thu, 17 Nov 2022 12:44:49 +0200 Subject: [PATCH 21/29] chore: add test for filtering unix socket address (#229) Fixes #132 --- test/filter.spec.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/filter.spec.ts b/test/filter.spec.ts index 5c4fbb4..23b8877 100644 --- a/test/filter.spec.ts +++ b/test/filter.spec.ts @@ -6,6 +6,7 @@ import type { Transport } from '@libp2p/interface-transport' describe('filter addrs', () => { const base = '/ip4/127.0.0.1' const ipfs = '/ipfs/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw' + const unix = '/tmp/some/file.sock' let transport: Transport @@ -22,11 +23,13 @@ describe('filter addrs', () => { const ma6 = multiaddr('/ip4/127.0.0.1/tcp/9090/p2p-circuit' + ipfs) const ma7 = multiaddr('/dns4/libp2p.io/tcp/9090') const ma8 = multiaddr('/dnsaddr/libp2p.io/tcp/9090') + const ma9 = multiaddr('/unix' + unix) - const valid = transport.filter([ma1, ma2, ma3, ma4, ma5, ma6, ma7, ma8]) - expect(valid.length).to.equal(4) + const valid = transport.filter([ma1, ma2, ma3, ma4, ma5, ma6, ma7, ma8, ma9]) + expect(valid.length).to.equal(5) expect(valid[0]).to.deep.equal(ma1) expect(valid[1]).to.deep.equal(ma4) + expect(valid[4]).to.deep.equal(ma9) }) it('filter a single addr for this transport', () => { From de04ef432399cebf43f7b2213936298df445d0c1 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 17 Nov 2022 10:49:37 +0000 Subject: [PATCH 22/29] chore(release): 6.0.2 [skip ci] ## [6.0.2](https://github.com/libp2p/js-libp2p-tcp/compare/v6.0.1...v6.0.2) (2022-11-17) ### Bug Fixes * update metric names to follow prometheus naming guide ([#228](https://github.com/libp2p/js-libp2p-tcp/issues/228)) ([24c5b37](https://github.com/libp2p/js-libp2p-tcp/commit/24c5b37ab64429972f29af6ae4516c18232d1ff3)) ### Trivial Changes * add test for filtering unix socket address ([#229](https://github.com/libp2p/js-libp2p-tcp/issues/229)) ([efcfbb2](https://github.com/libp2p/js-libp2p-tcp/commit/efcfbb28a77192a489834c8b8ad832337539d62b)), closes [#132](https://github.com/libp2p/js-libp2p-tcp/issues/132) --- CHANGELOG.md | 12 ++++++++++++ package.json | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f2020f..8928f77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +## [6.0.2](https://github.com/libp2p/js-libp2p-tcp/compare/v6.0.1...v6.0.2) (2022-11-17) + + +### Bug Fixes + +* update metric names to follow prometheus naming guide ([#228](https://github.com/libp2p/js-libp2p-tcp/issues/228)) ([24c5b37](https://github.com/libp2p/js-libp2p-tcp/commit/24c5b37ab64429972f29af6ae4516c18232d1ff3)) + + +### Trivial Changes + +* add test for filtering unix socket address ([#229](https://github.com/libp2p/js-libp2p-tcp/issues/229)) ([efcfbb2](https://github.com/libp2p/js-libp2p-tcp/commit/efcfbb28a77192a489834c8b8ad832337539d62b)), closes [#132](https://github.com/libp2p/js-libp2p-tcp/issues/132) + ## [6.0.1](https://github.com/libp2p/js-libp2p-tcp/compare/v6.0.0...v6.0.1) (2022-11-16) diff --git a/package.json b/package.json index 4f7b1d0..d23118f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@libp2p/tcp", - "version": "6.0.1", + "version": "6.0.2", "description": "Node.js implementation of the TCP module that libp2p uses, which implements the interface-connection and interface-transport interfaces", "license": "Apache-2.0 OR MIT", "homepage": "https://github.com/libp2p/js-libp2p-tcp#readme", From 876ca132aa2b307315148628681cddfa0828b3ac Mon Sep 17 00:00:00 2001 From: Alex Potsides Date: Tue, 22 Nov 2022 10:09:26 +0000 Subject: [PATCH 23/29] fix: make metrics interface a dep instead of a dev dep (#231) Ensure we get the right version of the module. Also updates project config to the latest version. --- .github/dependabot.yml | 3 +++ README.md | 7 +++---- package.json | 14 +++++++++----- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 290ad02..0bc3b42 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -6,3 +6,6 @@ updates: interval: daily time: "10:00" open-pull-requests-limit: 10 + commit-message: + prefix: "deps" + prefix-development: "deps(dev)" diff --git a/README.md b/README.md index 4cd2d81..d9d95f2 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,9 @@ # @libp2p/tcp [![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) -[![IRC](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) [![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) [![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p-tcp.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p-tcp) -[![CI](https://img.shields.io/github/workflow/status/libp2p/js-libp2p-interfaces/test%20&%20maybe%20release/master?style=flat-square)](https://github.com/libp2p/js-libp2p-tcp/actions/workflows/js-test-and-release.yml) +[![CI](https://img.shields.io/github/workflow/status/libp2p/js-libp2p-tcp/test%20&%20maybe%20release/master?style=flat-square)](https://github.com/libp2p/js-libp2p-tcp/actions/workflows/js-test-and-release.yml) > Node.js implementation of the TCP module that libp2p uses, which implements the interface-connection and interface-transport interfaces @@ -18,7 +17,7 @@ - [Contribute](#contribute) - [Contribute](#contribute-1) - [License](#license) -- [Contribution](#contribution) +- [Contribute](#contribute-2) ## Install @@ -126,6 +125,6 @@ Licensed under either of - Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) - MIT ([LICENSE-MIT](LICENSE-MIT) / ) -## Contribution +## Contribute Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. diff --git a/package.json b/package.json index d23118f..2338f83 100644 --- a/package.json +++ b/package.json @@ -71,15 +71,15 @@ "release": "patch" }, { - "type": "chore", + "type": "docs", "release": "patch" }, { - "type": "docs", + "type": "test", "release": "patch" }, { - "type": "test", + "type": "deps", "release": "patch" }, { @@ -109,7 +109,11 @@ }, { "type": "docs", - "section": "Trivial Changes" + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" }, { "type": "test", @@ -137,6 +141,7 @@ }, "dependencies": { "@libp2p/interface-connection": "^3.0.2", + "@libp2p/interface-metrics": "^4.0.0", "@libp2p/interface-transport": "^2.0.0", "@libp2p/interfaces": "^3.0.3", "@libp2p/logger": "^2.0.0", @@ -148,7 +153,6 @@ "stream-to-it": "^0.2.2" }, "devDependencies": { - "@libp2p/interface-metrics": "^4.0.0", "@libp2p/interface-mocks": "^8.0.1", "@libp2p/interface-transport-compliance-tests": "^3.0.0", "aegir": "^37.5.3", From 6568f81ec52478e6316599a5564746faec881610 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 22 Nov 2022 10:13:42 +0000 Subject: [PATCH 24/29] chore(release): 6.0.3 [skip ci] ## [6.0.3](https://github.com/libp2p/js-libp2p-tcp/compare/v6.0.2...v6.0.3) (2022-11-22) ### Bug Fixes * make metrics interface a dep instead of a dev dep ([#231](https://github.com/libp2p/js-libp2p-tcp/issues/231)) ([876ca13](https://github.com/libp2p/js-libp2p-tcp/commit/876ca132aa2b307315148628681cddfa0828b3ac)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8928f77..938b86d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [6.0.3](https://github.com/libp2p/js-libp2p-tcp/compare/v6.0.2...v6.0.3) (2022-11-22) + + +### Bug Fixes + +* make metrics interface a dep instead of a dev dep ([#231](https://github.com/libp2p/js-libp2p-tcp/issues/231)) ([876ca13](https://github.com/libp2p/js-libp2p-tcp/commit/876ca132aa2b307315148628681cddfa0828b3ac)) + ## [6.0.2](https://github.com/libp2p/js-libp2p-tcp/compare/v6.0.1...v6.0.2) (2022-11-17) diff --git a/package.json b/package.json index 2338f83..0f33297 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@libp2p/tcp", - "version": "6.0.2", + "version": "6.0.3", "description": "Node.js implementation of the TCP module that libp2p uses, which implements the interface-connection and interface-transport interfaces", "license": "Apache-2.0 OR MIT", "homepage": "https://github.com/libp2p/js-libp2p-tcp#readme", From 6c4c316d080cde679c11a784c22284d6e1912b94 Mon Sep 17 00:00:00 2001 From: Alex Potsides Date: Tue, 22 Nov 2022 14:13:33 +0000 Subject: [PATCH 25/29] fix: use labels to differentiate interfaces for metrics (#230) Instead of inserting the interface address into the metric name, use the metric address as a label prefix for the value being reported. This allows our metric names to be stable even if you don't know the ip/port combo that will be used ahead of time. The tradeoff is the label names may change between restarts if the port number changes, but we have to apply a disambguator somewhere. Depends on: - [ ] https://github.com/libp2p/js-libp2p-prometheus-metrics/pull/6 --- src/index.ts | 11 +++----- src/listener.ts | 60 +++++++++++++++++++++++++------------------ src/socket-to-conn.ts | 8 +++--- 3 files changed, 43 insertions(+), 36 deletions(-) diff --git a/src/index.ts b/src/index.ts index a57d4ef..b15b907 100644 --- a/src/index.ts +++ b/src/index.ts @@ -62,7 +62,6 @@ export interface TCPComponents { export interface TCPMetrics { dialerEvents: CounterGroup - listenerEvents: CounterGroup } class TCP implements Transport { @@ -76,13 +75,9 @@ class TCP implements Transport { if (components.metrics != null) { this.metrics = { - dialerEvents: components.metrics.registerCounterGroup('libp2p_tcp_dialer_errors_total', { + dialerEvents: components.metrics.registerCounterGroup('libp2p_tcp_dialer_events_total', { label: 'event', - help: 'Total count of TCP dialer errors by error type' - }), - listenerEvents: components.metrics.registerCounterGroup('libp2p_tcp_listener_errors_total', { - label: 'event', - help: 'Total count of TCP listener errors by error type' + help: 'Total count of TCP dialer events by type' }) } } @@ -115,7 +110,7 @@ class TCP implements Transport { }) log('new outbound connection %s', maConn.remoteAddr) const conn = await options.upgrader.upgradeOutbound(maConn) - log('outbound connection %s upgraded', maConn.remoteAddr) + log('outbound connection upgraded %s', maConn.remoteAddr) return conn } diff --git a/src/listener.ts b/src/listener.ts index d7611d4..1b13385 100644 --- a/src/listener.ts +++ b/src/listener.ts @@ -11,7 +11,7 @@ import type { MultiaddrConnection, Connection } from '@libp2p/interface-connecti import type { Upgrader, Listener, ListenerEvents } from '@libp2p/interface-transport' import type { Multiaddr } from '@multiformats/multiaddr' import type { TCPCreateListenerOptions } from './index.js' -import type { CounterGroup, Metric, Metrics } from '@libp2p/interface-metrics' +import type { CounterGroup, MetricGroup, Metrics } from '@libp2p/interface-metrics' const log = logger('libp2p:tcp:listener') @@ -39,7 +39,7 @@ const SERVER_STATUS_UP = 1 const SERVER_STATUS_DOWN = 0 export interface TCPListenerMetrics { - status: Metric + status: MetricGroup errors: CounterGroup events: CounterGroup } @@ -52,12 +52,14 @@ export class TCPListener extends EventEmitter implements Listene private readonly connections = new Set() private status: Status = { started: false } private metrics?: TCPListenerMetrics + private addr: string constructor (private readonly context: Context) { super() context.keepAlive = context.keepAlive ?? true + this.addr = 'unknown' this.server = net.createServer(context, this.onSocket.bind(this)) // https://nodejs.org/api/net.html#servermaxconnections @@ -72,49 +74,56 @@ export class TCPListener extends EventEmitter implements Listene if (context.metrics != null) { // we are listening, register metrics for our port const address = this.server.address() - let addr: string if (address == null) { - addr = 'unknown' + this.addr = 'unknown' } else if (typeof address === 'string') { // unix socket - addr = address + this.addr = address } else { - addr = `${address.address}:${address.port}` + this.addr = `${address.address}:${address.port}` } - context.metrics?.registerMetric(`libp2p_tcp_connections_${addr}_total`, { + context.metrics?.registerMetricGroup('libp2p_tcp_inbound_connections_total', { + label: 'address', help: 'Current active connections in TCP listener', calculate: () => { - return this.connections.size + return { + [this.addr]: this.connections.size + } } }) this.metrics = { - status: context.metrics.registerMetric(`libp2p_tcp_${addr}_server_status_info`, { - help: 'Current status of the TCP server' + status: context.metrics.registerMetricGroup('libp2p_tcp_listener_status_info', { + label: 'address', + help: 'Current status of the TCP listener socket' }), - errors: context.metrics.registerCounterGroup(`libp2p_tcp_${addr}_server_errors_total`, { - label: 'error', - help: 'Total count of TCP listener errors by error type' + errors: context.metrics.registerMetricGroup('libp2p_tcp_listener_errors_total', { + label: 'address', + help: 'Total count of TCP listener errors by type' }), - events: context.metrics.registerCounterGroup(`libp2p_tcp_${addr}_socket_events_total`, { - label: 'event', - help: 'Total count of TCP socket events by event' + events: context.metrics.registerMetricGroup('libp2p_tcp_listener_events_total', { + label: 'address', + help: 'Total count of TCP listener events by type' }) } - this.metrics?.status.update(SERVER_STATUS_UP) + this.metrics?.status.update({ + [this.addr]: SERVER_STATUS_UP + }) } this.dispatchEvent(new CustomEvent('listening')) }) .on('error', err => { - this.metrics?.errors.increment({ listen_error: true }) + this.metrics?.errors.increment({ [`${this.addr} listen_error`]: true }) this.dispatchEvent(new CustomEvent('error', { detail: err })) }) .on('close', () => { - this.metrics?.status.update(SERVER_STATUS_DOWN) + this.metrics?.status.update({ + [this.addr]: SERVER_STATUS_DOWN + }) this.dispatchEvent(new CustomEvent('close')) }) } @@ -123,7 +132,7 @@ export class TCPListener extends EventEmitter implements Listene // Avoid uncaught errors caused by unstable connections socket.on('error', err => { log('socket error', err) - this.metrics?.events.increment({ error: true }) + this.metrics?.events.increment({ [`${this.addr} error`]: true }) }) let maConn: MultiaddrConnection @@ -132,11 +141,12 @@ export class TCPListener extends EventEmitter implements Listene listeningAddr: this.status.started ? this.status.listeningAddr : undefined, socketInactivityTimeout: this.context.socketInactivityTimeout, socketCloseTimeout: this.context.socketCloseTimeout, - metrics: this.metrics?.events + metrics: this.metrics?.events, + metricPrefix: `${this.addr} ` }) } catch (err) { log.error('inbound connection failed', err) - this.metrics?.errors.increment({ inbound_to_connection: true }) + this.metrics?.errors.increment({ [`${this.addr} inbound_to_connection`]: true }) return } @@ -144,7 +154,7 @@ export class TCPListener extends EventEmitter implements Listene try { this.context.upgrader.upgradeInbound(maConn) .then((conn) => { - log('inbound connection %s upgraded', maConn.remoteAddr) + log('inbound connection upgraded %s', maConn.remoteAddr) this.connections.add(maConn) socket.once('close', () => { @@ -159,7 +169,7 @@ export class TCPListener extends EventEmitter implements Listene }) .catch(async err => { log.error('inbound connection failed', err) - this.metrics?.errors.increment({ inbound_upgrade: true }) + this.metrics?.errors.increment({ [`${this.addr} inbound_upgrade`]: true }) await attemptClose(maConn) }) @@ -172,7 +182,7 @@ export class TCPListener extends EventEmitter implements Listene attemptClose(maConn) .catch(err => { log.error('closing inbound connection failed', err) - this.metrics?.errors.increment({ inbound_closing_failed: true }) + this.metrics?.errors.increment({ [`${this.addr} inbound_closing_failed`]: true }) }) } } diff --git a/src/socket-to-conn.ts b/src/socket-to-conn.ts index a8230cc..efd7e8a 100644 --- a/src/socket-to-conn.ts +++ b/src/socket-to-conn.ts @@ -21,6 +21,7 @@ interface ToConnectionOptions { socketInactivityTimeout?: number socketCloseTimeout?: number metrics?: CounterGroup + metricPrefix?: string } /** @@ -29,6 +30,7 @@ interface ToConnectionOptions { */ export const toMultiaddrConnection = (socket: Socket, options: ToConnectionOptions) => { const metrics = options.metrics + const metricPrefix = options.metricPrefix ?? '' const inactivityTimeout = options.socketInactivityTimeout ?? SOCKET_TIMEOUT const closeTimeout = options.socketCloseTimeout ?? CLOSE_TIMEOUT @@ -63,7 +65,7 @@ export const toMultiaddrConnection = (socket: Socket, options: ToConnectionOptio // https://nodejs.org/dist/latest-v16.x/docs/api/net.html#socketsettimeouttimeout-callback socket.setTimeout(inactivityTimeout, () => { log('%s socket read timeout', lOptsStr) - metrics?.increment({ timeout: true }) + metrics?.increment({ [`${metricPrefix}timeout`]: true }) // only destroy with an error if the remote has not sent the FIN message let err: Error | undefined @@ -78,7 +80,7 @@ export const toMultiaddrConnection = (socket: Socket, options: ToConnectionOptio socket.once('close', () => { log('%s socket read timeout', lOptsStr) - metrics?.increment({ close: true }) + metrics?.increment({ [`${metricPrefix}close`]: true }) // In instances where `close` was not explicitly called, // such as an iterable stream ending, ensure we have set the close @@ -92,7 +94,7 @@ export const toMultiaddrConnection = (socket: Socket, options: ToConnectionOptio // the remote sent a FIN packet which means no more data will be sent // https://nodejs.org/dist/latest-v16.x/docs/api/net.html#event-end log('socket ended', maConn.remoteAddr.toString()) - metrics?.increment({ end: true }) + metrics?.increment({ [`${metricPrefix}end`]: true }) }) const maConn: MultiaddrConnection = { From 609c9b83c950dffc341888554376e559f07f3443 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 22 Nov 2022 14:18:37 +0000 Subject: [PATCH 26/29] chore(release): 6.0.4 [skip ci] ## [6.0.4](https://github.com/libp2p/js-libp2p-tcp/compare/v6.0.3...v6.0.4) (2022-11-22) ### Bug Fixes * use labels to differentiate interfaces for metrics ([#230](https://github.com/libp2p/js-libp2p-tcp/issues/230)) ([6c4c316](https://github.com/libp2p/js-libp2p-tcp/commit/6c4c316d080cde679c11a784c22284d6e1912b94)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 938b86d..6927203 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [6.0.4](https://github.com/libp2p/js-libp2p-tcp/compare/v6.0.3...v6.0.4) (2022-11-22) + + +### Bug Fixes + +* use labels to differentiate interfaces for metrics ([#230](https://github.com/libp2p/js-libp2p-tcp/issues/230)) ([6c4c316](https://github.com/libp2p/js-libp2p-tcp/commit/6c4c316d080cde679c11a784c22284d6e1912b94)) + ## [6.0.3](https://github.com/libp2p/js-libp2p-tcp/compare/v6.0.2...v6.0.3) (2022-11-22) diff --git a/package.json b/package.json index 0f33297..d417fef 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@libp2p/tcp", - "version": "6.0.3", + "version": "6.0.4", "description": "Node.js implementation of the TCP module that libp2p uses, which implements the interface-connection and interface-transport interfaces", "license": "Apache-2.0 OR MIT", "homepage": "https://github.com/libp2p/js-libp2p-tcp#readme", From 34f688ffe5ef3d8b1e1507d264c871f78a9a0104 Mon Sep 17 00:00:00 2001 From: web3-bot <81333946+web3-bot@users.noreply.github.com> Date: Tue, 6 Dec 2022 10:19:19 +0100 Subject: [PATCH 27/29] sync: update CI config files (#232) * update .github/workflows/js-test-and-release.yml * test: fix tests on node 18 (#234) We need to specify the host name to connect. If we don't it defaults to `localhost` - it seems in node 17+ DNS resolution has changed to return IPv6 addresses by default which causes the connection to fail because the listener has only bound to an IPv4 address. Co-authored-by: web3-bot Co-authored-by: Alex Potsides --- .github/workflows/js-test-and-release.yml | 2 +- test/max-connections.spec.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/js-test-and-release.yml b/.github/workflows/js-test-and-release.yml index ed17349..c6897e3 100644 --- a/.github/workflows/js-test-and-release.yml +++ b/.github/workflows/js-test-and-release.yml @@ -27,7 +27,7 @@ jobs: strategy: matrix: os: [windows-latest, ubuntu-latest, macos-latest] - node: [16] + node: [lts/*] fail-fast: true steps: - uses: actions/checkout@v3 diff --git a/test/max-connections.spec.ts b/test/max-connections.spec.ts index 19f4bbf..24551a0 100644 --- a/test/max-connections.spec.ts +++ b/test/max-connections.spec.ts @@ -18,10 +18,10 @@ describe('maxConnections', () => { const port = 9900 const seenRemoteConnections = new Set() - const trasnport = tcp({ maxConnections })() + const transport = tcp({ maxConnections })() const upgrader = mockUpgrader() - const listener = trasnport.createListener({ upgrader }) + const listener = transport.createListener({ upgrader }) // eslint-disable-next-line @typescript-eslint/promise-function-async afterEachCallbacks.push(() => listener.close()) await listener.listen(multiaddr(`/ip4/127.0.0.1/tcp/${port}`)) @@ -33,7 +33,7 @@ describe('maxConnections', () => { const sockets: net.Socket[] = [] for (let i = 0; i < socketCount; i++) { - const socket = net.connect({ port }) + const socket = net.connect({ host: '127.0.0.1', port }) sockets.push(socket) // eslint-disable-next-line @typescript-eslint/promise-function-async From 72a79ab81d79daaeb8a77656e98a19b70f132595 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Dec 2022 10:19:40 +0100 Subject: [PATCH 28/29] deps(dev): bump sinon from 14.0.2 to 15.0.0 (#233) Bumps [sinon](https://github.com/sinonjs/sinon) from 14.0.2 to 15.0.0. - [Release notes](https://github.com/sinonjs/sinon/releases) - [Changelog](https://github.com/sinonjs/sinon/blob/main/docs/changelog.md) - [Commits](https://github.com/sinonjs/sinon/compare/v14.0.2...v15.0.0) --- updated-dependencies: - dependency-name: sinon dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d417fef..13981f2 100644 --- a/package.json +++ b/package.json @@ -159,7 +159,7 @@ "it-all": "^2.0.0", "it-pipe": "^2.0.3", "p-defer": "^4.0.0", - "sinon": "^14.0.0", + "sinon": "^15.0.0", "uint8arrays": "^4.0.2" } } From 1bfc601382bd501e3b6a10f5a6b6303313cf5d21 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 6 Dec 2022 09:24:04 +0000 Subject: [PATCH 29/29] chore(release): 6.0.5 [skip ci] ## [6.0.5](https://github.com/libp2p/js-libp2p-tcp/compare/v6.0.4...v6.0.5) (2022-12-06) ### Dependencies * **dev:** bump sinon from 14.0.2 to 15.0.0 ([#233](https://github.com/libp2p/js-libp2p-tcp/issues/233)) ([72a79ab](https://github.com/libp2p/js-libp2p-tcp/commit/72a79ab81d79daaeb8a77656e98a19b70f132595)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6927203..a5b691c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [6.0.5](https://github.com/libp2p/js-libp2p-tcp/compare/v6.0.4...v6.0.5) (2022-12-06) + + +### Dependencies + +* **dev:** bump sinon from 14.0.2 to 15.0.0 ([#233](https://github.com/libp2p/js-libp2p-tcp/issues/233)) ([72a79ab](https://github.com/libp2p/js-libp2p-tcp/commit/72a79ab81d79daaeb8a77656e98a19b70f132595)) + ## [6.0.4](https://github.com/libp2p/js-libp2p-tcp/compare/v6.0.3...v6.0.4) (2022-11-22) diff --git a/package.json b/package.json index 13981f2..cbe5619 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@libp2p/tcp", - "version": "6.0.4", + "version": "6.0.5", "description": "Node.js implementation of the TCP module that libp2p uses, which implements the interface-connection and interface-transport interfaces", "license": "Apache-2.0 OR MIT", "homepage": "https://github.com/libp2p/js-libp2p-tcp#readme",