aboutsummaryrefslogtreecommitdiff
path: root/src/vpn/gnunet-helper-vpn-windows.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vpn/gnunet-helper-vpn-windows.c')
-rw-r--r--src/vpn/gnunet-helper-vpn-windows.c1106
1 files changed, 556 insertions, 550 deletions
diff --git a/src/vpn/gnunet-helper-vpn-windows.c b/src/vpn/gnunet-helper-vpn-windows.c
index 17f32c5a8..afa4fa139 100644
--- a/src/vpn/gnunet-helper-vpn-windows.c
+++ b/src/vpn/gnunet-helper-vpn-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,19 +382,19 @@ 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, 395 fprintf(stderr,
400 "FATAL: removing IPv6 address failed: %s\n", 396 "FATAL: removing IPv6 address failed: %s\n",
401 strerror (ret)); 397 strerror(ret));
402} 398}
403 399
404 400
@@ -409,21 +405,22 @@ remove_address6 (const char *address)
409 * @param mask the netmask 405 * @param mask the netmask
410 */ 406 */
411static int 407static int
412set_address4 (const char *address, const char *mask) 408set_address4(const char *address, const char *mask)
413{ 409{
414 int ret = EINVAL; 410 int ret = EINVAL;
415 char command[LINE_LEN]; 411 char command[LINE_LEN];
416 412
417 struct sockaddr_in addr; 413 struct sockaddr_in addr;
414
418 addr.sin_family = AF_INET; 415 addr.sin_family = AF_INET;
419 416
420 /* 417 /*
421 * Parse the address 418 * Parse the address
422 */ 419 */
423 if (1 != inet_pton (AF_INET, address, &addr.sin_addr.s_addr)) 420 if (1 != inet_pton(AF_INET, address, &addr.sin_addr.s_addr))
424 { 421 {
425 fprintf (stderr, "ERROR: Failed to parse address `%s': %s\n", address, 422 fprintf(stderr, "ERROR: Failed to parse address `%s': %s\n", address,
426 strerror (errno)); 423 strerror(errno));
427 return -1; 424 return -1;
428 } 425 }
429 // Set Device to Subnet-Mode? do we really need openvpn/tun.c:2925 ? 426 // Set Device to Subnet-Mode? do we really need openvpn/tun.c:2925 ?
@@ -431,19 +428,19 @@ set_address4 (const char *address, const char *mask)
431 /* 428 /*
432 * prepare the command 429 * prepare the command
433 */ 430 */
434 snprintf (command, LINE_LEN, 431 snprintf(command, LINE_LEN,
435 "netsh interface ipv4 add address \"%s\" %s %s store=active", 432 "netsh interface ipv4 add address \"%s\" %s %s store=active",
436 device_visible_name, address, mask); 433 device_visible_name, address, mask);
437 /* 434 /*
438 * Set the address 435 * Set the address
439 */ 436 */
440 ret = execute_shellcommand (command); 437 ret = execute_shellcommand(command);
441 438
442 /* Did it work?*/ 439 /* Did it work?*/
443 if (0 != ret) 440 if (0 != ret)
444 fprintf (stderr, 441 fprintf(stderr,
445 "FATAL: Setting IPv4 address failed: %s\n", 442 "FATAL: Setting IPv4 address failed: %s\n",
446 strerror (ret)); 443 strerror(ret));
447 return ret; 444 return ret;
448} 445}
449 446
@@ -454,7 +451,7 @@ set_address4 (const char *address, const char *mask)
454 * @param address the IPv4-Address 451 * @param address the IPv4-Address
455 */ 452 */
456static void 453static void
457remove_address4 (const char *address) 454remove_address4(const char *address)
458{ 455{
459 char command[LINE_LEN]; 456 char command[LINE_LEN];
460 int ret = EINVAL; 457 int ret = EINVAL;
@@ -464,17 +461,17 @@ remove_address4 (const char *address)
464 /* 461 /*
465 * prepare the command 462 * prepare the command
466 */ 463 */
467 snprintf (command, LINE_LEN, 464 snprintf(command, LINE_LEN,
468 "netsh interface ipv4 delete address \"%s\" gateway=all store=persistent", 465 "netsh interface ipv4 delete address \"%s\" gateway=all store=persistent",
469 device_visible_name); 466 device_visible_name);
470 /* 467 /*
471 * Set the address 468 * Set the address
472 */ 469 */
473 ret = execute_shellcommand (command); 470 ret = execute_shellcommand(command);
474 471
475 /* Did it work?*/ 472 /* Did it work?*/
476 if (0 != ret) 473 if (0 != ret)
477 fprintf (stderr, "FATAL: removing IPv4 address failed: %s\n", strerror (ret)); 474 fprintf(stderr, "FATAL: removing IPv4 address failed: %s\n", strerror(ret));
478} 475}
479 476
480 477
@@ -484,7 +481,7 @@ remove_address4 (const char *address)
484 * @return: TRUE if setup was successful, else FALSE 481 * @return: TRUE if setup was successful, else FALSE
485 */ 482 */
486static BOOL 483static BOOL
487setup_interface () 484setup_interface()
488{ 485{
489 /* 486 /*
490 * where to find our inf-file. (+ the "full" path, after windows found") 487 * where to find our inf-file. (+ the "full" path, after windows found")
@@ -503,19 +500,19 @@ setup_interface ()
503 * Set the device's hardware ID and add it to a list. 500 * Set the device's hardware ID and add it to a list.
504 * This information will later on identify this device in registry. 501 * This information will later on identify this device in registry.
505 */ 502 */
506 str_len = GNUNET_strlcpy (hwidlist, 503 str_len = GNUNET_strlcpy(hwidlist,
507 HARDWARE_ID, 504 HARDWARE_ID,
508 sizeof (hwidList)) + 1; 505 sizeof(hwidList)) + 1;
509 /** 506 /**
510 * this is kind of over-complicated, but allows keeps things independent of 507 * this is kind of over-complicated, but allows keeps things independent of
511 * how the openvpn-hwid is actually stored. 508 * how the openvpn-hwid is actually stored.
512 * 509 *
513 * A HWID list is double-\0 terminated and \0 separated 510 * A HWID list is double-\0 terminated and \0 separated
514 */ 511 */
515 str_len += GNUNET_strlcpy (&hwidlist[str_length], 512 str_len += GNUNET_strlcpy(&hwidlist[str_length],
516 secondary_hwid, 513 secondary_hwid,
517 sizeof (hwidlist) - str_len) + 1; 514 sizeof(hwidlist) - str_len) + 1;
518 GNUNET_assert (str_len < sizeof (hwidlist)); 515 GNUNET_assert(str_len < sizeof(hwidlist));
519 hwidlist[str_len] = '\0'; 516 hwidlist[str_len] = '\0';
520 ++str_len; 517 ++str_len;
521 518
@@ -524,62 +521,62 @@ setup_interface ()
524 * find it. We need to pick the correct driver for win32/win64. 521 * find it. We need to pick the correct driver for win32/win64.
525 */ 522 */
526 if (is_win64()) 523 if (is_win64())
527 GetFullPathNameA (INF_FILE64, MAX_PATH, inf_file_path, &temp_inf_filename); 524 GetFullPathNameA(INF_FILE64, MAX_PATH, inf_file_path, &temp_inf_filename);
528 else 525 else
529 GetFullPathNameA (INF_FILE, MAX_PATH, inf_file_path, &temp_inf_filename); 526 GetFullPathNameA(INF_FILE, MAX_PATH, inf_file_path, &temp_inf_filename);
530 527
531 fprintf (stderr, "INFO: Located our driver's .inf file at %s\n", inf_file_path); 528 fprintf(stderr, "INFO: Located our driver's .inf file at %s\n", inf_file_path);
532 /** 529 /**
533 * Bootstrap our device info using the drivers inf-file 530 * Bootstrap our device info using the drivers inf-file
534 */ 531 */
535 if ( ! SetupDiGetINFClassA (inf_file_path, 532 if (!SetupDiGetINFClassA(inf_file_path,
536 &class_guid, 533 &class_guid,
537 class_name, sizeof (class_name) / sizeof (char), 534 class_name, sizeof(class_name) / sizeof(char),
538 NULL)) 535 NULL))
539 return FALSE; 536 return FALSE;
540 537
541 /** 538 /**
542 * Collect all the other needed information... 539 * Collect all the other needed information...
543 * let the system fill our this form 540 * let the system fill our this form
544 */ 541 */
545 DeviceInfo = SetupDiCreateDeviceInfoList (&class_guid, NULL); 542 DeviceInfo = SetupDiCreateDeviceInfoList(&class_guid, NULL);
546 if (DeviceInfo == INVALID_HANDLE_VALUE) 543 if (DeviceInfo == INVALID_HANDLE_VALUE)
547 return FALSE; 544 return FALSE;
548 545
549 DeviceNode.cbSize = sizeof (SP_DEVINFO_DATA); 546 DeviceNode.cbSize = sizeof(SP_DEVINFO_DATA);
550 if ( ! SetupDiCreateDeviceInfoA (DeviceInfo, 547 if (!SetupDiCreateDeviceInfoA(DeviceInfo,
551 class_name, 548 class_name,
552 &class_guid, 549 &class_guid,
553 NULL, 550 NULL,
554 0, 551 0,
555 DICD_GENERATE_ID, 552 DICD_GENERATE_ID,
556 &DeviceNode)) 553 &DeviceNode))
557 return FALSE; 554 return FALSE;
558 555
559 /* Deploy all the information collected into the registry */ 556 /* Deploy all the information collected into the registry */
560 if ( ! SetupDiSetDeviceRegistryPropertyA (DeviceInfo, 557 if (!SetupDiSetDeviceRegistryPropertyA(DeviceInfo,
561 &DeviceNode, 558 &DeviceNode,
562 SPDRP_HARDWAREID, 559 SPDRP_HARDWAREID,
563 (LPBYTE) hwidlist, 560 (LPBYTE)hwidlist,
564 str_length * sizeof (char))) 561 str_length * sizeof(char)))
565 return FALSE; 562 return FALSE;
566 563
567 /* Install our new class(=device) into the system */ 564 /* Install our new class(=device) into the system */
568 if ( ! SetupDiCallClassInstaller (DIF_REGISTERDEVICE, 565 if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE,
569 DeviceInfo, 566 DeviceInfo,
570 &DeviceNode)) 567 &DeviceNode))
571 return FALSE; 568 return FALSE;
572 569
573 /* This system call tends to take a while (several seconds!) on 570 /* This system call tends to take a while (several seconds!) on
574 "modern" Windoze systems */ 571 "modern" Windoze systems */
575 if ( ! UpdateDriverForPlugAndPlayDevicesA (NULL, 572 if (!UpdateDriverForPlugAndPlayDevicesA(NULL,
576 secondary_hwid, 573 secondary_hwid,
577 inf_file_path, 574 inf_file_path,
578 INSTALLFLAG_FORCE | INSTALLFLAG_NONINTERACTIVE, 575 INSTALLFLAG_FORCE | INSTALLFLAG_NONINTERACTIVE,
579 NULL)) //reboot required? NEVER! 576 NULL)) //reboot required? NEVER!
580 return FALSE; 577 return FALSE;
581 578
582 fprintf (stderr, "DEBUG: successfully created a network device\n"); 579 fprintf(stderr, "DEBUG: successfully created a network device\n");
583 return TRUE; 580 return TRUE;
584} 581}
585 582
@@ -591,14 +588,14 @@ setup_interface ()
591 * @return: TRUE if destruction was successful, else FALSE 588 * @return: TRUE if destruction was successful, else FALSE
592 */ 589 */
593static BOOL 590static BOOL
594remove_interface () 591remove_interface()
595{ 592{
596 SP_REMOVEDEVICE_PARAMS remove; 593 SP_REMOVEDEVICE_PARAMS remove;
597 594
598 if (INVALID_HANDLE_VALUE == DeviceInfo) 595 if (INVALID_HANDLE_VALUE == DeviceInfo)
599 return FALSE; 596 return FALSE;
600 597
601 remove.ClassInstallHeader.cbSize = sizeof (SP_CLASSINSTALL_HEADER); 598 remove.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
602 remove.HwProfile = 0; 599 remove.HwProfile = 0;
603 remove.Scope = DI_REMOVEDEVICE_GLOBAL; 600 remove.Scope = DI_REMOVEDEVICE_GLOBAL;
604 remove.ClassInstallHeader.InstallFunction = DIF_REMOVE; 601 remove.ClassInstallHeader.InstallFunction = DIF_REMOVE;
@@ -606,22 +603,22 @@ remove_interface ()
606 * 1. Prepare our existing device information set, and place the 603 * 1. Prepare our existing device information set, and place the
607 * uninstall related information into the structure 604 * uninstall related information into the structure
608 */ 605 */
609 if ( ! SetupDiSetClassInstallParamsA (DeviceInfo, 606 if (!SetupDiSetClassInstallParamsA(DeviceInfo,
610 (PSP_DEVINFO_DATA) & DeviceNode, 607 (PSP_DEVINFO_DATA)&DeviceNode,
611 &remove.ClassInstallHeader, 608 &remove.ClassInstallHeader,
612 sizeof (remove))) 609 sizeof(remove)))
613 return FALSE; 610 return FALSE;
614 /* 611 /*
615 * 2. Uninstall the virtual interface using the class installer 612 * 2. Uninstall the virtual interface using the class installer
616 */ 613 */
617 if ( ! SetupDiCallClassInstaller (DIF_REMOVE, 614 if (!SetupDiCallClassInstaller(DIF_REMOVE,
618 DeviceInfo, 615 DeviceInfo,
619 (PSP_DEVINFO_DATA) & DeviceNode)) 616 (PSP_DEVINFO_DATA)&DeviceNode))
620 return FALSE; 617 return FALSE;
621 618
622 SetupDiDestroyDeviceInfoList (DeviceInfo); 619 SetupDiDestroyDeviceInfoList(DeviceInfo);
623 620
624 fprintf (stderr, "DEBUG: removed interface successfully\n"); 621 fprintf(stderr, "DEBUG: removed interface successfully\n");
625 622
626 return TRUE; 623 return TRUE;
627} 624}
@@ -634,7 +631,7 @@ remove_interface ()
634 * @return: TRUE if we were able to lookup the interface's name, else FALSE 631 * @return: TRUE if we were able to lookup the interface's name, else FALSE
635 */ 632 */
636static BOOL 633static BOOL
637resolve_interface_name () 634resolve_interface_name()
638{ 635{
639 SP_DEVINFO_LIST_DETAIL_DATA device_details; 636 SP_DEVINFO_LIST_DETAIL_DATA device_details;
640 char pnp_instance_id [MAX_DEVICE_ID_LEN]; 637 char pnp_instance_id [MAX_DEVICE_ID_LEN];
@@ -647,29 +644,29 @@ resolve_interface_name ()
647 char adapter[] = INTERFACE_REGISTRY_LOCATION; 644 char adapter[] = INTERFACE_REGISTRY_LOCATION;
648 645
649 /* We can obtain the PNP instance ID from our setupapi handle */ 646 /* We can obtain the PNP instance ID from our setupapi handle */
650 device_details.cbSize = sizeof (device_details); 647 device_details.cbSize = sizeof(device_details);
651 if (CR_SUCCESS != CM_Get_Device_ID_ExA (DeviceNode.DevInst, 648 if (CR_SUCCESS != CM_Get_Device_ID_ExA(DeviceNode.DevInst,
652 (PCHAR) pnp_instance_id, 649 (PCHAR)pnp_instance_id,
653 MAX_DEVICE_ID_LEN, 650 MAX_DEVICE_ID_LEN,
654 0, //must be 0 651 0, //must be 0
655 NULL)) //hMachine, we are local 652 NULL)) //hMachine, we are local
656 return FALSE; 653 return FALSE;
657 654
658 fprintf (stderr, "DEBUG: Resolving interface name for network device %s\n",pnp_instance_id); 655 fprintf(stderr, "DEBUG: Resolving interface name for network device %s\n", pnp_instance_id);
659 656
660 /* Registry is incredibly slow, retry for up to 30 seconds to allow registry to refresh */ 657 /* Registry is incredibly slow, retry for up to 30 seconds to allow registry to refresh */
661 for (retrys = 0; retrys < 120 && !retval; retrys++) 658 for (retrys = 0; retrys < 120 && !retval; retrys++)
662 { 659 {
663 /* sleep for 250ms*/ 660 /* sleep for 250ms*/
664 Sleep (250); 661 Sleep(250);
665 662
666 /* Now we can use this ID to locate the correct networks interface in registry */ 663 /* Now we can use this ID to locate the correct networks interface in registry */
667 if (ERROR_SUCCESS != RegOpenKeyExA ( 664 if (ERROR_SUCCESS != RegOpenKeyExA(
668 HKEY_LOCAL_MACHINE, 665 HKEY_LOCAL_MACHINE,
669 adapter, 666 adapter,
670 0, 667 0,
671 KEY_READ, 668 KEY_READ,
672 &adapter_key_handle)) 669 &adapter_key_handle))
673 return FALSE; 670 return FALSE;
674 671
675 /* Of course there is a multitude of entries here, with arbitrary names, 672 /* Of course there is a multitude of entries here, with arbitrary names,
@@ -685,17 +682,17 @@ resolve_interface_name ()
685 char adaptername_name[] = "Name"; 682 char adaptername_name[] = "Name";
686 DWORD data_type; 683 DWORD data_type;
687 684
688 len = 256 * sizeof (char); 685 len = 256 * sizeof(char);
689 /* optain a subkey of {4D36E972-E325-11CE-BFC1-08002BE10318} */ 686 /* optain a subkey of {4D36E972-E325-11CE-BFC1-08002BE10318} */
690 status = RegEnumKeyExA ( 687 status = RegEnumKeyExA(
691 adapter_key_handle, 688 adapter_key_handle,
692 i, 689 i,
693 instance_key, 690 instance_key,
694 &len, 691 &len,
695 NULL, 692 NULL,
696 NULL, 693 NULL,
697 NULL, 694 NULL,
698 NULL); 695 NULL);
699 696
700 /* this may fail due to one of two reasons: 697 /* this may fail due to one of two reasons:
701 * we are at the end of the list*/ 698 * we are at the end of the list*/
@@ -706,44 +703,44 @@ resolve_interface_name ()
706 goto cleanup; 703 goto cleanup;
707 704
708 /* prepare our new query string: */ 705 /* prepare our new query string: */
709 snprintf (query_key, 256, "%s\\%s\\Connection", 706 snprintf(query_key, 256, "%s\\%s\\Connection",
710 adapter, 707 adapter,
711 instance_key); 708 instance_key);
712 709
713 /* look inside instance_key\\Connection */ 710 /* look inside instance_key\\Connection */
714 if (ERROR_SUCCESS != RegOpenKeyExA ( 711 if (ERROR_SUCCESS != RegOpenKeyExA(
715 HKEY_LOCAL_MACHINE, 712 HKEY_LOCAL_MACHINE,
716 query_key, 713 query_key,
717 0, 714 0,
718 KEY_READ, 715 KEY_READ,
719 &instance_key_handle)) 716 &instance_key_handle))
720 goto cleanup; 717 goto cleanup;
721 718
722 /* now, read our PnpInstanceID */ 719 /* now, read our PnpInstanceID */
723 len = sizeof (pnpinstanceid_value); 720 len = sizeof(pnpinstanceid_value);
724 status = RegQueryValueExA (instance_key_handle, 721 status = RegQueryValueExA(instance_key_handle,
725 pnpinstanceid_name, 722 pnpinstanceid_name,
726 NULL, //reserved, always NULL according to MSDN 723 NULL, //reserved, always NULL according to MSDN
727 &data_type, 724 &data_type,
728 (LPBYTE) pnpinstanceid_value, 725 (LPBYTE)pnpinstanceid_value,
729 &len); 726 &len);
730 727
731 if (status != ERROR_SUCCESS || data_type != REG_SZ) 728 if (status != ERROR_SUCCESS || data_type != REG_SZ)
732 goto cleanup; 729 goto cleanup;
733 730
734 /* compare the value we got to our devices PNPInstanceID*/ 731 /* compare the value we got to our devices PNPInstanceID*/
735 if (0 != strncmp (pnpinstanceid_value, pnp_instance_id, 732 if (0 != strncmp(pnpinstanceid_value, pnp_instance_id,
736 sizeof (pnpinstanceid_value) / sizeof (char))) 733 sizeof(pnpinstanceid_value) / sizeof(char)))
737 goto cleanup; 734 goto cleanup;
738 735
739 len = sizeof (device_visible_name); 736 len = sizeof(device_visible_name);
740 status = RegQueryValueExA ( 737 status = RegQueryValueExA(
741 instance_key_handle, 738 instance_key_handle,
742 adaptername_name, 739 adaptername_name,
743 NULL, //reserved, always NULL according to MSDN 740 NULL, //reserved, always NULL according to MSDN
744 &data_type, 741 &data_type,
745 (LPBYTE) device_visible_name, 742 (LPBYTE)device_visible_name,
746 &len); 743 &len);
747 744
748 if (status != ERROR_SUCCESS || data_type != REG_SZ) 745 if (status != ERROR_SUCCESS || data_type != REG_SZ)
749 goto cleanup; 746 goto cleanup;
@@ -752,17 +749,17 @@ resolve_interface_name ()
752 * we have successfully found OUR instance, 749 * we have successfully found OUR instance,
753 * save the device GUID before exiting 750 * save the device GUID before exiting
754 */ 751 */
755 GNUNET_strlcpy (device_guid, instance_key, sizeof (device_guid)); 752 GNUNET_strlcpy(device_guid, instance_key, sizeof(device_guid));
756 retval = TRUE; 753 retval = TRUE;
757 fprintf (stderr, "DEBUG: Interface Name lookup succeeded on retry %d, got \"%s\" %s\n", retrys, device_visible_name, device_guid); 754 fprintf(stderr, "DEBUG: Interface Name lookup succeeded on retry %d, got \"%s\" %s\n", retrys, device_visible_name, device_guid);
758 755
759cleanup: 756cleanup:
760 RegCloseKey (instance_key_handle); 757 RegCloseKey(instance_key_handle);
761 758
762 ++i; 759 ++i;
763 } 760 }
764 761
765 RegCloseKey (adapter_key_handle); 762 RegCloseKey(adapter_key_handle);
766 } 763 }
767 return retval; 764 return retval;
768} 765}
@@ -775,25 +772,27 @@ cleanup:
775 * @return TRUE if the version is sufficient, else FALSE 772 * @return TRUE if the version is sufficient, else FALSE
776 */ 773 */
777static BOOL 774static BOOL
778check_tapw32_version (HANDLE handle) 775check_tapw32_version(HANDLE handle)
779{ 776{
780 ULONG version[3]; 777 ULONG version[3];
781 DWORD len; 778 DWORD len;
782 memset (&(version), 0, sizeof (version));
783 779
784 if (DeviceIoControl (handle, TAP_WIN_IOCTL_GET_VERSION, 780 memset(&(version), 0, sizeof(version));
785 &version, sizeof (version), 781
786 &version, sizeof (version), &len, NULL)) 782 if (DeviceIoControl(handle, TAP_WIN_IOCTL_GET_VERSION,
787 fprintf (stderr, "INFO: TAP-Windows Driver Version %d.%d %s\n", 783 &version, sizeof(version),
788 (int) version[0], 784 &version, sizeof(version), &len, NULL))
789 (int) version[1], 785 fprintf(stderr, "INFO: TAP-Windows Driver Version %d.%d %s\n",
790 (version[2] ? "(DEBUG)" : "")); 786 (int)version[0],
787 (int)version[1],
788 (version[2] ? "(DEBUG)" : ""));
791 789
792 if ((version[0] != TAP_WIN_MIN_MAJOR) || 790 if ((version[0] != TAP_WIN_MIN_MAJOR) ||
793 (version[1] < TAP_WIN_MIN_MINOR )){ 791 (version[1] < TAP_WIN_MIN_MINOR))
794 fprintf (stderr, "FATAL: This version of gnunet requires a TAP-Windows driver that is at least version %d.%d\n", 792 {
795 TAP_WIN_MIN_MAJOR, 793 fprintf(stderr, "FATAL: This version of gnunet requires a TAP-Windows driver that is at least version %d.%d\n",
796 TAP_WIN_MIN_MINOR); 794 TAP_WIN_MIN_MAJOR,
795 TAP_WIN_MIN_MINOR);
797 return FALSE; 796 return FALSE;
798 } 797 }
799 798
@@ -807,55 +806,55 @@ check_tapw32_version (HANDLE handle)
807 * @return the fd to the tun or -1 on error 806 * @return the fd to the tun or -1 on error
808 */ 807 */
809static HANDLE 808static HANDLE
810init_tun () 809init_tun()
811{ 810{
812 char device_path[256]; 811 char device_path[256];
813 HANDLE handle; 812 HANDLE handle;
814 813
815 if (! setup_interface ()) 814 if (!setup_interface())
816 { 815 {
817 errno = ENODEV; 816 errno = ENODEV;
818 return INVALID_HANDLE_VALUE; 817 return INVALID_HANDLE_VALUE;
819 } 818 }
820 819
821 if (! resolve_interface_name ()) 820 if (!resolve_interface_name())
822 { 821 {
823 errno = ENODEV; 822 errno = ENODEV;
824 return INVALID_HANDLE_VALUE; 823 return INVALID_HANDLE_VALUE;
825 } 824 }
826 825
827 /* Open Windows TAP-Windows adapter */ 826 /* Open Windows TAP-Windows adapter */
828 snprintf (device_path, sizeof (device_path), "%s%s%s", 827 snprintf(device_path, sizeof(device_path), "%s%s%s",
829 USERMODEDEVICEDIR, 828 USERMODEDEVICEDIR,
830 device_guid, 829 device_guid,
831 TAP_WIN_SUFFIX); 830 TAP_WIN_SUFFIX);
832 831
833 handle = CreateFile ( 832 handle = CreateFile(
834 device_path, 833 device_path,
835 GENERIC_READ | GENERIC_WRITE, 834 GENERIC_READ | GENERIC_WRITE,
836 0, /* was: FILE_SHARE_READ */ 835 0, /* was: FILE_SHARE_READ */
837 0, 836 0,
838 OPEN_EXISTING, 837 OPEN_EXISTING,
839 FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 838 FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
840 0 839 0
841 ); 840 );
842 841
843 if (INVALID_HANDLE_VALUE == handle) 842 if (INVALID_HANDLE_VALUE == handle)
844 { 843 {
845 fprintf (stderr, "FATAL: CreateFile failed on TAP device: %s\n", device_path); 844 fprintf(stderr, "FATAL: CreateFile failed on TAP device: %s\n", device_path);
846 return handle; 845 return handle;
847 } 846 }
848 847
849 /* get driver version info */ 848 /* get driver version info */
850 if (! check_tapw32_version (handle)) 849 if (!check_tapw32_version(handle))
851 { 850 {
852 CloseHandle (handle); 851 CloseHandle(handle);
853 return INVALID_HANDLE_VALUE; 852 return INVALID_HANDLE_VALUE;
854 } 853 }
855 854
856 /* TODO (opt?): get MTU-Size */ 855 /* TODO (opt?): get MTU-Size */
857 856
858 fprintf (stderr, "DEBUG: successfully opened TAP device\n"); 857 fprintf(stderr, "DEBUG: successfully opened TAP device\n");
859 return handle; 858 return handle;
860} 859}
861 860
@@ -867,21 +866,22 @@ init_tun ()
867 * @return True if the operation succeeded, else false 866 * @return True if the operation succeeded, else false
868 */ 867 */
869static BOOL 868static BOOL
870tun_up (HANDLE handle) 869tun_up(HANDLE handle)
871{ 870{
872 ULONG status = TRUE; 871 ULONG status = TRUE;
873 DWORD len; 872 DWORD len;
874 if (! DeviceIoControl (handle, TAP_WIN_IOCTL_SET_MEDIA_STATUS, 873
875 &status, sizeof (status), 874 if (!DeviceIoControl(handle, TAP_WIN_IOCTL_SET_MEDIA_STATUS,
876 &status, sizeof (status), &len, NULL)) 875 &status, sizeof(status),
876 &status, sizeof(status), &len, NULL))
877 { 877 {
878 fprintf (stderr, "FATAL: TAP driver ignored request to UP interface (DeviceIoControl call)\n"); 878 fprintf(stderr, "FATAL: TAP driver ignored request to UP interface (DeviceIoControl call)\n");
879 return FALSE; 879 return FALSE;
880 } 880 }
881 881
882 /* Wait for the device to go UP, might take some time. */ 882 /* Wait for the device to go UP, might take some time. */
883 Sleep (TAP32_POSTUP_WAITTIME * 1000); 883 Sleep(TAP32_POSTUP_WAITTIME * 1000);
884 fprintf (stderr, "DEBUG: successfully set TAP device to UP\n"); 884 fprintf(stderr, "DEBUG: successfully set TAP device to UP\n");
885 885
886 return TRUE; 886 return TRUE;
887} 887}
@@ -913,8 +913,8 @@ tun_up (HANDLE handle)
913 * @return false if an event reset was impossible (OS error), else true 913 * @return false if an event reset was impossible (OS error), else true
914 */ 914 */
915static BOOL 915static BOOL
916attempt_read_tap (struct io_facility * input_facility, 916attempt_read_tap(struct io_facility * input_facility,
917 struct io_facility * output_facility) 917 struct io_facility * output_facility)
918{ 918{
919 struct GNUNET_MessageHeader * hdr; 919 struct GNUNET_MessageHeader * hdr;
920 unsigned short size; 920 unsigned short size;
@@ -922,137 +922,139 @@ attempt_read_tap (struct io_facility * input_facility,
922 switch (input_facility->facility_state) 922 switch (input_facility->facility_state)
923 { 923 {
924 case IOSTATE_READY: 924 case IOSTATE_READY:
925 { 925 {
926 if (! ResetEvent (input_facility->overlapped.hEvent)) 926 if (!ResetEvent(input_facility->overlapped.hEvent))
927 { 927 {
928 return FALSE;
929 }
930
931 input_facility->buffer_size = 0;
932
933 /* Check how the task is handled */
934 if (ReadFile(input_facility->handle,
935 input_facility->buffer,
936 sizeof(input_facility->buffer) - sizeof(struct GNUNET_MessageHeader),
937 &input_facility->buffer_size,
938 &input_facility->overlapped))
939 { /* async event processed immediately*/
940 /* reset event manually*/
941 if (!SetEvent(input_facility->overlapped.hEvent))
928 return FALSE; 942 return FALSE;
929 } 943
930 944 fprintf(stderr, "DEBUG: tap read succeeded immediately\n");
931 input_facility->buffer_size = 0; 945
932 946 /* we successfully read something from the TAP and now need to
933 /* Check how the task is handled */ 947 * send it our via STDOUT. Is that possible at the moment? */
934 if (ReadFile (input_facility->handle, 948 if ((IOSTATE_READY == output_facility->facility_state ||
935 input_facility->buffer, 949 IOSTATE_WAITING == output_facility->facility_state)
936 sizeof (input_facility->buffer) - sizeof (struct GNUNET_MessageHeader), 950 && (0 < input_facility->buffer_size))
937 &input_facility->buffer_size, 951 { /* hand over this buffers content and apply message header for gnunet */
938 &input_facility->overlapped)) 952 hdr = (struct GNUNET_MessageHeader *)output_facility->buffer;
939 {/* async event processed immediately*/ 953 size = input_facility->buffer_size + sizeof(struct GNUNET_MessageHeader);
940 954
941 /* reset event manually*/ 955 GNUNET_memcpy(output_facility->buffer + sizeof(struct GNUNET_MessageHeader),
942 if (! SetEvent (input_facility->overlapped.hEvent)) 956 input_facility->buffer,
943 return FALSE; 957 input_facility->buffer_size);
944 958
945 fprintf (stderr, "DEBUG: tap read succeeded immediately\n"); 959 output_facility->buffer_size = size;
946 960 hdr->size = htons(size);
947 /* we successfully read something from the TAP and now need to 961 hdr->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
948 * send it our via STDOUT. Is that possible at the moment? */ 962 output_facility->facility_state = IOSTATE_READY;
949 if ((IOSTATE_READY == output_facility->facility_state || 963 }
950 IOSTATE_WAITING == output_facility->facility_state) 964 else if (0 < input_facility->buffer_size)
951 && (0 < input_facility->buffer_size)) 965 /* If we have have read our buffer, wait for our write-partner*/
952 { /* hand over this buffers content and apply message header for gnunet */ 966 input_facility->facility_state = IOSTATE_WAITING;
953 hdr = (struct GNUNET_MessageHeader *) output_facility->buffer; 967 }
954 size = input_facility->buffer_size + sizeof (struct GNUNET_MessageHeader); 968 else /* operation was either queued or failed*/
955 969 {
956 GNUNET_memcpy (output_facility->buffer + sizeof (struct GNUNET_MessageHeader), 970 int err = GetLastError();
957 input_facility->buffer, 971 if (ERROR_IO_PENDING == err)
958 input_facility->buffer_size); 972 { /* operation queued */
959 973 input_facility->facility_state = IOSTATE_QUEUED;
960 output_facility->buffer_size = size; 974 }
961 hdr->size = htons (size); 975 else
962 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); 976 { /* error occurred, let the rest of the elements finish */
963 output_facility->facility_state = IOSTATE_READY; 977 input_facility->path_open = FALSE;
964 } 978 input_facility->facility_state = IOSTATE_FAILED;
965 else if (0 < input_facility->buffer_size) 979 if (IOSTATE_WAITING == output_facility->facility_state)
966 /* If we have have read our buffer, wait for our write-partner*/ 980 output_facility->path_open = FALSE;
967 input_facility->facility_state = IOSTATE_WAITING; 981
968 } 982 fprintf(stderr, "FATAL: Read from handle failed, allowing write to finish\n");
969 else /* operation was either queued or failed*/ 983 }
970 { 984 }
971 int err = GetLastError (); 985 }
972 if (ERROR_IO_PENDING == err)
973 { /* operation queued */
974 input_facility->facility_state = IOSTATE_QUEUED;
975 }
976 else
977 { /* error occurred, let the rest of the elements finish */
978 input_facility->path_open = FALSE;
979 input_facility->facility_state = IOSTATE_FAILED;
980 if (IOSTATE_WAITING == output_facility->facility_state)
981 output_facility->path_open = FALSE;
982
983 fprintf (stderr, "FATAL: Read from handle failed, allowing write to finish\n");
984 }
985 }
986 }
987 return TRUE; 986 return TRUE;
988 // We are queued and should check if the read has finished 987
988 // We are queued and should check if the read has finished
989 case IOSTATE_QUEUED: 989 case IOSTATE_QUEUED:
990 { 990 {
991 // there was an operation going on already, check if that has completed now. 991 // there was an operation going on already, check if that has completed now.
992 992
993 if (GetOverlappedResult (input_facility->handle, 993 if (GetOverlappedResult(input_facility->handle,
994 &input_facility->overlapped, 994 &input_facility->overlapped,
995 &input_facility->buffer_size, 995 &input_facility->buffer_size,
996 FALSE)) 996 FALSE))
997 {/* successful return for a queued operation */ 997 { /* successful return for a queued operation */
998 if (! ResetEvent (input_facility->overlapped.hEvent)) 998 if (!ResetEvent(input_facility->overlapped.hEvent))
999 return FALSE; 999 return FALSE;
1000 1000
1001 fprintf (stderr, "DEBUG: tap read succeeded delayed\n"); 1001 fprintf(stderr, "DEBUG: tap read succeeded delayed\n");
1002 1002
1003 /* we successfully read something from the TAP and now need to 1003 /* we successfully read something from the TAP and now need to
1004 * send it our via STDOUT. Is that possible at the moment? */ 1004 * send it our via STDOUT. Is that possible at the moment? */
1005 if ((IOSTATE_READY == output_facility->facility_state || 1005 if ((IOSTATE_READY == output_facility->facility_state ||
1006 IOSTATE_WAITING == output_facility->facility_state) 1006 IOSTATE_WAITING == output_facility->facility_state)
1007 && 0 < input_facility->buffer_size) 1007 && 0 < input_facility->buffer_size)
1008 { /* hand over this buffers content and apply message header for gnunet */ 1008 { /* hand over this buffers content and apply message header for gnunet */
1009 hdr = (struct GNUNET_MessageHeader *) output_facility->buffer; 1009 hdr = (struct GNUNET_MessageHeader *)output_facility->buffer;
1010 size = input_facility->buffer_size + sizeof (struct GNUNET_MessageHeader); 1010 size = input_facility->buffer_size + sizeof(struct GNUNET_MessageHeader);
1011 1011
1012 GNUNET_memcpy (output_facility->buffer + sizeof (struct GNUNET_MessageHeader), 1012 GNUNET_memcpy(output_facility->buffer + sizeof(struct GNUNET_MessageHeader),
1013 input_facility->buffer, 1013 input_facility->buffer,
1014 input_facility->buffer_size); 1014 input_facility->buffer_size);
1015 1015
1016 output_facility->buffer_size = size; 1016 output_facility->buffer_size = size;
1017 hdr->size = htons(size); 1017 hdr->size = htons(size);
1018 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); 1018 hdr->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
1019 output_facility->facility_state = IOSTATE_READY; 1019 output_facility->facility_state = IOSTATE_READY;
1020 input_facility->facility_state = IOSTATE_READY; 1020 input_facility->facility_state = IOSTATE_READY;
1021 } 1021 }
1022 else if (0 < input_facility->buffer_size) 1022 else if (0 < input_facility->buffer_size)
1023 { /* If we have have read our buffer, wait for our write-partner*/ 1023 { /* If we have have read our buffer, wait for our write-partner*/
1024 input_facility->facility_state = IOSTATE_WAITING; 1024 input_facility->facility_state = IOSTATE_WAITING;
1025 // TODO: shall we attempt to fill our buffer or should we wait for our write-partner to finish? 1025 // TODO: shall we attempt to fill our buffer or should we wait for our write-partner to finish?
1026 } 1026 }
1027 } 1027 }
1028 else 1028 else
1029 { /* operation still pending/queued or failed? */ 1029 { /* operation still pending/queued or failed? */
1030 int err = GetLastError (); 1030 int err = GetLastError();
1031 if ((ERROR_IO_INCOMPLETE != err) && (ERROR_IO_PENDING != err)) 1031 if ((ERROR_IO_INCOMPLETE != err) && (ERROR_IO_PENDING != err))
1032 { /* error occurred, let the rest of the elements finish */ 1032 { /* error occurred, let the rest of the elements finish */
1033 input_facility->path_open = FALSE; 1033 input_facility->path_open = FALSE;
1034 input_facility->facility_state = IOSTATE_FAILED; 1034 input_facility->facility_state = IOSTATE_FAILED;
1035 if (IOSTATE_WAITING == output_facility->facility_state) 1035 if (IOSTATE_WAITING == output_facility->facility_state)
1036 output_facility->path_open = FALSE; 1036 output_facility->path_open = FALSE;
1037 fprintf (stderr, "FATAL: Read from handle failed, allowing write to finish\n"); 1037 fprintf(stderr, "FATAL: Read from handle failed, allowing write to finish\n");
1038 } 1038 }
1039 } 1039 }
1040 } 1040 }
1041 return TRUE; 1041 return TRUE;
1042
1042 case IOSTATE_RESUME: 1043 case IOSTATE_RESUME:
1043 hdr = (struct GNUNET_MessageHeader *) output_facility->buffer; 1044 hdr = (struct GNUNET_MessageHeader *)output_facility->buffer;
1044 size = input_facility->buffer_size + sizeof (struct GNUNET_MessageHeader); 1045 size = input_facility->buffer_size + sizeof(struct GNUNET_MessageHeader);
1045 1046
1046 GNUNET_memcpy (output_facility->buffer + sizeof (struct GNUNET_MessageHeader), 1047 GNUNET_memcpy(output_facility->buffer + sizeof(struct GNUNET_MessageHeader),
1047 input_facility->buffer, 1048 input_facility->buffer,
1048 input_facility->buffer_size); 1049 input_facility->buffer_size);
1049 1050
1050 output_facility->buffer_size = size; 1051 output_facility->buffer_size = size;
1051 hdr->size = htons (size); 1052 hdr->size = htons(size);
1052 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); 1053 hdr->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
1053 output_facility->facility_state = IOSTATE_READY; 1054 output_facility->facility_state = IOSTATE_READY;
1054 input_facility->facility_state = IOSTATE_READY; 1055 input_facility->facility_state = IOSTATE_READY;
1055 return TRUE; 1056 return TRUE;
1057
1056 default: 1058 default:
1057 return TRUE; 1059 return TRUE;
1058 } 1060 }
@@ -1086,154 +1088,157 @@ attempt_read_tap (struct io_facility * input_facility,
1086 * @return false if an event reset was impossible (OS error), else true 1088 * @return false if an event reset was impossible (OS error), else true
1087 */ 1089 */
1088static BOOL 1090static BOOL
1089attempt_read_stdin (struct io_facility * input_facility, 1091attempt_read_stdin(struct io_facility * input_facility,
1090 struct io_facility * output_facility) 1092 struct io_facility * output_facility)
1091{ 1093{
1092 struct GNUNET_MessageHeader * hdr; 1094 struct GNUNET_MessageHeader * hdr;
1093 1095
1094 switch (input_facility->facility_state) 1096 switch (input_facility->facility_state)
1095 { 1097 {
1096 case IOSTATE_READY: 1098 case IOSTATE_READY:
1097 { 1099 {
1098 input_facility->buffer_size = 0; 1100 input_facility->buffer_size = 0;
1099 1101
1100partial_read_iostate_ready: 1102partial_read_iostate_ready:
1101 if (! ResetEvent (input_facility->overlapped.hEvent)) 1103 if (!ResetEvent(input_facility->overlapped.hEvent))
1102 return FALSE; 1104 return FALSE;
1103 1105
1104 /* Check how the task is handled */ 1106 /* Check how the task is handled */
1105 if (ReadFile (input_facility->handle, 1107 if (ReadFile(input_facility->handle,
1106 input_facility->buffer + input_facility->buffer_size, 1108 input_facility->buffer + input_facility->buffer_size,
1107 sizeof (input_facility->buffer) - input_facility->buffer_size, 1109 sizeof(input_facility->buffer) - input_facility->buffer_size,
1108 &input_facility->buffer_size_processed, 1110 &input_facility->buffer_size_processed,
1109 &input_facility->overlapped)) 1111 &input_facility->overlapped))
1110 {/* async event processed immediately*/ 1112 { /* async event processed immediately*/
1111 hdr = (struct GNUNET_MessageHeader *) input_facility->buffer; 1113 hdr = (struct GNUNET_MessageHeader *)input_facility->buffer;
1112 1114
1113 /* reset event manually*/ 1115 /* reset event manually*/
1114 if (!SetEvent (input_facility->overlapped.hEvent)) 1116 if (!SetEvent(input_facility->overlapped.hEvent))
1115 return FALSE; 1117 return FALSE;
1116 1118
1117 fprintf (stderr, "DEBUG: stdin read succeeded immediately\n"); 1119 fprintf(stderr, "DEBUG: stdin read succeeded immediately\n");
1118 input_facility->buffer_size += input_facility->buffer_size_processed; 1120 input_facility->buffer_size += input_facility->buffer_size_processed;
1119 1121
1120 if (ntohs (hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER || 1122 if (ntohs(hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER ||
1121 ntohs (hdr->size) > sizeof (input_facility->buffer)) 1123 ntohs(hdr->size) > sizeof(input_facility->buffer))
1122 { 1124 {
1123 fprintf (stderr, "WARNING: Protocol violation, got GNUnet Message type %h, size %h\n", ntohs (hdr->type), ntohs (hdr->size)); 1125 fprintf(stderr, "WARNING: Protocol violation, got GNUnet Message type %h, size %h\n", ntohs(hdr->type), ntohs(hdr->size));
1124 input_facility->facility_state = IOSTATE_READY; 1126 input_facility->facility_state = IOSTATE_READY;
1125 return TRUE; 1127 return TRUE;
1126 } 1128 }
1127 /* we got the a part of a packet */ 1129 /* we got the a part of a packet */
1128 if (ntohs (hdr->size) > input_facility->buffer_size) 1130 if (ntohs(hdr->size) > input_facility->buffer_size)
1129 goto partial_read_iostate_ready; 1131 goto partial_read_iostate_ready;
1130 1132
1131 /* have we read more than 0 bytes of payload? (sizeread > header)*/ 1133 /* have we read more than 0 bytes of payload? (sizeread > header)*/
1132 if (input_facility->buffer_size > sizeof (struct GNUNET_MessageHeader) && 1134 if (input_facility->buffer_size > sizeof(struct GNUNET_MessageHeader) &&
1133 ((IOSTATE_READY == output_facility->facility_state) || 1135 ((IOSTATE_READY == output_facility->facility_state) ||
1134 (IOSTATE_WAITING == output_facility->facility_state))) 1136 (IOSTATE_WAITING == output_facility->facility_state)))
1135 {/* we successfully read something from the TAP and now need to 1137 { /* we successfully read something from the TAP and now need to
1136 * send it our via STDOUT. Is that possible at the moment? */ 1138 * send it our via STDOUT. Is that possible at the moment? */
1137 1139 /* hand over this buffers content and strip gnunet message header */
1138 /* hand over this buffers content and strip gnunet message header */ 1140 GNUNET_memcpy(output_facility->buffer,
1139 GNUNET_memcpy (output_facility->buffer, 1141 input_facility->buffer + sizeof(struct GNUNET_MessageHeader),
1140 input_facility->buffer + sizeof (struct GNUNET_MessageHeader), 1142 input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader));
1141 input_facility->buffer_size - sizeof (struct GNUNET_MessageHeader)); 1143 output_facility->buffer_size = input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader);
1142 output_facility->buffer_size = input_facility->buffer_size - sizeof (struct GNUNET_MessageHeader); 1144 output_facility->facility_state = IOSTATE_READY;
1143 output_facility->facility_state = IOSTATE_READY;
1144 input_facility->facility_state = IOSTATE_READY;
1145 }
1146 else if (input_facility->buffer_size > sizeof (struct GNUNET_MessageHeader))
1147 /* If we have have read our buffer, wait for our write-partner*/
1148 input_facility->facility_state = IOSTATE_WAITING;
1149 else /* we read nothing */
1150 input_facility->facility_state = IOSTATE_READY; 1145 input_facility->facility_state = IOSTATE_READY;
1151 } 1146 }
1152 else /* operation was either queued or failed*/ 1147 else if (input_facility->buffer_size > sizeof(struct GNUNET_MessageHeader))
1153 { 1148 /* If we have have read our buffer, wait for our write-partner*/
1154 int err = GetLastError (); 1149 input_facility->facility_state = IOSTATE_WAITING;
1155 if (ERROR_IO_PENDING == err) /* operation queued */ 1150 else /* we read nothing */
1156 input_facility->facility_state = IOSTATE_QUEUED; 1151 input_facility->facility_state = IOSTATE_READY;
1157 else 1152 }
1158 { /* error occurred, let the rest of the elements finish */ 1153 else /* operation was either queued or failed*/
1159 input_facility->path_open = FALSE; 1154 {
1160 input_facility->facility_state = IOSTATE_FAILED; 1155 int err = GetLastError();
1161 if (IOSTATE_WAITING == output_facility->facility_state) 1156 if (ERROR_IO_PENDING == err) /* operation queued */
1162 output_facility->path_open = FALSE; 1157 input_facility->facility_state = IOSTATE_QUEUED;
1163 1158 else
1164 fprintf (stderr, "FATAL: Read from handle failed, allowing write to finish\n"); 1159 { /* error occurred, let the rest of the elements finish */
1165 } 1160 input_facility->path_open = FALSE;
1166 } 1161 input_facility->facility_state = IOSTATE_FAILED;
1167 } 1162 if (IOSTATE_WAITING == output_facility->facility_state)
1163 output_facility->path_open = FALSE;
1164
1165 fprintf(stderr, "FATAL: Read from handle failed, allowing write to finish\n");
1166 }
1167 }
1168 }
1168 return TRUE; 1169 return TRUE;
1169 // We are queued and should check if the read has finished 1170
1171 // We are queued and should check if the read has finished
1170 case IOSTATE_QUEUED: 1172 case IOSTATE_QUEUED:
1171 { 1173 {
1172 // there was an operation going on already, check if that has completed now. 1174 // there was an operation going on already, check if that has completed now.
1173 if (GetOverlappedResult (input_facility->handle, 1175 if (GetOverlappedResult(input_facility->handle,
1174 &input_facility->overlapped, 1176 &input_facility->overlapped,
1175 &input_facility->buffer_size_processed, 1177 &input_facility->buffer_size_processed,
1176 FALSE)) 1178 FALSE))
1177 {/* successful return for a queued operation */ 1179 { /* successful return for a queued operation */
1178 hdr = (struct GNUNET_MessageHeader *) input_facility->buffer; 1180 hdr = (struct GNUNET_MessageHeader *)input_facility->buffer;
1179 1181
1180 if (! ResetEvent (input_facility->overlapped.hEvent)) 1182 if (!ResetEvent(input_facility->overlapped.hEvent))
1181 return FALSE; 1183 return FALSE;
1182 1184
1183 fprintf (stderr, "DEBUG: stdin read succeeded delayed\n"); 1185 fprintf(stderr, "DEBUG: stdin read succeeded delayed\n");
1184 input_facility->buffer_size += input_facility->buffer_size_processed; 1186 input_facility->buffer_size += input_facility->buffer_size_processed;
1185 1187
1186 if ((ntohs (hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) || 1188 if ((ntohs(hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) ||
1187 (ntohs (hdr->size) > sizeof (input_facility->buffer))) 1189 (ntohs(hdr->size) > sizeof(input_facility->buffer)))
1188 { 1190 {
1189 fprintf (stderr, "WARNING: Protocol violation, got GNUnet Message type %h, size %h\n", ntohs (hdr->type), ntohs (hdr->size)); 1191 fprintf(stderr, "WARNING: Protocol violation, got GNUnet Message type %h, size %h\n", ntohs(hdr->type), ntohs(hdr->size));
1190 input_facility->facility_state = IOSTATE_READY; 1192 input_facility->facility_state = IOSTATE_READY;
1191 return TRUE; 1193 return TRUE;
1192 } 1194 }
1193 /* we got the a part of a packet */ 1195 /* we got the a part of a packet */
1194 if (ntohs (hdr->size) > input_facility->buffer_size ); 1196 if (ntohs(hdr->size) > input_facility->buffer_size)
1195 goto partial_read_iostate_ready; 1197 ;
1196 1198 goto partial_read_iostate_ready;
1197 /* we successfully read something from the TAP and now need to 1199
1198 * send it our via STDOUT. Is that possible at the moment? */ 1200 /* we successfully read something from the TAP and now need to
1199 if ((IOSTATE_READY == output_facility->facility_state || 1201 * send it our via STDOUT. Is that possible at the moment? */
1200 IOSTATE_WAITING == output_facility->facility_state) 1202 if ((IOSTATE_READY == output_facility->facility_state ||
1201 && input_facility->buffer_size > sizeof(struct GNUNET_MessageHeader)) 1203 IOSTATE_WAITING == output_facility->facility_state)
1202 { /* hand over this buffers content and strip gnunet message header */ 1204 && input_facility->buffer_size > sizeof(struct GNUNET_MessageHeader))
1203 GNUNET_memcpy (output_facility->buffer, 1205 { /* hand over this buffers content and strip gnunet message header */
1204 input_facility->buffer + sizeof(struct GNUNET_MessageHeader), 1206 GNUNET_memcpy(output_facility->buffer,
1205 input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader)); 1207 input_facility->buffer + sizeof(struct GNUNET_MessageHeader),
1206 output_facility->buffer_size = input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader); 1208 input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader));
1207 output_facility->facility_state = IOSTATE_READY; 1209 output_facility->buffer_size = input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader);
1208 input_facility->facility_state = IOSTATE_READY; 1210 output_facility->facility_state = IOSTATE_READY;
1209 }
1210 else if (input_facility->buffer_size > sizeof(struct GNUNET_MessageHeader))
1211 input_facility->facility_state = IOSTATE_WAITING;
1212 else
1213 input_facility->facility_state = IOSTATE_READY; 1211 input_facility->facility_state = IOSTATE_READY;
1214 } 1212 }
1215 else 1213 else if (input_facility->buffer_size > sizeof(struct GNUNET_MessageHeader))
1216 { /* operation still pending/queued or failed? */ 1214 input_facility->facility_state = IOSTATE_WAITING;
1217 int err = GetLastError (); 1215 else
1218 if ((ERROR_IO_INCOMPLETE != err) && (ERROR_IO_PENDING != err)) 1216 input_facility->facility_state = IOSTATE_READY;
1219 { /* error occurred, let the rest of the elements finish */ 1217 }
1220 input_facility->path_open = FALSE; 1218 else
1221 input_facility->facility_state = IOSTATE_FAILED; 1219 { /* operation still pending/queued or failed? */
1222 if (IOSTATE_WAITING == output_facility->facility_state) 1220 int err = GetLastError();
1223 output_facility->path_open = FALSE; 1221 if ((ERROR_IO_INCOMPLETE != err) && (ERROR_IO_PENDING != err))
1224 fprintf (stderr, "FATAL: Read from handle failed, allowing write to finish\n"); 1222 { /* error occurred, let the rest of the elements finish */
1225 } 1223 input_facility->path_open = FALSE;
1226 } 1224 input_facility->facility_state = IOSTATE_FAILED;
1227 } 1225 if (IOSTATE_WAITING == output_facility->facility_state)
1226 output_facility->path_open = FALSE;
1227 fprintf(stderr, "FATAL: Read from handle failed, allowing write to finish\n");
1228 }
1229 }
1230 }
1228 return TRUE; 1231 return TRUE;
1232
1229 case IOSTATE_RESUME: /* Our buffer was filled already but our write facility was busy. */ 1233 case IOSTATE_RESUME: /* Our buffer was filled already but our write facility was busy. */
1230 GNUNET_memcpy (output_facility->buffer, 1234 GNUNET_memcpy(output_facility->buffer,
1231 input_facility->buffer + sizeof (struct GNUNET_MessageHeader), 1235 input_facility->buffer + sizeof(struct GNUNET_MessageHeader),
1232 input_facility->buffer_size - sizeof (struct GNUNET_MessageHeader)); 1236 input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader));
1233 output_facility->buffer_size = input_facility->buffer_size - sizeof (struct GNUNET_MessageHeader); 1237 output_facility->buffer_size = input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader);
1234 output_facility->facility_state = IOSTATE_READY; 1238 output_facility->facility_state = IOSTATE_READY;
1235 input_facility->facility_state = IOSTATE_READY; 1239 input_facility->facility_state = IOSTATE_READY;
1236 return TRUE; 1240 return TRUE;
1241
1237 default: 1242 default:
1238 return TRUE; 1243 return TRUE;
1239 } 1244 }
@@ -1250,8 +1255,8 @@ partial_read_iostate_ready:
1250 * @return false if an event reset was impossible (OS error), else true 1255 * @return false if an event reset was impossible (OS error), else true
1251 */ 1256 */
1252static BOOL 1257static BOOL
1253attempt_write (struct io_facility * output_facility, 1258attempt_write(struct io_facility * output_facility,
1254 struct io_facility * input_facility) 1259 struct io_facility * input_facility)
1255{ 1260{
1256 switch (output_facility->facility_state) 1261 switch (output_facility->facility_state)
1257 { 1262 {
@@ -1259,22 +1264,21 @@ attempt_write (struct io_facility * output_facility,
1259 output_facility->buffer_size_written = 0; 1264 output_facility->buffer_size_written = 0;
1260 1265
1261continue_partial_write: 1266continue_partial_write:
1262 if (! ResetEvent (output_facility->overlapped.hEvent)) 1267 if (!ResetEvent(output_facility->overlapped.hEvent))
1263 return FALSE; 1268 return FALSE;
1264 1269
1265 /* Check how the task was handled */ 1270 /* Check how the task was handled */
1266 if (WriteFile (output_facility->handle, 1271 if (WriteFile(output_facility->handle,
1267 output_facility->buffer + output_facility->buffer_size_written, 1272 output_facility->buffer + output_facility->buffer_size_written,
1268 output_facility->buffer_size - output_facility->buffer_size_written, 1273 output_facility->buffer_size - output_facility->buffer_size_written,
1269 &output_facility->buffer_size_processed, 1274 &output_facility->buffer_size_processed,
1270 &output_facility->overlapped)) 1275 &output_facility->overlapped))
1271 {/* async event processed immediately*/ 1276 {/* async event processed immediately*/
1272 1277 fprintf(stderr, "DEBUG: write succeeded immediately\n");
1273 fprintf (stderr, "DEBUG: write succeeded immediately\n");
1274 output_facility->buffer_size_written += output_facility->buffer_size_processed; 1278 output_facility->buffer_size_written += output_facility->buffer_size_processed;
1275 1279
1276 /* reset event manually*/ 1280 /* reset event manually*/
1277 if (! SetEvent (output_facility->overlapped.hEvent)) 1281 if (!SetEvent(output_facility->overlapped.hEvent))
1278 return FALSE; 1282 return FALSE;
1279 1283
1280 /* partial write */ 1284 /* partial write */
@@ -1292,7 +1296,7 @@ continue_partial_write:
1292 } 1296 }
1293 else /* operation was either queued or failed*/ 1297 else /* operation was either queued or failed*/
1294 { 1298 {
1295 int err = GetLastError (); 1299 int err = GetLastError();
1296 if (ERROR_IO_PENDING == err) 1300 if (ERROR_IO_PENDING == err)
1297 { /* operation queued */ 1301 { /* operation queued */
1298 output_facility->facility_state = IOSTATE_QUEUED; 1302 output_facility->facility_state = IOSTATE_QUEUED;
@@ -1301,22 +1305,23 @@ continue_partial_write:
1301 { /* error occurred, close this path */ 1305 { /* error occurred, close this path */
1302 output_facility->path_open = FALSE; 1306 output_facility->path_open = FALSE;
1303 output_facility->facility_state = IOSTATE_FAILED; 1307 output_facility->facility_state = IOSTATE_FAILED;
1304 fprintf (stderr, "FATAL: Write to handle failed, exiting\n"); 1308 fprintf(stderr, "FATAL: Write to handle failed, exiting\n");
1305 } 1309 }
1306 } 1310 }
1307 return TRUE; 1311 return TRUE;
1312
1308 case IOSTATE_QUEUED: 1313 case IOSTATE_QUEUED:
1309 // there was an operation going on already, check if that has completed now. 1314 // there was an operation going on already, check if that has completed now.
1310 1315
1311 if (GetOverlappedResult (output_facility->handle, 1316 if (GetOverlappedResult(output_facility->handle,
1312 &output_facility->overlapped, 1317 &output_facility->overlapped,
1313 &output_facility->buffer_size_processed, 1318 &output_facility->buffer_size_processed,
1314 FALSE)) 1319 FALSE))
1315 {/* successful return for a queued operation */ 1320 {/* successful return for a queued operation */
1316 if (! ResetEvent (output_facility->overlapped.hEvent)) 1321 if (!ResetEvent(output_facility->overlapped.hEvent))
1317 return FALSE; 1322 return FALSE;
1318 1323
1319 fprintf (stderr, "DEBUG: write succeeded delayed\n"); 1324 fprintf(stderr, "DEBUG: write succeeded delayed\n");
1320 output_facility->buffer_size_written += output_facility->buffer_size_processed; 1325 output_facility->buffer_size_written += output_facility->buffer_size_processed;
1321 1326
1322 /* partial write */ 1327 /* partial write */
@@ -1334,14 +1339,15 @@ continue_partial_write:
1334 } 1339 }
1335 else 1340 else
1336 { /* operation still pending/queued or failed? */ 1341 { /* operation still pending/queued or failed? */
1337 int err = GetLastError (); 1342 int err = GetLastError();
1338 if ((ERROR_IO_INCOMPLETE != err) && (ERROR_IO_PENDING != err)) 1343 if ((ERROR_IO_INCOMPLETE != err) && (ERROR_IO_PENDING != err))
1339 { /* error occurred, close this path */ 1344 { /* error occurred, close this path */
1340 output_facility->path_open = FALSE; 1345 output_facility->path_open = FALSE;
1341 output_facility->facility_state = IOSTATE_FAILED; 1346 output_facility->facility_state = IOSTATE_FAILED;
1342 fprintf (stderr, "FATAL: Write to handle failed, exiting\n"); 1347 fprintf(stderr, "FATAL: Write to handle failed, exiting\n");
1343 } 1348 }
1344 } 1349 }
1350
1345 default: 1351 default:
1346 return TRUE; 1352 return TRUE;
1347 } 1353 }
@@ -1357,15 +1363,15 @@ continue_partial_write:
1357 * @return true on success, else false 1363 * @return true on success, else false
1358 */ 1364 */
1359static BOOL 1365static BOOL
1360initialize_io_facility (struct io_facility * elem, 1366initialize_io_facility(struct io_facility * elem,
1361 int initial_state, 1367 int initial_state,
1362 BOOL signaled) 1368 BOOL signaled)
1363{ 1369{
1364 elem->path_open = TRUE; 1370 elem->path_open = TRUE;
1365 elem->handle = INVALID_HANDLE_VALUE; 1371 elem->handle = INVALID_HANDLE_VALUE;
1366 elem->facility_state = initial_state; 1372 elem->facility_state = initial_state;
1367 elem->buffer_size = 0; 1373 elem->buffer_size = 0;
1368 elem->overlapped.hEvent = CreateEvent (NULL, TRUE, signaled, NULL); 1374 elem->overlapped.hEvent = CreateEvent(NULL, TRUE, signaled, NULL);
1369 if (NULL == elem->overlapped.hEvent) 1375 if (NULL == elem->overlapped.hEvent)
1370 return FALSE; 1376 return FALSE;
1371 1377
@@ -1379,7 +1385,7 @@ initialize_io_facility (struct io_facility * elem,
1379 * @param tap_handle device handle for interacting with the Virtual interface 1385 * @param tap_handle device handle for interacting with the Virtual interface
1380 */ 1386 */
1381static void 1387static void
1382run (HANDLE tap_handle) 1388run(HANDLE tap_handle)
1383{ 1389{
1384 /* IO-Facility for reading from our virtual interface */ 1390 /* IO-Facility for reading from our virtual interface */
1385 struct io_facility tap_read; 1391 struct io_facility tap_read;
@@ -1390,8 +1396,8 @@ run (HANDLE tap_handle)
1390 /* IO-Facility for writing to stdout */ 1396 /* IO-Facility for writing to stdout */
1391 struct io_facility std_out; 1397 struct io_facility std_out;
1392 1398
1393 HANDLE parent_std_in_handle = GetStdHandle (STD_INPUT_HANDLE); 1399 HANDLE parent_std_in_handle = GetStdHandle(STD_INPUT_HANDLE);
1394 HANDLE parent_std_out_handle = GetStdHandle (STD_OUTPUT_HANDLE); 1400 HANDLE parent_std_out_handle = GetStdHandle(STD_OUTPUT_HANDLE);
1395 1401
1396 /* tun up: */ 1402 /* tun up: */
1397 /* we do this HERE and not beforehand (in init_tun()), in contrast to openvpn 1403 /* we do this HERE and not beforehand (in init_tun()), in contrast to openvpn
@@ -1400,14 +1406,14 @@ run (HANDLE tap_handle)
1400 * DHCP and such are all features we will never use in gnunet afaik. 1406 * DHCP and such are all features we will never use in gnunet afaik.
1401 * But for openvpn those are essential. 1407 * But for openvpn those are essential.
1402 */ 1408 */
1403 if ((privilege_testing) || (! tun_up (tap_handle))) 1409 if ((privilege_testing) || (!tun_up(tap_handle)))
1404 goto teardown_final; 1410 goto teardown_final;
1405 1411
1406 /* Initialize our overlapped IO structures*/ 1412 /* Initialize our overlapped IO structures*/
1407 if (! (initialize_io_facility (&tap_read, IOSTATE_READY, FALSE) 1413 if (!(initialize_io_facility(&tap_read, IOSTATE_READY, FALSE)
1408 && initialize_io_facility (&tap_write, IOSTATE_WAITING, TRUE) 1414 && initialize_io_facility(&tap_write, IOSTATE_WAITING, TRUE)
1409 && initialize_io_facility (&std_in, IOSTATE_READY, FALSE) 1415 && initialize_io_facility(&std_in, IOSTATE_READY, FALSE)
1410 && initialize_io_facility (&std_out, IOSTATE_WAITING, TRUE))) 1416 && initialize_io_facility(&std_out, IOSTATE_WAITING, TRUE)))
1411 goto teardown_final; 1417 goto teardown_final;
1412 1418
1413 /* Handles for STDIN and STDOUT */ 1419 /* Handles for STDIN and STDOUT */
@@ -1418,72 +1424,71 @@ run (HANDLE tap_handle)
1418 /* Debug output to console STDIN/STDOUT*/ 1424 /* Debug output to console STDIN/STDOUT*/
1419 std_in.handle = parent_std_in_handle; 1425 std_in.handle = parent_std_in_handle;
1420 std_out.handle = parent_std_out_handle; 1426 std_out.handle = parent_std_out_handle;
1421
1422#else 1427#else
1423 fprintf (stderr, "DEBUG: reopening stdin/out for overlapped IO\n"); 1428 fprintf(stderr, "DEBUG: reopening stdin/out for overlapped IO\n");
1424 /* 1429 /*
1425 * Find out the types of our handles. 1430 * Find out the types of our handles.
1426 * This part is a problem, because in windows we need to handle files, 1431 * This part is a problem, because in windows we need to handle files,
1427 * pipes and the console differently. 1432 * pipes and the console differently.
1428 */ 1433 */
1429 if ((FILE_TYPE_PIPE != GetFileType (parent_std_in_handle)) || 1434 if ((FILE_TYPE_PIPE != GetFileType(parent_std_in_handle)) ||
1430 (FILE_TYPE_PIPE != GetFileType (parent_std_out_handle))) 1435 (FILE_TYPE_PIPE != GetFileType(parent_std_out_handle)))
1431 { 1436 {
1432 fprintf (stderr, "ERROR: stdin/stdout must be named pipes\n"); 1437 fprintf(stderr, "ERROR: stdin/stdout must be named pipes\n");
1433 goto teardown; 1438 goto teardown;
1434 } 1439 }
1435 1440
1436 std_in.handle = ReOpenFile (parent_std_in_handle, 1441 std_in.handle = ReOpenFile(parent_std_in_handle,
1437 GENERIC_READ, 1442 GENERIC_READ,
1438 FILE_SHARE_WRITE | FILE_SHARE_READ, 1443 FILE_SHARE_WRITE | FILE_SHARE_READ,
1439 FILE_FLAG_OVERLAPPED); 1444 FILE_FLAG_OVERLAPPED);
1440 1445
1441 if (INVALID_HANDLE_VALUE == std_in.handle) 1446 if (INVALID_HANDLE_VALUE == std_in.handle)
1442 { 1447 {
1443 fprintf (stderr, "FATAL: Could not reopen stdin for in overlapped mode, has to be a named pipe\n"); 1448 fprintf(stderr, "FATAL: Could not reopen stdin for in overlapped mode, has to be a named pipe\n");
1444 goto teardown; 1449 goto teardown;
1445 } 1450 }
1446 1451
1447 std_out.handle = ReOpenFile (parent_std_out_handle, 1452 std_out.handle = ReOpenFile(parent_std_out_handle,
1448 GENERIC_WRITE, 1453 GENERIC_WRITE,
1449 FILE_SHARE_READ, 1454 FILE_SHARE_READ,
1450 FILE_FLAG_OVERLAPPED); 1455 FILE_FLAG_OVERLAPPED);
1451 1456
1452 if (INVALID_HANDLE_VALUE == std_out.handle) 1457 if (INVALID_HANDLE_VALUE == std_out.handle)
1453 { 1458 {
1454 fprintf (stderr, "FATAL: Could not reopen stdout for in overlapped mode, has to be a named pipe\n"); 1459 fprintf(stderr, "FATAL: Could not reopen stdout for in overlapped mode, has to be a named pipe\n");
1455 goto teardown; 1460 goto teardown;
1456 } 1461 }
1457#endif 1462#endif
1458 1463
1459 fprintf (stderr, "DEBUG: mainloop has begun\n"); 1464 fprintf(stderr, "DEBUG: mainloop has begun\n");
1460 1465
1461 while (std_out.path_open || tap_write.path_open) 1466 while (std_out.path_open || tap_write.path_open)
1462 { 1467 {
1463 /* perform READ from stdin if possible */ 1468 /* perform READ from stdin if possible */
1464 if (std_in.path_open && (! attempt_read_stdin (&std_in, &tap_write))) 1469 if (std_in.path_open && (!attempt_read_stdin(&std_in, &tap_write)))
1465 break; 1470 break;
1466 1471
1467 /* perform READ from tap if possible */ 1472 /* perform READ from tap if possible */
1468 if (tap_read.path_open && (! attempt_read_tap (&tap_read, &std_out))) 1473 if (tap_read.path_open && (!attempt_read_tap(&tap_read, &std_out)))
1469 break; 1474 break;
1470 1475
1471 /* perform WRITE to tap if possible */ 1476 /* perform WRITE to tap if possible */
1472 if (tap_write.path_open && (! attempt_write (&tap_write, &std_in))) 1477 if (tap_write.path_open && (!attempt_write(&tap_write, &std_in)))
1473 break; 1478 break;
1474 1479
1475 /* perform WRITE to STDOUT if possible */ 1480 /* perform WRITE to STDOUT if possible */
1476 if (std_out.path_open && (! attempt_write (&std_out, &tap_read))) 1481 if (std_out.path_open && (!attempt_write(&std_out, &tap_read)))
1477 break; 1482 break;
1478 } 1483 }
1479 1484
1480 fprintf (stderr, "DEBUG: teardown initiated\n"); 1485 fprintf(stderr, "DEBUG: teardown initiated\n");
1481teardown: 1486teardown:
1482 CancelIo (tap_handle); 1487 CancelIo(tap_handle);
1483 CancelIo (std_in.handle); 1488 CancelIo(std_in.handle);
1484 CancelIo (std_out.handle); 1489 CancelIo(std_out.handle);
1485teardown_final: 1490teardown_final:
1486 CloseHandle (tap_handle); 1491 CloseHandle(tap_handle);
1487} 1492}
1488 1493
1489 1494
@@ -1500,7 +1505,7 @@ teardown_final:
1500 * 6: IPv4 netmask (255.255.0.0), ignored if #4 is "-" 1505 * 6: IPv4 netmask (255.255.0.0), ignored if #4 is "-"
1501 */ 1506 */
1502int 1507int
1503main (int argc, char **argv) 1508main(int argc, char **argv)
1504{ 1509{
1505 char hwid[LINE_LEN]; 1510 char hwid[LINE_LEN];
1506 HANDLE handle; 1511 HANDLE handle;
@@ -1508,97 +1513,98 @@ main (int argc, char **argv)
1508 BOOL have_ip4 = FALSE; 1513 BOOL have_ip4 = FALSE;
1509 BOOL have_ip6 = FALSE; 1514 BOOL have_ip6 = FALSE;
1510 1515
1511 if (argc > 1 && 0 == strcmp (argv[1], "-d")){ 1516 if (argc > 1 && 0 == strcmp(argv[1], "-d"))
1517 {
1512 privilege_testing = TRUE; 1518 privilege_testing = TRUE;
1513 fprintf (stderr, 1519 fprintf(stderr,
1514 "%s", 1520 "%s",
1515 "DEBUG: Running binary in privilege testing mode."); 1521 "DEBUG: Running binary in privilege testing mode.");
1516 argv++; 1522 argv++;
1517 argc--; 1523 argc--;
1518 } 1524 }
1519 1525
1520 if (6 != argc) 1526 if (6 != argc)
1521 { 1527 {
1522 fprintf (stderr, 1528 fprintf(stderr,
1523 "%s", 1529 "%s",
1524 "FATAL: must supply 5 arguments\nUsage:\ngnunet-helper-vpn [-d] <if name prefix> <address6 or \"-\"> <netbits6> <address4 or \"-\"> <netmask4>\n"); 1530 "FATAL: must supply 5 arguments\nUsage:\ngnunet-helper-vpn [-d] <if name prefix> <address6 or \"-\"> <netbits6> <address4 or \"-\"> <netmask4>\n");
1525 return 1; 1531 return 1;
1526 } 1532 }
1527 1533
1528 GNUNET_strlcpy (hwid, argv[1], sizeof (hwid)); 1534 GNUNET_strlcpy(hwid, argv[1], sizeof(hwid));
1529 1535
1530 /* 1536 /*
1531 * We use our PID for finding/resolving the control-panel name of our virtual 1537 * We use our PID for finding/resolving the control-panel name of our virtual
1532 * device. PIDs are (of course) unique at runtime, thus we can safely use it 1538 * device. PIDs are (of course) unique at runtime, thus we can safely use it
1533 * as additional hardware-id for our device. 1539 * as additional hardware-id for our device.
1534 */ 1540 */
1535 snprintf (secondary_hwid, LINE_LEN / 2, "%s-%d", 1541 snprintf(secondary_hwid, LINE_LEN / 2, "%s-%d",
1536 hwid, 1542 hwid,
1537 _getpid ()); 1543 _getpid());
1538 1544
1539 if (INVALID_HANDLE_VALUE == (handle = init_tun ())) 1545 if (INVALID_HANDLE_VALUE == (handle = init_tun()))
1540 { 1546 {
1541 fprintf (stderr, "FATAL: could not initialize virtual-interface %s with IPv6 %s/%s and IPv4 %s/%s\n", 1547 fprintf(stderr, "FATAL: could not initialize virtual-interface %s with IPv6 %s/%s and IPv4 %s/%s\n",
1542 hwid, 1548 hwid,
1543 argv[2], 1549 argv[2],
1544 argv[3], 1550 argv[3],
1545 argv[4], 1551 argv[4],
1546 argv[5]); 1552 argv[5]);
1547 global_ret = -1; 1553 global_ret = -1;
1548 goto cleanup; 1554 goto cleanup;
1549 } 1555 }
1550 1556
1551 fprintf (stderr, "DEBUG: Setting IPs, if needed\n"); 1557 fprintf(stderr, "DEBUG: Setting IPs, if needed\n");
1552 if (0 != strcmp (argv[2], "-")) 1558 if (0 != strcmp(argv[2], "-"))
1553 { 1559 {
1554 const char *address = argv[2]; 1560 const char *address = argv[2];
1555 long prefix_len = atol (argv[3]); 1561 long prefix_len = atol(argv[3]);
1556 1562
1557 if ((prefix_len < 1) || (prefix_len > 127)) 1563 if ((prefix_len < 1) || (prefix_len > 127))
1558 { 1564 {
1559 fprintf (stderr, "FATAL: ipv6 prefix_len out of range\n"); 1565 fprintf(stderr, "FATAL: ipv6 prefix_len out of range\n");
1560 global_ret = -1; 1566 global_ret = -1;
1561 goto cleanup; 1567 goto cleanup;
1562 } 1568 }
1563 1569
1564 fprintf (stderr, "DEBUG: Setting IP6 address: %s/%d\n",address,prefix_len); 1570 fprintf(stderr, "DEBUG: Setting IP6 address: %s/%d\n", address, prefix_len);
1565 if (0 != (global_ret = set_address6 (address, prefix_len))) 1571 if (0 != (global_ret = set_address6(address, prefix_len)))
1566 goto cleanup; 1572 goto cleanup;
1567 1573
1568 have_ip6 = TRUE; 1574 have_ip6 = TRUE;
1569 } 1575 }
1570 1576
1571 if (0 != strcmp (argv[4], "-")) 1577 if (0 != strcmp(argv[4], "-"))
1572 { 1578 {
1573 const char *address = argv[4]; 1579 const char *address = argv[4];
1574 const char *mask = argv[5]; 1580 const char *mask = argv[5];
1575 1581
1576 fprintf (stderr, "DEBUG: Setting IP4 address: %s/%s\n",address,mask); 1582 fprintf(stderr, "DEBUG: Setting IP4 address: %s/%s\n", address, mask);
1577 if (0 != (global_ret = set_address4 (address, mask))) 1583 if (0 != (global_ret = set_address4(address, mask)))
1578 goto cleanup; 1584 goto cleanup;
1579 1585
1580 have_ip4 = TRUE; 1586 have_ip4 = TRUE;
1581 } 1587 }
1582 1588
1583 run (handle); 1589 run(handle);
1584cleanup: 1590cleanup:
1585 1591
1586 if (have_ip4) 1592 if (have_ip4)
1587 { 1593 {
1588 const char *address = argv[4]; 1594 const char *address = argv[4];
1589 fprintf (stderr, "DEBUG: Removing IP4 address\n"); 1595 fprintf(stderr, "DEBUG: Removing IP4 address\n");
1590 remove_address4 (address); 1596 remove_address4(address);
1591 } 1597 }
1592 if (have_ip6) 1598 if (have_ip6)
1593 { 1599 {
1594 const char *address = argv[2]; 1600 const char *address = argv[2];
1595 fprintf (stderr, "DEBUG: Removing IP6 address\n"); 1601 fprintf(stderr, "DEBUG: Removing IP6 address\n");
1596 remove_address6 (address); 1602 remove_address6(address);
1597 } 1603 }
1598 1604
1599 fprintf (stderr, "DEBUG: removing interface\n"); 1605 fprintf(stderr, "DEBUG: removing interface\n");
1600 remove_interface (); 1606 remove_interface();
1601 fprintf (stderr, "DEBUG: graceful exit completed\n"); 1607 fprintf(stderr, "DEBUG: graceful exit completed\n");
1602 1608
1603 return global_ret; 1609 return global_ret;
1604} 1610}