@peers-app/peers-sdk 0.27.4 → 0.27.5
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/contracts/contract-transport.d.ts +2 -1
- package/dist/contracts/contract-transport.js +24 -2
- package/dist/contracts/tool-catalog.js +6 -2
- package/dist/device/binary-peer-connection-v2.d.ts +7 -15
- package/dist/device/binary-peer-connection-v2.js +14 -30
- package/dist/device/connection.d.ts +34 -43
- package/dist/device/connection.js +188 -186
- package/dist/device/device.d.ts +1 -8
- package/dist/device/device.js +1 -30
- package/dist/device/socket.type.d.ts +6 -12
- package/package.json +1 -1
- package/dist/device/binary-peer-connection.d.ts +0 -58
- package/dist/device/binary-peer-connection.js +0 -516
- package/dist/device/streamed-socket.d.ts +0 -23
- package/dist/device/streamed-socket.js +0 -255
|
@@ -63,7 +63,8 @@ export declare const CONTRACT_REQUEST_CHANNEL = "contractCall";
|
|
|
63
63
|
export declare const CONTRACT_NOTIFY_CHANNEL = "contractNotify";
|
|
64
64
|
/**
|
|
65
65
|
* Wrap a duplex RPC emitter (e.g. a device {@link Connection}) as an
|
|
66
|
-
* {@link IContractTransport}. `emit` delegates directly
|
|
66
|
+
* {@link IContractTransport}. `emit` delegates directly and rejects with an `Error`
|
|
67
|
+
* carrying the remote message, whatever the emitter rejected with. `on` uses one adapter-owned
|
|
67
68
|
* dispatcher per emitter/channel and returns an unsubscribe that removes only the caller's
|
|
68
69
|
* handler from that dispatcher; it never uses a coarse `removeAllListeners`.
|
|
69
70
|
*
|
|
@@ -33,9 +33,24 @@ exports.CONTRACT_REQUEST_CHANNEL = "contractCall";
|
|
|
33
33
|
*/
|
|
34
34
|
exports.CONTRACT_NOTIFY_CHANNEL = "contractNotify";
|
|
35
35
|
const connectionDispatcherStates = new WeakMap();
|
|
36
|
+
/**
|
|
37
|
+
* Turn a failed emit into an `Error`. A device connection rejects with the remote handler's
|
|
38
|
+
* `{ error, errorType }` envelope, or with a string when the call times out.
|
|
39
|
+
*/
|
|
40
|
+
function toError(error) {
|
|
41
|
+
if (error instanceof Error)
|
|
42
|
+
return error;
|
|
43
|
+
if (error &&
|
|
44
|
+
typeof error === "object" &&
|
|
45
|
+
typeof error.error === "string") {
|
|
46
|
+
return new Error(error.error);
|
|
47
|
+
}
|
|
48
|
+
return new Error(typeof error === "string" ? error : JSON.stringify(error));
|
|
49
|
+
}
|
|
36
50
|
/**
|
|
37
51
|
* Wrap a duplex RPC emitter (e.g. a device {@link Connection}) as an
|
|
38
|
-
* {@link IContractTransport}. `emit` delegates directly
|
|
52
|
+
* {@link IContractTransport}. `emit` delegates directly and rejects with an `Error`
|
|
53
|
+
* carrying the remote message, whatever the emitter rejected with. `on` uses one adapter-owned
|
|
39
54
|
* dispatcher per emitter/channel and returns an unsubscribe that removes only the caller's
|
|
40
55
|
* handler from that dispatcher; it never uses a coarse `removeAllListeners`.
|
|
41
56
|
*
|
|
@@ -53,7 +68,14 @@ const connectionDispatcherStates = new WeakMap();
|
|
|
53
68
|
*/
|
|
54
69
|
function connectionContractTransport(emitter) {
|
|
55
70
|
return {
|
|
56
|
-
emit: (channel, ...args) =>
|
|
71
|
+
emit: async (channel, ...args) => {
|
|
72
|
+
try {
|
|
73
|
+
return await emitter.emit(channel, ...args);
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
throw toError(error);
|
|
77
|
+
}
|
|
78
|
+
},
|
|
57
79
|
on: (channel, handler) => {
|
|
58
80
|
let channelStates = connectionDispatcherStates.get(emitter);
|
|
59
81
|
if (!channelStates) {
|
|
@@ -179,13 +179,17 @@ function validateToolCatalogWrite(existing, candidate, recordId = candidate?.too
|
|
|
179
179
|
!isMissingTargetQuarantine(existing) &&
|
|
180
180
|
isMissingTargetQuarantine(candidate))
|
|
181
181
|
throw new Error(`Quarantined tool identity: ${candidate.toolId}`);
|
|
182
|
-
// Quarantine preserves the original evidence byte-for-byte; it cannot retarget it.
|
|
182
|
+
// Quarantine preserves the original evidence byte-for-byte; it cannot retarget it. That
|
|
183
|
+
// includes an existing quarantine's reason: a peer's resolve patch whose `catalogReason`
|
|
184
|
+
// half arrives first must park, not erase the missing-target reason its other half needs.
|
|
183
185
|
if (existing &&
|
|
184
186
|
candidate.catalogState === "quarantined" &&
|
|
185
187
|
existing.contractId === candidate.contractId &&
|
|
186
188
|
existing.contractVersion === candidate.contractVersion &&
|
|
187
189
|
existing.toolName === candidate.toolName &&
|
|
188
|
-
existing.catalogIdentity === candidate.catalogIdentity
|
|
190
|
+
existing.catalogIdentity === candidate.catalogIdentity &&
|
|
191
|
+
(existing.catalogState !== "quarantined" ||
|
|
192
|
+
(existing.catalogReason ?? undefined) === (candidate.catalogReason ?? undefined)))
|
|
189
193
|
return;
|
|
190
194
|
// Changing quarantined identity evidence also requires an approved repair, even
|
|
191
195
|
// when the candidate stays quarantined and would be resolved by reconciliation.
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* binary-peer-connection-v2.ts
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Binary transport layer under every device connection. Provides two cleanly
|
|
5
|
+
* separated modes:
|
|
6
6
|
*
|
|
7
7
|
* 1. **RPC mode** (emit/on): request/response interactions with automatic
|
|
8
8
|
* encoding (txEncode for objects, passthrough for Uint8Array) and transparent
|
|
9
9
|
* chunking for large payloads.
|
|
10
10
|
*
|
|
11
11
|
* 2. **Stream mode** (sendRawBytes/onRawBytes): continuous byte transfer for
|
|
12
|
-
* file syncing,
|
|
12
|
+
* file syncing, log streaming, etc. Each sendRawBytes
|
|
13
13
|
* call = exactly one onRawBytes callback (atomic delivery after reassembly).
|
|
14
14
|
*
|
|
15
15
|
* Both modes share a single sendFrame() function that handles backpressure
|
|
@@ -61,19 +61,12 @@ export declare const DEFAULT_BINARY_PEER_RECEIVE_LIMITS: Readonly<BinaryPeerRece
|
|
|
61
61
|
export interface WrapBinaryPeerOptions {
|
|
62
62
|
/** Protocol identifier used for server address (e.g., 'wrtc' or 'ws') */
|
|
63
63
|
protocol: "wrtc" | "ws";
|
|
64
|
-
/**
|
|
65
|
-
* Mark the transport as already secure (encrypted at transport layer).
|
|
66
|
-
* When true, sets secureLocal and secureRemote to skip the legacy per-message
|
|
67
|
-
* envelope against a legacy peer. Irrelevant once the frame cipher is armed.
|
|
68
|
-
* @deprecated Removed with the legacy path.
|
|
69
|
-
*/
|
|
70
|
-
markTransportSecure?: boolean;
|
|
71
64
|
/** Optional hard limits for untrusted inbound messages. */
|
|
72
65
|
receiveLimits?: Partial<BinaryPeerReceiveLimits>;
|
|
73
66
|
}
|
|
74
67
|
/**
|
|
75
68
|
* Creates an ISocket from a binary peer. This is the core v2 factory function.
|
|
76
|
-
*
|
|
69
|
+
* Used for every device connection.
|
|
77
70
|
*/
|
|
78
71
|
export declare function createBinaryPeerSocket(connectionId: string, peer: IBinaryPeer, protocol?: string, receiveLimitOverrides?: Partial<BinaryPeerReceiveLimits>): ISocket;
|
|
79
72
|
/**
|
|
@@ -82,10 +75,9 @@ export declare function createBinaryPeerSocket(connectionId: string, peer: IBina
|
|
|
82
75
|
*/
|
|
83
76
|
export declare function wrapBinaryPeer(connectionId: string, peer: IBinaryPeer, localDevice: Device, initiator: boolean, options: WrapBinaryPeerOptions, getTrustLevel?: ITrustLevelFn): Connection;
|
|
84
77
|
/**
|
|
85
|
-
* Wraps a WebRTC peer into a Connection.
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
* classification.
|
|
78
|
+
* Wraps a WebRTC peer into a Connection. WebRTC is encrypted at the transport
|
|
79
|
+
* layer (DTLS-SRTP); the handshake arms the frame cipher on top of it, as on
|
|
80
|
+
* every transport.
|
|
89
81
|
*/
|
|
90
82
|
export declare function wrapWrtc(connectionId: string, peer: IWebRTCPeer, localDevice: Device, initiator: boolean, getTrustLevel?: ITrustLevelFn, receiveLimits?: Partial<BinaryPeerReceiveLimits>): Connection;
|
|
91
83
|
export {};
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* binary-peer-connection-v2.ts
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* Binary transport layer under every device connection. Provides two cleanly
|
|
6
|
+
* separated modes:
|
|
7
7
|
*
|
|
8
8
|
* 1. **RPC mode** (emit/on): request/response interactions with automatic
|
|
9
9
|
* encoding (txEncode for objects, passthrough for Uint8Array) and transparent
|
|
10
10
|
* chunking for large payloads.
|
|
11
11
|
*
|
|
12
12
|
* 2. **Stream mode** (sendRawBytes/onRawBytes): continuous byte transfer for
|
|
13
|
-
* file syncing,
|
|
13
|
+
* file syncing, log streaming, etc. Each sendRawBytes
|
|
14
14
|
* call = exactly one onRawBytes callback (atomic delivery after reassembly).
|
|
15
15
|
*
|
|
16
16
|
* Both modes share a single sendFrame() function that handles backpressure
|
|
@@ -240,7 +240,7 @@ function buildStreamCont(sidBytes, chunkData) {
|
|
|
240
240
|
}
|
|
241
241
|
/**
|
|
242
242
|
* Creates an ISocket from a binary peer. This is the core v2 factory function.
|
|
243
|
-
*
|
|
243
|
+
* Used for every device connection.
|
|
244
244
|
*/
|
|
245
245
|
function createBinaryPeerSocket(connectionId, peer, protocol = "binary", receiveLimitOverrides = {}) {
|
|
246
246
|
const handlers = {};
|
|
@@ -265,7 +265,7 @@ function createBinaryPeerSocket(connectionId, peer, protocol = "binary", receive
|
|
|
265
265
|
let sendSealer = null;
|
|
266
266
|
let receiveOpener = null;
|
|
267
267
|
// Bare sockets (no Connection) deliver plaintext streams; Connection turns
|
|
268
|
-
// this off
|
|
268
|
+
// this off, so it receives only sealed stream frames.
|
|
269
269
|
let plaintextStreamsAllowed = true;
|
|
270
270
|
// Every inner frame must leave room for the cipher's 17 bytes so a sealed
|
|
271
271
|
// frame never exceeds the transport limit (64 KB SCTP on WebRTC). Reserved
|
|
@@ -503,7 +503,7 @@ function createBinaryPeerSocket(connectionId, peer, protocol = "binary", receive
|
|
|
503
503
|
else
|
|
504
504
|
responseMessage.result = result;
|
|
505
505
|
const encoded = encodeMessage(responseMessage);
|
|
506
|
-
sendRPC(encoded, sendOptions);
|
|
506
|
+
return sendRPC(encoded, sendOptions);
|
|
507
507
|
};
|
|
508
508
|
handler(message.args, callback);
|
|
509
509
|
}
|
|
@@ -730,17 +730,8 @@ function createBinaryPeerSocket(connectionId, peer, protocol = "binary", receive
|
|
|
730
730
|
break;
|
|
731
731
|
}
|
|
732
732
|
default: {
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
// legacy format (no discriminator), try to decode as RPC.
|
|
736
|
-
// This handles the transition period where v1 peers send raw RPC without
|
|
737
|
-
// a frame type byte.
|
|
738
|
-
if (bytes.length > receiveLimits.maxRpcMessageBytes) {
|
|
739
|
-
closeForProtocolViolation("legacy RPC exceeds the message-size limit");
|
|
740
|
-
return;
|
|
741
|
-
}
|
|
742
|
-
handleIncomingRPC(bytes);
|
|
743
|
-
break;
|
|
733
|
+
closeForProtocolViolation(`unknown frame type ${frameType}`);
|
|
734
|
+
return;
|
|
744
735
|
}
|
|
745
736
|
}
|
|
746
737
|
}
|
|
@@ -762,7 +753,6 @@ function createBinaryPeerSocket(connectionId, peer, protocol = "binary", receive
|
|
|
762
753
|
const socket = {
|
|
763
754
|
id: connectionId,
|
|
764
755
|
connected: true,
|
|
765
|
-
handlesOwnEncoding: true,
|
|
766
756
|
transportType,
|
|
767
757
|
stats,
|
|
768
758
|
armFrameCipher,
|
|
@@ -811,26 +801,20 @@ function createBinaryPeerSocket(connectionId, peer, protocol = "binary", receive
|
|
|
811
801
|
* This is the main implementation that handles all binary protocols.
|
|
812
802
|
*/
|
|
813
803
|
function wrapBinaryPeer(connectionId, peer, localDevice, initiator, options, getTrustLevel) {
|
|
814
|
-
const { protocol,
|
|
804
|
+
const { protocol, receiveLimits } = options;
|
|
815
805
|
const socket = createBinaryPeerSocket(connectionId, peer, protocol, receiveLimits);
|
|
816
806
|
const serverAddress = `${protocol}://${connectionId}`;
|
|
817
807
|
const localServerAddresses = initiator ? undefined : [serverAddress];
|
|
818
808
|
if (process.env.NODE_ENV !== "test") {
|
|
819
809
|
getTrustLevel ??= (0, get_trust_level_fn_1.getTrustLevelFn)(localDevice, serverAddress);
|
|
820
810
|
}
|
|
821
|
-
|
|
822
|
-
if (markTransportSecure) {
|
|
823
|
-
connection.secureLocal = true;
|
|
824
|
-
connection.secureRemote = true;
|
|
825
|
-
}
|
|
826
|
-
return connection;
|
|
811
|
+
return new connection_1.Connection(socket, localDevice, localServerAddresses, getTrustLevel);
|
|
827
812
|
}
|
|
828
813
|
/**
|
|
829
|
-
* Wraps a WebRTC peer into a Connection.
|
|
830
|
-
*
|
|
831
|
-
*
|
|
832
|
-
* classification.
|
|
814
|
+
* Wraps a WebRTC peer into a Connection. WebRTC is encrypted at the transport
|
|
815
|
+
* layer (DTLS-SRTP); the handshake arms the frame cipher on top of it, as on
|
|
816
|
+
* every transport.
|
|
833
817
|
*/
|
|
834
818
|
function wrapWrtc(connectionId, peer, localDevice, initiator, getTrustLevel, receiveLimits) {
|
|
835
|
-
return wrapBinaryPeer(connectionId, peer, localDevice, initiator, { protocol: "wrtc",
|
|
819
|
+
return wrapBinaryPeer(connectionId, peer, localDevice, initiator, { protocol: "wrtc", receiveLimits }, getTrustLevel);
|
|
836
820
|
}
|
|
@@ -8,12 +8,10 @@ export type GetTrustLevel = (deviceInfo: IDeviceInfo, registerNew?: boolean) =>
|
|
|
8
8
|
* Authenticated RPC connection between two Peers devices.
|
|
9
9
|
*
|
|
10
10
|
* The handshake (`doHandshake` on the client, `completeHandshake` on the
|
|
11
|
-
* server) authenticates both identities with signed, boxed messages
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* Against a peer that does not advertise `frameCrypto` the connection falls
|
|
16
|
-
* back to the legacy behaviour and logs a warning.
|
|
11
|
+
* server) authenticates both identities with signed, boxed messages and agrees
|
|
12
|
+
* on per-connection frame-cipher keys (`frame-cipher.ts`), then arms the
|
|
13
|
+
* socket: every frame after the handshake is sealed. A peer that does not
|
|
14
|
+
* offer frame encryption (a build before 0.25.7) is refused.
|
|
17
15
|
*/
|
|
18
16
|
export declare class Connection {
|
|
19
17
|
readonly localDevice: Device;
|
|
@@ -21,23 +19,9 @@ export declare class Connection {
|
|
|
21
19
|
protected readonly getTrustLevel: GetTrustLevel;
|
|
22
20
|
private _verified;
|
|
23
21
|
private _remoteDeviceInfo;
|
|
24
|
-
/**
|
|
25
|
-
* @deprecated Legacy transport classification, only consulted when the frame
|
|
26
|
-
* cipher is not armed. Removed once legacy peers are no longer supported.
|
|
27
|
-
*/
|
|
28
|
-
secureLocal: boolean;
|
|
29
|
-
/** @deprecated See {@link Connection.secureLocal}. */
|
|
30
|
-
secureRemote: boolean;
|
|
31
|
-
/**
|
|
32
|
-
* Legacy per-message encryption override. Ignored once the frame cipher is
|
|
33
|
-
* armed. `"dont-encrypt-traffic-after-handshake"` is honoured only under
|
|
34
|
-
* `NODE_ENV=test`.
|
|
35
|
-
* @deprecated Removed with the legacy path.
|
|
36
|
-
*/
|
|
37
|
-
overrideEncryption?: "encrypt-traffic-regardless-of-protocol" | "dont-encrypt-traffic-after-handshake";
|
|
38
22
|
/** Trust assigned to the remote identity once the handshake completes. */
|
|
39
23
|
trustLevel: TrustLevel;
|
|
40
|
-
/** Server-side hook fired shortly after
|
|
24
|
+
/** Server-side hook fired shortly after the successful handshake reply has been sent. */
|
|
41
25
|
onHandshakeComplete: ((deviceInfo: IDeviceInfo) => void) | undefined;
|
|
42
26
|
/** RPC timeout for {@link Connection.emit}. */
|
|
43
27
|
timeoutMs: number;
|
|
@@ -53,21 +37,13 @@ export declare class Connection {
|
|
|
53
37
|
private pendingClientHandshake;
|
|
54
38
|
/** Server side: keys to arm for sending right after the handshake response frame. */
|
|
55
39
|
private pendingSendArm;
|
|
40
|
+
/** Bumped by every {@link Connection.reset}, so a handshake can tell it was cut short. */
|
|
41
|
+
private handshakeGeneration;
|
|
56
42
|
constructor(socket: ISocket, localDevice: Device, localDeviceServerAddresses?: string[] | undefined, getTrustLevel?: GetTrustLevel);
|
|
57
43
|
/** True once the remote identity has been authenticated by the handshake. */
|
|
58
44
|
get verified(): boolean;
|
|
59
45
|
/** True when every frame on this connection is sealed by the frame cipher. */
|
|
60
46
|
get frameCipherArmed(): boolean;
|
|
61
|
-
/**
|
|
62
|
-
* Whether to apply the legacy per-message envelope (sign + box) to RPC payloads.
|
|
63
|
-
*
|
|
64
|
-
* Always false once the frame cipher is armed: the frame layer already gives
|
|
65
|
-
* confidentiality, integrity, and sender binding for every frame. Otherwise
|
|
66
|
-
* (legacy peer) the transport classification below applies:
|
|
67
|
-
* - skipped when both sides agreed the transport is secure (`secureLocal && secureRemote`)
|
|
68
|
-
* - applied on plain `ws` / `http`
|
|
69
|
-
*/
|
|
70
|
-
get encryptTraffic(): boolean;
|
|
71
47
|
/** Copy of the authenticated remote device identity (empty before the handshake). */
|
|
72
48
|
get remoteDeviceInfo(): {
|
|
73
49
|
publicKey: string;
|
|
@@ -79,8 +55,8 @@ export declare class Connection {
|
|
|
79
55
|
};
|
|
80
56
|
/** Socket ID shared by both ends; also the frame-cipher AAD and HKDF salt. */
|
|
81
57
|
get connectionId(): string;
|
|
82
|
-
|
|
83
|
-
private
|
|
58
|
+
/** The socket's frame-cipher arming; throws when the transport can't encrypt frames. */
|
|
59
|
+
private requireFrameCipher;
|
|
84
60
|
private readonly handleCompleteHandshakeRPC;
|
|
85
61
|
/**
|
|
86
62
|
* Get connection throughput stats with calculated rates.
|
|
@@ -105,10 +81,15 @@ export declare class Connection {
|
|
|
105
81
|
exposeRPC<T extends Function>(fn: T): void;
|
|
106
82
|
/** Calls a remote RPC handler and resolves with its result (rejects on error or timeout). */
|
|
107
83
|
emit<T = any>(eventName: string, ...args: any): Promise<T>;
|
|
84
|
+
/**
|
|
85
|
+
* Sends one RPC. `onReply`, when given, runs synchronously while the reply frame is
|
|
86
|
+
* processed, before any later frame from the peer; its return value (or throw) settles
|
|
87
|
+
* the call.
|
|
88
|
+
*/
|
|
89
|
+
private request;
|
|
108
90
|
/**
|
|
109
91
|
* Registers an RPC handler. Events other than the handshake set are rejected
|
|
110
|
-
* until the connection is verified
|
|
111
|
-
* when {@link Connection.encryptTraffic} is true.
|
|
92
|
+
* until the connection is verified.
|
|
112
93
|
*/
|
|
113
94
|
on(eventName: string, handler: Function): void;
|
|
114
95
|
/** Removes RPC handlers for `eventName`, or all handlers when omitted. */
|
|
@@ -120,26 +101,36 @@ export declare class Connection {
|
|
|
120
101
|
*/
|
|
121
102
|
reset(): void;
|
|
122
103
|
/**
|
|
123
|
-
* Client side: builds the signed handshake (
|
|
124
|
-
*
|
|
125
|
-
* remote device.
|
|
104
|
+
* Client side: builds the signed handshake (offering frame encryption with a
|
|
105
|
+
* fresh ephemeral key) and boxes it to the remote device.
|
|
126
106
|
*/
|
|
127
107
|
initiateHandshake(serverAddress: string, remoteDeviceInfo?: IDeviceInfo): IDataBox;
|
|
128
108
|
/**
|
|
129
109
|
* Server side: verifies the client's handshake, resolves trust, and returns
|
|
130
|
-
* the (unsigned) response for the caller to sign and box.
|
|
131
|
-
* offered `frameCrypto` and this socket can arm a cipher, derives the frame
|
|
110
|
+
* the (unsigned) response for the caller to sign and box. Derives the frame
|
|
132
111
|
* keys, arms the receive direction immediately, and schedules the send
|
|
133
112
|
* direction to arm right after the response frame (see
|
|
134
|
-
* {@link Connection.handleCompleteHandshakeRPC}).
|
|
113
|
+
* {@link Connection.handleCompleteHandshakeRPC}). A client that does not
|
|
114
|
+
* offer frame encryption is refused.
|
|
135
115
|
*/
|
|
136
116
|
completeHandshake(boxedHandshake: IDataBox): Promise<IDeviceHandshake>;
|
|
137
117
|
/**
|
|
138
118
|
* Client side: runs the full handshake against `remoteAddress`. On success
|
|
139
|
-
* the remote identity is verified and
|
|
140
|
-
*
|
|
119
|
+
* the remote identity is verified and the frame cipher is armed in both
|
|
120
|
+
* directions before this resolves.
|
|
141
121
|
*/
|
|
142
122
|
doHandshake(remoteAddress: string): Promise<IDeviceHandshake>;
|
|
123
|
+
/**
|
|
124
|
+
* Client side: checks the server's handshake reply, arms the frame cipher, and records the
|
|
125
|
+
* verified identity. Runs synchronously while the reply frame is processed, so a sealed
|
|
126
|
+
* frame read right after it finds the cipher armed and the connection verified.
|
|
127
|
+
*/
|
|
128
|
+
private acceptHandshakeReply;
|
|
129
|
+
/**
|
|
130
|
+
* Throws when the connection was reset or closed after the handshake started: a handshake
|
|
131
|
+
* cut short must fail, not finish on a dead or reused connection.
|
|
132
|
+
*/
|
|
133
|
+
private assertHandshakeCurrent;
|
|
143
134
|
/**
|
|
144
135
|
* Resets this side and asks the remote to do the same. The remote call is a courtesy: a
|
|
145
136
|
* peer that is not a server has no `reset` handler, and a peer we just refused may already
|