code wiki / (root) / nx_tracker_url.nx

nx_tracker_url.nx source

↩ module page · 125 lines · 5941 B

1// nx_tracker_url.nx -- parse a BitTorrent tracker URL (from nx_magnet's tr= list) into 2// scheme/host/port/path, the input the announce round-trip needs (resolve host -> IP, dial 3// host:port). Pure/deterministic/sovereign. scheme: udp=1 (BEP-15), http=2, https=3, else 0=reject. 4// Default port by scheme when absent (http=80, https=443, udp=6969); default path "/announce". 5// Self-gating (main = baked KAT). license_tier: ORIGINAL 6// 7// module: nishi-core.torrent.tracker_url 8// depends: nishi-core.sys.syscalls 9// capability: TORRENT_TRACKER_URL_PARSE 10import "nx_syscalls.nx" 11const K_MAGIC_6969: i64 = 6969 12const K_MAGIC_1337: i64 = 1337 13 14func tu_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 } 15func tu_wn(fd: i64, v: i64) -> i64 { 16 let t: *u8=sys_mmap(28); var m: i64=v; if m<0 {m=0-m; sys_write(fd,"-" as *u8,1)} 17 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} 18 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 19} 20func tu_len(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 21// buf[a,..) starts with lit? 22func tu_starts(buf: *u8, a: i64, n: i64, lit: *u8) -> i64 { 23 let ll: i64 = tu_len(lit) 24 if a + ll > n { return 0 } 25 var i: i64 = 0 26 while i < ll { if buf[a+i] != lit[i] { return 0 } i = i + 1 } 27 return 1 28} 29// str equals lit? 30func tu_streq(s: *u8, lit: *u8) -> i64 { 31 var i: i64 = 0 32 while s[i] != (0 as u8) { if s[i] != lit[i] { return 0 } i = i + 1 } 33 if lit[i] != (0 as u8) { return 0 } 34 return 1 35} 36 37// parse url -> scheme_id (ret), host (out), port (out), path (out). 0 = unknown/invalid scheme. 38func tu_parse(url: *u8, port_out: *i64, host: *u8, path: *u8) -> i64 { 39 let n: i64 = tu_len(url) 40 var scheme: i64 = 0 41 var rest: i64 = 0 42 if tu_starts(url, 0, n, "udp://" as *u8) == 1 { scheme = 1; rest = 6 } 43 if tu_starts(url, 0, n, "http://" as *u8) == 1 { scheme = 2; rest = 7 } 44 if tu_starts(url, 0, n, "https://" as *u8) == 1 { scheme = 3; rest = 8 } 45 if scheme == 0 { return 0 } 46 // host = [rest, until ':' or '/' or end) 47 var i: i64 = rest 48 var h: i64 = 0 49 while i < n { if url[i] == (58 as u8) { i = n + 1 } else { if url[i] == (47 as u8) { i = n + 2 } else { host[h] = url[i]; h = h + 1; i = i + 1 } } } 50 host[h] = 0 as u8 51 // default port by scheme 52 var port: i64 = K_MAGIC_6969 53 if scheme == 2 { port = 80 } 54 if scheme == 3 { port = 443 } 55 // re-scan from rest+h to find ':' (explicit port) and '/' (path) 56 var p: i64 = rest + h 57 if p < n { if url[p] == (58 as u8) { 58 // explicit port digits 59 var pv: i64 = 0 60 var any: i64 = 0 61 p = p + 1 62 while p < n { if url[p] == (47 as u8) { p = n + 5 } else { let c: i64 = url[p] as i64; if c >= 48 { if c <= 57 { pv = pv*10 + (c-48); any = 1 } } p = p + 1 } } 63 if any == 1 { port = pv } 64 if p > n { p = p - 5 } // landed on '/': restore p to the '/' index 65 } } 66 port_out[0] = port 67 // path = from the FIRST '/' after the authority to end; else "/announce" 68 var sp: i64 = rest 69 var slashpos: i64 = 0 - 1 70 while sp < n { if url[sp] == (47 as u8) { slashpos = sp; sp = n + 100 } else { sp = sp + 1 } } 71 if slashpos >= 0 { 72 var k: i64 = 0 73 var q: i64 = slashpos 74 while q < n { path[k] = url[q]; k = k + 1; q = q + 1 } 75 path[k] = 0 as u8 76 } else { 77 path[0]=47 as u8; path[1]=97 as u8; path[2]=110 as u8; path[3]=110 as u8; path[4]=111 as u8; path[5]=117 as u8; path[6]=110 as u8; path[7]=99 as u8; path[8]=101 as u8; path[9]=0 as u8 // "/announce" 78 } 79 return scheme 80} 81 82func main() -> i64 { 83 let host: *u8 = sys_mmap(512) 84 let path: *u8 = sys_mmap(512) 85 let port: *i64 = sys_mmap(16) as *i64 86 87 // pos1: udp with explicit port + path 88 let s1: i64 = tu_parse("udp://tracker.opentrackr.org:1337/announce" as *u8, port, host, path) 89 var pos1: i64 = 0 90 if s1 == 1 { if port[0] == K_MAGIC_1337 { if tu_streq(host, "tracker.opentrackr.org" as *u8) == 1 { if tu_streq(path, "/announce" as *u8) == 1 { pos1 = 1 } } } } 91 92 // pos2: http with explicit port 93 let s2: i64 = tu_parse("http://torrent.ubuntu.com:6969/announce" as *u8, port, host, path) 94 var pos2: i64 = 0 95 if s2 == 2 { if port[0] == K_MAGIC_6969 { if tu_streq(host, "torrent.ubuntu.com" as *u8) == 1 { pos2 = 1 } } } 96 97 // pos3: https, no explicit port -> default 443; path "/x" 98 let s3: i64 = tu_parse("https://tracker.example/x" as *u8, port, host, path) 99 var pos3: i64 = 0 100 if s3 == 3 { if port[0] == 443 { if tu_streq(host, "tracker.example" as *u8) == 1 { if tu_streq(path, "/x" as *u8) == 1 { pos3 = 1 } } } } 101 102 // pos4: udp, no port, no path -> default 6969 + "/announce" 103 let s4: i64 = tu_parse("udp://t.example" as *u8, port, host, path) 104 var pos4: i64 = 0 105 if s4 == 1 { if port[0] == K_MAGIC_6969 { if tu_streq(host, "t.example" as *u8) == 1 { if tu_streq(path, "/announce" as *u8) == 1 { pos4 = 1 } } } } 106 107 // neg1: unknown scheme 108 var neg1: i64 = 0 109 if tu_parse("ftp://x:1/y" as *u8, port, host, path) == 0 { neg1 = 1 } 110 // neg2: no scheme 111 var neg2: i64 = 0 112 if tu_parse("tracker.example:80/announce" as *u8, port, host, path) == 0 { neg2 = 1 } 113 114 tu_w(1, "TRACKERURL-GATE authored=organ pos1_udp=" as *u8); tu_wn(1, pos1) 115 tu_w(1, " pos2_http=" as *u8); tu_wn(1, pos2) 116 tu_w(1, " pos3_https_defport=" as *u8); tu_wn(1, pos3) 117 tu_w(1, " pos4_noport_nopath=" as *u8); tu_wn(1, pos4) 118 tu_w(1, " neg1_badscheme=" as *u8); tu_wn(1, neg1) 119 tu_w(1, " neg2_noscheme=" as *u8); tu_wn(1, neg2) 120 var ok: i64 = 0 121 if pos1==1 { if pos2==1 { if pos3==1 { if pos4==1 { if neg1==1 { if neg2==1 { ok = 1 } } } } } } 122 if ok == 1 { tu_w(1, " verdict=GREEN\n" as *u8); sys_exit(0); return 0 } 123 tu_w(1, " verdict=RED\n" as *u8); sys_exit(1) 124 return 1 125}