diff options
author | Christian Fuchs <christian.fuchs@cfuchs.net> | 2013-01-31 12:32:20 +0000 |
---|---|---|
committer | Christian Fuchs <christian.fuchs@cfuchs.net> | 2013-01-31 12:32:20 +0000 |
commit | b19d787fc3b840821157471bb07f287a68e37709 (patch) | |
tree | 0ad5f315f04aad65f8591e42337ddb2eda262303 /src/vpn | |
parent | 9b4b22d13f5ced89931b0986dc43e1656c539a07 (diff) | |
download | gnunet-b19d787fc3b840821157471bb07f287a68e37709.tar.gz gnunet-b19d787fc3b840821157471bb07f287a68e37709.zip |
added support for partial reads from stdin
Diffstat (limited to 'src/vpn')
-rw-r--r-- | src/vpn/gnunet-helper-vpn-windows.c | 119 |
1 files changed, 55 insertions, 64 deletions
diff --git a/src/vpn/gnunet-helper-vpn-windows.c b/src/vpn/gnunet-helper-vpn-windows.c index dbf5663e4..bd364ec7e 100644 --- a/src/vpn/gnunet-helper-vpn-windows.c +++ b/src/vpn/gnunet-helper-vpn-windows.c | |||
@@ -218,9 +218,9 @@ struct io_facility | |||
218 | DWORD buffer_size; | 218 | DWORD buffer_size; |
219 | 219 | ||
220 | /** | 220 | /** |
221 | * Amount of data written, is compared to buffer_size. | 221 | * Amount of data actually written or read by readfile/writefile. |
222 | */ | 222 | */ |
223 | DWORD buffer_size_written; | 223 | DWORD buffer_size_processed; |
224 | }; | 224 | }; |
225 | 225 | ||
226 | /** | 226 | /** |
@@ -917,10 +917,8 @@ attempt_read_tap (struct io_facility * input_facility, | |||
917 | output_facility->facility_state = IOSTATE_READY; | 917 | output_facility->facility_state = IOSTATE_READY; |
918 | } | 918 | } |
919 | else if (0 < input_facility->buffer_size) | 919 | else if (0 < input_facility->buffer_size) |
920 | { /* If we have have read our buffer, wait for our write-partner*/ | 920 | /* If we have have read our buffer, wait for our write-partner*/ |
921 | input_facility->facility_state = IOSTATE_WAITING; | 921 | input_facility->facility_state = IOSTATE_WAITING; |
922 | // TODO: shall we attempt to fill our buffer or should we wait for our write-partner to finish? | ||
923 | } | ||
924 | } | 922 | } |
925 | else /* operation was either queued or failed*/ | 923 | else /* operation was either queued or failed*/ |
926 | { | 924 | { |
@@ -1046,31 +1044,33 @@ attempt_read_stdin (struct io_facility * input_facility, | |||
1046 | struct io_facility * output_facility) | 1044 | struct io_facility * output_facility) |
1047 | { | 1045 | { |
1048 | struct GNUNET_MessageHeader * hdr; | 1046 | struct GNUNET_MessageHeader * hdr; |
1049 | BOOL status; | 1047 | |
1050 | switch (input_facility->facility_state) | 1048 | switch (input_facility->facility_state) |
1051 | { | 1049 | { |
1052 | case IOSTATE_READY: | 1050 | case IOSTATE_READY: |
1053 | { | 1051 | { |
1052 | input_facility->buffer_size = 0; | ||
1053 | |||
1054 | partial_read_iostate_ready: | ||
1054 | if (! ResetEvent (input_facility->overlapped.hEvent)) | 1055 | if (! ResetEvent (input_facility->overlapped.hEvent)) |
1055 | return FALSE; | 1056 | return FALSE; |
1056 | input_facility->buffer_size = 0; | 1057 | |
1057 | status = ReadFile (input_facility->handle, | ||
1058 | input_facility->buffer, | ||
1059 | sizeof (input_facility->buffer), | ||
1060 | &input_facility->buffer_size, | ||
1061 | &input_facility->overlapped); | ||
1062 | |||
1063 | /* Check how the task is handled */ | 1058 | /* Check how the task is handled */ |
1064 | if (status && (sizeof (struct GNUNET_MessageHeader) < input_facility->buffer_size)) | 1059 | if (ReadFile (input_facility->handle, |
1060 | input_facility->buffer + input_facility->buffer_size, | ||
1061 | sizeof (input_facility->buffer) - input_facility->buffer_size, | ||
1062 | &input_facility->buffer_size_processed, | ||
1063 | &input_facility->overlapped)) | ||
1065 | {/* async event processed immediately*/ | 1064 | {/* async event processed immediately*/ |
1066 | hdr = (struct GNUNET_MessageHeader *) input_facility->buffer; | 1065 | hdr = (struct GNUNET_MessageHeader *) input_facility->buffer; |
1067 | 1066 | ||
1068 | /* reset event manually*/ | 1067 | /* reset event manually*/ |
1069 | if (! SetEvent (input_facility->overlapped.hEvent)) | 1068 | if (!SetEvent (input_facility->overlapped.hEvent)) |
1070 | return FALSE; | 1069 | return FALSE; |
1071 | 1070 | ||
1072 | fprintf (stderr, "DEBUG: stdin read succeeded immediately\n"); | 1071 | fprintf (stderr, "DEBUG: stdin read succeeded immediately\n"); |
1073 | 1072 | input_facility->buffer_size += input_facility->buffer_size_processed; | |
1073 | |||
1074 | if (ntohs (hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER || | 1074 | if (ntohs (hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER || |
1075 | ntohs (hdr->size) > sizeof (input_facility->buffer)) | 1075 | ntohs (hdr->size) > sizeof (input_facility->buffer)) |
1076 | { | 1076 | { |
@@ -1078,44 +1078,36 @@ attempt_read_stdin (struct io_facility * input_facility, | |||
1078 | input_facility->facility_state = IOSTATE_READY; | 1078 | input_facility->facility_state = IOSTATE_READY; |
1079 | return TRUE; | 1079 | return TRUE; |
1080 | } | 1080 | } |
1081 | if (ntohs (hdr->size) > input_facility->buffer_size); | 1081 | /* we got the a part of a packet */ |
1082 | // TODO: add support for partial read | 1082 | if (ntohs (hdr->size) > input_facility->buffer_size) |
1083 | 1083 | goto partial_read_iostate_ready; | |
1084 | /* we successfully read something from the TAP and now need to | 1084 | |
1085 | /* have we read more than 0 bytes of payload? (sizeread > header)*/ | ||
1086 | if (input_facility->buffer_size > sizeof (struct GNUNET_MessageHeader) && | ||
1087 | ((IOSTATE_READY == output_facility->facility_state) || | ||
1088 | (IOSTATE_WAITING == output_facility->facility_state))) | ||
1089 | {/* we successfully read something from the TAP and now need to | ||
1085 | * send it our via STDOUT. Is that possible at the moment? */ | 1090 | * send it our via STDOUT. Is that possible at the moment? */ |
1086 | if (sizeof (struct GNUNET_MessageHeader) < input_facility->buffer_size) | ||
1087 | { | ||
1088 | if (IOSTATE_READY == output_facility->facility_state || | ||
1089 | IOSTATE_WAITING == output_facility->facility_state) | ||
1090 | { | ||
1091 | /* hand over this buffers content and strip gnunet message header */ | ||
1092 | memcpy (output_facility->buffer, | ||
1093 | input_facility->buffer + sizeof (struct GNUNET_MessageHeader), | ||
1094 | input_facility->buffer_size - sizeof (struct GNUNET_MessageHeader)); | ||
1095 | output_facility->buffer_size = input_facility->buffer_size - sizeof (struct GNUNET_MessageHeader); | ||
1096 | output_facility->facility_state = IOSTATE_READY; | ||
1097 | |||
1098 | } | ||
1099 | else if (IOSTATE_QUEUED == output_facility->facility_state) | ||
1100 | /* If we have have read our buffer, wait for our write-partner*/ | ||
1101 | input_facility->facility_state = IOSTATE_WAITING; | ||
1102 | // TODO: shall we attempt to fill our buffer or should we wait for our write-partner to finish? | ||
1103 | } | ||
1104 | } | ||
1105 | else if (status && 0 >= input_facility->buffer_size) | ||
1106 | { | ||
1107 | if (! SetEvent (input_facility->overlapped.hEvent)) | ||
1108 | return FALSE; | ||
1109 | 1091 | ||
1110 | input_facility->facility_state = IOSTATE_READY; | 1092 | /* hand over this buffers content and strip gnunet message header */ |
1111 | } | 1093 | memcpy (output_facility->buffer, |
1094 | input_facility->buffer + sizeof (struct GNUNET_MessageHeader), | ||
1095 | input_facility->buffer_size - sizeof (struct GNUNET_MessageHeader)); | ||
1096 | output_facility->buffer_size = input_facility->buffer_size - sizeof (struct GNUNET_MessageHeader); | ||
1097 | output_facility->facility_state = IOSTATE_READY; | ||
1098 | input_facility->facility_state = IOSTATE_READY; | ||
1099 | } | ||
1100 | else if (input_facility->buffer_size > sizeof (struct GNUNET_MessageHeader)) | ||
1101 | /* If we have have read our buffer, wait for our write-partner*/ | ||
1102 | input_facility->facility_state = IOSTATE_WAITING; | ||
1103 | else /* we read nothing */ | ||
1104 | input_facility->facility_state = IOSTATE_READY; | ||
1105 | } | ||
1112 | else /* operation was either queued or failed*/ | 1106 | else /* operation was either queued or failed*/ |
1113 | { | 1107 | { |
1114 | int err = GetLastError (); | 1108 | int err = GetLastError (); |
1115 | if (ERROR_IO_PENDING == err) | 1109 | if (ERROR_IO_PENDING == err) /* operation queued */ |
1116 | { /* operation queued */ | ||
1117 | input_facility->facility_state = IOSTATE_QUEUED; | 1110 | input_facility->facility_state = IOSTATE_QUEUED; |
1118 | } | ||
1119 | else | 1111 | else |
1120 | { /* error occurred, let the rest of the elements finish */ | 1112 | { /* error occurred, let the rest of the elements finish */ |
1121 | input_facility->path_open = FALSE; | 1113 | input_facility->path_open = FALSE; |
@@ -1134,7 +1126,7 @@ attempt_read_stdin (struct io_facility * input_facility, | |||
1134 | // there was an operation going on already, check if that has completed now. | 1126 | // there was an operation going on already, check if that has completed now. |
1135 | if (GetOverlappedResult (input_facility->handle, | 1127 | if (GetOverlappedResult (input_facility->handle, |
1136 | &input_facility->overlapped, | 1128 | &input_facility->overlapped, |
1137 | &input_facility->buffer_size, | 1129 | &input_facility->buffer_size_processed, |
1138 | FALSE)) | 1130 | FALSE)) |
1139 | {/* successful return for a queued operation */ | 1131 | {/* successful return for a queued operation */ |
1140 | hdr = (struct GNUNET_MessageHeader *) input_facility->buffer; | 1132 | hdr = (struct GNUNET_MessageHeader *) input_facility->buffer; |
@@ -1143,6 +1135,7 @@ attempt_read_stdin (struct io_facility * input_facility, | |||
1143 | return FALSE; | 1135 | return FALSE; |
1144 | 1136 | ||
1145 | fprintf (stderr, "DEBUG: stdin read succeeded delayed\n"); | 1137 | fprintf (stderr, "DEBUG: stdin read succeeded delayed\n"); |
1138 | input_facility->buffer_size += input_facility->buffer_size_processed; | ||
1146 | 1139 | ||
1147 | if ((ntohs (hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) || | 1140 | if ((ntohs (hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) || |
1148 | (ntohs (hdr->size) > sizeof (input_facility->buffer))) | 1141 | (ntohs (hdr->size) > sizeof (input_facility->buffer))) |
@@ -1151,14 +1144,15 @@ attempt_read_stdin (struct io_facility * input_facility, | |||
1151 | input_facility->facility_state = IOSTATE_READY; | 1144 | input_facility->facility_state = IOSTATE_READY; |
1152 | return TRUE; | 1145 | return TRUE; |
1153 | } | 1146 | } |
1147 | /* we got the a part of a packet */ | ||
1154 | if (ntohs (hdr->size) > input_facility->buffer_size ); | 1148 | if (ntohs (hdr->size) > input_facility->buffer_size ); |
1155 | // TODO: add support for partial read | 1149 | goto partial_read_iostate_ready; |
1156 | 1150 | ||
1157 | /* we successfully read something from the TAP and now need to | 1151 | /* we successfully read something from the TAP and now need to |
1158 | * send it our via STDOUT. Is that possible at the moment? */ | 1152 | * send it our via STDOUT. Is that possible at the moment? */ |
1159 | if ((IOSTATE_READY == output_facility->facility_state || | 1153 | if ((IOSTATE_READY == output_facility->facility_state || |
1160 | IOSTATE_WAITING == output_facility->facility_state) | 1154 | IOSTATE_WAITING == output_facility->facility_state) |
1161 | && sizeof(struct GNUNET_MessageHeader) < input_facility->buffer_size) | 1155 | && input_facility->buffer_size > sizeof(struct GNUNET_MessageHeader)) |
1162 | { /* hand over this buffers content and strip gnunet message header */ | 1156 | { /* hand over this buffers content and strip gnunet message header */ |
1163 | memcpy (output_facility->buffer, | 1157 | memcpy (output_facility->buffer, |
1164 | input_facility->buffer + sizeof(struct GNUNET_MessageHeader), | 1158 | input_facility->buffer + sizeof(struct GNUNET_MessageHeader), |
@@ -1167,12 +1161,9 @@ attempt_read_stdin (struct io_facility * input_facility, | |||
1167 | output_facility->facility_state = IOSTATE_READY; | 1161 | output_facility->facility_state = IOSTATE_READY; |
1168 | input_facility->facility_state = IOSTATE_READY; | 1162 | input_facility->facility_state = IOSTATE_READY; |
1169 | } | 1163 | } |
1170 | else if (sizeof(struct GNUNET_MessageHeader) < input_facility->buffer_size) | 1164 | else if (input_facility->buffer_size > sizeof(struct GNUNET_MessageHeader)) |
1171 | { /* If we have have read our buffer, wait for our write-partner*/ | 1165 | input_facility->facility_state = IOSTATE_WAITING; |
1172 | input_facility->facility_state = IOSTATE_WAITING; | 1166 | else |
1173 | // TODO: shall we attempt to fill our buffer or should we wait for our write-partner to finish? | ||
1174 | } | ||
1175 | else if (sizeof(struct GNUNET_MessageHeader) >= input_facility->buffer_size) | ||
1176 | input_facility->facility_state = IOSTATE_READY; | 1167 | input_facility->facility_state = IOSTATE_READY; |
1177 | } | 1168 | } |
1178 | else | 1169 | else |
@@ -1225,16 +1216,16 @@ attempt_write (struct io_facility * output_facility, | |||
1225 | if (! ResetEvent (output_facility->overlapped.hEvent)) | 1216 | if (! ResetEvent (output_facility->overlapped.hEvent)) |
1226 | return FALSE; | 1217 | return FALSE; |
1227 | 1218 | ||
1228 | output_facility->buffer_size_written = 0; | 1219 | output_facility->buffer_size_processed = 0; |
1229 | status = WriteFile (output_facility->handle, | 1220 | status = WriteFile (output_facility->handle, |
1230 | output_facility->buffer, | 1221 | output_facility->buffer, |
1231 | output_facility->buffer_size, | 1222 | output_facility->buffer_size, |
1232 | &output_facility->buffer_size_written, | 1223 | &output_facility->buffer_size_processed, |
1233 | &output_facility->overlapped); | 1224 | &output_facility->overlapped); |
1234 | 1225 | ||
1235 | /* Check how the task was handled */ | 1226 | /* Check how the task was handled */ |
1236 | if (status && | 1227 | if (status && |
1237 | output_facility->buffer_size_written == output_facility->buffer_size) | 1228 | output_facility->buffer_size_processed == output_facility->buffer_size) |
1238 | {/* async event processed immediately*/ | 1229 | {/* async event processed immediately*/ |
1239 | 1230 | ||
1240 | fprintf (stderr, "DEBUG: write succeeded immediately\n"); | 1231 | fprintf (stderr, "DEBUG: write succeeded immediately\n"); |
@@ -1246,7 +1237,7 @@ attempt_write (struct io_facility * output_facility, | |||
1246 | /* we are now waiting for our buffer to be filled*/ | 1237 | /* we are now waiting for our buffer to be filled*/ |
1247 | output_facility->facility_state = IOSTATE_WAITING; | 1238 | output_facility->facility_state = IOSTATE_WAITING; |
1248 | output_facility->buffer_size = 0; | 1239 | output_facility->buffer_size = 0; |
1249 | output_facility->buffer_size_written = 0; | 1240 | output_facility->buffer_size_processed = 0; |
1250 | 1241 | ||
1251 | /* we successfully wrote something and now need to reset our reader */ | 1242 | /* we successfully wrote something and now need to reset our reader */ |
1252 | if (IOSTATE_WAITING == input_facility->facility_state) | 1243 | if (IOSTATE_WAITING == input_facility->facility_state) |
@@ -1273,10 +1264,10 @@ attempt_write (struct io_facility * output_facility, | |||
1273 | // there was an operation going on already, check if that has completed now. | 1264 | // there was an operation going on already, check if that has completed now. |
1274 | status = GetOverlappedResult (output_facility->handle, | 1265 | status = GetOverlappedResult (output_facility->handle, |
1275 | &output_facility->overlapped, | 1266 | &output_facility->overlapped, |
1276 | &output_facility->buffer_size_written, | 1267 | &output_facility->buffer_size_processed, |
1277 | FALSE); | 1268 | FALSE); |
1278 | if (status && | 1269 | if (status && |
1279 | output_facility->buffer_size_written == output_facility->buffer_size) | 1270 | output_facility->buffer_size_processed == output_facility->buffer_size) |
1280 | {/* successful return for a queued operation */ | 1271 | {/* successful return for a queued operation */ |
1281 | if (! ResetEvent (output_facility->overlapped.hEvent)) | 1272 | if (! ResetEvent (output_facility->overlapped.hEvent)) |
1282 | return FALSE; | 1273 | return FALSE; |
@@ -1286,7 +1277,7 @@ attempt_write (struct io_facility * output_facility, | |||
1286 | /* we are now waiting for our buffer to be filled*/ | 1277 | /* we are now waiting for our buffer to be filled*/ |
1287 | output_facility->facility_state = IOSTATE_WAITING; | 1278 | output_facility->facility_state = IOSTATE_WAITING; |
1288 | output_facility->buffer_size = 0; | 1279 | output_facility->buffer_size = 0; |
1289 | output_facility->buffer_size_written = 0; | 1280 | output_facility->buffer_size_processed = 0; |
1290 | 1281 | ||
1291 | /* we successfully wrote something and now need to reset our reader */ | 1282 | /* we successfully wrote something and now need to reset our reader */ |
1292 | if (IOSTATE_WAITING == input_facility->facility_state) | 1283 | if (IOSTATE_WAITING == input_facility->facility_state) |