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}