📝 document the fixed-length control protocol that I need to replace soon
parent
26135471cb
commit
d3675473ed
|
@ -22,6 +22,76 @@ The end-to-end testing above is the happy path. Try these sadder cases:
|
|||
- After Step 2, restart the relay server P3
|
||||
- After Step 3, restart the relay server P3
|
||||
|
||||
# Network protocol
|
||||
|
||||
For the prototype, all control messages are fixed 4-byte messages at the
|
||||
start of bidirectional streams.
|
||||
|
||||
Unused bytes are always "0".
|
||||
|
||||
## QUIC client connection
|
||||
|
||||
When P2 or P4 connects to P3 over QUIC, it opens a bi stream and identifies
|
||||
itself with a 4-byte request. The bytes are:
|
||||
|
||||
1. Client type
|
||||
2. Client ID
|
||||
3. Unused
|
||||
4. Unused
|
||||
|
||||
The type is "2" or "4" to identify the client as a P2 or a P4. The IDs are
|
||||
hard-coded as "42" and "43" for now.
|
||||
|
||||
P3 responds with these 4 bytes:
|
||||
|
||||
1. Status code
|
||||
2. Unused
|
||||
3. Unused
|
||||
4. Unused
|
||||
|
||||
The status code is always "20" to mean "OK". If authorization or authentication
|
||||
had failed, it would be something else, and P3 would close the connection.
|
||||
|
||||
## PTTH connection
|
||||
|
||||
When P1 connects to P2's TCP listener, P2 opens a bi stream to P3 and sends
|
||||
this request:
|
||||
|
||||
1. "1" to mean "Open a PTTH connection"
|
||||
2. Server ID, hard-coded as "43" for the only P4 server instance we have
|
||||
3. Unused
|
||||
4. Unused
|
||||
|
||||
The first 4 bytes are interpreted by P3. If everything is okay, P3 responds
|
||||
with:
|
||||
|
||||
1. "20" to mean "OK".
|
||||
2. Unused
|
||||
3. Unused
|
||||
4. Unused
|
||||
|
||||
Then P3 opens a bi stream to P4 and begins relaying from P2 to P4.
|
||||
|
||||
P2 reads that response and sends another request, which will be forwarded
|
||||
to P4:
|
||||
|
||||
1. "1" to mean "Open a PTTH connection"
|
||||
2. Unused (Reserved for choosing port)
|
||||
3. Unused
|
||||
4. Unused
|
||||
|
||||
P4 parses the last 4 bytes. If everything is okay, P4 (via P3) responds to P2 with:
|
||||
|
||||
1. "20" to mean "OK".
|
||||
2. Unused
|
||||
3. Unused
|
||||
4. Unused
|
||||
|
||||
And then P4 begins relaying between P2 and P5.
|
||||
|
||||
P2 reads the 4 byte response from P3 and the 4 byte response from P4.
|
||||
If everything is okay, it completes the relaying from P1 to P5.
|
||||
|
||||
# Plan
|
||||
|
||||
This is a TCP port forwarding system, like SSH has, but better.
|
||||
|
|
|
@ -42,12 +42,26 @@ async fn main () -> anyhow::Result <()> {
|
|||
|
||||
let (mut relay_send, mut relay_recv) = connection.open_bi ().await?;
|
||||
|
||||
let req_buf = [1, 43, 0, 0, 1, 0, 0, 0];
|
||||
// Ask P3 if we can connect to P4
|
||||
|
||||
let req_buf = [1, 43, 0, 0];
|
||||
relay_send.write_all (&req_buf).await?;
|
||||
|
||||
let mut resp_buf = [0; 8];
|
||||
let mut resp_buf = [0; 4];
|
||||
relay_recv.read_exact (&mut resp_buf).await?;
|
||||
|
||||
debug! ("Status code from P3: {}", resp_buf [0]);
|
||||
|
||||
// Ask P4 if we can connect to P5
|
||||
|
||||
let req_buf = [1, 0, 0, 0];
|
||||
relay_send.write_all (&req_buf).await?;
|
||||
|
||||
let mut resp_buf = [0; 4];
|
||||
relay_recv.read_exact (&mut resp_buf).await?;
|
||||
|
||||
debug! ("Status code from P4: {}", resp_buf [0]);
|
||||
|
||||
trace! ("Relaying bytes...");
|
||||
|
||||
let ptth_conn = PtthNewConnection {
|
||||
|
|
|
@ -239,7 +239,7 @@ async fn handle_request_p2_to_p4 (
|
|||
|
||||
// TODO: Auth checks
|
||||
|
||||
let resp_buf = [0, 0, 0, 0];
|
||||
let resp_buf = [20, 0, 0, 0];
|
||||
client_send.write_all (&resp_buf).await?;
|
||||
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue