@libp2p/tcp 8.0.13 → 9.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.min.js +1 -5
- package/dist/src/index.d.ts +23 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +25 -19
- package/dist/src/index.js.map +1 -1
- package/dist/src/listener.d.ts +4 -4
- package/dist/src/listener.d.ts.map +1 -1
- package/dist/src/listener.js +31 -24
- package/dist/src/listener.js.map +1 -1
- package/dist/src/socket-to-conn.d.ts +3 -2
- package/dist/src/socket-to-conn.d.ts.map +1 -1
- package/dist/src/socket-to-conn.js +14 -5
- package/dist/src/socket-to-conn.js.map +1 -1
- package/dist/src/utils.js +1 -1
- package/dist/src/utils.js.map +1 -1
- package/package.json +14 -10
- package/src/index.ts +53 -23
- package/src/listener.ts +33 -28
- package/src/socket-to-conn.ts +16 -8
- package/src/utils.ts +1 -1
package/src/listener.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import net from 'net'
|
|
2
|
-
import { CodeError } from '@libp2p/interface
|
|
3
|
-
import { TypedEventEmitter, CustomEvent } from '@libp2p/interface/events'
|
|
4
|
-
import { logger } from '@libp2p/logger'
|
|
2
|
+
import { CodeError, TypedEventEmitter, CustomEvent } from '@libp2p/interface'
|
|
5
3
|
import { CODE_P2P } from './constants.js'
|
|
6
4
|
import { toMultiaddrConnection } from './socket-to-conn.js'
|
|
7
5
|
import {
|
|
@@ -10,21 +8,17 @@ import {
|
|
|
10
8
|
type NetConfig
|
|
11
9
|
} from './utils.js'
|
|
12
10
|
import type { TCPCreateListenerOptions } from './index.js'
|
|
13
|
-
import type { MultiaddrConnection, Connection } from '@libp2p/interface
|
|
14
|
-
import type { CounterGroup, MetricGroup, Metrics } from '@libp2p/interface/metrics'
|
|
15
|
-
import type { Listener, ListenerEvents, Upgrader } from '@libp2p/interface/transport'
|
|
11
|
+
import type { ComponentLogger, Logger, LoggerOptions, MultiaddrConnection, Connection, CounterGroup, MetricGroup, Metrics, Listener, ListenerEvents, Upgrader } from '@libp2p/interface'
|
|
16
12
|
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
17
13
|
|
|
18
|
-
const log = logger('libp2p:tcp:listener')
|
|
19
|
-
|
|
20
14
|
/**
|
|
21
15
|
* Attempts to close the given maConn. If a failure occurs, it will be logged
|
|
22
16
|
*/
|
|
23
|
-
async function attemptClose (maConn: MultiaddrConnection): Promise<void> {
|
|
17
|
+
async function attemptClose (maConn: MultiaddrConnection, options: LoggerOptions): Promise<void> {
|
|
24
18
|
try {
|
|
25
19
|
await maConn.close()
|
|
26
20
|
} catch (err) {
|
|
27
|
-
log.error('an error occurred closing the connection', err)
|
|
21
|
+
options.log.error('an error occurred closing the connection', err)
|
|
28
22
|
}
|
|
29
23
|
}
|
|
30
24
|
|
|
@@ -45,6 +39,7 @@ interface Context extends TCPCreateListenerOptions {
|
|
|
45
39
|
backlog?: number
|
|
46
40
|
metrics?: Metrics
|
|
47
41
|
closeServerOnMaxConnections?: CloseServerOnMaxConnectionsOpts
|
|
42
|
+
logger: ComponentLogger
|
|
48
43
|
}
|
|
49
44
|
|
|
50
45
|
export interface TCPListenerMetrics {
|
|
@@ -78,12 +73,15 @@ export class TCPListener extends TypedEventEmitter<ListenerEvents> implements Li
|
|
|
78
73
|
private status: Status = { code: TCPListenerStatusCode.INACTIVE }
|
|
79
74
|
private metrics?: TCPListenerMetrics
|
|
80
75
|
private addr: string
|
|
76
|
+
private readonly log: Logger
|
|
81
77
|
|
|
82
78
|
constructor (private readonly context: Context) {
|
|
83
79
|
super()
|
|
84
80
|
|
|
85
81
|
context.keepAlive = context.keepAlive ?? true
|
|
82
|
+
context.noDelay = context.noDelay ?? true
|
|
86
83
|
|
|
84
|
+
this.log = context.logger.forComponent('libp2p:tcp:listener')
|
|
87
85
|
this.addr = 'unknown'
|
|
88
86
|
this.server = net.createServer(context, this.onSocket.bind(this))
|
|
89
87
|
|
|
@@ -172,7 +170,7 @@ export class TCPListener extends TypedEventEmitter<ListenerEvents> implements Li
|
|
|
172
170
|
}
|
|
173
171
|
// Avoid uncaught errors caused by unstable connections
|
|
174
172
|
socket.on('error', err => {
|
|
175
|
-
log('socket error', err)
|
|
173
|
+
this.log('socket error', err)
|
|
176
174
|
this.metrics?.events.increment({ [`${this.addr} error`]: true })
|
|
177
175
|
})
|
|
178
176
|
|
|
@@ -183,19 +181,20 @@ export class TCPListener extends TypedEventEmitter<ListenerEvents> implements Li
|
|
|
183
181
|
socketInactivityTimeout: this.context.socketInactivityTimeout,
|
|
184
182
|
socketCloseTimeout: this.context.socketCloseTimeout,
|
|
185
183
|
metrics: this.metrics?.events,
|
|
186
|
-
metricPrefix: `${this.addr}
|
|
184
|
+
metricPrefix: `${this.addr} `,
|
|
185
|
+
logger: this.context.logger
|
|
187
186
|
})
|
|
188
187
|
} catch (err) {
|
|
189
|
-
log.error('inbound connection failed', err)
|
|
188
|
+
this.log.error('inbound connection failed', err)
|
|
190
189
|
this.metrics?.errors.increment({ [`${this.addr} inbound_to_connection`]: true })
|
|
191
190
|
return
|
|
192
191
|
}
|
|
193
192
|
|
|
194
|
-
log('new inbound connection %s', maConn.remoteAddr)
|
|
193
|
+
this.log('new inbound connection %s', maConn.remoteAddr)
|
|
195
194
|
try {
|
|
196
195
|
this.context.upgrader.upgradeInbound(maConn)
|
|
197
196
|
.then((conn) => {
|
|
198
|
-
log('inbound connection upgraded %s', maConn.remoteAddr)
|
|
197
|
+
this.log('inbound connection upgraded %s', maConn.remoteAddr)
|
|
199
198
|
this.connections.add(maConn)
|
|
200
199
|
|
|
201
200
|
socket.once('close', () => {
|
|
@@ -210,7 +209,7 @@ export class TCPListener extends TypedEventEmitter<ListenerEvents> implements Li
|
|
|
210
209
|
// we can do. resume() will be called again every time a connection is dropped, which
|
|
211
210
|
// acts as an eventual retry mechanism. onListenError allows the consumer act on this.
|
|
212
211
|
this.resume().catch(e => {
|
|
213
|
-
log.error('error attempting to listen server once connection count under limit', e)
|
|
212
|
+
this.log.error('error attempting to listen server once connection count under limit', e)
|
|
214
213
|
this.context.closeServerOnMaxConnections?.onListenError?.(e as Error)
|
|
215
214
|
})
|
|
216
215
|
}
|
|
@@ -225,27 +224,31 @@ export class TCPListener extends TypedEventEmitter<ListenerEvents> implements Li
|
|
|
225
224
|
this.connections.size >= this.context.closeServerOnMaxConnections.closeAbove
|
|
226
225
|
) {
|
|
227
226
|
this.pause(false).catch(e => {
|
|
228
|
-
log.error('error attempting to close server once connection count over limit', e)
|
|
227
|
+
this.log.error('error attempting to close server once connection count over limit', e)
|
|
229
228
|
})
|
|
230
229
|
}
|
|
231
230
|
|
|
232
231
|
this.dispatchEvent(new CustomEvent<Connection>('connection', { detail: conn }))
|
|
233
232
|
})
|
|
234
233
|
.catch(async err => {
|
|
235
|
-
log.error('inbound connection failed', err)
|
|
234
|
+
this.log.error('inbound connection failed', err)
|
|
236
235
|
this.metrics?.errors.increment({ [`${this.addr} inbound_upgrade`]: true })
|
|
237
236
|
|
|
238
|
-
await attemptClose(maConn
|
|
237
|
+
await attemptClose(maConn, {
|
|
238
|
+
log: this.log
|
|
239
|
+
})
|
|
239
240
|
})
|
|
240
241
|
.catch(err => {
|
|
241
|
-
log.error('closing inbound connection failed', err)
|
|
242
|
+
this.log.error('closing inbound connection failed', err)
|
|
242
243
|
})
|
|
243
244
|
} catch (err) {
|
|
244
|
-
log.error('inbound connection failed', err)
|
|
245
|
+
this.log.error('inbound connection failed', err)
|
|
245
246
|
|
|
246
|
-
attemptClose(maConn
|
|
247
|
+
attemptClose(maConn, {
|
|
248
|
+
log: this.log
|
|
249
|
+
})
|
|
247
250
|
.catch(err => {
|
|
248
|
-
log.error('closing inbound connection failed', err)
|
|
251
|
+
this.log.error('closing inbound connection failed', err)
|
|
249
252
|
this.metrics?.errors.increment({ [`${this.addr} inbound_closing_failed`]: true })
|
|
250
253
|
})
|
|
251
254
|
}
|
|
@@ -276,7 +279,7 @@ export class TCPListener extends TypedEventEmitter<ListenerEvents> implements Li
|
|
|
276
279
|
addrs = addrs.concat(getMultiaddrs('ip6', address.address, address.port))
|
|
277
280
|
}
|
|
278
281
|
} catch (err) {
|
|
279
|
-
log.error('could not turn %s:%s into multiaddr', address.address, address.port, err)
|
|
282
|
+
this.log.error('could not turn %s:%s into multiaddr', address.address, address.port, err)
|
|
280
283
|
}
|
|
281
284
|
}
|
|
282
285
|
|
|
@@ -310,9 +313,11 @@ export class TCPListener extends TypedEventEmitter<ListenerEvents> implements Li
|
|
|
310
313
|
async close (): Promise<void> {
|
|
311
314
|
// Close connections and server the same time to avoid any race condition
|
|
312
315
|
await Promise.all([
|
|
313
|
-
Promise.all(Array.from(this.connections.values()).map(async maConn => attemptClose(maConn
|
|
316
|
+
Promise.all(Array.from(this.connections.values()).map(async maConn => attemptClose(maConn, {
|
|
317
|
+
log: this.log
|
|
318
|
+
}))),
|
|
314
319
|
this.pause(true).catch(e => {
|
|
315
|
-
log.error('error attempting to close server once connection count over limit', e)
|
|
320
|
+
this.log.error('error attempting to close server once connection count over limit', e)
|
|
316
321
|
})
|
|
317
322
|
])
|
|
318
323
|
}
|
|
@@ -334,7 +339,7 @@ export class TCPListener extends TypedEventEmitter<ListenerEvents> implements Li
|
|
|
334
339
|
})
|
|
335
340
|
|
|
336
341
|
this.status = { ...this.status, code: TCPListenerStatusCode.ACTIVE }
|
|
337
|
-
log('Listening on %s', this.server.address())
|
|
342
|
+
this.log('Listening on %s', this.server.address())
|
|
338
343
|
}
|
|
339
344
|
|
|
340
345
|
private async pause (permanent: boolean): Promise<void> {
|
|
@@ -347,7 +352,7 @@ export class TCPListener extends TypedEventEmitter<ListenerEvents> implements Li
|
|
|
347
352
|
return
|
|
348
353
|
}
|
|
349
354
|
|
|
350
|
-
log('Closing server on %s', this.server.address())
|
|
355
|
+
this.log('Closing server on %s', this.server.address())
|
|
351
356
|
|
|
352
357
|
// NodeJS implementation tracks listening status with `this._handle` property.
|
|
353
358
|
// - Server.close() sets this._handle to null immediately. If this._handle is null, ERR_SERVER_NOT_RUNNING is thrown
|
package/src/socket-to-conn.ts
CHANGED
|
@@ -1,17 +1,13 @@
|
|
|
1
|
-
import { CodeError } from '@libp2p/interface
|
|
2
|
-
import { logger } from '@libp2p/logger'
|
|
1
|
+
import { CodeError } from '@libp2p/interface'
|
|
3
2
|
import { ipPortToMultiaddr as toMultiaddr } from '@libp2p/utils/ip-port-to-multiaddr'
|
|
4
3
|
// @ts-expect-error no types
|
|
5
4
|
import toIterable from 'stream-to-it'
|
|
6
5
|
import { CLOSE_TIMEOUT, SOCKET_TIMEOUT } from './constants.js'
|
|
7
6
|
import { multiaddrToNetConfig } from './utils.js'
|
|
8
|
-
import type { MultiaddrConnection } from '@libp2p/interface
|
|
9
|
-
import type { CounterGroup } from '@libp2p/interface/metrics'
|
|
7
|
+
import type { ComponentLogger, MultiaddrConnection, CounterGroup } from '@libp2p/interface'
|
|
10
8
|
import type { AbortOptions, Multiaddr } from '@multiformats/multiaddr'
|
|
11
9
|
import type { Socket } from 'net'
|
|
12
10
|
|
|
13
|
-
const log = logger('libp2p:tcp:socket')
|
|
14
|
-
|
|
15
11
|
interface ToConnectionOptions {
|
|
16
12
|
listeningAddr?: Multiaddr
|
|
17
13
|
remoteAddr?: Multiaddr
|
|
@@ -20,6 +16,7 @@ interface ToConnectionOptions {
|
|
|
20
16
|
socketCloseTimeout?: number
|
|
21
17
|
metrics?: CounterGroup
|
|
22
18
|
metricPrefix?: string
|
|
19
|
+
logger: ComponentLogger
|
|
23
20
|
}
|
|
24
21
|
|
|
25
22
|
/**
|
|
@@ -27,6 +24,7 @@ interface ToConnectionOptions {
|
|
|
27
24
|
* https://github.com/libp2p/interface-transport#multiaddrconnection
|
|
28
25
|
*/
|
|
29
26
|
export const toMultiaddrConnection = (socket: Socket, options: ToConnectionOptions): MultiaddrConnection => {
|
|
27
|
+
const log = options.logger.forComponent('libp2p:tcp:socket')
|
|
30
28
|
const metrics = options.metrics
|
|
31
29
|
const metricPrefix = options.metricPrefix ?? ''
|
|
32
30
|
const inactivityTimeout = options.socketInactivityTimeout ?? SOCKET_TIMEOUT
|
|
@@ -98,7 +96,15 @@ export const toMultiaddrConnection = (socket: Socket, options: ToConnectionOptio
|
|
|
98
96
|
const maConn: MultiaddrConnection = {
|
|
99
97
|
async sink (source) {
|
|
100
98
|
try {
|
|
101
|
-
await sink(
|
|
99
|
+
await sink((async function * () {
|
|
100
|
+
for await (const buf of source) {
|
|
101
|
+
if (buf instanceof Uint8Array) {
|
|
102
|
+
yield buf
|
|
103
|
+
} else {
|
|
104
|
+
yield buf.subarray()
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
})())
|
|
102
108
|
} catch (err: any) {
|
|
103
109
|
// If aborted we can safely ignore
|
|
104
110
|
if (err.type !== 'aborted') {
|
|
@@ -182,7 +188,9 @@ export const toMultiaddrConnection = (socket: Socket, options: ToConnectionOptio
|
|
|
182
188
|
log('%s socket abort due to error', lOptsStr, err)
|
|
183
189
|
|
|
184
190
|
socket.destroy(err)
|
|
185
|
-
}
|
|
191
|
+
},
|
|
192
|
+
|
|
193
|
+
log
|
|
186
194
|
}
|
|
187
195
|
|
|
188
196
|
return maConn
|
package/src/utils.ts
CHANGED
|
@@ -22,7 +22,7 @@ export function multiaddrToNetConfig (addr: Multiaddr, config: NetConfig = {}):
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
// tcp listening
|
|
25
|
-
return { ...addr.toOptions()
|
|
25
|
+
return { ...config, ...addr.toOptions() }
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
export function getMultiaddrs (proto: 'ip4' | 'ip6', ip: string, port: number): Multiaddr[] {
|