[or-cvs] r20179: {torvm} Launch Vidalia in a thread and respawn when exited abnormall (in torvm/trunk: . build/kamikaze/patches build/win32 build/win32/files build/win32/src/torvm-w32)

coderman at seul.org coderman at seul.org
Tue Jul 28 06:01:31 UTC 2009


Author: coderman
Date: 2009-07-28 02:01:31 -0400 (Tue, 28 Jul 2009)
New Revision: 20179

Modified:
   torvm/trunk/HACKING
   torvm/trunk/Makefile
   torvm/trunk/TODO
   torvm/trunk/build/kamikaze/patches/001-kamikaze-tor-package.patch
   torvm/trunk/build/win32/Makefile
   torvm/trunk/build/win32/files/defpolipo.conf
   torvm/trunk/build/win32/src/torvm-w32/creds.c
   torvm/trunk/build/win32/src/torvm-w32/torvm.c
   torvm/trunk/build/win32/src/torvm-w32/torvm.h
Log:
Launch Vidalia in a thread and respawn when exited abnormally. Misc build and config cleanup.

Modified: torvm/trunk/HACKING
===================================================================
--- torvm/trunk/HACKING	2009-07-28 04:11:23 UTC (rev 20178)
+++ torvm/trunk/HACKING	2009-07-28 06:01:31 UTC (rev 20179)
@@ -38,7 +38,7 @@
 
 Some files and paths of interest:
 
-./build/kamikaze/x86-uclibc-vm/bin/openwrt-x86-vmlinuz
+./build/kamikaze/x86-vm/bin/openwrt-x86-vmlinuz
 > this is the Linux kernel and initramfs used in the VM.
 
 ./build/win32/w32build.iso

Modified: torvm/trunk/Makefile
===================================================================
--- torvm/trunk/Makefile	2009-07-28 04:11:23 UTC (rev 20178)
+++ torvm/trunk/Makefile	2009-07-28 06:01:31 UTC (rev 20179)
@@ -24,7 +24,7 @@
 	BGROUP=users
 endif
 ifeq (,$(TGTNAME))
-	TGTNAME=x86-uclibc-vm
+	TGTNAME=x86-vm
 endif
 
 # default locations for download directories

Modified: torvm/trunk/TODO
===================================================================
--- torvm/trunk/TODO	2009-07-28 04:11:23 UTC (rev 20178)
+++ torvm/trunk/TODO	2009-07-28 06:01:31 UTC (rev 20179)
@@ -48,10 +48,6 @@
      and route metric must be used to distinguish properly.
    - Make addresses, devices, and other configuration dynamic for Tor
      VM kernel and Vidalia controller.
-   ? Keep a host or guid identifier with the saved network state files
-     to ensure that an unclean exit on one host does not accidentally
-     hose the settings of another installation. (expect to use hostname
-     and account name when considering saved state for load via netsh).
    - Implement command line parameter parsing for the configurable
      parameters implemented in the afore mentioned tasks.
    - Pass ARP parameters to VM kernel for faster IP setup.

Modified: torvm/trunk/build/kamikaze/patches/001-kamikaze-tor-package.patch
===================================================================
--- torvm/trunk/build/kamikaze/patches/001-kamikaze-tor-package.patch	2009-07-28 04:11:23 UTC (rev 20178)
+++ torvm/trunk/build/kamikaze/patches/001-kamikaze-tor-package.patch	2009-07-28 06:01:31 UTC (rev 20179)
@@ -314,7 +314,7 @@
 +
 diff -Naur a/package/tor/files/tor.init b/package/tor/files/tor.init
 --- a/package/tor/files/tor.init	1970-01-01 00:00:00.000000000 +0000
-+++ b/package/tor/files/tor.init	2009-06-24 23:46:11.702526906 +0000
++++ b/package/tor/files/tor.init	2009-07-24 12:19:57.898944904 +0000
 @@ -0,0 +1,147 @@
 +#!/bin/sh 
 +# make sure we check the system bin dirs
@@ -333,6 +333,7 @@
 +RUN_USER=$BIN
 +RUN_GROUP=$BIN
 +TOR_INTF=eth0
++TOR_SOCKSPORT=9050
 +
 +source /sbin/vmrouter.sh
 +
@@ -343,16 +344,16 @@
 +MYIP=$(ifconfig $TOR_INTF | grep 'inet addr' | sed 's/.*inet addr://' | sed 's/ .*//')
 +ARGS=`cat /proc/cmdline`
 +ARGS="_ $ARGS _"
