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.c382
1 files changed, 297 insertions, 85 deletions
diff --git a/src/vpn/gnunet-helper-vpn-windows.c b/src/vpn/gnunet-helper-vpn-windows.c
index 05a0aeeff..619eb4226 100644
--- a/src/vpn/gnunet-helper-vpn-windows.c
+++ b/src/vpn/gnunet-helper-vpn-windows.c
@@ -71,12 +71,7 @@
71 * Hardware ID used in the inf-file. 71 * Hardware ID used in the inf-file.
72 * This might change over time, as openvpn advances their driver 72 * This might change over time, as openvpn advances their driver
73 */ 73 */
74#define HARDWARE_ID "TAP0901" 74#define HARDWARE_ID "tap0901"
75
76/**
77 * Component ID if our driver
78 */
79#define TAP_WIN_COMPONENT_ID "tap0901"
80 75
81/** 76/**
82 * Minimum major-id of the driver version we can work with 77 * Minimum major-id of the driver version we can work with
@@ -142,31 +137,66 @@ static char device_guid[256];
142 */ 137 */
143struct io_facility 138struct io_facility
144{ 139{
145 HANDLE handle; 140 /**
146 141 * The mode the state machine associated with this object is in. IOSTATE_*
147 BOOL path_open; // BOOL is winbool, NOT boolean! 142 */
148 int facility_state; 143 int facility_state;
149 BOOL status;
150 144
145 /**
146 * If the path is open or blocked in general (used for quickly checking)
147 */
148 BOOL path_open; // BOOL is winbool (int), NOT boolean (unsigned char)!
149
150 /**
151 * Windows Object-Handle (used for accessing TAP and STDIN/STDOUT)
152 */
153 HANDLE handle;
154
155 /**
156 * Overlaped IO structure used for asynchronous IO in windows.
157 */
151 OVERLAPPED overlapped; 158 OVERLAPPED overlapped;
159
160 /**
161 * Buffer for reading things to and writing from...
162 */
163 unsigned char buffer[MAX_SIZE];
164
165 /**
166 * How much of this buffer was used when reading or how much data can be written
167 */
152 DWORD buffer_size; 168 DWORD buffer_size;
169
170 /**
171 * Amount of data written, is compared to buffer_size.
172 */
153 DWORD buffer_size_written; 173 DWORD buffer_size_written;
154 unsigned char buffer[MAX_SIZE];
155}; 174};
156 175
157/** 176/**
158 * Operlapped IO states for facility objects 177 * Operlapped IO states for facility objects
178 * overlapped I/O has failed, stop processing
179 */
180#define IOSTATE_FAILED -1
181/**
182 * overlapped I/O is ready for work
159 */ 183 */
160#define IOSTATE_FAILED -1 /* overlapped I/O has failed, stop processing */ 184#define IOSTATE_READY 0
161#define IOSTATE_READY 0 /* overlapped I/O is ready for work */ 185/**
162#define IOSTATE_QUEUED 1 /* overlapped I/O has been queued */ 186 * overlapped I/O has been queued
163#define IOSTATE_WAITING 3 /* overlapped I/O has finished, but is waiting for it's write-partner */ 187 */
188#define IOSTATE_QUEUED 1
189/**
190 * overlapped I/O has finished, but is waiting for it's write-partner
191 */
192#define IOSTATE_WAITING 3
164 193
165/** 194/**
166 * ReOpenFile is only available as of XP SP2 and 2003 SP1 195 * ReOpenFile is only available as of XP SP2 and 2003 SP1
167 */ 196 */
168WINBASEAPI HANDLE WINAPI ReOpenFile (HANDLE, DWORD, DWORD, DWORD); 197WINBASEAPI HANDLE WINAPI ReOpenFile (HANDLE, DWORD, DWORD, DWORD);
169 198
199
170/** 200/**
171 * Wrapper for executing a shellcommand in windows. 201 * Wrapper for executing a shellcommand in windows.
172 * 202 *
@@ -194,6 +224,7 @@ execute_shellcommand (const char *command)
194 return _pclose (pipe); 224 return _pclose (pipe);
195} 225}
196 226
227
197/** 228/**
198 * @brief Sets the IPv6-Address given in address on the interface dev 229 * @brief Sets the IPv6-Address given in address on the interface dev
199 * 230 *
@@ -236,6 +267,7 @@ set_address6 (const char *address, unsigned long prefix_len)
236 return ret; 267 return ret;
237} 268}
238 269
270
239/** 271/**
240 * @brief Removes the IPv6-Address given in address from the interface dev 272 * @brief Removes the IPv6-Address given in address from the interface dev
241 * 273 *
@@ -248,7 +280,7 @@ remove_address6 (const char *address)
248{ 280{
249 char command[LINE_LEN]; 281 char command[LINE_LEN];
250 int ret = EINVAL; 282 int ret = EINVAL;
251 283
252 // sanity checking was already done in set_address6 284 // sanity checking was already done in set_address6
253 /* 285 /*
254 * prepare the command 286 * prepare the command
@@ -312,6 +344,7 @@ set_address4 (const char *address, const char *mask)
312 return ret; 344 return ret;
313} 345}
314 346
347
315/** 348/**
316 * @brief Removes the IPv4-Address given in address from the interface dev 349 * @brief Removes the IPv4-Address given in address from the interface dev
317 * 350 *
@@ -324,7 +357,7 @@ remove_address4 (const char *address)
324{ 357{
325 char command[LINE_LEN]; 358 char command[LINE_LEN];
326 int ret = EINVAL; 359 int ret = EINVAL;
327 360
328 // sanity checking was already done in set_address4 361 // sanity checking was already done in set_address4
329 362
330 /* 363 /*
@@ -343,6 +376,7 @@ remove_address4 (const char *address)
343 fprintf (stderr, "FATAL: removing IPv4 address failed: %s\n", strerror (ret)); 376 fprintf (stderr, "FATAL: removing IPv4 address failed: %s\n", strerror (ret));
344} 377}
345 378
379
346/** 380/**
347 * Setup a new virtual interface to use for tunneling. 381 * Setup a new virtual interface to use for tunneling.
348 * 382 *
@@ -391,7 +425,7 @@ setup_interface ()
391 /** 425 /**
392 * Bootstrap our device info using the drivers inf-file 426 * Bootstrap our device info using the drivers inf-file
393 */ 427 */
394 if ( ! SetupDiGetINFClassA (inf_file_path, 428 if (!SetupDiGetINFClassA (inf_file_path,
395 &class_guid, 429 &class_guid,
396 class_name, sizeof (class_name) / sizeof (char), 430 class_name, sizeof (class_name) / sizeof (char),
397 NULL)) 431 NULL))
@@ -406,7 +440,7 @@ setup_interface ()
406 return FALSE; 440 return FALSE;
407 441
408 DeviceNode.cbSize = sizeof (SP_DEVINFO_DATA); 442 DeviceNode.cbSize = sizeof (SP_DEVINFO_DATA);
409 if ( ! SetupDiCreateDeviceInfoA (DeviceInfo, 443 if (!SetupDiCreateDeviceInfoA (DeviceInfo,
410 class_name, 444 class_name,
411 &class_guid, 445 &class_guid,
412 NULL, 446 NULL,
@@ -416,7 +450,7 @@ setup_interface ()
416 return FALSE; 450 return FALSE;
417 451
418 /* Deploy all the information collected into the registry */ 452 /* Deploy all the information collected into the registry */
419 if ( ! SetupDiSetDeviceRegistryPropertyA (DeviceInfo, 453 if (!SetupDiSetDeviceRegistryPropertyA (DeviceInfo,
420 &DeviceNode, 454 &DeviceNode,
421 SPDRP_HARDWAREID, 455 SPDRP_HARDWAREID,
422 (LPBYTE) hwidlist, 456 (LPBYTE) hwidlist,
@@ -424,14 +458,14 @@ setup_interface ()
424 return FALSE; 458 return FALSE;
425 459
426 /* Install our new class(=device) into the system */ 460 /* Install our new class(=device) into the system */
427 if ( ! SetupDiCallClassInstaller (DIF_REGISTERDEVICE, 461 if (!SetupDiCallClassInstaller (DIF_REGISTERDEVICE,
428 DeviceInfo, 462 DeviceInfo,
429 &DeviceNode)) 463 &DeviceNode))
430 return FALSE; 464 return FALSE;
431 465
432 /* This system call tends to take a while (several seconds!) on 466 /* This system call tends to take a while (several seconds!) on
433 "modern" Windoze systems */ 467 "modern" Windoze systems */
434 if ( ! UpdateDriverForPlugAndPlayDevicesA (NULL, 468 if (!UpdateDriverForPlugAndPlayDevicesA (NULL,
435 secondary_hwid, 469 secondary_hwid,
436 inf_file_path, 470 inf_file_path,
437 INSTALLFLAG_FORCE | INSTALLFLAG_NONINTERACTIVE, 471 INSTALLFLAG_FORCE | INSTALLFLAG_NONINTERACTIVE,
@@ -441,6 +475,7 @@ setup_interface ()
441 return TRUE; 475 return TRUE;
442} 476}
443 477
478
444/** 479/**
445 * Remove our new virtual interface to use for tunneling. 480 * Remove our new virtual interface to use for tunneling.
446 * This function must be called AFTER setup_interface! 481 * This function must be called AFTER setup_interface!
@@ -463,7 +498,7 @@ remove_interface ()
463 * 1. Prepare our existing device information set, and place the 498 * 1. Prepare our existing device information set, and place the
464 * uninstall related information into the structure 499 * uninstall related information into the structure
465 */ 500 */
466 if ( ! SetupDiSetClassInstallParamsA (DeviceInfo, 501 if (!SetupDiSetClassInstallParamsA (DeviceInfo,
467 (PSP_DEVINFO_DATA) & DeviceNode, 502 (PSP_DEVINFO_DATA) & DeviceNode,
468 &remove.ClassInstallHeader, 503 &remove.ClassInstallHeader,
469 sizeof (remove))) 504 sizeof (remove)))
@@ -471,7 +506,7 @@ remove_interface ()
471 /* 506 /*
472 * 2. Uninstall the virtual interface using the class installer 507 * 2. Uninstall the virtual interface using the class installer
473 */ 508 */
474 if ( ! SetupDiCallClassInstaller (DIF_REMOVE, 509 if (!SetupDiCallClassInstaller (DIF_REMOVE,
475 DeviceInfo, 510 DeviceInfo,
476 (PSP_DEVINFO_DATA) & DeviceNode)) 511 (PSP_DEVINFO_DATA) & DeviceNode))
477 return FALSE; 512 return FALSE;
@@ -481,6 +516,7 @@ remove_interface ()
481 return TRUE; 516 return TRUE;
482} 517}
483 518
519
484/** 520/**
485 * Do all the lookup necessary to retrieve the inteface's actual name 521 * Do all the lookup necessary to retrieve the inteface's actual name
486 * off the registry. 522 * off the registry.
@@ -527,7 +563,7 @@ resolve_interface_name ()
527 /* Of course there is a multitude of entries here, with arbitrary names, 563 /* Of course there is a multitude of entries here, with arbitrary names,
528 * thus we need to iterate through there. 564 * thus we need to iterate through there.
529 */ 565 */
530 while ( ! retval) 566 while (!retval)
531 { 567 {
532 char instance_key[256]; 568 char instance_key[256];
533 char query_key [256]; 569 char query_key [256];
@@ -622,6 +658,7 @@ cleanup:
622 return retval; 658 return retval;
623} 659}
624 660
661
625static boolean 662static boolean
626check_tapw32_version (HANDLE handle) 663check_tapw32_version (HANDLE handle)
627{ 664{
@@ -650,6 +687,7 @@ check_tapw32_version (HANDLE handle)
650 return TRUE; 687 return TRUE;
651} 688}
652 689
690
653/** 691/**
654 * Creates a tun-interface called dev; 692 * Creates a tun-interface called dev;
655 * 693 *
@@ -661,13 +699,13 @@ init_tun ()
661 char device_path[256]; 699 char device_path[256];
662 HANDLE handle; 700 HANDLE handle;
663 701
664 if ( ! setup_interface ()) 702 if (!setup_interface ())
665 { 703 {
666 errno = ENODEV; 704 errno = ENODEV;
667 return INVALID_HANDLE_VALUE; 705 return INVALID_HANDLE_VALUE;
668 } 706 }
669 707
670 if ( ! resolve_interface_name ()) 708 if (!resolve_interface_name ())
671 { 709 {
672 errno = ENODEV; 710 errno = ENODEV;
673 return INVALID_HANDLE_VALUE; 711 return INVALID_HANDLE_VALUE;
@@ -696,7 +734,7 @@ init_tun ()
696 } 734 }
697 735
698 /* get driver version info */ 736 /* get driver version info */
699 if ( ! check_tapw32_version (handle)) 737 if (!check_tapw32_version (handle))
700 { 738 {
701 CloseHandle (handle); 739 CloseHandle (handle);
702 return INVALID_HANDLE_VALUE; 740 return INVALID_HANDLE_VALUE;
@@ -707,6 +745,7 @@ init_tun ()
707 return handle; 745 return handle;
708} 746}
709 747
748
710/** 749/**
711 * Brings a TAP device up and sets it to connected state. 750 * Brings a TAP device up and sets it to connected state.
712 * 751 *
@@ -718,9 +757,9 @@ tun_up (HANDLE handle)
718{ 757{
719 ULONG status = TRUE; 758 ULONG status = TRUE;
720 DWORD len; 759 DWORD len;
721 if ( ! DeviceIoControl (handle, TAP_WIN_IOCTL_SET_MEDIA_STATUS, 760 if (!DeviceIoControl (handle, TAP_WIN_IOCTL_SET_MEDIA_STATUS,
722 &status, sizeof (status), 761 &status, sizeof (status),
723 &status, sizeof (status), &len, NULL)) 762 &status, sizeof (status), &len, NULL))
724 { 763 {
725 fprintf (stderr, "FATAL: TAP driver ignored request to UP interface (DeviceIoControl call)!\n"); 764 fprintf (stderr, "FATAL: TAP driver ignored request to UP interface (DeviceIoControl call)!\n");
726 return FALSE; 765 return FALSE;
@@ -733,6 +772,7 @@ tun_up (HANDLE handle)
733 772
734} 773}
735 774
775
736/** 776/**
737 * Attempts to read off an input facility (tap or named pipe) in overlapped mode. 777 * Attempts to read off an input facility (tap or named pipe) in overlapped mode.
738 * 778 *
@@ -759,29 +799,30 @@ tun_up (HANDLE handle)
759 * @return false if an event reset was impossible (OS error), else true 799 * @return false if an event reset was impossible (OS error), else true
760 */ 800 */
761static boolean 801static boolean
762attempt_read (struct io_facility * input_facility, 802attempt_read_tap (struct io_facility * input_facility,
763 struct io_facility * output_facility) 803 struct io_facility * output_facility)
764{ 804{
765 switch (input_facility->facility_state) 805 switch (input_facility->facility_state)
766 { 806 {
767 case IOSTATE_READY: 807 case IOSTATE_READY:
768 { 808 {
769 if ( ! ResetEvent (input_facility->overlapped.hEvent)) 809 BOOL status; // BOOL is winbool, NOT boolean!
810 if (!ResetEvent (input_facility->overlapped.hEvent))
770 { 811 {
771 return FALSE; 812 return FALSE;
772 } 813 }
773 input_facility->status = ReadFile (input_facility->handle, 814 status = ReadFile (input_facility->handle,
774 input_facility->buffer, 815 input_facility->buffer + sizeof (struct GNUNET_MessageHeader),
775 MAX_SIZE, 816 sizeof (input_facility->buffer) - sizeof (struct GNUNET_MessageHeader),
776 &input_facility->buffer_size, 817 &input_facility->buffer_size,
777 &input_facility->overlapped); 818 &input_facility->overlapped);
778 819
779 /* Check how the task is handled */ 820 /* Check how the task is handled */
780 if (input_facility->status) 821 if (status)
781 {/* async event processed immediately*/ 822 {/* async event processed immediately*/
782 823
783 /* reset event manually*/ 824 /* reset event manually*/
784 if ( ! SetEvent (input_facility->overlapped.hEvent)) 825 if (!SetEvent (input_facility->overlapped.hEvent))
785 return FALSE; 826 return FALSE;
786 827
787 /* we successfully read something from the TAP and now need to 828 /* we successfully read something from the TAP and now need to
@@ -792,7 +833,161 @@ attempt_read (struct io_facility * input_facility,
792 { /* hand over this buffers content */ 833 { /* hand over this buffers content */
793 memcpy (output_facility->buffer, 834 memcpy (output_facility->buffer,
794 input_facility->buffer, 835 input_facility->buffer,
795 MAX_SIZE); 836 sizeof (input_facility->buffer));
837 output_facility->buffer_size = input_facility->buffer_size;
838 output_facility->facility_state = IOSTATE_READY;
839 }
840 else if (0 < input_facility->buffer_size)
841 { /* If we have have read our buffer, wait for our write-partner*/
842 input_facility->facility_state = IOSTATE_WAITING;
843 // TODO: shall we attempt to fill our buffer or should we wait for our write-partner to finish?
844 }
845 }
846 else /* operation was either queued or failed*/
847 {
848 int err = GetLastError ();
849 if (ERROR_IO_PENDING == err)
850 { /* operation queued */
851 input_facility->facility_state = IOSTATE_QUEUED;
852 }
853 else
854 { /* error occurred, let the rest of the elements finish */
855 input_facility->path_open = FALSE;
856 input_facility->facility_state = IOSTATE_FAILED;
857 if (IOSTATE_WAITING == output_facility->facility_state)
858 output_facility->path_open = FALSE;
859
860 fprintf (stderr, "FATAL: Read from handle failed, allowing write to finish!\n");
861 }
862 }
863 }
864 return TRUE;
865 // We are queued and should check if the read has finished
866 case IOSTATE_QUEUED:
867 {
868 BOOL status; // BOOL is winbool, NOT boolean!
869
870 // there was an operation going on already, check if that has completed now.
871 status = GetOverlappedResult (input_facility->handle,
872 &input_facility->overlapped,
873 &input_facility->buffer_size,
874 FALSE);
875 if (status)
876 {/* successful return for a queued operation */
877 if (!ResetEvent (input_facility->overlapped.hEvent))
878 return FALSE;
879
880 /* we successfully read something from the TAP and now need to
881 * send it our via STDOUT. Is that possible at the moment? */
882 if ((IOSTATE_READY == output_facility->facility_state ||
883 IOSTATE_WAITING == output_facility->facility_state)
884 && 0 < input_facility->buffer_size)
885 { /* hand over this buffers content */
886 memcpy (output_facility->buffer,
887 input_facility->buffer,
888 input_facility->buffer_size);
889 output_facility->buffer_size = input_facility->buffer_size;
890 output_facility->facility_state = IOSTATE_READY;
891 input_facility->facility_state = IOSTATE_READY;
892 }
893 else if (0 < input_facility->buffer_size)
894 { /* If we have have read our buffer, wait for our write-partner*/
895 input_facility->facility_state = IOSTATE_WAITING;
896 // TODO: shall we attempt to fill our buffer or should we wait for our write-partner to finish?
897 }
898 }
899 else
900 { /* operation still pending/queued or failed? */
901 int err = GetLastError ();
902 if (ERROR_IO_INCOMPLETE != err && ERROR_IO_PENDING != err)
903 { /* error occurred, let the rest of the elements finish */
904 input_facility->path_open = FALSE;
905 input_facility->facility_state = IOSTATE_FAILED;
906 if (IOSTATE_WAITING == output_facility->facility_state)
907 output_facility->path_open = FALSE;
908 fprintf (stderr, "FATAL: Read from handle failed, allowing write to finish!\n");
909 }
910 }
911 }
912 return TRUE;
913 default:
914 return TRUE;
915 }
916}
917
918/**
919 * Attempts to read off an input facility (tap or named pipe) in overlapped mode.
920 *
921 * 1.
922 * If the input facility is in IOSTATE_READY, it will issue a new read operation to the
923 * input handle. Then it goes into IOSTATE_QUEUED state.
924 * In case the read succeeded instantly the input facility enters 3.
925 *
926 * 2.
927 * If the input facility is in IOSTATE_QUEUED state, it will check if the queued read has finished already.
928 * If it has finished, go to state 3.
929 * If it has failed, set IOSTATE_FAILED
930 *
931 * 3.
932 * If the facility is finished with ready
933 * The read-buffer is copied to the output buffer, except for the GNUNET_MessageHeader.
934 * The input facility enters state IOSTATE_READY
935 * The output facility enters state IOSTATE_READY
936 * If the output facility is in state IOSTATE_QUEUED, the input facility enters IOSTATE_WAITING
937 *
938 * IOSTATE_WAITING is reset by the output facility, once it has completed.
939 *
940 * @param input_facility input named pipe or file to work with.
941 * @param output_facility output pipe or file to hand over data to.
942 * @return false if an event reset was impossible (OS error), else true
943 */
944static boolean
945attempt_read_stdin (struct io_facility * input_facility,
946 struct io_facility * output_facility)
947{
948 switch (input_facility->facility_state)
949 {
950 case IOSTATE_READY:
951 {
952 BOOL status; // BOOL is winbool, NOT boolean!
953 if (!ResetEvent (input_facility->overlapped.hEvent))
954 {
955 return FALSE;
956 }
957 status = ReadFile (input_facility->handle,
958 input_facility->buffer,
959 sizeof (input_facility->buffer),
960 &input_facility->buffer_size,
961 &input_facility->overlapped);
962
963 /* Check how the task is handled */
964 if (status && (0 < input_facility->buffer_size))
965 {/* async event processed immediately*/
966 struct GNUNET_MessageHeader *hdr;
967
968 /* reset event manually*/
969 if (!SetEvent (input_facility->overlapped.hEvent))
970 return FALSE;
971
972 hdr = (struct GNUNET_MessageHeader *) input_facility->buffer;
973 if (ntohs (hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER ||
974 ntohs (hdr->size) > sizeof (input_facility->buffer))
975 {
976 fprintf (stderr, "WARNING: Protocol violation, got GNUnet Message type %h, size %h!\n", ntohs (hdr->type), ntohs (hdr->size));
977 input_facility->facility_state = IOSTATE_READY;
978 return TRUE;
979 }
980 //if (ntohs (hdr->size) > input_facility->buffer_size );
981 // TODO: add support for partial read
982
983 /* we successfully read something from the TAP and now need to
984 * send it our via STDOUT. Is that possible at the moment? */
985 if (IOSTATE_READY == output_facility->facility_state ||
986 IOSTATE_WAITING == output_facility->facility_state)
987 { /* hand over this buffers content */
988 memcpy (output_facility->buffer,
989 input_facility->buffer,
990 sizeof (input_facility->buffer));
796 output_facility->buffer_size = input_facility->buffer_size; 991 output_facility->buffer_size = input_facility->buffer_size;
797 output_facility->facility_state = IOSTATE_READY; 992 output_facility->facility_state = IOSTATE_READY;
798 } 993 }
@@ -801,6 +996,15 @@ attempt_read (struct io_facility * input_facility,
801 input_facility->facility_state = IOSTATE_WAITING; 996 input_facility->facility_state = IOSTATE_WAITING;
802 // TODO: shall we attempt to fill our buffer or should we wait for our write-partner to finish? 997 // TODO: shall we attempt to fill our buffer or should we wait for our write-partner to finish?
803 } 998 }
999
1000 input_facility->facility_state = IOSTATE_READY;
1001 }
1002 else if (status && 0 >= input_facility->buffer_size)
1003 {
1004 if (!SetEvent (input_facility->overlapped.hEvent))
1005 return FALSE;
1006
1007 input_facility->facility_state = IOSTATE_READY;
804 } 1008 }
805 else /* operation was either queued or failed*/ 1009 else /* operation was either queued or failed*/
806 { 1010 {
@@ -824,14 +1028,16 @@ attempt_read (struct io_facility * input_facility,
824 // We are queued and should check if the read has finished 1028 // We are queued and should check if the read has finished
825 case IOSTATE_QUEUED: 1029 case IOSTATE_QUEUED:
826 { 1030 {
1031 BOOL status; // BOOL is winbool, NOT boolean!
1032
827 // there was an operation going on already, check if that has completed now. 1033 // there was an operation going on already, check if that has completed now.
828 input_facility->status = GetOverlappedResult (input_facility->handle, 1034 status = GetOverlappedResult (input_facility->handle,
829 &input_facility->overlapped, 1035 &input_facility->overlapped,
830 &input_facility->buffer_size, 1036 &input_facility->buffer_size,
831 FALSE); 1037 FALSE);
832 if (input_facility->status) 1038 if (status)
833 {/* successful return for a queued operation */ 1039 {/* successful return for a queued operation */
834 if ( ! ResetEvent (input_facility->overlapped.hEvent)) 1040 if (!ResetEvent (input_facility->overlapped.hEvent))
835 return FALSE; 1041 return FALSE;
836 1042
837 /* we successfully read something from the TAP and now need to 1043 /* we successfully read something from the TAP and now need to
@@ -842,7 +1048,7 @@ attempt_read (struct io_facility * input_facility,
842 { /* hand over this buffers content */ 1048 { /* hand over this buffers content */
843 memcpy (output_facility->buffer, 1049 memcpy (output_facility->buffer,
844 input_facility->buffer, 1050 input_facility->buffer,
845 MAX_SIZE); 1051 input_facility->buffer_size);
846 output_facility->buffer_size = input_facility->buffer_size; 1052 output_facility->buffer_size = input_facility->buffer_size;
847 output_facility->facility_state = IOSTATE_READY; 1053 output_facility->facility_state = IOSTATE_READY;
848 input_facility->facility_state = IOSTATE_READY; 1054 input_facility->facility_state = IOSTATE_READY;
@@ -872,6 +1078,7 @@ attempt_read (struct io_facility * input_facility,
872 } 1078 }
873} 1079}
874 1080
1081
875/** 1082/**
876 * Attempts to write to an output facility (tap or named pipe) in overlapped mode. 1083 * Attempts to write to an output facility (tap or named pipe) in overlapped mode.
877 * 1084 *
@@ -888,24 +1095,26 @@ attempt_write (struct io_facility * output_facility,
888 if (IOSTATE_READY == output_facility->facility_state 1095 if (IOSTATE_READY == output_facility->facility_state
889 && output_facility->buffer_size > 0) 1096 && output_facility->buffer_size > 0)
890 { 1097 {
891 if ( ! ResetEvent (output_facility->overlapped.hEvent)) 1098 BOOL status; // BOOL is winbool, NOT boolean!
1099
1100 if (!ResetEvent (output_facility->overlapped.hEvent))
892 { 1101 {
893 return FALSE; 1102 return FALSE;
894 } 1103 }
895 1104
896 output_facility->status = WriteFile (output_facility->handle, 1105 status = WriteFile (output_facility->handle,
897 output_facility->buffer, 1106 output_facility->buffer,
898 output_facility->buffer_size, 1107 output_facility->buffer_size,
899 &output_facility->buffer_size_written, 1108 &output_facility->buffer_size_written,
900 &output_facility->overlapped); 1109 &output_facility->overlapped);
901 1110
902 /* Check how the task is handled */ 1111 /* Check how the task is handled */
903 if (output_facility->status && 1112 if (status &&
904 output_facility->buffer_size_written == output_facility->buffer_size) 1113 output_facility->buffer_size_written == output_facility->buffer_size)
905 {/* async event processed immediately*/ 1114 {/* async event processed immediately*/
906 1115
907 /* reset event manually*/ 1116 /* reset event manually*/
908 if ( ! SetEvent (output_facility->overlapped.hEvent)) 1117 if (!SetEvent (output_facility->overlapped.hEvent))
909 return FALSE; 1118 return FALSE;
910 1119
911 /* we are now waiting for our buffer to be filled*/ 1120 /* we are now waiting for our buffer to be filled*/
@@ -937,15 +1146,16 @@ attempt_write (struct io_facility * output_facility,
937 } 1146 }
938 else if (IOSTATE_QUEUED == output_facility->facility_state) 1147 else if (IOSTATE_QUEUED == output_facility->facility_state)
939 { 1148 {
1149 BOOL status; // BOOL is winbool, NOT boolean!
940 // there was an operation going on already, check if that has completed now. 1150 // there was an operation going on already, check if that has completed now.
941 output_facility->status = GetOverlappedResult (output_facility->handle, 1151 status = GetOverlappedResult (output_facility->handle,
942 &output_facility->overlapped, 1152 &output_facility->overlapped,
943 &output_facility->buffer_size_written, 1153 &output_facility->buffer_size_written,
944 FALSE); 1154 FALSE);
945 if (output_facility->status && 1155 if (status &&
946 output_facility->buffer_size_written == output_facility->buffer_size) 1156 output_facility->buffer_size_written == output_facility->buffer_size)
947 {/* successful return for a queued operation */ 1157 {/* successful return for a queued operation */
948 if ( ! ResetEvent (output_facility->overlapped.hEvent)) 1158 if (!ResetEvent (output_facility->overlapped.hEvent))
949 return FALSE; 1159 return FALSE;
950 1160
951 /* we are now waiting for our buffer to be filled*/ 1161 /* we are now waiting for our buffer to be filled*/
@@ -974,6 +1184,7 @@ attempt_write (struct io_facility * output_facility,
974 return TRUE; 1184 return TRUE;
975} 1185}
976 1186
1187
977/** 1188/**
978 * Initialize a overlapped structure 1189 * Initialize a overlapped structure
979 * 1190 *
@@ -984,14 +1195,13 @@ attempt_write (struct io_facility * output_facility,
984 */ 1195 */
985static boolean 1196static boolean
986initialize_io_facility (struct io_facility * elem, 1197initialize_io_facility (struct io_facility * elem,
987 BOOL initial_state, 1198 int initial_state,
988 BOOL signaled) 1199 BOOL signaled)
989{ 1200{
990 1201
991 elem->path_open = TRUE; 1202 elem->path_open = TRUE;
992 elem->status = initial_state;
993 elem->handle = INVALID_HANDLE_VALUE; 1203 elem->handle = INVALID_HANDLE_VALUE;
994 elem->facility_state = 0; 1204 elem->facility_state = initial_state;
995 elem->buffer_size = 0; 1205 elem->buffer_size = 0;
996 elem->overlapped.hEvent = CreateEvent (NULL, TRUE, signaled, NULL); 1206 elem->overlapped.hEvent = CreateEvent (NULL, TRUE, signaled, NULL);
997 if (NULL == elem->overlapped.hEvent) 1207 if (NULL == elem->overlapped.hEvent)
@@ -1000,6 +1210,7 @@ initialize_io_facility (struct io_facility * elem,
1000 return TRUE; 1210 return TRUE;
1001} 1211}
1002 1212
1213
1003/** 1214/**
1004 * Start forwarding to and from the tunnel. 1215 * Start forwarding to and from the tunnel.
1005 * 1216 *
@@ -1027,14 +1238,14 @@ run (HANDLE tap_handle)
1027 * DHCP and such are all features we will never use in gnunet afaik. 1238 * DHCP and such are all features we will never use in gnunet afaik.
1028 * But for openvpn those are essential. 1239 * But for openvpn those are essential.
1029 */ 1240 */
1030 if ( ! tun_up (tap_handle)) 1241 if (!tun_up (tap_handle))
1031 return; 1242 return;
1032 1243
1033 /* Initialize our overlapped IO structures*/ 1244 /* Initialize our overlapped IO structures*/
1034 if ( ! (initialize_io_facility (&tap_read, TRUE, FALSE) 1245 if (!(initialize_io_facility (&tap_read, IOSTATE_READY, FALSE)
1035 && initialize_io_facility (&tap_write, FALSE, TRUE) 1246 && initialize_io_facility (&tap_write, IOSTATE_WAITING, TRUE)
1036 && initialize_io_facility (&std_in, TRUE, FALSE) 1247 && initialize_io_facility (&std_in, IOSTATE_READY, FALSE)
1037 && initialize_io_facility (&std_out, FALSE, TRUE))) 1248 && initialize_io_facility (&std_out, IOSTATE_WAITING, TRUE)))
1038 goto teardown_final; 1249 goto teardown_final;
1039 1250
1040 /* Handles for STDIN and STDOUT */ 1251 /* Handles for STDIN and STDOUT */
@@ -1050,8 +1261,6 @@ run (HANDLE tap_handle)
1050 FILE_TYPE_PIPE != GetFileType (parent_std_out_handle)) 1261 FILE_TYPE_PIPE != GetFileType (parent_std_out_handle))
1051 { 1262 {
1052 fprintf (stderr, "ERROR: stdin/stdout must be named pipes!\n"); 1263 fprintf (stderr, "ERROR: stdin/stdout must be named pipes!\n");
1053 printf("\nPress Enter to continue...");
1054 getchar();
1055 goto teardown; 1264 goto teardown;
1056 } 1265 }
1057 1266
@@ -1080,19 +1289,19 @@ run (HANDLE tap_handle)
1080 while (std_out.path_open || tap_write.path_open) 1289 while (std_out.path_open || tap_write.path_open)
1081 { 1290 {
1082 /* perform READ from stdin if possible */ 1291 /* perform READ from stdin if possible */
1083 if (std_in.path_open && tap_write.path_open && !attempt_read (&std_in, &tap_write)) 1292 if (std_in.path_open && tap_write.path_open && (!attempt_read_stdin (&std_in, &tap_write)))
1084 break; 1293 break;
1085 1294
1086 /* perform READ from tap if possible */ 1295 /* perform READ from tap if possible */
1087 if (tap_read.path_open && std_out.path_open && !attempt_read (&tap_read, &std_out)) 1296 if (tap_read.path_open && std_out.path_open && (!attempt_read_tap (&tap_read, &std_out)))
1088 break; 1297 break;
1089 1298
1090 /* perform WRITE to tap if possible */ 1299 /* perform WRITE to tap if possible */
1091 if (tap_write.path_open && !attempt_write (&tap_write, &std_in)) 1300 if (tap_write.path_open && (!attempt_write (&tap_write, &std_in)))
1092 break; 1301 break;
1093 1302
1094 /* perform WRITE to STDOUT if possible */ 1303 /* perform WRITE to STDOUT if possible */
1095 if (std_out.path_open && !attempt_write (&std_out, &tap_read)) 1304 if (std_out.path_open && (!attempt_write (&std_out, &tap_read)))
1096 break; 1305 break;
1097 } 1306 }
1098 1307
@@ -1107,6 +1316,7 @@ teardown_final:
1107 CloseHandle (tap_handle); 1316 CloseHandle (tap_handle);
1108} 1317}
1109 1318
1319
1110/** 1320/**
1111 * Open VPN tunnel interface. 1321 * Open VPN tunnel interface.
1112 * 1322 *
@@ -1124,8 +1334,8 @@ main (int argc, char **argv)
1124 char hwid[LINE_LEN]; 1334 char hwid[LINE_LEN];
1125 HANDLE handle; 1335 HANDLE handle;
1126 int global_ret = 0; 1336 int global_ret = 0;
1127 boolean have_ip4=FALSE; 1337 boolean have_ip4 = FALSE;
1128 boolean have_ip6=FALSE; 1338 boolean have_ip6 = FALSE;
1129 1339
1130 if (6 != argc) 1340 if (6 != argc)
1131 { 1341 {
@@ -1171,7 +1381,7 @@ main (int argc, char **argv)
1171 1381
1172 if (0 != (global_ret = set_address6 (address, prefix_len))) 1382 if (0 != (global_ret = set_address6 (address, prefix_len)))
1173 goto cleanup; 1383 goto cleanup;
1174 1384
1175 have_ip6 = TRUE; 1385 have_ip6 = TRUE;
1176 } 1386 }
1177 1387
@@ -1182,7 +1392,7 @@ main (int argc, char **argv)
1182 1392
1183 if (0 != (global_ret = set_address4 (address, mask))) 1393 if (0 != (global_ret = set_address4 (address, mask)))
1184 goto cleanup; 1394 goto cleanup;
1185 1395
1186 have_ip4 = TRUE; 1396 have_ip4 = TRUE;
1187 } 1397 }
1188 1398
@@ -1190,13 +1400,15 @@ main (int argc, char **argv)
1190 global_ret = 0; 1400 global_ret = 0;
1191cleanup: 1401cleanup:
1192 1402
1193 if (have_ip4){ 1403 if (have_ip4)
1404 {
1194 const char *address = argv[4]; 1405 const char *address = argv[4];
1195 remove_address4(address); 1406 remove_address4 (address);
1196 } 1407 }
1197 if (have_ip6){ 1408 if (have_ip6)
1409 {
1198 const char *address = argv[2]; 1410 const char *address = argv[2];
1199 remove_address6(address); 1411 remove_address6 (address);
1200 } 1412 }
1201 remove_interface (); 1413 remove_interface ();
1202 return global_ret; 1414 return global_ret;