aboutsummaryrefslogtreecommitdiff
path: root/src/vpn
diff options
context:
space:
mode:
authorChristian Fuchs <christian.fuchs@cfuchs.net>2013-01-16 17:21:37 +0000
committerChristian Fuchs <christian.fuchs@cfuchs.net>2013-01-16 17:21:37 +0000
commitbdee53dd2cb760e9acd601e251ba59c42c98c02f (patch)
tree484154f4edfe3ae8ce89219bed8c84824913d81d /src/vpn
parenta98bf7b88926295d9c0c823a60c0cf7b8a981871 (diff)
downloadgnunet-bdee53dd2cb760e9acd601e251ba59c42c98c02f.tar.gz
gnunet-bdee53dd2cb760e9acd601e251ba59c42c98c02f.zip
more debugging work.
Registry is extremely slow at refreshing. inserted a makeshift sleep(5) to avoid retrieving outdated interface-information. added proper return-codes to set_address4/6 fixed incorrect string-length handling for the HWID tags updatedriverforplugandplaydevicesa now updates only the driver for our current device, no longer the other siblings too (for >10 devices, this could easily have taken > 60 seconds! ). removed inet_pton, as we require API version XPSP2 anyway.
Diffstat (limited to 'src/vpn')
-rw-r--r--src/vpn/gnunet-helper-vpn-windows.c165
1 files changed, 57 insertions, 108 deletions
diff --git a/src/vpn/gnunet-helper-vpn-windows.c b/src/vpn/gnunet-helper-vpn-windows.c
index dffe92cce..9d4657354 100644
--- a/src/vpn/gnunet-helper-vpn-windows.c
+++ b/src/vpn/gnunet-helper-vpn-windows.c
@@ -39,7 +39,6 @@
39#include <Winsock2.h> 39#include <Winsock2.h>
40#include "platform.h" 40#include "platform.h"
41#include "tap-windows.h" 41#include "tap-windows.h"
42
43/** 42/**
44 * Need 'struct GNUNET_MessageHeader'. 43 * Need 'struct GNUNET_MessageHeader'.
45 */ 44 */
@@ -100,7 +99,6 @@
100 99
101/** 100/**
102 * Location of the network interface list resides in registry. 101 * Location of the network interface list resides in registry.
103 * TODO: is this fixed on all version of windows? Checked with XP and 7
104 */ 102 */
105#define INTERFACE_REGISTRY_LOCATION "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}" 103#define INTERFACE_REGISTRY_LOCATION "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
106 104
@@ -138,8 +136,6 @@ static SP_DEVINFO_DATA DeviceNode;
138 */ 136 */
139static char device_guid[256]; 137static char device_guid[256];
140 138
141/* Overlapped IO Begins here (warning: nasty!) */
142
143/** 139/**
144 * A IO Object + read/writebuffer + buffer-size for windows asynchronous IO handling 140 * A IO Object + read/writebuffer + buffer-size for windows asynchronous IO handling
145 */ 141 */
@@ -167,46 +163,8 @@ struct io_facility
167 163
168/** 164/**
169 * ReOpenFile is only available as of XP SP2 and 2003 SP1 165 * ReOpenFile is only available as of XP SP2 and 2003 SP1
170 */
171WINBASEAPI HANDLE WINAPI ReOpenFile (HANDLE, DWORD, DWORD, DWORD);
172
173/**
174 * inet_pton() wrapper for WSAStringToAddress()
175 *
176 * this is needed as long as we support WinXP, because only Vista+ support
177 * inet_pton at all, and mingw does not yet offer inet_pton/ntop at all
178 *
179 * @param af - IN - the aftype this address is supposed to be (v4/v6)
180 * @param src - IN - the presentation form of the address
181 * @param dst - OUT - the numerical form of the address
182 * @return 0 on success, 1 on failure
183 */ 166 */
184int 167WINBASEAPI HANDLE WINAPI ReOpenFile (HANDLE, DWORD, DWORD, DWORD);
185inet_pton (int af, const char *src, void *dst)
186{
187 struct sockaddr_storage addr;
188 int size = sizeof (addr);
189 char local_copy[INET6_ADDRSTRLEN + 1];
190
191 ZeroMemory (&addr, sizeof (addr));
192 /* stupid non-const API */
193 strncpy (local_copy, src, INET6_ADDRSTRLEN + 1);
194 local_copy[INET6_ADDRSTRLEN] = 0;
195
196 if (WSAStringToAddressA (local_copy, af, NULL, (struct sockaddr *) &addr, &size) == 0)
197 {
198 switch (af)
199 {
200 case AF_INET:
201 *(struct in_addr *) dst = ((struct sockaddr_in *) &addr)->sin_addr;
202 return 1;
203 case AF_INET6:
204 *(struct in6_addr *) dst = ((struct sockaddr_in6 *) &addr)->sin6_addr;
205 return 1;
206 }
207 }
208 return 0;
209}
210 168
211/** 169/**
212 * Wrapper for executing a shellcommand in windows. 170 * Wrapper for executing a shellcommand in windows.
@@ -226,18 +184,11 @@ execute_shellcommand (char * command)
226 return EINVAL; 184 return EINVAL;
227 185
228#ifdef TESTING 186#ifdef TESTING
229 { 187 char output[LINE_LEN];
230 char output[LINE_LEN]; 188 while (NULL != fgets (output, sizeof (output), pipe))
231 189 printf (output);
232 printf ("executed command: %s", command);
233 while (NULL != fgets (output, sizeof (output), pipe))
234 printf (output);
235 }
236#endif 190#endif
237 191
238 if (!feof (pipe))
239 return EPIPE;
240
241 return _pclose (pipe); 192 return _pclose (pipe);
242} 193}
243 194
@@ -247,7 +198,7 @@ execute_shellcommand (char * command)
247 * @param address the IPv6-Address 198 * @param address the IPv6-Address
248 * @param prefix_len the length of the network-prefix 199 * @param prefix_len the length of the network-prefix
249 */ 200 */
250static void 201static int
251set_address6 (const char *address, unsigned long prefix_len) 202set_address6 (const char *address, unsigned long prefix_len)
252{ 203{
253 int ret = EINVAL; 204 int ret = EINVAL;
@@ -263,7 +214,7 @@ set_address6 (const char *address, unsigned long prefix_len)
263 { 214 {
264 fprintf (stderr, "Failed to parse address `%s': %s\n", address, 215 fprintf (stderr, "Failed to parse address `%s': %s\n", address,
265 strerror (errno)); 216 strerror (errno));
266 exit (1); 217 return -1;
267 } 218 }
268 219
269 /* 220 /*
@@ -279,10 +230,8 @@ set_address6 (const char *address, unsigned long prefix_len)
279 230
280 /* Did it work?*/ 231 /* Did it work?*/
281 if (0 != ret) 232 if (0 != ret)
282 { 233 fprintf (stderr, "Setting IPv6 address failed: %s\n", strerror (ret));
283 fprintf (stderr, "Setting IPv6 address failed: %s\n", strerror (ret)); 234 return ret;
284 exit (1); // FIXME: return error code, shut down interface / unload driver
285 }
286} 235}
287 236
288/** 237/**
@@ -292,7 +241,7 @@ set_address6 (const char *address, unsigned long prefix_len)
292 * @param address the IPv4-Address 241 * @param address the IPv4-Address
293 * @param mask the netmask 242 * @param mask the netmask
294 */ 243 */
295static void 244static int
296set_address4 (const char *address, const char *mask) 245set_address4 (const char *address, const char *mask)
297{ 246{
298 int ret = EINVAL; 247 int ret = EINVAL;
@@ -308,13 +257,11 @@ set_address4 (const char *address, const char *mask)
308 { 257 {
309 fprintf (stderr, "Failed to parse address `%s': %s\n", address, 258 fprintf (stderr, "Failed to parse address `%s': %s\n", address,
310 strerror (errno)); 259 strerror (errno));
311 exit (1); 260 return -1;
312 } 261 }
313
314 // Set Device to Subnet-Mode? 262 // Set Device to Subnet-Mode?
315 // do we really need tun.c:2925 ? 263 // do we really need tun.c:2925 ?
316 264
317
318 /* 265 /*
319 * prepare the command 266 * prepare the command
320 */ 267 */
@@ -328,10 +275,8 @@ set_address4 (const char *address, const char *mask)
328 275
329 /* Did it work?*/ 276 /* Did it work?*/
330 if (0 != ret) 277 if (0 != ret)
331 { 278 fprintf (stderr, "Setting IPv4 address failed: %s\n", strerror (ret));
332 fprintf (stderr, "Setting IPv4 address failed: %s\n", strerror (ret)); 279 return ret;
333 exit (1); // FIXME: return error code, shut down interface / unload driver
334 }
335} 280}
336 281
337/** 282/**
@@ -353,14 +298,11 @@ setup_interface ()
353 char hwidlist[LINE_LEN + 4]; 298 char hwidlist[LINE_LEN + 4];
354 char class_name[128]; 299 char class_name[128];
355 GUID class_guid; 300 GUID class_guid;
356 int str_lenth = 0; 301 int str_length = 0;
357 302
358 /** 303 /**
359 * Set the device's hardware ID and add it to a list. 304 * Set the device's hardware ID and add it to a list.
360 * This information will later on identify this device in registry. 305 * This information will later on identify this device in registry.
361 *
362 * TODO: Currently we just use TAP0901 as HWID,
363 * but we might want to add additional information
364 */ 306 */
365 strncpy (hwidlist, HARDWARE_ID, LINE_LEN); 307 strncpy (hwidlist, HARDWARE_ID, LINE_LEN);
366 /** 308 /**
@@ -369,9 +311,10 @@ setup_interface ()
369 * 311 *
370 * A HWID list is double-\0 terminated and \0 separated 312 * A HWID list is double-\0 terminated and \0 separated
371 */ 313 */
372 str_lenth = strlen (hwidlist) + 1; 314 str_length = strlen (hwidlist) + 1;
373 strncpy (&hwidlist[str_lenth], secondary_hwid, LINE_LEN - str_lenth); 315 strncpy (&hwidlist[str_length], secondary_hwid, LINE_LEN);
374 316 str_length += strlen (&hwidlist[str_length]) + 1;
317
375 /** 318 /**
376 * Locate the inf-file, we need to store it somewhere where the system can 319 * Locate the inf-file, we need to store it somewhere where the system can
377 * find it. A good choice would be CWD/PDW or %WINDIR$\system32\ 320 * find it. A good choice would be CWD/PDW or %WINDIR$\system32\
@@ -380,7 +323,7 @@ setup_interface ()
380 * We need to use a different driver for amd64/i386 ! 323 * We need to use a different driver for amd64/i386 !
381 */ 324 */
382 GetFullPathNameA (INF_FILE, MAX_PATH, inf_file_path, &temp_inf_filename); 325 GetFullPathNameA (INF_FILE, MAX_PATH, inf_file_path, &temp_inf_filename);
383 326
384 /** 327 /**
385 * Bootstrap our device info using the drivers inf-file 328 * Bootstrap our device info using the drivers inf-file
386 */ 329 */
@@ -389,7 +332,7 @@ setup_interface ()
389 class_name, sizeof (class_name) / sizeof (char), 332 class_name, sizeof (class_name) / sizeof (char),
390 NULL)) 333 NULL))
391 return FALSE; 334 return FALSE;
392 335
393 /** 336 /**
394 * Collect all the other needed information... 337 * Collect all the other needed information...
395 * let the system fill our this form 338 * let the system fill our this form
@@ -397,7 +340,7 @@ setup_interface ()
397 DeviceInfo = SetupDiCreateDeviceInfoList (&class_guid, NULL); 340 DeviceInfo = SetupDiCreateDeviceInfoList (&class_guid, NULL);
398 if (DeviceInfo == INVALID_HANDLE_VALUE) 341 if (DeviceInfo == INVALID_HANDLE_VALUE)
399 return FALSE; 342 return FALSE;
400 343
401 DeviceNode.cbSize = sizeof (SP_DEVINFO_DATA); 344 DeviceNode.cbSize = sizeof (SP_DEVINFO_DATA);
402 if (!SetupDiCreateDeviceInfoA (DeviceInfo, 345 if (!SetupDiCreateDeviceInfoA (DeviceInfo,
403 class_name, 346 class_name,
@@ -407,28 +350,28 @@ setup_interface ()
407 DICD_GENERATE_ID, 350 DICD_GENERATE_ID,
408 &DeviceNode)) 351 &DeviceNode))
409 return FALSE; 352 return FALSE;
410 353
411 /* Deploy all the information collected into the registry */ 354 /* Deploy all the information collected into the registry */
412 if (!SetupDiSetDeviceRegistryPropertyA (DeviceInfo, 355 if (!SetupDiSetDeviceRegistryPropertyA (DeviceInfo,
413 &DeviceNode, 356 &DeviceNode,
414 SPDRP_HARDWAREID, 357 SPDRP_HARDWAREID,
415 (LPBYTE) hwidlist, 358 (LPBYTE) hwidlist,
416 (lstrlenA (hwidlist) + 2) * sizeof (char))) 359 str_length * sizeof (char)))
417 return FALSE; 360 return FALSE;
418 361
419 /* Install our new class(=device) into the system */ 362 /* Install our new class(=device) into the system */
420 if (!SetupDiCallClassInstaller (DIF_REGISTERDEVICE, 363 if (!SetupDiCallClassInstaller (DIF_REGISTERDEVICE,
421 DeviceInfo, 364 DeviceInfo,
422 &DeviceNode)) 365 &DeviceNode))
423 return FALSE; 366 return FALSE;
424 367
425 if(!UpdateDriverForPlugAndPlayDevicesA(NULL, 368 if (!UpdateDriverForPlugAndPlayDevicesA (NULL,
426 HARDWARE_ID, // I can haz secondary HWID too? 369 secondary_hwid,
427 inf_file_path, 370 inf_file_path,
428 INSTALLFLAG_FORCE | INSTALLFLAG_NONINTERACTIVE, 371 INSTALLFLAG_FORCE | INSTALLFLAG_NONINTERACTIVE,
429 NULL)) //reboot required? NEVER! 372 NULL)) //reboot required? NEVER!
430 return FALSE; 373 return FALSE;
431 374
432 return TRUE; 375 return TRUE;
433} 376}
434 377
@@ -491,6 +434,9 @@ resolve_interface_name ()
491 boolean retval = FALSE; 434 boolean retval = FALSE;
492 char adapter[] = INTERFACE_REGISTRY_LOCATION; 435 char adapter[] = INTERFACE_REGISTRY_LOCATION;
493 436
437 /* Registry is incredibly slow, wait a few seconds for it to refresh */
438 sleep (5);
439
494 /* We can obtain the PNP instance ID from our setupapi handle */ 440 /* We can obtain the PNP instance ID from our setupapi handle */
495 device_details.cbSize = sizeof (device_details); 441 device_details.cbSize = sizeof (device_details);
496 if (CR_SUCCESS != CM_Get_Device_ID_ExA (DeviceNode.DevInst, 442 if (CR_SUCCESS != CM_Get_Device_ID_ExA (DeviceNode.DevInst,
@@ -499,7 +445,7 @@ resolve_interface_name ()
499 0, //must be 0 445 0, //must be 0
500 NULL)) //hMachine, we are local 446 NULL)) //hMachine, we are local
501 return FALSE; 447 return FALSE;
502 448
503 /* Now we can use this ID to locate the correct networks interface in registry */ 449 /* Now we can use this ID to locate the correct networks interface in registry */
504 if (ERROR_SUCCESS != RegOpenKeyExA ( 450 if (ERROR_SUCCESS != RegOpenKeyExA (
505 HKEY_LOCAL_MACHINE, 451 HKEY_LOCAL_MACHINE,
@@ -521,8 +467,8 @@ resolve_interface_name ()
521 char pnpinstanceid_value[256]; 467 char pnpinstanceid_value[256];
522 char adaptername_name[] = "Name"; 468 char adaptername_name[] = "Name";
523 DWORD data_type; 469 DWORD data_type;
524 470
525 len = 256 * sizeof(char); 471 len = 256 * sizeof (char);
526 /* optain a subkey of {4D36E972-E325-11CE-BFC1-08002BE10318} */ 472 /* optain a subkey of {4D36E972-E325-11CE-BFC1-08002BE10318} */
527 status = RegEnumKeyExA ( 473 status = RegEnumKeyExA (
528 adapter_key_handle, 474 adapter_key_handle,
@@ -533,7 +479,7 @@ resolve_interface_name ()
533 NULL, 479 NULL,
534 NULL, 480 NULL,
535 NULL); 481 NULL);
536 482
537 /* this may fail due to one of two reasons: 483 /* this may fail due to one of two reasons:
538 * we are at the end of the list*/ 484 * we are at the end of the list*/
539 if (ERROR_NO_MORE_ITEMS == status) 485 if (ERROR_NO_MORE_ITEMS == status)
@@ -541,10 +487,10 @@ resolve_interface_name ()
541 // * we found a broken registry key, continue with the next key. 487 // * we found a broken registry key, continue with the next key.
542 if (ERROR_SUCCESS != status) 488 if (ERROR_SUCCESS != status)
543 goto cleanup; 489 goto cleanup;
544 490
545 /* prepare our new query string: */ 491 /* prepare our new query string: */
546 snprintf (query_key, 256, "%s\\%s\\Connection", 492 snprintf (query_key, 256, "%s\\%s\\Connection",
547 INTERFACE_REGISTRY_LOCATION, 493 adapter,
548 instance_key); 494 instance_key);
549 495
550 /* look inside instance_key\\Connection */ 496 /* look inside instance_key\\Connection */
@@ -594,15 +540,15 @@ resolve_interface_name ()
594 540
595 strncpy (device_guid, instance_key, 256); 541 strncpy (device_guid, instance_key, 256);
596 retval = TRUE; 542 retval = TRUE;
597 543
598cleanup: 544cleanup:
599 RegCloseKey (instance_key_handle); 545 RegCloseKey (instance_key_handle);
600 546
601 ++i; 547 ++i;
602 } 548 }
603 549
604 RegCloseKey (adapter_key_handle); 550 RegCloseKey (adapter_key_handle);
605 551
606 return retval; 552 return retval;
607} 553}
608 554
@@ -660,7 +606,7 @@ init_tun ()
660 errno = ENODEV; 606 errno = ENODEV;
661 return INVALID_HANDLE_VALUE; 607 return INVALID_HANDLE_VALUE;
662 } 608 }
663 609
664 /* Open Windows TAP-Windows adapter */ 610 /* Open Windows TAP-Windows adapter */
665 snprintf (device_path, sizeof (device_path), "%s%s%s", 611 snprintf (device_path, sizeof (device_path), "%s%s%s",
666 USERMODEDEVICEDIR, 612 USERMODEDEVICEDIR,
@@ -682,14 +628,14 @@ init_tun ()
682 fprintf (stderr, "CreateFile failed on TAP device: %s\n", device_path); 628 fprintf (stderr, "CreateFile failed on TAP device: %s\n", device_path);
683 return handle; 629 return handle;
684 } 630 }
685 631
686 /* get driver version info */ 632 /* get driver version info */
687 if (!check_tapw32_version (handle)) 633 if (!check_tapw32_version (handle))
688 { 634 {
689 CloseHandle (handle); 635 CloseHandle (handle);
690 return INVALID_HANDLE_VALUE; 636 return INVALID_HANDLE_VALUE;
691 } 637 }
692 638
693 /* TODO (opt?): get MTU-Size */ 639 /* TODO (opt?): get MTU-Size */
694 640
695 return handle; 641 return handle;
@@ -1104,7 +1050,7 @@ main (int argc, char **argv)
1104{ 1050{
1105 char hwid[LINE_LEN]; 1051 char hwid[LINE_LEN];
1106 HANDLE handle; 1052 HANDLE handle;
1107 int global_ret; 1053 int global_ret = 0;
1108 1054
1109 if (6 != argc) 1055 if (6 != argc)
1110 { 1056 {
@@ -1123,7 +1069,7 @@ main (int argc, char **argv)
1123 snprintf (secondary_hwid, LINE_LEN / 2, "%s-%d", 1069 snprintf (secondary_hwid, LINE_LEN / 2, "%s-%d",
1124 hwid, 1070 hwid,
1125 _getpid ()); 1071 _getpid ());
1126 1072
1127 if (INVALID_HANDLE_VALUE == (handle = init_tun ())) 1073 if (INVALID_HANDLE_VALUE == (handle = init_tun ()))
1128 { 1074 {
1129 fprintf (stderr, "Fatal: could not initialize virtual-interface %s with IPv6 %s/%s and IPv4 %s/%s\n", 1075 fprintf (stderr, "Fatal: could not initialize virtual-interface %s with IPv6 %s/%s and IPv4 %s/%s\n",
@@ -1132,7 +1078,8 @@ main (int argc, char **argv)
1132 argv[3], 1078 argv[3],
1133 argv[4], 1079 argv[4],
1134 argv[5]); 1080 argv[5]);
1135 return 1; 1081 global_ret = -1;
1082 goto cleanup;
1136 } 1083 }
1137 1084
1138 if (0 != strcmp (argv[2], "-")) 1085 if (0 != strcmp (argv[2], "-"))
@@ -1147,7 +1094,8 @@ main (int argc, char **argv)
1147 goto cleanup; 1094 goto cleanup;
1148 } 1095 }
1149 1096
1150 set_address6 (address, prefix_len); 1097 if (0 != (global_ret = set_address6 (address, prefix_len)))
1098 goto cleanup;
1151 } 1099 }
1152 1100
1153 if (0 != strcmp (argv[4], "-")) 1101 if (0 != strcmp (argv[4], "-"))
@@ -1155,13 +1103,14 @@ main (int argc, char **argv)
1155 const char *address = argv[4]; 1103 const char *address = argv[4];
1156 const char *mask = argv[5]; 1104 const char *mask = argv[5];
1157 1105
1158 set_address4 (address, mask); 1106 if (0 != (global_ret = set_address4 (address, mask)))
1107 goto cleanup;
1159 } 1108 }
1160 1109
1161 run (handle); 1110 run (handle);
1162 global_ret = 0; 1111 global_ret = 0;
1163cleanup: 1112cleanup:
1164 remove_interface ();
1165 1113
1114 remove_interface ();
1166 return global_ret; 1115 return global_ret;
1167} 1116}