-+echo $ARGS | grep ' CTLREADY=' >/dev/null 2>&1 
-+if [ $? -eq 0 ]; then 
-+  CTLREADY=$(echo $ARGS | sed 's/.* CTLREADY=//' | sed 's/ .*//') 
-+fi 
 +echo $ARGS | grep ' CTLSOCK=' >/dev/null 2>&1  
 +if [ $? -eq 0 ]; then 
 +  CTLADDR=$(echo $ARGS | sed 's/.* CTLSOCK=//' | sed 's/ .*//')
 +  CTLIP=$(echo $CTLADDR | sed 's/:.*//')
 +  CTLPORT=$(echo $CTLADDR | sed 's/.*://')
 +fi
++echo $ARGS | grep ' SOCKSPORT=' >/dev/null 2>&1  
++if [ $? -eq 0 ]; then 
++  TOR_SOCKSPORT=$(echo $ARGS | sed 's/.* SOCKSPORT=//' | sed 's/ .*//')
++fi
 +
 +if [ "$1" = "start" ]; then
 +	[ -f $DEFAULT ] && . $DEFAULT
@@ -385,16 +386,16 @@
 +	  cat $CONF_F | grep -v ControlListenAddress | grep -v ControlPort | grep -v SocksListenAddress | grep -v SocksPort > $TMP_F; \
 +	  echo "ControlListenAddress ${CTLADDR}" >> $TMP_F; \
 +	  echo "ControlPort ${CTLPORT}" >> $TMP_F; \
-+	  echo "SocksListenAddress ${CTLIP}:9050" >> $TMP_F; \
-+	  echo "SocksPort 9050" >> $TMP_F; \
++	  echo "SocksListenAddress ${CTLIP}:${TOR_SOCKSPORT}" >> $TMP_F; \
++	  echo "SocksPort $TOR_SOCKSPORT" >> $TMP_F; \
 +	  mv -f $TMP_F $CONF_F; \
 +	fi; \
 +	chown $RUN_USER:$RUN_GROUP $CONF_F ; \
 +        vmr_fwdadd $TOR_INT
 +        vmr_opentcp $TOR_INTF $MYIP $CTLPORT
-+        vmr_opentcp $TOR_INTF $MYIP 9050
 +        vmr_opentcp $TOR_INTF $MYIP $TOR_TRANSPORT
 +        vmr_openudp $TOR_INTF $MYIP $TOR_DNSPORT
++	vmr_closetcp $TOR_INTF $MYIP $TOR_SOCKSPORT
 +	if [ "$FOLLOWTOR" = "1" ]; then \
 +	  nohup /etc/init.d/tor dofollow >/dev/null 2>&1 & \
 +        else \
@@ -402,10 +403,9 @@
 +	fi; 
 +
 +elif [ "$1" = "stop" ]; then
-+	vmr_undirtcp $TOR_INTF $MYIP $CTLREADY $CTLPORT
 +	vmr_closeudp $TOR_INTF $MYIP $TOR_DNSPORT
 +	vmr_closetcp $TOR_INTF $MYIP $TOR_TRANSPORT
-+	vmr_closetcp $TOR_INTF $MYIP 9050
++	vmr_closetcp $TOR_INTF $MYIP $TOR_SOCKSPORT
 +	vmr_closetcp $TOR_INTF $MYIP $CTLPORT
 +        vmr_fwddel $TOR_INT
 +	killall tor
@@ -430,7 +430,7 @@
 +	while [ "$waiting" -eq "1" ]; do
 +	  grep 'Bootstrapped 100' $LOG_F >/dev/null 2>&1
 +	  if [ "$?" -eq "0" ]; then
-+	    vmr_redirtcp $TOR_INTF $MYIP $CTLREADY $CTLPORT
++            vmr_opentcp $TOR_INTF $MYIP $TOR_SOCKSPORT
 +	    waiting=0
 +          fi
 +	done
@@ -453,7 +453,7 @@
 +	  else
 +	  	echo "Tor is fully connected into the Tor network."
 +	  	echo "Transparent proxy traffic:"
-+	  	iptables -n --verbose -t nat --list $cli_prenat_tb | sed 's/opt .*destination.*/destination/'|sed 's/    0.0.0.0.0           //'|sed "s/\-\- .*${MYIP}   //"|grep -v $cli_prenat_tb|grep -v $CTLREADY|grep -v $CTLPORT
++	  	iptables -n --verbose -t nat --list $cli_prenat_tbl| sed 's/opt .*destination.*/destination/'|sed 's/    0.0.0.0.0           //'|sed "s/\-\- .*${MYIP}   //"|grep -v $cli_prenat_tbl|grep -v $CTLPORT
 +	  fi
 +	  sleep 4
 +	done  
