code wiki / _hdl_build / nx_quic_recovery_test.nx
nx_quic_recovery_test.nx source
↩ module page · 59 lines · 3106 B
1// nx_quic_recovery_test.nx -- RUNG 7 gate: RFC 9002 RTT estimation + NewReno congestion control + loss
2// detection, against hand-computed worked examples. Native, sovereign, integer-only. license_tier: ORIGINAL
3import "nx_quic_recovery.nx"
4import "nx_g_check_lib.nx"
5import "nx_g_puts_lib.nx"
6
7func g_pn(v: i64) -> i64 {
8 if v==0 { sys_write(1,"0" as *u8,1); return 0 }
9 let b: *u8 = sys_mmap(28); var x: i64 = v; if x<0 { sys_write(1,"-" as *u8,1); x=0-x }
10 var d: i64=0; var y: i64=x
11 while y>0 { d=d+1; y=y/10 }
12 var i: i64=d-1; y=x
13 while i>=0 { b[i]=(48+(y%10)) as u8; y=y/10; i=i-1 }
14 sys_write(1,b,d); return 0
15}
16func main() -> i64 {
17 g_puts("nx_quic_recovery gate -- RFC 9002 RTT + NewReno CC + loss detection\n" as *u8)
18 var pass: i64=0; var total: i64=0
19
20 // ---- RTT estimation (RFC 9002 sec 5) ----
21 let rtt: *i64 = sys_mmap(8*4) as *i64
22 quic_rtt_init(rtt)
23 quic_rtt_sample(rtt, 100000, 0)
24 var r1: i64=1
25 if rtt[0]!=100000 { r1=0 }
26 if rtt[1]!=50000 { r1=0 }
27 if rtt[2]!=100000 { r1=0 }
28 pass = pass + g_check("RTT 1st sample: smoothed=100000 rttvar=50000 min=100000" as *u8, r1); total=total+1
29 quic_rtt_sample(rtt, 120000, 5000)
30 var r2: i64=1
31 if rtt[0]!=101875 { r2=0 } // (7*100000 + 115000)/8
32 if rtt[1]!=41250 { r2=0 } // (3*50000 + 15000)/4
33 if rtt[2]!=100000 { r2=0 }
34 pass = pass + g_check("RTT 2nd sample (ack_delay 5ms): smoothed=101875 rttvar=41250" as *u8, r2); total=total+1
35
36 // ---- NewReno congestion control (RFC 9002 sec 7) ----
37 let cc: *i64 = sys_mmap(8*2) as *i64
38 quic_cc_init(cc)
39 pass = pass + g_check("CC init cwnd=12000 (RFC 9002 7.2)" as *u8, (cc[0]==12000) as i64); total=total+1
40 quic_cc_on_ack(cc, 1200)
41 pass = pass + g_check("CC slow-start on_ack(1200) -> cwnd=13200" as *u8, (cc[0]==13200) as i64); total=total+1
42 quic_cc_on_loss(cc)
43 var c3: i64=1; if cc[0]!=6600 { c3=0 } if cc[1]!=6600 { c3=0 }
44 pass = pass + g_check("CC on_loss -> ssthresh=6600 cwnd=6600 (>= 2*max)" as *u8, c3); total=total+1
45 quic_cc_on_ack(cc, 1200) // now cwnd(6600) >= ssthresh(6600) -> congestion avoidance
46 pass = pass + g_check("CC avoidance on_ack(1200) -> cwnd=6818 (+1200*1200/6600=218)" as *u8, (cc[0]==6818) as i64); total=total+1
47
48 // ---- loss detection (RFC 9002 sec 6) ----
49 var l1: i64=1
50 if quic_pkt_lost_by_threshold(5, 8)!=1 { l1=0 } // 8-5=3 >= 3 -> lost
51 if quic_pkt_lost_by_threshold(6, 8)!=0 { l1=0 } // 8-6=2 < 3 -> not
52 pass = pass + g_check("packet-threshold: lost(5,8)=1, lost(6,8)=0 (kPacketThreshold=3)" as *u8, l1); total=total+1
53 pass = pass + g_check("time-threshold loss_delay = 9/8*max(100000,120000) = 135000" as *u8, (quic_loss_delay(100000,120000)==135000) as i64); total=total+1
54
55 g_puts("---- quic_recovery gate: passed " as *u8); g_pn(pass); g_puts(" / " as *u8); g_pn(total); g_puts(" ----\n" as *u8)
56 if pass == total { g_puts("VERDICT: GREEN (RFC 9002 RTT + NewReno CC + loss detection, sovereign, integer-only)\n" as *u8); return 0 }
57 g_puts("VERDICT: RED\n" as *u8)
58 return 1
59}