p2party 0.14.7 → 0.14.10
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 +26 -23
- package/THIRD_PARTY_NOTICES.md +33 -6
- package/docs/getting-started.md +103 -4
- package/docs/protocol-v4-security.md +57 -7
- package/docs/references.md +1 -1
- package/docs/session-api.md +9 -0
- package/docs/wire-format.md +102 -14
- package/lib/api/signalingServerApi.d.ts +38 -0
- package/lib/api/webrtc/interfaces.d.ts +33 -1
- package/lib/api/webrtc/peerSocketGeneration.d.ts +68 -0
- package/lib/cryptography/coverCell.d.ts +7 -0
- package/lib/cryptography/emscripten.d.ts +101 -0
- package/lib/cryptography/libcrypto.d.ts +181 -0
- package/lib/db/outboxTypes.d.ts +135 -0
- package/lib/db/types.d.ts +29 -3
- package/lib/db.worker.js +1 -1
- package/lib/handlers/coverRuntime.d.ts +14 -1
- package/lib/handlers/coverScheduler.d.ts +59 -1
- package/lib/handlers/coverTransfer.d.ts +169 -3
- package/lib/handlers/handleSendMessage.d.ts +79 -3
- package/lib/handlers/outbox.d.ts +47 -0
- package/lib/handlers/ratchetGate.d.ts +9 -0
- package/lib/handlers/reconcile.d.ts +5 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.js +1 -1
- package/lib/index.min.js +1 -1
- package/lib/index.mjs +1 -1
- package/lib/reducers/roomSlice.d.ts +9 -2
- package/lib/session.js +1 -1
- package/lib/session.mjs +1 -1
- package/lib/utils/constants.d.ts +7 -0
- package/lib/utils/interfaces.d.ts +11 -0
- package/lib/utils/signalingReconnectController.d.ts +44 -0
- package/package.json +13 -15
- package/lib/api/webrtc/applyIceConfiguration.d.ts +0 -9
- package/lib/api/webrtc/dataChannelHandler.d.ts +0 -10
- package/lib/api/webrtc/deleteRoomData.d.ts +0 -13
- package/lib/api/webrtc/disconnectFromAllRoomsQuery.d.ts +0 -9
- package/lib/api/webrtc/disconnectFromChannelLabelQuery.d.ts +0 -7
- package/lib/api/webrtc/disconnectFromPeerChannelLabelQuery.d.ts +0 -8
- package/lib/api/webrtc/disconnectFromPeerQuery.d.ts +0 -9
- package/lib/api/webrtc/disconnectFromRoomQuery.d.ts +0 -9
- package/lib/api/webrtc/disconnectQuery.d.ts +0 -9
- package/lib/api/webrtc/iceGeneration.d.ts +0 -17
- package/lib/api/webrtc/iceRepair.d.ts +0 -12
- package/lib/api/webrtc/index.d.ts +0 -17
- package/lib/api/webrtc/negotiationLock.d.ts +0 -36
- package/lib/api/webrtc/openChannelQuery.d.ts +0 -8
- package/lib/api/webrtc/pendingIceCandidates.d.ts +0 -14
- package/lib/api/webrtc/pendingOffer.d.ts +0 -29
- package/lib/api/webrtc/rebindDeadline.d.ts +0 -61
- package/lib/api/webrtc/remoteTransportChange.d.ts +0 -142
- package/lib/api/webrtc/retiredRemoteTransports.d.ts +0 -70
- package/lib/api/webrtc/roomEdgeBudget.d.ts +0 -10
- package/lib/api/webrtc/roomPeer.d.ts +0 -11
- package/lib/api/webrtc/sendMessageQuery.d.ts +0 -14
- package/lib/api/webrtc/setCandidateQuery.d.ts +0 -8
- package/lib/api/webrtc/setDescriptionQuery.d.ts +0 -16
- package/lib/api/webrtc/settleOnClose.d.ts +0 -36
- package/lib/blindRendezvous/admissionInput.d.ts +0 -11
- package/lib/blindRendezvous/admissionPolicy.d.ts +0 -217
- package/lib/blindRendezvous/canonicalSchema.d.ts +0 -139
- package/lib/blindRendezvous/carrierEnvelope.d.ts +0 -105
- package/lib/blindRendezvous/coreReduce.d.ts +0 -199
- package/lib/blindRendezvous/derivations.d.ts +0 -381
- package/lib/blindRendezvous/identityHelloAdmission.d.ts +0 -89
- package/lib/blindRendezvous/identityHelloAdmissionPersistence.d.ts +0 -133
- package/lib/blindRendezvous/identityHelloHistoricalEvidence.d.ts +0 -52
- package/lib/blindRendezvous/identityHelloOpen.d.ts +0 -167
- package/lib/blindRendezvous/identityHelloTrial.d.ts +0 -271
- package/lib/blindRendezvous/localAdmissibleProject.d.ts +0 -101
- package/lib/blindRendezvous/localPresenceKeyBinding.d.ts +0 -108
- package/lib/blindRendezvous/localStableIdentityCustody.d.ts +0 -46
- package/lib/blindRendezvous/normativeKernel.d.ts +0 -222
- package/lib/blindRendezvous/operation.d.ts +0 -137
- package/lib/blindRendezvous/operationPayload.d.ts +0 -134
- package/lib/blindRendezvous/pairBootstrapSuite.d.ts +0 -93
- package/lib/blindRendezvous/pairCrypto.d.ts +0 -122
- package/lib/blindRendezvous/pairLedger.d.ts +0 -154
- package/lib/blindRendezvous/pairOpenBudget.d.ts +0 -67
- package/lib/blindRendezvous/pairOpenReservation.d.ts +0 -157
- package/lib/blindRendezvous/pairPlaintext.d.ts +0 -240
- package/lib/blindRendezvous/pairStepEnvelope.d.ts +0 -60
- package/lib/blindRendezvous/plannerState.d.ts +0 -61
- package/lib/blindRendezvous/projections.d.ts +0 -71
- package/lib/blindRendezvous/publicWindow.d.ts +0 -330
- package/lib/blindRendezvous/retainedOperationStore.d.ts +0 -187
- package/lib/blindRendezvous/roomInviteV2.d.ts +0 -92
- package/lib/blindRendezvous/roomPolicyV4.d.ts +0 -90
- package/lib/blindRendezvous/schemas.d.ts +0 -221
- package/lib/blindRendezvous/storeDescriptor.d.ts +0 -160
- package/lib/cryptography/aeadWasm.d.ts +0 -18
- package/lib/cryptography/byteInput.d.ts +0 -12
- package/lib/cryptography/carrierAead.d.ts +0 -23
- package/lib/cryptography/chacha20poly1305.d.ts +0 -7
- package/lib/cryptography/cpace.d.ts +0 -41
- package/lib/cryptography/ed25519.d.ts +0 -11
- package/lib/cryptography/fips202.d.ts +0 -10
- package/lib/cryptography/hashStream.d.ts +0 -15
- package/lib/cryptography/hkdf.d.ts +0 -3
- package/lib/cryptography/hpke.d.ts +0 -84
- package/lib/cryptography/hpkeSuite.d.ts +0 -39
- package/lib/cryptography/hybridKem.d.ts +0 -42
- package/lib/cryptography/hybridKemSuite.d.ts +0 -22
- package/lib/cryptography/identityCrossSig.d.ts +0 -7
- package/lib/cryptography/memory.d.ts +0 -14
- package/lib/cryptography/merkle.d.ts +0 -42
- package/lib/cryptography/ownedEd25519KeyMaterial.d.ts +0 -27
- package/lib/cryptography/pqHealingFrame.d.ts +0 -39
- package/lib/cryptography/random.d.ts +0 -22
- package/lib/cryptography/testModule.d.ts +0 -7
- package/lib/cryptography/utils.d.ts +0 -13
- package/lib/cryptography/webCryptoSha256.d.ts +0 -20
- package/lib/cryptography/x25519.d.ts +0 -33
- package/lib/cryptography/x3dh.d.ts +0 -9
- package/lib/cryptography/xchacha20poly1305.d.ts +0 -7
- package/lib/db/api.d.ts +0 -70
- package/lib/db/db.worker.d.ts +0 -1
- package/lib/db/identityEd25519ClientBoundary.d.ts +0 -13
- package/lib/db/ratchetWrap.d.ts +0 -36
- package/lib/db/src/getDB.d.ts +0 -81
- package/lib/handlers/chunkFrame.d.ts +0 -13
- package/lib/handlers/connectionSignal.d.ts +0 -26
- package/lib/handlers/coverChannelRegistry.d.ts +0 -22
- package/lib/handlers/coverEdge.d.ts +0 -42
- package/lib/handlers/edgeTeardownFollowUp.d.ts +0 -35
- package/lib/handlers/frameType.d.ts +0 -10
- package/lib/handlers/handleChallenge.d.ts +0 -4
- package/lib/handlers/handleConnectToPeer.d.ts +0 -6
- package/lib/handlers/handleHandshake.d.ts +0 -70
- package/lib/handlers/handleMessageQueueing.d.ts +0 -54
- package/lib/handlers/handleOpenChannel.d.ts +0 -12
- package/lib/handlers/handleQueuedIceCandidates.d.ts +0 -2
- package/lib/handlers/handleReadReceipt.d.ts +0 -17
- package/lib/handlers/handleReceiveMessage.d.ts +0 -32
- package/lib/handlers/handleWebSocketMessage.d.ts +0 -3
- package/lib/handlers/messageChunkCrypto.d.ts +0 -70
- package/lib/handlers/peerRosterDelta.d.ts +0 -12
- package/lib/handlers/pqHealingOrchestrator.d.ts +0 -46
- package/lib/handlers/ratchetGateWait.d.ts +0 -13
- package/lib/handlers/ratchetPersist.d.ts +0 -53
- package/lib/handlers/receiptFrame.d.ts +0 -18
- package/lib/handlers/receiveMessageKeyLifetime.d.ts +0 -24
- package/lib/handlers/requestRoom.d.ts +0 -30
- package/lib/handlers/roomResponse.d.ts +0 -53
- package/lib/handlers/transferAbort.d.ts +0 -42
- package/lib/middleware/keyPairListenerMiddleware.d.ts +0 -2
- package/lib/middleware/roomListenerMiddleware.d.ts +0 -5
- package/lib/roomInvite.d.ts +0 -18
- package/lib/roomPinAttempts.d.ts +0 -12
- package/lib/roomPinVault.d.ts +0 -26
- package/lib/utils/channelLabel.d.ts +0 -9
- package/lib/utils/chunkBounds.d.ts +0 -9
- package/lib/utils/correlationId.d.ts +0 -4
- package/lib/utils/drainAndClose.d.ts +0 -5
- package/lib/utils/identityRole.d.ts +0 -19
- package/lib/utils/leafHash.d.ts +0 -13
- package/lib/utils/metadata.d.ts +0 -22
- package/lib/utils/mutex.d.ts +0 -24
- package/lib/utils/protocolVersion.d.ts +0 -5
- package/lib/utils/receiptToken.d.ts +0 -7
- package/lib/utils/roomConnectAdmission.d.ts +0 -15
- package/lib/utils/roomRequestCoordinator.d.ts +0 -104
- package/lib/utils/roomRosterReconciler.d.ts +0 -83
- package/lib/utils/sdpFingerprint.d.ts +0 -6
- package/lib/utils/sendQueueKey.d.ts +0 -2
- package/lib/utils/signalingAttemptLifecycle.d.ts +0 -33
- package/lib/utils/signalingAuth.d.ts +0 -27
- package/lib/utils/signalingBounds.d.ts +0 -15
- package/lib/utils/signalingFrame.d.ts +0 -21
- package/lib/utils/signalingHeartbeatWatchdog.d.ts +0 -45
- package/lib/utils/signalingIngressQueue.d.ts +0 -49
- package/lib/utils/signalingPeerRequestDebouncer.d.ts +0 -13
- package/lib/utils/signalingRoomLifecycle.d.ts +0 -7
- package/lib/utils/signalingRoomOperationLifecycle.d.ts +0 -14
- package/lib/utils/signalingServerBoundary.d.ts +0 -11
- package/lib/utils/splitToChunks.d.ts +0 -30
- package/lib/utils/transportIdentity.d.ts +0 -5
- package/lib/utils/uint8array.d.ts +0 -16
- package/lib/utils/waitForOpen.d.ts +0 -3
- package/lib/utils/zeroFree.d.ts +0 -10
package/README.md
CHANGED
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
Protocol-v4 end-to-end encryption and reliable file transfer over a WebRTC
|
|
10
10
|
room mesh.
|
|
11
11
|
|
|
12
|
-
Apache-2.0 · [LICENSE.md](
|
|
12
|
+
Apache-2.0 · [License](LICENSE.md) · [Getting started](docs/getting-started.md) ·
|
|
13
|
+
[Contributing](CONTRIBUTING.md) · [Security policy](SECURITY.md)
|
|
13
14
|
|
|
14
15
|
> Status: protocol v4 is an intentional wire break — v3 peers and persisted v3
|
|
15
16
|
> crypto rows are not resumed. The current code has not completed an
|
|
@@ -33,7 +34,7 @@ Apache-2.0 · [LICENSE.md](LICENSE.md)
|
|
|
33
34
|
decoy slots can hide a message's exact payload length within its transfer.
|
|
34
35
|
- Each outbound message has its own transfer identity and data channel, a
|
|
35
36
|
cancellable handle, authenticated receipts, selective retransmission, and
|
|
36
|
-
reconnect
|
|
37
|
+
reconnect and sender-reload recovery from a bounded durable outbox.
|
|
37
38
|
- Text and files up to the enforced 10 GiB application limit are supported.
|
|
38
39
|
Browser builds use IndexedDB and, where available, OPFS for disk-backed large
|
|
39
40
|
file receipt.
|
|
@@ -248,15 +249,14 @@ reconverge and exchange byte-exact messages 0.5–6.5 s after wake, and four
|
|
|
248
249
|
in-flight 8 MiB transfer configurations finish byte-exact with the sender
|
|
249
250
|
reporting `delivered`.
|
|
250
251
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
[roadmap](ROADMAP.md#near-term).
|
|
252
|
+
Prepared sends now survive sender reloads in the same browser storage and
|
|
253
|
+
identity. Pending state and retry/cancel APIs are described in
|
|
254
|
+
[durable transfer recovery](docs/getting-started.md). A failed `handle.done`
|
|
255
|
+
reports the outcome of that attempt; it does not mean its pending data was
|
|
256
|
+
removed. The outbox retains prepared sends for up to 24 hours and cannot recover
|
|
257
|
+
an upload whose preparation never finished or whose browser storage was erased.
|
|
258
|
+
Current measured recovery results and remaining compatibility limits are in
|
|
259
|
+
[the browser report](docs/e2e/README.md).
|
|
260
260
|
|
|
261
261
|
## Wire format
|
|
262
262
|
|
|
@@ -795,14 +795,9 @@ is what this package compiles.
|
|
|
795
795
|
|
|
796
796
|
## No build step: a script tag and the CDN
|
|
797
797
|
|
|
798
|
-
> **`0.14.
|
|
799
|
-
>
|
|
800
|
-
>
|
|
801
|
-
> answers 404, and npm still resolves `p2party` to an older release. The
|
|
802
|
-
> snippet below is generated from this build and is what the release will
|
|
803
|
-
> serve — until then, either pin the version `npm view p2party version` reports
|
|
804
|
-
> (its objects are live) or self-host the bundle, which works today and is
|
|
805
|
-
> described in the next section.
|
|
798
|
+
> **`0.14.10` is a local release candidate.** This work does not publish npm
|
|
799
|
+
> packages or CDN assets. The snippet names the candidate's intended release
|
|
800
|
+
> path; use the generated local bundle until that version is published.
|
|
806
801
|
|
|
807
802
|
A release publishes its browser bundle, its database worker and its
|
|
808
803
|
cryptographic module as immutable, versioned CDN objects. The version is in the
|
|
@@ -815,8 +810,8 @@ script in and `window.p2party` is there — no npm, no bundler, no build:
|
|
|
815
810
|
<title>p2party in one file</title>
|
|
816
811
|
|
|
817
812
|
<script
|
|
818
|
-
src="https://cdn.p2party.com/@0.14.
|
|
819
|
-
integrity="sha384-
|
|
813
|
+
src="https://cdn.p2party.com/@0.14.10/p2party.min.js"
|
|
814
|
+
integrity="sha384-z5PjsRDKjtPcQ9JhEwkPyr/7zthzQgjjh6pSTdjTmhZrwVhhhFS/KhRkGtmJwqJX"
|
|
820
815
|
crossorigin="anonymous"
|
|
821
816
|
></script>
|
|
822
817
|
|
|
@@ -855,7 +850,7 @@ https://cdn.p2party.com/@<version>/libcrypto.wasm the cryptographic module
|
|
|
855
850
|
The `integrity` value above is this release's bundle, and the release build
|
|
856
851
|
fails if the README and the built artifact ever disagree — so it is safe to
|
|
857
852
|
copy verbatim. The worker, if you host it yourself, is
|
|
858
|
-
`integrity=sha384-
|
|
853
|
+
`integrity=sha384-iZfBJVoMgpK1+s2shZQucC0OUSBaX4eHMTjHj4NqzGApUodsP9T16+EHgyDKTVQP`.
|
|
859
854
|
|
|
860
855
|
The WASM is integrity-checked whether or not you pin the script: that hash is
|
|
861
856
|
compiled into the bundle and cannot be turned off.
|
|
@@ -894,7 +889,7 @@ immutable, versioned path, so a URL names exactly one build and is safe to
|
|
|
894
889
|
cache forever:
|
|
895
890
|
|
|
896
891
|
```sh
|
|
897
|
-
curl -O "https://cdn.p2party.com/@$(npm view p2party version)/libcrypto.wasm"
|
|
892
|
+
curl --compressed -O "https://cdn.p2party.com/@$(npm view p2party version)/libcrypto.wasm"
|
|
898
893
|
```
|
|
899
894
|
|
|
900
895
|
Two caveats, both current as of this release. The CDN carries only three
|
|
@@ -905,6 +900,14 @@ the tarball. And nothing is uploaded for this release yet, which is why the
|
|
|
905
900
|
command above asks npm for a version that is actually published instead of
|
|
906
901
|
naming this one.
|
|
907
902
|
|
|
903
|
+
New CDN uploads gzip all three objects; WASM keeps `Content-Type:
|
|
904
|
+
application/wasm` and uses `Content-Encoding: gzip`. Browsers decode it before
|
|
905
|
+
SRI verification, and `curl --compressed` saves those same decoded bytes for
|
|
906
|
+
the checks below. Existing raw WASM objects remain untouched when their decoded
|
|
907
|
+
content matches; enabling compression never overwrites a published version.
|
|
908
|
+
Upload preparation compresses the validated artifacts already in `lib/`; it
|
|
909
|
+
does not replace them from a local development crypto build.
|
|
910
|
+
|
|
908
911
|
Check what you downloaded before you serve it. The SHA-256 and the SRI value
|
|
909
912
|
are both recorded in the provenance file:
|
|
910
913
|
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -68,7 +68,7 @@ SOFTWARE.
|
|
|
68
68
|
|
|
69
69
|
## Emscripten-generated runtime
|
|
70
70
|
|
|
71
|
-
The WebAssembly and JavaScript glue are built with Emscripten 6.0.
|
|
71
|
+
The WebAssembly and JavaScript glue are built with Emscripten 6.0.9.
|
|
72
72
|
|
|
73
73
|
Verbatim upstream license:
|
|
74
74
|
|
|
@@ -416,11 +416,6 @@ The browser bundle and/or installed runtime dependency graph includes:
|
|
|
416
416
|
- `redux-thunk` 3.1.0 — Copyright (c) 2015-present Dan Abramov
|
|
417
417
|
- `reselect` 5.1.1 — Copyright (c) 2015-2018 Reselect Contributors
|
|
418
418
|
- `immer` 11.1.15 — Copyright (c) 2017 Michel Weststrate
|
|
419
|
-
- `class-validator` 0.15.1 — Copyright (c) 2015-2020 TypeStack
|
|
420
|
-
- `validator` 13.15.23 — Copyright (c) 2018 Chris O'Hara
|
|
421
|
-
`<cohara87@gmail.com>`
|
|
422
|
-
- `libphonenumber-js` 1.12.27 — Copyright (c) 2016 @catamphetamine
|
|
423
|
-
`<purecatamphetamine@gmail.com>`
|
|
424
419
|
|
|
425
420
|
Each component above is MIT-licensed. Verbatim grant and disclaimer:
|
|
426
421
|
|
|
@@ -456,3 +451,35 @@ Permission to use, copy, modify, and/or distribute this software for any purpose
|
|
|
456
451
|
|
|
457
452
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
458
453
|
```
|
|
454
|
+
|
|
455
|
+
## Emscripten TypeScript declarations
|
|
456
|
+
|
|
457
|
+
The module-scoped `EmscriptenModule` and factory types are adapted from
|
|
458
|
+
`@types/emscripten` 1.41.5 in DefinitelyTyped. All inherited LibCrypto members
|
|
459
|
+
are retained; unrelated global declarations are not included.
|
|
460
|
+
|
|
461
|
+
Verbatim upstream license:
|
|
462
|
+
|
|
463
|
+
```text
|
|
464
|
+
MIT License
|
|
465
|
+
|
|
466
|
+
Copyright (c) Microsoft Corporation.
|
|
467
|
+
|
|
468
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
469
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
470
|
+
in the Software without restriction, including without limitation the rights
|
|
471
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
472
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
473
|
+
furnished to do so, subject to the following conditions:
|
|
474
|
+
|
|
475
|
+
The above copyright notice and this permission notice shall be included in all
|
|
476
|
+
copies or substantial portions of the Software.
|
|
477
|
+
|
|
478
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
479
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
480
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
481
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
482
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
483
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
484
|
+
SOFTWARE
|
|
485
|
+
```
|
package/docs/getting-started.md
CHANGED
|
@@ -109,6 +109,14 @@ bytes are deliberately absent from the public policy, Redux, persistent room
|
|
|
109
109
|
records, and logs. PIN mode adds CPace authentication to the identity and
|
|
110
110
|
ML-KEM handshake; it does not replace identity possession.
|
|
111
111
|
|
|
112
|
+
The SDK retries an unexpectedly closed signaling socket with bounded backoff.
|
|
113
|
+
Let that controller own recovery: do not call `connect()` on every disconnected
|
|
114
|
+
render or browser focus event. Call it for initial admission and a deliberate
|
|
115
|
+
retry, such as entering a corrected PIN. Terminal PIN or policy failures stay
|
|
116
|
+
visible and do not trigger automatic peer discovery or transport retries.
|
|
117
|
+
A fresh connection request from the other peer can retry that peer's failed
|
|
118
|
+
edge; the existing PIN-attempt throttle still applies.
|
|
119
|
+
|
|
112
120
|
Scheduled timing cover is wired as of 0.14: a policy may pin `coverMode:
|
|
113
121
|
"scheduled"` with a cadence, lane count, and frames per cell, and every edge in
|
|
114
122
|
the room then emits fixed-size cells on that schedule whether or not data is
|
|
@@ -117,8 +125,10 @@ their live transport wiring is not complete.
|
|
|
117
125
|
|
|
118
126
|
## Send, cancel, and read
|
|
119
127
|
|
|
120
|
-
Wait until the room has
|
|
121
|
-
transfer ID
|
|
128
|
+
Wait until the room has known recipient identities before sending. Each logical
|
|
129
|
+
send has a random transfer ID. Immediate mode opens a per-message data channel
|
|
130
|
+
on each eligible edge; scheduled mode places its chunks into the existing
|
|
131
|
+
fixed-cadence cover lanes.
|
|
122
132
|
|
|
123
133
|
```ts
|
|
124
134
|
const handle = p2party.sendMessage("hello room", "chat", room.id);
|
|
@@ -147,8 +157,97 @@ void cancel; // Remove when a UI event uses it.
|
|
|
147
157
|
|
|
148
158
|
`sendMessage()` returns a `MessageTransferHandle`, not a promise. `done`
|
|
149
159
|
settles after all started peer sends and cleanup and reports ordered per-peer
|
|
150
|
-
outcomes. A peer may be delivered, failed during setup/transfer,
|
|
151
|
-
because it is disconnected, unauthenticated, or the transfer was
|
|
160
|
+
outcomes for that attempt. A peer may be delivered, failed during setup/transfer,
|
|
161
|
+
or skipped because it is disconnected, unauthenticated, or the transfer was
|
|
162
|
+
cancelled. A rejected attempt can still have a durable pending transfer: do not
|
|
163
|
+
label it delivered, or assume that its resend source was discarded.
|
|
164
|
+
|
|
165
|
+
The sender publishes its outbox record only after every staged chunk, the
|
|
166
|
+
Merkle tree, and its local message copy have committed. A reload before that
|
|
167
|
+
point cannot resume preparation; select the original file again. After
|
|
168
|
+
publication, a reload or an exhausted reconnect budget retains the original
|
|
169
|
+
transfer ID, Merkle root and staged bytes for retry. Nothing is rehashed or
|
|
170
|
+
randomly repadded on a resumed send.
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
import type { PendingMessage } from "p2party";
|
|
174
|
+
|
|
175
|
+
const pending: PendingMessage[] = await p2party.listPendingMessages(room.id);
|
|
176
|
+
for (const message of pending) {
|
|
177
|
+
console.log(message.filename, message.phase, message.remainingRecipients);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Use a deliberate retry button. It may take the room's scheduled delivery
|
|
181
|
+
// time to settle; leave cancellation available while this promise is pending.
|
|
182
|
+
try {
|
|
183
|
+
const attempts = await p2party.resumePendingMessages(room.id);
|
|
184
|
+
for (const attempt of attempts) console.table(attempt.outcomes);
|
|
185
|
+
} catch (error) {
|
|
186
|
+
// AggregateError.errors contains failed attempts; their pending records stay
|
|
187
|
+
// available unless explicitly cancelled or expired.
|
|
188
|
+
console.error(error);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Exact logical-send cancellation also works after the original handle was
|
|
192
|
+
// lost to a reload. It fences queued writes before removing retained staging.
|
|
193
|
+
if (pending[0])
|
|
194
|
+
await p2party.cancelPendingMessage(room.id, pending[0].transferId);
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Authenticated-peer events trigger a serialized retry pass, including a bounded
|
|
198
|
+
claim after an old tab's lease expires. A failed pass does not start an endless
|
|
199
|
+
retry timer. Explicit retry requires verified signaling and a matching
|
|
200
|
+
currently authenticated recipient; it never calls `connect()`, prompts for a
|
|
201
|
+
passkey, or supplies a PIN. A PIN room must first be admitted with the user's
|
|
202
|
+
current in-memory PIN. PIN and policy failures remain terminal until a deliberate
|
|
203
|
+
authentication retry.
|
|
204
|
+
|
|
205
|
+
The immutable outbox binds the sender's public key and durable identity
|
|
206
|
+
revision, room capability and canonical policy, channel, and recipient public
|
|
207
|
+
keys. Session peer IDs may change. Only one tab can own a transfer's 30-second
|
|
208
|
+
lease at a time; it renews every 10 seconds. A stale tab cannot publish queued
|
|
209
|
+
writes or renew a replacement owner's lease. Terminal signaling refusal stops
|
|
210
|
+
its current owners, and switching identity invalidates the old outbox.
|
|
211
|
+
|
|
212
|
+
Confirmed recipients are recorded separately and never retried. A recipient's
|
|
213
|
+
explicit cancellation also ends retries to that recipient without cancelling
|
|
214
|
+
other recipients. Immediate retries rebuild the have-set from authenticated
|
|
215
|
+
receipt replay, so older receivers that discarded a closed channel's partial
|
|
216
|
+
can still recover. Scheduled retries preserve the receipt bitmap and send
|
|
217
|
+
missing chunks plus at most one already-received real chunk as a completion
|
|
218
|
+
probe. The fixed cover cadence and lane count remain unchanged.
|
|
219
|
+
|
|
220
|
+
Retention and admission have explicit limits:
|
|
221
|
+
|
|
222
|
+
- Published pending transfers expire 24 hours after publication. Active owners
|
|
223
|
+
are protected while they run; a completed recipient is never reported as a
|
|
224
|
+
new delivery merely because staging remains.
|
|
225
|
+
- Interrupted preparation expires after one hour. Its `phase` remains
|
|
226
|
+
`"staging"`; an expired `retryAfter` means its owner is gone, not that the
|
|
227
|
+
unfinished file can resume.
|
|
228
|
+
- At most 32 pending transfers and 64 recipients per transfer are admitted.
|
|
229
|
+
Their aggregate storage reservation is capped at 12 GiB and charges padded
|
|
230
|
+
cells, metadata, proofs and the sender's local copy. Browser quota can impose
|
|
231
|
+
a smaller limit than the 10 GiB per-message protocol maximum. Admission
|
|
232
|
+
refuses excess work rather than evicting another pending send.
|
|
233
|
+
- Incomplete received transfers expire after 24 hours without local receive
|
|
234
|
+
activity. Cleanup uses the device's activity clock, not the sender's message
|
|
235
|
+
timestamp. It protects active writes, completed messages and sender copies,
|
|
236
|
+
checks the room/receive owner, and fences writes queued before cancellation.
|
|
237
|
+
|
|
238
|
+
Storage sweeps run when pending transfers are listed or an authentication event
|
|
239
|
+
checks for resumable work. Maintenance runs immediately on the first check,
|
|
240
|
+
then at most once every 30 seconds, and defers while receive queues are busy.
|
|
241
|
+
Committed expiry also removes the old room view and retires its mapped receive
|
|
242
|
+
key, preserving newer receives and connection generations.
|
|
243
|
+
Cancelling or deleting a message removes its pending
|
|
244
|
+
outbox; leaving a room discards that room's pending work. Successful completion
|
|
245
|
+
removes resend staging while retaining completed local history.
|
|
246
|
+
|
|
247
|
+
The outbox reuses the already-staged message bytes in browser storage; it is
|
|
248
|
+
not a new encryption-at-rest guarantee for files or message history. It stores
|
|
249
|
+
no PIN, passkey assertion, plaintext ratchet key or message key. A resumed send
|
|
250
|
+
derives fresh message encryption state from the currently authenticated edge.
|
|
152
251
|
|
|
153
252
|
For an inbound message, take `merkleRootHex` (and, if needed, `sha512Hex`) from
|
|
154
253
|
the room's exported `messages` state:
|
|
@@ -17,9 +17,9 @@ There are three different acknowledgements in the system:
|
|
|
17
17
|
2. The protocol-v4 handshake runs over the open main channel. After HELLO,
|
|
18
18
|
responder CONFIRM, initiator CONFIRM, and responder FINISH, the peers have
|
|
19
19
|
authenticated the same hybrid root and initial ratchet keys.
|
|
20
|
-
3.
|
|
21
|
-
|
|
22
|
-
establishment.
|
|
20
|
+
3. Immediate 65-byte receipts on authenticated message channels, or encrypted
|
|
21
|
+
scheduled control cells, acknowledge chunks and transfer completion. They
|
|
22
|
+
are delivery/reconciliation signals, not handshake establishment.
|
|
23
23
|
|
|
24
24
|
An open data channel therefore is necessary transport readiness, not an
|
|
25
25
|
established p2party crypto session.
|
|
@@ -66,15 +66,65 @@ byte so the sparse post-quantum healing epoch cannot wrap.
|
|
|
66
66
|
|
|
67
67
|
The fixed frame geometry absorbs the ratchet and AEAD overhead into the cell
|
|
68
68
|
budget. Random padding and decoy slots can hide the exact payload length within
|
|
69
|
-
one transfer's chosen number of frames.
|
|
70
|
-
geometry
|
|
71
|
-
65,490-byte
|
|
69
|
+
one transfer's chosen number of frames. Immediate receipts have a distinct
|
|
70
|
+
65-byte geometry and immediate pause/cancel controls are 66 bytes. Scheduled
|
|
71
|
+
receipt batches, terminal receipts and CANCELs occupy existing 65,490-byte
|
|
72
|
+
cover slots. Handshake flights are suite- and step-dependent.
|
|
72
73
|
|
|
73
74
|
Per-message channels give each transfer an independent lifecycle for
|
|
74
75
|
cancellation, bounded channel accounting, receipts, selective retransmission,
|
|
75
76
|
and reconnect resume. Channel isolation is a UX and reliability property; it
|
|
76
77
|
does not make timing or channel count invisible.
|
|
77
78
|
|
|
79
|
+
### Durable selective resume and cancellation
|
|
80
|
+
|
|
81
|
+
A chunk acknowledgement becomes live only after its per-recipient outbox
|
|
82
|
+
update commits. Receipt acceptance binds room, peer ID, peer public key,
|
|
83
|
+
random transfer ID, Merkle root and original chunk index. Scheduled cells
|
|
84
|
+
add direction, PQ epoch, AEAD and counter replay checks; their terminal token
|
|
85
|
+
must equal the transfer root. Stale asynchronous storage responses cannot
|
|
86
|
+
advance a replacement owner's live state. Recipient refusal is persisted
|
|
87
|
+
separately from completion and stops only that recipient's retry.
|
|
88
|
+
|
|
89
|
+
Scheduled chunk receipts use a separate encrypted subtype with up to 64 tokens
|
|
90
|
+
per root. Existing subtype 3 remains terminal-only: older clients interpreted
|
|
91
|
+
any token in that subtype as completion. Older protocol-v4 clients drop the
|
|
92
|
+
new subtype and retain terminal-only scheduled delivery, including full replay
|
|
93
|
+
when necessary. Selective scheduled resume therefore requires supporting peers.
|
|
94
|
+
|
|
95
|
+
Have-set membership is O(1) in memory and does not allocate a set copy per
|
|
96
|
+
scheduled slot. A resume scans indices once, sends missing real chunks and
|
|
97
|
+
may send one completion probe. Storage lookup costs, initial file preparation
|
|
98
|
+
and scanning remain; this is not a claim of sublinear total file processing.
|
|
99
|
+
Batching and selective resume reduce real work within the existing schedule,
|
|
100
|
+
whose observable cell count remains fixed.
|
|
101
|
+
|
|
102
|
+
Immediate resume uses the channel protocol `p2party-resume-v1` and a capability
|
|
103
|
+
echo to distinguish pause from explicit cancellation. Type-6 controls are
|
|
104
|
+
authenticated by the concrete DTLS/SCTP channel and current identity gate,
|
|
105
|
+
with an exact-root check; they do not have a separate application AEAD.
|
|
106
|
+
Legacy peers retain close-as-cancel behavior. A fresh immediate attempt
|
|
107
|
+
rebuilds its have-set from paced receiver receipts instead of assuming a
|
|
108
|
+
legacy receiver retained its partial. Remote cancellation drains pending
|
|
109
|
+
writes, then atomically checks room, sender and incomplete status before
|
|
110
|
+
deleting receiver data; completed files and sender self-copies are preserved.
|
|
111
|
+
|
|
112
|
+
### Sparse-PQ healing during scheduled sends
|
|
113
|
+
|
|
114
|
+
Local healing waits for queued or admitted real jobs, message channels,
|
|
115
|
+
derive-to-enqueue reservations and queued receive work to drain. An atomic
|
|
116
|
+
application reservation closes the race between deriving a message key and
|
|
117
|
+
admitting its scheduled producer. Dummy cover does not block healing.
|
|
118
|
+
|
|
119
|
+
An incoming exchange blocks new admission and drains reservations, then
|
|
120
|
+
persists its new epoch before adopting it. Epoch adoption invalidates old-key
|
|
121
|
+
real producers on the same scheduler and wakes bounded sender recovery.
|
|
122
|
+
Recovery requires an actual epoch advance when reusing that runtime and
|
|
123
|
+
re-derives the missing chunks. If sealing was already in flight, its retired
|
|
124
|
+
cell is wiped and the slot remains dummy; pending explicit CANCEL is resealed
|
|
125
|
+
under the new epoch. Lane timing continues throughout this transition.
|
|
126
|
+
Persistence failure leaves the prior live epoch unchanged for exact retry.
|
|
127
|
+
|
|
78
128
|
## Guarantees, assuming authenticated peer keys
|
|
79
129
|
|
|
80
130
|
With a correctly pinned peer Ed25519 identity, uncompromised endpoints, matching
|
|
@@ -128,7 +178,7 @@ receives its normalized value. A fragment is not a server-blind meeting point.
|
|
|
128
178
|
|
|
129
179
|
## Signaling and TURN correctness boundary
|
|
130
180
|
|
|
131
|
-
SDK 0.14.
|
|
181
|
+
SDK 0.14.10 makes legacy signaling state transitions correlated and bounded; it
|
|
132
182
|
does not make that signaling path blind.
|
|
133
183
|
|
|
134
184
|
- A room response is accepted only for the exact current socket, room
|
package/docs/references.md
CHANGED
|
@@ -172,6 +172,6 @@ third-party security audit. Cite the implementation:
|
|
|
172
172
|
@software{p2party,
|
|
173
173
|
title = {p2party: protocol-v4 end-to-end encryption over a WebRTC room mesh},
|
|
174
174
|
url = {https://github.com/p2party/p2party-js},
|
|
175
|
-
note = {Version 0.14.
|
|
175
|
+
note = {Version 0.14.10}
|
|
176
176
|
}
|
|
177
177
|
```
|
package/docs/session-api.md
CHANGED
|
@@ -381,6 +381,15 @@ The bootstrap ML-KEM exchange protects the initial root. Healing periodically
|
|
|
381
381
|
re-runs it so a later post-quantum compromise cannot unwind an old session.
|
|
382
382
|
The session owns the state machine; the caller owns scheduling and transport.
|
|
383
383
|
|
|
384
|
+
The browser SDK separately coordinates queued scheduled producers with epoch
|
|
385
|
+
changes, persists per-recipient chunk receipts, and implements WebRTC pause and
|
|
386
|
+
CANCEL controls. Those transport/outbox services are not part of
|
|
387
|
+
`p2party/session`. A session integrator must coordinate its own pending output
|
|
388
|
+
and recovery when `pqEpoch` changes; the session does not selectively resend
|
|
389
|
+
previously returned frames or interpret cover receipt subtypes. See the
|
|
390
|
+
[wire format](wire-format.md#scheduled-control-cells--65490-bytes) for the browser
|
|
391
|
+
contract.
|
|
392
|
+
|
|
384
393
|
Control frames are the same 65,490-byte size as chunk frames, so the outer
|
|
385
394
|
framing MUST record which kind a record is — the session will reject a control
|
|
386
395
|
frame handed to `decrypt()` and vice versa.
|
package/docs/wire-format.md
CHANGED
|
@@ -1,26 +1,29 @@
|
|
|
1
1
|
# Wire format
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
[`src/utils/constants.ts`](../src/utils/constants.ts)
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
Chunk geometry is defined in
|
|
4
|
+
[`src/utils/constants.ts`](../src/utils/constants.ts) and byte-matched in
|
|
5
|
+
`utils.h`. Scheduled control subtypes are defined in
|
|
6
|
+
[`coverCell.ts`](../src/cryptography/coverCell.ts); immediate transfer controls
|
|
7
|
+
are defined in [`immediateDisposition.ts`](../src/handlers/immediateDisposition.ts).
|
|
8
|
+
For what these frames do and do not protect, read the
|
|
7
9
|
[protocol-v4 security boundary](protocol-v4-security.md).
|
|
8
10
|
|
|
9
|
-
|
|
10
11
|
## Outer frame types
|
|
11
12
|
|
|
12
13
|
One tag byte leads every frame on a data channel.
|
|
13
14
|
|
|
14
|
-
| Tag | Name
|
|
15
|
-
| --- |
|
|
16
|
-
| 1 | `HANDSHAKE`
|
|
17
|
-
| 2 | `CHUNK`
|
|
18
|
-
| 3 | `RECEIPT`
|
|
19
|
-
| 4 | `COVER`
|
|
20
|
-
| 5 | `PQ_CONTROL`
|
|
15
|
+
| Tag | Name | Size on the wire | Carries |
|
|
16
|
+
| --- | ----------------------- | ---------------- | ------------------------------------- |
|
|
17
|
+
| 1 | `HANDSHAKE` | step-dependent | HELLO, CONFIRM, FINISH |
|
|
18
|
+
| 2 | `CHUNK` | 65,490 B | one fixed application cell |
|
|
19
|
+
| 3 | `RECEIPT` | 65 B | SHA-512 acknowledgement token |
|
|
20
|
+
| 4 | `COVER` | 65,490 B | scheduled dummy or encrypted control |
|
|
21
|
+
| 5 | `PQ_CONTROL` | 65,490 B | sparse-PQ OFFER / ADVANCE / ACK |
|
|
22
|
+
| 6 | `IMMEDIATE_DISPOSITION` | 66 B | immediate resume capability or CANCEL |
|
|
21
23
|
|
|
22
|
-
Tags 2, 4, and 5
|
|
23
|
-
|
|
24
|
+
Tags 2, 4, and 5 have equal payload lengths. The frame tags travel inside
|
|
25
|
+
WebRTC's DTLS transport; packetization, timing and total traffic remain
|
|
26
|
+
observable. Scheduled real data uses tag 2 in a scheduled lane slot.
|
|
24
27
|
|
|
25
28
|
## Chunk frame — 65,490 bytes
|
|
26
29
|
|
|
@@ -52,6 +55,81 @@ application cell from a decoy or from a healing exchange by looking at the wire.
|
|
|
52
55
|
|
|
53
56
|
Both per-chunk acknowledgements and the terminal content-hash acknowledgement
|
|
54
57
|
use this exact geometry, so a completion is not distinguishable by size.
|
|
58
|
+
Chunk tokens bind the transfer Merkle root, original chunk index and leaf hash.
|
|
59
|
+
The sender resolves them through its staged chunk index and persists the
|
|
60
|
+
per-recipient acknowledgement before updating the live have-set. A terminal
|
|
61
|
+
immediate receipt must equal the message's content hash. These frames use the
|
|
62
|
+
authenticated concrete message channel and its current identity gate.
|
|
63
|
+
|
|
64
|
+
## Scheduled control cells — 65,490 bytes
|
|
65
|
+
|
|
66
|
+
```text
|
|
67
|
+
type=4(1) || edge binding(32) || counter(8) || reserved zero(8) ||
|
|
68
|
+
PQ epoch(8) || nonce(12) || ciphertext(65,405) || AEAD tag(16)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
All 69 header bytes are authenticated. The key binds the room's suite, edge,
|
|
72
|
+
direction and PQ epoch. After authentication and counter replay rejection,
|
|
73
|
+
the plaintext is `subtype(1) || payload length(4, BE) || payload || zero pad`:
|
|
74
|
+
|
|
75
|
+
| Subtype | Meaning | Payload |
|
|
76
|
+
| ------- | ---------------- | ---------------------------------------------------------------------- |
|
|
77
|
+
| 1 | Dummy | Empty |
|
|
78
|
+
| 2 | CANCEL | Transfer Merkle root (64 B) |
|
|
79
|
+
| 3 | Terminal receipt | Transfer Merkle root (64 B), followed by the same root as token (64 B) |
|
|
80
|
+
| 4 | Chunk receipts | Transfer Merkle root (64 B), followed by 1–64 chunk tokens (64 B each) |
|
|
81
|
+
|
|
82
|
+
Subtype 4's authenticated payload length determines the token count; partial
|
|
83
|
+
tokens, empty batches and batches over 64 tokens are rejected. Only tokens for
|
|
84
|
+
one transfer root share a batch. A subtype 3 token unequal to its root cannot
|
|
85
|
+
complete a send. Each chunk token must resolve to the tracked transfer, root
|
|
86
|
+
and a valid original index. The durable owner also binds room, recipient ID
|
|
87
|
+
and public key; a stale owner cannot advance live state after a storage await.
|
|
88
|
+
A recipient's CANCEL records refusal only for that recipient.
|
|
89
|
+
|
|
90
|
+
Receipts and CANCELs replace dummy slots in the existing schedule. The pending
|
|
91
|
+
outbound control queue is bounded to 4,096 token/control units; dropping a
|
|
92
|
+
queued acknowledgement may require a later retransmission. A terminal receipt
|
|
93
|
+
supersedes unsent chunk acknowledgements for the same root, preserving the
|
|
94
|
+
first available reverse slot for completion even at long cadences. Other roots
|
|
95
|
+
and queued CANCEL controls retain their order. Live have-set
|
|
96
|
+
membership uses an O(1) `Set` lookup without copying the set per slot. A resumed
|
|
97
|
+
producer scans original indices once and emits missing chunks. It also selects
|
|
98
|
+
index zero once per attempt to recover a lost terminal receipt: if that index
|
|
99
|
+
was already acknowledged, this costs one extra completion probe. Index scanning
|
|
100
|
+
and durable token lookups do not imply globally sublinear processing, and fewer
|
|
101
|
+
real chunks do not reduce the fixed scheduled cell count.
|
|
102
|
+
|
|
103
|
+
Subtype 4 is a protocol-v4 wire addition. Earlier clients reject and drop this
|
|
104
|
+
unknown subtype and keep using subtype 3 completion. They cannot selectively
|
|
105
|
+
resume scheduled chunks; a missing terminal receipt can require whole-transfer
|
|
106
|
+
replay. Subtype 3 is never reused for chunk tokens, because earlier clients
|
|
107
|
+
treated any subtype 3 receipt for a tracked root as completion. These additions
|
|
108
|
+
do not introduce a fallback to an earlier cryptographic protocol version.
|
|
109
|
+
|
|
110
|
+
## Immediate pause and cancellation — 66 bytes
|
|
111
|
+
|
|
112
|
+
```text
|
|
113
|
+
type=6(1) || kind(1) || transfer Merkle root(64)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Kind 0 announces resume support; kind 1 is explicit CANCEL. An immediate
|
|
117
|
+
message channel opened with DCEP protocol `p2party-resume-v1` promises that a
|
|
118
|
+
bare close may pause the transfer. A supporting receiver echoes kind 0 after
|
|
119
|
+
the identity gate opens; the opener then also treats a bare remote close as
|
|
120
|
+
pause. CANCEL is accepted once per concrete channel, only under its current
|
|
121
|
+
authenticated gate and exact root. Malformed, unknown, stale and cross-root
|
|
122
|
+
controls have no effect. This control relies on the authenticated DTLS/SCTP
|
|
123
|
+
channel; it has no separate application AEAD envelope.
|
|
124
|
+
|
|
125
|
+
An explicit cancellation sends kind 1 before closing. A transient failed
|
|
126
|
+
attempt closes without CANCEL, allowing a supporting receiver to retain its
|
|
127
|
+
partial data for bounded resume. Earlier clients ignore type 6 and retain
|
|
128
|
+
their close-as-cancel behavior. At a fresh immediate attempt the new sender
|
|
129
|
+
starts a fresh live chunk have-set and rebuilds it from the receiver's paced
|
|
130
|
+
receipt replay, so deleted legacy partials cause full resend
|
|
131
|
+
instead of trusting stale acknowledgements. The store-free session API does
|
|
132
|
+
not implement this WebRTC channel contract.
|
|
55
133
|
|
|
56
134
|
## Handshake ladder
|
|
57
135
|
|
|
@@ -88,6 +166,16 @@ rather than something both sides have to reconcile. Each side persists its
|
|
|
88
166
|
mutated state **before** dispatching, and application traffic is blocked while
|
|
89
167
|
an epoch is in flight.
|
|
90
168
|
|
|
169
|
+
The browser scheduler starts a local exchange only when no real producer,
|
|
170
|
+
derive-to-enqueue reservation, message channel or queued receive work remains.
|
|
171
|
+
Dummy/control cover alone does not hold it back. A remote exchange blocks new
|
|
172
|
+
application admission and drains reservations before the durable transition;
|
|
173
|
+
it does not wait for a long scheduled send to finish. A committed new epoch
|
|
174
|
+
retires old-key real producers and publishes a cover generation change on the
|
|
175
|
+
same runtime. The sender re-derives the remaining transfer under that epoch;
|
|
176
|
+
fixed lane timing continues with dummy tails. An unrelated generation notice
|
|
177
|
+
cannot authorize reuse of the same runtime without an actual PQ epoch advance.
|
|
178
|
+
|
|
91
179
|
## Room policy — 32 bytes
|
|
92
180
|
|
|
93
181
|
A room's policy is a fixed 32-byte record (magic `"P2RP"`) that pins the ML-KEM
|
|
@@ -8,6 +8,44 @@ export interface WebSocketParams {
|
|
|
8
8
|
export interface WebSocketMessage {
|
|
9
9
|
content: WebSocketMessagePongResponse | WebSocketMessageCandidateSend | WebSocketMessageDescriptionSend | WebSocketMessageChallengeResponse | WebSocketMessageRoomIdRequest | WebSocketMessageLeaveRoomRequest | WebSocketMessagePeersRequest | WebSocketMessageConnectionResponse | WebSocketMessagePeerConnectionRequest;
|
|
10
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* The host the reconnect controller reads Redux state from and dispatches
|
|
13
|
+
* through. Bound on every connect attempt; the tests rebind it directly. It is
|
|
14
|
+
* NOT the store import, so this module keeps its existing dependency edges.
|
|
15
|
+
*/
|
|
16
|
+
type SignalingReconnectHost = {
|
|
17
|
+
dispatch: (action: unknown) => unknown;
|
|
18
|
+
getState: () => unknown;
|
|
19
|
+
};
|
|
20
|
+
export declare const setSignalingReconnectHost: (host: SignalingReconnectHost | null) => void;
|
|
21
|
+
/**
|
|
22
|
+
* Record how a socket ended, so the reconnect ladder can refuse a close the
|
|
23
|
+
* server means as final. `selfInitiated` is what keeps the SDK's own protective
|
|
24
|
+
* closes out of the policy: `onOverflow` closes with 1008 when this tab's
|
|
25
|
+
* ingress backlog is exceeded, and local overload is exactly what bounded
|
|
26
|
+
* backoff is for.
|
|
27
|
+
*/
|
|
28
|
+
export declare const noteSignalingSocketClose: (close: Readonly<{
|
|
29
|
+
code: number;
|
|
30
|
+
selfInitiated: boolean;
|
|
31
|
+
}>) => void;
|
|
32
|
+
/**
|
|
33
|
+
* A ladder rung is a floor, never shortened, and at most 25 % longer. Without
|
|
34
|
+
* this every client a server restart disconnected walks the identical
|
|
35
|
+
* 1/2/4/8 s ladder and re-handshakes in lockstep, which is the same stampede
|
|
36
|
+
* the restart caused. The spread lives here rather than in the controller
|
|
37
|
+
* because the controller's ladder is exact by contract and its tests assert
|
|
38
|
+
* exact delays; the scheduler this module injects is the seam that perturbs it.
|
|
39
|
+
*/
|
|
40
|
+
export declare const signalingReconnectDelayWithJitter: (delayMs: number) => number;
|
|
41
|
+
/**
|
|
42
|
+
* C4: a socket close that carries no browser wake event is otherwise terminal.
|
|
43
|
+
* `settleClosedSocket` detects; this reconnects. Shared by the close handler,
|
|
44
|
+
* the error handler and the heartbeat watchdog, so a peer whose socket died
|
|
45
|
+
* while its edges stayed authenticated is found again within 1-30 s instead of
|
|
46
|
+
* never.
|
|
47
|
+
*/
|
|
48
|
+
export declare const signalingReconnect: import("../utils/signalingReconnectController").SignalingReconnectController;
|
|
11
49
|
type CurrentSocketApi = Pick<BaseQueryApi, "dispatch" | "getState">;
|
|
12
50
|
/**
|
|
13
51
|
* Send a correlated leave on the exact authenticated socket and wait for its
|