@@ -751,8 +751,8 @@
 +fi
 diff -Naur a/package/tor/files/vmrouter.sh b/package/tor/files/vmrouter.sh
 --- a/package/tor/files/vmrouter.sh	1970-01-01 00:00:00.000000000 +0000
-+++ b/package/tor/files/vmrouter.sh	2009-07-18 11:24:47.211822577 +0000
-@@ -0,0 +1,149 @@
++++ b/package/tor/files/vmrouter.sh	2009-07-24 12:17:59.397042898 +0000
+@@ -0,0 +1,153 @@
 +#!/bin/bash
 +# Utility script for Tor VM routing
 +# Source or run directly.
@@ -865,19 +865,23 @@
 +}
 +
 +vmr_opentcp() {
++  iptables -t filter -D $host_filt_tbl -i "$1" -d "$2" -p tcp --dport "$3" -j DROP
 +  iptables -t filter -I $host_filt_tbl -i "$1" -d "$2" -p tcp --dport "$3" -j ACCEPT
 +}
 +
 +vmr_openudp() {
++  iptables -t filter -D $host_filt_tbl -i "$1" -d "$2" -p udp --dport "$3" -j DROP
 +  iptables -t filter -I $host_filt_tbl -i "$1" -d "$2" -p udp --dport "$3" -j ACCEPT
 +}
 +
 +vmr_closetcp() {
 +  iptables -t filter -D $host_filt_tbl -i "$1" -d "$2" -p tcp --dport "$3" -j ACCEPT
++  iptables -t filter -I $host_filt_tbl -i "$1" -d "$2" -p tcp --dport "$3" -j DROP
 +}
 +
 +vmr_closeudp() {
 +  iptables -t filter -D $host_filt_tbl -i "$1" -d "$2" -p udp --dport "$3" -j ACCEPT
++  iptables -t filter -I $host_filt_tbl -i "$1" -d "$2" -p udp --dport "$3" -j DROP
 +}
 +
 +vmr_redirtcp() {

Modified: torvm/trunk/build/win32/Makefile
===================================================================
--- torvm/trunk/build/win32/Makefile	2009-07-28 04:11:23 UTC (rev 20178)
+++ torvm/trunk/build/win32/Makefile	2009-07-28 06:01:31 UTC (rev 20179)
@@ -305,8 +305,8 @@
 	if [ -e ../kamikaze/kernel-license-docs.tgz ]; then \
 		cp ../kamikaze/kernel-license-docs.tgz $(ISODIR)/add/; \
 	fi; \
-	if [ -e ../kamikaze/x86-uclibc-vm/bin/openwrt-x86-vmlinuz ]; then \
-		cp ../kamikaze/x86-uclibc-vm/bin/openwrt-x86-vmlinuz $(ISODIR)/add/vmlinuz; \
+	if [ -e ../kamikaze/x86-vm/bin/openwrt-x86-vmlinuz ]; then \
+		cp ../kamikaze/x86-vm/bin/openwrt-x86-vmlinuz $(ISODIR)/add/vmlinuz; \
 	fi; \
 	if [ -e $(BUILD_SCP_IDF) ]; then \
 		mkdir $(ISODIR)/ssh; \

Modified: torvm/trunk/build/win32/files/defpolipo.conf
===================================================================
--- torvm/trunk/build/win32/files/defpolipo.conf	2009-07-28 04:11:23 UTC (rev 20178)
+++ torvm/trunk/build/win32/files/defpolipo.conf	2009-07-28 06:01:31 UTC (rev 20179)
@@ -3,27 +3,21 @@
 allowedClients = 127.0.0.1
 allowedPorts = 1-65535
 proxyName = "localhost"
-# cacheIsShared = false
-### Memory
 chunkHighMark = 33554432
-# disable the on-disk cache:
-diskCacheRoot = ""
-# disable the local web server:
-localDocumentRoot = ""
-# disableIndexing = false
-# disableServersList = false
 disableLocalInterface = true
 disableConfiguration = true
-dnsQueryIPv6 = no
 dnsUseGethostbyname = no
 disableVia = true
 censoredHeaders = from,accept-language,x-pad,link
 censorReferer = maybe
-# censoredHeaders = set-cookie, cookie, cookie2, from, accept-language
-# censorReferer = true
-# should age match circuit dirtiness?
 maxConnectionAge = 10m
 maxConnectionRequests = 120
 serverMaxSlots = 16
 serverSlots = 4
 tunnelAllowedPorts = 1-65535
+#
+# NOTE: the following are compiled out of the Polipo binary used
+# and do not need to be set.
+# diskCacheRoot = ""
+# localDocumentRoot = ""
+# dnsQueryIPv6 = no

Modified: torvm/trunk/build/win32/src/torvm-w32/creds.c
===================================================================
--- torvm/trunk/build/win32/src/torvm-w32/creds.c	2009-07-28 04:11:23 UTC (rev 20178)
+++ torvm/trunk/build/win32/src/torvm-w32/creds.c	2009-07-28 06:01:31 UTC (rev 20179)
@@ -963,7 +963,7 @@
   cmd = "echo Waiting for Tor VM to exit...\r\n";
   WriteFile(fh, cmd, strlen(cmd),  &numwritten, NULL);
   cmd = malloc(CMDMAX);
-  snprintf(cmd, CMDMAX -1, "\"%s\" --follow --ctlip %s --ctlport %s\r\n", binpath, ctlip, ctlport);
+  snprintf(cmd, CMDMAX -1, "\"%s\" --followip %s --followport %s\r\n", binpath, ctlip, ctlport);
   WriteFile(fh, cmd, strlen(cmd),  &numwritten, NULL);
   CloseHandle(fh);
   free(relpath);

Modified: torvm/trunk/build/win32/src/torvm-w32/torvm.c
===================================================================
--- torvm/trunk/build/win32/src/torvm-w32/torvm.c	2009-07-28 04:11:23 UTC (rev 20178)
+++ torvm/trunk/build/win32/src/torvm-w32/torvm.c	2009-07-28 06:01:31 UTC (rev 20179)
@@ -19,25 +19,6 @@
 #define QEMU_DEF_MEM   32
 #define CAP_MTU        1480
 
-struct s_rconnelem {
-  BOOL    isactive;
-  BOOL    isdefgw;
-  BOOL    isdhcp;
-  BOOL    istortap;
-  LPTSTR  name;
-  LPTSTR  guid;
-  LPTSTR  macaddr;
-  LPTSTR  ipaddr;
-  LPTSTR  netmask;
-  LPTSTR  gateway;
-  LPTSTR  gwmacaddr;
-  LPTSTR  dhcpsvr;
-  LPTSTR  svrmacaddr;
-  LPTSTR  dhcpname;
-  LPTSTR  driver;
-  struct s_rconnelem * next;
-};
-
 /* logging:
  *   lerror to stderr and log file(s) if set
  *   linfo  to log and debug file
@@ -1531,7 +1512,7 @@
   else {
     if (brif->isdhcp == FALSE) {
       snprintf (*cmdline, cmdlen -1,
-                "%s %s%s %s IP=%s MASK=%s GW=%s MAC=%s MTU=%d PRIVIP=%s CTLSOCK=%s:9051 CTLREADY=9052 HASHPW=%s %s%s%s%s",
+                "%s %s%s %s IP=%s MASK=%s GW=%s MAC=%s MTU=%d PRIVIP=%s CTLSOCK=%s:9051 HASHPW=%s %s%s%s%s",
                 usedebug ? dbgcmds : basecmds,
                 myhostname ? "USEHOSTNAME=" : "",
                 myhostname ? myhostname : "",
@@ -1555,7 +1536,7 @@
         myhostname = brif->dhcpname;
 
       snprintf (*cmdline, cmdlen -1,
-                "%s %s%s %s IP=%s MASK=%s GW=%s MAC=%s MTU=%d PRIVIP=%s ISDHCP DHCPSVR=%s DHCPNAME=%s CTLSOCK=%s:9051 CTLREADY=9052 HASHPW=%s %s%s%s%s %s%s%s%s",
+                "%s %s%s %s IP=%s MASK=%s GW=%s MAC=%s MTU=%d PRIVIP=%s ISDHCP DHCPSVR=%s DHCPNAME=%s CTLSOCK=%s:9051 HASHPW=%s %s%s%s%s %s%s%s%s",
                 usedebug ? dbgcmds : basecmds,
                 myhostname ? "USEHOSTNAME=" : "",
                 myhostname ? myhostname : "",
@@ -1625,15 +1606,16 @@
   return TRUE;
 }
 
-BOOL runvidalia (BOOL  indebug)
+DWORD WINAPI runvidalia (LPVOID arg)
 {
-  BOOL  retval = FALSE;
+  t_ctx *ctx = (t_ctx *)arg;
   PROCESS_INFORMATION pi;
   STARTUPINFO si;
   SECURITY_ATTRIBUTES sattr;
   TCHAR * cmd = NULL;
   LPTSTR exe = NULL;
   LPTSTR dir = NULL;
+  DWORD exitcode;
   LPTSTR vcfgtmp = NULL;
   LPTSTR vcfgdest = NULL;
   DWORD opts = CREATE_NEW_PROCESS_GROUP;
@@ -1678,25 +1660,44 @@
             "\"%s\" -tor-address %s %s",
             exe,
             TOR_TAP_VMIP,
-            indebug ? " -loglevel debug -logfile debuglog.txt" :
-                      " -loglevel info -logfile infolog.txt");
-  ldebug ("Launching Vidalia in dir: %s , with cmd: %s", dir, cmd);
-  if( !CreateProcess(NULL,
-                     cmd,
-                     NULL,   // process handle no inherit
-                     NULL,   // thread handle no inherit
-                     TRUE,   
-                     opts,
-                     NULL,   // environment block
-                     dir,
-                     &si,
-                     &pi) ) {
-    lerror ("Failed to launch process.  Error code: %d", GetLastError());
-    goto cleanup;
+            ctx->indebug ? " -loglevel debug -logfile debuglog.txt" :
+                           " -loglevel info -logfile infolog.txt");
+
+  while (ctx->running) {
+    ldebug ("Launching Vidalia in dir: %s , with cmd: %s", dir, cmd);
+    if( !CreateProcess(NULL,
+                       cmd,
+                       NULL,   // process handle no inherit
+                       NULL,   // thread handle no inherit
+                       TRUE,   
+                       opts,
+                       NULL,   // environment block
+                       dir,
+                       &si,
+                       &pi) ) {
+      lerror ("Failed to launch process.  Error code: %d", GetLastError());
+      goto cleanup;
+    }
+    while ( GetExitCodeProcess(pi.hProcess, &exitcode)
+          && (exitcode == STILL_ACTIVE)
+          && (ctx->running) ) {
+      Sleep (500);
+    }
+    if (exitcode == STILL_ACTIVE) {
+      ldebug ("Shutdown signaled, stopping Vidalia.");
+      TerminateProcess(pi.hProcess, 0);
+    }
+    else {
+      if (exitcode) {
+        ldebug ("Vidalia exited unexpectedly with code %d, respawning.", exitcode);
+      }
+      else {
+        /* Vidalia exited normally. The VM should be in shutdown so don't respawn. */
+        ldebug ("Vidalia exit requested. Exiting thread.");
+        goto cleanup;
+      }
+    }
   }
-  else {
-    retval = TRUE;
-  }
 
  cleanup:
   if(cmd)
@@ -1710,18 +1711,20 @@
   if(vcfgdest)
     free(vcfgdest);
 
-  return retval;
+  return 0;
 }
 
 DWORD WINAPI runpolipo (LPVOID arg)
 {
   DWORD  retval = 0;
+  t_ctx *ctx = (t_ctx *)arg;
   PROCESS_INFORMATION pi;
   STARTUPINFO si;
   SECURITY_ATTRIBUTES sattr;
   TCHAR * cmd = NULL;
   LPTSTR exe = NULL;
   LPTSTR dir = NULL;
+  DWORD exitcode;
   LPTSTR pcfgtmp = NULL;
   LPTSTR pcfgdest = NULL;
   LPTSTR pcfgdestsave = NULL;
@@ -1731,7 +1734,7 @@
   si.cb = sizeof(si);
   ZeroMemory( &pi, sizeof(pi) );
   
-  if (!buildsyspath(SYSDIR_LCLPROGRAMS, "Polipo", &dir)) {
+  if (!buildsyspath(SYSDIR_LCLPROGRAMS, "Vidalia", &dir)) {
     lerror ("Unable to build path for Vidalia programs dir."); 
     goto cleanup;
   } 
@@ -1760,23 +1763,35 @@
             "\"%s\" -c \"%s\"",
             exe,
             pcfgdest);
-  ldebug ("Launching Polipo in dir: %s , with cmd: %s", dir, cmd);
-  if( !CreateProcess(NULL,
-                     cmd,
-                     NULL,   // process handle no inherit
-                     NULL,   // thread handle no inherit
-                     TRUE,   
-                     opts,
-                     NULL,   // environment block
-                     dir,
-                     &si,
-                     &pi) ) {
-    lerror ("Failed to launch process.  Error code: %d", GetLastError());
-    goto cleanup;
+
+  while (ctx->running) {
+    ldebug ("Launching Polipo in dir: %s , with cmd: %s", dir, cmd);
+    if( !CreateProcess(NULL,
+                       cmd,
+                       NULL,   // process handle no inherit
+                       NULL,   // thread handle no inherit
+                       TRUE,   
+                       opts,
+                       NULL,   // environment block
+                       dir,
+                       &si,
+                       &pi) ) {
+      lerror ("Failed to launch process.  Error code: %d", GetLastError());
+      goto cleanup;
+    }
+    while ( GetExitCodeProcess(pi.hProcess, &exitcode)
+          && (exitcode == STILL_ACTIVE)
+          && (ctx->running) ) {
+      Sleep (500);
+    }
+    if (exitcode == STILL_ACTIVE) {
+      ldebug ("Shutdown signaled, stopping Polipo.");
+      TerminateProcess(pi.hProcess, 0);
+    }
+    else {
+      ldebug ("Polipo exited unexpectedly with code %d, respawning.", exitcode);
+    }
   }
-  else {
-    retval = 1;
-  }
 
  cleanup:
   if(cmd)
@@ -2000,8 +2015,8 @@
 }
 
 BOOL setupuser (LPTSTR username,
-                LPTSTR ctlip,
-                LPTSTR ctlport)
+                LPTSTR followip,
+                LPTSTR followport)
 {
   BOOL retval = FALSE;
   userinfo * ui;
@@ -2015,7 +2030,7 @@
       ldebug ("Failed to initialize user profile data in setupuser.");
     }
     else {
-      if (!setupruserfollow(ui, ctlip, ctlport)) {
+      if (!setupruserfollow(ui, followip, followport)) {
         ldebug ("Failed to setup Tor follow startup script for user %s.", username);
       }
       else {
@@ -2162,9 +2177,8 @@
   { "vmnop" , no_argument , NULL, 'X' },
   { "noinit" , no_argument , NULL, 'Z' },
   { "help" , no_argument , NULL, 'h' },
-  { "follow" , no_argument , NULL, 'F' },
-  { "ctlip" , required_argument, NULL, 'I' },
-  { "ctlport" , required_argument, NULL, 'P' },
+  { "followip" , required_argument, NULL, 'I' },
+  { "followport" , required_argument, NULL, 'P' },
   {0}
 };
 
@@ -2188,29 +2202,28 @@
 
 int main(int argc, char **argv)
 {
+  t_ctx *ctx = NULL;
   const char *cmd;
   int numintf;
   struct s_rconnelem *connlist = NULL;
   struct s_rconnelem *ce = NULL;
   struct s_rconnelem *tapconn = NULL;
-  BOOL vmaccel = FALSE;
-  BOOL bundle = FALSE;
-  BOOL follow = FALSE;
   BOOL clean = FALSE;
-  BOOL indebug = FALSE;
-  BOOL vmnop = FALSE;
-  BOOL noinit = FALSE;
   BOOL foundit = FALSE;
   char *cmdline = NULL;
+  LPTSTR fname = NULL;
   LPTSTR logfile = NULL;
-  LPTSTR ctliparg = NULL;
-  LPTSTR ctlportarg = NULL;
+  LPTSTR followiparg = NULL;
+  LPTSTR followportarg = NULL;
   LPTSTR polipodir;
   DWORD taptimeout = 60; /* the tap device can't be configured until the VM connects it */
   int c, optidx = 0;
 
   setupthrctx();
 
+  ctx = malloc(sizeof(t_ctx));
+  memset(ctx, 0, sizeof(t_ctx));
+
   while (1) {
     c = getopt_long(argc, argv, "avubshrcXZ", torvm_options, &optidx);
     if (c == -1)
@@ -2218,74 +2231,56 @@
 
     switch (c) {
         case 'a':
-          ldebug ("Set option %s.", torvm_options[optidx].name);
-          vmaccel = TRUE;
+          ctx->vmaccel = TRUE;
           break;
 
         case 'v':
-          ldebug ("Set option %s.", torvm_options[optidx].name);
-          indebug = TRUE;
+          ctx->indebug = TRUE;
           break;
 
         case 'b':
-          ldebug ("Set option %s.", torvm_options[optidx].name);
-          bundle = TRUE;
+          ctx->bundle = TRUE;
           break;
 
         case 's':
-          ldebug ("Set option %s.", torvm_options[optidx].name);
           break;
 
         case 'r':
-          ldebug ("Set option %s.", torvm_options[optidx].name);
-          LPTSTR fname = NULL;
           if (!buildfpath(PATH_RELATIVE, VMDIR_STATE, NULL, TOR_HDD_FILE, &fname)) {
             lerror ("Unable to build path for dest %s", TOR_HDD_FILE);
           }
           else {
             DeleteFile (fname);
 	    free(fname);
-            linfo ("Removed existing virtual disk image for replacement to original state.");
+            fname = NULL;
           }
           break;
 
         case 'c':
-          ldebug ("Set option %s.", torvm_options[optidx].name);
           clean = TRUE;
           break;
 
         case 'X':
-          ldebug ("Set option %s.", torvm_options[optidx].name);
-          indebug = TRUE;
-          vmnop = TRUE;
+          ctx->indebug = TRUE;
+          ctx->vmnop = TRUE;
           break;
 
         case 'Z':
-          ldebug ("Set option %s.", torvm_options[optidx].name);
-          indebug = TRUE;
-          noinit = TRUE;
+          ctx->indebug = TRUE;
+          ctx->noinit = TRUE;
           break;
 
-        case 'F':
-          follow = TRUE;
-          break;
-
         case 'I':
           if (optarg)
-            ctliparg = optarg;
-          else
-            ctliparg = TOR_TAP_VMIP;
+            followiparg = optarg;
           break;
 
         case 'P':
           if (optarg)
-            ctlportarg = optarg;
-          else
-            ctlportarg = "9051";
+            followportarg = optarg;
           break;
 
         case 'h':
-          linfo ("Help for command usage invoked.");
           usage();
           break;
 
@@ -2297,17 +2292,17 @@
     }
   }
  
-  /* The Tor follow mode is a special case. All we do is loop until the control
+  /* The Tor follow mode is a special case. All we do is loop until the socks
    * port is no longer accepting connections and then we issue a logoff request.
    */ 
-  if (follow) {
-    while(follow) {
+  if (followiparg) {
+    while(followiparg) {
       Sleep(1000);
-      if (!tryconnect(ctliparg, atol(ctlportarg))) {
+      if (!tryconnect(followiparg, atol(followportarg))) {
         Sleep(1000);
         /* XXX: Increase prio if intermittent connect timeouts? */
-        if (!tryconnect(ctliparg, atol(ctlportarg))) {
-          follow = FALSE;
+        if (!tryconnect(followiparg, atol(followportarg))) {
+          followiparg = NULL;
         }
       }
     }
@@ -2315,7 +2310,7 @@
      * This is our cue to force the restricted user to log off.
      */
     runcommand("shutdown -l -f", NULL);
-    return 0;
+    exit(0);
   }
 
   if (buildfpath(PATH_FQ, VMDIR_STATE, NULL, "vmlog.txt", &logfile)) {
@@ -2351,18 +2346,34 @@
     fatal ("Unable to prepare process environment.");
   }
 
+  ctx->insthnd = CreateNamedPipe("\\\\.\\pipe\\" TORVM_INSTNAME,
+                                 PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE,
+                                 PIPE_TYPE_BYTE | PIPE_NOWAIT,
+                                 1,
+                                 32,
+                                 32,
+                                 0,
+                                 NULL);
+  if (ctx->insthnd == INVALID_HANDLE_VALUE) {
+    DWORD errorno = GetLastError();
+    ldebug ("CreateNamedPipe failed on Tor VM instance GUID. Error code: %d", errorno);
+    fatal ("Tor VM appears to be running. Exiting.");
+  }
+
   if (clean)
     goto shutdown;
 
   dispmsg("Tor VM is starting. Please be patient.");
-  if (!vmnop) {
+  ctx->running = TRUE;
+
+  if (!ctx->vmnop) {
     if (!savenetconfig()) {
       fatal ("Unable to save current network configuration.");
     }
 
-    if (bundle) {
+    if (ctx->bundle) {
       /* XXX: note we're using the "all ready" alias for the control port. */
-      if (!setupuser(TOR_RESTRICTED_USER, TOR_TAP_VMIP, "9052")) {
+      if (!setupuser(TOR_RESTRICTED_USER, TOR_TAP_VMIP, "9050")) {
         lerror ("Unable to setup restricted user.");
       }
     }
@@ -2427,7 +2438,7 @@
     lerror ("Unable to confirm usable virtual disk is present.");
   }
 
-  if (!vmnop) {
+  if (!ctx->vmnop) {
     if (numintf <= 0) {
       lerror ("Unable to find any usable network interfaces.");
       goto shutdown;
@@ -2448,8 +2459,8 @@
     }
   }
 
-  if (!vmnop) {
-    if (! buildcmdline(ce, bundle, indebug, noinit, &cmdline)) {
+  if (!ctx->vmnop) {
+    if (! buildcmdline(ce, ctx->bundle, ctx->indebug, ctx->noinit, &cmdline)) {
       lerror ("Unable to generate command line for kernel.");
       goto shutdown;
     }
@@ -2458,7 +2469,7 @@
 
   dispmsg(" - Launching QEMU virtual machine");
   PROCESS_INFORMATION pi;
-  if (vmnop) {
+  if (ctx->vmnop) {
     if (! spawnprocess(&pi, "qemu.exe")) {
       lerror ("Unable to launch default Qemu instance.");
     }
@@ -2504,7 +2515,7 @@
    * once Tor is stopped the no longer listening control port signals
    * restricted user log off and clean shutdown.
    */
-  if (bundle) {
+  if (ctx->bundle) {
     dispmsg(" - Waiting for Tor control port to open");
     /* try to confirm control port is up before launching vidalia... */
     int i = 10;
@@ -2525,7 +2536,9 @@
        */
       Sleep(2000);
       dispmsg(" - Launching Vidalia");
-      runvidalia(indebug);
+      if (!createthr(&runvidalia, ctx, FALSE)) {
+        lerror("Failed to start Vidalia thread.");
+      }
 
       /* XXX: Now we wait for the ALL READY socket to be listening before switching.
        * If we don't get bootstrapped within this period of time something is broken/blocked.
@@ -2533,7 +2546,7 @@
       ldebug("Waiting for Tor to bootstrap ...");
       dispmsg(" - Waiting for Tor to establish a circuit");
       i = 60 * 5; 
-      while ( (!tryconnect(TOR_TAP_VMIP, 9052)) && (i > 0) ) {
+      while ( (!tryconnect(TOR_TAP_VMIP, 9050)) && (i > 0) ) {
         Sleep(1000);
         ldebug("Tor has not bootstrapped yet, checking again... [%d left]", i);
         if (!isrunning(&pi)) 
@@ -2544,7 +2557,7 @@
       if (i > 0) {
         /* Polipo now has a working Tor for SOCKS outbound. */
         dispmsg(" - Launching Polipo");
-        if (!createthr(&runpolipo, NULL, FALSE)) {
+        if (!createthr(&runpolipo, ctx, FALSE)) {
           lerror("Failed to start Polipo thread.");
         }
 
@@ -2558,7 +2571,7 @@
     dispmsg("");
     dispmsg("GOOD! Tor VM is running.");
     dispmsg(" - Waiting for VM to exit ...");
-    if (bundle)
+    if (ctx->bundle)
       dispmsg(" NOTE: Select the \"Exit\" option in Vidalia to shutdown.");
     else
       dispmsg(" NOTE: Close the \"QEMU (Tor VM)\" window to shutdown.");
@@ -2573,11 +2586,13 @@
     lerror ("Virtual machine failed to start properly.");
     linfo ("Tor VM Qemu failed to start properly.");
   }
+  ctx->running = FALSE;
   dispmsg("Shutting down.");
   dispmsg("CAUTION: Restoring network settings. Do NOT close this window!");
 
  shutdown:
-  if (bundle) {
+  CloseHandle(ctx->insthnd);
+  if (ctx->bundle) {
     disableuser(TOR_RESTRICTED_USER);
     /* cleanruserfiles(TOR_RESTRICTED_USER); */
   }
@@ -2604,6 +2619,7 @@
     lerror ("Unable to restore network configuration.");
   }
   linfo ("Tor VM shutdown completed.");
-  return 0;
+  /* XXX: at this point be sure all threads are killed. */
+  exit(0);
 }
 

Modified: torvm/trunk/build/win32/src/torvm-w32/torvm.h
===================================================================
--- torvm/trunk/build/win32/src/torvm-w32/torvm.h	2009-07-28 04:11:23 UTC (rev 20178)
+++ torvm/trunk/build/win32/src/torvm-w32/torvm.h	2009-07-28 06:01:31 UTC (rev 20179)
@@ -10,4 +10,37 @@
 #include "registry.h"
 #include "thr.h"
 
+typedef struct s_rconnelem {
+  BOOL    isactive;
+  BOOL    isdefgw;
+  BOOL    isdhcp;
+  BOOL    istortap;
+  LPTSTR  name;
+  LPTSTR  guid;
+  LPTSTR  macaddr;
+  LPTSTR  ipaddr;
+  LPTSTR  netmask;
+  LPTSTR  gateway;
+  LPTSTR  gwmacaddr;
+  LPTSTR  dhcpsvr;
+  LPTSTR  svrmacaddr;
+  LPTSTR  dhcpname;
+  LPTSTR  driver;
+  struct s_rconnelem * next;
+} t_rconnelem;
+
+typedef struct s_ctx {
+  BOOL          vmaccel;
+  BOOL          bundle;
+  BOOL          indebug;
+  BOOL          vmnop;
+  BOOL          noinit;
+  BOOL          running;
+  HANDLE        insthnd;
+  LPTSTR        netcfgfile;
+  LPTSTR        fwcfgfile;
+} t_ctx;
+
+#define TORVM_INSTNAME "{1c6870d3-235d-4fb7-828d-25d7f05e2e76}"
+
 #endif /* torvm_h */



More information about the tor-commits mailing list