Skip to content

Commit df2153e

Browse files
authored
fix(circuit-relay): respect applyDefaultLimit when it is false (#2139)
We were accidentally applying the default limits if no limits were set, which is intentionally the case when the `applyDefaultLimit` config option is set to `false`.
1 parent 70dbb97 commit df2153e

File tree

3 files changed

+224
-381
lines changed

3 files changed

+224
-381
lines changed

packages/libp2p/src/circuit-relay/utils.ts

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { anySignal } from 'any-signal'
44
import { CID } from 'multiformats/cid'
55
import { sha256 } from 'multiformats/hashes/sha2'
66
import { codes } from '../errors.js'
7-
import { DEFAULT_DATA_LIMIT, DEFAULT_DURATION_LIMIT } from './constants.js'
87
import type { Limit } from './pb/index.js'
98
import type { Stream } from '@libp2p/interface/connection'
109
import type { Source } from 'it-stream-types'
@@ -13,6 +12,8 @@ import type { Uint8ArrayList } from 'uint8arraylist'
1312
const log = logger('libp2p:circuit-relay:utils')
1413

1514
async function * countStreamBytes (source: Source<Uint8Array | Uint8ArrayList>, limit: { remaining: bigint }): AsyncGenerator<Uint8Array | Uint8ArrayList, void, unknown> {
15+
const limitBytes = limit.remaining
16+
1617
for await (const buf of source) {
1718
const len = BigInt(buf.byteLength)
1819

@@ -29,15 +30,15 @@ async function * countStreamBytes (source: Source<Uint8Array | Uint8ArrayList>,
2930
log.error(err)
3031
}
3132

32-
throw new Error('data limit exceeded')
33+
throw new CodeError(`data limit of ${limitBytes} bytes exceeded`, codes.ERR_TRANSFER_LIMIT_EXCEEDED)
3334
}
3435

3536
limit.remaining -= len
3637
yield buf
3738
}
3839
}
3940

40-
const doRelay = (src: Stream, dst: Stream, abortSignal: AbortSignal, limit: Required<Limit>): void => {
41+
export function createLimitedRelay (src: Stream, dst: Stream, abortSignal: AbortSignal, limit?: Limit): void {
4142
function abortStreams (err: Error): void {
4243
src.abort(err)
4344
dst.abort(err)
@@ -47,25 +48,33 @@ const doRelay = (src: Stream, dst: Stream, abortSignal: AbortSignal, limit: Requ
4748
const abortController = new AbortController()
4849
const signal = anySignal([abortSignal, abortController.signal])
4950

50-
const timeout = setTimeout(() => {
51-
abortController.abort()
52-
}, limit.duration)
51+
let timeout: ReturnType<typeof setTimeout> | undefined
52+
53+
if (limit?.duration != null) {
54+
timeout = setTimeout(() => {
55+
abortController.abort()
56+
}, limit.duration)
57+
}
5358

5459
let srcDstFinished = false
5560
let dstSrcFinished = false
5661

57-
const dataLimit = {
58-
remaining: limit.data
62+
let dataLimit: { remaining: bigint } | undefined
63+
64+
if (limit?.data != null) {
65+
dataLimit = {
66+
remaining: limit.data
67+
}
5968
}
6069

6170
queueMicrotask(() => {
6271
const onAbort = (): void => {
63-
dst.abort(new CodeError('duration limit exceeded', codes.ERR_TIMEOUT))
72+
dst.abort(new CodeError(`duration limit of ${limit?.duration} ms exceeded`, codes.ERR_TRANSFER_LIMIT_EXCEEDED))
6473
}
6574

6675
signal.addEventListener('abort', onAbort, { once: true })
6776

68-
void dst.sink(countStreamBytes(src.source, dataLimit))
77+
void dst.sink(dataLimit == null ? src.source : countStreamBytes(src.source, dataLimit))
6978
.catch(err => {
7079
log.error('error while relaying streams src -> dst', err)
7180
abortStreams(err)
@@ -83,12 +92,12 @@ const doRelay = (src: Stream, dst: Stream, abortSignal: AbortSignal, limit: Requ
8392

8493
queueMicrotask(() => {
8594
const onAbort = (): void => {
86-
src.abort(new CodeError('duration limit exceeded', codes.ERR_TIMEOUT))
95+
src.abort(new CodeError(`duration limit of ${limit?.duration} ms exceeded`, codes.ERR_TRANSFER_LIMIT_EXCEEDED))
8796
}
8897

8998
signal.addEventListener('abort', onAbort, { once: true })
9099

91-
void src.sink(countStreamBytes(dst.source, dataLimit))
100+
void src.sink(dataLimit == null ? dst.source : countStreamBytes(dst.source, dataLimit))
92101
.catch(err => {
93102
log.error('error while relaying streams dst -> src', err)
94103
abortStreams(err)
@@ -105,16 +114,6 @@ const doRelay = (src: Stream, dst: Stream, abortSignal: AbortSignal, limit: Requ
105114
})
106115
}
107116

108-
export function createLimitedRelay (source: Stream, destination: Stream, abortSignal: AbortSignal, limit?: Limit): void {
109-
const dataLimit = limit?.data ?? BigInt(DEFAULT_DATA_LIMIT)
110-
const durationLimit = limit?.duration ?? DEFAULT_DURATION_LIMIT
111-
112-
doRelay(source, destination, abortSignal, {
113-
data: dataLimit,
114-
duration: durationLimit
115-
})
116-
}
117-
118117
/**
119118
* Convert a namespace string into a cid
120119
*/

packages/libp2p/src/errors.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,5 +75,5 @@ export enum codes {
7575
ERR_TOO_MANY_OUTBOUND_PROTOCOL_STREAMS = 'ERR_TOO_MANY_OUTBOUND_PROTOCOL_STREAMS',
7676
ERR_TOO_MANY_INBOUND_PROTOCOL_STREAMS = 'ERR_TOO_MANY_INBOUND_PROTOCOL_STREAMS',
7777
ERR_CONNECTION_DENIED = 'ERR_CONNECTION_DENIED',
78-
ERR_TRANSFER_LIMIT_EXCEEDED = 'ERR_TRANSFER_LIMIT_EXCEEDED',
78+
ERR_TRANSFER_LIMIT_EXCEEDED = 'ERR_TRANSFER_LIMIT_EXCEEDED'
7979
}

0 commit comments

Comments
 (0)