Worked for 4m 50s
Completed the destination-routed DATA and reverse-PROOF three-tier unit. Key findings: Intermediate relays retarget HEADER_2; the final relay delivers HEADER_1. Each relay records independent reverse-table state. PROOF destination hashes remain invariant across transport transformations. A wrong-interface PROOF consumes the reverse entry before being dropped. REVERSE_TIMEOUT is 480 seconds, not 30 seconds. Added Tier 1 audit, two-relay flow, deterministic vectors, regenerator, and runtime verifier. Corrected affected specification, flows, playbook, and status documentation. Verification: Deterministic regeneration: identical SHA-256 Full pinned suite: 22 passed, 0 failed git diff --check: passed No commit created.
This commit is contained in:
parent
4a14dca3a4
commit
9c3b628c6a
14 changed files with 578 additions and 16 deletions
|
|
@ -22,6 +22,8 @@ The two views are complementary: SPEC.md tells you what each piece looks like; t
|
|||
| [`receive-propagated-lxmf.md`](receive-propagated-lxmf.md) (recipient pulling messages via `/get`) | ✅ |
|
||||
| [`propagation-peer-sync.md`](propagation-peer-sync.md) (propagation-node announce, `/offer`, and peer Resource sync) | ✅ |
|
||||
| [`lxmf-outbound-retry.md`](lxmf-outbound-retry.md) (process_outbound retry loop, per-message state machine, fail_message) | ✅ |
|
||||
| [`transport-link.md`](transport-link.md) (relayed Link establishment and established-Link traffic) | ✅ |
|
||||
| [`transport-data.md`](transport-data.md) (ordinary DATA and returning PROOF through relays) | ✅ |
|
||||
|
||||
## Conventions
|
||||
|
||||
|
|
|
|||
|
|
@ -195,20 +195,18 @@ SPEC.md §9.5: if the operator runs both an originator and a transport node on t
|
|||
|
||||
## Wire-byte summary (mirror of the send-flow summary)
|
||||
|
||||
What arrives at the recipient before deframing — assumes a 0-hop direct send (HEADER_1) or a >1-hop relayed packet that arrives as HEADER_2 with a transport_id at offset 2:
|
||||
What arrives at the recipient before deframing is HEADER_1 whether sent directly or delivered by a last-hop transport relay. Intermediate relays use HEADER_2, but the final relay strips the transport-id slot before transmission:
|
||||
|
||||
```
|
||||
HEADER_1:
|
||||
[ 1B flags ][ 1B hops ][ 16B dest_hash ][ 1B context=0x00 ]
|
||||
[ 32B sender_ephemeral_X25519_pub ][ 16B iv ]
|
||||
[ N×16B aes_ciphertext ][ 32B hmac_sha256 ]
|
||||
|
||||
HEADER_2 (after relay):
|
||||
[ 1B flags ][ 1B hops ][ 16B transport_id ][ 16B dest_hash ][ 1B context=0x00 ]
|
||||
[ 32B sender_ephemeral_X25519_pub ][ 16B iv ]
|
||||
[ N×16B aes_ciphertext ][ 32B hmac_sha256 ]
|
||||
```
|
||||
|
||||
See [`transport-data.md`](transport-data.md) for the intermediate HEADER_2
|
||||
forms and reverse-PROOF path.
|
||||
|
||||
After AES-CBC decryption with the matching ratchet (or long-term) key, the plaintext is the opportunistic LXMF body **without** the recipient's dest_hash (SPEC.md §5.1):
|
||||
|
||||
```
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ Strictly speaking, the flow above ends at step 10. Steps 11-13 are about **what
|
|||
|
||||
### 11. Recipient processes the inbound DATA packet
|
||||
|
||||
Inverse of steps 7-9, in the order: deframe → optional HEADER_2 strip / hop-table lookup → packet enters `Transport.inbound` → handed to the destination → `RNS.Destination.decrypt` reverses the Token (HMAC verified **before** AES decrypt per SPEC.md §3.3) → LXMF body parsed → Ed25519 signature verified, with the dual-msgpack-variant tolerance described in SPEC.md §5.6 → message surfaced to the recipient's app.
|
||||
Inverse of steps 7-9, in the order: intermediate relays process HEADER_2 via their path tables → the last relay strips the transport slot and emits HEADER_1 → recipient deframes → packet enters `Transport.inbound` → handed to the destination → `RNS.Destination.decrypt` reverses the Token (HMAC verified **before** AES decrypt per SPEC.md §3.3) → LXMF body parsed → Ed25519 signature verified, with the dual-msgpack-variant tolerance described in SPEC.md §5.6 → message surfaced to the recipient's app. See `transport-data.md` for the relay sequence.
|
||||
|
||||
The receive flow is its own document; see `receive-opportunistic-lxmf.md` (TODO) for the detailed step list.
|
||||
|
||||
|
|
|
|||
46
flows/transport-data.md
Normal file
46
flows/transport-data.md
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
# Flow: Destination-Routed DATA Through Transport Relays
|
||||
|
||||
This flow follows ordinary DATA and its returning PROOF across two transport
|
||||
relays, pinned to RNS 1.2.4. Opportunistic LXMF is the common example.
|
||||
|
||||
## Forward DATA
|
||||
|
||||
1. The originator emits HEADER_2 because its path has more than one hop. The
|
||||
`transport_id` names relay 1; the final destination hash remains in the
|
||||
second address slot.
|
||||
2. Relay 1 verifies that `transport_id` names itself and finds the final
|
||||
destination in `path_table`.
|
||||
3. With more than one remaining hop, relay 1 increments hops, replaces
|
||||
`transport_id` with relay 2's identity hash, and preserves HEADER_2.
|
||||
4. Relay 1 records `reverse_table[packet.getTruncatedHash()]` with the ingress
|
||||
and egress interfaces.
|
||||
5. Relay 2 receives the retargeted HEADER_2 packet. With one remaining hop, it
|
||||
increments hops, strips the transport slot, and emits HEADER_1 toward the
|
||||
destination.
|
||||
6. Relay 2 records its own reverse entry under the same truncated packet hash.
|
||||
|
||||
The hash is stable because `Packet.get_hashable_part()` excludes hops,
|
||||
transport type/header type, and the HEADER_2 transport-id slot.
|
||||
|
||||
## Returning PROOF
|
||||
|
||||
1. The destination emits a HEADER_1 PROOF addressed to the original DATA
|
||||
packet's truncated hash.
|
||||
2. Relay 2 pops that hash from `reverse_table`. If the PROOF arrived on the
|
||||
recorded outbound interface, it increments hops and sends toward relay 1.
|
||||
3. Relay 1 repeats the operation and sends toward the originator.
|
||||
4. Each entry is one-shot. A duplicate PROOF has no route.
|
||||
|
||||
## Failure Diagnostics
|
||||
|
||||
| Observation | Meaning |
|
||||
|---|---|
|
||||
| First relay receives DATA but does not forward it | Check HEADER_2 `transport_id` and relay `path_table`. |
|
||||
| Intermediate relay forwards HEADER_2 but final endpoint parser expects HEADER_2 | Endpoint receives HEADER_1; the last relay strips the transport slot. |
|
||||
| DATA reaches endpoint but no PROOF returns | Inspect every relay's reverse entry and recorded interfaces. |
|
||||
| PROOF appears first on the wrong interface | Upstream drops it after popping the reverse entry; a later correct copy cannot return. |
|
||||
| Reverse entry remains indefinitely in a clean-room relay | RNS 1.2.4 expires it after 480 seconds or when a recorded interface disappears. |
|
||||
|
||||
Executable evidence: `tools/verify_transport_data.py` and
|
||||
`test-vectors/transport-data.json`.
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue