code wiki / (root) / nx_peer_connect_live.nx

nx_peer_connect_live.nx source

↩ module page · 145 lines · 8061 B

1// nx_peer_connect_live.nx -- LIVE BEP-3 handshake with a REAL peer (X-TORRENT-LIVE-001 L3a): 2// announce -> real peers -> TCP connect + handshake each, validate info_hash. BOUNDED CONNECT (no- 3// hang law): blocking connect() to an unreachable peer hangs ~127s, so each attempt runs in a FORK 4// and the PARENT bounds it (WNOHANG poll loop + nx_kill on timeout) -- reliable, no fcntl needed. 5// Composes nx_dns_a + nx_udp_tracker (announce) + nx_peerwire (handshake). Test = Big Buck Bunny. 6// GATE = LIVE: any real peer completes the BEP-3 handshake (info_hash matches). license_tier: ORIGINAL 7// 8// module: nishi-core.torrent.peer_connect_live 9// depends: nishi-core.torrent.dns_a, nishi-core.torrent.udp_tracker, nishi-core.torrent.peerwire 10import "nx_dns_a.nx" 11import "nx_connect.nx" // bounded connect: a raw sys_connect hangs ~127s on a black-holed host 12import "nx_udp_tracker.nx" 13import "nx_peerwire.nx" 14const K_MAGIC_305419896: i64 = 305419896 15const K_MAGIC_1000000000: i64 = 1000000000 16const K_MAGIC_6881: i64 = 6881 17const K_MAGIC_2048: i64 = 2048 18const K_MAGIC_6000: i64 = 6000 19 20func cl_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 } 21func cl_wn(fd: i64, v: i64) -> i64 { 22 let t: *u8=sys_mmap(28); var m: i64=v; if m<0 {m=0-m; sys_write(fd,"-" as *u8,1)} 23 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} 24 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 25} 26func cl_sockaddr(sa: *u8, port: i64, i0: i64, i1: i64, i2: i64, i3: i64) -> i64 { 27 sa[0]=2 as u8; sa[1]=0 as u8 28 sa[2]=((port>>8)&0xff) as u8; sa[3]=(port&0xff) as u8 29 sa[4]=i0 as u8; sa[5]=i1 as u8; sa[6]=i2 as u8; sa[7]=i3 as u8 30 var k: i64=8; while k<16 { sa[k]=0 as u8; k=k+1 } 31 return 0 32} 33func cl_read_n(fd: i64, buf: *u8, n: i64) -> i64 { 34 var got: i64 = 0 35 while got < n { let r: i64 = sys_read(fd, buf + got, n - got); if r <= 0 { return 0 - 1 } got = got + r } 36 return got 37} 38func cl_write_n(fd: i64, buf: *u8, n: i64) -> i64 { 39 var off: i64 = 0 40 while off < n { let w: i64 = sys_write(fd, buf + off, n - off); if w <= 0 { return 0 - 1 } off = off + w } 41 return n 42} 43 44// announce BBB to open.stealth.si:80 -> fill ips[]/ports[]; returns peer count 45func cl_announce(ih: *u8, pid: *u8, ips: *i64, ports: *i64, max: i64) -> i64 { 46 let ip: *u8 = sys_mmap(4) 47 if nx_dns_a_resolve("open.stealth.si" as *u8, ip) != 1 { return 0 - 1 } 48 let fd: i64 = sys_socket(AF_INET, SOCK_DGRAM, 0); if fd < 0 { return 0 - 1 } 49 sys_set_socket_timeout(fd, 5) 50 let dest: *u8 = sys_mmap(16); cl_sockaddr(dest, 80, ip[0] as i64, ip[1] as i64, ip[2] as i64, ip[3] as i64) 51 let txid: i64 = K_MAGIC_305419896 52 let creq: *u8 = sys_mmap(32); nx_udp_build_connect(txid, creq); sys_sendto(fd, creq, 16, 0, dest, 16) 53 let cr: *u8 = sys_mmap(64); let cn: i64 = sys_recvfrom(fd, cr, 64, 0, 0 as *u8, 0 as *i64) 54 let oc: *i64 = sys_mmap(16) as *i64 55 if cn < 16 { sys_close(fd); return 0 - 1 } 56 if nx_udp_parse_connect_resp(cr, cn, txid, oc) != 1 { sys_close(fd); return 0 - 1 } 57 let areq: *u8 = sys_mmap(128); nx_udp_build_announce(oc[0], txid, ih, pid, 0, K_MAGIC_1000000000, 0, 2, 80, K_MAGIC_6881, areq) 58 sys_sendto(fd, areq, 98, 0, dest, 16) 59 let ar: *u8 = sys_mmap(K_MAGIC_2048); let an: i64 = sys_recvfrom(fd, ar, K_MAGIC_2048, 0, 0 as *u8, 0 as *i64) 60 sys_close(fd) 61 if an < 20 { return 0 - 1 } 62 let oiv: *i64 = sys_mmap(16) as *i64; let osd: *i64 = sys_mmap(16) as *i64; let olc: *i64 = sys_mmap(16) as *i64 63 return nx_udp_parse_announce_resp(ar, an, txid, oiv, osd, olc, ips, ports, max) 64} 65 66// CHILD: connect+handshake one peer; on success write [1][20 peer_id] to respath. 67func cl_child(ipv: i64, port: i64, ih: *u8, mypid: *u8, respath: *u8) -> i64 { 68 let fd: i64 = sys_socket(AF_INET, SOCK_STREAM, 0) 69 if fd < 0 { return 0 } 70 sys_set_socket_timeout(fd, 3) 71 let dest: *u8 = sys_mmap(16) 72 cl_sockaddr(dest, port, (ipv>>24)&0xff, (ipv>>16)&0xff, (ipv>>8)&0xff, ipv&0xff) 73 if nx_connect_bounded(fd, dest, 16, NX_CONN_DEFAULT_MS) == 0 { 74 let ch: *u8 = sys_mmap(128); nx_pw_build_handshake(ih, mypid, ch); ch[25] = (ch[25] as i64 | 0x10) as u8 75 if cl_write_n(fd, ch, 68) == 68 { 76 let ph: *u8 = sys_mmap(128) 77 if cl_read_n(fd, ph, 68) == 68 { 78 let gih: *u8 = sys_mmap(20); let gpid: *u8 = sys_mmap(20) 79 if nx_pw_parse_handshake(ph, 68, gih, gpid) == 1 { 80 var eqv: i64 = 1; var i: i64 = 0; while i < 20 { if gih[i] != ih[i] { eqv = 0; i = 20 } else { i = i + 1 } } 81 if eqv == 1 { 82 let rf: i64 = sys_openat_wr(respath, 0x1a4) 83 if rf >= 0 { let ob: *u8 = sys_mmap(32); ob[0]=1 as u8; var k: i64=0; while k<20 { ob[1+k]=gpid[k]; k=k+1 } cl_write_n(rf, ob, 21); sys_close(rf) } 84 } 85 } 86 } 87 } 88 } 89 sys_close(fd) 90 return 0 91} 92 93func main() -> i64 { 94 let ih: *u8 = sys_mmap(20) 95 ih[0]=221 as u8; ih[1]=130 as u8; ih[2]=85 as u8; ih[3]=236 as u8; ih[4]=220 as u8 96 ih[5]=124 as u8; ih[6]=165 as u8; ih[7]=95 as u8; ih[8]=176 as u8; ih[9]=187 as u8 97 ih[10]=248 as u8; ih[11]=19 as u8; ih[12]=35 as u8; ih[13]=216 as u8; ih[14]=112 as u8 98 ih[15]=98 as u8; ih[16]=219 as u8; ih[17]=31 as u8; ih[18]=109 as u8; ih[19]=28 as u8 99 let mypid: *u8 = sys_mmap(20); let ps: *u8 = "-NX0001-000000000000" as *u8; var z: i64 = 0; while z < 20 { mypid[z] = ps[z]; z = z + 1 } 100 101 let ips: *i64 = sys_mmap(8*64) as *i64; let ports: *i64 = sys_mmap(8*64) as *i64 102 let np: i64 = cl_announce(ih, mypid, ips, ports, 64) 103 cl_w(1, "PEERCONNLIVE peers_from_tracker=" as *u8); cl_wn(1, np); cl_w(1, "\n" as *u8) 104 if np < 1 { cl_w(1, "PEERCONNLIVE verdict=RED reason=no-peers\n" as *u8); sys_exit(1); return 1 } 105 106 let respath: *u8 = "/tmp/_nx_peer_hs.bin" as *u8 107 let st: *i64 = sys_mmap(16) as *i64 108 var tries: i64 = np; if tries > 20 { tries = 20 } 109 var ok: i64 = 0 110 var attempted: i64 = 0 111 var i: i64 = 0 112 while i < tries { 113 if ok == 0 { 114 // clear result 115 let cf: i64 = sys_openat_wr(respath, 0x1a4); if cf >= 0 { let zb: *u8 = sys_mmap(4); zb[0]=0 as u8; cl_write_n(cf, zb, 1); sys_close(cf) } 116 attempted = attempted + 1 117 let pid: i64 = sys_fork() 118 if pid == 0 { cl_child(ips[i], ports[i], ih, mypid, respath); sys_exit(0) } 119 // parent: bound to ~6s 120 var el: i64 = 0; var go: i64 = 1 121 while go == 1 { 122 let r: i64 = sys_wait4(pid, st, WNOHANG) 123 if r > 0 { go = 0 } else { if el >= K_MAGIC_6000 { go = 0 } else { sys_sleep_ms(150); el = el + 150 } } 124 } 125 // if still alive, kill + reap 126 if sys_wait4(pid, st, WNOHANG) <= 0 { nx_kill(pid, 9); sys_wait4(pid, st, 0) } 127 // read result 128 let rf: i64 = sys_openat_rd(respath) 129 if rf >= 0 { let rb: *u8 = sys_mmap(32); let rn: i64 = sys_read(rf, rb, 32); sys_close(rf) 130 if rn >= 1 { if (rb[0] as i64) == 1 { 131 ok = 1 132 let a: i64 = ips[i] 133 cl_w(1, "PEERCONNLIVE HANDSHAKE OK peer=" as *u8) 134 cl_wn(1, (a>>24)&0xff); cl_w(1, "." as *u8); cl_wn(1, (a>>16)&0xff); cl_w(1, "." as *u8); cl_wn(1, (a>>8)&0xff); cl_w(1, "." as *u8); cl_wn(1, a&0xff); cl_w(1, ":" as *u8); cl_wn(1, ports[i]) 135 cl_w(1, " peer_id[0..8]=" as *u8); var q: i64 = 1; while q < 9 { cl_wn(1, rb[q] as i64); cl_w(1, " " as *u8); q = q + 1 } cl_w(1, "\n" as *u8) 136 } } 137 } 138 } 139 i = i + 1 140 } 141 cl_w(1, "PEERCONNLIVE attempted=" as *u8); cl_wn(1, attempted) 142 if ok == 1 { cl_w(1, " verdict=GREEN (real BEP-3 handshake with a real peer)\n" as *u8); sys_exit(0); return 0 } 143 cl_w(1, " verdict=RED reason=no-peer-handshook (firewalled/timeout)\n" as *u8); sys_exit(1) 144 return 1 145}