code wiki / (root) / nx_udp_tracker_announce.nx

nx_udp_tracker_announce.nx source

↩ module page · 117 lines · 6124 B

1// nx_udp_tracker_announce.nx -- BEP-15 UDP tracker ANNOUNCE round-trip (X-TORRENT-LIVE-001 R2b-ii): 2// the live peer-discovery step. Wires nx_udp_tracker's KAT'd build/parse to a real UDP socket 3// (the nx_syscalls-layer plumbing proven by nx_udp_loopback): connect -> conn_id -> announce(info_hash) 4// -> compact peer list. Import nx_udp_tracker ONLY (it pulls nx_syscalls transitively -> sys_* + 5// AF_INET/SOCK_DGRAM + the _ut_* byte helpers; avoids the double-import rc=6 and the wrong-layer 6// nx_udp.nx). GATE = SOVEREIGN LOOPBACK: fork a mock UDP tracker (bind-before-fork; echoes the 7// request txid, replies connect->conn_id, announce->one synthetic compact peer 1.2.3.4:5678); the 8// client announces and must parse that exact peer. No external network; deterministic; no-hang 9// (socket timeouts). license_tier: ORIGINAL 10// 11// module: nishi-core.torrent.udp_tracker_announce 12// depends: nishi-core.torrent.udp_tracker 13import "nx_udp_tracker.nx" 14const K_MAGIC_53219: i64 = 53219 15const K_MAGIC_305419896: i64 = 305419896 16const K_MAGIC_11259375: i64 = 11259375 17const K_MAGIC_1800: i64 = 1800 18const K_MAGIC_5678: i64 = 5678 19const K_MAGIC_1000000: i64 = 1000000 20const K_MAGIC_6881: i64 = 6881 21const K_MAGIC_16909060: i64 = 16909060 22 23func ta_w(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd,s,n); return 0 } 24func ta_wn(fd: i64, v: i64) -> i64 { 25 let t: *u8=sys_mmap(28); var m: i64=v; if m<0 {m=0-m; sys_write(fd,"-" as *u8,1)} 26 var k: i64=0; if m==0 {t[0]=48 as u8;k=1}; while m>0 {t[k]=(48+(m%10)) as u8; m=m/10; k=k+1} 27 let b: *u8=sys_mmap(28); var i: i64=0; while i<k {b[i]=t[k-1-i]; i=i+1}; sys_write(fd,b,k); return 0 28} 29func ta_sockaddr(sa: *u8, port: i64, i0: i64, i1: i64, i2: i64, i3: i64) -> i64 { 30 sa[0]=2 as u8; sa[1]=0 as u8 31 sa[2]=((port>>8)&0xff) as u8; sa[3]=(port&0xff) as u8 32 sa[4]=i0 as u8; sa[5]=i1 as u8; sa[6]=i2 as u8; sa[7]=i3 as u8 33 var k: i64=8; while k<16 { sa[k]=0 as u8; k=k+1 } 34 return 0 35} 36 37func main() -> i64 { 38 let PORT: i64 = K_MAGIC_53219 39 let txid: i64 = K_MAGIC_305419896 // 0x12345678 40 let sa: *u8 = sys_mmap(16); ta_sockaddr(sa, PORT, 127, 0, 0, 1) 41 let sfd: i64 = sys_socket(AF_INET, SOCK_DGRAM, 0) 42 var bound: i64 = 0 43 if sfd >= 0 { sys_set_socket_timeout(sfd, 2); if sys_bind(sfd, sa, 16) >= 0 { bound = 1 } } 44 if bound == 0 { ta_w(1, "TRACKER-RT-GATE authored=organ bound=0 verdict=RED\n" as *u8); sys_exit(1); return 1 } 45 46 let pid: i64 = sys_fork() 47 if pid == 0 { 48 // MOCK UDP TRACKER (inherited bound sfd): echo txid, reply connect then announce. 49 let req: *u8 = sys_mmap(256); let resp: *u8 = sys_mmap(256) 50 let src: *u8 = sys_mmap(16); let slen: *i64 = sys_mmap(16) as *i64 51 slen[0] = 16 52 let n1: i64 = sys_recvfrom(sfd, req, 256, 0, src, slen) 53 if n1 >= 16 { 54 let rtx1: i64 = _ut_get_u32(req, 12) 55 _ut_put_u32(resp, 0, 0) // action=connect 56 _ut_put_u32(resp, 4, rtx1) 57 _ut_put_u64(resp, 8, K_MAGIC_11259375) // conn_id = 0xABCDEF 58 sys_sendto(sfd, resp, 16, 0, src, slen[0]) 59 } 60 slen[0] = 16 61 let n2: i64 = sys_recvfrom(sfd, req, 256, 0, src, slen) 62 if n2 >= 16 { 63 let rtx2: i64 = _ut_get_u32(req, 12) 64 _ut_put_u32(resp, 0, 1) // action=announce 65 _ut_put_u32(resp, 4, rtx2) 66 _ut_put_u32(resp, 8, K_MAGIC_1800) // interval 67 _ut_put_u32(resp, 12, 5) // leechers 68 _ut_put_u32(resp, 16, 10) // seeders 69 resp[20]=1 as u8; resp[21]=2 as u8; resp[22]=3 as u8; resp[23]=4 as u8 // peer 1.2.3.4 70 resp[24]=((K_MAGIC_5678>>8)&0xff) as u8; resp[25]=(K_MAGIC_5678&0xff) as u8 // port K_MAGIC_5678 BE 71 sys_sendto(sfd, resp, 26, 0, src, slen[0]) 72 } 73 sys_close(sfd) 74 sys_exit(0) 75 } 76 77 // CLIENT 78 let cfd: i64 = sys_socket(AF_INET, SOCK_DGRAM, 0) 79 sys_set_socket_timeout(cfd, 2) 80 let dest: *u8 = sys_mmap(16); ta_sockaddr(dest, PORT, 127, 0, 0, 1) 81 82 // connect 83 let creq: *u8 = sys_mmap(64); nx_udp_build_connect(txid, creq) 84 sys_sendto(cfd, creq, 16, 0, dest, 16) 85 let cresp: *u8 = sys_mmap(64) 86 let cn: i64 = sys_recvfrom(cfd, cresp, 64, 0, 0 as *u8, 0 as *i64) 87 let out_conn: *i64 = sys_mmap(16) as *i64 88 var conn_ok: i64 = 0 89 if cn >= 16 { if nx_udp_parse_connect_resp(cresp, cn, txid, out_conn) == 1 { conn_ok = 1 } } 90 91 // announce (with the conn_id we just got) 92 let info_hash: *u8 = sys_mmap(20); var z: i64 = 0; while z < 20 { info_hash[z] = (z+1) as u8; z = z + 1 } 93 let peer_id: *u8 = sys_mmap(20); z = 0; while z < 20 { peer_id[z] = (65+z) as u8; z = z + 1 } 94 let areq: *u8 = sys_mmap(128) 95 nx_udp_build_announce(out_conn[0], txid, info_hash, peer_id, 0, K_MAGIC_1000000, 0, 2, 10, K_MAGIC_6881, areq) 96 sys_sendto(cfd, areq, 98, 0, dest, 16) 97 let aresp: *u8 = sys_mmap(256) 98 let an: i64 = sys_recvfrom(cfd, aresp, 256, 0, 0 as *u8, 0 as *i64) 99 let oiv: *i64 = sys_mmap(16) as *i64; let osd: *i64 = sys_mmap(16) as *i64; let olc: *i64 = sys_mmap(16) as *i64 100 let ips: *i64 = sys_mmap(8*16) as *i64; let ports: *i64 = sys_mmap(8*16) as *i64 101 var npeers: i64 = 0 102 if an >= 20 { npeers = nx_udp_parse_announce_resp(aresp, an, txid, oiv, osd, olc, ips, ports, 16) } 103 var ip_ok: i64 = 0; var port_ok: i64 = 0 104 if npeers >= 1 { if ips[0] == K_MAGIC_16909060 { ip_ok = 1 } if ports[0] == K_MAGIC_5678 { port_ok = 1 } } 105 106 let st: *i64 = sys_mmap(16) as *i64; sys_wait4(pid, st, 0); sys_close(cfd) 107 108 ta_w(1, "TRACKER-RT-GATE authored=organ conn_ok=" as *u8); ta_wn(1, conn_ok) 109 ta_w(1, " peers=" as *u8); ta_wn(1, npeers) 110 ta_w(1, " peer0_ip_ok=" as *u8); ta_wn(1, ip_ok) 111 ta_w(1, " peer0_port_ok=" as *u8); ta_wn(1, port_ok) 112 var allok: i64 = 0 113 if conn_ok == 1 { if npeers >= 1 { if ip_ok == 1 { if port_ok == 1 { allok = 1 } } } } 114 if allok == 1 { ta_w(1, " verdict=GREEN\n" as *u8); sys_exit(0); return 0 } 115 ta_w(1, " verdict=RED\n" as *u8); sys_exit(1) 116 return 1 117}