@libp2p/circuit-relay-v2 3.2.24-f5932c294 → 3.2.24-fb19b055d
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/dist/index.min.js +1 -1
- package/dist/index.min.js.map +4 -4
- package/dist/src/constants.d.ts +1 -6
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +1 -6
- package/dist/src/constants.js.map +1 -1
- package/dist/src/index.d.ts +162 -7
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +12 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/server/index.d.ts +41 -45
- package/dist/src/server/index.d.ts.map +1 -1
- package/dist/src/server/index.js +32 -51
- package/dist/src/server/index.js.map +1 -1
- package/dist/src/server/reservation-store.d.ts +2 -36
- package/dist/src/server/reservation-store.d.ts.map +1 -1
- package/dist/src/server/reservation-store.js.map +1 -1
- package/dist/src/transport/discovery.d.ts +2 -17
- package/dist/src/transport/discovery.d.ts.map +1 -1
- package/dist/src/transport/discovery.js +2 -2
- package/dist/src/transport/discovery.js.map +1 -1
- package/dist/src/transport/index.d.ts +34 -42
- package/dist/src/transport/index.d.ts.map +1 -1
- package/dist/src/transport/index.js +291 -5
- package/dist/src/transport/index.js.map +1 -1
- package/dist/src/transport/reservation-store.d.ts +3 -37
- package/dist/src/transport/reservation-store.d.ts.map +1 -1
- package/dist/src/transport/reservation-store.js +4 -6
- package/dist/src/transport/reservation-store.js.map +1 -1
- package/dist/src/transport/stream-to-conn.d.ts +19 -0
- package/dist/src/transport/stream-to-conn.d.ts.map +1 -0
- package/dist/src/transport/stream-to-conn.js +60 -0
- package/dist/src/transport/stream-to-conn.js.map +1 -0
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +36 -59
- package/dist/src/utils.js.map +1 -1
- package/package.json +19 -24
- package/src/constants.ts +1 -7
- package/src/index.ts +198 -8
- package/src/server/index.ts +37 -105
- package/src/server/reservation-store.ts +2 -42
- package/src/transport/discovery.ts +4 -22
- package/src/transport/index.ts +338 -46
- package/src/transport/reservation-store.ts +8 -46
- package/src/transport/stream-to-conn.ts +91 -0
- package/src/utils.ts +37 -66
- package/dist/src/transport/transport.d.ts +0 -54
- package/dist/src/transport/transport.d.ts.map +0 -1
- package/dist/src/transport/transport.js +0 -314
- package/dist/src/transport/transport.js.map +0 -1
- package/src/transport/transport.ts +0 -380
package/src/index.ts
CHANGED
@@ -40,7 +40,11 @@
|
|
40
40
|
*/
|
41
41
|
|
42
42
|
import { TypedEventEmitter } from 'main-event'
|
43
|
+
import { CircuitRelayServer } from './server/index.js'
|
44
|
+
import { CircuitRelayTransport } from './transport/index.ts'
|
43
45
|
import type { Limit } from './pb/index.js'
|
46
|
+
import type { ComponentLogger, ConnectionGater, Libp2pEvents, Metrics, PeerId, PeerStore, PrivateKey, TopologyFilter, Transport, TypedEventTarget, Upgrader } from '@libp2p/interface'
|
47
|
+
import type { AddressManager, ConnectionManager, RandomWalk, Registrar, TransportManager } from '@libp2p/interface-internal'
|
44
48
|
import type { PeerMap } from '@libp2p/peer-collections'
|
45
49
|
import type { Multiaddr } from '@multiformats/multiaddr'
|
46
50
|
import type { RetimeableAbortSignal } from 'retimeable-signal'
|
@@ -80,15 +84,201 @@ export interface CircuitRelayService extends TypedEventEmitter<CircuitRelayServi
|
|
80
84
|
reservations: PeerMap<RelayReservation>
|
81
85
|
}
|
82
86
|
|
83
|
-
export { circuitRelayServer } from './server/index.js'
|
84
|
-
export type { CircuitRelayServerInit, CircuitRelayServerComponents } from './server/index.js'
|
85
|
-
export type { ReservationStoreInit as ServerReservationStoreInit } from './server/reservation-store.js'
|
86
|
-
export { circuitRelayTransport } from './transport/index.js'
|
87
|
-
export type { RelayDiscoveryComponents } from './transport/discovery.js'
|
88
|
-
export type { ReservationStoreInit as TransportReservationStoreInit } from './transport/reservation-store.js'
|
89
|
-
export type { CircuitRelayTransportInit, CircuitRelayTransportComponents } from './transport/index.js'
|
90
|
-
|
91
87
|
export {
|
92
88
|
RELAY_V2_HOP_CODEC,
|
93
89
|
RELAY_V2_STOP_CODEC
|
94
90
|
} from './constants.js'
|
91
|
+
|
92
|
+
export interface ServerReservationStoreInit {
|
93
|
+
/**
|
94
|
+
* maximum number of reservations allowed
|
95
|
+
*
|
96
|
+
* @default 15
|
97
|
+
*/
|
98
|
+
maxReservations?: number
|
99
|
+
|
100
|
+
/**
|
101
|
+
* interval after which stale reservations are cleared
|
102
|
+
*
|
103
|
+
* @default 300000
|
104
|
+
*/
|
105
|
+
reservationClearInterval?: number
|
106
|
+
|
107
|
+
/**
|
108
|
+
* apply default relay limits to a new reservation
|
109
|
+
*
|
110
|
+
* @default true
|
111
|
+
*/
|
112
|
+
applyDefaultLimit?: boolean
|
113
|
+
|
114
|
+
/**
|
115
|
+
* reservation ttl
|
116
|
+
*
|
117
|
+
* @default 7200000
|
118
|
+
*/
|
119
|
+
reservationTtl?: number
|
120
|
+
|
121
|
+
/**
|
122
|
+
* The maximum time a relayed connection can be open for
|
123
|
+
*/
|
124
|
+
defaultDurationLimit?: number
|
125
|
+
|
126
|
+
/**
|
127
|
+
* The maximum amount of data allowed to be transferred over a relayed connection
|
128
|
+
*/
|
129
|
+
defaultDataLimit?: bigint
|
130
|
+
}
|
131
|
+
|
132
|
+
export interface CircuitRelayServerComponents {
|
133
|
+
registrar: Registrar
|
134
|
+
peerStore: PeerStore
|
135
|
+
addressManager: AddressManager
|
136
|
+
peerId: PeerId
|
137
|
+
privateKey: PrivateKey
|
138
|
+
connectionManager: ConnectionManager
|
139
|
+
connectionGater: ConnectionGater
|
140
|
+
logger: ComponentLogger
|
141
|
+
metrics?: Metrics
|
142
|
+
}
|
143
|
+
|
144
|
+
export interface CircuitRelayServerInit {
|
145
|
+
/**
|
146
|
+
* Incoming hop requests must complete within this time in ms otherwise
|
147
|
+
* the stream will be reset
|
148
|
+
*
|
149
|
+
* @default 30000
|
150
|
+
*/
|
151
|
+
hopTimeout?: number
|
152
|
+
|
153
|
+
/**
|
154
|
+
* Configuration of reservations
|
155
|
+
*/
|
156
|
+
reservations?: ServerReservationStoreInit
|
157
|
+
|
158
|
+
/**
|
159
|
+
* The maximum number of simultaneous HOP inbound streams that can be open at once
|
160
|
+
*/
|
161
|
+
maxInboundHopStreams?: number
|
162
|
+
|
163
|
+
/**
|
164
|
+
* The maximum number of simultaneous HOP outbound streams that can be open at once
|
165
|
+
*/
|
166
|
+
maxOutboundHopStreams?: number
|
167
|
+
|
168
|
+
/**
|
169
|
+
* The maximum number of simultaneous STOP outbound streams that can be open at
|
170
|
+
* once.
|
171
|
+
*
|
172
|
+
* @default 300
|
173
|
+
*/
|
174
|
+
maxOutboundStopStreams?: number
|
175
|
+
}
|
176
|
+
|
177
|
+
export function circuitRelayServer (init: CircuitRelayServerInit = {}): (components: CircuitRelayServerComponents) => CircuitRelayService {
|
178
|
+
return (components) => {
|
179
|
+
return new CircuitRelayServer(components, init)
|
180
|
+
}
|
181
|
+
}
|
182
|
+
|
183
|
+
export interface RelayDiscoveryEvents {
|
184
|
+
'relay:discover': CustomEvent<PeerId>
|
185
|
+
}
|
186
|
+
|
187
|
+
export interface TransportReservationStoreComponents {
|
188
|
+
peerId: PeerId
|
189
|
+
connectionManager: ConnectionManager
|
190
|
+
peerStore: PeerStore
|
191
|
+
events: TypedEventTarget<Libp2pEvents>
|
192
|
+
logger: ComponentLogger
|
193
|
+
metrics?: Metrics
|
194
|
+
}
|
195
|
+
|
196
|
+
export interface TransportReservationStoreInit {
|
197
|
+
/**
|
198
|
+
* Multiple relays may be discovered simultaneously - to prevent listening
|
199
|
+
* on too many relays, this value controls how many to attempt to reserve a
|
200
|
+
* slot on at once. If set to more than one, we may end up listening on
|
201
|
+
* more relays than the `maxReservations` value, but on networks with poor
|
202
|
+
* connectivity the user may wish to attempt to reserve on multiple relays
|
203
|
+
* simultaneously.
|
204
|
+
*
|
205
|
+
* @default 1
|
206
|
+
*/
|
207
|
+
reservationConcurrency?: number
|
208
|
+
|
209
|
+
/**
|
210
|
+
* Limit the number of potential relays we will dial
|
211
|
+
*
|
212
|
+
* @default 100
|
213
|
+
*/
|
214
|
+
maxReservationQueueLength?: number
|
215
|
+
|
216
|
+
/**
|
217
|
+
* When creating a reservation it must complete within this number of ms
|
218
|
+
*
|
219
|
+
* @default 5000
|
220
|
+
*/
|
221
|
+
reservationCompletionTimeout?: number
|
222
|
+
}
|
223
|
+
|
224
|
+
export interface RelayDiscoveryComponents {
|
225
|
+
peerStore: PeerStore
|
226
|
+
connectionManager: ConnectionManager
|
227
|
+
transportManager: TransportManager
|
228
|
+
registrar: Registrar
|
229
|
+
logger: ComponentLogger
|
230
|
+
randomWalk: RandomWalk
|
231
|
+
events: TypedEventTarget<Libp2pEvents>
|
232
|
+
}
|
233
|
+
|
234
|
+
export interface RelayDiscoveryInit {
|
235
|
+
filter?: TopologyFilter
|
236
|
+
}
|
237
|
+
|
238
|
+
export interface CircuitRelayTransportComponents extends RelayDiscoveryComponents {
|
239
|
+
peerId: PeerId
|
240
|
+
upgrader: Upgrader
|
241
|
+
addressManager: AddressManager
|
242
|
+
connectionGater: ConnectionGater
|
243
|
+
}
|
244
|
+
|
245
|
+
/**
|
246
|
+
* RelayConfig configures the circuit v2 relay transport.
|
247
|
+
*/
|
248
|
+
export interface CircuitRelayTransportInit extends TransportReservationStoreInit {
|
249
|
+
/**
|
250
|
+
* An optional filter used to prevent duplicate attempts to reserve relay
|
251
|
+
* slots on the same peer
|
252
|
+
*/
|
253
|
+
discoveryFilter?: TopologyFilter
|
254
|
+
|
255
|
+
/**
|
256
|
+
* The maximum number of simultaneous STOP inbound streams that can be open at
|
257
|
+
* once - each inbound relayed connection uses a STOP stream
|
258
|
+
*
|
259
|
+
* @default 300
|
260
|
+
*/
|
261
|
+
maxInboundStopStreams?: number
|
262
|
+
|
263
|
+
/**
|
264
|
+
* The maximum number of simultaneous STOP outbound streams that can be open
|
265
|
+
* at once. If this transport is used along with the relay server these
|
266
|
+
* settings should be set to the same value
|
267
|
+
*
|
268
|
+
* @default 300
|
269
|
+
*/
|
270
|
+
maxOutboundStopStreams?: number
|
271
|
+
|
272
|
+
/**
|
273
|
+
* When creating a reservation it must complete within this number of ms
|
274
|
+
*
|
275
|
+
* @default 10_000
|
276
|
+
*/
|
277
|
+
reservationCompletionTimeout?: number
|
278
|
+
}
|
279
|
+
|
280
|
+
export function circuitRelayTransport (init: CircuitRelayTransportInit = {}): (components: CircuitRelayTransportComponents) => Transport {
|
281
|
+
return (components) => {
|
282
|
+
return new CircuitRelayTransport(components, init)
|
283
|
+
}
|
284
|
+
}
|
package/src/server/index.ts
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
import { publicKeyToProtobuf } from '@libp2p/crypto/keys'
|
2
2
|
import { peerIdFromMultihash } from '@libp2p/peer-id'
|
3
3
|
import { RecordEnvelope } from '@libp2p/peer-record'
|
4
|
+
import { pbStream } from '@libp2p/utils'
|
4
5
|
import { multiaddr } from '@multiformats/multiaddr'
|
5
|
-
import {
|
6
|
+
import { Circuit } from '@multiformats/multiaddr-matcher'
|
6
7
|
import { TypedEventEmitter, setMaxListeners } from 'main-event'
|
7
8
|
import * as Digest from 'multiformats/hashes/digest'
|
8
9
|
import {
|
9
|
-
CIRCUIT_PROTO_CODE,
|
10
10
|
DEFAULT_HOP_TIMEOUT,
|
11
|
-
KEEP_ALIVE_SOURCE_TAG,
|
12
11
|
MAX_CONNECTIONS,
|
13
12
|
RELAY_SOURCE_TAG,
|
14
13
|
RELAY_V2_HOP_CODEC,
|
@@ -18,49 +17,11 @@ import { HopMessage, Status, StopMessage } from '../pb/index.js'
|
|
18
17
|
import { createLimitedRelay } from '../utils.js'
|
19
18
|
import { ReservationStore } from './reservation-store.js'
|
20
19
|
import { ReservationVoucherRecord } from './reservation-voucher.js'
|
21
|
-
import type {
|
22
|
-
import type { CircuitRelayService, RelayReservation } from '../index.js'
|
20
|
+
import type { CircuitRelayServerComponents, CircuitRelayServerInit, CircuitRelayService, RelayReservation } from '../index.js'
|
23
21
|
import type { Reservation } from '../pb/index.js'
|
24
|
-
import type {
|
25
|
-
import type { AddressManager, ConnectionManager, Registrar } from '@libp2p/interface-internal'
|
22
|
+
import type { Logger, Connection, Stream, PeerId, Startable, AbortOptions } from '@libp2p/interface'
|
26
23
|
import type { PeerMap } from '@libp2p/peer-collections'
|
27
|
-
import type {
|
28
|
-
import type { ProtobufStream } from 'it-protobuf-stream'
|
29
|
-
|
30
|
-
const isRelayAddr = (ma: Multiaddr): boolean => ma.protoCodes().includes(CIRCUIT_PROTO_CODE)
|
31
|
-
|
32
|
-
export interface CircuitRelayServerInit {
|
33
|
-
/**
|
34
|
-
* Incoming hop requests must complete within this time in ms otherwise
|
35
|
-
* the stream will be reset
|
36
|
-
*
|
37
|
-
* @default 30000
|
38
|
-
*/
|
39
|
-
hopTimeout?: number
|
40
|
-
|
41
|
-
/**
|
42
|
-
* Configuration of reservations
|
43
|
-
*/
|
44
|
-
reservations?: ReservationStoreInit
|
45
|
-
|
46
|
-
/**
|
47
|
-
* The maximum number of simultaneous HOP inbound streams that can be open at once
|
48
|
-
*/
|
49
|
-
maxInboundHopStreams?: number
|
50
|
-
|
51
|
-
/**
|
52
|
-
* The maximum number of simultaneous HOP outbound streams that can be open at once
|
53
|
-
*/
|
54
|
-
maxOutboundHopStreams?: number
|
55
|
-
|
56
|
-
/**
|
57
|
-
* The maximum number of simultaneous STOP outbound streams that can be open at
|
58
|
-
* once.
|
59
|
-
*
|
60
|
-
* @default 300
|
61
|
-
*/
|
62
|
-
maxOutboundStopStreams?: number
|
63
|
-
}
|
24
|
+
import type { ProtobufStream } from '@libp2p/utils'
|
64
25
|
|
65
26
|
export interface HopProtocolOptions {
|
66
27
|
connection: Connection
|
@@ -73,18 +34,6 @@ export interface StopOptions {
|
|
73
34
|
request: StopMessage
|
74
35
|
}
|
75
36
|
|
76
|
-
export interface CircuitRelayServerComponents {
|
77
|
-
registrar: Registrar
|
78
|
-
peerStore: PeerStore
|
79
|
-
addressManager: AddressManager
|
80
|
-
peerId: PeerId
|
81
|
-
privateKey: PrivateKey
|
82
|
-
connectionManager: ConnectionManager
|
83
|
-
connectionGater: ConnectionGater
|
84
|
-
logger: ComponentLogger
|
85
|
-
metrics?: Metrics
|
86
|
-
}
|
87
|
-
|
88
37
|
export interface RelayServerEvents {
|
89
38
|
'relay:reservation': CustomEvent<RelayReservation>
|
90
39
|
'relay:advert:success': CustomEvent<unknown>
|
@@ -95,14 +44,8 @@ const defaults = {
|
|
95
44
|
maxOutboundStopStreams: MAX_CONNECTIONS
|
96
45
|
}
|
97
46
|
|
98
|
-
class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements Startable, CircuitRelayService {
|
99
|
-
private readonly
|
100
|
-
private readonly peerStore: PeerStore
|
101
|
-
private readonly addressManager: AddressManager
|
102
|
-
private readonly peerId: PeerId
|
103
|
-
private readonly privateKey: PrivateKey
|
104
|
-
private readonly connectionManager: ConnectionManager
|
105
|
-
private readonly connectionGater: ConnectionGater
|
47
|
+
export class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements Startable, CircuitRelayService {
|
48
|
+
private readonly components: CircuitRelayServerComponents
|
106
49
|
private readonly reservationStore: ReservationStore
|
107
50
|
private started: boolean
|
108
51
|
private readonly hopTimeout: number
|
@@ -119,13 +62,7 @@ class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements
|
|
119
62
|
super()
|
120
63
|
|
121
64
|
this.log = components.logger.forComponent('libp2p:circuit-relay:server')
|
122
|
-
this.
|
123
|
-
this.peerStore = components.peerStore
|
124
|
-
this.addressManager = components.addressManager
|
125
|
-
this.peerId = components.peerId
|
126
|
-
this.privateKey = components.privateKey
|
127
|
-
this.connectionManager = components.connectionManager
|
128
|
-
this.connectionGater = components.connectionGater
|
65
|
+
this.components = components
|
129
66
|
this.started = false
|
130
67
|
this.hopTimeout = init?.hopTimeout ?? DEFAULT_HOP_TIMEOUT
|
131
68
|
this.maxInboundHopStreams = init.maxInboundHopStreams
|
@@ -135,6 +72,8 @@ class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements
|
|
135
72
|
|
136
73
|
this.shutdownController = new AbortController()
|
137
74
|
setMaxListeners(Infinity, this.shutdownController.signal)
|
75
|
+
|
76
|
+
this.onHop = this.onHop.bind(this)
|
138
77
|
}
|
139
78
|
|
140
79
|
readonly [Symbol.toStringTag] = '@libp2p/circuit-relay-v2-server'
|
@@ -151,11 +90,7 @@ class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements
|
|
151
90
|
return
|
152
91
|
}
|
153
92
|
|
154
|
-
await this.registrar.handle(RELAY_V2_HOP_CODEC,
|
155
|
-
void this.onHop(data).catch(err => {
|
156
|
-
this.log.error(err)
|
157
|
-
})
|
158
|
-
}, {
|
93
|
+
await this.components.registrar.handle(RELAY_V2_HOP_CODEC, this.onHop, {
|
159
94
|
maxInboundStreams: this.maxInboundHopStreams,
|
160
95
|
maxOutboundStreams: this.maxOutboundHopStreams,
|
161
96
|
runOnLimitedConnection: true
|
@@ -170,16 +105,19 @@ class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements
|
|
170
105
|
async stop (): Promise<void> {
|
171
106
|
this.reservationStore.clear()
|
172
107
|
this.shutdownController.abort()
|
173
|
-
await this.registrar.unhandle(RELAY_V2_HOP_CODEC)
|
108
|
+
await this.components.registrar.unhandle(RELAY_V2_HOP_CODEC)
|
174
109
|
|
175
110
|
this.started = false
|
176
111
|
}
|
177
112
|
|
178
|
-
async onHop (
|
113
|
+
async onHop (stream: Stream, connection: Connection): Promise<void> {
|
179
114
|
this.log('received circuit v2 hop protocol stream from %p', connection.remotePeer)
|
180
115
|
|
116
|
+
const signal = AbortSignal.timeout(this.hopTimeout)
|
117
|
+
setMaxListeners(Infinity, signal)
|
118
|
+
|
181
119
|
const options = {
|
182
|
-
signal
|
120
|
+
signal
|
183
121
|
}
|
184
122
|
const pbstr = pbStream(stream)
|
185
123
|
|
@@ -223,13 +161,13 @@ class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements
|
|
223
161
|
const hopstr = stream.pb(HopMessage)
|
224
162
|
this.log('hop reserve request from %p', connection.remotePeer)
|
225
163
|
|
226
|
-
if (
|
164
|
+
if (Circuit.exactMatch(connection.remoteAddr)) {
|
227
165
|
this.log.error('relay reservation over circuit connection denied for peer: %p', connection.remotePeer)
|
228
166
|
await hopstr.write({ type: HopMessage.Type.STATUS, status: Status.PERMISSION_DENIED }, options)
|
229
167
|
return
|
230
168
|
}
|
231
169
|
|
232
|
-
if ((await this.connectionGater.denyInboundRelayReservation?.(connection.remotePeer)) === true) {
|
170
|
+
if ((await this.components.connectionGater.denyInboundRelayReservation?.(connection.remotePeer)) === true) {
|
233
171
|
this.log.error('reservation for %p denied by connection gater', connection.remotePeer)
|
234
172
|
await hopstr.write({ type: HopMessage.Type.STATUS, status: Status.PERMISSION_DENIED }, options)
|
235
173
|
return
|
@@ -247,12 +185,11 @@ class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements
|
|
247
185
|
// result.expire is non-null if `ReservationStore.reserve` returns with status == OK
|
248
186
|
if (result.expire != null) {
|
249
187
|
const ttl = (result.expire * 1000) - Date.now()
|
250
|
-
await this.peerStore.merge(connection.remotePeer, {
|
188
|
+
await this.components.peerStore.merge(connection.remotePeer, {
|
251
189
|
tags: {
|
252
|
-
[RELAY_SOURCE_TAG]: { value: 1, ttl }
|
253
|
-
[KEEP_ALIVE_SOURCE_TAG]: { value: 1, ttl }
|
190
|
+
[RELAY_SOURCE_TAG]: { value: 1, ttl }
|
254
191
|
}
|
255
|
-
})
|
192
|
+
}, options)
|
256
193
|
}
|
257
194
|
|
258
195
|
await hopstr.write({
|
@@ -262,17 +199,19 @@ class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements
|
|
262
199
|
limit: this.reservationStore.get(connection.remotePeer)?.limit
|
263
200
|
}, options)
|
264
201
|
this.log('sent confirmation response to %s', connection.remotePeer)
|
202
|
+
|
203
|
+
// close writable end of stream
|
204
|
+
await hopstr.unwrap().unwrap().close(options)
|
265
205
|
} catch (err) {
|
266
206
|
this.log.error('failed to send confirmation response to %p - %e', connection.remotePeer, err)
|
267
207
|
this.reservationStore.removeReservation(connection.remotePeer)
|
268
208
|
|
269
209
|
try {
|
270
|
-
await this.peerStore.merge(connection.remotePeer, {
|
210
|
+
await this.components.peerStore.merge(connection.remotePeer, {
|
271
211
|
tags: {
|
272
|
-
[RELAY_SOURCE_TAG]: undefined
|
273
|
-
[KEEP_ALIVE_SOURCE_TAG]: undefined
|
212
|
+
[RELAY_SOURCE_TAG]: undefined
|
274
213
|
}
|
275
|
-
})
|
214
|
+
}, options)
|
276
215
|
} catch (err) {
|
277
216
|
this.log.error('failed to untag relay source peer %p - %e', connection.remotePeer, err)
|
278
217
|
}
|
@@ -285,7 +224,7 @@ class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements
|
|
285
224
|
): Promise<Reservation> {
|
286
225
|
const addrs = []
|
287
226
|
|
288
|
-
for (const relayAddr of this.addressManager.getAddresses()) {
|
227
|
+
for (const relayAddr of this.components.addressManager.getAddresses()) {
|
289
228
|
if (relayAddr.toString().includes('/p2p-circuit')) {
|
290
229
|
continue
|
291
230
|
}
|
@@ -295,9 +234,9 @@ class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements
|
|
295
234
|
|
296
235
|
const envelope = await RecordEnvelope.seal(new ReservationVoucherRecord({
|
297
236
|
peer: remotePeer,
|
298
|
-
relay: this.peerId,
|
237
|
+
relay: this.components.peerId,
|
299
238
|
expiration: expire
|
300
|
-
}), this.privateKey)
|
239
|
+
}), this.components.privateKey)
|
301
240
|
|
302
241
|
return {
|
303
242
|
addrs,
|
@@ -307,7 +246,7 @@ class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements
|
|
307
246
|
payloadType: envelope.payloadType,
|
308
247
|
payload: {
|
309
248
|
peer: remotePeer.toMultihash().bytes,
|
310
|
-
relay: this.peerId.toMultihash().bytes,
|
249
|
+
relay: this.components.peerId.toMultihash().bytes,
|
311
250
|
expiration: expire
|
312
251
|
},
|
313
252
|
signature: envelope.signature
|
@@ -318,7 +257,7 @@ class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements
|
|
318
257
|
async handleConnect ({ stream, request, connection }: HopProtocolOptions, options: AbortOptions): Promise<void> {
|
319
258
|
const hopstr = stream.pb(HopMessage)
|
320
259
|
|
321
|
-
if (
|
260
|
+
if (Circuit.matches(connection.remoteAddr)) {
|
322
261
|
this.log.error('relay reservation over circuit connection denied for peer: %p', connection.remotePeer)
|
323
262
|
await hopstr.write({ type: HopMessage.Type.STATUS, status: Status.PERMISSION_DENIED }, options)
|
324
263
|
return
|
@@ -350,13 +289,13 @@ class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements
|
|
350
289
|
return
|
351
290
|
}
|
352
291
|
|
353
|
-
if ((await this.connectionGater.denyOutboundRelayedConnection?.(connection.remotePeer, dstPeer)) === true) {
|
292
|
+
if ((await this.components.connectionGater.denyOutboundRelayedConnection?.(connection.remotePeer, dstPeer)) === true) {
|
354
293
|
this.log.error('hop connect for %p to %p denied by connection gater', connection.remotePeer, dstPeer)
|
355
294
|
await hopstr.write({ type: HopMessage.Type.STATUS, status: Status.PERMISSION_DENIED }, options)
|
356
295
|
return
|
357
296
|
}
|
358
297
|
|
359
|
-
const connections = this.connectionManager.getConnections(dstPeer)
|
298
|
+
const connections = this.components.connectionManager.getConnections(dstPeer)
|
360
299
|
|
361
300
|
if (connections.length === 0) {
|
362
301
|
this.log('hop connect denied for destination peer %p not having a connection for %p as there is no destination connection', dstPeer, connection.remotePeer)
|
@@ -389,12 +328,11 @@ class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements
|
|
389
328
|
status: Status.OK,
|
390
329
|
limit: reservation?.limit
|
391
330
|
}, options)
|
392
|
-
const sourceStream = stream.unwrap()
|
393
331
|
|
394
332
|
this.log('connection from %p to %p established - merging streams', connection.remotePeer, dstPeer)
|
395
333
|
|
396
334
|
// Short circuit the two streams to create the relayed connection
|
397
|
-
createLimitedRelay(
|
335
|
+
createLimitedRelay(stream.unwrap(), destinationStream, this.shutdownController.signal, reservation, {
|
398
336
|
log: this.log
|
399
337
|
})
|
400
338
|
}
|
@@ -404,7 +342,7 @@ class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements
|
|
404
342
|
*/
|
405
343
|
async stopHop ({ connection, request }: StopOptions, options: AbortOptions): Promise<Stream | undefined> {
|
406
344
|
this.log('starting circuit relay v2 stop request to %s', connection.remotePeer)
|
407
|
-
const stream = await connection.newStream(
|
345
|
+
const stream = await connection.newStream(RELAY_V2_STOP_CODEC, {
|
408
346
|
maxOutboundStreams: this.maxOutboundStopStreams,
|
409
347
|
runOnLimitedConnection: true,
|
410
348
|
...options
|
@@ -439,9 +377,3 @@ class CircuitRelayServer extends TypedEventEmitter<RelayServerEvents> implements
|
|
439
377
|
return this.reservationStore.reservations
|
440
378
|
}
|
441
379
|
}
|
442
|
-
|
443
|
-
export function circuitRelayServer (init: CircuitRelayServerInit = {}): (components: CircuitRelayServerComponents) => CircuitRelayService {
|
444
|
-
return (components) => {
|
445
|
-
return new CircuitRelayServer(components, init)
|
446
|
-
}
|
447
|
-
}
|
@@ -2,7 +2,7 @@ import { trackedPeerMap } from '@libp2p/peer-collections'
|
|
2
2
|
import { retimeableSignal } from 'retimeable-signal'
|
3
3
|
import { DEFAULT_DATA_LIMIT, DEFAULT_DURATION_LIMIT, DEFAULT_MAX_RESERVATION_STORE_SIZE, DEFAULT_MAX_RESERVATION_TTL } from '../constants.js'
|
4
4
|
import { Status } from '../pb/index.js'
|
5
|
-
import type { RelayReservation } from '../index.js'
|
5
|
+
import type { RelayReservation, ServerReservationStoreInit } from '../index.js'
|
6
6
|
import type { Limit } from '../pb/index.js'
|
7
7
|
import type { ComponentLogger, Logger, Metrics, PeerId } from '@libp2p/interface'
|
8
8
|
import type { PeerMap } from '@libp2p/peer-collections'
|
@@ -15,46 +15,6 @@ export interface ReservationStoreComponents {
|
|
15
15
|
metrics?: Metrics
|
16
16
|
}
|
17
17
|
|
18
|
-
export interface ReservationStoreInit {
|
19
|
-
/**
|
20
|
-
* maximum number of reservations allowed
|
21
|
-
*
|
22
|
-
* @default 15
|
23
|
-
*/
|
24
|
-
maxReservations?: number
|
25
|
-
|
26
|
-
/**
|
27
|
-
* interval after which stale reservations are cleared
|
28
|
-
*
|
29
|
-
* @default 300000
|
30
|
-
*/
|
31
|
-
reservationClearInterval?: number
|
32
|
-
|
33
|
-
/**
|
34
|
-
* apply default relay limits to a new reservation
|
35
|
-
*
|
36
|
-
* @default true
|
37
|
-
*/
|
38
|
-
applyDefaultLimit?: boolean
|
39
|
-
|
40
|
-
/**
|
41
|
-
* reservation ttl
|
42
|
-
*
|
43
|
-
* @default 7200000
|
44
|
-
*/
|
45
|
-
reservationTtl?: number
|
46
|
-
|
47
|
-
/**
|
48
|
-
* The maximum time a relayed connection can be open for
|
49
|
-
*/
|
50
|
-
defaultDurationLimit?: number
|
51
|
-
|
52
|
-
/**
|
53
|
-
* The maximum amount of data allowed to be transferred over a relayed connection
|
54
|
-
*/
|
55
|
-
defaultDataLimit?: bigint
|
56
|
-
}
|
57
|
-
|
58
18
|
export class ReservationStore {
|
59
19
|
public readonly reservations: PeerMap<RelayReservation>
|
60
20
|
private readonly maxReservations: number
|
@@ -64,7 +24,7 @@ export class ReservationStore {
|
|
64
24
|
private readonly defaultDataLimit: bigint
|
65
25
|
private readonly log: Logger
|
66
26
|
|
67
|
-
constructor (components: ReservationStoreComponents, init:
|
27
|
+
constructor (components: ReservationStoreComponents, init: ServerReservationStoreInit = {}) {
|
68
28
|
this.log = components.logger.forComponent('libp2p:circuit-relay:server:reservation-store')
|
69
29
|
this.maxReservations = init.maxReservations ?? DEFAULT_MAX_RESERVATION_STORE_SIZE
|
70
30
|
this.applyDefaultLimit = init.applyDefaultLimit !== false
|
@@ -1,30 +1,12 @@
|
|
1
|
-
import { PeerQueue } from '@libp2p/utils
|
1
|
+
import { PeerQueue } from '@libp2p/utils'
|
2
2
|
import { anySignal } from 'any-signal'
|
3
3
|
import { TypedEventEmitter, setMaxListeners } from 'main-event'
|
4
4
|
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
|
5
5
|
import {
|
6
6
|
RELAY_V2_HOP_CODEC
|
7
7
|
} from '../constants.js'
|
8
|
-
import type {
|
9
|
-
import type {
|
10
|
-
|
11
|
-
export interface RelayDiscoveryEvents {
|
12
|
-
'relay:discover': CustomEvent<PeerId>
|
13
|
-
}
|
14
|
-
|
15
|
-
export interface RelayDiscoveryComponents {
|
16
|
-
peerStore: PeerStore
|
17
|
-
connectionManager: ConnectionManager
|
18
|
-
transportManager: TransportManager
|
19
|
-
registrar: Registrar
|
20
|
-
logger: ComponentLogger
|
21
|
-
randomWalk: RandomWalk
|
22
|
-
events: TypedEventTarget<Libp2pEvents>
|
23
|
-
}
|
24
|
-
|
25
|
-
export interface RelayDiscoveryInit {
|
26
|
-
filter?: TopologyFilter
|
27
|
-
}
|
8
|
+
import type { RelayDiscoveryComponents, RelayDiscoveryEvents, RelayDiscoveryInit } from '../index.ts'
|
9
|
+
import type { Logger, Peer, PeerId, PeerInfo, Startable, TopologyFilter } from '@libp2p/interface'
|
28
10
|
|
29
11
|
/**
|
30
12
|
* ReservationManager automatically makes a circuit v2 reservation on any connected
|
@@ -221,7 +203,7 @@ export class RelayDiscovery extends TypedEventEmitter<RelayDiscoveryEvents> impl
|
|
221
203
|
}
|
222
204
|
|
223
205
|
onPeer (evt: CustomEvent<PeerInfo>): void {
|
224
|
-
this.log.trace('maybe dialing discovered peer %p
|
206
|
+
this.log.trace('maybe dialing discovered peer %p', evt.detail.id)
|
225
207
|
|
226
208
|
this.maybeDialPeer(evt)
|
227
209
|
.catch(err => {
|