@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.
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +4 -4
- package/dist/src/index.d.ts +170 -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 +26 -43
- 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 +296 -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 +2 -4
- 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/index.ts +207 -8
- package/src/server/index.ts +32 -94
- package/src/server/reservation-store.ts +2 -42
- package/src/transport/discovery.ts +4 -22
- package/src/transport/index.ts +344 -46
- package/src/transport/reservation-store.ts +6 -44
- 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/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
|
-
|
15
|
+
function countStreamBytes (source: MessageStream, limit: { remaining: bigint }, options: LoggerOptions): void {
|
15
16
|
const limitBytes = limit.remaining
|
16
17
|
|
17
|
-
|
18
|
-
const len = BigInt(
|
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
|
-
|
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
|
-
|
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
|
-
|
69
|
-
|
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
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
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
|
-
|
65
|
+
abortStreams(err)
|
66
|
+
}
|
67
|
+
signal.addEventListener('abort', onAbort, { once: true })
|
98
68
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
})
|
104
|
-
.finally(() => {
|
105
|
-
dstSrcFinished = true
|
69
|
+
if (dataLimit != null) {
|
70
|
+
countStreamBytes(dst, dataLimit, options)
|
71
|
+
countStreamBytes(src, dataLimit, options)
|
72
|
+
}
|
106
73
|
|
107
|
-
|
108
|
-
|
109
|
-
|
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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"}
|