@libp2p/mplex 5.1.0 → 5.2.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 -0
- package/dist/src/encode.js +1 -1
- package/dist/src/encode.js.map +1 -1
- package/dist/src/index.d.ts +12 -4
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/mplex.d.ts +2 -1
- package/dist/src/mplex.d.ts.map +1 -1
- package/dist/src/mplex.js +28 -10
- package/dist/src/mplex.js.map +1 -1
- package/package.json +3 -2
- package/src/encode.ts +1 -1
- package/src/index.ts +13 -4
- package/src/mplex.ts +31 -11
package/README.md
CHANGED
@@ -73,6 +73,7 @@ Creates a factory that can be used to create new muxers.
|
|
73
73
|
- `maxInboundStreams` - a number that defines how many incoming streams are allowed per connection (default: 1024)
|
74
74
|
- `maxOutboundStreams` - a number that defines how many outgoing streams are allowed per connection (default: 1024)
|
75
75
|
- `maxStreamBufferSize` - a number that defines how large the message buffer is allowed to grow (default: 1024 \* 1024 \* 4 - e.g. 4MB)
|
76
|
+
- `disconnectThreshold` - if `maxInboundStreams` is reached, close the connection if the remote continues trying to open more than this many streams per second (default: 5)
|
76
77
|
|
77
78
|
### `const muxer = factory.createStreamMuxer(components, [options])`
|
78
79
|
|
package/dist/src/encode.js
CHANGED
@@ -33,7 +33,7 @@ class Encoder {
|
|
33
33
|
if ((msg.type === MessageTypes.NEW_STREAM || msg.type === MessageTypes.MESSAGE_INITIATOR || msg.type === MessageTypes.MESSAGE_RECEIVER) && msg.data != null) {
|
34
34
|
return [
|
35
35
|
header,
|
36
|
-
msg.data instanceof Uint8Array ? msg.data : msg.data
|
36
|
+
...(msg.data instanceof Uint8Array ? [msg.data] : msg.data)
|
37
37
|
];
|
38
38
|
}
|
39
39
|
return [
|
package/dist/src/encode.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"encode.js","sourceRoot":"","sources":["../../src/encode.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,QAAQ,CAAA;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAW,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAE1D,MAAM,SAAS,GAAG,EAAE,GAAG,IAAI,CAAA;AAE3B,MAAM,OAAO;IAIX;QACE,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,SAAS,CAAC,CAAA;QACnC,IAAI,CAAC,WAAW,GAAG,CAAC,CAAA;IACtB,CAAC;IAED;;OAEG;IACH,KAAK,CAAE,GAAY;QACjB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAA;QACvB,IAAI,MAAM,GAAG,IAAI,CAAC,WAAW,CAAA;QAE7B,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;QACnD,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAA;QAE7B,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,YAAY,CAAC,UAAU,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,CAAC,iBAAiB,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,CAAC,gBAAgB,CAAC,IAAI,GAAG,CAAC,IAAI,IAAI,IAAI,EAAE;YAC3J,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;SAC7C;aAAM;YACL,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;SAC/B;QAED,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAA;QAE7B,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;QAEtD,IAAI,SAAS,GAAG,MAAM,GAAG,GAAG,EAAE;YAC5B,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,SAAS,CAAC,CAAA;YACnC,IAAI,CAAC,WAAW,GAAG,CAAC,CAAA;SACrB;aAAM;YACL,IAAI,CAAC,WAAW,GAAG,MAAM,CAAA;SAC1B;QAED,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,YAAY,CAAC,UAAU,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,CAAC,iBAAiB,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,CAAC,gBAAgB,CAAC,IAAI,GAAG,CAAC,IAAI,IAAI,IAAI,EAAE;YAC3J,OAAO;gBACL,MAAM;gBACN,GAAG,CAAC,IAAI,YAAY,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC
|
1
|
+
{"version":3,"file":"encode.js","sourceRoot":"","sources":["../../src/encode.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,QAAQ,CAAA;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAW,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAE1D,MAAM,SAAS,GAAG,EAAE,GAAG,IAAI,CAAA;AAE3B,MAAM,OAAO;IAIX;QACE,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,SAAS,CAAC,CAAA;QACnC,IAAI,CAAC,WAAW,GAAG,CAAC,CAAA;IACtB,CAAC;IAED;;OAEG;IACH,KAAK,CAAE,GAAY;QACjB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAA;QACvB,IAAI,MAAM,GAAG,IAAI,CAAC,WAAW,CAAA;QAE7B,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;QACnD,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAA;QAE7B,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,YAAY,CAAC,UAAU,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,CAAC,iBAAiB,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,CAAC,gBAAgB,CAAC,IAAI,GAAG,CAAC,IAAI,IAAI,IAAI,EAAE;YAC3J,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;SAC7C;aAAM;YACL,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;SAC/B;QAED,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAA;QAE7B,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;QAEtD,IAAI,SAAS,GAAG,MAAM,GAAG,GAAG,EAAE;YAC5B,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,SAAS,CAAC,CAAA;YACnC,IAAI,CAAC,WAAW,GAAG,CAAC,CAAA;SACrB;aAAM;YACL,IAAI,CAAC,WAAW,GAAG,MAAM,CAAA;SAC1B;QAED,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,YAAY,CAAC,UAAU,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,CAAC,iBAAiB,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,CAAC,gBAAgB,CAAC,IAAI,GAAG,CAAC,IAAI,IAAI,IAAI,EAAE;YAC3J,OAAO;gBACL,MAAM;gBACN,GAAG,CAAC,GAAG,CAAC,IAAI,YAAY,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;aAC5D,CAAA;SACF;QAED,OAAO;YACL,MAAM;SACP,CAAA;IACH,CAAC;CACF;AAED,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAA;AAE7B;;GAEG;AACH,MAAM,CAAC,KAAK,SAAU,CAAC,CAAC,MAAM,CAAE,MAAmC;IACjE,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,MAAM,EAAE;QAC9B,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;YACtB,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE;gBACnB,KAAM,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;aACzB;SACF;aAAM;YACL,KAAM,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;SAC3B;KACF;AACH,CAAC"}
|
package/dist/src/index.d.ts
CHANGED
@@ -4,25 +4,33 @@ export interface MplexInit {
|
|
4
4
|
/**
|
5
5
|
* The maximum size of message that can be sent in one go in bytes.
|
6
6
|
* Messages larger than this will be split into multiple smaller
|
7
|
-
* messages
|
7
|
+
* messages (default: 1MB)
|
8
8
|
*/
|
9
9
|
maxMsgSize?: number;
|
10
10
|
/**
|
11
11
|
* The maximum number of multiplexed streams that can be open at any
|
12
|
-
* one time.
|
12
|
+
* one time. A request to open more than this will have a stream
|
13
|
+
* reset message sent immediately as a response for the newly opened
|
14
|
+
* stream id (default: 1024)
|
13
15
|
*/
|
14
16
|
maxInboundStreams?: number;
|
15
17
|
/**
|
16
18
|
* The maximum number of multiplexed streams that can be open at any
|
17
|
-
* one time. An attempt to open more than this will throw
|
19
|
+
* one time. An attempt to open more than this will throw (default: 1024)
|
18
20
|
*/
|
19
21
|
maxOutboundStreams?: number;
|
20
22
|
/**
|
21
23
|
* Incoming stream messages are buffered until processed by the stream
|
22
24
|
* handler. If the buffer reaches this size in bytes the stream will
|
23
|
-
* be reset
|
25
|
+
* be reset (default: 4MB)
|
24
26
|
*/
|
25
27
|
maxStreamBufferSize?: number;
|
28
|
+
/**
|
29
|
+
* When `maxInboundStreams` is hit, if the remote continues try to open
|
30
|
+
* more than this many new multiplexed streams per second the connection
|
31
|
+
* will be closed (default: 5)
|
32
|
+
*/
|
33
|
+
disconnectThreshold?: number;
|
26
34
|
}
|
27
35
|
export declare class Mplex implements StreamMuxerFactory, Initializable {
|
28
36
|
protocol: string;
|
package/dist/src/index.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAGtG,MAAM,WAAW,SAAS;IACxB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAGtG,MAAM,WAAW,SAAS;IACxB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAE1B;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAE3B;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAE5B;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAC7B;AAED,qBAAa,KAAM,YAAW,kBAAkB,EAAE,aAAa;IACtD,QAAQ,SAAiB;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAW;IACjC,OAAO,CAAC,UAAU,CAA+B;gBAEpC,IAAI,GAAE,SAAc;IAIjC,IAAI,CAAE,UAAU,EAAE,UAAU,GAAG,IAAI;IAInC,iBAAiB,CAAE,IAAI,GAAE,eAAoB,GAAG,WAAW;CAM5D"}
|
package/dist/src/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAiB,MAAM,oBAAoB,CAAA;AAE9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAiB,MAAM,oBAAoB,CAAA;AAE9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAuC7C,MAAM,OAAO,KAAK;IAKhB,YAAa,OAAkB,EAAE;QAJ1B,aAAQ,GAAG,cAAc,CAAA;QAExB,eAAU,GAAe,IAAI,UAAU,EAAE,CAAA;QAG/C,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;IACnB,CAAC;IAED,IAAI,CAAE,UAAsB;QAC1B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;IAC9B,CAAC;IAED,iBAAiB,CAAE,OAAwB,EAAE;QAC3C,OAAO,IAAI,gBAAgB,CAAC,IAAI,CAAC,UAAU,EAAE;YAC3C,GAAG,IAAI;YACP,GAAG,IAAI,CAAC,KAAK;SACd,CAAC,CAAA;IACJ,CAAC;CACF"}
|
package/dist/src/mplex.d.ts
CHANGED
@@ -20,6 +20,7 @@ export declare class MplexStreamMuxer implements StreamMuxer {
|
|
20
20
|
private readonly _init;
|
21
21
|
private readonly _source;
|
22
22
|
private readonly closeController;
|
23
|
+
private readonly rateLimiter;
|
23
24
|
constructor(components: Components, init?: MplexStreamMuxerInit);
|
24
25
|
init(components: Components): void;
|
25
26
|
/**
|
@@ -64,7 +65,7 @@ export declare class MplexStreamMuxer implements StreamMuxer {
|
|
64
65
|
done: boolean;
|
65
66
|
};
|
66
67
|
};
|
67
|
-
_handleIncoming(message: Message): void
|
68
|
+
_handleIncoming(message: Message): Promise<void>;
|
68
69
|
}
|
69
70
|
export {};
|
70
71
|
//# sourceMappingURL=mplex.d.ts.map
|
package/dist/src/mplex.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"mplex.d.ts","sourceRoot":"","sources":["../../src/mplex.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAa,MAAM,aAAa,CAAA;AAKjD,OAAO,EAAkC,OAAO,EAAE,MAAM,oBAAoB,CAAA;
|
1
|
+
{"version":3,"file":"mplex.d.ts","sourceRoot":"","sources":["../../src/mplex.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAa,MAAM,aAAa,CAAA;AAKjD,OAAO,EAAkC,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAO5E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAClF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAA;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAE3C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AA0BpD,MAAM,WAAW,WAAY,SAAQ,MAAM;IACzC,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAA;CACjC;AAED,UAAU,oBAAqB,SAAQ,SAAS,EAAE,eAAe;CAAG;AAEpE,qBAAa,gBAAiB,YAAW,WAAW;IAC3C,QAAQ,SAAiB;IAEzB,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,CAAA;IACtB,MAAM,EAAE,aAAa,CAAC,UAAU,CAAC,CAAA;IAExC,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA+E;IACxG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAsB;IAC5C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8D;IACtF,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiB;IACjD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAmB;gBAElC,UAAU,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,oBAAoB;IAuChE,IAAI,CAAE,UAAU,EAAE,UAAU;IAE5B;;OAEG;IACH,IAAI,OAAO,aAWV;IAED;;;OAGG;IACH,SAAS,CAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM;IAUjC;;OAEG;IACH,KAAK,CAAE,GAAG,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,IAAI;IAWrC;;OAEG;IACH,kBAAkB,CAAE,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;IAMzD,UAAU,CAAE,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,WAAW,GAAG,UAAU,CAAC;QAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;KAAE;IAmCrH;;;OAGG;IACH,WAAW;IA+BX;;;OAGG;IACH,aAAa;;;;;;;IAgBP,eAAe,CAAE,OAAO,EAAE,OAAO;CAwFxC"}
|
package/dist/src/mplex.js
CHANGED
@@ -10,11 +10,13 @@ import { toString as uint8ArrayToString } from 'uint8arrays';
|
|
10
10
|
import { trackedMap } from '@libp2p/tracked-map';
|
11
11
|
import { logger } from '@libp2p/logger';
|
12
12
|
import errCode from 'err-code';
|
13
|
+
import { RateLimiterMemory } from 'rate-limiter-flexible';
|
13
14
|
import anySignal from 'any-signal';
|
14
15
|
const log = logger('libp2p:mplex');
|
15
16
|
const MAX_STREAMS_INBOUND_STREAMS_PER_CONNECTION = 1024;
|
16
17
|
const MAX_STREAMS_OUTBOUND_STREAMS_PER_CONNECTION = 1024;
|
17
18
|
const MAX_STREAM_BUFFER_SIZE = 1024 * 1024 * 4; // 4MB
|
19
|
+
const DISCONNECT_THRESHOLD = 5;
|
18
20
|
function printMessage(msg) {
|
19
21
|
const output = {
|
20
22
|
...msg,
|
@@ -58,6 +60,10 @@ export class MplexStreamMuxer {
|
|
58
60
|
* Close controller
|
59
61
|
*/
|
60
62
|
this.closeController = new AbortController();
|
63
|
+
this.rateLimiter = new RateLimiterMemory({
|
64
|
+
points: init.disconnectThreshold ?? DISCONNECT_THRESHOLD,
|
65
|
+
duration: 1
|
66
|
+
});
|
61
67
|
}
|
62
68
|
init(components) { }
|
63
69
|
/**
|
@@ -66,12 +72,12 @@ export class MplexStreamMuxer {
|
|
66
72
|
get streams() {
|
67
73
|
// Inbound and Outbound streams may have the same ids, so we need to make those unique
|
68
74
|
const streams = [];
|
69
|
-
this._streams.initiators.
|
75
|
+
for (const stream of this._streams.initiators.values()) {
|
70
76
|
streams.push(stream);
|
71
|
-
}
|
72
|
-
this._streams.receivers.
|
77
|
+
}
|
78
|
+
for (const stream of this._streams.receivers.values()) {
|
73
79
|
streams.push(stream);
|
74
|
-
}
|
80
|
+
}
|
75
81
|
return streams;
|
76
82
|
}
|
77
83
|
/**
|
@@ -111,7 +117,7 @@ export class MplexStreamMuxer {
|
|
111
117
|
}
|
112
118
|
_newStream(options) {
|
113
119
|
const { id, name, type, registry } = options;
|
114
|
-
log('new %s stream %s %s', type, id
|
120
|
+
log('new %s stream %s %s', type, id);
|
115
121
|
if (type === 'initiator' && this._streams.initiators.size === (this._init.maxOutboundStreams ?? MAX_STREAMS_OUTBOUND_STREAMS_PER_CONNECTION)) {
|
116
122
|
throw errCode(new Error('Too many outbound streams open'), 'ERR_TOO_MANY_OUTBOUND_STREAMS');
|
117
123
|
}
|
@@ -125,7 +131,7 @@ export class MplexStreamMuxer {
|
|
125
131
|
this._source.push(msg);
|
126
132
|
};
|
127
133
|
const onEnd = () => {
|
128
|
-
log('%s stream %s ended', type, id,
|
134
|
+
log('%s stream with id %s and protocol %s ended', type, id, stream.stat.protocol);
|
129
135
|
registry.delete(id);
|
130
136
|
if (this._init.onStreamEnd != null) {
|
131
137
|
this._init.onStreamEnd(stream);
|
@@ -150,7 +156,7 @@ export class MplexStreamMuxer {
|
|
150
156
|
try {
|
151
157
|
await pipe(source, decode, restrictSize(this._init.maxMsgSize), async (source) => {
|
152
158
|
for await (const msg of source) {
|
153
|
-
this._handleIncoming(msg);
|
159
|
+
await this._handleIncoming(msg);
|
154
160
|
}
|
155
161
|
});
|
156
162
|
this._source.end();
|
@@ -180,7 +186,7 @@ export class MplexStreamMuxer {
|
|
180
186
|
return: source.return
|
181
187
|
});
|
182
188
|
}
|
183
|
-
_handleIncoming(message) {
|
189
|
+
async _handleIncoming(message) {
|
184
190
|
const { id, type } = message;
|
185
191
|
if (log.enabled) {
|
186
192
|
log.trace('incoming message', printMessage(message));
|
@@ -188,13 +194,25 @@ export class MplexStreamMuxer {
|
|
188
194
|
// Create a new stream?
|
189
195
|
if (message.type === MessageTypes.NEW_STREAM) {
|
190
196
|
if (this._streams.receivers.size === (this._init.maxInboundStreams ?? MAX_STREAMS_INBOUND_STREAMS_PER_CONNECTION)) {
|
191
|
-
log
|
197
|
+
log('too many inbound streams open');
|
192
198
|
// not going to allow this stream, send the reset message manually
|
193
199
|
// instead of setting it up just to tear it down
|
194
200
|
this._source.push({
|
195
201
|
id,
|
196
202
|
type: MessageTypes.RESET_RECEIVER
|
197
203
|
});
|
204
|
+
// if we've hit our stream limit, and the remote keeps trying to open
|
205
|
+
// more new streams, if they are doing this very quickly maybe they
|
206
|
+
// are attacking us and we should close the connection
|
207
|
+
try {
|
208
|
+
await this.rateLimiter.consume('new-stream', 1);
|
209
|
+
}
|
210
|
+
catch {
|
211
|
+
log('rate limit hit when opening too many new streams over the inbound stream limit - closing remote connection');
|
212
|
+
// since there's no backpressure in mplex, the only thing we can really do to protect ourselves is close the connection
|
213
|
+
this._source.end(new Error('Too many open streams'));
|
214
|
+
return;
|
215
|
+
}
|
198
216
|
return;
|
199
217
|
}
|
200
218
|
const stream = this._newReceiverStream({ id, name: uint8ArrayToString(message.data instanceof Uint8Array ? message.data : message.data.subarray()) });
|
@@ -206,7 +224,7 @@ export class MplexStreamMuxer {
|
|
206
224
|
const list = (type & 1) === 1 ? this._streams.initiators : this._streams.receivers;
|
207
225
|
const stream = list.get(id);
|
208
226
|
if (stream == null) {
|
209
|
-
log('missing stream %s', id);
|
227
|
+
log('missing stream %s for message type %s', id, MessageTypeNames[type]);
|
210
228
|
return;
|
211
229
|
}
|
212
230
|
const maxBufferSize = this._init.maxStreamBufferSize ?? MAX_STREAM_BUFFER_SIZE;
|
package/dist/src/mplex.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"mplex.js","sourceRoot":"","sources":["../../src/mplex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AAC9B,OAAO,EAAY,SAAS,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAW,MAAM,oBAAoB,CAAA;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAE,QAAQ,IAAI,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AACvC,OAAO,OAAO,MAAM,UAAU,CAAA;
|
1
|
+
{"version":3,"file":"mplex.js","sourceRoot":"","sources":["../../src/mplex.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@libp2p/mplex",
|
3
|
-
"version": "5.
|
3
|
+
"version": "5.2.0",
|
4
4
|
"description": "JavaScript implementation of https://github.com/libp2p/mplex",
|
5
5
|
"license": "Apache-2.0 OR MIT",
|
6
6
|
"homepage": "https://github.com/libp2p/js-libp2p-mplex#readme",
|
@@ -155,8 +155,9 @@
|
|
155
155
|
"any-signal": "^3.0.0",
|
156
156
|
"err-code": "^3.0.1",
|
157
157
|
"it-pipe": "^2.0.3",
|
158
|
-
"it-pushable": "^3.
|
158
|
+
"it-pushable": "^3.1.0",
|
159
159
|
"it-stream-types": "^1.0.4",
|
160
|
+
"rate-limiter-flexible": "^2.3.9",
|
160
161
|
"uint8arraylist": "^2.1.1",
|
161
162
|
"uint8arrays": "^3.0.0",
|
162
163
|
"varint": "^6.0.0"
|
package/src/encode.ts
CHANGED
@@ -44,7 +44,7 @@ class Encoder {
|
|
44
44
|
if ((msg.type === MessageTypes.NEW_STREAM || msg.type === MessageTypes.MESSAGE_INITIATOR || msg.type === MessageTypes.MESSAGE_RECEIVER) && msg.data != null) {
|
45
45
|
return [
|
46
46
|
header,
|
47
|
-
msg.data instanceof Uint8Array ? msg.data : msg.data
|
47
|
+
...(msg.data instanceof Uint8Array ? [msg.data] : msg.data)
|
48
48
|
]
|
49
49
|
}
|
50
50
|
|
package/src/index.ts
CHANGED
@@ -6,28 +6,37 @@ export interface MplexInit {
|
|
6
6
|
/**
|
7
7
|
* The maximum size of message that can be sent in one go in bytes.
|
8
8
|
* Messages larger than this will be split into multiple smaller
|
9
|
-
* messages
|
9
|
+
* messages (default: 1MB)
|
10
10
|
*/
|
11
11
|
maxMsgSize?: number
|
12
12
|
|
13
13
|
/**
|
14
14
|
* The maximum number of multiplexed streams that can be open at any
|
15
|
-
* one time.
|
15
|
+
* one time. A request to open more than this will have a stream
|
16
|
+
* reset message sent immediately as a response for the newly opened
|
17
|
+
* stream id (default: 1024)
|
16
18
|
*/
|
17
19
|
maxInboundStreams?: number
|
18
20
|
|
19
21
|
/**
|
20
22
|
* The maximum number of multiplexed streams that can be open at any
|
21
|
-
* one time. An attempt to open more than this will throw
|
23
|
+
* one time. An attempt to open more than this will throw (default: 1024)
|
22
24
|
*/
|
23
25
|
maxOutboundStreams?: number
|
24
26
|
|
25
27
|
/**
|
26
28
|
* Incoming stream messages are buffered until processed by the stream
|
27
29
|
* handler. If the buffer reaches this size in bytes the stream will
|
28
|
-
* be reset
|
30
|
+
* be reset (default: 4MB)
|
29
31
|
*/
|
30
32
|
maxStreamBufferSize?: number
|
33
|
+
|
34
|
+
/**
|
35
|
+
* When `maxInboundStreams` is hit, if the remote continues try to open
|
36
|
+
* more than this many new multiplexed streams per second the connection
|
37
|
+
* will be closed (default: 5)
|
38
|
+
*/
|
39
|
+
disconnectThreshold?: number
|
31
40
|
}
|
32
41
|
|
33
42
|
export class Mplex implements StreamMuxerFactory, Initializable {
|
package/src/mplex.ts
CHANGED
@@ -10,6 +10,7 @@ import { toString as uint8ArrayToString } from 'uint8arrays'
|
|
10
10
|
import { trackedMap } from '@libp2p/tracked-map'
|
11
11
|
import { logger } from '@libp2p/logger'
|
12
12
|
import errCode from 'err-code'
|
13
|
+
import { RateLimiterMemory } from 'rate-limiter-flexible'
|
13
14
|
import type { Components } from '@libp2p/components'
|
14
15
|
import type { Sink } from 'it-stream-types'
|
15
16
|
import type { StreamMuxer, StreamMuxerInit } from '@libp2p/interface-stream-muxer'
|
@@ -23,6 +24,7 @@ const log = logger('libp2p:mplex')
|
|
23
24
|
const MAX_STREAMS_INBOUND_STREAMS_PER_CONNECTION = 1024
|
24
25
|
const MAX_STREAMS_OUTBOUND_STREAMS_PER_CONNECTION = 1024
|
25
26
|
const MAX_STREAM_BUFFER_SIZE = 1024 * 1024 * 4 // 4MB
|
27
|
+
const DISCONNECT_THRESHOLD = 5
|
26
28
|
|
27
29
|
function printMessage (msg: Message) {
|
28
30
|
const output: any = {
|
@@ -58,6 +60,7 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
58
60
|
private readonly _init: MplexStreamMuxerInit
|
59
61
|
private readonly _source: { push: (val: Message) => void, end: (err?: Error) => void }
|
60
62
|
private readonly closeController: AbortController
|
63
|
+
private readonly rateLimiter: RateLimiterMemory
|
61
64
|
|
62
65
|
constructor (components: Components, init?: MplexStreamMuxerInit) {
|
63
66
|
init = init ?? {}
|
@@ -91,6 +94,11 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
91
94
|
* Close controller
|
92
95
|
*/
|
93
96
|
this.closeController = new AbortController()
|
97
|
+
|
98
|
+
this.rateLimiter = new RateLimiterMemory({
|
99
|
+
points: init.disconnectThreshold ?? DISCONNECT_THRESHOLD,
|
100
|
+
duration: 1
|
101
|
+
})
|
94
102
|
}
|
95
103
|
|
96
104
|
init (components: Components) {}
|
@@ -101,12 +109,13 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
101
109
|
get streams () {
|
102
110
|
// Inbound and Outbound streams may have the same ids, so we need to make those unique
|
103
111
|
const streams: Stream[] = []
|
104
|
-
this._streams.initiators.
|
112
|
+
for (const stream of this._streams.initiators.values()) {
|
105
113
|
streams.push(stream)
|
106
|
-
}
|
107
|
-
|
114
|
+
}
|
115
|
+
|
116
|
+
for (const stream of this._streams.receivers.values()) {
|
108
117
|
streams.push(stream)
|
109
|
-
}
|
118
|
+
}
|
110
119
|
return streams
|
111
120
|
}
|
112
121
|
|
@@ -150,7 +159,7 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
150
159
|
_newStream (options: { id: number, name: string, type: 'initiator' | 'receiver', registry: Map<number, MplexStream> }) {
|
151
160
|
const { id, name, type, registry } = options
|
152
161
|
|
153
|
-
log('new %s stream %s %s', type, id
|
162
|
+
log('new %s stream %s %s', type, id)
|
154
163
|
|
155
164
|
if (type === 'initiator' && this._streams.initiators.size === (this._init.maxOutboundStreams ?? MAX_STREAMS_OUTBOUND_STREAMS_PER_CONNECTION)) {
|
156
165
|
throw errCode(new Error('Too many outbound streams open'), 'ERR_TOO_MANY_OUTBOUND_STREAMS')
|
@@ -169,7 +178,7 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
169
178
|
}
|
170
179
|
|
171
180
|
const onEnd = () => {
|
172
|
-
log('%s stream %s ended', type, id,
|
181
|
+
log('%s stream with id %s and protocol %s ended', type, id, stream.stat.protocol)
|
173
182
|
registry.delete(id)
|
174
183
|
|
175
184
|
if (this._init.onStreamEnd != null) {
|
@@ -202,7 +211,7 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
202
211
|
restrictSize(this._init.maxMsgSize),
|
203
212
|
async source => {
|
204
213
|
for await (const msg of source) {
|
205
|
-
this._handleIncoming(msg)
|
214
|
+
await this._handleIncoming(msg)
|
206
215
|
}
|
207
216
|
}
|
208
217
|
)
|
@@ -237,7 +246,7 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
237
246
|
})
|
238
247
|
}
|
239
248
|
|
240
|
-
_handleIncoming (message: Message) {
|
249
|
+
async _handleIncoming (message: Message) {
|
241
250
|
const { id, type } = message
|
242
251
|
|
243
252
|
if (log.enabled) {
|
@@ -247,16 +256,27 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
247
256
|
// Create a new stream?
|
248
257
|
if (message.type === MessageTypes.NEW_STREAM) {
|
249
258
|
if (this._streams.receivers.size === (this._init.maxInboundStreams ?? MAX_STREAMS_INBOUND_STREAMS_PER_CONNECTION)) {
|
250
|
-
log
|
259
|
+
log('too many inbound streams open')
|
251
260
|
|
252
261
|
// not going to allow this stream, send the reset message manually
|
253
262
|
// instead of setting it up just to tear it down
|
254
|
-
|
255
263
|
this._source.push({
|
256
264
|
id,
|
257
265
|
type: MessageTypes.RESET_RECEIVER
|
258
266
|
})
|
259
267
|
|
268
|
+
// if we've hit our stream limit, and the remote keeps trying to open
|
269
|
+
// more new streams, if they are doing this very quickly maybe they
|
270
|
+
// are attacking us and we should close the connection
|
271
|
+
try {
|
272
|
+
await this.rateLimiter.consume('new-stream', 1)
|
273
|
+
} catch {
|
274
|
+
log('rate limit hit when opening too many new streams over the inbound stream limit - closing remote connection')
|
275
|
+
// since there's no backpressure in mplex, the only thing we can really do to protect ourselves is close the connection
|
276
|
+
this._source.end(new Error('Too many open streams'))
|
277
|
+
return
|
278
|
+
}
|
279
|
+
|
260
280
|
return
|
261
281
|
}
|
262
282
|
|
@@ -273,7 +293,7 @@ export class MplexStreamMuxer implements StreamMuxer {
|
|
273
293
|
const stream = list.get(id)
|
274
294
|
|
275
295
|
if (stream == null) {
|
276
|
-
log('missing stream %s', id)
|
296
|
+
log('missing stream %s for message type %s', id, MessageTypeNames[type])
|
277
297
|
|
278
298
|
return
|
279
299
|
}
|