aboutsummaryrefslogtreecommitdiff
path: root/src/exit/gnunet-helper-exit-windows.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/exit/gnunet-helper-exit-windows.c')
-rw-r--r--src/exit/gnunet-helper-exit-windows.c1160
1 files changed, 584 insertions, 576 deletions
diff --git a/src/exit/gnunet-helper-exit-windows.c b/src/exit/gnunet-helper-exit-windows.c
index 8bae7ca86..0ffd28148 100644
--- a/src/exit/gnunet-helper-exit-windows.c
+++ b/src/exit/gnunet-helper-exit-windows.c
@@ -11,7 +11,7 @@
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU Affero General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 17
@@ -66,7 +66,7 @@
66 66
67#if DEBUG 67#if DEBUG
68/* FIXME: define with varargs... */ 68/* FIXME: define with varargs... */
69#define LOG_DEBUG(msg) fprintf (stderr, "%s", msg); 69#define LOG_DEBUG(msg) fprintf(stderr, "%s", msg);
70#else 70#else
71#define LOG_DEBUG(msg) do {} while (0) 71#define LOG_DEBUG(msg) do {} while (0)
72#endif 72#endif
@@ -162,9 +162,7 @@ static char device_guid[256];
162/** 162/**
163 * Possible states of an IO facility. 163 * Possible states of an IO facility.
164 */ 164 */
165enum IO_State 165enum IO_State {
166{
167
168 /** 166 /**
169 * overlapped I/O is ready for work 167 * overlapped I/O is ready for work
170 */ 168 */
@@ -190,15 +188,13 @@ enum IO_State
190 * overlapped I/O has failed, stop processing 188 * overlapped I/O has failed, stop processing
191 */ 189 */
192 IOSTATE_FAILED 190 IOSTATE_FAILED
193
194}; 191};
195 192
196 193
197/** 194/**
198 * A IO Object + read/writebuffer + buffer-size for windows asynchronous IO handling 195 * A IO Object + read/writebuffer + buffer-size for windows asynchronous IO handling
199 */ 196 */
200struct io_facility 197struct io_facility {
201{
202 /** 198 /**
203 * The mode the state machine associated with this object is in. 199 * The mode the state machine associated with this object is in.
204 */ 200 */
@@ -243,12 +239,12 @@ struct io_facility
243/** 239/**
244 * ReOpenFile is only available as of XP SP2 and 2003 SP1 240 * ReOpenFile is only available as of XP SP2 and 2003 SP1
245 */ 241 */
246WINBASEAPI HANDLE WINAPI ReOpenFile (HANDLE, DWORD, DWORD, DWORD); 242WINBASEAPI HANDLE WINAPI ReOpenFile(HANDLE, DWORD, DWORD, DWORD);
247 243
248/** 244/**
249 * IsWow64Process definition for our is_win64, as this is a kernel function 245 * IsWow64Process definition for our is_win64, as this is a kernel function
250 */ 246 */
251typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); 247typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS)(HANDLE, PBOOL);
252 248
253 249
254/** 250/**
@@ -261,7 +257,7 @@ typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
261 * @param n the length of the string to copy, including its terminating null 257 * @param n the length of the string to copy, including its terminating null
262 * byte 258 * byte
263 * @return the length of the string that was copied, excluding the terminating 259 * @return the length of the string that was copied, excluding the terminating
264 * null byte 260 * null byte
265 */ 261 */
266size_t 262size_t
267GNUNET_strlcpy(char *dst, const char *src, size_t n) 263GNUNET_strlcpy(char *dst, const char *src, size_t n)
@@ -269,9 +265,9 @@ GNUNET_strlcpy(char *dst, const char *src, size_t n)
269 size_t ret; 265 size_t ret;
270 size_t slen; 266 size_t slen;
271 267
272 GNUNET_assert (0 != n); 268 GNUNET_assert(0 != n);
273 slen = strnlen (src, n - 1); 269 slen = strnlen(src, n - 1);
274 memcpy (dst, src, slen); 270 memcpy(dst, src, slen);
275 dst[slen] = '\0'; 271 dst[slen] = '\0';
276 return slen; 272 return slen;
277} 273}
@@ -283,7 +279,7 @@ GNUNET_strlcpy(char *dst, const char *src, size_t n)
283 * @return true if 279 * @return true if
284 */ 280 */
285BOOL 281BOOL
286is_win64 () 282is_win64()
287{ 283{
288#if defined(_WIN64) 284#if defined(_WIN64)
289 //this is a win64 binary, 285 //this is a win64 binary,
@@ -292,10 +288,10 @@ is_win64 ()
292 //this is a 32bit binary, and we need to check if we are running in WOW64 288 //this is a 32bit binary, and we need to check if we are running in WOW64
293 BOOL success = FALSE; 289 BOOL success = FALSE;
294 BOOL on_wow64 = FALSE; 290 BOOL on_wow64 = FALSE;
295 LPFN_ISWOW64PROCESS IsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress (GetModuleHandle ("kernel32"), "IsWow64Process"); 291 LPFN_ISWOW64PROCESS IsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle("kernel32"), "IsWow64Process");
296 292
297 if (NULL != IsWow64Process) 293 if (NULL != IsWow64Process)
298 success = IsWow64Process (GetCurrentProcess (), &on_wow64); 294 success = IsWow64Process(GetCurrentProcess(), &on_wow64);
299 295
300 return success && on_wow64; 296 return success && on_wow64;
301#endif 297#endif
@@ -309,22 +305,22 @@ is_win64 ()
309 * * EPIPE (could not read STDOUT) 305 * * EPIPE (could not read STDOUT)
310 */ 306 */
311static int 307static int
312execute_shellcommand (const char *command) 308execute_shellcommand(const char *command)
313{ 309{
314 FILE *pipe; 310 FILE *pipe;
315 311
316 if ( (NULL == command) || 312 if ((NULL == command) ||
317 (NULL == (pipe = _popen (command, "rt"))) ) 313 (NULL == (pipe = _popen(command, "rt"))))
318 return EINVAL; 314 return EINVAL;
319 315
320#if DEBUG 316#if DEBUG
321 fprintf (stderr, "DEBUG: Command output: \n"); 317 fprintf(stderr, "DEBUG: Command output: \n");
322 char output[LINE_LEN]; 318 char output[LINE_LEN];
323 while (NULL != fgets (output, sizeof (output), pipe)) 319 while (NULL != fgets(output, sizeof(output), pipe))
324 fprintf (stderr, "%s", output); 320 fprintf(stderr, "%s", output);
325#endif 321#endif
326 322
327 return _pclose (pipe); 323 return _pclose(pipe);
328} 324}
329 325
330 326
@@ -335,7 +331,7 @@ execute_shellcommand (const char *command)
335 * @param prefix_len the length of the network-prefix 331 * @param prefix_len the length of the network-prefix
336 */ 332 */
337static int 333static int
338set_address6 (const char *address, unsigned long prefix_len) 334set_address6(const char *address, unsigned long prefix_len)
339{ 335{
340 int ret = EINVAL; 336 int ret = EINVAL;
341 char command[LINE_LEN]; 337 char command[LINE_LEN];
@@ -344,29 +340,29 @@ set_address6 (const char *address, unsigned long prefix_len)
344 /* 340 /*
345 * parse the new address 341 * parse the new address
346 */ 342 */
347 memset (&sa6, 0, sizeof (struct sockaddr_in6)); 343 memset(&sa6, 0, sizeof(struct sockaddr_in6));
348 sa6.sin6_family = AF_INET6; 344 sa6.sin6_family = AF_INET6;
349 if (1 != inet_pton (AF_INET6, address, &sa6.sin6_addr.s6_addr)) 345 if (1 != inet_pton(AF_INET6, address, &sa6.sin6_addr.s6_addr))
350 { 346 {
351 fprintf (stderr, "ERROR: Failed to parse address `%s': %s\n", address, 347 fprintf(stderr, "ERROR: Failed to parse address `%s': %s\n", address,
352 strerror (errno)); 348 strerror(errno));
353 return -1; 349 return -1;
354 } 350 }
355 351
356 /* 352 /*
357 * prepare the command 353 * prepare the command
358 */ 354 */
359 snprintf (command, LINE_LEN, 355 snprintf(command, LINE_LEN,
360 "netsh interface ipv6 add address \"%s\" %s/%d store=active", 356 "netsh interface ipv6 add address \"%s\" %s/%d store=active",
361 device_visible_name, address, prefix_len); 357 device_visible_name, address, prefix_len);
362 /* 358 /*
363 * Set the address 359 * Set the address
364 */ 360 */
365 ret = execute_shellcommand (command); 361 ret = execute_shellcommand(command);
366 362
367 /* Did it work?*/ 363 /* Did it work?*/
368 if (0 != ret) 364 if (0 != ret)
369 fprintf (stderr, "FATAL: Setting IPv6 address failed: %s\n", strerror (ret)); 365 fprintf(stderr, "FATAL: Setting IPv6 address failed: %s\n", strerror(ret));
370 return ret; 366 return ret;
371} 367}
372 368
@@ -377,7 +373,7 @@ set_address6 (const char *address, unsigned long prefix_len)
377 * @param address the IPv4-Address 373 * @param address the IPv4-Address
378 */ 374 */
379static void 375static void
380remove_address6 (const char *address) 376remove_address6(const char *address)
381{ 377{
382 char command[LINE_LEN]; 378 char command[LINE_LEN];
383 int ret = EINVAL; 379 int ret = EINVAL;
@@ -386,17 +382,17 @@ remove_address6 (const char *address)
386 /* 382 /*
387 * prepare the command 383 * prepare the command
388 */ 384 */
389 snprintf (command, LINE_LEN, 385 snprintf(command, LINE_LEN,
390 "netsh interface ipv6 delete address \"%s\" store=persistent", 386 "netsh interface ipv6 delete address \"%s\" store=persistent",
391 device_visible_name); 387 device_visible_name);
392 /* 388 /*
393 * Set the address 389 * Set the address
394 */ 390 */
395 ret = execute_shellcommand (command); 391 ret = execute_shellcommand(command);
396 392
397 /* Did it work?*/ 393 /* Did it work?*/
398 if (0 != ret) 394 if (0 != ret)
399 fprintf (stderr, "FATAL: removing IPv6 address failed: %s\n", strerror (ret)); 395 fprintf(stderr, "FATAL: removing IPv6 address failed: %s\n", strerror(ret));
400} 396}
401 397
402 398
@@ -407,21 +403,22 @@ remove_address6 (const char *address)
407 * @param mask the netmask 403 * @param mask the netmask
408 */ 404 */
409static int 405static int
410set_address4 (const char *address, const char *mask) 406set_address4(const char *address, const char *mask)
411{ 407{
412 int ret = EINVAL; 408 int ret = EINVAL;
413 char command[LINE_LEN]; 409 char command[LINE_LEN];
414 410
415 struct sockaddr_in addr; 411 struct sockaddr_in addr;
412
416 addr.sin_family = AF_INET; 413 addr.sin_family = AF_INET;
417 414
418 /* 415 /*
419 * Parse the address 416 * Parse the address
420 */ 417 */
421 if (1 != inet_pton (AF_INET, address, &addr.sin_addr.s_addr)) 418 if (1 != inet_pton(AF_INET, address, &addr.sin_addr.s_addr))
422 { 419 {
423 fprintf (stderr, "ERROR: Failed to parse address `%s': %s\n", address, 420 fprintf(stderr, "ERROR: Failed to parse address `%s': %s\n", address,
424 strerror (errno)); 421 strerror(errno));
425 return -1; 422 return -1;
426 } 423 }
427 // Set Device to Subnet-Mode? 424 // Set Device to Subnet-Mode?
@@ -430,17 +427,17 @@ set_address4 (const char *address, const char *mask)
430 /* 427 /*
431 * prepare the command 428 * prepare the command
432 */ 429 */
433 snprintf (command, LINE_LEN, 430 snprintf(command, LINE_LEN,
434 "netsh interface ipv4 add address \"%s\" %s %s store=active", 431 "netsh interface ipv4 add address \"%s\" %s %s store=active",
435 device_visible_name, address, mask); 432 device_visible_name, address, mask);
436 /* 433 /*
437 * Set the address 434 * Set the address
438 */ 435 */
439 ret = execute_shellcommand (command); 436 ret = execute_shellcommand(command);
440 437
441 /* Did it work?*/ 438 /* Did it work?*/
442 if (0 != ret) 439 if (0 != ret)
443 fprintf (stderr, "FATAL: Setting IPv4 address failed: %s\n", strerror (ret)); 440 fprintf(stderr, "FATAL: Setting IPv4 address failed: %s\n", strerror(ret));
444 return ret; 441 return ret;
445} 442}
446 443
@@ -451,7 +448,7 @@ set_address4 (const char *address, const char *mask)
451 * @param address the IPv4-Address 448 * @param address the IPv4-Address
452 */ 449 */
453static void 450static void
454remove_address4 (const char *address) 451remove_address4(const char *address)
455{ 452{
456 char command[LINE_LEN]; 453 char command[LINE_LEN];
457 int ret = EINVAL; 454 int ret = EINVAL;
@@ -461,17 +458,17 @@ remove_address4 (const char *address)
461 /* 458 /*
462 * prepare the command 459 * prepare the command
463 */ 460 */
464 snprintf (command, LINE_LEN, 461 snprintf(command, LINE_LEN,
465 "netsh interface ipv4 delete address \"%s\" gateway=all store=persistent", 462 "netsh interface ipv4 delete address \"%s\" gateway=all store=persistent",
466 device_visible_name); 463 device_visible_name);
467 /* 464 /*
468 * Set the address 465 * Set the address
469 */ 466 */
470 ret = execute_shellcommand (command); 467 ret = execute_shellcommand(command);
471 468
472 /* Did it work?*/ 469 /* Did it work?*/
473 if (0 != ret) 470 if (0 != ret)
474 fprintf (stderr, "FATAL: removing IPv4 address failed: %s\n", strerror (ret)); 471 fprintf(stderr, "FATAL: removing IPv4 address failed: %s\n", strerror(ret));
475} 472}
476 473
477 474
@@ -481,7 +478,7 @@ remove_address4 (const char *address)
481 * @return: TRUE if setup was successful, else FALSE 478 * @return: TRUE if setup was successful, else FALSE
482 */ 479 */
483static BOOL 480static BOOL
484setup_interface () 481setup_interface()
485{ 482{
486 /* 483 /*
487 * where to find our inf-file. (+ the "full" path, after windows found") 484 * where to find our inf-file. (+ the "full" path, after windows found")
@@ -500,20 +497,20 @@ setup_interface ()
500 * Set the device's hardware ID and add it to a list. 497 * Set the device's hardware ID and add it to a list.
501 * This information will later on identify this device in registry. 498 * This information will later on identify this device in registry.
502 */ 499 */
503 str_length = GNUNET_strlcpy (hwidlist, 500 str_length = GNUNET_strlcpy(hwidlist,
504 HARDWARE_ID, 501 HARDWARE_ID,
505 sizeof (hwidlist)) + 1; 502 sizeof(hwidlist)) + 1;
506 /** 503 /**
507 * this is kind of over-complicated, but allows keeps things independent of 504 * this is kind of over-complicated, but allows keeps things independent of
508 * how the openvpn-hwid is actually stored. 505 * how the openvpn-hwid is actually stored.
509 * 506 *
510 * A HWID list is double-\0 terminated and \0 separated 507 * A HWID list is double-\0 terminated and \0 separated
511 */ 508 */
512 str_length = strlen (hwidlist) + 1; 509 str_length = strlen(hwidlist) + 1;
513 str_length += GNUNET_strlcpy (&hwidlist[str_length], 510 str_length += GNUNET_strlcpy(&hwidlist[str_length],
514 secondary_hwid, 511 secondary_hwid,
515 sizeof (hwidlist) - str_length) + 1; 512 sizeof(hwidlist) - str_length) + 1;
516 GNUNET_assert (str_length < sizeof (hwidlist)); 513 GNUNET_assert(str_length < sizeof(hwidlist));
517 hwidlist[str_length] = '\0'; 514 hwidlist[str_length] = '\0';
518 ++str_length; 515 ++str_length;
519 516
@@ -522,62 +519,62 @@ setup_interface ()
522 * find it. We need to pick the correct driver for win32/win64. 519 * find it. We need to pick the correct driver for win32/win64.
523 */ 520 */
524 if (is_win64()) 521 if (is_win64())
525 GetFullPathNameA (INF_FILE64, MAX_PATH, inf_file_path, &temp_inf_filename); 522 GetFullPathNameA(INF_FILE64, MAX_PATH, inf_file_path, &temp_inf_filename);
526 else 523 else
527 GetFullPathNameA (INF_FILE, MAX_PATH, inf_file_path, &temp_inf_filename); 524 GetFullPathNameA(INF_FILE, MAX_PATH, inf_file_path, &temp_inf_filename);
528 525
529 fprintf (stderr, "INFO: Located our driver's .inf file at %s\n", inf_file_path); 526 fprintf(stderr, "INFO: Located our driver's .inf file at %s\n", inf_file_path);
530 /** 527 /**
531 * Bootstrap our device info using the drivers inf-file 528 * Bootstrap our device info using the drivers inf-file
532 */ 529 */
533 if ( ! SetupDiGetINFClassA (inf_file_path, 530 if (!SetupDiGetINFClassA(inf_file_path,
534 &class_guid, 531 &class_guid,
535 class_name, sizeof (class_name) / sizeof (char), 532 class_name, sizeof(class_name) / sizeof(char),
536 NULL)) 533 NULL))
537 return FALSE; 534 return FALSE;
538 535
539 /** 536 /**
540 * Collect all the other needed information... 537 * Collect all the other needed information...
541 * let the system fill our this form 538 * let the system fill our this form
542 */ 539 */
543 DeviceInfo = SetupDiCreateDeviceInfoList (&class_guid, NULL); 540 DeviceInfo = SetupDiCreateDeviceInfoList(&class_guid, NULL);
544 if (DeviceInfo == INVALID_HANDLE_VALUE) 541 if (DeviceInfo == INVALID_HANDLE_VALUE)
545 return FALSE; 542 return FALSE;
546 543
547 DeviceNode.cbSize = sizeof (SP_DEVINFO_DATA); 544 DeviceNode.cbSize = sizeof(SP_DEVINFO_DATA);
548 if ( ! SetupDiCreateDeviceInfoA (DeviceInfo, 545 if (!SetupDiCreateDeviceInfoA(DeviceInfo,
549 class_name, 546 class_name,
550 &class_guid, 547 &class_guid,
551 NULL, 548 NULL,
552 0, 549 0,
553 DICD_GENERATE_ID, 550 DICD_GENERATE_ID,
554 &DeviceNode)) 551 &DeviceNode))
555 return FALSE; 552 return FALSE;
556 553
557 /* Deploy all the information collected into the registry */ 554 /* Deploy all the information collected into the registry */
558 if ( ! SetupDiSetDeviceRegistryPropertyA (DeviceInfo, 555 if (!SetupDiSetDeviceRegistryPropertyA(DeviceInfo,
559 &DeviceNode, 556 &DeviceNode,
560 SPDRP_HARDWAREID, 557 SPDRP_HARDWAREID,
561 (LPBYTE) hwidlist, 558 (LPBYTE)hwidlist,
562 str_length * sizeof (char))) 559 str_length * sizeof(char)))
563 return FALSE; 560 return FALSE;
564 561
565 /* Install our new class(=device) into the system */ 562 /* Install our new class(=device) into the system */
566 if ( ! SetupDiCallClassInstaller (DIF_REGISTERDEVICE, 563 if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE,
567 DeviceInfo, 564 DeviceInfo,
568 &DeviceNode)) 565 &DeviceNode))
569 return FALSE; 566 return FALSE;
570 567
571 /* This system call tends to take a while (several seconds!) on 568 /* This system call tends to take a while (several seconds!) on
572 "modern" Windoze systems */ 569 "modern" Windoze systems */
573 if ( ! UpdateDriverForPlugAndPlayDevicesA (NULL, 570 if (!UpdateDriverForPlugAndPlayDevicesA(NULL,
574 secondary_hwid, 571 secondary_hwid,
575 inf_file_path, 572 inf_file_path,
576 INSTALLFLAG_FORCE | INSTALLFLAG_NONINTERACTIVE, 573 INSTALLFLAG_FORCE | INSTALLFLAG_NONINTERACTIVE,
577 NULL)) //reboot required? NEVER! 574 NULL)) //reboot required? NEVER!
578 return FALSE; 575 return FALSE;
579 576
580 fprintf (stderr, "DEBUG: successfully created a network device\n"); 577 fprintf(stderr, "DEBUG: successfully created a network device\n");
581 return TRUE; 578 return TRUE;
582} 579}
583 580
@@ -589,14 +586,14 @@ setup_interface ()
589 * @return: TRUE if destruction was successful, else FALSE 586 * @return: TRUE if destruction was successful, else FALSE
590 */ 587 */
591static BOOL 588static BOOL
592remove_interface () 589remove_interface()
593{ 590{
594 SP_REMOVEDEVICE_PARAMS remove; 591 SP_REMOVEDEVICE_PARAMS remove;
595 592
596 if (INVALID_HANDLE_VALUE == DeviceInfo) 593 if (INVALID_HANDLE_VALUE == DeviceInfo)
597 return FALSE; 594 return FALSE;
598 595
599 remove.ClassInstallHeader.cbSize = sizeof (SP_CLASSINSTALL_HEADER); 596 remove.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
600 remove.HwProfile = 0; 597 remove.HwProfile = 0;
601 remove.Scope = DI_REMOVEDEVICE_GLOBAL; 598 remove.Scope = DI_REMOVEDEVICE_GLOBAL;
602 remove.ClassInstallHeader.InstallFunction = DIF_REMOVE; 599 remove.ClassInstallHeader.InstallFunction = DIF_REMOVE;
@@ -604,22 +601,22 @@ remove_interface ()
604 * 1. Prepare our existing device information set, and place the 601 * 1. Prepare our existing device information set, and place the
605 * uninstall related information into the structure 602 * uninstall related information into the structure
606 */ 603 */
607 if ( ! SetupDiSetClassInstallParamsA (DeviceInfo, 604 if (!SetupDiSetClassInstallParamsA(DeviceInfo,
608 (PSP_DEVINFO_DATA) & DeviceNode, 605 (PSP_DEVINFO_DATA)&DeviceNode,
609 &remove.ClassInstallHeader, 606 &remove.ClassInstallHeader,
610 sizeof (remove))) 607 sizeof(remove)))
611 return FALSE; 608 return FALSE;
612 /* 609 /*
613 * 2. Uninstall the virtual interface using the class installer 610 * 2. Uninstall the virtual interface using the class installer
614 */ 611 */
615 if ( ! SetupDiCallClassInstaller (DIF_REMOVE, 612 if (!SetupDiCallClassInstaller(DIF_REMOVE,
616 DeviceInfo, 613 DeviceInfo,
617 (PSP_DEVINFO_DATA) & DeviceNode)) 614 (PSP_DEVINFO_DATA)&DeviceNode))
618 return FALSE; 615 return FALSE;
619 616
620 SetupDiDestroyDeviceInfoList (DeviceInfo); 617 SetupDiDestroyDeviceInfoList(DeviceInfo);
621 618
622 fprintf (stderr, "DEBUG: removed interface successfully\n"); 619 fprintf(stderr, "DEBUG: removed interface successfully\n");
623 620
624 return TRUE; 621 return TRUE;
625} 622}
@@ -632,7 +629,7 @@ remove_interface ()
632 * @return: TRUE if we were able to lookup the interface's name, else FALSE 629 * @return: TRUE if we were able to lookup the interface's name, else FALSE
633 */ 630 */
634static BOOL 631static BOOL
635resolve_interface_name () 632resolve_interface_name()
636{ 633{
637 SP_DEVINFO_LIST_DETAIL_DATA device_details; 634 SP_DEVINFO_LIST_DETAIL_DATA device_details;
638 char pnp_instance_id [MAX_DEVICE_ID_LEN]; 635 char pnp_instance_id [MAX_DEVICE_ID_LEN];
@@ -645,29 +642,29 @@ resolve_interface_name ()
645 char adapter[] = INTERFACE_REGISTRY_LOCATION; 642 char adapter[] = INTERFACE_REGISTRY_LOCATION;
646 643
647 /* We can obtain the PNP instance ID from our setupapi handle */ 644 /* We can obtain the PNP instance ID from our setupapi handle */
648 device_details.cbSize = sizeof (device_details); 645 device_details.cbSize = sizeof(device_details);
649 if (CR_SUCCESS != CM_Get_Device_ID_ExA (DeviceNode.DevInst, 646 if (CR_SUCCESS != CM_Get_Device_ID_ExA(DeviceNode.DevInst,
650 (PCHAR) pnp_instance_id, 647 (PCHAR)pnp_instance_id,
651 MAX_DEVICE_ID_LEN, 648 MAX_DEVICE_ID_LEN,
652 0, //must be 0 649 0, //must be 0
653 NULL)) //hMachine, we are local 650 NULL)) //hMachine, we are local
654 return FALSE; 651 return FALSE;
655 652
656 fprintf (stderr, "DEBUG: Resolving interface name for network device %s\n",pnp_instance_id); 653 fprintf(stderr, "DEBUG: Resolving interface name for network device %s\n", pnp_instance_id);
657 654
658 /* Registry is incredibly slow, retry for up to 30 seconds to allow registry to refresh */ 655 /* Registry is incredibly slow, retry for up to 30 seconds to allow registry to refresh */
659 for (retrys = 0; retrys < 120 && !retval; retrys++) 656 for (retrys = 0; retrys < 120 && !retval; retrys++)
660 { 657 {
661 /* sleep for 250ms*/ 658 /* sleep for 250ms*/
662 Sleep (250); 659 Sleep(250);
663 660
664 /* Now we can use this ID to locate the correct networks interface in registry */ 661 /* Now we can use this ID to locate the correct networks interface in registry */
665 if (ERROR_SUCCESS != RegOpenKeyExA ( 662 if (ERROR_SUCCESS != RegOpenKeyExA(
666 HKEY_LOCAL_MACHINE, 663 HKEY_LOCAL_MACHINE,
667 adapter, 664 adapter,
668 0, 665 0,
669 KEY_READ, 666 KEY_READ,
670 &adapter_key_handle)) 667 &adapter_key_handle))
671 return FALSE; 668 return FALSE;
672 669
673 /* Of course there is a multitude of entries here, with arbitrary names, 670 /* Of course there is a multitude of entries here, with arbitrary names,
@@ -683,17 +680,17 @@ resolve_interface_name ()
683 char adaptername_name[] = "Name"; 680 char adaptername_name[] = "Name";
684 DWORD data_type; 681 DWORD data_type;
685 682
686 len = 256 * sizeof (char); 683 len = 256 * sizeof(char);
687 /* optain a subkey of {4D36E972-E325-11CE-BFC1-08002BE10318} */ 684 /* optain a subkey of {4D36E972-E325-11CE-BFC1-08002BE10318} */
688 status = RegEnumKeyExA ( 685 status = RegEnumKeyExA(
689 adapter_key_handle, 686 adapter_key_handle,
690 i, 687 i,
691 instance_key, 688 instance_key,
692 &len, 689 &len,
693 NULL, 690 NULL,
694 NULL, 691 NULL,
695 NULL, 692 NULL,
696 NULL); 693 NULL);
697 694
698 /* this may fail due to one of two reasons: 695 /* this may fail due to one of two reasons:
699 * we are at the end of the list*/ 696 * we are at the end of the list*/
@@ -704,44 +701,44 @@ resolve_interface_name ()
704 goto cleanup; 701 goto cleanup;
705 702
706 /* prepare our new query string: */ 703 /* prepare our new query string: */
707 snprintf (query_key, 256, "%s\\%s\\Connection", 704 snprintf(query_key, 256, "%s\\%s\\Connection",
708 adapter, 705 adapter,
709 instance_key); 706 instance_key);
710 707
711 /* look inside instance_key\\Connection */ 708 /* look inside instance_key\\Connection */
712 if (ERROR_SUCCESS != RegOpenKeyExA ( 709 if (ERROR_SUCCESS != RegOpenKeyExA(
713 HKEY_LOCAL_MACHINE, 710 HKEY_LOCAL_MACHINE,
714 query_key, 711 query_key,
715 0, 712 0,
716 KEY_READ, 713 KEY_READ,
717 &instance_key_handle)) 714 &instance_key_handle))
718 goto cleanup; 715 goto cleanup;
719 716
720 /* now, read our PnpInstanceID */ 717 /* now, read our PnpInstanceID */
721 len = sizeof (pnpinstanceid_value); 718 len = sizeof(pnpinstanceid_value);
722 status = RegQueryValueExA (instance_key_handle, 719 status = RegQueryValueExA(instance_key_handle,
723 pnpinstanceid_name, 720 pnpinstanceid_name,
724 NULL, //reserved, always NULL according to MSDN 721 NULL, //reserved, always NULL according to MSDN
725 &data_type, 722 &data_type,
726 (LPBYTE) pnpinstanceid_value, 723 (LPBYTE)pnpinstanceid_value,
727 &len); 724 &len);
728 725
729 if (status != ERROR_SUCCESS || data_type != REG_SZ) 726 if (status != ERROR_SUCCESS || data_type != REG_SZ)
730 goto cleanup; 727 goto cleanup;
731 728
732 /* compare the value we got to our devices PNPInstanceID*/ 729 /* compare the value we got to our devices PNPInstanceID*/
733 if (0 != strncmp (pnpinstanceid_value, pnp_instance_id, 730 if (0 != strncmp(pnpinstanceid_value, pnp_instance_id,
734 sizeof (pnpinstanceid_value) / sizeof (char))) 731 sizeof(pnpinstanceid_value) / sizeof(char)))
735 goto cleanup; 732 goto cleanup;
736 733
737 len = sizeof (device_visible_name); 734 len = sizeof(device_visible_name);
738 status = RegQueryValueExA ( 735 status = RegQueryValueExA(
739 instance_key_handle, 736 instance_key_handle,
740 adaptername_name, 737 adaptername_name,
741 NULL, //reserved, always NULL according to MSDN 738 NULL, //reserved, always NULL according to MSDN
742 &data_type, 739 &data_type,
743 (LPBYTE) device_visible_name, 740 (LPBYTE)device_visible_name,
744 &len); 741 &len);
745 742
746 if (status != ERROR_SUCCESS || data_type != REG_SZ) 743 if (status != ERROR_SUCCESS || data_type != REG_SZ)
747 goto cleanup; 744 goto cleanup;
@@ -750,17 +747,17 @@ resolve_interface_name ()
750 * we have successfully found OUR instance, 747 * we have successfully found OUR instance,
751 * save the device GUID before exiting 748 * save the device GUID before exiting
752 */ 749 */
753 GNUNET_strlcpy (device_guid, instance_key, sizeof (device_guid)); 750 GNUNET_strlcpy(device_guid, instance_key, sizeof(device_guid));
754 retval = TRUE; 751 retval = TRUE;
755 fprintf (stderr, "DEBUG: Interface Name lookup succeeded on retry %d, got \"%s\" %s\n", retrys, device_visible_name, device_guid); 752 fprintf(stderr, "DEBUG: Interface Name lookup succeeded on retry %d, got \"%s\" %s\n", retrys, device_visible_name, device_guid);
756 753
757cleanup: 754cleanup:
758 RegCloseKey (instance_key_handle); 755 RegCloseKey(instance_key_handle);
759 756
760 ++i; 757 ++i;
761 } 758 }
762 759
763 RegCloseKey (adapter_key_handle); 760 RegCloseKey(adapter_key_handle);
764 } 761 }
765 return retval; 762 return retval;
766} 763}
@@ -773,25 +770,27 @@ cleanup:
773 * @return TRUE if the version is sufficient, else FALSE 770 * @return TRUE if the version is sufficient, else FALSE
774 */ 771 */
775static BOOL 772static BOOL
776check_tapw32_version (HANDLE handle) 773check_tapw32_version(HANDLE handle)
777{ 774{
778 ULONG version[3]; 775 ULONG version[3];
779 DWORD len; 776 DWORD len;
780 memset (&(version), 0, sizeof (version));
781 777
782 if (DeviceIoControl (handle, TAP_WIN_IOCTL_GET_VERSION, 778 memset(&(version), 0, sizeof(version));
783 &version, sizeof (version), 779
784 &version, sizeof (version), &len, NULL)) 780 if (DeviceIoControl(handle, TAP_WIN_IOCTL_GET_VERSION,
785 fprintf (stderr, "INFO: TAP-Windows Driver Version %d.%d %s\n", 781 &version, sizeof(version),
786 (int) version[0], 782 &version, sizeof(version), &len, NULL))
787 (int) version[1], 783 fprintf(stderr, "INFO: TAP-Windows Driver Version %d.%d %s\n",
788 (version[2] ? "(DEBUG)" : "")); 784 (int)version[0],
785 (int)version[1],
786 (version[2] ? "(DEBUG)" : ""));
789 787
790 if ((version[0] != TAP_WIN_MIN_MAJOR) || 788 if ((version[0] != TAP_WIN_MIN_MAJOR) ||
791 (version[1] < TAP_WIN_MIN_MINOR )){ 789 (version[1] < TAP_WIN_MIN_MINOR))
792 fprintf (stderr, "FATAL: This version of gnunet requires a TAP-Windows driver that is at least version %d.%d\n", 790 {
793 TAP_WIN_MIN_MAJOR, 791 fprintf(stderr, "FATAL: This version of gnunet requires a TAP-Windows driver that is at least version %d.%d\n",
794 TAP_WIN_MIN_MINOR); 792 TAP_WIN_MIN_MAJOR,
793 TAP_WIN_MIN_MINOR);
795 return FALSE; 794 return FALSE;
796 } 795 }
797 796
@@ -805,55 +804,55 @@ check_tapw32_version (HANDLE handle)
805 * @return the fd to the tun or -1 on error 804 * @return the fd to the tun or -1 on error
806 */ 805 */
807static HANDLE 806static HANDLE
808init_tun () 807init_tun()
809{ 808{
810 char device_path[256]; 809 char device_path[256];
811 HANDLE handle; 810 HANDLE handle;
812 811
813 if (! setup_interface ()) 812 if (!setup_interface())
814 { 813 {
815 errno = ENODEV; 814 errno = ENODEV;
816 return INVALID_HANDLE_VALUE; 815 return INVALID_HANDLE_VALUE;
817 } 816 }
818 817
819 if (! resolve_interface_name ()) 818 if (!resolve_interface_name())
820 { 819 {
821 errno = ENODEV; 820 errno = ENODEV;
822 return INVALID_HANDLE_VALUE; 821 return INVALID_HANDLE_VALUE;
823 } 822 }
824 823
825 /* Open Windows TAP-Windows adapter */ 824 /* Open Windows TAP-Windows adapter */
826 snprintf (device_path, sizeof (device_path), "%s%s%s", 825 snprintf(device_path, sizeof(device_path), "%s%s%s",
827 USERMODEDEVICEDIR, 826 USERMODEDEVICEDIR,
828 device_guid, 827 device_guid,
829 TAP_WIN_SUFFIX); 828 TAP_WIN_SUFFIX);
830 829
831 handle = CreateFile ( 830 handle = CreateFile(
832 device_path, 831 device_path,
833 GENERIC_READ | GENERIC_WRITE, 832 GENERIC_READ | GENERIC_WRITE,
834 0, /* was: FILE_SHARE_READ */ 833 0, /* was: FILE_SHARE_READ */
835 0, 834 0,
836 OPEN_EXISTING, 835 OPEN_EXISTING,
837 FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 836 FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
838 0 837 0
839 ); 838 );
840 839
841 if (INVALID_HANDLE_VALUE == handle) 840 if (INVALID_HANDLE_VALUE == handle)
842 { 841 {
843 fprintf (stderr, "FATAL: CreateFile failed on TAP device: %s\n", device_path); 842 fprintf(stderr, "FATAL: CreateFile failed on TAP device: %s\n", device_path);
844 return handle; 843 return handle;
845 } 844 }
846 845
847 /* get driver version info */ 846 /* get driver version info */
848 if (! check_tapw32_version (handle)) 847 if (!check_tapw32_version(handle))
849 { 848 {
850 CloseHandle (handle); 849 CloseHandle(handle);
851 return INVALID_HANDLE_VALUE; 850 return INVALID_HANDLE_VALUE;
852 } 851 }
853 852
854 /* TODO (opt?): get MTU-Size */ 853 /* TODO (opt?): get MTU-Size */
855 854
856 fprintf (stderr, "DEBUG: successfully opened TAP device\n"); 855 fprintf(stderr, "DEBUG: successfully opened TAP device\n");
857 return handle; 856 return handle;
858} 857}
859 858
@@ -865,21 +864,22 @@ init_tun ()
865 * @return True if the operation succeeded, else false 864 * @return True if the operation succeeded, else false
866 */ 865 */
867static BOOL 866static BOOL
868tun_up (HANDLE handle) 867tun_up(HANDLE handle)
869{ 868{
870 ULONG status = TRUE; 869 ULONG status = TRUE;
871 DWORD len; 870 DWORD len;
872 if (! DeviceIoControl (handle, TAP_WIN_IOCTL_SET_MEDIA_STATUS, 871
873 &status, sizeof (status), 872 if (!DeviceIoControl(handle, TAP_WIN_IOCTL_SET_MEDIA_STATUS,
874 &status, sizeof (status), &len, NULL)) 873 &status, sizeof(status),
874 &status, sizeof(status), &len, NULL))
875 { 875 {
876 fprintf (stderr, "FATAL: TAP driver ignored request to UP interface (DeviceIoControl call)\n"); 876 fprintf(stderr, "FATAL: TAP driver ignored request to UP interface (DeviceIoControl call)\n");
877 return FALSE; 877 return FALSE;
878 } 878 }
879 879
880 /* Wait for the device to go UP, might take some time. */ 880 /* Wait for the device to go UP, might take some time. */
881 Sleep (TAP32_POSTUP_WAITTIME * 1000); 881 Sleep(TAP32_POSTUP_WAITTIME * 1000);
882 fprintf (stderr, "DEBUG: successfully set TAP device to UP\n"); 882 fprintf(stderr, "DEBUG: successfully set TAP device to UP\n");
883 883
884 return TRUE; 884 return TRUE;
885} 885}
@@ -911,8 +911,8 @@ tun_up (HANDLE handle)
911 * @return false if an event reset was impossible (OS error), else true 911 * @return false if an event reset was impossible (OS error), else true
912 */ 912 */
913static BOOL 913static BOOL
914attempt_read_tap (struct io_facility * input_facility, 914attempt_read_tap(struct io_facility * input_facility,
915 struct io_facility * output_facility) 915 struct io_facility * output_facility)
916{ 916{
917 struct GNUNET_MessageHeader * hdr; 917 struct GNUNET_MessageHeader * hdr;
918 unsigned short size; 918 unsigned short size;
@@ -920,137 +920,139 @@ attempt_read_tap (struct io_facility * input_facility,
920 switch (input_facility->facility_state) 920 switch (input_facility->facility_state)
921 { 921 {
922 case IOSTATE_READY: 922 case IOSTATE_READY:
923 { 923 {
924 if (! ResetEvent (input_facility->overlapped.hEvent)) 924 if (!ResetEvent(input_facility->overlapped.hEvent))
925 { 925 {
926 return FALSE;
927 }
928
929 input_facility->buffer_size = 0;
930
931 /* Check how the task is handled */
932 if (ReadFile(input_facility->handle,
933 input_facility->buffer,
934 sizeof(input_facility->buffer) - sizeof(struct GNUNET_MessageHeader),
935 &input_facility->buffer_size,
936 &input_facility->overlapped))
937 { /* async event processed immediately*/
938 /* reset event manually*/
939 if (!SetEvent(input_facility->overlapped.hEvent))
926 return FALSE; 940 return FALSE;
927 } 941
928 942 fprintf(stderr, "DEBUG: tap read succeeded immediately\n");
929 input_facility->buffer_size = 0; 943
930 944 /* we successfully read something from the TAP and now need to
931 /* Check how the task is handled */ 945 * send it our via STDOUT. Is that possible at the moment? */
932 if (ReadFile (input_facility->handle, 946 if ((IOSTATE_READY == output_facility->facility_state ||
933 input_facility->buffer, 947 IOSTATE_WAITING == output_facility->facility_state)
934 sizeof (input_facility->buffer) - sizeof (struct GNUNET_MessageHeader), 948 && (0 < input_facility->buffer_size))
935 &input_facility->buffer_size, 949 { /* hand over this buffers content and apply message header for gnunet */
936 &input_facility->overlapped)) 950 hdr = (struct GNUNET_MessageHeader *)output_facility->buffer;
937 {/* async event processed immediately*/ 951 size = input_facility->buffer_size + sizeof(struct GNUNET_MessageHeader);
938 952
939 /* reset event manually*/ 953 GNUNET_memcpy(output_facility->buffer + sizeof(struct GNUNET_MessageHeader),
940 if (! SetEvent (input_facility->overlapped.hEvent)) 954 input_facility->buffer,
941 return FALSE; 955 input_facility->buffer_size);
942 956
943 fprintf (stderr, "DEBUG: tap read succeeded immediately\n"); 957 output_facility->buffer_size = size;
944 958 hdr->size = htons(size);
945 /* we successfully read something from the TAP and now need to 959 hdr->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
946 * send it our via STDOUT. Is that possible at the moment? */ 960 output_facility->facility_state = IOSTATE_READY;
947 if ((IOSTATE_READY == output_facility->facility_state || 961 }
948 IOSTATE_WAITING == output_facility->facility_state) 962 else if (0 < input_facility->buffer_size)
949 && (0 < input_facility->buffer_size)) 963 /* If we have have read our buffer, wait for our write-partner*/
950 { /* hand over this buffers content and apply message header for gnunet */ 964 input_facility->facility_state = IOSTATE_WAITING;
951 hdr = (struct GNUNET_MessageHeader *) output_facility->buffer; 965 }
952 size = input_facility->buffer_size + sizeof (struct GNUNET_MessageHeader); 966 else /* operation was either queued or failed*/
953 967 {
954 GNUNET_memcpy (output_facility->buffer + sizeof (struct GNUNET_MessageHeader), 968 int err = GetLastError();
955 input_facility->buffer, 969 if (ERROR_IO_PENDING == err)
956 input_facility->buffer_size); 970 { /* operation queued */
957 971 input_facility->facility_state = IOSTATE_QUEUED;
958 output_facility->buffer_size = size; 972 }
959 hdr->size = htons (size); 973 else
960 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); 974 { /* error occurred, let the rest of the elements finish */
961 output_facility->facility_state = IOSTATE_READY; 975 input_facility->path_open = FALSE;
962 } 976 input_facility->facility_state = IOSTATE_FAILED;
963 else if (0 < input_facility->buffer_size) 977 if (IOSTATE_WAITING == output_facility->facility_state)
964 /* If we have have read our buffer, wait for our write-partner*/ 978 output_facility->path_open = FALSE;
965 input_facility->facility_state = IOSTATE_WAITING; 979
966 } 980 fprintf(stderr, "FATAL: Read from handle failed, allowing write to finish\n");
967 else /* operation was either queued or failed*/ 981 }
968 { 982 }
969 int err = GetLastError (); 983 }
970 if (ERROR_IO_PENDING == err)
971 { /* operation queued */
972 input_facility->facility_state = IOSTATE_QUEUED;
973 }
974 else
975 { /* error occurred, let the rest of the elements finish */
976 input_facility->path_open = FALSE;
977 input_facility->facility_state = IOSTATE_FAILED;
978 if (IOSTATE_WAITING == output_facility->facility_state)
979 output_facility->path_open = FALSE;
980
981 fprintf (stderr, "FATAL: Read from handle failed, allowing write to finish\n");
982 }
983 }
984 }
985 return TRUE; 984 return TRUE;
986 // We are queued and should check if the read has finished 985
986 // We are queued and should check if the read has finished
987 case IOSTATE_QUEUED: 987 case IOSTATE_QUEUED:
988 { 988 {
989 // there was an operation going on already, check if that has completed now. 989 // there was an operation going on already, check if that has completed now.
990 990
991 if (GetOverlappedResult (input_facility->handle, 991 if (GetOverlappedResult(input_facility->handle,
992 &input_facility->overlapped, 992 &input_facility->overlapped,
993 &input_facility->buffer_size, 993 &input_facility->buffer_size,
994 FALSE)) 994 FALSE))
995 {/* successful return for a queued operation */ 995 { /* successful return for a queued operation */
996 if (! ResetEvent (input_facility->overlapped.hEvent)) 996 if (!ResetEvent(input_facility->overlapped.hEvent))
997 return FALSE; 997 return FALSE;
998 998
999 fprintf (stderr, "DEBUG: tap read succeeded delayed\n"); 999 fprintf(stderr, "DEBUG: tap read succeeded delayed\n");
1000 1000
1001 /* we successfully read something from the TAP and now need to 1001 /* we successfully read something from the TAP and now need to
1002 * send it our via STDOUT. Is that possible at the moment? */ 1002 * send it our via STDOUT. Is that possible at the moment? */
1003 if ((IOSTATE_READY == output_facility->facility_state || 1003 if ((IOSTATE_READY == output_facility->facility_state ||
1004 IOSTATE_WAITING == output_facility->facility_state) 1004 IOSTATE_WAITING == output_facility->facility_state)
1005 && 0 < input_facility->buffer_size) 1005 && 0 < input_facility->buffer_size)
1006 { /* hand over this buffers content and apply message header for gnunet */ 1006 { /* hand over this buffers content and apply message header for gnunet */
1007 hdr = (struct GNUNET_MessageHeader *) output_facility->buffer; 1007 hdr = (struct GNUNET_MessageHeader *)output_facility->buffer;
1008 size = input_facility->buffer_size + sizeof (struct GNUNET_MessageHeader); 1008 size = input_facility->buffer_size + sizeof(struct GNUNET_MessageHeader);
1009 1009
1010 GNUNET_memcpy (output_facility->buffer + sizeof (struct GNUNET_MessageHeader), 1010 GNUNET_memcpy(output_facility->buffer + sizeof(struct GNUNET_MessageHeader),
1011 input_facility->buffer, 1011 input_facility->buffer,
1012 input_facility->buffer_size); 1012 input_facility->buffer_size);
1013 1013
1014 output_facility->buffer_size = size; 1014 output_facility->buffer_size = size;
1015 hdr->size = htons(size); 1015 hdr->size = htons(size);
1016 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); 1016 hdr->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
1017 output_facility->facility_state = IOSTATE_READY; 1017 output_facility->facility_state = IOSTATE_READY;
1018 input_facility->facility_state = IOSTATE_READY; 1018 input_facility->facility_state = IOSTATE_READY;
1019 } 1019 }
1020 else if (0 < input_facility->buffer_size) 1020 else if (0 < input_facility->buffer_size)
1021 { /* If we have have read our buffer, wait for our write-partner*/ 1021 { /* If we have have read our buffer, wait for our write-partner*/
1022 input_facility->facility_state = IOSTATE_WAITING; 1022 input_facility->facility_state = IOSTATE_WAITING;
1023 // TODO: shall we attempt to fill our buffer or should we wait for our write-partner to finish? 1023 // TODO: shall we attempt to fill our buffer or should we wait for our write-partner to finish?
1024 } 1024 }
1025 } 1025 }
1026 else 1026 else
1027 { /* operation still pending/queued or failed? */ 1027 { /* operation still pending/queued or failed? */
1028 int err = GetLastError (); 1028 int err = GetLastError();
1029 if ((ERROR_IO_INCOMPLETE != err) && (ERROR_IO_PENDING != err)) 1029 if ((ERROR_IO_INCOMPLETE != err) && (ERROR_IO_PENDING != err))
1030 { /* error occurred, let the rest of the elements finish */ 1030 { /* error occurred, let the rest of the elements finish */
1031 input_facility->path_open = FALSE; 1031 input_facility->path_open = FALSE;
1032 input_facility->facility_state = IOSTATE_FAILED; 1032 input_facility->facility_state = IOSTATE_FAILED;
1033 if (IOSTATE_WAITING == output_facility->facility_state) 1033 if (IOSTATE_WAITING == output_facility->facility_state)
1034 output_facility->path_open = FALSE; 1034 output_facility->path_open = FALSE;
1035 fprintf (stderr, "FATAL: Read from handle failed, allowing write to finish\n"); 1035 fprintf(stderr, "FATAL: Read from handle failed, allowing write to finish\n");
1036 } 1036 }
1037 } 1037 }
1038 } 1038 }
1039 return TRUE; 1039 return TRUE;
1040
1040 case IOSTATE_RESUME: 1041 case IOSTATE_RESUME:
1041 hdr = (struct GNUNET_MessageHeader *) output_facility->buffer; 1042 hdr = (struct GNUNET_MessageHeader *)output_facility->buffer;
1042 size = input_facility->buffer_size + sizeof (struct GNUNET_MessageHeader); 1043 size = input_facility->buffer_size + sizeof(struct GNUNET_MessageHeader);
1043 1044
1044 GNUNET_memcpy (output_facility->buffer + sizeof (struct GNUNET_MessageHeader), 1045 GNUNET_memcpy(output_facility->buffer + sizeof(struct GNUNET_MessageHeader),
1045 input_facility->buffer, 1046 input_facility->buffer,
1046 input_facility->buffer_size); 1047 input_facility->buffer_size);
1047 1048
1048 output_facility->buffer_size = size; 1049 output_facility->buffer_size = size;
1049 hdr->size = htons (size); 1050 hdr->size = htons(size);
1050 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); 1051 hdr->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
1051 output_facility->facility_state = IOSTATE_READY; 1052 output_facility->facility_state = IOSTATE_READY;
1052 input_facility->facility_state = IOSTATE_READY; 1053 input_facility->facility_state = IOSTATE_READY;
1053 return TRUE; 1054 return TRUE;
1055
1054 default: 1056 default:
1055 return TRUE; 1057 return TRUE;
1056 } 1058 }
@@ -1084,154 +1086,157 @@ attempt_read_tap (struct io_facility * input_facility,
1084 * @return false if an event reset was impossible (OS error), else true 1086 * @return false if an event reset was impossible (OS error), else true
1085 */ 1087 */
1086static BOOL 1088static BOOL
1087attempt_read_stdin (struct io_facility * input_facility, 1089attempt_read_stdin(struct io_facility * input_facility,
1088 struct io_facility * output_facility) 1090 struct io_facility * output_facility)
1089{ 1091{
1090 struct GNUNET_MessageHeader * hdr; 1092 struct GNUNET_MessageHeader * hdr;
1091 1093
1092 switch (input_facility->facility_state) 1094 switch (input_facility->facility_state)
1093 { 1095 {
1094 case IOSTATE_READY: 1096 case IOSTATE_READY:
1095 { 1097 {
1096 input_facility->buffer_size = 0; 1098 input_facility->buffer_size = 0;
1097 1099
1098partial_read_iostate_ready: 1100partial_read_iostate_ready:
1099 if (! ResetEvent (input_facility->overlapped.hEvent)) 1101 if (!ResetEvent(input_facility->overlapped.hEvent))
1100 return FALSE; 1102 return FALSE;
1101 1103
1102 /* Check how the task is handled */ 1104 /* Check how the task is handled */
1103 if (ReadFile (input_facility->handle, 1105 if (ReadFile(input_facility->handle,
1104 input_facility->buffer + input_facility->buffer_size, 1106 input_facility->buffer + input_facility->buffer_size,
1105 sizeof (input_facility->buffer) - input_facility->buffer_size, 1107 sizeof(input_facility->buffer) - input_facility->buffer_size,
1106 &input_facility->buffer_size_processed, 1108 &input_facility->buffer_size_processed,
1107 &input_facility->overlapped)) 1109 &input_facility->overlapped))
1108 {/* async event processed immediately*/ 1110 { /* async event processed immediately*/
1109 hdr = (struct GNUNET_MessageHeader *) input_facility->buffer; 1111 hdr = (struct GNUNET_MessageHeader *)input_facility->buffer;
1110 1112
1111 /* reset event manually*/ 1113 /* reset event manually*/
1112 if (!SetEvent (input_facility->overlapped.hEvent)) 1114 if (!SetEvent(input_facility->overlapped.hEvent))
1113 return FALSE; 1115 return FALSE;
1114 1116
1115 fprintf (stderr, "DEBUG: stdin read succeeded immediately\n"); 1117 fprintf(stderr, "DEBUG: stdin read succeeded immediately\n");
1116 input_facility->buffer_size += input_facility->buffer_size_processed; 1118 input_facility->buffer_size += input_facility->buffer_size_processed;
1117 1119
1118 if (ntohs (hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER || 1120 if (ntohs(hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER ||
1119 ntohs (hdr->size) > sizeof (input_facility->buffer)) 1121 ntohs(hdr->size) > sizeof(input_facility->buffer))
1120 { 1122 {
1121 fprintf (stderr, "WARNING: Protocol violation, got GNUnet Message type %h, size %h\n", ntohs (hdr->type), ntohs (hdr->size)); 1123 fprintf(stderr, "WARNING: Protocol violation, got GNUnet Message type %h, size %h\n", ntohs(hdr->type), ntohs(hdr->size));
1122 input_facility->facility_state = IOSTATE_READY; 1124 input_facility->facility_state = IOSTATE_READY;
1123 return TRUE; 1125 return TRUE;
1124 } 1126 }
1125 /* we got the a part of a packet */ 1127 /* we got the a part of a packet */
1126 if (ntohs (hdr->size) > input_facility->buffer_size) 1128 if (ntohs(hdr->size) > input_facility->buffer_size)
1127 goto partial_read_iostate_ready; 1129 goto partial_read_iostate_ready;
1128 1130
1129 /* have we read more than 0 bytes of payload? (sizeread > header)*/ 1131 /* have we read more than 0 bytes of payload? (sizeread > header)*/
1130 if (input_facility->buffer_size > sizeof (struct GNUNET_MessageHeader) && 1132 if (input_facility->buffer_size > sizeof(struct GNUNET_MessageHeader) &&
1131 ((IOSTATE_READY == output_facility->facility_state) || 1133 ((IOSTATE_READY == output_facility->facility_state) ||
1132 (IOSTATE_WAITING == output_facility->facility_state))) 1134 (IOSTATE_WAITING == output_facility->facility_state)))
1133 {/* we successfully read something from the TAP and now need to 1135 { /* we successfully read something from the TAP and now need to
1134 * send it our via STDOUT. Is that possible at the moment? */ 1136 * send it our via STDOUT. Is that possible at the moment? */
1135 1137 /* hand over this buffers content and strip gnunet message header */
1136 /* hand over this buffers content and strip gnunet message header */ 1138 GNUNET_memcpy(output_facility->buffer,
1137 GNUNET_memcpy (output_facility->buffer, 1139 input_facility->buffer + sizeof(struct GNUNET_MessageHeader),
1138 input_facility->buffer + sizeof (struct GNUNET_MessageHeader), 1140 input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader));
1139 input_facility->buffer_size - sizeof (struct GNUNET_MessageHeader)); 1141 output_facility->buffer_size = input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader);
1140 output_facility->buffer_size = input_facility->buffer_size - sizeof (struct GNUNET_MessageHeader); 1142 output_facility->facility_state = IOSTATE_READY;
1141 output_facility->facility_state = IOSTATE_READY;
1142 input_facility->facility_state = IOSTATE_READY;
1143 }
1144 else if (input_facility->buffer_size > sizeof (struct GNUNET_MessageHeader))
1145 /* If we have have read our buffer, wait for our write-partner*/
1146 input_facility->facility_state = IOSTATE_WAITING;
1147 else /* we read nothing */
1148 input_facility->facility_state = IOSTATE_READY; 1143 input_facility->facility_state = IOSTATE_READY;
1149 } 1144 }
1150 else /* operation was either queued or failed*/ 1145 else if (input_facility->buffer_size > sizeof(struct GNUNET_MessageHeader))
1151 { 1146 /* If we have have read our buffer, wait for our write-partner*/
1152 int err = GetLastError (); 1147 input_facility->facility_state = IOSTATE_WAITING;
1153 if (ERROR_IO_PENDING == err) /* operation queued */ 1148 else /* we read nothing */
1154 input_facility->facility_state = IOSTATE_QUEUED; 1149 input_facility->facility_state = IOSTATE_READY;
1155 else 1150 }
1156 { /* error occurred, let the rest of the elements finish */ 1151 else /* operation was either queued or failed*/
1157 input_facility->path_open = FALSE; 1152 {
1158 input_facility->facility_state = IOSTATE_FAILED; 1153 int err = GetLastError();
1159 if (IOSTATE_WAITING == output_facility->facility_state) 1154 if (ERROR_IO_PENDING == err) /* operation queued */
1160 output_facility->path_open = FALSE; 1155 input_facility->facility_state = IOSTATE_QUEUED;
1161 1156 else
1162 fprintf (stderr, "FATAL: Read from handle failed, allowing write to finish\n"); 1157 { /* error occurred, let the rest of the elements finish */
1163 } 1158 input_facility->path_open = FALSE;
1164 } 1159 input_facility->facility_state = IOSTATE_FAILED;
1165 } 1160 if (IOSTATE_WAITING == output_facility->facility_state)
1161 output_facility->path_open = FALSE;
1162
1163 fprintf(stderr, "FATAL: Read from handle failed, allowing write to finish\n");
1164 }
1165 }
1166 }
1166 return TRUE; 1167 return TRUE;
1167 // We are queued and should check if the read has finished 1168
1169 // We are queued and should check if the read has finished
1168 case IOSTATE_QUEUED: 1170 case IOSTATE_QUEUED:
1169 { 1171 {
1170 // there was an operation going on already, check if that has completed now. 1172 // there was an operation going on already, check if that has completed now.
1171 if (GetOverlappedResult (input_facility->handle, 1173 if (GetOverlappedResult(input_facility->handle,
1172 &input_facility->overlapped, 1174 &input_facility->overlapped,
1173 &input_facility->buffer_size_processed, 1175 &input_facility->buffer_size_processed,
1174 FALSE)) 1176 FALSE))
1175 {/* successful return for a queued operation */ 1177 { /* successful return for a queued operation */
1176 hdr = (struct GNUNET_MessageHeader *) input_facility->buffer; 1178 hdr = (struct GNUNET_MessageHeader *)input_facility->buffer;
1177 1179
1178 if (! ResetEvent (input_facility->overlapped.hEvent)) 1180 if (!ResetEvent(input_facility->overlapped.hEvent))
1179 return FALSE; 1181 return FALSE;
1180 1182
1181 fprintf (stderr, "DEBUG: stdin read succeeded delayed\n"); 1183 fprintf(stderr, "DEBUG: stdin read succeeded delayed\n");
1182 input_facility->buffer_size += input_facility->buffer_size_processed; 1184 input_facility->buffer_size += input_facility->buffer_size_processed;
1183 1185
1184 if ((ntohs (hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) || 1186 if ((ntohs(hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) ||
1185 (ntohs (hdr->size) > sizeof (input_facility->buffer))) 1187 (ntohs(hdr->size) > sizeof(input_facility->buffer)))
1186 { 1188 {
1187 fprintf (stderr, "WARNING: Protocol violation, got GNUnet Message type %h, size %h\n", ntohs (hdr->type), ntohs (hdr->size)); 1189 fprintf(stderr, "WARNING: Protocol violation, got GNUnet Message type %h, size %h\n", ntohs(hdr->type), ntohs(hdr->size));
1188 input_facility->facility_state = IOSTATE_READY;
1189 return TRUE;
1190 }
1191 /* we got the a part of a packet */
1192 if (ntohs (hdr->size) > input_facility->buffer_size );
1193 goto partial_read_iostate_ready;
1194
1195 /* we successfully read something from the TAP and now need to
1196 * send it our via STDOUT. Is that possible at the moment? */
1197 if ((IOSTATE_READY == output_facility->facility_state ||
1198 IOSTATE_WAITING == output_facility->facility_state)
1199 && input_facility->buffer_size > sizeof(struct GNUNET_MessageHeader))
1200 { /* hand over this buffers content and strip gnunet message header */
1201 GNUNET_memcpy (output_facility->buffer,
1202 input_facility->buffer + sizeof(struct GNUNET_MessageHeader),
1203 input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader));
1204 output_facility->buffer_size = input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader);
1205 output_facility->facility_state = IOSTATE_READY;
1206 input_facility->facility_state = IOSTATE_READY;
1207 }
1208 else if (input_facility->buffer_size > sizeof(struct GNUNET_MessageHeader))
1209 input_facility->facility_state = IOSTATE_WAITING;
1210 else
1211 input_facility->facility_state = IOSTATE_READY; 1190 input_facility->facility_state = IOSTATE_READY;
1212 } 1191 return TRUE;
1213 else 1192 }
1214 { /* operation still pending/queued or failed? */ 1193 /* we got the a part of a packet */
1215 int err = GetLastError (); 1194 if (ntohs(hdr->size) > input_facility->buffer_size)
1216 if ((ERROR_IO_INCOMPLETE != err) && (ERROR_IO_PENDING != err)) 1195 ;
1217 { /* error occurred, let the rest of the elements finish */ 1196 goto partial_read_iostate_ready;
1218 input_facility->path_open = FALSE; 1197
1219 input_facility->facility_state = IOSTATE_FAILED; 1198 /* we successfully read something from the TAP and now need to
1220 if (IOSTATE_WAITING == output_facility->facility_state) 1199 * send it our via STDOUT. Is that possible at the moment? */
1221 output_facility->path_open = FALSE; 1200 if ((IOSTATE_READY == output_facility->facility_state ||
1222 fprintf (stderr, "FATAL: Read from handle failed, allowing write to finish\n"); 1201 IOSTATE_WAITING == output_facility->facility_state)
1223 } 1202 && input_facility->buffer_size > sizeof(struct GNUNET_MessageHeader))
1224 } 1203 { /* hand over this buffers content and strip gnunet message header */
1225 } 1204 GNUNET_memcpy(output_facility->buffer,
1205 input_facility->buffer + sizeof(struct GNUNET_MessageHeader),
1206 input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader));
1207 output_facility->buffer_size = input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader);
1208 output_facility->facility_state = IOSTATE_READY;
1209 input_facility->facility_state = IOSTATE_READY;
1210 }
1211 else if (input_facility->buffer_size > sizeof(struct GNUNET_MessageHeader))
1212 input_facility->facility_state = IOSTATE_WAITING;
1213 else
1214 input_facility->facility_state = IOSTATE_READY;
1215 }
1216 else
1217 { /* operation still pending/queued or failed? */
1218 int err = GetLastError();
1219 if ((ERROR_IO_INCOMPLETE != err) && (ERROR_IO_PENDING != err))
1220 { /* error occurred, let the rest of the elements finish */
1221 input_facility->path_open = FALSE;
1222 input_facility->facility_state = IOSTATE_FAILED;
1223 if (IOSTATE_WAITING == output_facility->facility_state)
1224 output_facility->path_open = FALSE;
1225 fprintf(stderr, "FATAL: Read from handle failed, allowing write to finish\n");
1226 }
1227 }
1228 }
1226 return TRUE; 1229 return TRUE;
1230
1227 case IOSTATE_RESUME: /* Our buffer was filled already but our write facility was busy. */ 1231 case IOSTATE_RESUME: /* Our buffer was filled already but our write facility was busy. */
1228 GNUNET_memcpy (output_facility->buffer, 1232 GNUNET_memcpy(output_facility->buffer,
1229 input_facility->buffer + sizeof (struct GNUNET_MessageHeader), 1233 input_facility->buffer + sizeof(struct GNUNET_MessageHeader),
1230 input_facility->buffer_size - sizeof (struct GNUNET_MessageHeader)); 1234 input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader));
1231 output_facility->buffer_size = input_facility->buffer_size - sizeof (struct GNUNET_MessageHeader); 1235 output_facility->buffer_size = input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader);
1232 output_facility->facility_state = IOSTATE_READY; 1236 output_facility->facility_state = IOSTATE_READY;
1233 input_facility->facility_state = IOSTATE_READY; 1237 input_facility->facility_state = IOSTATE_READY;
1234 return TRUE; 1238 return TRUE;
1239
1235 default: 1240 default:
1236 return TRUE; 1241 return TRUE;
1237 } 1242 }
@@ -1248,8 +1253,8 @@ partial_read_iostate_ready:
1248 * @return false if an event reset was impossible (OS error), else true 1253 * @return false if an event reset was impossible (OS error), else true
1249 */ 1254 */
1250static BOOL 1255static BOOL
1251attempt_write (struct io_facility * output_facility, 1256attempt_write(struct io_facility * output_facility,
1252 struct io_facility * input_facility) 1257 struct io_facility * input_facility)
1253{ 1258{
1254 switch (output_facility->facility_state) 1259 switch (output_facility->facility_state)
1255 { 1260 {
@@ -1257,22 +1262,21 @@ attempt_write (struct io_facility * output_facility,
1257 output_facility->buffer_size_written = 0; 1262 output_facility->buffer_size_written = 0;
1258 1263
1259continue_partial_write: 1264continue_partial_write:
1260 if (! ResetEvent (output_facility->overlapped.hEvent)) 1265 if (!ResetEvent(output_facility->overlapped.hEvent))
1261 return FALSE; 1266 return FALSE;
1262 1267
1263 /* Check how the task was handled */ 1268 /* Check how the task was handled */
1264 if (WriteFile (output_facility->handle, 1269 if (WriteFile(output_facility->handle,
1265 output_facility->buffer + output_facility->buffer_size_written, 1270 output_facility->buffer + output_facility->buffer_size_written,
1266 output_facility->buffer_size - output_facility->buffer_size_written, 1271 output_facility->buffer_size - output_facility->buffer_size_written,
1267 &output_facility->buffer_size_processed, 1272 &output_facility->buffer_size_processed,
1268 &output_facility->overlapped)) 1273 &output_facility->overlapped))
1269 {/* async event processed immediately*/ 1274 {/* async event processed immediately*/
1270 1275 fprintf(stderr, "DEBUG: write succeeded immediately\n");
1271 fprintf (stderr, "DEBUG: write succeeded immediately\n");
1272 output_facility->buffer_size_written += output_facility->buffer_size_processed; 1276 output_facility->buffer_size_written += output_facility->buffer_size_processed;
1273 1277
1274 /* reset event manually*/ 1278 /* reset event manually*/
1275 if (! SetEvent (output_facility->overlapped.hEvent)) 1279 if (!SetEvent(output_facility->overlapped.hEvent))
1276 return FALSE; 1280 return FALSE;
1277 1281
1278 /* partial write */ 1282 /* partial write */
@@ -1290,7 +1294,7 @@ continue_partial_write:
1290 } 1294 }
1291 else /* operation was either queued or failed*/ 1295 else /* operation was either queued or failed*/
1292 { 1296 {
1293 int err = GetLastError (); 1297 int err = GetLastError();
1294 if (ERROR_IO_PENDING == err) 1298 if (ERROR_IO_PENDING == err)
1295 { /* operation queued */ 1299 { /* operation queued */
1296 output_facility->facility_state = IOSTATE_QUEUED; 1300 output_facility->facility_state = IOSTATE_QUEUED;
@@ -1299,22 +1303,23 @@ continue_partial_write:
1299 { /* error occurred, close this path */ 1303 { /* error occurred, close this path */
1300 output_facility->path_open = FALSE; 1304 output_facility->path_open = FALSE;
1301 output_facility->facility_state = IOSTATE_FAILED; 1305 output_facility->facility_state = IOSTATE_FAILED;
1302 fprintf (stderr, "FATAL: Write to handle failed, exiting\n"); 1306 fprintf(stderr, "FATAL: Write to handle failed, exiting\n");
1303 } 1307 }
1304 } 1308 }
1305 return TRUE; 1309 return TRUE;
1310
1306 case IOSTATE_QUEUED: 1311 case IOSTATE_QUEUED:
1307 // there was an operation going on already, check if that has completed now. 1312 // there was an operation going on already, check if that has completed now.
1308 1313
1309 if (GetOverlappedResult (output_facility->handle, 1314 if (GetOverlappedResult(output_facility->handle,
1310 &output_facility->overlapped, 1315 &output_facility->overlapped,
1311 &output_facility->buffer_size_processed, 1316 &output_facility->buffer_size_processed,
1312 FALSE)) 1317 FALSE))
1313 {/* successful return for a queued operation */ 1318 {/* successful return for a queued operation */
1314 if (! ResetEvent (output_facility->overlapped.hEvent)) 1319 if (!ResetEvent(output_facility->overlapped.hEvent))
1315 return FALSE; 1320 return FALSE;
1316 1321
1317 fprintf (stderr, "DEBUG: write succeeded delayed\n"); 1322 fprintf(stderr, "DEBUG: write succeeded delayed\n");
1318 output_facility->buffer_size_written += output_facility->buffer_size_processed; 1323 output_facility->buffer_size_written += output_facility->buffer_size_processed;
1319 1324
1320 /* partial write */ 1325 /* partial write */
@@ -1332,14 +1337,15 @@ continue_partial_write:
1332 } 1337 }
1333 else 1338 else
1334 { /* operation still pending/queued or failed? */ 1339 { /* operation still pending/queued or failed? */
1335 int err = GetLastError (); 1340 int err = GetLastError();
1336 if ((ERROR_IO_INCOMPLETE != err) && (ERROR_IO_PENDING != err)) 1341 if ((ERROR_IO_INCOMPLETE != err) && (ERROR_IO_PENDING != err))
1337 { /* error occurred, close this path */ 1342 { /* error occurred, close this path */
1338 output_facility->path_open = FALSE; 1343 output_facility->path_open = FALSE;
1339 output_facility->facility_state = IOSTATE_FAILED; 1344 output_facility->facility_state = IOSTATE_FAILED;
1340 fprintf (stderr, "FATAL: Write to handle failed, exiting\n"); 1345 fprintf(stderr, "FATAL: Write to handle failed, exiting\n");
1341 } 1346 }
1342 } 1347 }
1348
1343 default: 1349 default:
1344 return TRUE; 1350 return TRUE;
1345 } 1351 }
@@ -1355,15 +1361,15 @@ continue_partial_write:
1355 * @return true on success, else false 1361 * @return true on success, else false
1356 */ 1362 */
1357static BOOL 1363static BOOL
1358initialize_io_facility (struct io_facility * elem, 1364initialize_io_facility(struct io_facility * elem,
1359 int initial_state, 1365 int initial_state,
1360 BOOL signaled) 1366 BOOL signaled)
1361{ 1367{
1362 elem->path_open = TRUE; 1368 elem->path_open = TRUE;
1363 elem->handle = INVALID_HANDLE_VALUE; 1369 elem->handle = INVALID_HANDLE_VALUE;
1364 elem->facility_state = initial_state; 1370 elem->facility_state = initial_state;
1365 elem->buffer_size = 0; 1371 elem->buffer_size = 0;
1366 elem->overlapped.hEvent = CreateEvent (NULL, TRUE, signaled, NULL); 1372 elem->overlapped.hEvent = CreateEvent(NULL, TRUE, signaled, NULL);
1367 if (NULL == elem->overlapped.hEvent) 1373 if (NULL == elem->overlapped.hEvent)
1368 return FALSE; 1374 return FALSE;
1369 1375
@@ -1377,7 +1383,7 @@ initialize_io_facility (struct io_facility * elem,
1377 * @param tap_handle device handle for interacting with the Virtual interface 1383 * @param tap_handle device handle for interacting with the Virtual interface
1378 */ 1384 */
1379static void 1385static void
1380run (HANDLE tap_handle) 1386run(HANDLE tap_handle)
1381{ 1387{
1382 /* IO-Facility for reading from our virtual interface */ 1388 /* IO-Facility for reading from our virtual interface */
1383 struct io_facility tap_read; 1389 struct io_facility tap_read;
@@ -1388,8 +1394,8 @@ run (HANDLE tap_handle)
1388 /* IO-Facility for writing to stdout */ 1394 /* IO-Facility for writing to stdout */
1389 struct io_facility std_out; 1395 struct io_facility std_out;
1390 1396
1391 HANDLE parent_std_in_handle = GetStdHandle (STD_INPUT_HANDLE); 1397 HANDLE parent_std_in_handle = GetStdHandle(STD_INPUT_HANDLE);
1392 HANDLE parent_std_out_handle = GetStdHandle (STD_OUTPUT_HANDLE); 1398 HANDLE parent_std_out_handle = GetStdHandle(STD_OUTPUT_HANDLE);
1393 1399
1394 /* tun up: */ 1400 /* tun up: */
1395 /* we do this HERE and not beforehand (in init_tun()), in contrast to openvpn 1401 /* we do this HERE and not beforehand (in init_tun()), in contrast to openvpn
@@ -1398,14 +1404,14 @@ run (HANDLE tap_handle)
1398 * DHCP and such are all features we will never use in gnunet afaik. 1404 * DHCP and such are all features we will never use in gnunet afaik.
1399 * But for openvpn those are essential. 1405 * But for openvpn those are essential.
1400 */ 1406 */
1401 if ((privilege_testing) || (! tun_up (tap_handle) )) 1407 if ((privilege_testing) || (!tun_up(tap_handle)))
1402 goto teardown_final; 1408 goto teardown_final;
1403 1409
1404 /* Initialize our overlapped IO structures*/ 1410 /* Initialize our overlapped IO structures*/
1405 if (! (initialize_io_facility (&tap_read, IOSTATE_READY, FALSE) 1411 if (!(initialize_io_facility(&tap_read, IOSTATE_READY, FALSE)
1406 && initialize_io_facility (&tap_write, IOSTATE_WAITING, TRUE) 1412 && initialize_io_facility(&tap_write, IOSTATE_WAITING, TRUE)
1407 && initialize_io_facility (&std_in, IOSTATE_READY, FALSE) 1413 && initialize_io_facility(&std_in, IOSTATE_READY, FALSE)
1408 && initialize_io_facility (&std_out, IOSTATE_WAITING, TRUE))) 1414 && initialize_io_facility(&std_out, IOSTATE_WAITING, TRUE)))
1409 goto teardown_final; 1415 goto teardown_final;
1410 1416
1411 /* Handles for STDIN and STDOUT */ 1417 /* Handles for STDIN and STDOUT */
@@ -1416,75 +1422,74 @@ run (HANDLE tap_handle)
1416 /* Debug output to console STDIN/STDOUT*/ 1422 /* Debug output to console STDIN/STDOUT*/
1417 std_in.handle = parent_std_in_handle; 1423 std_in.handle = parent_std_in_handle;
1418 std_out.handle = parent_std_out_handle; 1424 std_out.handle = parent_std_out_handle;
1419
1420#else 1425#else
1421 fprintf (stderr, "DEBUG: reopening stdin/out for overlapped IO\n"); 1426 fprintf(stderr, "DEBUG: reopening stdin/out for overlapped IO\n");
1422 /* 1427 /*
1423 * Find out the types of our handles. 1428 * Find out the types of our handles.
1424 * This part is a problem, because in windows we need to handle files, 1429 * This part is a problem, because in windows we need to handle files,
1425 * pipes and the console differently. 1430 * pipes and the console differently.
1426 */ 1431 */
1427 if ((FILE_TYPE_PIPE != GetFileType (parent_std_in_handle)) || 1432 if ((FILE_TYPE_PIPE != GetFileType(parent_std_in_handle)) ||
1428 (FILE_TYPE_PIPE != GetFileType (parent_std_out_handle))) 1433 (FILE_TYPE_PIPE != GetFileType(parent_std_out_handle)))
1429 { 1434 {
1430 fprintf (stderr, "ERROR: stdin/stdout must be named pipes\n"); 1435 fprintf(stderr, "ERROR: stdin/stdout must be named pipes\n");
1431 goto teardown; 1436 goto teardown;
1432 } 1437 }
1433 1438
1434 std_in.handle = ReOpenFile (parent_std_in_handle, 1439 std_in.handle = ReOpenFile(parent_std_in_handle,
1435 GENERIC_READ, 1440 GENERIC_READ,
1436 FILE_SHARE_WRITE | FILE_SHARE_READ, 1441 FILE_SHARE_WRITE | FILE_SHARE_READ,
1437 FILE_FLAG_OVERLAPPED); 1442 FILE_FLAG_OVERLAPPED);
1438 1443
1439 if (INVALID_HANDLE_VALUE == std_in.handle) 1444 if (INVALID_HANDLE_VALUE == std_in.handle)
1440 { 1445 {
1441 fprintf (stderr, "FATAL: Could not reopen stdin for in overlapped mode, has to be a named pipe\n"); 1446 fprintf(stderr, "FATAL: Could not reopen stdin for in overlapped mode, has to be a named pipe\n");
1442 goto teardown; 1447 goto teardown;
1443 } 1448 }
1444 1449
1445 std_out.handle = ReOpenFile (parent_std_out_handle, 1450 std_out.handle = ReOpenFile(parent_std_out_handle,
1446 GENERIC_WRITE, 1451 GENERIC_WRITE,
1447 FILE_SHARE_READ, 1452 FILE_SHARE_READ,
1448 FILE_FLAG_OVERLAPPED); 1453 FILE_FLAG_OVERLAPPED);
1449 1454
1450 if (INVALID_HANDLE_VALUE == std_out.handle) 1455 if (INVALID_HANDLE_VALUE == std_out.handle)
1451 { 1456 {
1452 fprintf (stderr, "FATAL: Could not reopen stdout for in overlapped mode, has to be a named pipe\n"); 1457 fprintf(stderr, "FATAL: Could not reopen stdout for in overlapped mode, has to be a named pipe\n");
1453 goto teardown; 1458 goto teardown;
1454 } 1459 }
1455#endif 1460#endif
1456 1461
1457 fprintf (stderr, "DEBUG: mainloop has begun\n"); 1462 fprintf(stderr, "DEBUG: mainloop has begun\n");
1458 1463
1459 while (std_out.path_open || tap_write.path_open) 1464 while (std_out.path_open || tap_write.path_open)
1460 { 1465 {
1461 /* perform READ from stdin if possible */ 1466 /* perform READ from stdin if possible */
1462 if (std_in.path_open && (! attempt_read_stdin (&std_in, &tap_write))) 1467 if (std_in.path_open && (!attempt_read_stdin(&std_in, &tap_write)))
1463 break; 1468 break;
1464 1469
1465 /* perform READ from tap if possible */ 1470 /* perform READ from tap if possible */
1466 if (tap_read.path_open && (! attempt_read_tap (&tap_read, &std_out))) 1471 if (tap_read.path_open && (!attempt_read_tap(&tap_read, &std_out)))
1467 break; 1472 break;
1468 1473
1469 /* perform WRITE to tap if possible */ 1474 /* perform WRITE to tap if possible */
1470 if (tap_write.path_open && (! attempt_write (&tap_write, &std_in))) 1475 if (tap_write.path_open && (!attempt_write(&tap_write, &std_in)))
1471 break; 1476 break;
1472 1477
1473 /* perform WRITE to STDOUT if possible */ 1478 /* perform WRITE to STDOUT if possible */
1474 if (std_out.path_open && (! attempt_write (&std_out, &tap_read))) 1479 if (std_out.path_open && (!attempt_write(&std_out, &tap_read)))
1475 break; 1480 break;
1476 } 1481 }
1477 fprintf (stderr, "DEBUG: teardown initiated\n"); 1482 fprintf(stderr, "DEBUG: teardown initiated\n");
1478 1483
1479teardown: 1484teardown:
1480 1485
1481 CancelIo (tap_handle); 1486 CancelIo(tap_handle);
1482 CancelIo (std_in.handle); 1487 CancelIo(std_in.handle);
1483 CancelIo (std_out.handle); 1488 CancelIo(std_out.handle);
1484 1489
1485teardown_final: 1490teardown_final:
1486 1491
1487 CloseHandle (tap_handle); 1492 CloseHandle(tap_handle);
1488} 1493}
1489 1494
1490 1495
@@ -1501,7 +1506,7 @@ teardown_final:
1501 * 6: IPv4 netmask ("255.255.0.0") [ignored if #4 is "-"] 1506 * 6: IPv4 netmask ("255.255.0.0") [ignored if #4 is "-"]
1502 */ 1507 */
1503int 1508int
1504main (int argc, char **argv) 1509main(int argc, char **argv)
1505{ 1510{
1506 char hwid[LINE_LEN]; 1511 char hwid[LINE_LEN];
1507 HANDLE handle; 1512 HANDLE handle;
@@ -1511,99 +1516,100 @@ main (int argc, char **argv)
1511 BOOL have_ip6 = FALSE; 1516 BOOL have_ip6 = FALSE;
1512 BOOL have_nat44 = FALSE; 1517 BOOL have_nat44 = FALSE;
1513 1518
1514 if ( (1 < argc) && (0 != strcmp (argv[1], "-d"))){ 1519 if ((1 < argc) && (0 != strcmp(argv[1], "-d")))
1520 {
1515 privilege_testing = TRUE; 1521 privilege_testing = TRUE;
1516 fprintf (stderr, 1522 fprintf(stderr,
1517 "%s", 1523 "%s",
1518 "DEBUG: Running binary in privilege testing mode."); 1524 "DEBUG: Running binary in privilege testing mode.");
1519 argv++; 1525 argv++;
1520 argc--; 1526 argc--;
1521 } 1527 }
1522 1528
1523 if (6 != argc) 1529 if (6 != argc)
1524 { 1530 {
1525 fprintf (stderr, 1531 fprintf(stderr,
1526 "%s", 1532 "%s",
1527 "FATAL: must supply 6 arguments\nUsage:\ngnunet-helper-exit [-d] <if name prefix> <uplink-interface name> <address6 or \"-\"> <netbits6> <address4 or \"-\"> <netmask4>\n"); 1533 "FATAL: must supply 6 arguments\nUsage:\ngnunet-helper-exit [-d] <if name prefix> <uplink-interface name> <address6 or \"-\"> <netbits6> <address4 or \"-\"> <netmask4>\n");
1528 return 1; 1534 return 1;
1529 } 1535 }
1530 1536
1531 GNUNET_strlcpy (hwid, argv[1], sizeof (hwid)); 1537 GNUNET_strlcpy(hwid, argv[1], sizeof(hwid));
1532 1538
1533 /* 1539 /*
1534 * We use our PID for finding/resolving the control-panel name of our virtual 1540 * We use our PID for finding/resolving the control-panel name of our virtual
1535 * device. PIDs are (of course) unique at runtime, thus we can safely use it 1541 * device. PIDs are (of course) unique at runtime, thus we can safely use it
1536 * as additional hardware-id for our device. 1542 * as additional hardware-id for our device.
1537 */ 1543 */
1538 snprintf (secondary_hwid, LINE_LEN / 2, "%s-%d", 1544 snprintf(secondary_hwid, LINE_LEN / 2, "%s-%d",
1539 hwid, 1545 hwid,
1540 _getpid ()); 1546 _getpid());
1541 1547
1542 if (INVALID_HANDLE_VALUE == (handle = init_tun ())) 1548 if (INVALID_HANDLE_VALUE == (handle = init_tun()))
1543 { 1549 {
1544 fprintf (stderr, "FATAL: could not initialize virtual-interface %s with IPv6 %s/%s and IPv4 %s/%s\n", 1550 fprintf(stderr, "FATAL: could not initialize virtual-interface %s with IPv6 %s/%s and IPv4 %s/%s\n",
1545 hwid, 1551 hwid,
1546 argv[3], 1552 argv[3],
1547 argv[4], 1553 argv[4],
1548 argv[5], 1554 argv[5],
1549 argv[6]); 1555 argv[6]);
1550 global_ret = -1; 1556 global_ret = -1;
1551 goto cleanup; 1557 goto cleanup;
1552 } 1558 }
1553 1559
1554 fprintf (stderr, "DEBUG: Setting IPs, if needed\n"); 1560 fprintf(stderr, "DEBUG: Setting IPs, if needed\n");
1555 if (0 != strcmp (argv[3], "-")) 1561 if (0 != strcmp(argv[3], "-"))
1556 { 1562 {
1557 char command[LINE_LEN]; 1563 char command[LINE_LEN];
1558 const char *address = argv[3]; 1564 const char *address = argv[3];
1559 long prefix_len = atol (argv[4]); 1565 long prefix_len = atol(argv[4]);
1560 1566
1561 if ((prefix_len < 1) || (prefix_len > 127)) 1567 if ((prefix_len < 1) || (prefix_len > 127))
1562 { 1568 {
1563 fprintf (stderr, "FATAL: ipv6 prefix_len out of range\n"); 1569 fprintf(stderr, "FATAL: ipv6 prefix_len out of range\n");
1564 global_ret = -1; 1570 global_ret = -1;
1565 goto cleanup; 1571 goto cleanup;
1566 } 1572 }
1567 1573
1568 fprintf (stderr, "DEBUG: Setting IP6 address: %s/%d\n", address, prefix_len); 1574 fprintf(stderr, "DEBUG: Setting IP6 address: %s/%d\n", address, prefix_len);
1569 if (0 != (global_ret = set_address6 (address, prefix_len))) 1575 if (0 != (global_ret = set_address6(address, prefix_len)))
1570 goto cleanup; 1576 goto cleanup;
1571 1577
1572 have_ip6 = TRUE; 1578 have_ip6 = TRUE;
1573 1579
1574 /* install our the windows NAT module*/ 1580 /* install our the windows NAT module*/
1575 fprintf (stderr, "DEBUG: Setting IPv6 Forwarding for internal and external interface.\n"); 1581 fprintf(stderr, "DEBUG: Setting IPv6 Forwarding for internal and external interface.\n");
1576 /* outside interface (maybe that's already set) */ 1582 /* outside interface (maybe that's already set) */
1577 snprintf (command, LINE_LEN, 1583 snprintf(command, LINE_LEN,
1578 "netsh interface ipv6 set interface interface=\"%s\" metric=1 forwarding=enabled store=active", 1584 "netsh interface ipv6 set interface interface=\"%s\" metric=1 forwarding=enabled store=active",
1579 argv[2]); 1585 argv[2]);
1580 local_ret = execute_shellcommand (command); 1586 local_ret = execute_shellcommand(command);
1581 if (0 != local_ret) 1587 if (0 != local_ret)
1582 { 1588 {
1583 fprintf (stderr, "FATAL: Could not enable forwarding via netsh: %s\n", strerror (local_ret)); 1589 fprintf(stderr, "FATAL: Could not enable forwarding via netsh: %s\n", strerror(local_ret));
1584 goto cleanup; 1590 goto cleanup;
1585 } 1591 }
1586 /* internal interface */ 1592 /* internal interface */
1587 snprintf (command, LINE_LEN, 1593 snprintf(command, LINE_LEN,
1588 "netsh interface ipv6 set interface interface=\"%s\" metric=1 forwarding=enabled advertise=enabled store=active", 1594 "netsh interface ipv6 set interface interface=\"%s\" metric=1 forwarding=enabled advertise=enabled store=active",
1589 device_visible_name); 1595 device_visible_name);
1590 local_ret = execute_shellcommand (command); 1596 local_ret = execute_shellcommand(command);
1591 if (0 != local_ret) 1597 if (0 != local_ret)
1592 { 1598 {
1593 fprintf (stderr, "FATAL: Could not enable forwarding via netsh: %s\n", strerror (local_ret)); 1599 fprintf(stderr, "FATAL: Could not enable forwarding via netsh: %s\n", strerror(local_ret));
1594 goto cleanup; 1600 goto cleanup;
1595 } 1601 }
1596 /* we can keep IPv6 forwarding around, as all interfaces have 1602 /* we can keep IPv6 forwarding around, as all interfaces have
1597 * their forwarding mode reset to false at bootup. */ 1603 * their forwarding mode reset to false at bootup. */
1598 } 1604 }
1599 1605
1600 if (0 != strcmp (argv[5], "-")) 1606 if (0 != strcmp(argv[5], "-"))
1601 { 1607 {
1602 const char *address = argv[5]; 1608 const char *address = argv[5];
1603 const char *mask = argv[6]; 1609 const char *mask = argv[6];
1604 1610
1605 fprintf (stderr, "DEBUG: Setting IP4 address: %s/%s\n", address, mask); 1611 fprintf(stderr, "DEBUG: Setting IP4 address: %s/%s\n", address, mask);
1606 if (0 != (global_ret = set_address4 (address, mask))) 1612 if (0 != (global_ret = set_address4(address, mask)))
1607 goto cleanup; 1613 goto cleanup;
1608 1614
1609 // setup NAPT, if possible 1615 // setup NAPT, if possible
@@ -1620,36 +1626,36 @@ main (int argc, char **argv)
1620 * ... 1626 * ...
1621 */ 1627 */
1622 have_ip4 = TRUE; 1628 have_ip4 = TRUE;
1623 if (0 != strcmp (argv[2], "-")) 1629 if (0 != strcmp(argv[2], "-"))
1624 { 1630 {
1625 char command[LINE_LEN]; 1631 char command[LINE_LEN];
1626 1632
1627 /* install our the windows NAT module*/ 1633 /* install our the windows NAT module*/
1628 fprintf (stderr, "DEBUG: Adding NAPT/Masquerading between external IF %s and mine.\n", argv[2]); 1634 fprintf(stderr, "DEBUG: Adding NAPT/Masquerading between external IF %s and mine.\n", argv[2]);
1629 local_ret = execute_shellcommand ("netsh routing ip nat install"); 1635 local_ret = execute_shellcommand("netsh routing ip nat install");
1630 if (0 != local_ret) 1636 if (0 != local_ret)
1631 { 1637 {
1632 fprintf (stderr, "FATAL: Could not install NAPT support via Netsh: %s\n", strerror (local_ret)); 1638 fprintf(stderr, "FATAL: Could not install NAPT support via Netsh: %s\n", strerror(local_ret));
1633 goto cleanup; 1639 goto cleanup;
1634 } 1640 }
1635 /* external IF */ 1641 /* external IF */
1636 snprintf (command, LINE_LEN, 1642 snprintf(command, LINE_LEN,
1637 "netsh routing ip nat add interface \"%s\" full", /*full = NAPT (addr+port)*/ 1643 "netsh routing ip nat add interface \"%s\" full", /*full = NAPT (addr+port)*/
1638 argv[2]); 1644 argv[2]);
1639 local_ret = execute_shellcommand (command); 1645 local_ret = execute_shellcommand(command);
1640 if (0 != local_ret) 1646 if (0 != local_ret)
1641 { 1647 {
1642 fprintf (stderr, "FATAL: IPv4-NAPT on external interface failed: %s\n", strerror (local_ret)); 1648 fprintf(stderr, "FATAL: IPv4-NAPT on external interface failed: %s\n", strerror(local_ret));
1643 goto cleanup; 1649 goto cleanup;
1644 } 1650 }
1645 /* private/internal/virtual IF */ 1651 /* private/internal/virtual IF */
1646 snprintf (command, LINE_LEN, 1652 snprintf(command, LINE_LEN,
1647 "netsh routing ip nat add interface \"%s\" private", 1653 "netsh routing ip nat add interface \"%s\" private",
1648 device_visible_name); 1654 device_visible_name);
1649 local_ret = execute_shellcommand (command); 1655 local_ret = execute_shellcommand(command);
1650 if (0 != local_ret) 1656 if (0 != local_ret)
1651 { 1657 {
1652 fprintf (stderr, "FATAL: IPv4-NAPT on internal interface failed: %s\n", strerror (local_ret)); 1658 fprintf(stderr, "FATAL: IPv4-NAPT on internal interface failed: %s\n", strerror(local_ret));
1653 goto cleanup; 1659 goto cleanup;
1654 1660
1655 have_nat44 = TRUE; 1661 have_nat44 = TRUE;
@@ -1657,12 +1663,14 @@ main (int argc, char **argv)
1657 } 1663 }
1658 } 1664 }
1659 1665
1660 run (handle); 1666 run(handle);
1661cleanup: 1667cleanup:
1662 1668
1663 if (have_ip4) { 1669 if (have_ip4)
1670 {
1664 const char *address = argv[5]; 1671 const char *address = argv[5];
1665 if (have_nat44) { 1672 if (have_nat44)
1673 {
1666 char command[LINE_LEN]; 1674 char command[LINE_LEN];
1667 fprintf(stderr, "DEBUG: removing IP4 NAPT from virtual interface \n"); 1675 fprintf(stderr, "DEBUG: removing IP4 NAPT from virtual interface \n");
1668 snprintf(command, LINE_LEN, 1676 snprintf(command, LINE_LEN,
@@ -1670,22 +1678,22 @@ cleanup:
1670 device_visible_name); 1678 device_visible_name);
1671 local_ret = execute_shellcommand(command); 1679 local_ret = execute_shellcommand(command);
1672 if (0 != local_ret) 1680 if (0 != local_ret)
1673 fprintf(stderr, "WARNING: Could not remove IPv4-NAPT from internal interface, hopefully this will have no effect in future runs: %s\n", strerror(local_ret)); 1681 fprintf(stderr, "WARNING: Could not remove IPv4-NAPT from internal interface, hopefully this will have no effect in future runs: %s\n", strerror(local_ret));
1674 } 1682 }
1675 1683
1676 fprintf(stderr, "DEBUG: Removing IP4 address\n"); 1684 fprintf(stderr, "DEBUG: Removing IP4 address\n");
1677 remove_address4 (address); 1685 remove_address4(address);
1678 } 1686 }
1679 if (have_ip6) 1687 if (have_ip6)
1680 { 1688 {
1681 const char *address = argv[3]; 1689 const char *address = argv[3];
1682 fprintf (stderr, "DEBUG: Removing IP6 address\n"); 1690 fprintf(stderr, "DEBUG: Removing IP6 address\n");
1683 remove_address6 (address); 1691 remove_address6(address);
1684 } 1692 }
1685 1693
1686 fprintf (stderr, "DEBUG: removing interface\n"); 1694 fprintf(stderr, "DEBUG: removing interface\n");
1687 remove_interface (); 1695 remove_interface();
1688 fprintf (stderr, "DEBUG: graceful exit completed\n"); 1696 fprintf(stderr, "DEBUG: graceful exit completed\n");
1689 1697
1690 return global_ret; 1698 return global_ret;
1691} 1699}