@@ -4,7 +4,6 @@ import { anySignal } from 'any-signal'
4
4
import { CID } from 'multiformats/cid'
5
5
import { sha256 } from 'multiformats/hashes/sha2'
6
6
import { codes } from '../errors.js'
7
- import { DEFAULT_DATA_LIMIT , DEFAULT_DURATION_LIMIT } from './constants.js'
8
7
import type { Limit } from './pb/index.js'
9
8
import type { Stream } from '@libp2p/interface/connection'
10
9
import type { Source } from 'it-stream-types'
@@ -13,6 +12,8 @@ import type { Uint8ArrayList } from 'uint8arraylist'
13
12
const log = logger ( 'libp2p:circuit-relay:utils' )
14
13
15
14
async function * countStreamBytes ( source : Source < Uint8Array | Uint8ArrayList > , limit : { remaining : bigint } ) : AsyncGenerator < Uint8Array | Uint8ArrayList , void , unknown > {
15
+ const limitBytes = limit . remaining
16
+
16
17
for await ( const buf of source ) {
17
18
const len = BigInt ( buf . byteLength )
18
19
@@ -29,15 +30,15 @@ async function * countStreamBytes (source: Source<Uint8Array | Uint8ArrayList>,
29
30
log . error ( err )
30
31
}
31
32
32
- throw new Error ( ' data limit exceeded' )
33
+ throw new CodeError ( ` data limit of ${ limitBytes } bytes exceeded` , codes . ERR_TRANSFER_LIMIT_EXCEEDED )
33
34
}
34
35
35
36
limit . remaining -= len
36
37
yield buf
37
38
}
38
39
}
39
40
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 {
41
42
function abortStreams ( err : Error ) : void {
42
43
src . abort ( err )
43
44
dst . abort ( err )
@@ -47,25 +48,33 @@ const doRelay = (src: Stream, dst: Stream, abortSignal: AbortSignal, limit: Requ
47
48
const abortController = new AbortController ( )
48
49
const signal = anySignal ( [ abortSignal , abortController . signal ] )
49
50
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
+ }
53
58
54
59
let srcDstFinished = false
55
60
let dstSrcFinished = false
56
61
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
+ }
59
68
}
60
69
61
70
queueMicrotask ( ( ) => {
62
71
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 ) )
64
73
}
65
74
66
75
signal . addEventListener ( 'abort' , onAbort , { once : true } )
67
76
68
- void dst . sink ( countStreamBytes ( src . source , dataLimit ) )
77
+ void dst . sink ( dataLimit == null ? src . source : countStreamBytes ( src . source , dataLimit ) )
69
78
. catch ( err => {
70
79
log . error ( 'error while relaying streams src -> dst' , err )
71
80
abortStreams ( err )
@@ -83,12 +92,12 @@ const doRelay = (src: Stream, dst: Stream, abortSignal: AbortSignal, limit: Requ
83
92
84
93
queueMicrotask ( ( ) => {
85
94
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 ) )
87
96
}
88
97
89
98
signal . addEventListener ( 'abort' , onAbort , { once : true } )
90
99
91
- void src . sink ( countStreamBytes ( dst . source , dataLimit ) )
100
+ void src . sink ( dataLimit == null ? dst . source : countStreamBytes ( dst . source , dataLimit ) )
92
101
. catch ( err => {
93
102
log . error ( 'error while relaying streams dst -> src' , err )
94
103
abortStreams ( err )
@@ -105,16 +114,6 @@ const doRelay = (src: Stream, dst: Stream, abortSignal: AbortSignal, limit: Requ
105
114
} )
106
115
}
107
116
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
-
118
117
/**
119
118
* Convert a namespace string into a cid
120
119
*/
0 commit comments