[or-cvs] r17048: {torvm} Modifications to support automatic network configuration for (torvm/trunk/build/win32/src/torvm-w32)
coderman at seul.org
coderman at seul.org
Mon Oct 6 07:52:53 UTC 2008
Author: coderman
Date: 2008-10-06 03:52:51 -0400 (Mon, 06 Oct 2008)
New Revision: 17048
Modified:
torvm/trunk/build/win32/src/torvm-w32/torvm.c
Log:
Modifications to support automatic network configuration for a functional test build. Improved error handling, logging, and registry clean up for tap adapter.
Modified: torvm/trunk/build/win32/src/torvm-w32/torvm.c
===================================================================
--- torvm/trunk/build/win32/src/torvm-w32/torvm.c 2008-10-06 01:40:34 UTC (rev 17047)
+++ torvm/trunk/build/win32/src/torvm-w32/torvm.c 2008-10-06 07:52:51 UTC (rev 17048)
@@ -35,22 +35,16 @@
#define TOR_TAP_NAME "Tor VM Tap32"
#define TOR_TAP_SVC "tortap91"
-struct s_rtcpipvals {
- BOOL isdhcp;
- LPTSTR ipaddr;
- LPTSTR netmask;
- LPTSTR gateway;
- LPTSTR hostname;
-};
-
struct s_rconnelem {
- int idx;
BOOL isactive;
BOOL isdefgw;
+ BOOL isdhcp;
LPTSTR name;
LPTSTR guid;
- LPTSTR driver;
LPTSTR macaddr;
+ LPTSTR ipaddr;
+ LPTSTR netmask;
+ LPTSTR gateway;
struct s_rconnelem * next;
};
@@ -75,6 +69,7 @@
/* OID's we need to query */
#define OID_802_3_PERMANENT_ADDRESS 0x01010101
#define OID_802_3_CURRENT_ADDRESS 0x01010102
+#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114
/* probably will never need these, but just in case ... */
#define OID_GEN_MEDIA_IN_USE 0x00010104
#define OID_WAN_PERMANENT_ADDRESS 0x04010101
@@ -88,7 +83,7 @@
#define NETWORK_CLIENTS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E973-E325-11CE-BFC1-08002BE10318}"
#define NETWORK_SERVICES_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E974-E325-11CE-BFC1-08002BE10318}"
#define NETWORK_PROTOCOLS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E975-E325-11CE-BFC1-08002BE10318}"
-#define TCPIP_KEY "SYSTEM\\CurrentControlSet\\Services\\Tcpip"
+#define TCPIP_KEY "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces"
/* debug, info and error logging
@@ -108,7 +103,7 @@
}
s_logh = CreateFile (path,
GENERIC_WRITE,
- 0,
+ FILE_SHARE_READ,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
@@ -230,7 +225,7 @@
}
s_dbgh = CreateFile (path,
GENERIC_WRITE,
- 0,
+ FILE_SHARE_READ,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
@@ -437,6 +432,13 @@
LPTSTR dir = NULL;
DWORD exitcode;
DWORD opts = 0;
+ LONG status;
+ HKEY key;
+ DWORD len;
+ int i = 0;
+ int stop = 0;
+ int numconn = 0;
+ const char name_string[] = "Name";
opts = CREATE_NEW_PROCESS_GROUP;
@@ -445,7 +447,8 @@
si.cb = sizeof(si);
dir = TOR_VM_LIB;
cmd = "\"" TOR_VM_BIN "\\devcon.exe\" remove TORTAP91";
-
+
+ ldebug ("Removing TORTAP91 device via devcon.");
if( !CreateProcess(NULL,
cmd,
NULL, // process handle no inherit
@@ -457,6 +460,7 @@
&si,
&pi) ) {
lerror ("Failed to launch process. Error code: %d", GetLastError());
+ return FALSE;
}
while ( GetExitCodeProcess(pi.hProcess, &exitcode) && (exitcode == STILL_ACTIVE) ) {
@@ -464,6 +468,116 @@
}
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
+
+ ldebug ("Removal complete. Checking registry for Tor Tap connection entries.");
+ /* clean up registry keys left after tap adapter is removed
+ */
+ status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ NETWORK_CONNECTIONS_KEY,
+ 0,
+ KEY_READ,
+ &key);
+ if (status != ERROR_SUCCESS) {
+ lerror ("Failed to open key for read: %d", status);
+ return -1;
+ }
+
+ while (!stop) {
+ char enum_name[REG_NAME_MAX];
+ char connection_string[REG_NAME_MAX];
+ HKEY ckey;
+ HKEY dkey;
+ char name_data[REG_NAME_MAX];
+ DWORD name_type;
+ int j;
+
+ len = sizeof (enum_name);
+ status = RegEnumKeyEx(key,
+ i++,
+ enum_name,
+ &len,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ if (status == ERROR_NO_MORE_ITEMS)
+ break;
+ else if (status != ERROR_SUCCESS) {
+ lerror ("Failed to query members of network connection tree.");
+ RegCloseKey (key);
+ return FALSE;
+ }
+
+ ldebug ("Checking connection entry %s name.", enum_name);
+ snprintf(connection_string,
+ sizeof(connection_string),
+ "%s\\%s\\Connection",
+ NETWORK_CONNECTIONS_KEY, enum_name);
+ status = RegOpenKeyEx(
+ HKEY_LOCAL_MACHINE,
+ connection_string,
+ 0,
+ KEY_READ,
+ &ckey);
+
+ if (status == ERROR_SUCCESS) {
+ len = sizeof (name_data);
+ status = RegQueryValueEx(
+ ckey,
+ name_string,
+ NULL,
+ &name_type,
+ name_data,
+ &len);
+
+ if (status != ERROR_SUCCESS || name_type != REG_SZ) {
+ continue;
+ }
+ if (strcmp(name_data, TOR_TAP_NAME) == 0) {
+ /* remove this connection entry to non-existant Tor Tap32 device */
+ ldebug ("Removing registry data for %s adapter key %s.", TOR_TAP_NAME, enum_name);
+ ldebug ("Deleting Connection subkey.");
+ snprintf(connection_string,
+ sizeof(connection_string),
+ "%s\\%s",
+ NETWORK_CONNECTIONS_KEY, enum_name);
+ status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ connection_string,
+ 0,
+ KEY_SET_VALUE,
+ &dkey);
+ if (status != ERROR_SUCCESS) {
+ lerror ("Failed to open network connection key for write: %d", status);
+ continue;
+ }
+ /* now we can delete the connection key itself */
+ status = RegDeleteKey(dkey, "Connection");
+ if (status != ERROR_SUCCESS) {
+ lerror ("Failed to remove tap connection subkey from registry: %d", status);
+ }
+ RegCloseKey (dkey);
+ /* finally, remove the top level connection key from the list of connections ids */
+ ldebug ("Deleting connection entry %s from top level connections key.", enum_name);
+ status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ NETWORK_CONNECTIONS_KEY,
+ 0,
+ KEY_SET_VALUE,
+ &dkey);
+ if (status != ERROR_SUCCESS) {
+ lerror ("Failed to open top level network connection key for write: %d", status);
+ }
+ status = RegDeleteKey(dkey, enum_name);
+ if (status != ERROR_SUCCESS) {
+ lerror ("Failed to remove top level tap key from registry: %d", status);
+ }
+ RegCloseKey (dkey);
+ }
+ RegCloseKey (ckey);
+ }
+ }
+
+ RegCloseKey (key);
+
return TRUE;
}
@@ -546,8 +660,8 @@
sattr.bInheritHandle = TRUE;
sattr.lpSecurityDescriptor = NULL;
dir = TOR_VM_STATE;
- /* cmd = "\"netsh.exe\" interface ip dump" */
- cmd = "\"netsh.exe\" dump";
+ cmd = "\"netsh.exe\" interface ip dump";
+ /* cmd = "\"netsh.exe\" dump"; <- this is noisy and slow. avoid if possible. */
CreatePipe(&stdout_rd, &stdout_wr, &sattr, 0);
SetHandleInformation(stdout_rd, HANDLE_FLAG_INHERIT, 0);
@@ -739,6 +853,77 @@
return TRUE;
}
+BOOL configbridge(void)
+{
+ LPSTR cmd;
+ cmd = "\"netsh.exe\" interface ip set address \"Local Area Connection\" static 10.231.254.1 255.255.255.254";
+ if (! runcommand(cmd)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+BOOL checkvirtdisk(void) {
+ HANDLE src = NULL;
+ HANDLE dest = NULL;
+ LPTSTR srcname = TOR_VM_LIB "\\hdd.img";
+ LPTSTR destname = TOR_VM_STATE "\\hdd.img";
+ CHAR * buff = NULL;
+ DWORD buffsz = 4096;
+ DWORD len;
+ DWORD written;
+
+ dest = CreateFile (destname,
+ GENERIC_READ,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (dest == INVALID_HANDLE_VALUE) {
+ if (GetLastError() != ERROR_FILE_NOT_FOUND) {
+ return FALSE;
+ }
+ }
+ else {
+ CloseHandle (dest);
+ return TRUE;
+ }
+
+ dest = CreateFile (destname,
+ GENERIC_WRITE,
+ 0,
+ NULL,
+ CREATE_NEW,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (dest == INVALID_HANDLE_VALUE) {
+ return FALSE;
+ }
+
+ src = CreateFile (srcname,
+ GENERIC_READ,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (src == INVALID_HANDLE_VALUE) {
+ CloseHandle (dest);
+ return FALSE;
+ }
+
+ buff = (CHAR *)malloc(buffsz);
+ while (ReadFile(src, buff, buffsz, &len, NULL) && (len > 0)) {
+ WriteFile(dest, buff, len, &written, NULL);
+ }
+ free (buff);
+ CloseHandle (src);
+ CloseHandle (dest);
+
+ return TRUE;
+}
+
BOOL getmacaddr(const char * devguid,
char ** mac)
{
@@ -793,6 +978,52 @@
return retval;
}
+BOOL isconnected(const char * devguid)
+{
+ char * devfstr = NULL;
+ BOOL status;
+ HANDLE devfd;
+ DWORD retsz, oidcode, intfStatus;
+ BOOL retval = FALSE;
+
+ devfstr = malloc(1024);
+ snprintf (devfstr, 1023, "\\\\.\\%s", devguid);
+ devfd = CreateFile(devfstr,
+ 0,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL);
+ if (devfd == INVALID_HANDLE_VALUE)
+ {
+ lerror ("Unable to open net device handle for path: %s", devfstr);
+ goto cleanup;
+ }
+
+ oidcode = OID_GEN_MEDIA_CONNECT_STATUS;
+ status = DeviceIoControl(devfd,
+ IOCTL_NDIS_QUERY_GLOBAL_STATS,
+ &oidcode, sizeof(oidcode),
+ &intfStatus, sizeof(intfStatus),
+ &retsz,
+ (LPOVERLAPPED) NULL);
+ if (status) {
+ ldebug ("Received media connect status %d for device %s.", intfStatus, devguid);
+ retval = (intfStatus == 0) ? TRUE : FALSE;
+ }
+ else {
+ retval = FALSE;
+ }
+
+ cleanup:
+ if (devfd != INVALID_HANDLE_VALUE)
+ CloseHandle(devfd);
+ free(devfstr);
+
+ return retval;
+}
+
int loadnetinfo(struct s_rconnelem **connlist)
{
LONG status;
@@ -800,9 +1031,9 @@
HKEY wkey;
DWORD len;
int i = 0;
- int stop = 0;
int numconn = 0;
struct s_rconnelem * ce = NULL;
+ struct s_rconnelem * ne = NULL;
const char name_string[] = "Name";
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
@@ -815,17 +1046,18 @@
return -1;
}
- while (!stop) {
- ce = malloc(sizeof(struct s_rconnelem));
+ while (1) {
char enum_name[REG_NAME_MAX];
char connection_string[REG_NAME_MAX];
+ char tcpip_string[REG_NAME_MAX];
HKEY ckey;
+ HKEY tkey;
char name_data[REG_NAME_MAX];
DWORD name_type;
len = sizeof (enum_name);
status = RegEnumKeyEx(key,
- i,
+ i++,
enum_name,
&len,
NULL,
@@ -864,19 +1096,95 @@
return -1;
}
else {
- if (getmacaddr (enum_name, &(ce->macaddr)) == TRUE) {
+ /* add this connection info the list */
+ numconn++;
+ if (ce == NULL) {
+ *connlist = ce = malloc(sizeof(struct s_rconnelem));
+ memset(ce, 0, sizeof(struct s_rconnelem));
+ }
+ else {
+ ne = malloc(sizeof(struct s_rconnelem));
+ memset(ne, 0, sizeof(struct s_rconnelem));
+ ce->next = ne;
+ ce = ne;
+ }
+ ce->name = strdup(name_data);
+ ce->guid = strdup(enum_name);
+ if (getmacaddr (ce->guid, &(ce->macaddr))) {
linfo ("Interface %s => %s mac(%s)", name_data, enum_name, ce->macaddr);
}
+ if (isconnected (enum_name)) {
+ linfo ("Interface %s (%s) is currently connected.", ce->name, ce->macaddr);
+ ce->isactive = TRUE;
+ snprintf(tcpip_string,
+ sizeof(tcpip_string),
+ "%s\\%s",
+ TCPIP_KEY, enum_name);
+ status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ tcpip_string,
+ 0,
+ KEY_READ,
+ &tkey);
+ if (status == ERROR_SUCCESS) {
+ len = sizeof (BOOL);
+ status = RegQueryValueEx(tkey,
+ "EnableDHCP",
+ NULL,
+ NULL,
+ &(ce->isdhcp),
+ &len);
+ if (status == ERROR_SUCCESS) {
+ ce->gateway = strdup(name_data);
+ ldebug ("Connection %s %s using DHCP.", ce->name, ce->isdhcp ? "is" : "is NOT");
+ }
+ len = sizeof (name_data);
+ status = RegQueryValueEx(tkey,
+ "DefaultGateway",
+ NULL,
+ &name_type,
+ name_data,
+ &len);
+ if (status == ERROR_SUCCESS) {
+ ce->gateway = strdup(name_data);
+ ldebug ("Connection %s default gateway: %s.", ce->name, ce->gateway);
+ if (strcmp(ce->gateway, "0.0.0.0") != 0) {
+ ce->isdefgw = TRUE;
+ ldebug ("Connection %s has the default route.");
+ }
+ }
+ len = sizeof (name_data);
+ status = RegQueryValueEx(tkey,
+ ce->isdhcp ? "DhcpIPAddress" : "IPAddress",
+ NULL,
+ &name_type,
+ name_data,
+ &len);
+ if (status == ERROR_SUCCESS) {
+ ce->ipaddr = strdup(name_data);
+ ldebug ("Connection %s current IP address: %s.", ce->name, ce->ipaddr);
+ }
+ len = sizeof (name_data);
+ status = RegQueryValueEx(tkey,
+ ce->isdhcp ? "DhcpSubnetMask" : "SubnetMask",
+ NULL,
+ &name_type,
+ name_data,
+ &len);
+ if (status == ERROR_SUCCESS) {
+ ce->netmask = strdup(name_data);
+ ldebug ("Connection %s netmask: %s.", ce->name, ce->netmask);
+ }
+ RegCloseKey (tkey);
+ }
+ }
}
RegCloseKey (ckey);
}
- ++i;
}
RegCloseKey (key);
i = 0;
- stop = 0;
status = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
ADAPTER_KEY,
@@ -889,8 +1197,7 @@
return -1;
}
- while (!stop)
- {
+ while (1) {
char enum_name[REG_NAME_MAX];
char connection_string[REG_NAME_MAX];
HKEY ckey;
@@ -901,7 +1208,7 @@
len = sizeof (enum_name);
status = RegEnumKeyEx(
key,
- i,
+ i++,
enum_name,
&len,
NULL,
@@ -940,7 +1247,7 @@
if (status != ERROR_SUCCESS || name_type != REG_SZ) {
}
else {
- /* printf ("-%s- %s", enum_name, name_data); */
+ ldebug ("-%s- %s", enum_name, name_data);
}
RegCloseKey (ckey);
@@ -972,17 +1279,17 @@
&len);
if (status != ERROR_SUCCESS || name_type != REG_SZ) {
- /* printf ("Failed parse of key %s\\NetCfgInstanceId , errorno: %d", connection_string, status); */
+ ldebug ("Failed parse of key %s\\NetCfgInstanceId , errorno: %d", connection_string, status);
}
else {
- /* printf ("GUID: %s", name_data); */
+ ldebug ("GUID: %s", name_data);
strcpy (cguid, name_data);
}
RegCloseKey (ckey);
}
else {
- /* printf ("Failed read key %s , errorno: %d", connection_string, status); */
+ ldebug ("Failed read key %s , errorno: %d", connection_string, status);
}
snprintf(connection_string,
@@ -1008,10 +1315,10 @@
&len);
if (status != ERROR_SUCCESS || name_type != REG_SZ) {
- /* printf ("Failed parse of key %s\\Service , errorno: %d", connection_string, status); */
+ ldebug ("Failed parse of key %s\\Service , errorno: %d", connection_string, status);
}
else {
- /* printf ("Service: %s", name_data); */
+ ldebug ("Service: %s", name_data);
if (strcmp(name_data, TOR_TAP_SVC) == 0) {
snprintf(connection_string,
sizeof(connection_string),
@@ -1041,15 +1348,13 @@
RegCloseKey (ckey);
}
else {
- /* printf ("Failed read key %s , errorno: %d", connection_string, status); */
+ ldebug ("Failed read key %s , errorno: %d", connection_string, status);
}
-
- i++;
}
RegCloseKey (key);
- return 0;
+ return numconn;
}
/* keep linkage to these dynamic, in case the requisite Dll's don't exist. */
@@ -1112,19 +1417,62 @@
return isadmin;
}
-BOOL launchtorvm (PROCESS_INFORMATION * pi)
+BOOL buildcmdline (struct s_rconnelem * brif,
+ char **cmdline)
{
+ *cmdline = (char *)malloc(4096);
+ const char * basecmds = "quiet loglevel=0 clocksource=hpet";
+ const char * dbgcmds = "loglevel=9 clocksource=hpet DEBUGINIT";
+ snprintf (*cmdline, 4095,
+ "%s IP=%s MASK=%s GW=%s MAC=%s MTU=1480 PRIVIP=10.10.10.1",
+ basecmds,
+ brif->ipaddr,
+ brif->netmask,
+ brif->gateway,
+ brif->macaddr);
+ return TRUE;
+}
+
+BOOL launchtorvm (PROCESS_INFORMATION * pi,
+ char * bridgeintf,
+ char * macaddr,
+ char * cmdline)
+{
STARTUPINFO si;
+ HANDLE stdin_rd = NULL;
+ HANDLE stdin_wr = NULL;
+ HANDLE stdout_rd = NULL;
+ HANDLE stdout_wr = NULL;
+ SECURITY_ATTRIBUTES sattr;
LPTSTR cmd = NULL;
LPTSTR dir = NULL;
DWORD opts = CREATE_NEW_PROCESS_GROUP | BELOW_NORMAL_PRIORITY_CLASS;
+ DWORD numwritten;
ZeroMemory( &si, sizeof(si) );
ZeroMemory( pi, sizeof(PROCESS_INFORMATION) );
si.cb = sizeof(si);
+ sattr.nLength = sizeof(SECURITY_ATTRIBUTES);
+ sattr.bInheritHandle = TRUE;
+ sattr.lpSecurityDescriptor = NULL;
dir = TOR_VM_BIN;
- cmd = "\"" TOR_VM_BIN "\\qemu.exe\" -name \"Tor VM \" -L . -kernel ../lib/vmlinuz -append \"clocksource=hpet IP=172.16.2.42 MASK=255.255.255.0 GW=172.16.2.1 MAC=00:11:22:33:44:55 MTU=1480 PRIVIP=10.10.10.1\" -hda ../state/hdd.img -m 32 -std-vga -net nic,model=pcnet,macaddr=00:11:22:33:44:55 -net pcap,devicename=\"Local Area Connection\" -net nic,vlan=1,model=pcnet -net tap,vlan=1,ifname=\"" TOR_TAP_NAME "\" -net user,vlan=2 -net nic,vlan=2,model=pcnet";
+ cmd = (LPTSTR)malloc(1024);
+ snprintf (cmd, 1023,
+ "\"" TOR_VM_BIN "\\qemu.exe\" -name \"Tor VM \" -L . -kernel ../lib/vmlinuz -appendstdin -hda ../state/hdd.img -m %d -std-vga -net nic,model=pcnet,macaddr=%s -net pcap,devicename=\"%s\" -net nic,vlan=1,model=pcnet -net tap,vlan=1,ifname=\"%s\" -net user,vlan=2 -net nic,vlan=2,model=pcnet",
+ 32,
+ macaddr,
+ bridgeintf,
+ TOR_TAP_NAME);
+ ldebug ("Launching Qemu with cmd: %s", cmd);
+ CreatePipe(&stdin_rd, &stdin_wr, &sattr, 0);
+ SetHandleInformation(stdin_wr, HANDLE_FLAG_INHERIT, 0);
+
+ si.hStdError = stderr;
+ si.hStdOutput = stdout;
+ si.hStdInput = stdin_rd;
+ si.dwFlags |= STARTF_USESTDHANDLES;
+
if( !CreateProcess(NULL,
cmd,
NULL, // process handle no inherit
@@ -1139,6 +1487,11 @@
return FALSE;
}
+ CloseHandle(stdin_rd);
+
+ WriteFile(stdin_wr, cmdline, strlen(cmdline), &numwritten, NULL);
+ CloseHandle(stdin_wr);
+
return TRUE;
}
@@ -1295,7 +1648,11 @@
int main(int argc, char **argv)
{
const char *cmd;
+ int numintf;
struct s_rconnelem *connlist = NULL;
+ struct s_rconnelem *ce = NULL;
+ BOOL foundit = FALSE;
+ char * cmdline = NULL;
if (!haveadminrights()) {
if (promptrunasadmin()) {
@@ -1317,11 +1674,6 @@
fatal ("Unable to save current network configuration.");
}
- if (!installtornpf()) {
- lerror ("Unable to install Tor NPF service driver.");
- goto shutdown;
- }
-
uninstalltap();
if (!setdriversigning (FALSE)) {
@@ -1335,8 +1687,17 @@
lerror ("Unable to restore driver signing checks.");
}
- loadnetinfo(&connlist);
+ if (!installtornpf()) {
+ lerror ("Unable to install Tor NPF service driver.");
+ goto shutdown;
+ }
+
+ numintf = loadnetinfo(&connlist);
+
+ if (! configbridge()) {
+ lerror ("Unable to configure blackhole route for bridged interface.");
+ }
if (! disableservices()) {
lerror ("Unable to disable dangerous windows network services.");
}
@@ -1349,13 +1710,46 @@
if (! flushdns()) {
lerror ("Unable to flush cached DNS entries.");
}
+ if (! checkvirtdisk()) {
+ lerror ("Unable to confirm usable virtual disk is present.");
+ }
+ if (numintf <= 0) {
+ lerror ("Unable to find any usable network interfaces.");
+ goto shutdown;
+ }
+
+ ce = connlist;
+ while (!foundit && ce) {
+ if (ce->isdefgw) {
+ foundit = TRUE;
+ }
+ else {
+ ce = ce->next;
+ }
+ }
+ if (ce == NULL) {
+ lerror ("Unable to find network interface with a default route.");
+ goto shutdown;
+ }
+ if (! buildcmdline(ce, &cmdline)) {
+ lerror ("Unable to generate command line for kernel.");
+ goto shutdown;
+ }
+ ldebug ("Generated kernel command line: %s", cmdline);
+
PROCESS_INFORMATION pi;
- if (! launchtorvm(&pi)) {
+ if (! launchtorvm(&pi,
+ ce->name,
+ ce->macaddr,
+ cmdline)) {
lerror ("Unable to launch Qemu TorVM instance.");
goto shutdown;
}
+
+ /* need to delay long enough to allow qemu to start and open tap device */
Sleep (4000);
+
if (! isrunning(&pi)) {
lerror ("Tor VM failed to start properly.");
goto shutdown;
@@ -1365,7 +1759,6 @@
lerror ("Unable to configure tap device. Exiting.");
goto shutdown;
}
- Sleep (4000);
waitforit(&pi);
More information about the tor-commits
mailing list