carry transport proto end-to-end through OPEN/OPEN_ACK
OPEN and OPEN_ACK now carry proto:1 alongside upstream_id:1. The session is tagged with its transport proto and reliability semantics switch on the specific proto: - TCP (proto=1): full L2 reliability (seq, ack, retransmit, in-order) - UDP (proto=2, reserved): best-effort (no retransmit, no ordering, no pure ACKs — seq/ack_seq fields present but ignored) This is architecturally correct: instead of a generic 'reliable:bool' flag, each proto gets the semantics it needs. Today only TCP exists so every session is reliable, but the extension point is clean for when stateless protos are added. Updated: PROTOCOL.md, Rust frame.rs/session.rs/main.rs, C# Frame.cs/SessionManager.cs.
This commit is contained in:
+30
-15
@@ -65,8 +65,8 @@ Maximum payload: 1500 (Ethernet MTU) − 8 (common header) − 8 (seq + ack_seq)
|
||||
|------|-------------|---------------|------------|----------------------------------|
|
||||
| 0x01 | DISCOVER | C → broadcast | 0 | empty |
|
||||
| 0x02 | MANIFEST | S → C | 0 | `hostname_len:1, hostname:N, entries...` |
|
||||
| 0x03 | OPEN | C → S | 0 | `upstream_id:1` |
|
||||
| 0x04 | OPEN_ACK | S → C | assigned | `upstream_id:1` |
|
||||
| 0x03 | OPEN | C → S | 0 | `upstream_id:1, proto:1` |
|
||||
| 0x04 | OPEN_ACK | S → C | assigned | `upstream_id:1, proto:1` |
|
||||
| 0x05 | OPEN_NAK | S → C | 0 | `upstream_id:1, reason:1` |
|
||||
| 0x06 | DATA | both | session | `seq:4, ack_seq:4, raw bytes` |
|
||||
| 0x07 | CLOSE | both | session | optional `reason:1` |
|
||||
@@ -83,11 +83,21 @@ Reserved (unimplemented; parse returns Err, encode unimplemented):
|
||||
|
||||
## L2 reliability
|
||||
|
||||
DATA frames are delivered reliably and in-order via a TCP-like sequence +
|
||||
cumulative ACK + retransmit mechanism. This ensures that a dropped Ethernet
|
||||
frame does not permanently corrupt a TCP session (which would otherwise happen
|
||||
because the local kernel TCP stack ACKs data before it is chunked into DATA
|
||||
frames).
|
||||
The reliability semantics of a session depend on its transport proto,
|
||||
which is carried end-to-end through OPEN/OPEN_ACK:
|
||||
|
||||
- **TCP (`proto = 1`):** DATA frames are delivered reliably and in-order via
|
||||
a TCP-like sequence + cumulative ACK + retransmit mechanism. This ensures
|
||||
that a dropped Ethernet frame does not permanently corrupt a TCP session
|
||||
(which would otherwise happen because the local kernel TCP stack ACKs data
|
||||
before it is chunked into DATA frames).
|
||||
- **UDP (`proto = 2`, reserved):** DATA frames are delivered best-effort. The
|
||||
`seq` and `ack_seq` fields are present in the frame layout for uniformity
|
||||
but are ignored — no retransmit, no in-order buffering, no pure ACKs. Drops
|
||||
are tolerated because stateless protocols either don't care or handle
|
||||
recovery at the application layer.
|
||||
|
||||
The following sections describe the TCP reliability mechanism.
|
||||
|
||||
### Sender state (per session)
|
||||
|
||||
@@ -197,23 +207,28 @@ the payload is exhausted. The number of entries is not carried explicitly.
|
||||
### OPEN payload
|
||||
|
||||
```
|
||||
+---------------+
|
||||
| upstream_id |
|
||||
+---------------+
|
||||
+---------------+---------------+
|
||||
| upstream_id | proto |
|
||||
+---------------+---------------+
|
||||
```
|
||||
|
||||
- **upstream_id** (u8): which MANIFEST entry to open.
|
||||
- **proto** (u8): the transport protocol of the upstream (`1 = TCP`,
|
||||
`2 = UDP`). Carried end-to-end so both sides know which reliability
|
||||
semantics apply to the session. Must match the proto advertised in the
|
||||
MANIFEST for that upstream.
|
||||
|
||||
### OPEN_ACK payload
|
||||
|
||||
```
|
||||
+---------------+
|
||||
| upstream_id |
|
||||
+---------------+
|
||||
+---------------+---------------+
|
||||
| upstream_id | proto |
|
||||
+---------------+---------------+
|
||||
```
|
||||
|
||||
- **upstream_id** (u8): echoes the requested upstream. The session is
|
||||
identified by the `session_id` field in the header, not the payload.
|
||||
- **upstream_id** (u8): echoes the requested upstream.
|
||||
- **proto** (u8): echoes the requested proto. The session is identified by
|
||||
the `session_id` field in the header, not the payload.
|
||||
|
||||
### OPEN_NAK payload
|
||||
|
||||
|
||||
Reference in New Issue
Block a user