nx_quic_transport_params.nx source
↩ module page · 67 lines · 3081 B
1// nx_quic_transport_params.nx -- RUNG 6a of the sovereign QUIC transport: transport parameters
2// (RFC 9000 sec 18) carried in the TLS quic_transport_parameters extension (0x39). Each is a varint
3// (id, length, value) tuple. THE one that matters for us is max_datagram_frame_size (id 0x20, RFC 9221
4// sec 3): unless BOTH peers advertise it > 0, DATAGRAM frames are forbidden -- i.e. no unreliable
5// FEC'd video. R6a makes that negotiable. No float. license_tier: ORIGINAL
6import "nx_quic_wire.nx"
7
8// RFC 9000 sec 18.2 + RFC 9221 sec 3 ids we use
9const QTP_MAX_IDLE_TIMEOUT: i64 = 0x01
10const QTP_INITIAL_MAX_DATA: i64 = 0x04
11const QTP_INITIAL_SRC_CONN_ID: i64 = 0x0f
12const QTP_MAX_DATAGRAM_FRAME_SIZE: i64 = 0x20 // RFC 9221 -- enables DATAGRAM frames
13
14// encode an integer-valued transport parameter: [id vi][len vi][value vi]. returns bytes written.
15func quic_tp_put_int(out: *u8, id: i64, val: i64) -> i64 {
16 var o: i64 = 0
17 o = o + quic_varint_encode((out as i64 + o) as *u8, id)
18 let tmp: *u8 = sys_mmap(8)
19 let vlen: i64 = quic_varint_encode(tmp, val)
20 o = o + quic_varint_encode((out as i64 + o) as *u8, vlen)
21 var i: i64 = 0; while i < vlen { out[o + i] = tmp[i]; i = i + 1 }
22 return o + vlen
23}
24
25// encode a bytes-valued transport parameter (e.g. connection IDs): [id vi][len vi][bytes].
26func quic_tp_put_bytes(out: *u8, id: i64, val: *u8, val_len: i64) -> i64 {
27 var o: i64 = 0
28 o = o + quic_varint_encode((out as i64 + o) as *u8, id)
29 o = o + quic_varint_encode((out as i64 + o) as *u8, val_len)
30 var i: i64 = 0; while i < val_len { out[o + i] = val[i]; i = i + 1 }
31 return o + val_len
32}
33
34// parse the next TP tuple at buf[off..n). info[0]=id, info[1]=value offset, info[2]=value length.
35// returns the offset of the NEXT tuple, or -1 on malformed.
36func quic_tp_parse_next(buf: *u8, n: i64, off: i64, info: *i64) -> i64 {
37 if off >= n { return 0 - 1 }
38 let vb: *i64 = sys_mmap(8) as *i64
39 var o: i64 = off
40 let a: i64 = quic_varint_decode((buf as i64 + o) as *u8, n - o, vb); if a == 0 { return 0 - 1 } info[0] = vb[0]; o = o + a
41 let b: i64 = quic_varint_decode((buf as i64 + o) as *u8, n - o, vb); if b == 0 { return 0 - 1 } let vlen: i64 = vb[0]; o = o + b
42 if o + vlen > n { return 0 - 1 }
43 info[1] = o; info[2] = vlen
44 return o + vlen
45}
46
47// read an integer-valued TP's value (the value is itself a varint).
48func quic_tp_read_int(buf: *u8, voff: i64, vlen: i64) -> i64 {
49 let vb: *i64 = sys_mmap(8) as *i64
50 quic_varint_decode((buf as i64 + voff) as *u8, vlen, vb)
51 return vb[0]
52}
53
54// scan a TP block for max_datagram_frame_size; returns its value, or 0 if absent (= DATAGRAMs forbidden).
55func quic_tp_datagram_size(buf: *u8, n: i64) -> i64 {
56 let info: *i64 = sys_mmap(8 * 3) as *i64
57 var off: i64 = 0
58 while off < n {
59 let nx: i64 = quic_tp_parse_next(buf, n, off, info)
60 if nx < 0 { return 0 }
61 if info[0] == QTP_MAX_DATAGRAM_FRAME_SIZE { return quic_tp_read_int(buf, info[1], info[2]) }
62 off = nx
63 }
64 return 0
65}
66
67func main() -> i64 { return 0 }