📝 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 2, restart the relay server P3
|
||||||
- After Step 3, 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
|
# Plan
|
||||||
|
|
||||||
This is a TCP port forwarding system, like SSH has, but better.
|
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 (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?;
|
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?;
|
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...");
|
trace! ("Relaying bytes...");
|
||||||
|
|
||||||
let ptth_conn = PtthNewConnection {
|
let ptth_conn = PtthNewConnection {
|
||||||
|
|
|
@ -239,7 +239,7 @@ async fn handle_request_p2_to_p4 (
|
||||||
|
|
||||||
// TODO: Auth checks
|
// TODO: Auth checks
|
||||||
|
|
||||||
let resp_buf = [0, 0, 0, 0];
|
let resp_buf = [20, 0, 0, 0];
|
||||||
client_send.write_all (&resp_buf).await?;
|
client_send.write_all (&resp_buf).await?;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue