@libp2p/circuit-relay-v2 3.2.23-cf9aab5c8 → 3.2.24-a02cb0461

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.
Files changed (46) hide show
  1. package/dist/index.min.js +1 -1
  2. package/dist/index.min.js.map +4 -4
  3. package/dist/src/index.d.ts +170 -7
  4. package/dist/src/index.d.ts.map +1 -1
  5. package/dist/src/index.js +12 -2
  6. package/dist/src/index.js.map +1 -1
  7. package/dist/src/server/index.d.ts +41 -45
  8. package/dist/src/server/index.d.ts.map +1 -1
  9. package/dist/src/server/index.js +26 -43
  10. package/dist/src/server/index.js.map +1 -1
  11. package/dist/src/server/reservation-store.d.ts +2 -36
  12. package/dist/src/server/reservation-store.d.ts.map +1 -1
  13. package/dist/src/server/reservation-store.js.map +1 -1
  14. package/dist/src/transport/discovery.d.ts +2 -17
  15. package/dist/src/transport/discovery.d.ts.map +1 -1
  16. package/dist/src/transport/discovery.js +2 -2
  17. package/dist/src/transport/discovery.js.map +1 -1
  18. package/dist/src/transport/index.d.ts +34 -42
  19. package/dist/src/transport/index.d.ts.map +1 -1
  20. package/dist/src/transport/index.js +296 -5
  21. package/dist/src/transport/index.js.map +1 -1
  22. package/dist/src/transport/reservation-store.d.ts +3 -37
  23. package/dist/src/transport/reservation-store.d.ts.map +1 -1
  24. package/dist/src/transport/reservation-store.js +2 -4
  25. package/dist/src/transport/reservation-store.js.map +1 -1
  26. package/dist/src/transport/stream-to-conn.d.ts +19 -0
  27. package/dist/src/transport/stream-to-conn.d.ts.map +1 -0
  28. package/dist/src/transport/stream-to-conn.js +60 -0
  29. package/dist/src/transport/stream-to-conn.js.map +1 -0
  30. package/dist/src/utils.d.ts.map +1 -1
  31. package/dist/src/utils.js +36 -59
  32. package/dist/src/utils.js.map +1 -1
  33. package/package.json +19 -24
  34. package/src/index.ts +207 -8
  35. package/src/server/index.ts +32 -94
  36. package/src/server/reservation-store.ts +2 -42
  37. package/src/transport/discovery.ts +4 -22
  38. package/src/transport/index.ts +344 -46
  39. package/src/transport/reservation-store.ts +6 -44
  40. package/src/transport/stream-to-conn.ts +91 -0
  41. package/src/utils.ts +37 -66
  42. package/dist/src/transport/transport.d.ts +0 -54
  43. package/dist/src/transport/transport.d.ts.map +0 -1
  44. package/dist/src/transport/transport.js +0 -314
  45. package/dist/src/transport/transport.js.map +0 -1
  46. package/src/transport/transport.ts +0 -380
package/src/utils.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { setMaxListeners } from '@libp2p/interface'
2
+ import { pipe } from '@libp2p/utils'
1
3
  import { CODE_P2P_CIRCUIT } from '@multiformats/multiaddr'
2
4
  import { P2P } from '@multiformats/multiaddr-matcher'
3
5
  import { fmt, code, and } from '@multiformats/multiaddr-matcher/utils'
@@ -7,35 +9,21 @@ import { sha256 } from 'multiformats/hashes/sha2'
7
9
  import { DurationLimitError, TransferLimitError } from './errors.js'
8
10
  import type { RelayReservation } from './index.js'
9
11
  import type { Limit } from './pb/index.js'
10
- import type { ConnectionLimits, LoggerOptions, Stream } from '@libp2p/interface'
11
- import type { Source } from 'it-stream-types'
12
+ import type { ConnectionLimits, LoggerOptions, Stream, MessageStream, StreamMessageEvent } from '@libp2p/interface'
12
13
  import type { Uint8ArrayList } from 'uint8arraylist'
13
14
 
14
- async function * countStreamBytes (source: Source<Uint8Array | Uint8ArrayList>, limit: { remaining: bigint }, options: LoggerOptions): AsyncGenerator<Uint8Array | Uint8ArrayList, void, unknown> {
15
+ function countStreamBytes (source: MessageStream, limit: { remaining: bigint }, options: LoggerOptions): void {
15
16
  const limitBytes = limit.remaining
16
17
 
17
- for await (const buf of source) {
18
- const len = BigInt(buf.byteLength)
19
-
20
- if ((limit.remaining - len) < 0) {
21
- // this is a safe downcast since len is guarantee to be in the range for a number
22
- const remaining = Number(limit.remaining)
23
- limit.remaining = 0n
24
-
25
- try {
26
- if (remaining !== 0) {
27
- yield buf.subarray(0, remaining)
28
- }
29
- } catch (err: any) {
30
- options.log.error(err)
31
- }
18
+ const abortIfStreamByteLimitExceeded = (evt: StreamMessageEvent): void => {
19
+ const len = BigInt(evt.data.byteLength)
20
+ limit.remaining -= len
32
21
 
33
- throw new TransferLimitError(`data limit of ${limitBytes} bytes exceeded`)
22
+ if (limit.remaining < 0) {
23
+ source.abort(new TransferLimitError(`data limit of ${limitBytes} bytes exceeded`))
34
24
  }
35
-
36
- limit.remaining -= len
37
- yield buf
38
25
  }
26
+ source.addEventListener('message', abortIfStreamByteLimitExceeded)
39
27
  }
40
28
 
41
29
  export function createLimitedRelay (src: Stream, dst: Stream, abortSignal: AbortSignal, reservation: RelayReservation, options: LoggerOptions): void {
@@ -49,13 +37,13 @@ export function createLimitedRelay (src: Stream, dst: Stream, abortSignal: Abort
49
37
 
50
38
  if (reservation.limit?.duration != null) {
51
39
  options.log('limiting relayed connection duration to %dms', reservation.limit.duration)
52
- signals.push(AbortSignal.timeout(reservation.limit.duration))
40
+ const durationSignal = AbortSignal.timeout(reservation.limit.duration)
41
+ setMaxListeners(Infinity, durationSignal)
42
+ signals.push(durationSignal)
53
43
  }
54
44
 
55
45
  const signal = anySignal(signals)
56
-
57
- let srcDstFinished = false
58
- let dstSrcFinished = false
46
+ setMaxListeners(Infinity, signal)
59
47
 
60
48
  let dataLimit: { remaining: bigint } | undefined
61
49
 
@@ -65,51 +53,34 @@ export function createLimitedRelay (src: Stream, dst: Stream, abortSignal: Abort
65
53
  }
66
54
  }
67
55
 
68
- queueMicrotask(() => {
69
- const onAbort = (): void => {
70
- options.log('relayed connection reached time limit')
71
- dst.abort(new DurationLimitError(`duration limit of ${reservation.limit?.duration} ms exceeded`))
72
- }
56
+ const onAbort = (): void => {
57
+ let err: Error
73
58
 
74
- signal.addEventListener('abort', onAbort, { once: true })
75
-
76
- void dst.sink(dataLimit == null ? src.source : countStreamBytes(src.source, dataLimit, options))
77
- .catch(err => {
78
- options.log.error('error while relaying streams src -> dst', err)
79
- abortStreams(err)
80
- })
81
- .finally(() => {
82
- srcDstFinished = true
83
-
84
- if (dstSrcFinished) {
85
- signal.removeEventListener('abort', onAbort)
86
- signal.clear()
87
- }
88
- })
89
- })
90
-
91
- queueMicrotask(() => {
92
- const onAbort = (): void => {
93
- options.log('relayed connection reached time limit')
94
- src.abort(new DurationLimitError(`duration limit of ${reservation.limit?.duration} ms exceeded`))
59
+ if (abortSignal.aborted) {
60
+ err = abortSignal.reason
61
+ } else {
62
+ err = new DurationLimitError(`duration limit of ${reservation.limit?.duration} ms exceeded`)
95
63
  }
96
64
 
97
- signal.addEventListener('abort', onAbort, { once: true })
65
+ abortStreams(err)
66
+ }
67
+ signal.addEventListener('abort', onAbort, { once: true })
98
68
 
99
- void src.sink(dataLimit == null ? dst.source : countStreamBytes(dst.source, dataLimit, options))
100
- .catch(err => {
101
- options.log.error('error while relaying streams dst -> src', err)
102
- abortStreams(err)
103
- })
104
- .finally(() => {
105
- dstSrcFinished = true
69
+ if (dataLimit != null) {
70
+ countStreamBytes(dst, dataLimit, options)
71
+ countStreamBytes(src, dataLimit, options)
72
+ }
106
73
 
107
- if (srcDstFinished) {
108
- signal.removeEventListener('abort', onAbort)
109
- signal.clear()
110
- }
111
- })
112
- })
74
+ // join the streams together
75
+ pipe(
76
+ src, dst, src
77
+ )
78
+ .catch(err => {
79
+ abortStreams(err)
80
+ })
81
+ .finally(() => {
82
+ signal.clear()
83
+ })
113
84
  }
114
85
 
115
86
  /**
@@ -1,54 +0,0 @@
1
- import { serviceCapabilities, serviceDependencies, transportSymbol } from '@libp2p/interface';
2
- import { ReservationStore } from './reservation-store.js';
3
- import type { CircuitRelayTransportComponents, CircuitRelayTransportInit } from './index.js';
4
- import type { Transport, CreateListenerOptions, Listener, Connection, OutboundConnectionUpgradeEvents, DialTransportOptions, OpenConnectionProgressEvents, IncomingStreamData } from '@libp2p/interface';
5
- import type { Multiaddr } from '@multiformats/multiaddr';
6
- import type { ProgressEvent } from 'progress-events';
7
- export type CircuitRelayDialEvents = OutboundConnectionUpgradeEvents | OpenConnectionProgressEvents | ProgressEvent<'circuit-relay:open-connection'> | ProgressEvent<'circuit-relay:reuse-connection'> | ProgressEvent<'circuit-relay:open-hop-stream'> | ProgressEvent<'circuit-relay:write-connect-message'> | ProgressEvent<'circuit-relay:read-connect-response'>;
8
- export declare class CircuitRelayTransport implements Transport<CircuitRelayDialEvents> {
9
- private readonly discovery?;
10
- private readonly registrar;
11
- private readonly peerStore;
12
- private readonly connectionManager;
13
- private readonly transportManager;
14
- private readonly peerId;
15
- private readonly upgrader;
16
- private readonly addressManager;
17
- private readonly connectionGater;
18
- readonly reservationStore: ReservationStore;
19
- private readonly logger;
20
- private readonly maxInboundStopStreams;
21
- private readonly maxOutboundStopStreams?;
22
- private started;
23
- private readonly log;
24
- private shutdownController;
25
- constructor(components: CircuitRelayTransportComponents, init?: CircuitRelayTransportInit);
26
- readonly [Symbol.toStringTag] = "@libp2p/circuit-relay-v2-transport";
27
- readonly [serviceCapabilities]: string[];
28
- get [serviceDependencies](): string[];
29
- readonly [transportSymbol] = true;
30
- isStarted(): boolean;
31
- start(): Promise<void>;
32
- stop(): Promise<void>;
33
- /**
34
- * Dial a peer over a relay
35
- */
36
- dial(ma: Multiaddr, options: DialTransportOptions<CircuitRelayDialEvents>): Promise<Connection>;
37
- /**
38
- * Create a listener
39
- */
40
- createListener(options: CreateListenerOptions): Listener;
41
- /**
42
- * Filter check for all Multiaddrs that this transport can listen on
43
- */
44
- listenFilter(multiaddrs: Multiaddr[]): Multiaddr[];
45
- /**
46
- * Filter check for all Multiaddrs that this transport can dial
47
- */
48
- dialFilter(multiaddrs: Multiaddr[]): Multiaddr[];
49
- /**
50
- * An incoming STOP request means a remote peer wants to dial us via a relay
51
- */
52
- onStop({ connection, stream }: IncomingStreamData, signal: AbortSignal): Promise<void>;
53
- }
54
- //# sourceMappingURL=transport.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../../src/transport/transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkC,mBAAmB,EAAE,mBAAmB,EAAe,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAe1I,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,KAAK,EAAE,+BAA+B,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAA;AAC5F,OAAO,KAAK,EAAE,SAAS,EAAE,qBAAqB,EAAE,QAAQ,EAAqC,UAAU,EAA8C,+BAA+B,EAAE,oBAAoB,EAAE,4BAA4B,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAEvR,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAsBpD,MAAM,MAAM,sBAAsB,GAChC,+BAA+B,GAC/B,4BAA4B,GAC5B,aAAa,CAAC,+BAA+B,CAAC,GAC9C,aAAa,CAAC,gCAAgC,CAAC,GAC/C,aAAa,CAAC,+BAA+B,CAAC,GAC9C,aAAa,CAAC,qCAAqC,CAAC,GACpD,aAAa,CAAC,qCAAqC,CAAC,CAAA;AAEtD,qBAAa,qBAAsB,YAAW,SAAS,CAAC,sBAAsB,CAAC;IAC7E,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAgB;IAC3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;IACrC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAmB;IACrD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAkB;IACnD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAU;IACnC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgB;IAC/C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiB;IACjD,SAAgB,gBAAgB,EAAE,gBAAgB,CAAA;IAClD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAQ;IAC9C,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CAAQ;IAChD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;IAC5B,OAAO,CAAC,kBAAkB,CAAiB;gBAE9B,UAAU,EAAE,+BAA+B,EAAE,IAAI,GAAE,yBAA8B;IAqC9F,QAAQ,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,wCAAuC;IAEpE,QAAQ,CAAC,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAGvC;IAED,IAAI,CAAC,mBAAmB,CAAC,IAAK,MAAM,EAAE,CASrC;IAED,QAAQ,CAAC,CAAC,eAAe,CAAC,QAAO;IAEjC,SAAS,IAAK,OAAO;IAIf,KAAK,IAAK,OAAO,CAAC,IAAI,CAAC;IA0BvB,IAAI,IAAK,OAAO,CAAC,IAAI,CAAC;IAQ5B;;OAEG;IACG,IAAI,CAAE,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,oBAAoB,CAAC,sBAAsB,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;IAyFtG;;OAEG;IACH,cAAc,CAAE,OAAO,EAAE,qBAAqB,GAAG,QAAQ;IAUzD;;OAEG;IACH,YAAY,CAAE,UAAU,EAAE,SAAS,EAAE,GAAG,SAAS,EAAE;IAQnD;;OAEG;IACH,UAAU,CAAE,UAAU,EAAE,SAAS,EAAE,GAAG,SAAS,EAAE;IAQjD;;OAEG;IACG,MAAM,CAAE,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,kBAAkB,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CAqF9F"}
@@ -1,314 +0,0 @@
1
- import { DialError, InvalidMessageError, serviceCapabilities, serviceDependencies, start, stop, transportSymbol } from '@libp2p/interface';
2
- import { peerFilter } from '@libp2p/peer-collections';
3
- import { peerIdFromMultihash, peerIdFromString } from '@libp2p/peer-id';
4
- import { streamToMaConnection } from '@libp2p/utils/stream-to-ma-conn';
5
- import { multiaddr } from '@multiformats/multiaddr';
6
- import { Circuit } from '@multiformats/multiaddr-matcher';
7
- import { pbStream } from 'it-protobuf-stream';
8
- import { setMaxListeners } from 'main-event';
9
- import * as Digest from 'multiformats/hashes/digest';
10
- import { CustomProgressEvent } from 'progress-events';
11
- import { CIRCUIT_PROTO_CODE, DEFAULT_DISCOVERY_FILTER_ERROR_RATE, DEFAULT_DISCOVERY_FILTER_SIZE, MAX_CONNECTIONS, RELAY_V2_HOP_CODEC, RELAY_V2_STOP_CODEC } from '../constants.js';
12
- import { StopMessage, HopMessage, Status } from '../pb/index.js';
13
- import { CircuitListen, CircuitSearch, LimitTracker } from '../utils.js';
14
- import { RelayDiscovery } from './discovery.js';
15
- import { createListener } from './listener.js';
16
- import { ReservationStore } from './reservation-store.js';
17
- const isValidStop = (request) => {
18
- if (request.peer == null) {
19
- return false;
20
- }
21
- try {
22
- request.peer.addrs.forEach(multiaddr);
23
- }
24
- catch {
25
- return false;
26
- }
27
- return true;
28
- };
29
- const defaults = {
30
- maxInboundStopStreams: MAX_CONNECTIONS,
31
- maxOutboundStopStreams: MAX_CONNECTIONS,
32
- stopTimeout: 30000
33
- };
34
- export class CircuitRelayTransport {
35
- discovery;
36
- registrar;
37
- peerStore;
38
- connectionManager;
39
- transportManager;
40
- peerId;
41
- upgrader;
42
- addressManager;
43
- connectionGater;
44
- reservationStore;
45
- logger;
46
- maxInboundStopStreams;
47
- maxOutboundStopStreams;
48
- started;
49
- log;
50
- shutdownController;
51
- constructor(components, init = {}) {
52
- this.log = components.logger.forComponent('libp2p:circuit-relay:transport');
53
- this.registrar = components.registrar;
54
- this.peerStore = components.peerStore;
55
- this.connectionManager = components.connectionManager;
56
- this.transportManager = components.transportManager;
57
- this.logger = components.logger;
58
- this.peerId = components.peerId;
59
- this.upgrader = components.upgrader;
60
- this.addressManager = components.addressManager;
61
- this.connectionGater = components.connectionGater;
62
- this.maxInboundStopStreams = init.maxInboundStopStreams ?? defaults.maxInboundStopStreams;
63
- this.maxOutboundStopStreams = init.maxOutboundStopStreams ?? defaults.maxOutboundStopStreams;
64
- this.shutdownController = new AbortController();
65
- this.discovery = new RelayDiscovery(components, {
66
- filter: init.discoveryFilter ?? peerFilter(DEFAULT_DISCOVERY_FILTER_SIZE, DEFAULT_DISCOVERY_FILTER_ERROR_RATE)
67
- });
68
- this.discovery.addEventListener('relay:discover', (evt) => {
69
- this.reservationStore.addRelay(evt.detail, 'discovered')
70
- .catch(err => {
71
- if (err.name !== 'HadEnoughRelaysError' && err.name !== 'RelayQueueFullError') {
72
- this.log.error('could not add discovered relay %p', evt.detail, err);
73
- }
74
- });
75
- });
76
- this.reservationStore = new ReservationStore(components, init);
77
- this.reservationStore.addEventListener('relay:not-enough-relays', () => {
78
- this.discovery?.startDiscovery();
79
- });
80
- this.reservationStore.addEventListener('relay:found-enough-relays', () => {
81
- this.discovery?.stopDiscovery();
82
- });
83
- this.started = false;
84
- }
85
- [Symbol.toStringTag] = '@libp2p/circuit-relay-v2-transport';
86
- [serviceCapabilities] = [
87
- '@libp2p/transport',
88
- '@libp2p/circuit-relay-v2-transport'
89
- ];
90
- get [serviceDependencies]() {
91
- // we only need identify if discovery is enabled
92
- if (this.discovery != null) {
93
- return [
94
- '@libp2p/identify'
95
- ];
96
- }
97
- return [];
98
- }
99
- [transportSymbol] = true;
100
- isStarted() {
101
- return this.started;
102
- }
103
- async start() {
104
- this.shutdownController = new AbortController();
105
- setMaxListeners(Infinity, this.shutdownController.signal);
106
- await this.registrar.handle(RELAY_V2_STOP_CODEC, (data) => {
107
- const signal = this.upgrader.createInboundAbortSignal(this.shutdownController.signal);
108
- void this.onStop(data, signal)
109
- .catch(err => {
110
- this.log.error('error while handling STOP protocol', err);
111
- data.stream.abort(err);
112
- })
113
- .finally(() => {
114
- signal.clear();
115
- });
116
- }, {
117
- maxInboundStreams: this.maxInboundStopStreams,
118
- maxOutboundStreams: this.maxOutboundStopStreams,
119
- runOnLimitedConnection: true
120
- });
121
- await start(this.discovery, this.reservationStore);
122
- this.started = true;
123
- }
124
- async stop() {
125
- this.shutdownController.abort();
126
- await stop(this.discovery, this.reservationStore);
127
- await this.registrar.unhandle(RELAY_V2_STOP_CODEC);
128
- this.started = false;
129
- }
130
- /**
131
- * Dial a peer over a relay
132
- */
133
- async dial(ma, options) {
134
- if (ma.protoCodes().filter(code => code === CIRCUIT_PROTO_CODE).length !== 1) {
135
- const errMsg = 'Invalid circuit relay address';
136
- this.log.error(errMsg, ma);
137
- throw new DialError(errMsg);
138
- }
139
- // Check the multiaddr to see if it contains a relay and a destination peer
140
- const addrs = ma.toString().split('/p2p-circuit');
141
- const relayAddr = multiaddr(addrs[0]);
142
- const destinationAddr = multiaddr(addrs[addrs.length - 1]);
143
- const relayId = relayAddr.getPeerId();
144
- const destinationId = destinationAddr.getPeerId();
145
- if (relayId == null || destinationId == null) {
146
- const errMsg = `ircuit relay dial to ${ma.toString()} failed as address did not have both relay and destination PeerIDs`;
147
- this.log.error(`c${errMsg}`);
148
- throw new DialError(`C${errMsg}`);
149
- }
150
- const relayPeer = peerIdFromString(relayId);
151
- const destinationPeer = peerIdFromString(destinationId);
152
- const relayConnections = this.connectionManager.getConnections(relayPeer);
153
- let relayConnection = relayConnections[0];
154
- if (relayConnection == null) {
155
- await this.peerStore.merge(relayPeer, {
156
- multiaddrs: [relayAddr]
157
- });
158
- options.onProgress?.(new CustomProgressEvent('circuit-relay:open-connection'));
159
- relayConnection = await this.connectionManager.openConnection(relayPeer, options);
160
- }
161
- else {
162
- options.onProgress?.(new CustomProgressEvent('circuit-relay:reuse-connection'));
163
- }
164
- let stream;
165
- try {
166
- options.onProgress?.(new CustomProgressEvent('circuit-relay:open-hop-stream'));
167
- stream = await relayConnection.newStream(RELAY_V2_HOP_CODEC, options);
168
- const pbstr = pbStream(stream);
169
- const hopstr = pbstr.pb(HopMessage);
170
- options.onProgress?.(new CustomProgressEvent('circuit-relay:write-connect-message'));
171
- await hopstr.write({
172
- type: HopMessage.Type.CONNECT,
173
- peer: {
174
- id: destinationPeer.toMultihash().bytes,
175
- addrs: [multiaddr(destinationAddr).bytes]
176
- }
177
- }, options);
178
- options.onProgress?.(new CustomProgressEvent('circuit-relay:read-connect-response'));
179
- const status = await hopstr.read(options);
180
- if (status.status !== Status.OK) {
181
- throw new InvalidMessageError(`failed to connect via relay with status ${status?.status?.toString() ?? 'undefined'}`);
182
- }
183
- const limits = new LimitTracker(status.limit);
184
- const maConn = streamToMaConnection({
185
- stream: pbstr.unwrap(),
186
- remoteAddr: ma,
187
- localAddr: relayAddr.encapsulate(`/p2p-circuit/p2p/${this.peerId.toString()}`),
188
- log: this.log,
189
- onDataRead: limits.onData,
190
- onDataWrite: limits.onData
191
- });
192
- const conn = await this.upgrader.upgradeOutbound(maConn, {
193
- ...options,
194
- limits: limits.getLimits()
195
- });
196
- conn.log('outbound relayed connection established to %p with limits %o, over connection %s', conn.remotePeer, status.limit ?? 'none', relayConnection.id);
197
- return conn;
198
- }
199
- catch (err) {
200
- this.log.error('circuit relay dial to destination %p via relay %p failed', destinationPeer, relayPeer, err);
201
- stream?.abort(err);
202
- throw err;
203
- }
204
- }
205
- /**
206
- * Create a listener
207
- */
208
- createListener(options) {
209
- return createListener({
210
- peerId: this.peerId,
211
- connectionManager: this.connectionManager,
212
- addressManager: this.addressManager,
213
- reservationStore: this.reservationStore,
214
- logger: this.logger
215
- });
216
- }
217
- /**
218
- * Filter check for all Multiaddrs that this transport can listen on
219
- */
220
- listenFilter(multiaddrs) {
221
- multiaddrs = Array.isArray(multiaddrs) ? multiaddrs : [multiaddrs];
222
- return multiaddrs.filter((ma) => {
223
- return CircuitListen.exactMatch(ma) || CircuitSearch.exactMatch(ma);
224
- });
225
- }
226
- /**
227
- * Filter check for all Multiaddrs that this transport can dial
228
- */
229
- dialFilter(multiaddrs) {
230
- multiaddrs = Array.isArray(multiaddrs) ? multiaddrs : [multiaddrs];
231
- return multiaddrs.filter((ma) => {
232
- return Circuit.exactMatch(ma);
233
- });
234
- }
235
- /**
236
- * An incoming STOP request means a remote peer wants to dial us via a relay
237
- */
238
- async onStop({ connection, stream }, signal) {
239
- if (!this.reservationStore.hasReservation(connection.remotePeer)) {
240
- try {
241
- this.log('dialed via relay we did not have a reservation on, start listening on that relay address');
242
- await this.transportManager.listen([connection.remoteAddr.encapsulate('/p2p-circuit')]);
243
- }
244
- catch (err) {
245
- // failed to refresh our hitherto unknown relay reservation but allow the connection attempt anyway
246
- this.log.error('failed to listen on a relay peer we were dialed via but did not have a reservation on', err);
247
- }
248
- }
249
- const pbstr = pbStream(stream).pb(StopMessage);
250
- const request = await pbstr.read({
251
- signal
252
- });
253
- this.log('new circuit relay v2 stop stream from %p with type %s', connection.remotePeer, request.type);
254
- if (request?.type === undefined) {
255
- this.log.error('type was missing from circuit v2 stop protocol request from %s', connection.remotePeer);
256
- await pbstr.write({ type: StopMessage.Type.STATUS, status: Status.MALFORMED_MESSAGE }, {
257
- signal
258
- });
259
- await stream.close();
260
- return;
261
- }
262
- // Validate the STOP request has the required input
263
- if (request.type !== StopMessage.Type.CONNECT) {
264
- this.log.error('invalid stop connect request via peer %p', connection.remotePeer);
265
- await pbstr.write({ type: StopMessage.Type.STATUS, status: Status.UNEXPECTED_MESSAGE }, {
266
- signal
267
- });
268
- await stream.close();
269
- return;
270
- }
271
- if (!isValidStop(request)) {
272
- this.log.error('invalid stop connect request via peer %p', connection.remotePeer);
273
- await pbstr.write({ type: StopMessage.Type.STATUS, status: Status.MALFORMED_MESSAGE }, {
274
- signal
275
- });
276
- await stream.close({
277
- signal
278
- });
279
- return;
280
- }
281
- const remotePeerId = peerIdFromMultihash(Digest.decode(request.peer.id));
282
- if ((await this.connectionGater.denyInboundRelayedConnection?.(connection.remotePeer, remotePeerId)) === true) {
283
- this.log.error('connection gater denied inbound relayed connection from %p', connection.remotePeer);
284
- await pbstr.write({ type: StopMessage.Type.STATUS, status: Status.PERMISSION_DENIED }, {
285
- signal
286
- });
287
- await stream.close({
288
- signal
289
- });
290
- return;
291
- }
292
- this.log.trace('sending success response to %p', connection.remotePeer);
293
- await pbstr.write({ type: StopMessage.Type.STATUS, status: Status.OK }, {
294
- signal
295
- });
296
- const limits = new LimitTracker(request.limit);
297
- const remoteAddr = connection.remoteAddr.encapsulate(`/p2p-circuit/p2p/${remotePeerId.toString()}`);
298
- const localAddr = this.addressManager.getAddresses()[0];
299
- const maConn = streamToMaConnection({
300
- stream: pbstr.unwrap().unwrap(),
301
- remoteAddr,
302
- localAddr,
303
- log: this.log,
304
- onDataRead: limits.onData,
305
- onDataWrite: limits.onData
306
- });
307
- await this.upgrader.upgradeInbound(maConn, {
308
- limits: limits.getLimits(),
309
- signal
310
- });
311
- maConn.log('inbound relayed connection established to %p with limits %o, over connection %s', remotePeerId, request.limit ?? 'none', connection.id);
312
- }
313
- }
314
- //# sourceMappingURL=transport.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"transport.js","sourceRoot":"","sources":["../../../src/transport/transport.ts"],"names":[],"mappings":"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"}