@replit/river 0.21.0 → 0.22.0
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/README.md +1 -1
- package/dist/{chunk-5WFL722S.js → chunk-3MFX6NXA.js} +94 -3
- package/dist/chunk-3MFX6NXA.js.map +1 -0
- package/dist/{chunk-NFV77C2M.js → chunk-GCLEWC26.js} +340 -507
- package/dist/chunk-GCLEWC26.js.map +1 -0
- package/dist/chunk-HUBFYN37.js +60 -0
- package/dist/chunk-HUBFYN37.js.map +1 -0
- package/dist/{chunk-DT5JS6TM.js → chunk-OTQNCLFH.js} +1 -1
- package/dist/chunk-OTQNCLFH.js.map +1 -0
- package/dist/{chunk-MJR36SUY.js → chunk-S3YKQT4J.js} +2 -2
- package/dist/{chunk-QU2EE6YU.js → chunk-ZPBWKBM5.js} +361 -394
- package/dist/chunk-ZPBWKBM5.js.map +1 -0
- package/dist/{connection-8a71dbe2.d.ts → connection-8b059ac4.d.ts} +6 -4
- package/dist/{connection-d49d5d56.d.ts → connection-bbfe1147.d.ts} +1 -1
- package/dist/{index-3ac92295.d.ts → index-2ece5234.d.ts} +18 -7
- package/dist/logging/index.cjs.map +1 -1
- package/dist/logging/index.d.cts +2 -1
- package/dist/logging/index.d.ts +2 -1
- package/dist/logging/index.js +1 -1
- package/dist/router/index.cjs +384 -492
- package/dist/router/index.cjs.map +1 -1
- package/dist/router/index.d.cts +5 -4
- package/dist/router/index.d.ts +5 -4
- package/dist/router/index.js +5 -4
- package/dist/{services-abc077db.d.ts → services-acbcc441.d.ts} +1 -1
- package/dist/{services-8496d6e8.d.ts → services-cb01a7a8.d.ts} +1 -1
- package/dist/transport/impls/uds/client.cjs +202 -155
- package/dist/transport/impls/uds/client.cjs.map +1 -1
- package/dist/transport/impls/uds/client.d.cts +3 -2
- package/dist/transport/impls/uds/client.d.ts +3 -2
- package/dist/transport/impls/uds/client.js +4 -4
- package/dist/transport/impls/uds/server.cjs +295 -264
- package/dist/transport/impls/uds/server.cjs.map +1 -1
- package/dist/transport/impls/uds/server.d.cts +3 -2
- package/dist/transport/impls/uds/server.d.ts +3 -2
- package/dist/transport/impls/uds/server.js +4 -4
- package/dist/transport/impls/ws/client.cjs +256 -214
- package/dist/transport/impls/ws/client.cjs.map +1 -1
- package/dist/transport/impls/ws/client.d.cts +6 -6
- package/dist/transport/impls/ws/client.d.ts +6 -6
- package/dist/transport/impls/ws/client.js +34 -49
- package/dist/transport/impls/ws/client.js.map +1 -1
- package/dist/transport/impls/ws/server.cjs +317 -278
- package/dist/transport/impls/ws/server.cjs.map +1 -1
- package/dist/transport/impls/ws/server.d.cts +5 -4
- package/dist/transport/impls/ws/server.d.ts +5 -4
- package/dist/transport/impls/ws/server.js +4 -4
- package/dist/transport/impls/ws/server.js.map +1 -1
- package/dist/transport/index.cjs +406 -391
- package/dist/transport/index.cjs.map +1 -1
- package/dist/transport/index.d.cts +5 -5
- package/dist/transport/index.d.ts +5 -5
- package/dist/transport/index.js +3 -3
- package/dist/util/testHelpers.cjs +71 -19
- package/dist/util/testHelpers.cjs.map +1 -1
- package/dist/util/testHelpers.d.cts +20 -8
- package/dist/util/testHelpers.d.ts +20 -8
- package/dist/util/testHelpers.js +13 -12
- package/dist/util/testHelpers.js.map +1 -1
- package/dist/wslike-e0b32dd5.d.ts +40 -0
- package/package.json +4 -5
- package/dist/chunk-2ERP6FUE.js +0 -42
- package/dist/chunk-2ERP6FUE.js.map +0 -1
- package/dist/chunk-5WFL722S.js.map +0 -1
- package/dist/chunk-DT5JS6TM.js.map +0 -1
- package/dist/chunk-NFV77C2M.js.map +0 -1
- package/dist/chunk-QU2EE6YU.js.map +0 -1
- /package/dist/{chunk-MJR36SUY.js.map → chunk-S3YKQT4J.js.map} +0 -0
|
@@ -4,31 +4,37 @@ import {
|
|
|
4
4
|
OpaqueTransportMessageSchema,
|
|
5
5
|
PROTOCOL_VERSION,
|
|
6
6
|
coerceErrorString,
|
|
7
|
+
createConnectionTelemetryInfo,
|
|
8
|
+
createSessionTelemetryInfo,
|
|
9
|
+
getPropagationContext,
|
|
7
10
|
handshakeRequestMessage,
|
|
8
11
|
handshakeResponseMessage,
|
|
9
12
|
isAck,
|
|
10
13
|
tracing_default
|
|
11
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-3MFX6NXA.js";
|
|
12
15
|
import {
|
|
13
16
|
log
|
|
14
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-OTQNCLFH.js";
|
|
15
18
|
import {
|
|
16
19
|
NaiveJsonCodec
|
|
17
20
|
} from "./chunk-3AW3IXVD.js";
|
|
18
21
|
|
|
19
22
|
// transport/session.ts
|
|
20
23
|
import { customAlphabet } from "nanoid";
|
|
24
|
+
import { SpanStatusCode } from "@opentelemetry/api";
|
|
21
25
|
var nanoid = customAlphabet("1234567890abcdefghijklmnopqrstuvxyz", 6);
|
|
22
26
|
var unsafeId = () => nanoid();
|
|
23
27
|
var Connection = class {
|
|
24
|
-
|
|
28
|
+
id;
|
|
29
|
+
telemetry;
|
|
25
30
|
constructor() {
|
|
26
|
-
this.
|
|
31
|
+
this.id = `conn-${nanoid(12)}`;
|
|
27
32
|
}
|
|
28
33
|
};
|
|
29
34
|
var Session = class {
|
|
30
35
|
codec;
|
|
31
36
|
options;
|
|
37
|
+
telemetry;
|
|
32
38
|
/**
|
|
33
39
|
* The buffer of messages that have been sent but not yet acknowledged.
|
|
34
40
|
*/
|
|
@@ -75,7 +81,7 @@ var Session = class {
|
|
|
75
81
|
* The interval for sending heartbeats.
|
|
76
82
|
*/
|
|
77
83
|
heartbeat;
|
|
78
|
-
constructor(conn, from, to, options) {
|
|
84
|
+
constructor(conn, from, to, options, propagationCtx) {
|
|
79
85
|
this.id = `session-${nanoid(12)}`;
|
|
80
86
|
this.options = options;
|
|
81
87
|
this.from = from;
|
|
@@ -87,13 +93,14 @@ var Session = class {
|
|
|
87
93
|
() => this.sendHeartbeat(),
|
|
88
94
|
options.heartbeatIntervalMs
|
|
89
95
|
);
|
|
96
|
+
this.telemetry = createSessionTelemetryInfo(this, propagationCtx);
|
|
90
97
|
}
|
|
91
98
|
get loggingMetadata() {
|
|
92
99
|
return {
|
|
93
100
|
clientId: this.from,
|
|
94
101
|
connectedTo: this.to,
|
|
95
102
|
sessionId: this.id,
|
|
96
|
-
connId: this.connection?.
|
|
103
|
+
connId: this.connection?.id
|
|
97
104
|
};
|
|
98
105
|
}
|
|
99
106
|
/**
|
|
@@ -138,6 +145,7 @@ var Session = class {
|
|
|
138
145
|
`closing connection to ${this.to} due to inactivity (missed ${misses} heartbeats which is ${missDuration}ms)`,
|
|
139
146
|
this.loggingMetadata
|
|
140
147
|
);
|
|
148
|
+
this.telemetry.span.addEvent("closing connection due to inactivity");
|
|
141
149
|
this.closeStaleConnection();
|
|
142
150
|
}
|
|
143
151
|
return;
|
|
@@ -159,32 +167,38 @@ var Session = class {
|
|
|
159
167
|
sendBufferedMessages(conn) {
|
|
160
168
|
log?.info(`resending ${this.sendBuffer.length} buffered messages`, {
|
|
161
169
|
...this.loggingMetadata,
|
|
162
|
-
connId: conn.
|
|
170
|
+
connId: conn.id
|
|
163
171
|
});
|
|
164
172
|
for (const msg of this.sendBuffer) {
|
|
165
173
|
log?.debug(`resending msg`, {
|
|
166
174
|
...this.loggingMetadata,
|
|
167
175
|
fullTransportMessage: msg,
|
|
168
|
-
connId: conn.
|
|
176
|
+
connId: conn.id
|
|
169
177
|
});
|
|
170
178
|
const ok = conn.send(this.codec.toBuffer(msg));
|
|
171
179
|
if (!ok) {
|
|
172
180
|
const errMsg = `failed to send buffered message to ${this.to} (sus, this is a fresh connection)`;
|
|
181
|
+
conn.telemetry?.span.setStatus({
|
|
182
|
+
code: SpanStatusCode.ERROR,
|
|
183
|
+
message: errMsg
|
|
184
|
+
});
|
|
173
185
|
log?.error(errMsg, {
|
|
174
186
|
...this.loggingMetadata,
|
|
175
187
|
fullTransportMessage: msg,
|
|
176
|
-
connId: conn.
|
|
188
|
+
connId: conn.id,
|
|
189
|
+
tags: ["invariant-violation"]
|
|
177
190
|
});
|
|
178
|
-
|
|
191
|
+
conn.close();
|
|
192
|
+
return;
|
|
179
193
|
}
|
|
180
194
|
}
|
|
181
195
|
}
|
|
182
196
|
updateBookkeeping(ack, seq) {
|
|
183
197
|
if (seq + 1 < this.ack) {
|
|
184
|
-
log?.error(
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
);
|
|
198
|
+
log?.error(`received stale seq ${seq} + 1 < ${this.ack}`, {
|
|
199
|
+
...this.loggingMetadata,
|
|
200
|
+
tags: ["invariant-violation"]
|
|
201
|
+
});
|
|
188
202
|
return;
|
|
189
203
|
}
|
|
190
204
|
this.sendBuffer = this.sendBuffer.filter((unacked) => unacked.seq >= ack);
|
|
@@ -290,12 +304,6 @@ var EventDispatcher = class {
|
|
|
290
304
|
|
|
291
305
|
// transport/transport.ts
|
|
292
306
|
import { Value } from "@sinclair/typebox/value";
|
|
293
|
-
import {
|
|
294
|
-
context,
|
|
295
|
-
propagation,
|
|
296
|
-
SpanKind,
|
|
297
|
-
SpanStatusCode
|
|
298
|
-
} from "@opentelemetry/api";
|
|
299
307
|
|
|
300
308
|
// transport/rateLimit.ts
|
|
301
309
|
var LeakyBucketRateLimit = class {
|
|
@@ -369,6 +377,7 @@ var LeakyBucketRateLimit = class {
|
|
|
369
377
|
};
|
|
370
378
|
|
|
371
379
|
// transport/transport.ts
|
|
380
|
+
import { SpanStatusCode as SpanStatusCode2 } from "@opentelemetry/api";
|
|
372
381
|
var defaultTransportOptions = {
|
|
373
382
|
heartbeatIntervalMs: 1e3,
|
|
374
383
|
heartbeatsUntilDead: 2,
|
|
@@ -447,17 +456,22 @@ var Transport = class {
|
|
|
447
456
|
status: "connect",
|
|
448
457
|
conn
|
|
449
458
|
});
|
|
459
|
+
conn.telemetry = createConnectionTelemetryInfo(
|
|
460
|
+
conn,
|
|
461
|
+
session.telemetry.span
|
|
462
|
+
);
|
|
450
463
|
if (isReconnect) {
|
|
451
464
|
session.replaceWithNewConnection(conn);
|
|
452
465
|
log?.info(`reconnected to ${connectedTo}`, session.loggingMetadata);
|
|
453
466
|
}
|
|
454
467
|
}
|
|
455
|
-
createSession(to, conn) {
|
|
468
|
+
createSession(to, conn, propagationCtx) {
|
|
456
469
|
const session = new Session(
|
|
457
470
|
conn,
|
|
458
471
|
this.clientId,
|
|
459
472
|
to,
|
|
460
|
-
this.options
|
|
473
|
+
this.options,
|
|
474
|
+
propagationCtx
|
|
461
475
|
);
|
|
462
476
|
this.sessions.set(session.to, session);
|
|
463
477
|
this.eventDispatcher.dispatchEvent("sessionStatus", {
|
|
@@ -466,11 +480,11 @@ var Transport = class {
|
|
|
466
480
|
});
|
|
467
481
|
return session;
|
|
468
482
|
}
|
|
469
|
-
getOrCreateSession(to, conn, sessionId) {
|
|
483
|
+
getOrCreateSession(to, conn, sessionId, propagationCtx) {
|
|
470
484
|
let session = this.sessions.get(to);
|
|
471
485
|
let isReconnect = session !== void 0;
|
|
472
486
|
if (session?.advertisedSessionId !== void 0 && sessionId !== void 0 && session.advertisedSessionId !== sessionId) {
|
|
473
|
-
log?.
|
|
487
|
+
log?.info(
|
|
474
488
|
`session for ${to} already exists but has a different session id (expected: ${session.advertisedSessionId}, got: ${sessionId}), creating a new one`,
|
|
475
489
|
session.loggingMetadata
|
|
476
490
|
);
|
|
@@ -479,7 +493,7 @@ var Transport = class {
|
|
|
479
493
|
session = void 0;
|
|
480
494
|
}
|
|
481
495
|
if (!session) {
|
|
482
|
-
session = this.createSession(to, conn);
|
|
496
|
+
session = this.createSession(to, conn, propagationCtx);
|
|
483
497
|
log?.info(
|
|
484
498
|
`no session for ${to}, created a new one`,
|
|
485
499
|
session.loggingMetadata
|
|
@@ -492,6 +506,7 @@ var Transport = class {
|
|
|
492
506
|
}
|
|
493
507
|
deleteSession(session) {
|
|
494
508
|
session.close();
|
|
509
|
+
session.telemetry.span.end();
|
|
495
510
|
this.sessions.delete(session.to);
|
|
496
511
|
log?.info(
|
|
497
512
|
`session ${session.id} disconnect from ${session.to}`,
|
|
@@ -508,12 +523,16 @@ var Transport = class {
|
|
|
508
523
|
* @param connectedTo The peer we are connected to.
|
|
509
524
|
*/
|
|
510
525
|
onDisconnect(conn, session) {
|
|
526
|
+
conn.telemetry?.span.end();
|
|
511
527
|
this.eventDispatcher.dispatchEvent("connectionStatus", {
|
|
512
528
|
status: "disconnect",
|
|
513
529
|
conn
|
|
514
530
|
});
|
|
515
531
|
session.connection = void 0;
|
|
516
|
-
session.beginGrace(() =>
|
|
532
|
+
session.beginGrace(() => {
|
|
533
|
+
session.telemetry.span.addEvent("session grace period expired");
|
|
534
|
+
this.deleteSession(session);
|
|
535
|
+
});
|
|
517
536
|
}
|
|
518
537
|
/**
|
|
519
538
|
* Parses a message from a Uint8Array into a {@link OpaqueTransportMessage}.
|
|
@@ -547,9 +566,10 @@ var Transport = class {
|
|
|
547
566
|
return;
|
|
548
567
|
const session = this.sessions.get(msg.from);
|
|
549
568
|
if (!session) {
|
|
550
|
-
log?.error(`
|
|
569
|
+
log?.error(`no existing session for ${msg.from}`, {
|
|
551
570
|
clientId: this.clientId,
|
|
552
|
-
fullTransportMessage: msg
|
|
571
|
+
fullTransportMessage: msg,
|
|
572
|
+
tags: ["invariant-violation"]
|
|
553
573
|
});
|
|
554
574
|
return;
|
|
555
575
|
}
|
|
@@ -568,9 +588,14 @@ var Transport = class {
|
|
|
568
588
|
const errMsg = `received out-of-order msg (got seq: ${msg.seq}, wanted seq: ${session.nextExpectedSeq})`;
|
|
569
589
|
log?.error(`${errMsg}, marking connection as dead`, {
|
|
570
590
|
clientId: this.clientId,
|
|
571
|
-
fullTransportMessage: msg
|
|
591
|
+
fullTransportMessage: msg,
|
|
592
|
+
tags: ["invariant-violation"]
|
|
572
593
|
});
|
|
573
594
|
this.protocolError(ProtocolError.MessageOrderingViolated, errMsg);
|
|
595
|
+
session.telemetry.span.setStatus({
|
|
596
|
+
code: SpanStatusCode2.ERROR,
|
|
597
|
+
message: "message order violated"
|
|
598
|
+
});
|
|
574
599
|
session.close();
|
|
575
600
|
}
|
|
576
601
|
return;
|
|
@@ -612,7 +637,8 @@ var Transport = class {
|
|
|
612
637
|
const err = "transport is destroyed, cant send";
|
|
613
638
|
log?.error(err, {
|
|
614
639
|
clientId: this.clientId,
|
|
615
|
-
partialTransportMessage: msg
|
|
640
|
+
partialTransportMessage: msg,
|
|
641
|
+
tags: ["invariant-violation"]
|
|
616
642
|
});
|
|
617
643
|
this.protocolError(ProtocolError.UseAfterDestroy, err);
|
|
618
644
|
return void 0;
|
|
@@ -697,7 +723,7 @@ var ClientTransport = class extends Transport {
|
|
|
697
723
|
if (!session) {
|
|
698
724
|
log?.warn(
|
|
699
725
|
`connection to ${to} timed out waiting for handshake, closing`,
|
|
700
|
-
{ clientId: this.clientId, connectedTo: to, connId: conn.
|
|
726
|
+
{ clientId: this.clientId, connectedTo: to, connId: conn.id }
|
|
701
727
|
);
|
|
702
728
|
conn.close();
|
|
703
729
|
}
|
|
@@ -715,6 +741,10 @@ var ClientTransport = class extends Transport {
|
|
|
715
741
|
conn.addDataListener((data2) => {
|
|
716
742
|
const parsed = this.parseMsg(data2);
|
|
717
743
|
if (!parsed) {
|
|
744
|
+
conn.telemetry?.span.setStatus({
|
|
745
|
+
code: SpanStatusCode2.ERROR,
|
|
746
|
+
message: "message parse failure"
|
|
747
|
+
});
|
|
718
748
|
conn.close();
|
|
719
749
|
return;
|
|
720
750
|
}
|
|
@@ -737,6 +767,10 @@ var ClientTransport = class extends Transport {
|
|
|
737
767
|
}
|
|
738
768
|
});
|
|
739
769
|
conn.addErrorListener((err) => {
|
|
770
|
+
conn.telemetry?.span.setStatus({
|
|
771
|
+
code: SpanStatusCode2.ERROR,
|
|
772
|
+
message: "connection error"
|
|
773
|
+
});
|
|
740
774
|
log?.warn(`error in connection to ${to}: ${coerceErrorString(err)}`, {
|
|
741
775
|
...session?.loggingMetadata,
|
|
742
776
|
clientId: this.clientId,
|
|
@@ -747,6 +781,10 @@ var ClientTransport = class extends Transport {
|
|
|
747
781
|
receiveHandshakeResponseMessage(data, conn) {
|
|
748
782
|
const parsed = this.parseMsg(data);
|
|
749
783
|
if (!parsed) {
|
|
784
|
+
conn.telemetry?.span.setStatus({
|
|
785
|
+
code: SpanStatusCode2.ERROR,
|
|
786
|
+
message: "non-transport message"
|
|
787
|
+
});
|
|
750
788
|
this.protocolError(
|
|
751
789
|
ProtocolError.HandshakeFailed,
|
|
752
790
|
"received non-transport message"
|
|
@@ -754,6 +792,10 @@ var ClientTransport = class extends Transport {
|
|
|
754
792
|
return false;
|
|
755
793
|
}
|
|
756
794
|
if (!Value.Check(ControlMessageHandshakeResponseSchema, parsed.payload)) {
|
|
795
|
+
conn.telemetry?.span.setStatus({
|
|
796
|
+
code: SpanStatusCode2.ERROR,
|
|
797
|
+
message: "invalid handshake response"
|
|
798
|
+
});
|
|
757
799
|
log?.warn(`received invalid handshake resp`, {
|
|
758
800
|
clientId: this.clientId,
|
|
759
801
|
connectedTo: parsed.from,
|
|
@@ -766,7 +808,11 @@ var ClientTransport = class extends Transport {
|
|
|
766
808
|
return false;
|
|
767
809
|
}
|
|
768
810
|
if (!parsed.payload.status.ok) {
|
|
769
|
-
|
|
811
|
+
conn.telemetry?.span.setStatus({
|
|
812
|
+
code: SpanStatusCode2.ERROR,
|
|
813
|
+
message: "handshake rejected"
|
|
814
|
+
});
|
|
815
|
+
log?.warn(`received handshake rejection`, {
|
|
770
816
|
clientId: this.clientId,
|
|
771
817
|
connectedTo: parsed.from,
|
|
772
818
|
fullTransportMessage: parsed
|
|
@@ -796,142 +842,94 @@ var ClientTransport = class extends Transport {
|
|
|
796
842
|
* @param to The client ID of the node to connect to.
|
|
797
843
|
*/
|
|
798
844
|
async connect(to) {
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
span.recordException(coerceErrorString(e));
|
|
816
|
-
}
|
|
817
|
-
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
818
|
-
} finally {
|
|
819
|
-
span.end();
|
|
820
|
-
}
|
|
845
|
+
const canProceedWithConnection = () => this.state === "open";
|
|
846
|
+
if (!canProceedWithConnection()) {
|
|
847
|
+
log?.info(
|
|
848
|
+
`transport state is no longer open, cancelling attempt to connect to ${to}`,
|
|
849
|
+
{ clientId: this.clientId, connectedTo: to }
|
|
850
|
+
);
|
|
851
|
+
return;
|
|
852
|
+
}
|
|
853
|
+
let reconnectPromise = this.inflightConnectionPromises.get(to);
|
|
854
|
+
if (!reconnectPromise) {
|
|
855
|
+
const budgetConsumed = this.retryBudget.getBudgetConsumed(to);
|
|
856
|
+
if (!this.retryBudget.hasBudget(to)) {
|
|
857
|
+
const errMsg = `tried to connect to ${to} but retry budget exceeded (more than ${budgetConsumed} attempts in the last ${this.retryBudget.totalBudgetRestoreTime}ms)`;
|
|
858
|
+
log?.warn(errMsg, { clientId: this.clientId, connectedTo: to });
|
|
859
|
+
this.protocolError(ProtocolError.RetriesExceeded, errMsg);
|
|
860
|
+
return;
|
|
821
861
|
}
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
{
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
kind: SpanKind.CLIENT
|
|
834
|
-
},
|
|
835
|
-
async (span) => {
|
|
862
|
+
let sleep = Promise.resolve();
|
|
863
|
+
const backoffMs = this.retryBudget.getBackoffMs(to);
|
|
864
|
+
if (backoffMs > 0) {
|
|
865
|
+
sleep = new Promise((resolve) => setTimeout(resolve, backoffMs));
|
|
866
|
+
}
|
|
867
|
+
log?.info(`attempting connection to ${to} (${backoffMs}ms backoff)`, {
|
|
868
|
+
clientId: this.clientId,
|
|
869
|
+
connectedTo: to
|
|
870
|
+
});
|
|
871
|
+
this.retryBudget.consumeBudget(to);
|
|
872
|
+
reconnectPromise = tracing_default.startActiveSpan("connect", async (span) => {
|
|
836
873
|
try {
|
|
837
|
-
|
|
874
|
+
span.addEvent("backoff", { backoffMs });
|
|
875
|
+
await sleep;
|
|
838
876
|
if (!canProceedWithConnection()) {
|
|
839
|
-
|
|
840
|
-
`transport state is no longer open, cancelling attempt to connect to ${to}`,
|
|
841
|
-
{ clientId: this.clientId, connectedTo: to }
|
|
842
|
-
);
|
|
843
|
-
return false;
|
|
877
|
+
throw new Error("transport state is no longer open");
|
|
844
878
|
}
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
if (!this.retryBudget.hasBudget(to)) {
|
|
849
|
-
const errMsg = `tried to connect to ${to} but retry budget exceeded (more than ${budgetConsumed} attempts in the last ${this.retryBudget.totalBudgetRestoreTime}ms)`;
|
|
850
|
-
log?.warn(errMsg, { clientId: this.clientId, connectedTo: to });
|
|
851
|
-
this.protocolError(ProtocolError.RetriesExceeded, errMsg);
|
|
852
|
-
return false;
|
|
853
|
-
}
|
|
854
|
-
let sleep = Promise.resolve();
|
|
855
|
-
const backoffMs = this.retryBudget.getBackoffMs(to);
|
|
856
|
-
if (backoffMs > 0) {
|
|
857
|
-
sleep = new Promise((resolve) => setTimeout(resolve, backoffMs));
|
|
858
|
-
}
|
|
859
|
-
log?.info(
|
|
860
|
-
`attempting connection to ${to} (${backoffMs}ms backoff)`,
|
|
861
|
-
{
|
|
862
|
-
clientId: this.clientId,
|
|
863
|
-
connectedTo: to
|
|
864
|
-
}
|
|
865
|
-
);
|
|
866
|
-
this.retryBudget.consumeBudget(to);
|
|
867
|
-
reconnectPromise = sleep.then(() => {
|
|
868
|
-
if (!canProceedWithConnection()) {
|
|
869
|
-
throw new Error("transport state is no longer open");
|
|
870
|
-
}
|
|
871
|
-
}).then(() => this.createNewOutgoingConnection(to)).then((conn) => {
|
|
872
|
-
if (!canProceedWithConnection()) {
|
|
873
|
-
log?.info(
|
|
874
|
-
`transport state is no longer open, closing pre-handshake connection to ${to}`,
|
|
875
|
-
{
|
|
876
|
-
clientId: this.clientId,
|
|
877
|
-
connectedTo: to,
|
|
878
|
-
connId: conn.debugId
|
|
879
|
-
}
|
|
880
|
-
);
|
|
881
|
-
conn.close();
|
|
882
|
-
throw new Error("transport state is no longer open");
|
|
883
|
-
}
|
|
884
|
-
return this.sendHandshake(to, conn).then((ok) => {
|
|
885
|
-
if (!ok) {
|
|
886
|
-
conn.close();
|
|
887
|
-
throw new Error("failed to send handshake");
|
|
888
|
-
}
|
|
889
|
-
return conn;
|
|
890
|
-
});
|
|
891
|
-
});
|
|
892
|
-
this.inflightConnectionPromises.set(to, reconnectPromise);
|
|
893
|
-
} else {
|
|
879
|
+
span.addEvent("connecting");
|
|
880
|
+
const conn = await this.createNewOutgoingConnection(to);
|
|
881
|
+
if (!canProceedWithConnection()) {
|
|
894
882
|
log?.info(
|
|
895
|
-
`
|
|
883
|
+
`transport state is no longer open, closing pre-handshake connection to ${to}`,
|
|
896
884
|
{
|
|
897
885
|
clientId: this.clientId,
|
|
898
|
-
connectedTo: to
|
|
886
|
+
connectedTo: to,
|
|
887
|
+
connId: conn.id
|
|
899
888
|
}
|
|
900
889
|
);
|
|
890
|
+
conn.close();
|
|
891
|
+
throw new Error("transport state is no longer open");
|
|
901
892
|
}
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
if (!this.reconnectOnConnectionDrop || !canProceedWithConnection()) {
|
|
908
|
-
log?.warn(`connection to ${to} failed (${errStr})`, {
|
|
909
|
-
clientId: this.clientId,
|
|
910
|
-
connectedTo: to
|
|
911
|
-
});
|
|
912
|
-
} else {
|
|
913
|
-
log?.warn(`connection to ${to} failed (${errStr}), retrying`, {
|
|
914
|
-
clientId: this.clientId,
|
|
915
|
-
connectedTo: to
|
|
916
|
-
});
|
|
917
|
-
return true;
|
|
918
|
-
}
|
|
919
|
-
}
|
|
920
|
-
} catch (e) {
|
|
921
|
-
if (e instanceof Error) {
|
|
922
|
-
span.recordException(e);
|
|
923
|
-
} else {
|
|
924
|
-
span.recordException(coerceErrorString(e));
|
|
893
|
+
span.addEvent("sending handshake");
|
|
894
|
+
const ok = await this.sendHandshake(to, conn);
|
|
895
|
+
if (!ok) {
|
|
896
|
+
conn.close();
|
|
897
|
+
throw new Error("failed to send handshake");
|
|
925
898
|
}
|
|
926
|
-
|
|
899
|
+
return conn;
|
|
900
|
+
} catch (err) {
|
|
901
|
+
const errStr = coerceErrorString(err);
|
|
902
|
+
span.recordException(errStr);
|
|
903
|
+
span.setStatus({ code: SpanStatusCode2.ERROR });
|
|
904
|
+
throw err;
|
|
927
905
|
} finally {
|
|
928
906
|
span.end();
|
|
929
907
|
}
|
|
930
|
-
|
|
908
|
+
});
|
|
909
|
+
this.inflightConnectionPromises.set(to, reconnectPromise);
|
|
910
|
+
} else {
|
|
911
|
+
log?.info(`attempting connection to ${to} (reusing previous attempt)`, {
|
|
912
|
+
clientId: this.clientId,
|
|
913
|
+
connectedTo: to
|
|
914
|
+
});
|
|
915
|
+
}
|
|
916
|
+
try {
|
|
917
|
+
await reconnectPromise;
|
|
918
|
+
} catch (error) {
|
|
919
|
+
this.inflightConnectionPromises.delete(to);
|
|
920
|
+
const errStr = coerceErrorString(error);
|
|
921
|
+
if (!this.reconnectOnConnectionDrop || !canProceedWithConnection()) {
|
|
922
|
+
log?.warn(`connection to ${to} failed (${errStr})`, {
|
|
923
|
+
clientId: this.clientId,
|
|
924
|
+
connectedTo: to
|
|
925
|
+
});
|
|
926
|
+
} else {
|
|
927
|
+
log?.warn(`connection to ${to} failed (${errStr}), retrying`, {
|
|
928
|
+
clientId: this.clientId,
|
|
929
|
+
connectedTo: to
|
|
930
|
+
});
|
|
931
|
+
return this.connect(to);
|
|
931
932
|
}
|
|
932
|
-
);
|
|
933
|
-
if (retry) {
|
|
934
|
-
return this.connectAttempt(to, attempt + 1);
|
|
935
933
|
}
|
|
936
934
|
}
|
|
937
935
|
deleteSession(session) {
|
|
@@ -939,20 +937,23 @@ var ClientTransport = class extends Transport {
|
|
|
939
937
|
super.deleteSession(session);
|
|
940
938
|
}
|
|
941
939
|
async sendHandshake(to, conn) {
|
|
942
|
-
const tracing = { traceparent: "", tracestate: "" };
|
|
943
|
-
propagation.inject(context.active(), tracing);
|
|
944
940
|
let metadata;
|
|
945
941
|
if (this.options.handshake) {
|
|
946
942
|
metadata = await this.options.handshake.get();
|
|
947
943
|
if (!Value.Check(this.options.handshake.schema, metadata)) {
|
|
948
944
|
log?.error(`handshake metadata did not match schema`, {
|
|
949
945
|
clientId: this.clientId,
|
|
950
|
-
connectedTo: to
|
|
946
|
+
connectedTo: to,
|
|
947
|
+
tags: ["invariant-violation"]
|
|
951
948
|
});
|
|
952
949
|
this.protocolError(
|
|
953
950
|
ProtocolError.HandshakeFailed,
|
|
954
951
|
"handshake metadata did not match schema"
|
|
955
952
|
);
|
|
953
|
+
conn.telemetry?.span.setStatus({
|
|
954
|
+
code: SpanStatusCode2.ERROR,
|
|
955
|
+
message: "handshake meta mismatch"
|
|
956
|
+
});
|
|
956
957
|
return false;
|
|
957
958
|
}
|
|
958
959
|
}
|
|
@@ -962,7 +963,7 @@ var ClientTransport = class extends Transport {
|
|
|
962
963
|
to,
|
|
963
964
|
session.id,
|
|
964
965
|
metadata,
|
|
965
|
-
|
|
966
|
+
getPropagationContext(session.telemetry.ctx)
|
|
966
967
|
);
|
|
967
968
|
log?.debug(`sending handshake request to ${to}`, {
|
|
968
969
|
clientId: this.clientId,
|
|
@@ -993,267 +994,233 @@ var ServerTransport = class extends Transport {
|
|
|
993
994
|
});
|
|
994
995
|
}
|
|
995
996
|
handleConnection(conn) {
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
(
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
997
|
+
if (this.state !== "open")
|
|
998
|
+
return;
|
|
999
|
+
log?.info(`new incoming connection`, {
|
|
1000
|
+
clientId: this.clientId,
|
|
1001
|
+
connId: conn.id
|
|
1002
|
+
});
|
|
1003
|
+
let session = void 0;
|
|
1004
|
+
const client = () => session?.to ?? "unknown";
|
|
1005
|
+
const handshakeTimeout = setTimeout(() => {
|
|
1006
|
+
if (!session) {
|
|
1007
|
+
log?.warn(
|
|
1008
|
+
`connection to ${client()} timed out waiting for handshake, closing`,
|
|
1009
|
+
{
|
|
1010
|
+
clientId: this.clientId,
|
|
1011
|
+
connectedTo: client(),
|
|
1012
|
+
connId: conn.id
|
|
1013
|
+
}
|
|
1014
|
+
);
|
|
1015
|
+
conn.telemetry?.span.setStatus({
|
|
1016
|
+
code: SpanStatusCode2.ERROR,
|
|
1017
|
+
message: "handshake timeout"
|
|
1011
1018
|
});
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1019
|
+
conn.close();
|
|
1020
|
+
}
|
|
1021
|
+
}, this.options.sessionDisconnectGraceMs);
|
|
1022
|
+
const buffer = [];
|
|
1023
|
+
let receivedHandshakeMessage = false;
|
|
1024
|
+
const handshakeHandler = (data) => {
|
|
1025
|
+
if (receivedHandshakeMessage) {
|
|
1026
|
+
buffer.push(data);
|
|
1027
|
+
return;
|
|
1028
|
+
}
|
|
1029
|
+
receivedHandshakeMessage = true;
|
|
1030
|
+
clearTimeout(handshakeTimeout);
|
|
1031
|
+
void this.receiveHandshakeRequestMessage(data, conn).then(
|
|
1032
|
+
(maybeSession) => {
|
|
1033
|
+
if (!maybeSession) {
|
|
1026
1034
|
conn.close();
|
|
1027
|
-
}
|
|
1028
|
-
}, this.options.sessionDisconnectGraceMs);
|
|
1029
|
-
const buffer = [];
|
|
1030
|
-
let receivedHandshakeMessage = false;
|
|
1031
|
-
const handshakeHandler = (data) => {
|
|
1032
|
-
if (receivedHandshakeMessage) {
|
|
1033
|
-
buffer.push(data);
|
|
1034
1035
|
return;
|
|
1035
1036
|
}
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
(
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
span.end();
|
|
1043
|
-
conn.close();
|
|
1044
|
-
return;
|
|
1045
|
-
}
|
|
1046
|
-
session = maybeSession;
|
|
1047
|
-
const dataHandler = (data2) => {
|
|
1048
|
-
const parsed = this.parseMsg(data2);
|
|
1049
|
-
if (!parsed) {
|
|
1050
|
-
conn.close();
|
|
1051
|
-
return;
|
|
1052
|
-
}
|
|
1053
|
-
this.handleMsg(parsed);
|
|
1054
|
-
};
|
|
1055
|
-
conn.removeDataListener(handshakeHandler);
|
|
1056
|
-
conn.addDataListener(dataHandler);
|
|
1057
|
-
for (const data2 of buffer) {
|
|
1058
|
-
dataHandler(data2);
|
|
1059
|
-
}
|
|
1060
|
-
buffer.length = 0;
|
|
1037
|
+
session = maybeSession;
|
|
1038
|
+
const dataHandler = (data2) => {
|
|
1039
|
+
const parsed = this.parseMsg(data2);
|
|
1040
|
+
if (!parsed) {
|
|
1041
|
+
conn.close();
|
|
1042
|
+
return;
|
|
1061
1043
|
}
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
if (session) {
|
|
1067
|
-
log?.info(`connection to ${client()} disconnected`, {
|
|
1068
|
-
clientId: this.clientId,
|
|
1069
|
-
connId: conn.debugId
|
|
1070
|
-
});
|
|
1071
|
-
this.onDisconnect(conn, session);
|
|
1072
|
-
}
|
|
1073
|
-
span.setStatus({ code: SpanStatusCode.OK });
|
|
1074
|
-
span.end();
|
|
1075
|
-
});
|
|
1076
|
-
conn.addErrorListener((err) => {
|
|
1077
|
-
if (session) {
|
|
1078
|
-
log?.warn(
|
|
1079
|
-
`connection to ${client()} got an error: ${coerceErrorString(
|
|
1080
|
-
err
|
|
1081
|
-
)}`,
|
|
1082
|
-
{ clientId: this.clientId, connId: conn.debugId }
|
|
1083
|
-
);
|
|
1044
|
+
this.handleMsg(parsed);
|
|
1045
|
+
};
|
|
1046
|
+
for (const data2 of buffer) {
|
|
1047
|
+
dataHandler(data2);
|
|
1084
1048
|
}
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1049
|
+
conn.removeDataListener(handshakeHandler);
|
|
1050
|
+
conn.addDataListener(dataHandler);
|
|
1051
|
+
buffer.length = 0;
|
|
1052
|
+
}
|
|
1053
|
+
);
|
|
1054
|
+
};
|
|
1055
|
+
conn.addDataListener(handshakeHandler);
|
|
1056
|
+
conn.addCloseListener(() => {
|
|
1057
|
+
if (!session)
|
|
1058
|
+
return;
|
|
1059
|
+
log?.info(`connection to ${client()} disconnected`, {
|
|
1060
|
+
clientId: this.clientId,
|
|
1061
|
+
connId: conn.id
|
|
1062
|
+
});
|
|
1063
|
+
this.onDisconnect(conn, session);
|
|
1064
|
+
});
|
|
1065
|
+
conn.addErrorListener((err) => {
|
|
1066
|
+
conn.telemetry?.span.setStatus({
|
|
1067
|
+
code: SpanStatusCode2.ERROR,
|
|
1068
|
+
message: "connection error"
|
|
1069
|
+
});
|
|
1070
|
+
if (!session)
|
|
1071
|
+
return;
|
|
1072
|
+
log?.warn(
|
|
1073
|
+
`connection to ${client()} got an error: ${coerceErrorString(err)}`,
|
|
1074
|
+
{ clientId: this.clientId, connId: conn.id }
|
|
1075
|
+
);
|
|
1076
|
+
});
|
|
1090
1077
|
}
|
|
1091
1078
|
async receiveHandshakeRequestMessage(data, conn) {
|
|
1092
1079
|
const parsed = this.parseMsg(data);
|
|
1093
1080
|
if (!parsed) {
|
|
1081
|
+
conn.telemetry?.span.setStatus({
|
|
1082
|
+
code: SpanStatusCode2.ERROR,
|
|
1083
|
+
message: "non-transport message"
|
|
1084
|
+
});
|
|
1094
1085
|
this.protocolError(
|
|
1095
1086
|
ProtocolError.HandshakeFailed,
|
|
1096
1087
|
"received non-transport message"
|
|
1097
1088
|
);
|
|
1098
1089
|
return false;
|
|
1099
1090
|
}
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1091
|
+
if (!Value.Check(ControlMessageHandshakeRequestSchema, parsed.payload)) {
|
|
1092
|
+
conn.telemetry?.span.setStatus({
|
|
1093
|
+
code: SpanStatusCode2.ERROR,
|
|
1094
|
+
message: "invalid handshake request"
|
|
1095
|
+
});
|
|
1096
|
+
const reason = "received invalid handshake msg";
|
|
1097
|
+
const responseMsg2 = handshakeResponseMessage(this.clientId, parsed.from, {
|
|
1098
|
+
ok: false,
|
|
1099
|
+
reason
|
|
1100
|
+
});
|
|
1101
|
+
conn.send(this.codec.toBuffer(responseMsg2));
|
|
1102
|
+
const logData = { ...parsed.payload ?? {}, metadata: "redacted" };
|
|
1103
|
+
log?.warn(reason, {
|
|
1104
|
+
clientId: this.clientId,
|
|
1105
|
+
connId: conn.id,
|
|
1106
|
+
partialTransportMessage: { ...parsed, payload: logData }
|
|
1107
|
+
});
|
|
1108
|
+
this.protocolError(
|
|
1109
|
+
ProtocolError.HandshakeFailed,
|
|
1110
|
+
"invalid handshake request"
|
|
1111
|
+
);
|
|
1112
|
+
return false;
|
|
1103
1113
|
}
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
{
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
const gotVersion = parsed.payload.protocolVersion;
|
|
1143
|
-
if (gotVersion !== PROTOCOL_VERSION) {
|
|
1144
|
-
const reason = `incorrect version (got: ${gotVersion} wanted ${PROTOCOL_VERSION})`;
|
|
1145
|
-
const responseMsg2 = handshakeResponseMessage(
|
|
1146
|
-
this.clientId,
|
|
1147
|
-
parsed.from,
|
|
1148
|
-
{
|
|
1149
|
-
ok: false,
|
|
1150
|
-
reason
|
|
1151
|
-
}
|
|
1152
|
-
);
|
|
1153
|
-
conn.send(this.codec.toBuffer(responseMsg2));
|
|
1154
|
-
log?.warn(
|
|
1155
|
-
`received handshake msg with incompatible protocol version (got: ${gotVersion}, expected: ${PROTOCOL_VERSION})`,
|
|
1156
|
-
{ clientId: this.clientId, connId: conn.debugId }
|
|
1157
|
-
);
|
|
1158
|
-
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
1159
|
-
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1160
|
-
span.end();
|
|
1161
|
-
return false;
|
|
1162
|
-
}
|
|
1163
|
-
const { session, isReconnect } = this.getOrCreateSession(
|
|
1114
|
+
const gotVersion = parsed.payload.protocolVersion;
|
|
1115
|
+
if (gotVersion !== PROTOCOL_VERSION) {
|
|
1116
|
+
conn.telemetry?.span.setStatus({
|
|
1117
|
+
code: SpanStatusCode2.ERROR,
|
|
1118
|
+
message: "incorrect protocol version"
|
|
1119
|
+
});
|
|
1120
|
+
const reason = `incorrect version (got: ${gotVersion} wanted ${PROTOCOL_VERSION})`;
|
|
1121
|
+
const responseMsg2 = handshakeResponseMessage(this.clientId, parsed.from, {
|
|
1122
|
+
ok: false,
|
|
1123
|
+
reason
|
|
1124
|
+
});
|
|
1125
|
+
conn.send(this.codec.toBuffer(responseMsg2));
|
|
1126
|
+
log?.warn(
|
|
1127
|
+
`received handshake msg with incompatible protocol version (got: ${gotVersion}, expected: ${PROTOCOL_VERSION})`,
|
|
1128
|
+
{ clientId: this.clientId, connId: conn.id }
|
|
1129
|
+
);
|
|
1130
|
+
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
1131
|
+
return false;
|
|
1132
|
+
}
|
|
1133
|
+
const { session, isReconnect } = this.getOrCreateSession(
|
|
1134
|
+
parsed.from,
|
|
1135
|
+
conn,
|
|
1136
|
+
parsed.payload.sessionId,
|
|
1137
|
+
parsed.tracing
|
|
1138
|
+
);
|
|
1139
|
+
let handshakeMetadata;
|
|
1140
|
+
if (this.options.handshake) {
|
|
1141
|
+
if (!Value.Check(
|
|
1142
|
+
this.options.handshake.requestSchema,
|
|
1143
|
+
parsed.payload.metadata
|
|
1144
|
+
)) {
|
|
1145
|
+
conn.telemetry?.span.setStatus({
|
|
1146
|
+
code: SpanStatusCode2.ERROR,
|
|
1147
|
+
message: "malformed handshake meta"
|
|
1148
|
+
});
|
|
1149
|
+
const reason = "received malformed handshake metadata";
|
|
1150
|
+
const responseMsg2 = handshakeResponseMessage(
|
|
1151
|
+
this.clientId,
|
|
1164
1152
|
parsed.from,
|
|
1165
|
-
|
|
1166
|
-
parsed.payload.sessionId
|
|
1153
|
+
{ ok: false, reason }
|
|
1167
1154
|
);
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
return false;
|
|
1193
|
-
}
|
|
1194
|
-
const parsedMetadata = await this.options.handshake.parse(
|
|
1195
|
-
parsed.payload.metadata,
|
|
1196
|
-
session,
|
|
1197
|
-
isReconnect
|
|
1198
|
-
);
|
|
1199
|
-
if (parsedMetadata === false) {
|
|
1200
|
-
const reason = "rejected by server";
|
|
1201
|
-
const responseMsg2 = handshakeResponseMessage(
|
|
1202
|
-
this.clientId,
|
|
1203
|
-
parsed.from,
|
|
1204
|
-
{ ok: false, reason }
|
|
1205
|
-
);
|
|
1206
|
-
conn.send(this.codec.toBuffer(responseMsg2));
|
|
1207
|
-
log?.warn(`rejected handshake from ${parsed.from}`, {
|
|
1208
|
-
clientId: this.clientId,
|
|
1209
|
-
connId: conn.debugId
|
|
1210
|
-
});
|
|
1211
|
-
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
1212
|
-
this.deleteSession(session);
|
|
1213
|
-
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1214
|
-
span.end();
|
|
1215
|
-
return false;
|
|
1216
|
-
}
|
|
1217
|
-
if (!Value.Check(this.options.handshake.parsedSchema, parsedMetadata)) {
|
|
1218
|
-
const reason = "failed to parse handshake metadata";
|
|
1219
|
-
const responseMsg2 = handshakeResponseMessage(
|
|
1220
|
-
this.clientId,
|
|
1221
|
-
parsed.from,
|
|
1222
|
-
{ ok: false, reason }
|
|
1223
|
-
);
|
|
1224
|
-
conn.send(this.codec.toBuffer(responseMsg2));
|
|
1225
|
-
log?.error(`failed to parse handshake metadata`, {
|
|
1226
|
-
clientId: this.clientId,
|
|
1227
|
-
connId: conn.debugId
|
|
1228
|
-
});
|
|
1229
|
-
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
1230
|
-
this.deleteSession(session);
|
|
1231
|
-
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1232
|
-
span.end();
|
|
1233
|
-
return false;
|
|
1234
|
-
}
|
|
1235
|
-
handshakeMetadata = parsedMetadata;
|
|
1236
|
-
}
|
|
1237
|
-
handshakeMetadata ??= {};
|
|
1238
|
-
session.metadata = handshakeMetadata;
|
|
1239
|
-
log?.debug(
|
|
1240
|
-
`handshake from ${parsed.from} ok, responding with handshake success`,
|
|
1241
|
-
{ clientId: this.clientId, connId: conn.debugId }
|
|
1155
|
+
conn.send(this.codec.toBuffer(responseMsg2));
|
|
1156
|
+
log?.warn(`received malformed handshake metadata from ${parsed.from}`, {
|
|
1157
|
+
clientId: this.clientId,
|
|
1158
|
+
connId: conn.id
|
|
1159
|
+
});
|
|
1160
|
+
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
1161
|
+
this.deleteSession(session);
|
|
1162
|
+
return false;
|
|
1163
|
+
}
|
|
1164
|
+
const parsedMetadata = await this.options.handshake.parse(
|
|
1165
|
+
parsed.payload.metadata,
|
|
1166
|
+
session,
|
|
1167
|
+
isReconnect
|
|
1168
|
+
);
|
|
1169
|
+
if (parsedMetadata === false) {
|
|
1170
|
+
conn.telemetry?.span.setStatus({
|
|
1171
|
+
code: SpanStatusCode2.ERROR,
|
|
1172
|
+
message: "rejected by handshake handler"
|
|
1173
|
+
});
|
|
1174
|
+
const reason = "rejected by handshake handler";
|
|
1175
|
+
const responseMsg2 = handshakeResponseMessage(
|
|
1176
|
+
this.clientId,
|
|
1177
|
+
parsed.from,
|
|
1178
|
+
{ ok: false, reason }
|
|
1242
1179
|
);
|
|
1243
|
-
|
|
1180
|
+
conn.send(this.codec.toBuffer(responseMsg2));
|
|
1181
|
+
log?.warn(`rejected handshake from ${parsed.from}`, {
|
|
1182
|
+
clientId: this.clientId,
|
|
1183
|
+
connId: conn.id
|
|
1184
|
+
});
|
|
1185
|
+
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
1186
|
+
this.deleteSession(session);
|
|
1187
|
+
return false;
|
|
1188
|
+
}
|
|
1189
|
+
if (!Value.Check(this.options.handshake.parsedSchema, parsedMetadata)) {
|
|
1190
|
+
conn.telemetry?.span.setStatus({
|
|
1191
|
+
code: SpanStatusCode2.ERROR,
|
|
1192
|
+
message: "malformed handshake meta"
|
|
1193
|
+
});
|
|
1194
|
+
const reason = "failed to parse handshake metadata";
|
|
1195
|
+
const responseMsg2 = handshakeResponseMessage(
|
|
1244
1196
|
this.clientId,
|
|
1245
1197
|
parsed.from,
|
|
1246
|
-
{
|
|
1247
|
-
ok: true,
|
|
1248
|
-
sessionId: session.id
|
|
1249
|
-
}
|
|
1198
|
+
{ ok: false, reason }
|
|
1250
1199
|
);
|
|
1251
|
-
conn.send(this.codec.toBuffer(
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1200
|
+
conn.send(this.codec.toBuffer(responseMsg2));
|
|
1201
|
+
log?.error(`failed to parse handshake metadata`, {
|
|
1202
|
+
clientId: this.clientId,
|
|
1203
|
+
connId: conn.id
|
|
1204
|
+
});
|
|
1205
|
+
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
1206
|
+
this.deleteSession(session);
|
|
1207
|
+
return false;
|
|
1255
1208
|
}
|
|
1209
|
+
handshakeMetadata = parsedMetadata;
|
|
1210
|
+
}
|
|
1211
|
+
handshakeMetadata ??= {};
|
|
1212
|
+
session.metadata = handshakeMetadata;
|
|
1213
|
+
log?.debug(
|
|
1214
|
+
`handshake from ${parsed.from} ok, responding with handshake success`,
|
|
1215
|
+
{ clientId: this.clientId, connId: conn.id }
|
|
1256
1216
|
);
|
|
1217
|
+
const responseMsg = handshakeResponseMessage(this.clientId, parsed.from, {
|
|
1218
|
+
ok: true,
|
|
1219
|
+
sessionId: session.id
|
|
1220
|
+
});
|
|
1221
|
+
conn.send(this.codec.toBuffer(responseMsg));
|
|
1222
|
+
this.onConnect(conn, parsed.from, session, isReconnect);
|
|
1223
|
+
return session;
|
|
1257
1224
|
}
|
|
1258
1225
|
};
|
|
1259
1226
|
|
|
@@ -1266,4 +1233,4 @@ export {
|
|
|
1266
1233
|
ClientTransport,
|
|
1267
1234
|
ServerTransport
|
|
1268
1235
|
};
|
|
1269
|
-
//# sourceMappingURL=chunk-
|
|
1236
|
+
//# sourceMappingURL=chunk-ZPBWKBM5.js.map
|