ws2_32: getsockname should fail on unbound socket.

This commit is contained in:
Damjan Jovanovic 2007-06-14 15:27:29 +02:00 committed by Alexandre Julliard
parent 3c3a879a86
commit 1cf9436efe
2 changed files with 43 additions and 0 deletions

View File

@ -927,6 +927,35 @@ static unsigned int ws_sockaddr_ws2u(const struct WS_sockaddr* wsaddr, int wsadd
return uaddrlen; 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 */ /* 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) 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()); SetLastError(wsaErrno());
} }
else if (!is_sockaddr_bound(&uaddr.addr, uaddrlen))
{
SetLastError(WSAEINVAL);
}
else if (ws_sockaddr_u2ws(&uaddr.addr, name, namelen) != 0) else if (ws_sockaddr_u2ws(&uaddr.addr, name, namelen) != 0)
{ {
/* The buffer was too small */ /* The buffer was too small */

View File

@ -1644,6 +1644,16 @@ static void test_getsockname(void)
return; 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){ if(bind(sock, (struct sockaddr *) &sa_set, sa_set_len) < 0){
trace("Failed to bind socket: %d\n", WSAGetLastError()); trace("Failed to bind socket: %d\n", WSAGetLastError());
closesocket(sock); closesocket(sock);