@libp2p/mplex 9.0.12 → 10.0.0-551622a96
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +6 -4
- package/dist/index.min.js +5 -5
- package/dist/src/decode.js.map +1 -1
- package/dist/src/encode.d.ts +2 -1
- package/dist/src/encode.d.ts.map +1 -1
- package/dist/src/encode.js +5 -21
- package/dist/src/encode.js.map +1 -1
- package/dist/src/index.d.ts +5 -13
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +5 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/mplex.d.ts +6 -6
- package/dist/src/mplex.d.ts.map +1 -1
- package/dist/src/mplex.js +32 -25
- package/dist/src/mplex.js.map +1 -1
- package/dist/src/stream.d.ts +3 -1
- package/dist/src/stream.d.ts.map +1 -1
- package/dist/src/stream.js +2 -3
- package/dist/src/stream.js.map +1 -1
- package/package.json +14 -11
- package/src/encode.ts +5 -25
- package/src/index.ts +11 -17
- package/src/mplex.ts +38 -33
- package/src/stream.ts +4 -3
- package/dist/typedoc-urls.json +0 -6
package/src/mplex.ts
CHANGED
@@ -1,23 +1,20 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
import {
|
1
|
+
/* eslint-disable complexity */
|
2
|
+
|
3
|
+
import { CodeError } from '@libp2p/interface'
|
4
|
+
import { closeSource } from '@libp2p/utils/close-source'
|
4
5
|
import { pipe } from 'it-pipe'
|
5
|
-
import { type
|
6
|
+
import { type Pushable, pushable } from 'it-pushable'
|
6
7
|
import { RateLimiterMemory } from 'rate-limiter-flexible'
|
7
8
|
import { toString as uint8ArrayToString } from 'uint8arrays'
|
8
9
|
import { Decoder } from './decode.js'
|
9
10
|
import { encode } from './encode.js'
|
10
11
|
import { MessageTypes, MessageTypeNames, type Message } from './message-types.js'
|
11
12
|
import { createStream, type MplexStream } from './stream.js'
|
12
|
-
import type { MplexInit } from './index.js'
|
13
|
-
import type { AbortOptions } from '@libp2p/interface'
|
14
|
-
import type { Stream } from '@libp2p/interface/connection'
|
15
|
-
import type { StreamMuxer, StreamMuxerInit } from '@libp2p/interface/stream-muxer'
|
13
|
+
import type { MplexComponents, MplexInit } from './index.js'
|
14
|
+
import type { AbortOptions, ComponentLogger, Logger, Stream, StreamMuxer, StreamMuxerInit } from '@libp2p/interface'
|
16
15
|
import type { Sink, Source } from 'it-stream-types'
|
17
16
|
import type { Uint8ArrayList } from 'uint8arraylist'
|
18
17
|
|
19
|
-
const log = logger('libp2p:mplex')
|
20
|
-
|
21
18
|
const MAX_STREAMS_INBOUND_STREAMS_PER_CONNECTION = 1024
|
22
19
|
const MAX_STREAMS_OUTBOUND_STREAMS_PER_CONNECTION = 1024
|
23
20
|
const MAX_STREAM_BUFFER_SIZE = 1024 * 1024 * 4 // 4MB
|
@@ -52,19 +49,23 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
52
49
|
public protocol = '/mplex/6.7.0'
|
53
50
|
|
54
51
|
public sink: Sink<Source<Uint8ArrayList | Uint8Array>, Promise<void>>
|
55
|
-
public source: AsyncGenerator<Uint8Array>
|
52
|
+
public source: AsyncGenerator<Uint8ArrayList | Uint8Array>
|
56
53
|
|
54
|
+
private readonly log: Logger
|
57
55
|
private _streamId: number
|
58
56
|
private readonly _streams: { initiators: Map<number, MplexStream>, receivers: Map<number, MplexStream> }
|
59
57
|
private readonly _init: MplexStreamMuxerInit
|
60
|
-
private readonly _source:
|
58
|
+
private readonly _source: Pushable<Message>
|
61
59
|
private readonly closeController: AbortController
|
62
60
|
private readonly rateLimiter: RateLimiterMemory
|
63
61
|
private readonly closeTimeout: number
|
62
|
+
private readonly logger: ComponentLogger
|
64
63
|
|
65
|
-
constructor (init?: MplexStreamMuxerInit) {
|
64
|
+
constructor (components: MplexComponents, init?: MplexStreamMuxerInit) {
|
66
65
|
init = init ?? {}
|
67
66
|
|
67
|
+
this.log = components.logger.forComponent('libp2p:mplex')
|
68
|
+
this.logger = components.logger
|
68
69
|
this._streamId = 0
|
69
70
|
this._streams = {
|
70
71
|
/**
|
@@ -87,7 +88,7 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
87
88
|
/**
|
88
89
|
* An iterable source
|
89
90
|
*/
|
90
|
-
this._source =
|
91
|
+
this._source = pushable<Message>({
|
91
92
|
objectMode: true,
|
92
93
|
onEnd: (): void => {
|
93
94
|
// the source has ended, we can't write any more messages to gracefully
|
@@ -103,7 +104,7 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
103
104
|
})
|
104
105
|
this.source = pipe(
|
105
106
|
this._source,
|
106
|
-
source => encode(source
|
107
|
+
source => encode(source)
|
107
108
|
)
|
108
109
|
|
109
110
|
/**
|
@@ -199,7 +200,7 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
199
200
|
_newStream (options: { id: number, name: string, type: 'initiator' | 'receiver', registry: Map<number, MplexStream> }): MplexStream {
|
200
201
|
const { id, name, type, registry } = options
|
201
202
|
|
202
|
-
log('new %s stream %s', type, id)
|
203
|
+
this.log('new %s stream %s', type, id)
|
203
204
|
|
204
205
|
if (type === 'initiator' && this._streams.initiators.size === (this._init.maxOutboundStreams ?? MAX_STREAMS_OUTBOUND_STREAMS_PER_CONNECTION)) {
|
205
206
|
throw new CodeError('Too many outbound streams open', 'ERR_TOO_MANY_OUTBOUND_STREAMS')
|
@@ -210,15 +211,15 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
210
211
|
}
|
211
212
|
|
212
213
|
const send = async (msg: Message): Promise<void> => {
|
213
|
-
if (log.enabled) {
|
214
|
-
log.trace('%s stream %s send', type, id, printMessage(msg))
|
214
|
+
if (this.log.enabled) {
|
215
|
+
this.log.trace('%s stream %s send', type, id, printMessage(msg))
|
215
216
|
}
|
216
217
|
|
217
218
|
this._source.push(msg)
|
218
219
|
}
|
219
220
|
|
220
221
|
const onEnd = (): void => {
|
221
|
-
log('%s stream with id %s and protocol %s ended', type, id, stream.protocol)
|
222
|
+
this.log('%s stream with id %s and protocol %s ended', type, id, stream.protocol)
|
222
223
|
registry.delete(id)
|
223
224
|
|
224
225
|
if (this._init.onStreamEnd != null) {
|
@@ -226,7 +227,7 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
226
227
|
}
|
227
228
|
}
|
228
229
|
|
229
|
-
const stream = createStream({ id, name, send, type, onEnd, maxMsgSize: this._init.maxMsgSize })
|
230
|
+
const stream = createStream({ id, name, send, type, onEnd, maxMsgSize: this._init.maxMsgSize, logger: this.logger })
|
230
231
|
registry.set(id, stream)
|
231
232
|
return stream
|
232
233
|
}
|
@@ -237,11 +238,13 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
237
238
|
*/
|
238
239
|
_createSink (): Sink<Source<Uint8ArrayList | Uint8Array>, Promise<void>> {
|
239
240
|
const sink: Sink<Source<Uint8ArrayList | Uint8Array>, Promise<void>> = async source => {
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
241
|
+
const abortListener = (): void => {
|
242
|
+
closeSource(source, this.log)
|
243
|
+
}
|
244
|
+
|
245
|
+
this.closeController.signal.addEventListener('abort', abortListener)
|
244
246
|
|
247
|
+
try {
|
245
248
|
const decoder = new Decoder(this._init.maxMsgSize, this._init.maxUnprocessedMessageQueueSize)
|
246
249
|
|
247
250
|
for await (const chunk of source) {
|
@@ -252,8 +255,10 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
252
255
|
|
253
256
|
this._source.end()
|
254
257
|
} catch (err: any) {
|
255
|
-
log('error in sink', err)
|
258
|
+
this.log('error in sink', err)
|
256
259
|
this._source.end(err) // End the source with an error
|
260
|
+
} finally {
|
261
|
+
this.closeController.signal.removeEventListener('abort', abortListener)
|
257
262
|
}
|
258
263
|
}
|
259
264
|
|
@@ -263,14 +268,14 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
263
268
|
async _handleIncoming (message: Message): Promise<void> {
|
264
269
|
const { id, type } = message
|
265
270
|
|
266
|
-
if (log.enabled) {
|
267
|
-
log.trace('incoming message', printMessage(message))
|
271
|
+
if (this.log.enabled) {
|
272
|
+
this.log.trace('incoming message', printMessage(message))
|
268
273
|
}
|
269
274
|
|
270
275
|
// Create a new stream?
|
271
276
|
if (message.type === MessageTypes.NEW_STREAM) {
|
272
277
|
if (this._streams.receivers.size === (this._init.maxInboundStreams ?? MAX_STREAMS_INBOUND_STREAMS_PER_CONNECTION)) {
|
273
|
-
log('too many inbound streams open')
|
278
|
+
this.log('too many inbound streams open')
|
274
279
|
|
275
280
|
// not going to allow this stream, send the reset message manually
|
276
281
|
// instead of setting it up just to tear it down
|
@@ -285,7 +290,7 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
285
290
|
try {
|
286
291
|
await this.rateLimiter.consume('new-stream', 1)
|
287
292
|
} catch {
|
288
|
-
log('rate limit hit when opening too many new streams over the inbound stream limit - closing remote connection')
|
293
|
+
this.log('rate limit hit when opening too many new streams over the inbound stream limit - closing remote connection')
|
289
294
|
// since there's no backpressure in mplex, the only thing we can really do to protect ourselves is close the connection
|
290
295
|
this.abort(new Error('Too many open streams'))
|
291
296
|
return
|
@@ -307,7 +312,7 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
307
312
|
const stream = list.get(id)
|
308
313
|
|
309
314
|
if (stream == null) {
|
310
|
-
log('missing stream %s for message type %s', id, MessageTypeNames[type])
|
315
|
+
this.log('missing stream %s for message type %s', id, MessageTypeNames[type])
|
311
316
|
|
312
317
|
// if the remote keeps sending us messages for streams that have been
|
313
318
|
// closed or were never opened they may be attacking us so if they do
|
@@ -315,7 +320,7 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
315
320
|
try {
|
316
321
|
await this.rateLimiter.consume('missing-stream', 1)
|
317
322
|
} catch {
|
318
|
-
log('rate limit hit when receiving messages for streams that do not exist - closing remote connection')
|
323
|
+
this.log('rate limit hit when receiving messages for streams that do not exist - closing remote connection')
|
319
324
|
// since there's no backpressure in mplex, the only thing we can really do to protect ourselves is close the connection
|
320
325
|
this.abort(new Error('Too many messages for missing streams'))
|
321
326
|
return
|
@@ -355,10 +360,10 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
355
360
|
stream.reset()
|
356
361
|
break
|
357
362
|
default:
|
358
|
-
log('unknown message type %s', type)
|
363
|
+
this.log('unknown message type %s', type)
|
359
364
|
}
|
360
365
|
} catch (err: any) {
|
361
|
-
log.error('error while processing message', err)
|
366
|
+
this.log.error('error while processing message', err)
|
362
367
|
stream.abort(err)
|
363
368
|
}
|
364
369
|
}
|
package/src/stream.ts
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
import { AbstractStream, type AbstractStreamInit } from '@libp2p/
|
2
|
-
import { logger } from '@libp2p/logger'
|
1
|
+
import { AbstractStream, type AbstractStreamInit } from '@libp2p/utils/abstract-stream'
|
3
2
|
import { Uint8ArrayList } from 'uint8arraylist'
|
4
3
|
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
|
5
4
|
import { MAX_MSG_SIZE } from './decode.js'
|
6
5
|
import { InitiatorMessageTypes, ReceiverMessageTypes } from './message-types.js'
|
7
6
|
import type { Message } from './message-types.js'
|
7
|
+
import type { ComponentLogger } from '@libp2p/interface'
|
8
8
|
|
9
9
|
export interface Options {
|
10
10
|
id: number
|
@@ -13,6 +13,7 @@ export interface Options {
|
|
13
13
|
onEnd?(err?: Error): void
|
14
14
|
type?: 'initiator' | 'receiver'
|
15
15
|
maxMsgSize?: number
|
16
|
+
logger: ComponentLogger
|
16
17
|
}
|
17
18
|
|
18
19
|
interface MplexStreamInit extends AbstractStreamInit {
|
@@ -87,6 +88,6 @@ export function createStream (options: Options): MplexStream {
|
|
87
88
|
maxDataSize: maxMsgSize,
|
88
89
|
onEnd,
|
89
90
|
send,
|
90
|
-
log: logger(`libp2p:mplex:stream:${type}:${id}`)
|
91
|
+
log: options.logger.forComponent(`libp2p:mplex:stream:${type}:${id}`)
|
91
92
|
})
|
92
93
|
}
|
package/dist/typedoc-urls.json
DELETED
@@ -1,6 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"MplexInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_mplex.MplexInit.html",
|
3
|
-
".:MplexInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_mplex.MplexInit.html",
|
4
|
-
"mplex": "https://libp2p.github.io/js-libp2p/functions/_libp2p_mplex.mplex.html",
|
5
|
-
".:mplex": "https://libp2p.github.io/js-libp2p/functions/_libp2p_mplex.mplex.html"
|
6
|
-
}
|