Handle TAP-Win32 immediate reads correctly.
authorEtienne Dechamps <etienne@edechamps.fr>
Sat, 19 Jul 2014 17:11:42 +0000 (18:11 +0100)
committerEtienne Dechamps <etienne@edechamps.fr>
Sat, 19 Jul 2014 17:38:24 +0000 (18:38 +0100)
The handling of TAP-Win32 virtual network device reads that complete
immediately (ReadFile() returns TRUE) is incorrect - instead of
starting a new read, tinc will continue listening for the overlapped
read completion event which will never fire. As a result, tinc stops
receiving packets on the interface.

src/mingw/device.c

index 2ef0064..6ee26e7 100644 (file)
@@ -49,11 +49,20 @@ static void device_issue_read() {
        device_read_overlapped.Offset = 0;
        device_read_overlapped.OffsetHigh = 0;
 
-       int status = ReadFile(device_handle, (void *)device_read_packet.data, MTU, NULL, &device_read_overlapped);
+       int status;
+       for (;;) {
+               DWORD len;
+               status = ReadFile(device_handle, (void *)device_read_packet.data, MTU, &len, &device_read_overlapped);
+               if (!status) {
+                       if (GetLastError() != ERROR_IO_PENDING)
+                               logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info,
+                                          device, strerror(errno));
+                       break;
+               }
 
-       if(!status && GetLastError() != ERROR_IO_PENDING) {
-               logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info,
-                          device, strerror(errno));
+               device_read_packet.len = len;
+               device_read_packet.priority = 0;
+               route(myself, &device_read_packet);
        }
 }