chiark / gitweb /
stest: Decode the slip packets that come via fake netlink
[secnet.git] / stest / common.tcl
index e490ee530e200b62652f18cb7d36171b0a0ca013..566757c75d4cd87b077fe76b8a4879b96545cf11 100644 (file)
@@ -80,10 +80,13 @@ exec cat
        local-key rsa-private(\"$builddir/test-example/$site.key\");
 "
     append cfg $extra($site)
-    append cfg {
+    append cfg "
        log logfile {
-           class "info","notice","warning","error","security","fatal";
+           prefix \"$site\";
+           class \"debug\",\"info\",\"notice\",\"warning\",\"error\",\"security\",\"fatal\";
        };
+    "
+    append cfg {
        system {
        };
        resolver adns {
@@ -107,28 +110,78 @@ proc spawn-secnet {location site} {
     global tmp
     global builddir
     global netlinkfh
+    global env
+    global pidmap
+    global readbuf
     upvar #0 pids($site) pid
+    set readbuf($site) {}
     set cf $tmp/$site.conf
     set ch [open $cf w]
     puts $ch [mkconf $location $site]
     close $ch
     set argl [list $builddir/secnet -dvnc $cf]
-    set pid [fork]
-    if {!$pid} {
-       execl [lindex $argl 0] [lrange $argl 1 end]
+    set divertk SECNET_STEST_DIVERT_$site
+    puts -nonewline "spawn"
+    foreach k [array names env] {
+       switch -glob $k {
+           SECNET_STEST_DIVERT_* -
+           SECNET_TEST_BUILDDIR { }
+           *SECNET* -
+           *PRELOAD* { puts -nonewline " $k=$env($k)" }
+       }
+    }
+    puts " $argl"
+    if {[info exists env($divertk)]} {
+       switch -glob $env($divertk) {
+           i {
+               puts -nonewline "run ^ command, hit return "
+               flush stdout
+               gets stdin
+               set argl {}
+           }
+           0 - "" {
+           }
+           * {
+               set argl [split $env($divertk)]
+           }
+       }
+    }
+    if {[llength $argl]} { 
+       set pid [fork]
+       set pidmap($pid) "secnet $location/$site"
+       if {!$pid} {
+           execl [lindex $argl 0] [lrange $argl 1 end]
+       }
     }
     puts -nonewline $netlinkfh($site.t) [hbytes h2raw c0]
 }
 
 proc netlink-readable {location site} {
     global ok
+    upvar #0 readbuf($site) buf
     upvar #0 netlinkfh($site.r) fh
-    read $fh; # empty the buffer
+    while 1 {
+       set x [read $fh]
+       set h [hbytes raw2h $x]
+       if {![hbytes length $h]} return
+       append buf $h
+       #puts "READABLE $site buf=$buf"
+       while {[regexp {^((?:..)*?)c0(.*)$} $buf dummy now buf]} {
+           #puts "READABLE $site now=$now (buf=$buf)"
+           regsub -all {^((?:..)*?)dbdc} $now {\1c0} now
+           regsub -all {^((?:..)*?)dbdd} $now {\1db} now
+           puts "netlink-got-packet $location $site $now"
+           netlink-got-packet $location $site $now
+       }
+    }
+}
+
+proc netlink-got-packet {location site data} {
+    if {![hbytes length $data]} return 
     switch -exact $site {
        inside {
            puts OK
-           set ok 1; # what a bodge
-           return
+           finish 0
        }
        outside {
            error "inside rx'd!"
@@ -148,7 +201,7 @@ $message
 ----------------------------------------
     "
     }
-    exit 1
+    finish 1
 }
 
 proc sendpkt {} {
@@ -167,13 +220,38 @@ proc sendpkt {} {
 
 set socktmp $tmp/s
 exec mkdir -p -m700 $socktmp
-regsub {^(?!/)} $socktmp {./} socktmp ;# dgram-socket wants ./ or /
+regsub {^(?!/|\./)} $socktmp {./} socktmp ;# dgram-socket wants ./ or /
 
 proc prefix_preload {lib} { prefix_some_path LD_PRELOAD $lib }
 
 set env(UDP_PRELOAD_DIR) $socktmp
 prefix_preload $builddir/stest/udp-preload.so
 
+proc finish {estatus} {
+    puts stderr "FINISHING $estatus"
+    signal default SIGCHLD
+    global pidmap
+    foreach pid [array names pidmap] {
+       kill KILL $pid
+    }
+    exit $estatus
+}
+
+proc reap {} {
+    global pidmap
+    #puts stderr REAPING
+    foreach pid [array names pidmap] {
+       set got [wait -nohang $pid]
+       if {![llength $got]} continue
+       set info $pidmap($pid)
+       unset pidmap($pid)
+       puts stderr "reaped $info: $got"
+       finish 1
+    }
+}
+
+signal -restart trap SIGCHLD { after idle reap }
+
 proc udp-proxy {} {
     global socktmp udpsock
     set u $socktmp/udp