From c487f2fef5048a15be034d052be6584bd9a7e135 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 29 Jul 2011 12:47:54 +0000 Subject: [PATCH] Throughout change "WinSock" to "Winsock" in comments. * fhandler_socket.cc (fhandler_socket::sendmsg): Add missing call to get_inet_addr to convert AF_LOCAL to AF_INET sockets. * net.cc (cygwin_socket): Workaround UDP Winsock problem. Add comment to explain why. * select.cc: Include winsock2.h rather than winsock.h. --- winsup/cygwin/ChangeLog | 9 +++++++++ winsup/cygwin/fhandler_socket.cc | 20 ++++++++++++++------ winsup/cygwin/net.cc | 27 ++++++++++++++++++++++----- winsup/cygwin/select.cc | 2 +- 4 files changed, 46 insertions(+), 12 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 2b87ba788..fb867945a 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,12 @@ +2011-07-29 Corinna Vinschen + + Throughout change "WinSock" to "Winsock" in comments. + * fhandler_socket.cc (fhandler_socket::sendmsg): Add missing call to + get_inet_addr to convert AF_LOCAL to AF_INET sockets. + * net.cc (cygwin_socket): Workaround UDP Winsock problem. Add comment + to explain why. + * select.cc: Include winsock2.h rather than winsock.h. + 2011-07-26 Corinna Vinschen * fhandler_disk_file.cc (__DIR_mounts::eval_ino): Create path_conv diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc index 62609fe48..500ee5069 100644 --- a/winsup/cygwin/fhandler_socket.cc +++ b/winsup/cygwin/fhandler_socket.cc @@ -1129,7 +1129,7 @@ fhandler_socket::listen (int backlog) { /* It's perfectly valid to call listen on an unbound INET socket. In this case the socket is automatically bound to an unused - port number, listening on all interfaces. On Winsock, listen + port number, listening on all interfaces. On WinSock, listen fails with WSAEINVAL when it's called on an unbound socket. So we have to bind manually here to have POSIX semantics. */ if (get_addr_family () == AF_INET) @@ -1283,7 +1283,7 @@ fhandler_socket::getsockname (struct sockaddr *name, int *namelen) { if (WSAGetLastError () == WSAEINVAL) { - /* Winsock returns WSAEINVAL if the socket is locally + /* WinSock returns WSAEINVAL if the socket is locally unbound. Per SUSv3 this is not an error condition. We're faking a valid return value here by creating the same content in the sockaddr structure as on Linux. */ @@ -1454,7 +1454,7 @@ fhandler_socket::recv_internal (LPWSAMSG wsamsg) about that and fails, while the same test is omitted in the recv functions. - This also covers another weird case: Winsock returns WSAEFAULT if + This also covers another weird case: WinSock returns WSAEFAULT if namelen is a valid pointer while name is NULL. Both parameters are ignored for TCP sockets, so this only occurs when using UDP socket. */ else if (!wsamsg->name || get_socket_type () == SOCK_STREAM) @@ -1698,9 +1698,17 @@ fhandler_socket::sendto (const void *ptr, size_t len, int flags, int fhandler_socket::sendmsg (const struct msghdr *msg, int flags) { + /* TODO: Descriptor passing on AF_LOCAL sockets. */ + + struct sockaddr_storage sst; + int len = 0; + pthread_testcancel (); - /* TODO: Descriptor passing on AF_LOCAL sockets. */ + if (msg->msg_name + && get_inet_addr ((struct sockaddr *) msg->msg_name, msg->msg_namelen, + &sst, &len) == SOCKET_ERROR) + return SOCKET_ERROR; WSABUF wsabuf[msg->msg_iovlen]; WSABUF *wsaptr = wsabuf; @@ -1710,7 +1718,7 @@ fhandler_socket::sendmsg (const struct msghdr *msg, int flags) wsaptr->len = iovptr->iov_len; (wsaptr++)->buf = (char *) (iovptr++)->iov_base; } - WSAMSG wsamsg = { (struct sockaddr *) msg->msg_name, msg->msg_namelen, + WSAMSG wsamsg = { msg->msg_name ? (struct sockaddr *) &sst : NULL, len, wsabuf, msg->msg_iovlen, /* Disappointing but true: Even if WSASendMsg is supported, it's only supported for datagram and @@ -1730,7 +1738,7 @@ fhandler_socket::shutdown (int how) /* Linux allows to call shutdown for any socket, even if it's not connected. This also disables to call accept on this socket, if shutdown has been - called with the SHUT_RD or SHUT_RDWR parameter. In contrast, Winsock + called with the SHUT_RD or SHUT_RDWR parameter. In contrast, WinSock only allows to call shutdown on a connected socket. The accept function is in no way affected. So, what we do here is to fake success, and to change the event settings so that an FD_CLOSE event is triggered for the diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc index 5c9de821e..2e51e6859 100644 --- a/winsup/cygwin/net.cc +++ b/winsup/cygwin/net.cc @@ -639,6 +639,23 @@ cygwin_socket (int af, int type, int protocol) ((fhandler_socket *) fd)->set_nonblocking (true); if (flags & SOCK_CLOEXEC) ((fhandler_socket *) fd)->set_close_on_exec (true); + if (type == SOCK_DGRAM) + { + /* Workaround the problem that a missing listener on a UDP socket + in a call to sendto will result in select/WSAEnumNetworkEvents + reporting that the socket has pending data and a subsequent call + to recvfrom will return -1 with error set to WSAECONNRESET. + + This problem is a regression introduced in Windows 2000. + Instead of fixing the problem, a new socket IOCTL code has + been added, see http://support.microsoft.com/kb/263823 */ + BOOL cr = FALSE; + DWORD blen; + if (WSAIoctl (soc, SIO_UDP_CONNRESET, &cr, sizeof cr, NULL, 0, + &blen, NULL, NULL) == SOCKET_ERROR) + debug_printf ("Reset SIO_UDP_CONNRESET: WinSock error %lu", + WSAGetLastError ()); + } res = fd; } } @@ -723,7 +740,7 @@ cygwin_setsockopt (int fd, int level, int optname, const void *optval, res = -1; else { - /* Old applications still use the old Winsock1 IPPROTO_IP values. */ + /* Old applications still use the old WinSock1 IPPROTO_IP values. */ if (level == IPPROTO_IP && CYGWIN_VERSION_CHECK_FOR_USING_WINSOCK1_VALUES) optname = convert_ws1_ip_optname (optname); @@ -822,7 +839,7 @@ cygwin_getsockopt (int fd, int level, int optname, void *optval, } else { - /* Old applications still use the old Winsock1 IPPROTO_IP values. */ + /* Old applications still use the old WinSock1 IPPROTO_IP values. */ if (level == IPPROTO_IP && CYGWIN_VERSION_CHECK_FOR_USING_WINSOCK1_VALUES) optname = convert_ws1_ip_optname (optname); res = getsockopt (fh->get_socket (), level, optname, (char *) optval, @@ -3345,7 +3362,7 @@ ga_aistruct (struct addrinfo ***paipnext, const struct addrinfo *hintsp, /* Cygwin specific: The ga_clone function is split up to allow an easy duplication of addrinfo structs. This is used to duplicate the - structures from Winsock, so that we have the allocation of the structs + structures from WinSock, so that we have the allocation of the structs returned to the application under control. This is especially helpful for the AI_V4MAPPED case prior to Vista. */ static struct addrinfo * @@ -4271,7 +4288,7 @@ cygwin_getaddrinfo (const char *hostname, const char *servname, | AI_NUMERICSERV | AI_ADDRCONFIG | AI_V4MAPPED))) return EAI_BADFLAGS; /* AI_NUMERICSERV is not supported in our replacement getaddrinfo, nor - is it supported by Winsock prior to Vista. We just check the servname + is it supported by WinSock prior to Vista. We just check the servname parameter by ourselves here. */ if (hints && (hints->ai_flags & AI_NUMERICSERV)) { @@ -4364,7 +4381,7 @@ cygwin_getnameinfo (const struct sockaddr *sa, socklen_t salen, return ipv4_getnameinfo (sa, salen, host, hostlen, serv, servlen, flags); /* When the incoming port number does not resolve to a well-known service, - Winsock's getnameinfo up to Windows 2003 returns with error WSANO_DATA + WinSock's getnameinfo up to Windows 2003 returns with error WSANO_DATA instead of setting `serv' to the numeric port number string, as required by RFC 3493. This is fixed on Vista and later. To avoid the error on systems up to Windows 2003, we check if the port number resolves diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index 305f41e2e..23cf233dc 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -23,7 +23,7 @@ details. */ #include #include #define USE_SYS_TYPES_FD_SET -#include +#include #include "cygerrno.h" #include "security.h" #include "path.h"