Skip to content

Commit f465c54

Browse files
authored
fix: add inbound upgrade timeout config option (#2995)
Similar to other transports, this lets us close the connection if encryption/muxer negotiation takes too long. Defaults to 10s.
1 parent 5b084e9 commit f465c54

File tree

5 files changed

+28
-2
lines changed

5 files changed

+28
-2
lines changed

packages/transport-tcp/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
"@multiformats/mafmt": "^12.1.6",
6666
"@multiformats/multiaddr": "^12.3.3",
6767
"@types/sinon": "^17.0.3",
68+
"any-signal": "^4.1.1",
6869
"p-defer": "^4.0.1",
6970
"p-event": "^6.0.1",
7071
"progress-events": "^1.0.1",

packages/transport-tcp/src/constants.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,6 @@ export const CLOSE_TIMEOUT = 500
88

99
// Close the socket if there is no activity after this long in ms
1010
export const SOCKET_TIMEOUT = 2 * 60000 // 2 mins
11+
12+
// Inbound connection upgrades must complete within this many ms
13+
export const INBOUND_UPGRADE_TIMEOUT = 10_000

packages/transport-tcp/src/index.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,14 @@ export interface TCPOptions {
7878
* Options passed to every `net.createServer` for every TCP server
7979
*/
8080
listenOpts?: TCPSocketOptions
81+
82+
/**
83+
* Upgrading an inbound connection must happen within this many ms otherwise
84+
* the connection will be closed.
85+
*
86+
* @default 10_000
87+
*/
88+
inboundUpgradeTimeout?: number
8189
}
8290

8391
/**

packages/transport-tcp/src/listener.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import net from 'net'
22
import { AlreadyStartedError, InvalidParametersError, NotStartedError, TypedEventEmitter, setMaxListeners } from '@libp2p/interface'
3+
import { anySignal } from 'any-signal'
34
import { pEvent } from 'p-event'
4-
import { CODE_P2P } from './constants.js'
5+
import { CODE_P2P, INBOUND_UPGRADE_TIMEOUT } from './constants.js'
56
import { toMultiaddrConnection } from './socket-to-conn.js'
67
import {
78
getMultiaddrs,
@@ -31,6 +32,7 @@ export interface CloseServerOnMaxConnectionsOpts {
3132

3233
interface Context extends TCPCreateListenerOptions {
3334
upgrader: Upgrader
35+
inboundUpgradeTimeout?: number
3436
socketInactivityTimeout?: number
3537
socketCloseTimeout?: number
3638
maxConnections?: number
@@ -74,6 +76,7 @@ export class TCPListener extends TypedEventEmitter<ListenerEvents> implements Li
7476
private addr: string
7577
private readonly log: Logger
7678
private readonly shutdownController: AbortController
79+
private readonly inboundUpgradeTimeout: number
7780

7881
constructor (private readonly context: Context) {
7982
super()
@@ -85,6 +88,7 @@ export class TCPListener extends TypedEventEmitter<ListenerEvents> implements Li
8588
setMaxListeners(Infinity, this.shutdownController.signal)
8689

8790
this.log = context.logger.forComponent('libp2p:tcp:listener')
91+
this.inboundUpgradeTimeout = context.inboundUpgradeTimeout ?? INBOUND_UPGRADE_TIMEOUT
8892
this.addr = 'unknown'
8993
this.server = net.createServer(context, this.onSocket.bind(this))
9094

@@ -201,8 +205,14 @@ export class TCPListener extends TypedEventEmitter<ListenerEvents> implements Li
201205
this.log('new inbound connection %s', maConn.remoteAddr)
202206
this.sockets.add(socket)
203207

208+
const signal = anySignal([
209+
this.shutdownController.signal,
210+
AbortSignal.timeout(this.inboundUpgradeTimeout)
211+
])
212+
setMaxListeners(Infinity, signal)
213+
204214
this.context.upgrader.upgradeInbound(maConn, {
205-
signal: this.shutdownController.signal
215+
signal
206216
})
207217
.then(() => {
208218
this.log('inbound connection upgraded %s', maConn.remoteAddr)
@@ -240,6 +250,9 @@ export class TCPListener extends TypedEventEmitter<ListenerEvents> implements Li
240250
this.sockets.delete(socket)
241251
maConn.abort(err)
242252
})
253+
.finally(() => {
254+
signal.clear()
255+
})
243256
}
244257

245258
getAddrs (): Multiaddr[] {

packages/transport-tcp/src/tcp.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ export class TCP implements Transport<TCPDialEvents> {
192192
return new TCPListener({
193193
...(this.opts.listenOpts ?? {}),
194194
...options,
195+
inboundUpgradeTimeout: this.opts.inboundUpgradeTimeout,
195196
maxConnections: this.opts.maxConnections,
196197
backlog: this.opts.backlog,
197198
closeServerOnMaxConnections: this.opts.closeServerOnMaxConnections,

0 commit comments

Comments
 (0)