aboutsummaryrefslogtreecommitdiff
path: root/src/vpn
diff options
context:
space:
mode:
authorChristian Fuchs <christian.fuchs@cfuchs.net>2013-01-24 08:23:16 +0000
committerChristian Fuchs <christian.fuchs@cfuchs.net>2013-01-24 08:23:16 +0000
commitfd62371e581bda804c67b3e60ccbd8000a7cd3ad (patch)
tree5d05238175605f8096d71fc923aecad7bc975314 /src/vpn
parent6d6233a449e848720c8caf2cd32ecf11a3c66147 (diff)
downloadgnunet-fd62371e581bda804c67b3e60ccbd8000a7cd3ad.tar.gz
gnunet-fd62371e581bda804c67b3e60ccbd8000a7cd3ad.zip
added ip-address remove functions
newly set IP addresses now should expire upon reboot (buggy on some windows, but at least it solves the IP-persistence issues in win7 and above) cloned read functions to properly apply or strip the gnunet message header removed the status BOOL from the overlapped struct and made it local some fixes here and there added a lot of comments style adjustments TODO: * actually strip the gnunet message header or apply it again * test with the main vpn binary
Diffstat (limited to 'src/vpn')
-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;