From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1F71Yn-0001K6-U4 for qemu-devel@nongnu.org; Wed, 08 Feb 2006 21:29:29 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1F71Yl-0001JB-Ny for qemu-devel@nongnu.org; Wed, 08 Feb 2006 21:29:29 -0500 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1F71Yl-0001J6-Gc for qemu-devel@nongnu.org; Wed, 08 Feb 2006 21:29:27 -0500 Received: from [211.5.2.83] (helo=nm01omta01f.dion.ne.jp) by monty-python.gnu.org with smtp (Exim 4.52) id 1F71cC-0000Zz-FR for qemu-devel@nongnu.org; Wed, 08 Feb 2006 21:33:01 -0500 Message-ID: <002201c62d20$a6993660$0464a8c0@athlon> From: "Kazu" References: <000c01c62638$d55e7800$0464a8c0@athlon><43E13FEC.7050804@bellard.org> <000a01c627df$fc48d660$0464a8c0@athlon> <43E4F24F.6040908@bellard.org> Subject: Re: [Qemu-devel][PATCH] Tap and VLAN socket support for win32 Date: Thu, 9 Feb 2006 11:29:28 +0900 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_001F_01C62D6C.164A16F0" Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org This is a multi-part message in MIME format. ------=_NextPart_000_001F_01C62D6C.164A16F0 Content-Type: text/plain; format=flowed; charset="iso-8859-1"; reply-type=original Content-Transfer-Encoding: 7bit Sunday, February 05, 2006 3:28 AM Fabrice Bellard wrote: > Kazu wrote: >> Thursday, February 02, 2006 8:10 AM Fabrice Bellard wrote: >> >>> Hi, >>> >>> I merged your patches and I made important changes to simplify them. I >>> did not do any tests so tell me if you see problems. >>> >> >> -net socket,connect doesn't work. On Windows host, connect returns with >> err >> = WSAEWOULDBLOCK and second time err = WSAEINVAL. I think changing the >> place >> of EWOULDBLOCK would be good. On Linux host, EWOULDBLOCK is the same as >> EAGAIN but a patch works on both Linux and Windows. > > Unfortunately on Linux the correct return value we are expecting is > EINPROGRESS. EAGAIN means that the 'connect' was not initiated so it is > necessary to redo it. > There is not good way to detect a completion of asynchronous connect. So I used an event object to detect it. A patch is attached. >> >> For -net socket,mcast, bind have to be done by sin_addr.s_addr = >> INADDR_ANY. >> It seems that it works on Linux host. > > It works on Linux but it is not correct because it prevents from listening > to several multicast addresses at the same time. If doing the same on > Windows is not possible I agree to make a special case. > I couldn't find a way to set a multicast address. I made it a special case in the patch Regard, Kazu Index: vl.c =================================================================== RCS file: /sources/qemu/qemu/vl.c,v retrieving revision 1.162 diff -u -r1.162 vl.c --- vl.c 5 Feb 2006 04:14:41 -0000 1.162 +++ vl.c 8 Feb 2006 05:50:28 -0000 @@ -1083,9 +1083,10 @@ #define socket_error() WSAGetLastError() #undef EINTR -#define EWOULDBLOCK WSAEWOULDBLOCK -#define EINTR WSAEINTR -#define EINPROGRESS WSAEINPROGRESS +#define EWOULDBLOCK WSAEWOULDBLOCK +#define EINTR WSAEINTR +#define EINPROGRESS WSAEINPROGRESS +#define EADDRNOTAVAIL WSAEADDRNOTAVAIL static void socket_cleanup(void) { @@ -1136,6 +1137,59 @@ ioctlsocket(fd, FIONBIO, &opt); } +static int socket_set_event(SOCKET fd, WSAEVENT *phEvent) +{ + int ret; + + *phEvent = WSACreateEvent(); + if (*phEvent == WSA_INVALID_EVENT) { + perror("connect: CreateEvent"); + return -1; + } + + ret = WSAEventSelect(fd, *phEvent, FD_CONNECT); + if (ret == SOCKET_ERROR) { + perror("connect: EventSelect"); + return -1; + } + return 0; +} + +static int socket_wait_event(SOCKET fd, WSAEVENT *phEvent) +{ + WSANETWORKEVENTS events; + int ret; + + ret = WSAWaitForMultipleEvents(1, phEvent, FALSE, WSA_INFINITE, FALSE); + if (ret == WSA_WAIT_FAILED) { + perror("connect: Wait"); + goto fail; + } + + ret = WSAEnumNetworkEvents(fd, *phEvent, &events); + if (ret == SOCKET_ERROR) { + perror("connect: EnumEvent"); + goto fail; + } else { + if (events.lNetworkEvents & FD_CONNECT) { + if (events.iErrorCode[FD_CONNECT_BIT] == 0) { + if (*phEvent != WSA_INVALID_EVENT) + WSACloseEvent(*phEvent); + return 1; + } else { + perror("connect: refused"); + goto fail; + } + } else { + perror("connect: fd_connect"); + goto fail; + } + } + fail: + if (*phEvent != WSA_INVALID_EVENT) + WSACloseEvent(*phEvent); + return 0; +} #else #define socket_error() errno @@ -2330,7 +2384,9 @@ { struct ip_mreq imr; int fd; - int val, ret; + int val, ret, err; + struct sockaddr_in addr; + if (!IN_MULTICAST(ntohl(mcastaddr->sin_addr.s_addr))) { fprintf(stderr, "qemu: error: specified mcastaddr \"%s\" (0x%08x) does not contain a multicast address\n", inet_ntoa(mcastaddr->sin_addr), @@ -2354,8 +2410,22 @@ ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr)); if (ret < 0) { - perror("bind"); - goto fail; + err = socket_error(); + if (err == EADDRNOTAVAIL) { + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = mcastaddr->sin_port; + addr.sin_addr.s_addr = INADDR_ANY; + + ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr)); + if (ret < 0) { + perror("bind"); + goto fail; + } + } else { + perror("bind"); + goto fail; + } } /* Add host to multicast group */ @@ -2557,11 +2627,15 @@ return 0; } + static int net_socket_connect_init(VLANState *vlan, const char *host_str) { NetSocketState *s; int fd, connected, ret, err; struct sockaddr_in saddr; +#ifdef _WIN32 + WSAEVENT hEvent; +#endif if (parse_host_port(&saddr, host_str) < 0) return -1; @@ -2573,6 +2647,26 @@ } socket_set_nonblock(fd); +#ifdef _WIN32 + ret = socket_set_event(fd, &hEvent); + if (ret < 0) { + perror("connect: set_event"); + closesocket(fd); + return -1; + } + + connected = 0; + ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr)); + + err = socket_wait_event(fd, &hEvent); + if (err > 0) { + connected = 1; + } else { + perror("connect"); + closesocket(fd); + return -1; + } +#else connected = 0; for(;;) { ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr)); @@ -2591,6 +2685,8 @@ break; } } +#endif + s = net_socket_fd_init(vlan, fd, connected); if (!s) return -1; ------=_NextPart_000_001F_01C62D6C.164A16F0 Content-Type: application/x-gzip; name="qemu-20060208-vlan-2.patch.gz" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="qemu-20060208-vlan-2.patch.gz" H4sICCGM6UMAA3FlbXUtMjAwNjAyMDgtdmxhbi0yLnBhdGNoAK1XbXOaWBT+HH/FqZ06EDEB32J1 04k1pMPU4o7aZHa2OwyRS8IUwXLRttvpf99z7wUEwbS7XT4I3HteHp7zco9G4JAvQ9j5Z6va5a9f tflkAa7nkyGc03AbrQg9/0TWW/HDvCi7WkTiyCM7L3iACG/UCwPQzrR+u+Z4rgutLbQi/i5gtVot /nDSgxtyD21V7YPaHWrdYVeDlorXidBuNptCcJAT7A176rA9EIK1qytoaeqgo7yEJr9rKlxd1aAG zx3iegEBGq4+ktgiURRGkgx3i/EbEk9tGutiBSW3yJkLumEu57VWqqffzd5Pr19PZ5O3TCn3mpNh KiAuJnNgwTB/n8/ezPXFItlNX2vNKi9w6KdZ5SfnqVnlCY77Gl9fz83Zcnw7NqZcKr/AOKOxHXsr 2IWek/K28okdbDcSW0OuvgnGtU5f6SPjWudC6b3kjLPLC1exLxQl11HgxpiZr42ZAo1wE8ujGnxH L83EixfEqRPKArQjQSwt8Lv1JTBlBvBWN5dwunnU2aaMut9qTe4IdTHrRuJN/KZicMlUJxGxY8IX JDmR81yQ9lJczDLM2/HUuLa4KxkS++zaiJSpr8IgIKt4CDmT9dQkuxDINgqQlWTtex4VbgpAXG9B fDTFuUmBIEvX1mRmmvpkmQfKFS9BEGLp8/ls/jS8nIOfgZcsq7iKK1VR+Wx7/zIsuGfqy7vZ/C0X WQDXpqNi0AQ5B/TcobObMHq39WNv4wuWqaQpsKdpPF3oShK0G8M0lnqyWEEbk7obG0vrBlNbv36a Oea7QNlDGIfg2p7/dESD7dok8ecw+pjALca1Ib7+14KKPsoZV8IHxKckb4g5E+7P/AJGaOTzLa9y oObx/jgJHfLnXsF6bSz/Yl+gllRLBfasqsDKOkneTPyQJuWaJdaoLJ1krXawVSbgKKMRcbeUOPUq 64e8Zub3r9WeSl5cx0qeS46qnHzf5xnbGVb0qx/Q+TSFhWKH5+wTnjgj8R6EvNG3Ox1VuYBmuzPo KqLPfxOtnsbRdhWDt7HWEfkE3joaJWcAYnWdUa2VvuxsX8k16/ySwlwl64lBBsV2nMjyAmB33E3s IhnPDNN69366NCbjxVIK4vDRl9YrPMuZZOsV9QKLPZ1RfpNllqRw4m4idOpKNHbQnQJ1NrsMgX/t EOiGrDzXIw5kluBD/QX9UAdJ/fJCHXyRwQkJhSCMAWMa2wwZrFmjYgocJaH0Q1BX0NkJ8hlbCM2u QiYrkPDa6yoD5LWrqUq7nYwsSaSwu9x7gcO7iXRAC5zKmVkFqPc3CV3pNFuS5dGeLWbqN1GprcNE ZQ5YZmYbVVmJsoilmByjgx7DRC6Lo0WpNazJGk94qSFAqxnuFHFBWAQQ+XLtted/RQDjG8x6fXlM bhNGjLIDttnqMY1cjqCiYTLw1tj8Y5SeSun142A0CoGo/KCDUBztUGlI/v+uVGm5ug3lb+L3/BTG jgOPIaY6auzz/iEKtxs4PRcJ3etdKJqGGd1v40MvGwn3nUcMf9mQyfoAK5V0zhTdEsvei6Xb6dhc oBiB051vBwqrO/S4erSRc4bEwkjIWS/CA27BrSQ6tNCKuDazTZx80+ESFU2HJl3nueeyfwXWnWF2 2tl4I0Yf0VyZEAnwL05auyzSGzuixOIYWQpKDSoyJEPN86CWT7F0OhM8XnTYZN3udy+Udj+jMQlJ bl4OwuDex1fMTFb0lYBF/paGbMZJo3hAHEvS0sGWWSkk1IodPdng/9PDcRYYRKmO8piTnaNlRwt1 R0uFJ54KDSw3zh4hgIm/OiAgDzH7hlK1HdD037nhR3P2ESUEapK3LjobjeS0AH6ZN5F6LzWReoMe nk1p5qXXPf77+Tjar2W9Ii2C5JymiCJX1zgI8ZIWdVyoxvxZ9YxW18Q/Ar3Mnc8QAAA= ------=_NextPart_000_001F_01C62D6C.164A16F0--