chiark / gitweb /
test: Proxy udp packets
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 12 Oct 2019 19:40:55 +0000 (20:40 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 12 Oct 2019 22:29:26 +0000 (23:29 +0100)
We must change the config to specify localhost addrs explicitly,
because we don't implement any special logic for IN[6]ADDR_ANY.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
test/invoke

index 6678bb6e1ae460c020b2f86b00f3a19daeda9a8e..22554cfbe72b3a4dce97f84d62af20f2a01724d3 100755 (executable)
@@ -3,6 +3,7 @@
 package require Tclx
 
 load chiark_tcl_hbytes-1.so
+load chiark_tcl_dgram-1.so
 
 set netlink(inside) {
     local-address "172.18.232.9";
@@ -66,6 +67,7 @@ exec cat
        append cfg "$delim
            udp {
                 port $port;
+                address \"::1\", \"127.0.0.1\";
                buffer sysbuffer(4096);
            }
        "
@@ -157,7 +159,42 @@ proc sendpkt {} {
 
 file mkdir test/tmp
 set tmp test/tmp
+set socktmp $tmp
+regsub {^(?!/)} $socktmp {./} socktmp ;# dgram-socket wants ./ or /
 
+proc udp-proxy {} {
+    global socktmp udpsock
+    set u $socktmp/udp
+    file delete $u
+    regsub {^(?!/)} $u {./} u
+    set udpsock [dgram-socket create $u]
+    dgram-socket on-receive $udpsock udp-relay
+}
+
+proc udp-relay {data src sock args} {
+    global udpsock socktmp
+    set headerlen [expr {52+1}]
+    set orgsrc $src
+
+    set dst [hbytes range $data 0 $headerlen]
+    regsub {(?:00)*$} $dst {} dst
+    set dst [hbytes h2raw $dst]
+
+    hbytes overwrite data 0 [hbytes zeroes $headerlen]
+    regsub {.*/} $src {} src
+    set srch [hbytes raw2h $src]
+    hbytes append srch 00
+    if {[catch {
+       if {[regexp {[^.,:0-9a-f]} $dst c]} { error "bad dst" }
+       if {[hbytes length $srch] > $headerlen} { error "src addr too long" }
+       hbytes overwrite data 0 $srch
+       dgram-socket transmit $udpsock $data $socktmp/$dst
+    } emsg]} {
+       puts stderr "$orgsrc -> $dst: $emsg"
+    }
+}
+
+udp-proxy
 spawn-secnet inside
 spawn-secnet outside