summaryrefslogtreecommitdiffstats
path: root/qemu/net/tap-win32.c
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/net/tap-win32.c')
-rw-r--r--qemu/net/tap-win32.c55
1 files changed, 41 insertions, 14 deletions
diff --git a/qemu/net/tap-win32.c b/qemu/net/tap-win32.c
index 625d53c64..f1e142ace 100644
--- a/qemu/net/tap-win32.c
+++ b/qemu/net/tap-win32.c
@@ -26,6 +26,7 @@
* distribution); if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu/osdep.h"
#include "tap_int.h"
#include "qemu-common.h"
@@ -34,7 +35,6 @@
#include "net/tap.h" /* tap_has_ufo, ... */
#include "sysemu/sysemu.h"
#include "qemu/error-report.h"
-#include <stdio.h>
#include <windows.h>
#include <winioctl.h>
@@ -77,7 +77,12 @@
//#define DEBUG_TAP_WIN32
-#define TUN_ASYNCHRONOUS_WRITES 1
+/* FIXME: The asynch write path appears to be broken at
+ * present. WriteFile() ignores the lpNumberOfBytesWritten parameter
+ * for overlapped writes, with the result we return zero bytes sent,
+ * and after handling a single packet, receive is disabled for this
+ * interface. */
+/* #define TUN_ASYNCHRONOUS_WRITES 1 */
#define TUN_BUFFER_SIZE 1560
#define TUN_MAX_BUFFER_COUNT 32
@@ -356,7 +361,8 @@ static int get_device_guid(
&len);
if (status != ERROR_SUCCESS || name_type != REG_SZ) {
- return -1;
+ ++i;
+ continue;
}
else {
if (is_tap_win32_dev(enum_name)) {
@@ -460,27 +466,48 @@ static int tap_win32_write(tap_win32_overlapped_t *overlapped,
BOOL result;
DWORD error;
+#ifdef TUN_ASYNCHRONOUS_WRITES
result = GetOverlappedResult( overlapped->handle, &overlapped->write_overlapped,
&write_size, FALSE);
if (!result && GetLastError() == ERROR_IO_INCOMPLETE)
WaitForSingleObject(overlapped->write_event, INFINITE);
+#endif
result = WriteFile(overlapped->handle, buffer, size,
&write_size, &overlapped->write_overlapped);
+#ifdef TUN_ASYNCHRONOUS_WRITES
+ /* FIXME: we can't sensibly set write_size here, without waiting
+ * for the IO to complete! Moreover, we can't return zero,
+ * because that will disable receive on this interface, and we
+ * also can't assume it will succeed and return the full size,
+ * because that will result in the buffer being reclaimed while
+ * the IO is in progress. */
+#error Async writes are broken. Please disable TUN_ASYNCHRONOUS_WRITES.
+#else /* !TUN_ASYNCHRONOUS_WRITES */
if (!result) {
- switch (error = GetLastError())
- {
- case ERROR_IO_PENDING:
-#ifndef TUN_ASYNCHRONOUS_WRITES
- WaitForSingleObject(overlapped->write_event, INFINITE);
-#endif
- break;
- default:
- return -1;
+ error = GetLastError();
+ if (error == ERROR_IO_PENDING) {
+ result = GetOverlappedResult(overlapped->handle,
+ &overlapped->write_overlapped,
+ &write_size, TRUE);
}
}
+#endif
+
+ if (!result) {
+#ifdef DEBUG_TAP_WIN32
+ LPTSTR msgbuf;
+ error = GetLastError();
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ &msgbuf, 0, NULL);
+ fprintf(stderr, "Tap-Win32: Error WriteFile %d - %s\n", error, msgbuf);
+ LocalFree(msgbuf);
+#endif
+ return 0;
+ }
return write_size;
}
@@ -767,8 +794,8 @@ int net_init_tap(const NetClientOptions *opts, const char *name,
/* FIXME error_setg(errp, ...) on failure */
const NetdevTapOptions *tap;
- assert(opts->kind == NET_CLIENT_OPTIONS_KIND_TAP);
- tap = opts->tap;
+ assert(opts->type == NET_CLIENT_OPTIONS_KIND_TAP);
+ tap = opts->u.tap.data;
if (!tap->has_ifname) {
error_report("tap: no interface name");