aboutsummaryrefslogtreecommitdiff
path: root/src/vpn
diff options
context:
space:
mode:
authorChristian Fuchs <christian.fuchs@cfuchs.net>2013-01-24 12:49:52 +0000
committerChristian Fuchs <christian.fuchs@cfuchs.net>2013-01-24 12:49:52 +0000
commit77da27b63ae4c24ff737fd2212f765a1b9b06de0 (patch)
tree572c2c4b19528ff6a6b9a76d39d45475780b0c94 /src/vpn
parent978b2684641b79bb7b7e4a1378d9f0f6d0f1a443 (diff)
downloadgnunet-77da27b63ae4c24ff737fd2212f765a1b9b06de0.tar.gz
gnunet-77da27b63ae4c24ff737fd2212f765a1b9b06de0.zip
added IOSTATE_RESUME and related code to state machines
Diffstat (limited to 'src/vpn')
-rw-r--r--src/vpn/gnunet-helper-vpn-windows.c124
1 files changed, 76 insertions, 48 deletions
diff --git a/src/vpn/gnunet-helper-vpn-windows.c b/src/vpn/gnunet-helper-vpn-windows.c
index 07285722e..3a9702096 100644
--- a/src/vpn/gnunet-helper-vpn-windows.c
+++ b/src/vpn/gnunet-helper-vpn-windows.c
@@ -155,6 +155,11 @@ enum IO_State
155 IOSTATE_WAITING, 155 IOSTATE_WAITING,
156 156
157 /** 157 /**
158 * there is a full buffer waiting
159 */
160 IOSTATE_RESUME,
161
162 /**
158 * Operlapped IO states for facility objects 163 * Operlapped IO states for facility objects
159 * overlapped I/O has failed, stop processing 164 * overlapped I/O has failed, stop processing
160 */ 165 */
@@ -204,7 +209,6 @@ struct io_facility
204 DWORD buffer_size_written; 209 DWORD buffer_size_written;
205}; 210};
206 211
207
208/** 212/**
209 * ReOpenFile is only available as of XP SP2 and 2003 SP1 213 * ReOpenFile is only available as of XP SP2 and 2003 SP1
210 */ 214 */
@@ -674,7 +678,10 @@ cleanup:
674 678
675 679
676/** 680/**
677 * FIXME. 681 * Determines the version of the installed TAP32 driver and checks if it's sufficiently new for GNUNET
682 *
683 * @param handle the handle to our tap device
684 * @return TRUE if the version is sufficient, else FALSE
678 */ 685 */
679static boolean 686static boolean
680check_tapw32_version (HANDLE handle) 687check_tapw32_version (HANDLE handle)
@@ -687,20 +694,18 @@ check_tapw32_version (HANDLE handle)
687 if (DeviceIoControl (handle, TAP_WIN_IOCTL_GET_VERSION, 694 if (DeviceIoControl (handle, TAP_WIN_IOCTL_GET_VERSION,
688 &version, sizeof (version), 695 &version, sizeof (version),
689 &version, sizeof (version), &len, NULL)) 696 &version, sizeof (version), &len, NULL))
690 {
691 fprintf (stderr, "INFO: TAP-Windows Driver Version %d.%d %s\n", 697 fprintf (stderr, "INFO: TAP-Windows Driver Version %d.%d %s\n",
692 (int) version[0], 698 (int) version[0],
693 (int) version[1], 699 (int) version[1],
694 (version[2] ? "(DEBUG)" : "")); 700 (version[2] ? "(DEBUG)" : ""));
695 }
696 701
697 if (version[0] != TAP_WIN_MIN_MAJOR || version[1] < TAP_WIN_MIN_MINOR) 702 if (version[0] != TAP_WIN_MIN_MAJOR || version[1] < TAP_WIN_MIN_MINOR){
698 {
699 fprintf (stderr, "FATAL: This version of gnunet requires a TAP-Windows driver that is at least version %d.%d!\n", 703 fprintf (stderr, "FATAL: This version of gnunet requires a TAP-Windows driver that is at least version %d.%d!\n",
700 TAP_WIN_MIN_MAJOR, 704 TAP_WIN_MIN_MAJOR,
701 TAP_WIN_MIN_MINOR); 705 TAP_WIN_MIN_MINOR);
702 return FALSE; 706 return FALSE;
703 } 707 }
708
704 return TRUE; 709 return TRUE;
705} 710}
706 711
@@ -819,6 +824,9 @@ static boolean
819attempt_read_tap (struct io_facility * input_facility, 824attempt_read_tap (struct io_facility * input_facility,
820 struct io_facility * output_facility) 825 struct io_facility * output_facility)
821{ 826{
827 struct GNUNET_MessageHeader * hdr;
828 unsigned short size;
829
822 switch (input_facility->facility_state) 830 switch (input_facility->facility_state)
823 { 831 {
824 case IOSTATE_READY: 832 case IOSTATE_READY:
@@ -828,6 +836,8 @@ attempt_read_tap (struct io_facility * input_facility,
828 { 836 {
829 return FALSE; 837 return FALSE;
830 } 838 }
839
840 input_facility->buffer_size = 0;
831 status = ReadFile (input_facility->handle, 841 status = ReadFile (input_facility->handle,
832 input_facility->buffer, 842 input_facility->buffer,
833 sizeof (input_facility->buffer) - sizeof (struct GNUNET_MessageHeader), 843 sizeof (input_facility->buffer) - sizeof (struct GNUNET_MessageHeader),
@@ -848,15 +858,15 @@ attempt_read_tap (struct io_facility * input_facility,
848 IOSTATE_WAITING == output_facility->facility_state) 858 IOSTATE_WAITING == output_facility->facility_state)
849 && 0 < input_facility->buffer_size) 859 && 0 < input_facility->buffer_size)
850 { /* hand over this buffers content and apply message header for gnunet */ 860 { /* hand over this buffers content and apply message header for gnunet */
851 struct GNUNET_MessageHeader * hdr = (struct GNUNET_MessageHeader *) output_facility->buffer; 861 hdr = (struct GNUNET_MessageHeader *) output_facility->buffer;
852 unsigned short size = input_facility->buffer_size + sizeof (struct GNUNET_MessageHeader); 862 size = input_facility->buffer_size + sizeof (struct GNUNET_MessageHeader);
853 863
854 memcpy (output_facility->buffer + sizeof (struct GNUNET_MessageHeader), 864 memcpy (output_facility->buffer + sizeof (struct GNUNET_MessageHeader),
855 input_facility->buffer, 865 input_facility->buffer,
856 input_facility->buffer_size); 866 input_facility->buffer_size);
857 867
858 output_facility->buffer_size = size; 868 output_facility->buffer_size = size;
859 hdr->size = htons(size); 869 hdr->size = htons (size);
860 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); 870 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
861 output_facility->facility_state = IOSTATE_READY; 871 output_facility->facility_state = IOSTATE_READY;
862 } 872 }
@@ -906,8 +916,8 @@ attempt_read_tap (struct io_facility * input_facility,
906 IOSTATE_WAITING == output_facility->facility_state) 916 IOSTATE_WAITING == output_facility->facility_state)
907 && 0 < input_facility->buffer_size) 917 && 0 < input_facility->buffer_size)
908 { /* hand over this buffers content and apply message header for gnunet */ 918 { /* hand over this buffers content and apply message header for gnunet */
909 struct GNUNET_MessageHeader * hdr = (struct GNUNET_MessageHeader *) output_facility->buffer; 919 hdr = (struct GNUNET_MessageHeader *) output_facility->buffer;
910 unsigned short size = input_facility->buffer_size + sizeof (struct GNUNET_MessageHeader); 920 size = input_facility->buffer_size + sizeof (struct GNUNET_MessageHeader);
911 921
912 memcpy (output_facility->buffer + sizeof (struct GNUNET_MessageHeader), 922 memcpy (output_facility->buffer + sizeof (struct GNUNET_MessageHeader),
913 input_facility->buffer, 923 input_facility->buffer,
@@ -939,12 +949,27 @@ attempt_read_tap (struct io_facility * input_facility,
939 } 949 }
940 } 950 }
941 return TRUE; 951 return TRUE;
952 case IOSTATE_RESUME:
953 {
954 hdr = (struct GNUNET_MessageHeader *) output_facility->buffer;
955 size = input_facility->buffer_size + sizeof (struct GNUNET_MessageHeader);
956
957 memcpy (output_facility->buffer + sizeof (struct GNUNET_MessageHeader),
958 input_facility->buffer,
959 input_facility->buffer_size);
960
961 output_facility->buffer_size = size;
962 hdr->size = htons (size);
963 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
964 output_facility->facility_state = IOSTATE_READY;
965 input_facility->facility_state = IOSTATE_READY;
966 return TRUE;
967 }
942 default: 968 default:
943 return TRUE; 969 return TRUE;
944 } 970 }
945} 971}
946 972
947
948/** 973/**
949 * Attempts to read off an input facility (tap or named pipe) in overlapped mode. 974 * Attempts to read off an input facility (tap or named pipe) in overlapped mode.
950 * 975 *
@@ -981,9 +1006,8 @@ attempt_read_stdin (struct io_facility * input_facility,
981 { 1006 {
982 BOOL status; // BOOL is winbool, NOT boolean! 1007 BOOL status; // BOOL is winbool, NOT boolean!
983 if (!ResetEvent (input_facility->overlapped.hEvent)) 1008 if (!ResetEvent (input_facility->overlapped.hEvent))
984 { 1009 return FALSE;
985 return FALSE; 1010 input_facility->buffer_size = 0;
986 }
987 status = ReadFile (input_facility->handle, 1011 status = ReadFile (input_facility->handle,
988 input_facility->buffer, 1012 input_facility->buffer,
989 sizeof (input_facility->buffer), 1013 sizeof (input_facility->buffer),
@@ -991,7 +1015,7 @@ attempt_read_stdin (struct io_facility * input_facility,
991 &input_facility->overlapped); 1015 &input_facility->overlapped);
992 1016
993 /* Check how the task is handled */ 1017 /* Check how the task is handled */
994 if (status && (sizeof(struct GNUNET_MessageHeader) < input_facility->buffer_size)) 1018 if (status && (sizeof (struct GNUNET_MessageHeader) < input_facility->buffer_size))
995 {/* async event processed immediately*/ 1019 {/* async event processed immediately*/
996 struct GNUNET_MessageHeader * hdr = (struct GNUNET_MessageHeader *) input_facility->buffer; 1020 struct GNUNET_MessageHeader * hdr = (struct GNUNET_MessageHeader *) input_facility->buffer;
997 1021
@@ -1006,28 +1030,29 @@ attempt_read_stdin (struct io_facility * input_facility,
1006 input_facility->facility_state = IOSTATE_READY; 1030 input_facility->facility_state = IOSTATE_READY;
1007 return TRUE; 1031 return TRUE;
1008 } 1032 }
1009 if (ntohs (hdr->size) > input_facility->buffer_size ); 1033 if (ntohs (hdr->size) > input_facility->buffer_size);
1010 // TODO: add support for partial read 1034 // TODO: add support for partial read
1011 1035
1012 /* we successfully read something from the TAP and now need to 1036 /* we successfully read something from the TAP and now need to
1013 * send it our via STDOUT. Is that possible at the moment? */ 1037 * send it our via STDOUT. Is that possible at the moment? */
1014 if ((IOSTATE_READY == output_facility->facility_state || 1038 if (sizeof (struct GNUNET_MessageHeader) < input_facility->buffer_size)
1015 IOSTATE_WAITING == output_facility->facility_state) 1039 {
1016 && sizeof(struct GNUNET_MessageHeader) < input_facility->buffer_size ) 1040 if (IOSTATE_READY == output_facility->facility_state ||
1017 { /* hand over this buffers content and strip gnunet message header */ 1041 IOSTATE_WAITING == output_facility->facility_state)
1018 memcpy (output_facility->buffer + sizeof(struct GNUNET_MessageHeader), 1042 {
1019 input_facility->buffer, 1043 /* hand over this buffers content and strip gnunet message header */
1020 input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader)); 1044 memcpy (output_facility->buffer + sizeof (struct GNUNET_MessageHeader),
1021 output_facility->buffer_size = input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader); 1045 input_facility->buffer,
1022 output_facility->facility_state = IOSTATE_READY; 1046 input_facility->buffer_size - sizeof (struct GNUNET_MessageHeader));
1023 } 1047 output_facility->buffer_size = input_facility->buffer_size - sizeof (struct GNUNET_MessageHeader);
1024 else if ( IOSTATE_QUEUED == output_facility->facility_state ) 1048 output_facility->facility_state = IOSTATE_READY;
1025 { /* If we have have read our buffer, wait for our write-partner*/ 1049
1026 input_facility->facility_state = IOSTATE_WAITING; 1050 }
1051 else if (IOSTATE_QUEUED == output_facility->facility_state)
1052 /* If we have have read our buffer, wait for our write-partner*/
1053 input_facility->facility_state = IOSTATE_WAITING;
1027 // TODO: shall we attempt to fill our buffer or should we wait for our write-partner to finish? 1054 // TODO: shall we attempt to fill our buffer or should we wait for our write-partner to finish?
1028 } 1055 }
1029
1030 input_facility->facility_state = IOSTATE_READY;
1031 } 1056 }
1032 else if (status && 0 >= input_facility->buffer_size) 1057 else if (status && 0 >= input_facility->buffer_size)
1033 { 1058 {
@@ -1117,12 +1142,19 @@ attempt_read_stdin (struct io_facility * input_facility,
1117 } 1142 }
1118 } 1143 }
1119 return TRUE; 1144 return TRUE;
1145 case IOSTATE_RESUME: /* Our buffer was filled already but our write facility was busy. */
1146 memcpy (output_facility->buffer + sizeof (struct GNUNET_MessageHeader),
1147 input_facility->buffer,
1148 input_facility->buffer_size - sizeof (struct GNUNET_MessageHeader));
1149 output_facility->buffer_size = input_facility->buffer_size - sizeof (struct GNUNET_MessageHeader);
1150 output_facility->facility_state = IOSTATE_READY;
1151 input_facility->facility_state = IOSTATE_READY;
1152 return TRUE;
1120 default: 1153 default:
1121 return TRUE; 1154 return TRUE;
1122 } 1155 }
1123} 1156}
1124 1157
1125
1126/** 1158/**
1127 * Attempts to write to an output facility (tap or named pipe) in overlapped mode. 1159 * Attempts to write to an output facility (tap or named pipe) in overlapped mode.
1128 * 1160 *
@@ -1136,24 +1168,23 @@ static boolean
1136attempt_write (struct io_facility * output_facility, 1168attempt_write (struct io_facility * output_facility,
1137 struct io_facility * input_facility) 1169 struct io_facility * input_facility)
1138{ 1170{
1139 // FIXME: use switch... 1171 BOOL status; // BOOL is winbool, NOT boolean!
1140 if (IOSTATE_READY == output_facility->facility_state 1172
1141 && output_facility->buffer_size > 0) 1173 switch (output_facility->facility_state)
1142 { 1174 {
1143 BOOL status; // BOOL is winbool, NOT boolean! 1175 case IOSTATE_READY:
1144 1176
1145 if (!ResetEvent (output_facility->overlapped.hEvent)) 1177 if (!ResetEvent (output_facility->overlapped.hEvent))
1146 { 1178 return FALSE;
1147 return FALSE;
1148 }
1149 1179
1180 output_facility->buffer_size_written = 0;
1150 status = WriteFile (output_facility->handle, 1181 status = WriteFile (output_facility->handle,
1151 output_facility->buffer, 1182 output_facility->buffer,
1152 output_facility->buffer_size, 1183 output_facility->buffer_size,
1153 &output_facility->buffer_size_written, 1184 &output_facility->buffer_size_written,
1154 &output_facility->overlapped); 1185 &output_facility->overlapped);
1155 1186
1156 /* Check how the task is handled */ 1187 /* Check how the task was handled */
1157 if (status && 1188 if (status &&
1158 output_facility->buffer_size_written == output_facility->buffer_size) 1189 output_facility->buffer_size_written == output_facility->buffer_size)
1159 {/* async event processed immediately*/ 1190 {/* async event processed immediately*/
@@ -1187,11 +1218,8 @@ attempt_write (struct io_facility * output_facility,
1187 fprintf (stderr, "FATAL: Write to handle failed, exiting!\n"); 1218 fprintf (stderr, "FATAL: Write to handle failed, exiting!\n");
1188 } 1219 }
1189 } 1220 }
1190 1221 return TRUE;
1191 } 1222 case IOSTATE_QUEUED:
1192 else if (IOSTATE_QUEUED == output_facility->facility_state)
1193 {
1194 BOOL status; // BOOL is winbool, NOT boolean!
1195 // there was an operation going on already, check if that has completed now. 1223 // there was an operation going on already, check if that has completed now.
1196 status = GetOverlappedResult (output_facility->handle, 1224 status = GetOverlappedResult (output_facility->handle,
1197 &output_facility->overlapped, 1225 &output_facility->overlapped,
@@ -1224,9 +1252,9 @@ attempt_write (struct io_facility * output_facility,
1224 fprintf (stderr, "FATAL: Write to handle failed, exiting!\n"); 1252 fprintf (stderr, "FATAL: Write to handle failed, exiting!\n");
1225 } 1253 }
1226 } 1254 }
1255 default:
1256 return TRUE;
1227 } 1257 }
1228
1229 return TRUE;
1230} 1258}
1231 1259
1232 1260