diff options
author | Christian Fuchs <christian.fuchs@cfuchs.net> | 2013-01-24 12:49:52 +0000 |
---|---|---|
committer | Christian Fuchs <christian.fuchs@cfuchs.net> | 2013-01-24 12:49:52 +0000 |
commit | 77da27b63ae4c24ff737fd2212f765a1b9b06de0 (patch) | |
tree | 572c2c4b19528ff6a6b9a76d39d45475780b0c94 /src/vpn | |
parent | 978b2684641b79bb7b7e4a1378d9f0f6d0f1a443 (diff) | |
download | gnunet-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.c | 124 |
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 | */ |
679 | static boolean | 686 | static boolean |
680 | check_tapw32_version (HANDLE handle) | 687 | check_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 | |||
819 | attempt_read_tap (struct io_facility * input_facility, | 824 | attempt_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 | |||
1136 | attempt_write (struct io_facility * output_facility, | 1168 | attempt_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 | ||