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.c250
1 files changed, 125 insertions, 125 deletions
diff --git a/src/exit/gnunet-helper-exit-windows.c b/src/exit/gnunet-helper-exit-windows.c
index 461494480..bb6b6a8e4 100644
--- a/src/exit/gnunet-helper-exit-windows.c
+++ b/src/exit/gnunet-helper-exit-windows.c
@@ -19,8 +19,8 @@
19 */ 19 */
20/** 20/**
21 * @file exit/gnunet-helper-exit-windows.c 21 * @file exit/gnunet-helper-exit-windows.c
22 * @brief the helper for the EXIT service in win32 builds. 22 * @brief the helper for the EXIT service in win32 builds.
23 * Opens a virtual network-interface, sends data received on the if to stdout, 23 * Opens a virtual network-interface, sends data received on the if to stdout,
24 * sends data received on stdin to the interface 24 * sends data received on stdin to the interface
25 * @author Christian M. Fuchs 25 * @author Christian M. Fuchs
26 * 26 *
@@ -68,7 +68,7 @@
68#endif 68#endif
69 69
70/** 70/**
71 * Will this binary be run in permissions testing mode? 71 * Will this binary be run in permissions testing mode?
72 */ 72 */
73static boolean privilege_testing = FALSE; 73static boolean privilege_testing = FALSE;
74 74
@@ -90,7 +90,7 @@ static boolean privilege_testing = FALSE;
90#define INF_FILE64 "share/gnunet/openvpn-tap32/tapw64/OemWin2k.inf" 90#define INF_FILE64 "share/gnunet/openvpn-tap32/tapw64/OemWin2k.inf"
91 91
92/** 92/**
93 * Hardware ID used in the inf-file. 93 * Hardware ID used in the inf-file.
94 * This might change over time, as openvpn advances their driver 94 * This might change over time, as openvpn advances their driver
95 */ 95 */
96#define HARDWARE_ID "tap0901" 96#define HARDWARE_ID "tap0901"
@@ -101,7 +101,7 @@ static boolean privilege_testing = FALSE;
101#define TAP_WIN_MIN_MAJOR 9 101#define TAP_WIN_MIN_MAJOR 9
102 102
103/** 103/**
104 * Minimum minor-id of the driver version we can work with. 104 * Minimum minor-id of the driver version we can work with.
105 * v <= 7 has buggy IPv6. 105 * v <= 7 has buggy IPv6.
106 * v == 8 is broken for small IPv4 Packets 106 * v == 8 is broken for small IPv4 Packets
107 */ 107 */
@@ -109,7 +109,7 @@ static boolean privilege_testing = FALSE;
109 109
110/** 110/**
111 * Time in seconds to wait for our virtual device to go up after telling it to do so. 111 * Time in seconds to wait for our virtual device to go up after telling it to do so.
112 * 112 *
113 * openvpn doesn't specify a value, 4 seems sane for testing, even for openwrt 113 * openvpn doesn't specify a value, 4 seems sane for testing, even for openwrt
114 * (in fact, 4 was chosen by a fair dice roll...) 114 * (in fact, 4 was chosen by a fair dice roll...)
115 */ 115 */
@@ -121,7 +121,7 @@ static boolean privilege_testing = FALSE;
121#define INTERFACE_REGISTRY_LOCATION "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}" 121#define INTERFACE_REGISTRY_LOCATION "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
122 122
123/** 123/**
124 * Our local process' PID. Used for creating a sufficiently unique additional 124 * Our local process' PID. Used for creating a sufficiently unique additional
125 * hardware ID for our device. 125 * hardware ID for our device.
126 */ 126 */
127static char secondary_hwid[LINE_LEN / 2]; 127static char secondary_hwid[LINE_LEN / 2];
@@ -132,13 +132,13 @@ static char secondary_hwid[LINE_LEN / 2];
132 */ 132 */
133static char device_visible_name[256]; 133static char device_visible_name[256];
134 134
135/** 135/**
136 * This is our own local instance of a virtual network interface 136 * This is our own local instance of a virtual network interface
137 * It is (somewhat) equivalent to using tun/tap in unixoid systems 137 * It is (somewhat) equivalent to using tun/tap in unixoid systems
138 * 138 *
139 * Upon initialization, we create such an device node. 139 * Upon initialization, we create such an device node.
140 * Upon termination, we remove it again. 140 * Upon termination, we remove it again.
141 * 141 *
142 * If we crash this device might stay around. 142 * If we crash this device might stay around.
143 */ 143 */
144static HDEVINFO DeviceInfo = INVALID_HANDLE_VALUE; 144static HDEVINFO DeviceInfo = INVALID_HANDLE_VALUE;
@@ -149,7 +149,7 @@ static HDEVINFO DeviceInfo = INVALID_HANDLE_VALUE;
149static SP_DEVINFO_DATA DeviceNode; 149static SP_DEVINFO_DATA DeviceNode;
150 150
151/** 151/**
152 * GUID of our virtual device in the form of 152 * GUID of our virtual device in the form of
153 * {12345678-1234-1234-1234-123456789abc} - in hex 153 * {12345678-1234-1234-1234-123456789abc} - in hex
154 */ 154 */
155static char device_guid[256]; 155static char device_guid[256];
@@ -161,36 +161,36 @@ static char device_guid[256];
161enum IO_State 161enum IO_State
162{ 162{
163 163
164 /** 164 /**
165 * overlapped I/O is ready for work 165 * overlapped I/O is ready for work
166 */ 166 */
167 IOSTATE_READY = 0, 167 IOSTATE_READY = 0,
168 168
169 /** 169 /**
170 * overlapped I/O has been queued 170 * overlapped I/O has been queued
171 */ 171 */
172 IOSTATE_QUEUED, 172 IOSTATE_QUEUED,
173 173
174 /** 174 /**
175 * overlapped I/O has finished, but is waiting for it's write-partner 175 * overlapped I/O has finished, but is waiting for it's write-partner
176 */ 176 */
177 IOSTATE_WAITING, 177 IOSTATE_WAITING,
178 178
179 /** 179 /**
180 * there is a full buffer waiting 180 * there is a full buffer waiting
181 */ 181 */
182 IOSTATE_RESUME, 182 IOSTATE_RESUME,
183 183
184 /** 184 /**
185 * Operlapped IO states for facility objects 185 * Operlapped IO states for facility objects
186 * overlapped I/O has failed, stop processing 186 * overlapped I/O has failed, stop processing
187 */ 187 */
188 IOSTATE_FAILED 188 IOSTATE_FAILED
189 189
190}; 190};
191 191
192 192
193/** 193/**
194 * A IO Object + read/writebuffer + buffer-size for windows asynchronous IO handling 194 * A IO Object + read/writebuffer + buffer-size for windows asynchronous IO handling
195 */ 195 */
196struct io_facility 196struct io_facility
@@ -229,7 +229,7 @@ struct io_facility
229 * Amount of data actually written or read by readfile/writefile. 229 * Amount of data actually written or read by readfile/writefile.
230 */ 230 */
231 DWORD buffer_size_processed; 231 DWORD buffer_size_processed;
232 232
233 /** 233 /**
234 * How much of this buffer we have written in total 234 * How much of this buffer we have written in total
235 */ 235 */
@@ -248,32 +248,32 @@ typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
248 248
249/** 249/**
250 * Determines if the host OS is win32 or win64 250 * Determines if the host OS is win32 or win64
251 * 251 *
252 * @return true if 252 * @return true if
253 */ 253 */
254BOOL 254BOOL
255is_win64 () 255is_win64 ()
256{ 256{
257#if defined(_WIN64) 257#if defined(_WIN64)
258 //this is a win64 binary, 258 //this is a win64 binary,
259 return TRUE; 259 return TRUE;
260#elif defined(_WIN32) 260#elif defined(_WIN32)
261 //this is a 32bit binary, and we need to check if we are running in WOW64 261 //this is a 32bit binary, and we need to check if we are running in WOW64
262 BOOL success = FALSE; 262 BOOL success = FALSE;
263 BOOL on_wow64 = FALSE; 263 BOOL on_wow64 = FALSE;
264 LPFN_ISWOW64PROCESS IsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress (GetModuleHandle ("kernel32"), "IsWow64Process"); 264 LPFN_ISWOW64PROCESS IsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress (GetModuleHandle ("kernel32"), "IsWow64Process");
265 265
266 if (NULL != IsWow64Process) 266 if (NULL != IsWow64Process)
267 success = IsWow64Process (GetCurrentProcess (), &on_wow64); 267 success = IsWow64Process (GetCurrentProcess (), &on_wow64);
268 268
269 return success && on_wow64; 269 return success && on_wow64;
270#endif 270#endif
271} 271}
272/** 272/**
273 * Wrapper for executing a shellcommand in windows. 273 * Wrapper for executing a shellcommand in windows.
274 * 274 *
275 * @param command - the command + parameters to execute 275 * @param command - the command + parameters to execute
276 * @return * exitcode of the program executed, 276 * @return * exitcode of the program executed,
277 * * EINVAL (cmd/file not found) 277 * * EINVAL (cmd/file not found)
278 * * EPIPE (could not read STDOUT) 278 * * EPIPE (could not read STDOUT)
279 */ 279 */
@@ -393,7 +393,7 @@ set_address4 (const char *address, const char *mask)
393 strerror (errno)); 393 strerror (errno));
394 return -1; 394 return -1;
395 } 395 }
396 // Set Device to Subnet-Mode? 396 // Set Device to Subnet-Mode?
397 // do we really need tun.c:2925 ? 397 // do we really need tun.c:2925 ?
398 398
399 /* 399 /*
@@ -445,8 +445,8 @@ remove_address4 (const char *address)
445 445
446 446
447/** 447/**
448 * Setup a new virtual interface to use for tunneling. 448 * Setup a new virtual interface to use for tunneling.
449 * 449 *
450 * @return: TRUE if setup was successful, else FALSE 450 * @return: TRUE if setup was successful, else FALSE
451 */ 451 */
452static BOOL 452static BOOL
@@ -454,7 +454,7 @@ setup_interface ()
454{ 454{
455 /* 455 /*
456 * where to find our inf-file. (+ the "full" path, after windows found") 456 * where to find our inf-file. (+ the "full" path, after windows found")
457 * 457 *
458 * We do not directly input all the props here, because openvpn will update 458 * We do not directly input all the props here, because openvpn will update
459 * these details over time. 459 * these details over time.
460 */ 460 */
@@ -465,22 +465,22 @@ setup_interface ()
465 GUID class_guid; 465 GUID class_guid;
466 int str_length = 0; 466 int str_length = 0;
467 467
468 /** 468 /**
469 * Set the device's hardware ID and add it to a list. 469 * Set the device's hardware ID and add it to a list.
470 * This information will later on identify this device in registry. 470 * This information will later on identify this device in registry.
471 */ 471 */
472 strncpy (hwidlist, HARDWARE_ID, LINE_LEN); 472 strncpy (hwidlist, HARDWARE_ID, LINE_LEN);
473 /** 473 /**
474 * this is kind of over-complicated, but allows keeps things independent of 474 * this is kind of over-complicated, but allows keeps things independent of
475 * how the openvpn-hwid is actually stored. 475 * how the openvpn-hwid is actually stored.
476 * 476 *
477 * A HWID list is double-\0 terminated and \0 separated 477 * A HWID list is double-\0 terminated and \0 separated
478 */ 478 */
479 str_length = strlen (hwidlist) + 1; 479 str_length = strlen (hwidlist) + 1;
480 strncpy (&hwidlist[str_length], secondary_hwid, LINE_LEN); 480 strncpy (&hwidlist[str_length], secondary_hwid, LINE_LEN);
481 str_length += strlen (&hwidlist[str_length]) + 1; 481 str_length += strlen (&hwidlist[str_length]) + 1;
482 482
483 /** 483 /**
484 * Locate the inf-file, we need to store it somewhere where the system can 484 * Locate the inf-file, we need to store it somewhere where the system can
485 * find it. We need to pick the correct driver for win32/win64. 485 * find it. We need to pick the correct driver for win32/win64.
486 */ 486 */
@@ -490,7 +490,7 @@ setup_interface ()
490 GetFullPathNameA (INF_FILE, MAX_PATH, inf_file_path, &temp_inf_filename); 490 GetFullPathNameA (INF_FILE, MAX_PATH, inf_file_path, &temp_inf_filename);
491 491
492 fprintf (stderr, "INFO: Located our driver's .inf file at %s\n", inf_file_path); 492 fprintf (stderr, "INFO: Located our driver's .inf file at %s\n", inf_file_path);
493 /** 493 /**
494 * Bootstrap our device info using the drivers inf-file 494 * Bootstrap our device info using the drivers inf-file
495 */ 495 */
496 if ( ! SetupDiGetINFClassA (inf_file_path, 496 if ( ! SetupDiGetINFClassA (inf_file_path,
@@ -499,9 +499,9 @@ setup_interface ()
499 NULL)) 499 NULL))
500 return FALSE; 500 return FALSE;
501 501
502 /** 502 /**
503 * Collect all the other needed information... 503 * Collect all the other needed information...
504 * let the system fill our this form 504 * let the system fill our this form
505 */ 505 */
506 DeviceInfo = SetupDiCreateDeviceInfoList (&class_guid, NULL); 506 DeviceInfo = SetupDiCreateDeviceInfoList (&class_guid, NULL);
507 if (DeviceInfo == INVALID_HANDLE_VALUE) 507 if (DeviceInfo == INVALID_HANDLE_VALUE)
@@ -546,9 +546,9 @@ setup_interface ()
546 546
547 547
548/** 548/**
549 * Remove our new virtual interface to use for tunneling. 549 * Remove our new virtual interface to use for tunneling.
550 * This function must be called AFTER setup_interface! 550 * This function must be called AFTER setup_interface!
551 * 551 *
552 * @return: TRUE if destruction was successful, else FALSE 552 * @return: TRUE if destruction was successful, else FALSE
553 */ 553 */
554static BOOL 554static BOOL
@@ -564,7 +564,7 @@ remove_interface ()
564 remove.Scope = DI_REMOVEDEVICE_GLOBAL; 564 remove.Scope = DI_REMOVEDEVICE_GLOBAL;
565 remove.ClassInstallHeader.InstallFunction = DIF_REMOVE; 565 remove.ClassInstallHeader.InstallFunction = DIF_REMOVE;
566 /* 566 /*
567 * 1. Prepare our existing device information set, and place the 567 * 1. Prepare our existing device information set, and place the
568 * uninstall related information into the structure 568 * uninstall related information into the structure
569 */ 569 */
570 if ( ! SetupDiSetClassInstallParamsA (DeviceInfo, 570 if ( ! SetupDiSetClassInstallParamsA (DeviceInfo,
@@ -581,7 +581,7 @@ remove_interface ()
581 return FALSE; 581 return FALSE;
582 582
583 SetupDiDestroyDeviceInfoList (DeviceInfo); 583 SetupDiDestroyDeviceInfoList (DeviceInfo);
584 584
585 fprintf (stderr, "DEBUG: removed interface successfully\n"); 585 fprintf (stderr, "DEBUG: removed interface successfully\n");
586 586
587 return TRUE; 587 return TRUE;
@@ -590,8 +590,8 @@ remove_interface ()
590 590
591/** 591/**
592 * Do all the lookup necessary to retrieve the inteface's actual name 592 * Do all the lookup necessary to retrieve the inteface's actual name
593 * off the registry. 593 * off the registry.
594 * 594 *
595 * @return: TRUE if we were able to lookup the interface's name, else FALSE 595 * @return: TRUE if we were able to lookup the interface's name, else FALSE
596 */ 596 */
597static BOOL 597static BOOL
@@ -615,7 +615,7 @@ resolve_interface_name ()
615 0, //must be 0 615 0, //must be 0
616 NULL)) //hMachine, we are local 616 NULL)) //hMachine, we are local
617 return FALSE; 617 return FALSE;
618 618
619 fprintf (stderr, "DEBUG: Resolving interface name for network device %s\n",pnp_instance_id); 619 fprintf (stderr, "DEBUG: Resolving interface name for network device %s\n",pnp_instance_id);
620 620
621 /* Registry is incredibly slow, retry for up to 30 seconds to allow registry to refresh */ 621 /* Registry is incredibly slow, retry for up to 30 seconds to allow registry to refresh */
@@ -633,7 +633,7 @@ resolve_interface_name ()
633 &adapter_key_handle)) 633 &adapter_key_handle))
634 return FALSE; 634 return FALSE;
635 635
636 /* Of course there is a multitude of entries here, with arbitrary names, 636 /* Of course there is a multitude of entries here, with arbitrary names,
637 * thus we need to iterate through there. 637 * thus we need to iterate through there.
638 */ 638 */
639 while (!retval) 639 while (!retval)
@@ -658,7 +658,7 @@ resolve_interface_name ()
658 NULL, 658 NULL,
659 NULL); 659 NULL);
660 660
661 /* this may fail due to one of two reasons: 661 /* this may fail due to one of two reasons:
662 * we are at the end of the list*/ 662 * we are at the end of the list*/
663 if (ERROR_NO_MORE_ITEMS == status) 663 if (ERROR_NO_MORE_ITEMS == status)
664 break; 664 break;
@@ -709,8 +709,8 @@ resolve_interface_name ()
709 if (status != ERROR_SUCCESS || data_type != REG_SZ) 709 if (status != ERROR_SUCCESS || data_type != REG_SZ)
710 goto cleanup; 710 goto cleanup;
711 711
712 /* 712 /*
713 * we have successfully found OUR instance, 713 * we have successfully found OUR instance,
714 * save the device GUID before exiting 714 * save the device GUID before exiting
715 */ 715 */
716 716
@@ -732,7 +732,7 @@ cleanup:
732 732
733/** 733/**
734 * Determines the version of the installed TAP32 driver and checks if it's sufficiently new for GNUNET 734 * Determines the version of the installed TAP32 driver and checks if it's sufficiently new for GNUNET
735 * 735 *
736 * @param handle the handle to our tap device 736 * @param handle the handle to our tap device
737 * @return TRUE if the version is sufficient, else FALSE 737 * @return TRUE if the version is sufficient, else FALSE
738 */ 738 */
@@ -758,7 +758,7 @@ check_tapw32_version (HANDLE handle)
758 TAP_WIN_MIN_MINOR); 758 TAP_WIN_MIN_MINOR);
759 return FALSE; 759 return FALSE;
760 } 760 }
761 761
762 return TRUE; 762 return TRUE;
763} 763}
764 764
@@ -824,8 +824,8 @@ init_tun ()
824 824
825/** 825/**
826 * Brings a TAP device up and sets it to connected state. 826 * Brings a TAP device up and sets it to connected state.
827 * 827 *
828 * @param handle the handle to our TAP device 828 * @param handle the handle to our TAP device
829 * @return True if the operation succeeded, else false 829 * @return True if the operation succeeded, else false
830 */ 830 */
831static BOOL 831static BOOL
@@ -851,25 +851,25 @@ tun_up (HANDLE handle)
851 851
852/** 852/**
853 * Attempts to read off an input facility (tap or named pipe) in overlapped mode. 853 * Attempts to read off an input facility (tap or named pipe) in overlapped mode.
854 * 854 *
855 * 1. 855 * 1.
856 * If the input facility is in IOSTATE_READY, it will issue a new read operation to the 856 * If the input facility is in IOSTATE_READY, it will issue a new read operation to the
857 * input handle. Then it goes into IOSTATE_QUEUED state. 857 * input handle. Then it goes into IOSTATE_QUEUED state.
858 * In case the read succeeded instantly the input facility enters 3. 858 * In case the read succeeded instantly the input facility enters 3.
859 * 859 *
860 * 2. 860 * 2.
861 * If the input facility is in IOSTATE_QUEUED state, it will check if the queued read has finished already. 861 * If the input facility is in IOSTATE_QUEUED state, it will check if the queued read has finished already.
862 * If it has finished, go to state 3. 862 * If it has finished, go to state 3.
863 * If it has failed, set IOSTATE_FAILED 863 * If it has failed, set IOSTATE_FAILED
864 * 864 *
865 * 3. 865 * 3.
866 * If the output facility is in state IOSTATE_READY, the read-buffer is copied to the output buffer. 866 * If the output facility is in state IOSTATE_READY, the read-buffer is copied to the output buffer.
867 * The input facility enters state IOSTATE_READY 867 * The input facility enters state IOSTATE_READY
868 * The output facility enters state IOSTATE_READY 868 * The output facility enters state IOSTATE_READY
869 * If the output facility is in state IOSTATE_QUEUED, the input facility enters IOSTATE_WAITING 869 * If the output facility is in state IOSTATE_QUEUED, the input facility enters IOSTATE_WAITING
870 * 870 *
871 * IOSTATE_WAITING is reset by the output facility, once it has completed. 871 * IOSTATE_WAITING is reset by the output facility, once it has completed.
872 * 872 *
873 * @param input_facility input named pipe or file to work with. 873 * @param input_facility input named pipe or file to work with.
874 * @param output_facility output pipe or file to hand over data to. 874 * @param output_facility output pipe or file to hand over data to.
875 * @return false if an event reset was impossible (OS error), else true 875 * @return false if an event reset was impossible (OS error), else true
@@ -880,11 +880,11 @@ attempt_read_tap (struct io_facility * input_facility,
880{ 880{
881 struct GNUNET_MessageHeader * hdr; 881 struct GNUNET_MessageHeader * hdr;
882 unsigned short size; 882 unsigned short size;
883 883
884 switch (input_facility->facility_state) 884 switch (input_facility->facility_state)
885 { 885 {
886 case IOSTATE_READY: 886 case IOSTATE_READY:
887 { 887 {
888 if (! ResetEvent (input_facility->overlapped.hEvent)) 888 if (! ResetEvent (input_facility->overlapped.hEvent))
889 { 889 {
890 return FALSE; 890 return FALSE;
@@ -903,9 +903,9 @@ attempt_read_tap (struct io_facility * input_facility,
903 /* reset event manually*/ 903 /* reset event manually*/
904 if (! SetEvent (input_facility->overlapped.hEvent)) 904 if (! SetEvent (input_facility->overlapped.hEvent))
905 return FALSE; 905 return FALSE;
906 906
907 fprintf (stderr, "DEBUG: tap read succeeded immediately\n"); 907 fprintf (stderr, "DEBUG: tap read succeeded immediately\n");
908 908
909 /* we successfully read something from the TAP and now need to 909 /* we successfully read something from the TAP and now need to
910 * send it our via STDOUT. Is that possible at the moment? */ 910 * send it our via STDOUT. Is that possible at the moment? */
911 if ((IOSTATE_READY == output_facility->facility_state || 911 if ((IOSTATE_READY == output_facility->facility_state ||
@@ -914,7 +914,7 @@ attempt_read_tap (struct io_facility * input_facility,
914 { /* hand over this buffers content and apply message header for gnunet */ 914 { /* hand over this buffers content and apply message header for gnunet */
915 hdr = (struct GNUNET_MessageHeader *) output_facility->buffer; 915 hdr = (struct GNUNET_MessageHeader *) output_facility->buffer;
916 size = input_facility->buffer_size + sizeof (struct GNUNET_MessageHeader); 916 size = input_facility->buffer_size + sizeof (struct GNUNET_MessageHeader);
917 917
918 memcpy (output_facility->buffer + sizeof (struct GNUNET_MessageHeader), 918 memcpy (output_facility->buffer + sizeof (struct GNUNET_MessageHeader),
919 input_facility->buffer, 919 input_facility->buffer,
920 input_facility->buffer_size); 920 input_facility->buffer_size);
@@ -961,7 +961,7 @@ attempt_read_tap (struct io_facility * input_facility,
961 return FALSE; 961 return FALSE;
962 962
963 fprintf (stderr, "DEBUG: tap read succeeded delayed\n"); 963 fprintf (stderr, "DEBUG: tap read succeeded delayed\n");
964 964
965 /* we successfully read something from the TAP and now need to 965 /* we successfully read something from the TAP and now need to
966 * send it our via STDOUT. Is that possible at the moment? */ 966 * send it our via STDOUT. Is that possible at the moment? */
967 if ((IOSTATE_READY == output_facility->facility_state || 967 if ((IOSTATE_READY == output_facility->facility_state ||
@@ -970,7 +970,7 @@ attempt_read_tap (struct io_facility * input_facility,
970 { /* hand over this buffers content and apply message header for gnunet */ 970 { /* hand over this buffers content and apply message header for gnunet */
971 hdr = (struct GNUNET_MessageHeader *) output_facility->buffer; 971 hdr = (struct GNUNET_MessageHeader *) output_facility->buffer;
972 size = input_facility->buffer_size + sizeof (struct GNUNET_MessageHeader); 972 size = input_facility->buffer_size + sizeof (struct GNUNET_MessageHeader);
973 973
974 memcpy (output_facility->buffer + sizeof (struct GNUNET_MessageHeader), 974 memcpy (output_facility->buffer + sizeof (struct GNUNET_MessageHeader),
975 input_facility->buffer, 975 input_facility->buffer,
976 input_facility->buffer_size); 976 input_facility->buffer_size);
@@ -1023,26 +1023,26 @@ attempt_read_tap (struct io_facility * input_facility,
1023 1023
1024/** 1024/**
1025 * Attempts to read off an input facility (tap or named pipe) in overlapped mode. 1025 * Attempts to read off an input facility (tap or named pipe) in overlapped mode.
1026 * 1026 *
1027 * 1. 1027 * 1.
1028 * If the input facility is in IOSTATE_READY, it will issue a new read operation to the 1028 * If the input facility is in IOSTATE_READY, it will issue a new read operation to the
1029 * input handle. Then it goes into IOSTATE_QUEUED state. 1029 * input handle. Then it goes into IOSTATE_QUEUED state.
1030 * In case the read succeeded instantly the input facility enters 3. 1030 * In case the read succeeded instantly the input facility enters 3.
1031 * 1031 *
1032 * 2. 1032 * 2.
1033 * If the input facility is in IOSTATE_QUEUED state, it will check if the queued read has finished already. 1033 * If the input facility is in IOSTATE_QUEUED state, it will check if the queued read has finished already.
1034 * If it has finished, go to state 3. 1034 * If it has finished, go to state 3.
1035 * If it has failed, set IOSTATE_FAILED 1035 * If it has failed, set IOSTATE_FAILED
1036 * 1036 *
1037 * 3. 1037 * 3.
1038 * If the facility is finished with ready 1038 * If the facility is finished with ready
1039 * The read-buffer is copied to the output buffer, except for the GNUNET_MessageHeader. 1039 * The read-buffer is copied to the output buffer, except for the GNUNET_MessageHeader.
1040 * The input facility enters state IOSTATE_READY 1040 * The input facility enters state IOSTATE_READY
1041 * The output facility enters state IOSTATE_READY 1041 * The output facility enters state IOSTATE_READY
1042 * If the output facility is in state IOSTATE_QUEUED, the input facility enters IOSTATE_WAITING 1042 * If the output facility is in state IOSTATE_QUEUED, the input facility enters IOSTATE_WAITING
1043 * 1043 *
1044 * IOSTATE_WAITING is reset by the output facility, once it has completed. 1044 * IOSTATE_WAITING is reset by the output facility, once it has completed.
1045 * 1045 *
1046 * @param input_facility input named pipe or file to work with. 1046 * @param input_facility input named pipe or file to work with.
1047 * @param output_facility output pipe or file to hand over data to. 1047 * @param output_facility output pipe or file to hand over data to.
1048 * @return false if an event reset was impossible (OS error), else true 1048 * @return false if an event reset was impossible (OS error), else true
@@ -1052,17 +1052,17 @@ attempt_read_stdin (struct io_facility * input_facility,
1052 struct io_facility * output_facility) 1052 struct io_facility * output_facility)
1053{ 1053{
1054 struct GNUNET_MessageHeader * hdr; 1054 struct GNUNET_MessageHeader * hdr;
1055 1055
1056 switch (input_facility->facility_state) 1056 switch (input_facility->facility_state)
1057 { 1057 {
1058 case IOSTATE_READY: 1058 case IOSTATE_READY:
1059 { 1059 {
1060 input_facility->buffer_size = 0; 1060 input_facility->buffer_size = 0;
1061 1061
1062partial_read_iostate_ready: 1062partial_read_iostate_ready:
1063 if (! ResetEvent (input_facility->overlapped.hEvent)) 1063 if (! ResetEvent (input_facility->overlapped.hEvent))
1064 return FALSE; 1064 return FALSE;
1065 1065
1066 /* Check how the task is handled */ 1066 /* Check how the task is handled */
1067 if (ReadFile (input_facility->handle, 1067 if (ReadFile (input_facility->handle,
1068 input_facility->buffer + input_facility->buffer_size, 1068 input_facility->buffer + input_facility->buffer_size,
@@ -1110,7 +1110,7 @@ partial_read_iostate_ready:
1110 input_facility->facility_state = IOSTATE_WAITING; 1110 input_facility->facility_state = IOSTATE_WAITING;
1111 else /* we read nothing */ 1111 else /* we read nothing */
1112 input_facility->facility_state = IOSTATE_READY; 1112 input_facility->facility_state = IOSTATE_READY;
1113 } 1113 }
1114 else /* operation was either queued or failed*/ 1114 else /* operation was either queued or failed*/
1115 { 1115 {
1116 int err = GetLastError (); 1116 int err = GetLastError ();
@@ -1138,13 +1138,13 @@ partial_read_iostate_ready:
1138 FALSE)) 1138 FALSE))
1139 {/* successful return for a queued operation */ 1139 {/* successful return for a queued operation */
1140 hdr = (struct GNUNET_MessageHeader *) input_facility->buffer; 1140 hdr = (struct GNUNET_MessageHeader *) input_facility->buffer;
1141 1141
1142 if (! ResetEvent (input_facility->overlapped.hEvent)) 1142 if (! ResetEvent (input_facility->overlapped.hEvent))
1143 return FALSE; 1143 return FALSE;
1144 1144
1145 fprintf (stderr, "DEBUG: stdin read succeeded delayed\n"); 1145 fprintf (stderr, "DEBUG: stdin read succeeded delayed\n");
1146 input_facility->buffer_size += input_facility->buffer_size_processed; 1146 input_facility->buffer_size += input_facility->buffer_size_processed;
1147 1147
1148 if ((ntohs (hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) || 1148 if ((ntohs (hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) ||
1149 (ntohs (hdr->size) > sizeof (input_facility->buffer))) 1149 (ntohs (hdr->size) > sizeof (input_facility->buffer)))
1150 { 1150 {
@@ -1206,7 +1206,7 @@ partial_read_iostate_ready:
1206 * Attempts to write to an output facility (tap or named pipe) in overlapped mode. 1206 * Attempts to write to an output facility (tap or named pipe) in overlapped mode.
1207 * 1207 *
1208 * TODO: high level description 1208 * TODO: high level description
1209 * 1209 *
1210 * @param output_facility output pipe or file to hand over data to. 1210 * @param output_facility output pipe or file to hand over data to.
1211 * @param input_facility input named pipe or file to work with. 1211 * @param input_facility input named pipe or file to work with.
1212 * @return false if an event reset was impossible (OS error), else true 1212 * @return false if an event reset was impossible (OS error), else true
@@ -1219,7 +1219,7 @@ attempt_write (struct io_facility * output_facility,
1219 { 1219 {
1220 case IOSTATE_READY: 1220 case IOSTATE_READY:
1221 output_facility->buffer_size_written = 0; 1221 output_facility->buffer_size_written = 0;
1222 1222
1223continue_partial_write: 1223continue_partial_write:
1224 if (! ResetEvent (output_facility->overlapped.hEvent)) 1224 if (! ResetEvent (output_facility->overlapped.hEvent))
1225 return FALSE; 1225 return FALSE;
@@ -1234,7 +1234,7 @@ continue_partial_write:
1234 1234
1235 fprintf (stderr, "DEBUG: write succeeded immediately\n"); 1235 fprintf (stderr, "DEBUG: write succeeded immediately\n");
1236 output_facility->buffer_size_written += output_facility->buffer_size_processed; 1236 output_facility->buffer_size_written += output_facility->buffer_size_processed;
1237 1237
1238 /* reset event manually*/ 1238 /* reset event manually*/
1239 if (! SetEvent (output_facility->overlapped.hEvent)) 1239 if (! SetEvent (output_facility->overlapped.hEvent))
1240 return FALSE; 1240 return FALSE;
@@ -1242,7 +1242,7 @@ continue_partial_write:
1242 /* partial write */ 1242 /* partial write */
1243 if (output_facility->buffer_size_written < output_facility->buffer_size) 1243 if (output_facility->buffer_size_written < output_facility->buffer_size)
1244 goto continue_partial_write; 1244 goto continue_partial_write;
1245 1245
1246 /* we are now waiting for our buffer to be filled*/ 1246 /* we are now waiting for our buffer to be filled*/
1247 output_facility->facility_state = IOSTATE_WAITING; 1247 output_facility->facility_state = IOSTATE_WAITING;
1248 1248
@@ -1269,7 +1269,7 @@ continue_partial_write:
1269 return TRUE; 1269 return TRUE;
1270 case IOSTATE_QUEUED: 1270 case IOSTATE_QUEUED:
1271 // there was an operation going on already, check if that has completed now. 1271 // there was an operation going on already, check if that has completed now.
1272 1272
1273 if (GetOverlappedResult (output_facility->handle, 1273 if (GetOverlappedResult (output_facility->handle,
1274 &output_facility->overlapped, 1274 &output_facility->overlapped,
1275 &output_facility->buffer_size_processed, 1275 &output_facility->buffer_size_processed,
@@ -1277,17 +1277,17 @@ continue_partial_write:
1277 {/* successful return for a queued operation */ 1277 {/* successful return for a queued operation */
1278 if (! ResetEvent (output_facility->overlapped.hEvent)) 1278 if (! ResetEvent (output_facility->overlapped.hEvent))
1279 return FALSE; 1279 return FALSE;
1280 1280
1281 fprintf (stderr, "DEBUG: write succeeded delayed\n"); 1281 fprintf (stderr, "DEBUG: write succeeded delayed\n");
1282 output_facility->buffer_size_written += output_facility->buffer_size_processed; 1282 output_facility->buffer_size_written += output_facility->buffer_size_processed;
1283 1283
1284 /* partial write */ 1284 /* partial write */
1285 if (output_facility->buffer_size_written < output_facility->buffer_size) 1285 if (output_facility->buffer_size_written < output_facility->buffer_size)
1286 goto continue_partial_write; 1286 goto continue_partial_write;
1287 1287
1288 /* we are now waiting for our buffer to be filled*/ 1288 /* we are now waiting for our buffer to be filled*/
1289 output_facility->facility_state = IOSTATE_WAITING; 1289 output_facility->facility_state = IOSTATE_WAITING;
1290 1290
1291 /* we successfully wrote something and now need to reset our reader */ 1291 /* we successfully wrote something and now need to reset our reader */
1292 if (IOSTATE_WAITING == input_facility->facility_state) 1292 if (IOSTATE_WAITING == input_facility->facility_state)
1293 input_facility->facility_state = IOSTATE_RESUME; 1293 input_facility->facility_state = IOSTATE_RESUME;
@@ -1304,7 +1304,7 @@ continue_partial_write:
1304 fprintf (stderr, "FATAL: Write to handle failed, exiting\n"); 1304 fprintf (stderr, "FATAL: Write to handle failed, exiting\n");
1305 } 1305 }
1306 } 1306 }
1307 default: 1307 default:
1308 return TRUE; 1308 return TRUE;
1309 } 1309 }
1310} 1310}
@@ -1312,7 +1312,7 @@ continue_partial_write:
1312 1312
1313/** 1313/**
1314 * Initialize a overlapped structure 1314 * Initialize a overlapped structure
1315 * 1315 *
1316 * @param elem the element to initilize 1316 * @param elem the element to initilize
1317 * @param initial_state the initial state for this instance 1317 * @param initial_state the initial state for this instance
1318 * @param signaled if the hEvent created should default to signaled or not 1318 * @param signaled if the hEvent created should default to signaled or not
@@ -1358,13 +1358,13 @@ run (HANDLE tap_handle)
1358 /* tun up: */ 1358 /* tun up: */
1359 /* we do this HERE and not beforehand (in init_tun()), in contrast to openvpn 1359 /* we do this HERE and not beforehand (in init_tun()), in contrast to openvpn
1360 * to remove the need to flush the arp cache, handle DHCP and wrong IPs. 1360 * to remove the need to flush the arp cache, handle DHCP and wrong IPs.
1361 * 1361 *
1362 * DHCP and such are all features we will never use in gnunet afaik. 1362 * DHCP and such are all features we will never use in gnunet afaik.
1363 * But for openvpn those are essential. 1363 * But for openvpn those are essential.
1364 */ 1364 */
1365 if ((privilege_testing) || (! tun_up (tap_handle) )) 1365 if ((privilege_testing) || (! tun_up (tap_handle) ))
1366 goto teardown_final; 1366 goto teardown_final;
1367 1367
1368 /* Initialize our overlapped IO structures*/ 1368 /* Initialize our overlapped IO structures*/
1369 if (! (initialize_io_facility (&tap_read, IOSTATE_READY, FALSE) 1369 if (! (initialize_io_facility (&tap_read, IOSTATE_READY, FALSE)
1370 && initialize_io_facility (&tap_write, IOSTATE_WAITING, TRUE) 1370 && initialize_io_facility (&tap_write, IOSTATE_WAITING, TRUE)
@@ -1380,12 +1380,12 @@ run (HANDLE tap_handle)
1380 /* Debug output to console STDIN/STDOUT*/ 1380 /* Debug output to console STDIN/STDOUT*/
1381 std_in.handle = parent_std_in_handle; 1381 std_in.handle = parent_std_in_handle;
1382 std_out.handle = parent_std_out_handle; 1382 std_out.handle = parent_std_out_handle;
1383 1383
1384#else 1384#else
1385 fprintf (stderr, "DEBUG: reopening stdin/out for overlapped IO\n"); 1385 fprintf (stderr, "DEBUG: reopening stdin/out for overlapped IO\n");
1386 /* 1386 /*
1387 * Find out the types of our handles. 1387 * Find out the types of our handles.
1388 * This part is a problem, because in windows we need to handle files, 1388 * This part is a problem, because in windows we need to handle files,
1389 * pipes and the console differently. 1389 * pipes and the console differently.
1390 */ 1390 */
1391 if ((FILE_TYPE_PIPE != GetFileType (parent_std_in_handle)) || 1391 if ((FILE_TYPE_PIPE != GetFileType (parent_std_in_handle)) ||
@@ -1417,9 +1417,9 @@ run (HANDLE tap_handle)
1417 goto teardown; 1417 goto teardown;
1418 } 1418 }
1419#endif 1419#endif
1420 1420
1421 fprintf (stderr, "DEBUG: mainloop has begun\n"); 1421 fprintf (stderr, "DEBUG: mainloop has begun\n");
1422 1422
1423 while (std_out.path_open || tap_write.path_open) 1423 while (std_out.path_open || tap_write.path_open)
1424 { 1424 {
1425 /* perform READ from stdin if possible */ 1425 /* perform READ from stdin if possible */
@@ -1439,15 +1439,15 @@ run (HANDLE tap_handle)
1439 break; 1439 break;
1440 } 1440 }
1441 fprintf (stderr, "DEBUG: teardown initiated\n"); 1441 fprintf (stderr, "DEBUG: teardown initiated\n");
1442 1442
1443teardown: 1443teardown:
1444 1444
1445 CancelIo (tap_handle); 1445 CancelIo (tap_handle);
1446 CancelIo (std_in.handle); 1446 CancelIo (std_in.handle);
1447 CancelIo (std_out.handle); 1447 CancelIo (std_out.handle);
1448 1448
1449teardown_final: 1449teardown_final:
1450 1450
1451 CloseHandle (tap_handle); 1451 CloseHandle (tap_handle);
1452} 1452}
1453 1453
@@ -1474,7 +1474,7 @@ main (int argc, char **argv)
1474 BOOL have_ip4 = FALSE; 1474 BOOL have_ip4 = FALSE;
1475 BOOL have_ip6 = FALSE; 1475 BOOL have_ip6 = FALSE;
1476 BOOL have_nat44 = FALSE; 1476 BOOL have_nat44 = FALSE;
1477 1477
1478 if ( (1 < argc) && (0 != strcmp (argv[1], "-d"))){ 1478 if ( (1 < argc) && (0 != strcmp (argv[1], "-d"))){
1479 privilege_testing = TRUE; 1479 privilege_testing = TRUE;
1480 fprintf (stderr, 1480 fprintf (stderr,
@@ -1483,10 +1483,10 @@ main (int argc, char **argv)
1483 argv++; 1483 argv++;
1484 argc--; 1484 argc--;
1485 } 1485 }
1486 1486
1487 if (6 != argc) 1487 if (6 != argc)
1488 { 1488 {
1489 fprintf (stderr, 1489 fprintf (stderr,
1490 "%s", 1490 "%s",
1491 "FATAL: must supply 6 arguments\nUsage:\ngnunet-helper-exit [-d] <if name prefix> <uplink-interface name> <address6 or \"-\"> <netbits6> <address4 or \"-\"> <netmask4>\n"); 1491 "FATAL: must supply 6 arguments\nUsage:\ngnunet-helper-exit [-d] <if name prefix> <uplink-interface name> <address6 or \"-\"> <netbits6> <address4 or \"-\"> <netmask4>\n");
1492 return 1; 1492 return 1;
@@ -1495,9 +1495,9 @@ main (int argc, char **argv)
1495 strncpy (hwid, argv[1], LINE_LEN); 1495 strncpy (hwid, argv[1], LINE_LEN);
1496 hwid[LINE_LEN - 1] = '\0'; 1496 hwid[LINE_LEN - 1] = '\0';
1497 1497
1498 /* 1498 /*
1499 * We use our PID for finding/resolving the control-panel name of our virtual 1499 * We use our PID for finding/resolving the control-panel name of our virtual
1500 * device. PIDs are (of course) unique at runtime, thus we can safely use it 1500 * device. PIDs are (of course) unique at runtime, thus we can safely use it
1501 * as additional hardware-id for our device. 1501 * as additional hardware-id for our device.
1502 */ 1502 */
1503 snprintf (secondary_hwid, LINE_LEN / 2, "%s-%d", 1503 snprintf (secondary_hwid, LINE_LEN / 2, "%s-%d",
@@ -1558,7 +1558,7 @@ main (int argc, char **argv)
1558 fprintf (stderr, "FATAL: Could not enable forwarding via netsh: %s\n", strerror (local_ret)); 1558 fprintf (stderr, "FATAL: Could not enable forwarding via netsh: %s\n", strerror (local_ret));
1559 goto cleanup; 1559 goto cleanup;
1560 } 1560 }
1561 /* we can keep IPv6 forwarding around, as all interfaces have 1561 /* we can keep IPv6 forwarding around, as all interfaces have
1562 * their forwarding mode reset to false at bootup. */ 1562 * their forwarding mode reset to false at bootup. */
1563 } 1563 }
1564 1564
@@ -1574,11 +1574,11 @@ main (int argc, char **argv)
1574 // setup NAPT, if possible 1574 // setup NAPT, if possible
1575 /* MS has REMOVED the routing/nat capabilities from Vista+, thus 1575 /* MS has REMOVED the routing/nat capabilities from Vista+, thus
1576 * we can not setup NAT like in XP or on the server. Actually the 1576 * we can not setup NAT like in XP or on the server. Actually the
1577 * the only feasible solution seems to be to use 1577 * the only feasible solution seems to be to use
1578 * Internet Connection Sharing, which introduces a horde of problems 1578 * Internet Connection Sharing, which introduces a horde of problems
1579 * such as sending out rogue-RAs on the external interface in an ipv6 1579 * such as sending out rogue-RAs on the external interface in an ipv6
1580 * network. 1580 * network.
1581 * Thus, below stuff ONLY works on 1581 * Thus, below stuff ONLY works on
1582 * WinXP SP3 1582 * WinXP SP3
1583 * Win Server 2003 SP1+ 1583 * Win Server 2003 SP1+
1584 * Win Server 2008 1584 * Win Server 2008
@@ -1637,7 +1637,7 @@ cleanup:
1637 if (0 != local_ret) 1637 if (0 != local_ret)
1638 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)); 1638 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));
1639 } 1639 }
1640 1640
1641 fprintf(stderr, "DEBUG: Removing IP4 address\n"); 1641 fprintf(stderr, "DEBUG: Removing IP4 address\n");
1642 remove_address4 (address); 1642 remove_address4 (address);
1643 } 1643 }