Module: wine Branch: master Commit: 1cf9436efe47b858a4cae33c956a78b8bcf83fbf URL: http://source.winehq.org/git/wine.git/?a=commit;h=1cf9436efe47b858a4cae33c95...
Author: Damjan Jovanovic damjan.jov@gmail.com Date: Thu Jun 14 15:27:29 2007 +0200
ws2_32: getsockname should fail on unbound socket.
---
dlls/ws2_32/socket.c | 33 +++++++++++++++++++++++++++++++++ dlls/ws2_32/tests/sock.c | 10 ++++++++++ 2 files changed, 43 insertions(+), 0 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 456be21..aab3888 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -927,6 +927,35 @@ static unsigned int ws_sockaddr_ws2u(const struct WS_sockaddr* wsaddr, int wsadd return uaddrlen; }
+static BOOL is_sockaddr_bound(const struct sockaddr *uaddr, int uaddrlen) +{ + switch (uaddr->sa_family) + { +#ifdef HAVE_IPX + case AF_IPX: + FIXME("don't know how to tell if IPX socket is bound, assuming it is!\n"); + return TRUE; +#endif + case AF_INET6: + { + static const struct sockaddr_in6 emptyAddr; + const struct sockaddr_in6 *in6 = (const struct sockaddr_in6*) uaddr; + return in6->sin6_port || memcmp(&in6->sin6_addr, &emptyAddr.sin6_addr, sizeof(struct in6_addr)); + } + case AF_INET: + { + static const struct sockaddr_in emptyAddr; + const struct sockaddr_in *in = (const struct sockaddr_in*) uaddr; + return in->sin_port || memcmp(&in->sin_addr, &emptyAddr.sin_addr, sizeof(struct in_addr)); + } + case AF_UNSPEC: + return FALSE; + default: + FIXME("unknown address family %d\n", uaddr->sa_family); + return TRUE; + } +} + /* Returns 0 if successful, -1 if the buffer is too small */ static int ws_sockaddr_u2ws(const struct sockaddr* uaddr, struct WS_sockaddr* wsaddr, int* wsaddrlen) { @@ -1590,6 +1619,10 @@ int WINAPI WS_getsockname(SOCKET s, struct WS_sockaddr *name, int *namelen) { SetLastError(wsaErrno()); } + else if (!is_sockaddr_bound(&uaddr.addr, uaddrlen)) + { + SetLastError(WSAEINVAL); + } else if (ws_sockaddr_u2ws(&uaddr.addr, name, namelen) != 0) { /* The buffer was too small */ diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 3403715..cc41320 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -1644,6 +1644,16 @@ static void test_getsockname(void) return; }
+ memcpy(&sa_get, &sa_set, sizeof(sa_set)); + if (getsockname(sock, (struct sockaddr*) &sa_get, &sa_get_len) == 0) + ok(0, "getsockname on unbound socket should fail\n"); + else { + ok(WSAGetLastError() == WSAEINVAL, "getsockname on unbound socket " + "failed with %d, expected %d\n", WSAGetLastError(), WSAEINVAL); + ok(memcmp(&sa_get, &sa_set, sizeof(sa_get)) == 0, + "failed getsockname modified sockaddr when it shouldn't\n"); + } + if(bind(sock, (struct sockaddr *) &sa_set, sa_set_len) < 0){ trace("Failed to bind socket: %d\n", WSAGetLastError()); closesocket(sock);