ws2_32/tests: Add more tests for bind() and getsockname().
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
e35ea310a6
commit
2e0cb6d4de
|
@ -1414,9 +1414,14 @@ static void test_get_events(void)
|
||||||
|
|
||||||
static void test_bind(void)
|
static void test_bind(void)
|
||||||
{
|
{
|
||||||
|
const struct sockaddr_in6 bind_addr6 = {.sin6_family = AF_INET6, .sin6_addr.s6_words = {0, 0, 0, 0, 0, 0, 0, htons(1)}};
|
||||||
|
const struct sockaddr_in6 invalid_addr6 = {.sin6_family = AF_INET6, .sin6_addr.s6_words = {htons(0x0100)}};
|
||||||
const struct sockaddr_in invalid_addr = {.sin_family = AF_INET, .sin_addr.s_addr = inet_addr("192.0.2.0")};
|
const struct sockaddr_in invalid_addr = {.sin_family = AF_INET, .sin_addr.s_addr = inet_addr("192.0.2.0")};
|
||||||
const struct sockaddr_in bind_addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK)};
|
const struct sockaddr_in bind_addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK)};
|
||||||
struct afd_bind_params params = {0};
|
static const size_t params6_size = offsetof(struct afd_bind_params, addr) + sizeof(struct sockaddr_in6);
|
||||||
|
static const size_t params4_size = offsetof(struct afd_bind_params, addr) + sizeof(struct sockaddr_in);
|
||||||
|
struct afd_bind_params *params = malloc(params6_size);
|
||||||
|
struct sockaddr_in6 addr6, addr6_2;
|
||||||
struct sockaddr_in addr, addr2;
|
struct sockaddr_in addr, addr2;
|
||||||
struct hostent *host;
|
struct hostent *host;
|
||||||
IO_STATUS_BLOCK io;
|
IO_STATUS_BLOCK io;
|
||||||
|
@ -1427,47 +1432,48 @@ static void test_bind(void)
|
||||||
|
|
||||||
event = CreateEventW(NULL, TRUE, FALSE, NULL);
|
event = CreateEventW(NULL, TRUE, FALSE, NULL);
|
||||||
memset(&addr, 0xcc, sizeof(addr));
|
memset(&addr, 0xcc, sizeof(addr));
|
||||||
|
memset(params, 0, params6_size);
|
||||||
|
|
||||||
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
|
||||||
params.addr.sa_family = 0xdead;
|
params->addr.sa_family = 0xdead;
|
||||||
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
||||||
¶ms, sizeof(params), &addr, sizeof(addr));
|
params, params4_size, &addr, sizeof(addr));
|
||||||
ok(ret == STATUS_INVALID_ADDRESS, "got %#x\n", ret);
|
ok(ret == STATUS_INVALID_ADDRESS, "got %#x\n", ret);
|
||||||
|
|
||||||
memcpy(¶ms.addr, &bind_addr, sizeof(bind_addr));
|
memcpy(¶ms->addr, &bind_addr, sizeof(bind_addr));
|
||||||
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
||||||
¶ms, sizeof(params) - 1, &addr, sizeof(addr));
|
params, params4_size - 1, &addr, sizeof(addr));
|
||||||
ok(ret == STATUS_INVALID_ADDRESS, "got %#x\n", ret);
|
ok(ret == STATUS_INVALID_ADDRESS, "got %#x\n", ret);
|
||||||
|
|
||||||
memcpy(¶ms.addr, &bind_addr, sizeof(bind_addr));
|
memcpy(¶ms->addr, &bind_addr, sizeof(bind_addr));
|
||||||
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
||||||
¶ms, offsetof(struct afd_bind_params, addr.sa_data), &addr, sizeof(addr));
|
params, offsetof(struct afd_bind_params, addr.sa_data), &addr, sizeof(addr));
|
||||||
ok(ret == STATUS_INVALID_ADDRESS, "got %#x\n", ret);
|
ok(ret == STATUS_INVALID_ADDRESS, "got %#x\n", ret);
|
||||||
|
|
||||||
memcpy(¶ms.addr, &bind_addr, sizeof(bind_addr));
|
memcpy(¶ms->addr, &bind_addr, sizeof(bind_addr));
|
||||||
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
||||||
¶ms, offsetof(struct afd_bind_params, addr.sa_data) - 1, &addr, sizeof(addr));
|
params, offsetof(struct afd_bind_params, addr.sa_data) - 1, &addr, sizeof(addr));
|
||||||
ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
|
ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
|
||||||
|
|
||||||
memcpy(¶ms.addr, &invalid_addr, sizeof(invalid_addr));
|
memcpy(¶ms->addr, &invalid_addr, sizeof(invalid_addr));
|
||||||
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
||||||
¶ms, sizeof(params), &addr, sizeof(addr));
|
params, params4_size, &addr, sizeof(addr));
|
||||||
todo_wine ok(ret == STATUS_PENDING, "got %#x\n", ret);
|
todo_wine ok(ret == STATUS_PENDING, "got %#x\n", ret);
|
||||||
ret = WaitForSingleObject(event, 0);
|
ret = WaitForSingleObject(event, 0);
|
||||||
ok(!ret, "got %#x\n", ret);
|
ok(!ret, "got %#x\n", ret);
|
||||||
ok(io.Status == STATUS_INVALID_ADDRESS_COMPONENT, "got %#x\n", io.Status);
|
ok(io.Status == STATUS_INVALID_ADDRESS_COMPONENT, "got %#x\n", io.Status);
|
||||||
|
|
||||||
memcpy(¶ms.addr, &bind_addr, sizeof(bind_addr));
|
memcpy(¶ms->addr, &bind_addr, sizeof(bind_addr));
|
||||||
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
||||||
¶ms, sizeof(params), &addr, sizeof(addr) - 1);
|
params, params4_size, &addr, sizeof(addr) - 1);
|
||||||
ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
|
ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
|
||||||
|
|
||||||
memcpy(¶ms.addr, &bind_addr, sizeof(bind_addr));
|
memcpy(¶ms->addr, &bind_addr, sizeof(bind_addr));
|
||||||
memset(&io, 0xcc, sizeof(io));
|
memset(&io, 0xcc, sizeof(io));
|
||||||
memset(&addr, 0xcc, sizeof(addr));
|
memset(&addr, 0xcc, sizeof(addr));
|
||||||
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
||||||
¶ms, sizeof(params), &addr, sizeof(addr));
|
params, params4_size, &addr, sizeof(addr));
|
||||||
todo_wine ok(ret == STATUS_PENDING, "got %#x\n", ret);
|
todo_wine ok(ret == STATUS_PENDING, "got %#x\n", ret);
|
||||||
ret = WaitForSingleObject(event, 0);
|
ret = WaitForSingleObject(event, 0);
|
||||||
ok(!ret, "got %#x\n", ret);
|
ok(!ret, "got %#x\n", ret);
|
||||||
|
@ -1485,16 +1491,16 @@ static void test_bind(void)
|
||||||
ok(!memcmp(&addr, &addr2, sizeof(addr)), "addresses didn't match\n");
|
ok(!memcmp(&addr, &addr2, sizeof(addr)), "addresses didn't match\n");
|
||||||
|
|
||||||
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
||||||
¶ms, sizeof(params), &addr, sizeof(addr));
|
params, params4_size, &addr, sizeof(addr));
|
||||||
ok(ret == STATUS_ADDRESS_ALREADY_ASSOCIATED, "got %#x\n", ret);
|
ok(ret == STATUS_ADDRESS_ALREADY_ASSOCIATED, "got %#x\n", ret);
|
||||||
|
|
||||||
s2 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
s2 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
|
||||||
memcpy(¶ms.addr, &addr2, sizeof(addr2));
|
memcpy(¶ms->addr, &addr2, sizeof(addr2));
|
||||||
memset(&io, 0xcc, sizeof(io));
|
memset(&io, 0xcc, sizeof(io));
|
||||||
memset(&addr, 0xcc, sizeof(addr));
|
memset(&addr, 0xcc, sizeof(addr));
|
||||||
ret = NtDeviceIoControlFile((HANDLE)s2, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
ret = NtDeviceIoControlFile((HANDLE)s2, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
||||||
¶ms, sizeof(params), &addr, sizeof(addr));
|
params, params4_size, &addr, sizeof(addr));
|
||||||
todo_wine ok(ret == STATUS_PENDING, "got %#x\n", ret);
|
todo_wine ok(ret == STATUS_PENDING, "got %#x\n", ret);
|
||||||
ret = WaitForSingleObject(event, 0);
|
ret = WaitForSingleObject(event, 0);
|
||||||
ok(!ret, "got %#x\n", ret);
|
ok(!ret, "got %#x\n", ret);
|
||||||
|
@ -1508,11 +1514,11 @@ static void test_bind(void)
|
||||||
|
|
||||||
s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
|
||||||
memcpy(¶ms.addr, &bind_addr, sizeof(bind_addr));
|
memcpy(¶ms->addr, &bind_addr, sizeof(bind_addr));
|
||||||
memset(&io, 0xcc, sizeof(io));
|
memset(&io, 0xcc, sizeof(io));
|
||||||
memset(&addr, 0xcc, sizeof(addr));
|
memset(&addr, 0xcc, sizeof(addr));
|
||||||
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
||||||
¶ms, sizeof(params), &addr, sizeof(addr));
|
params, params4_size, &addr, sizeof(addr));
|
||||||
todo_wine ok(ret == STATUS_PENDING, "got %#x\n", ret);
|
todo_wine ok(ret == STATUS_PENDING, "got %#x\n", ret);
|
||||||
ret = WaitForSingleObject(event, 0);
|
ret = WaitForSingleObject(event, 0);
|
||||||
ok(!ret, "got %#x\n", ret);
|
ok(!ret, "got %#x\n", ret);
|
||||||
|
@ -1539,11 +1545,11 @@ static void test_bind(void)
|
||||||
|
|
||||||
s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
|
||||||
((struct sockaddr_in *)¶ms.addr)->sin_addr.s_addr = in_addr;
|
((struct sockaddr_in *)¶ms->addr)->sin_addr.s_addr = in_addr;
|
||||||
memset(&io, 0xcc, sizeof(io));
|
memset(&io, 0xcc, sizeof(io));
|
||||||
memset(&addr, 0xcc, sizeof(addr));
|
memset(&addr, 0xcc, sizeof(addr));
|
||||||
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
||||||
¶ms, sizeof(params), &addr, sizeof(addr));
|
params, params4_size, &addr, sizeof(addr));
|
||||||
todo_wine ok(ret == STATUS_PENDING, "got %#x\n", ret);
|
todo_wine ok(ret == STATUS_PENDING, "got %#x\n", ret);
|
||||||
ret = WaitForSingleObject(event, 0);
|
ret = WaitForSingleObject(event, 0);
|
||||||
ok(!ret, "got %#x\n", ret);
|
ok(!ret, "got %#x\n", ret);
|
||||||
|
@ -1563,7 +1569,106 @@ static void test_bind(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* test IPv6 */
|
||||||
|
|
||||||
|
s = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
ok(s != -1, "failed to create IPv6 socket\n");
|
||||||
|
|
||||||
|
params->addr.sa_family = 0xdead;
|
||||||
|
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
||||||
|
params, params6_size, &addr6, sizeof(addr6));
|
||||||
|
ok(ret == STATUS_INVALID_ADDRESS, "got %#x\n", ret);
|
||||||
|
|
||||||
|
memcpy(¶ms->addr, &bind_addr6, sizeof(bind_addr6));
|
||||||
|
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
||||||
|
params, params6_size - 1, &addr6, sizeof(addr6));
|
||||||
|
todo_wine ok(ret == STATUS_INVALID_ADDRESS, "got %#x\n", ret);
|
||||||
|
|
||||||
|
memcpy(¶ms->addr, &bind_addr6, sizeof(bind_addr6));
|
||||||
|
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
||||||
|
params, offsetof(struct afd_bind_params, addr) + sizeof(struct sockaddr_in6_old), &addr6, sizeof(addr6));
|
||||||
|
todo_wine ok(ret == STATUS_INVALID_ADDRESS, "got %#x\n", ret);
|
||||||
|
|
||||||
|
memcpy(¶ms->addr, &bind_addr6, sizeof(bind_addr6));
|
||||||
|
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
||||||
|
params, offsetof(struct afd_bind_params, addr.sa_data), &addr6, sizeof(addr6));
|
||||||
|
todo_wine ok(ret == STATUS_INVALID_ADDRESS, "got %#x\n", ret);
|
||||||
|
|
||||||
|
memcpy(¶ms->addr, &bind_addr6, sizeof(bind_addr6));
|
||||||
|
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
||||||
|
params, offsetof(struct afd_bind_params, addr.sa_data) - 1, &addr6, sizeof(addr6));
|
||||||
|
ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
|
||||||
|
|
||||||
|
memcpy(¶ms->addr, &invalid_addr6, sizeof(invalid_addr6));
|
||||||
|
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
||||||
|
params, params6_size, &addr6, sizeof(addr6));
|
||||||
|
todo_wine ok(ret == STATUS_PENDING, "got %#x\n", ret);
|
||||||
|
ret = WaitForSingleObject(event, 0);
|
||||||
|
todo_wine ok(!ret, "got %#x\n", ret);
|
||||||
|
todo_wine ok(io.Status == STATUS_INVALID_ADDRESS_COMPONENT, "got %#x\n", io.Status);
|
||||||
|
|
||||||
|
memcpy(¶ms->addr, &bind_addr6, sizeof(bind_addr6));
|
||||||
|
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
||||||
|
params, params6_size, &addr6, sizeof(addr6) - 1);
|
||||||
|
todo_wine ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
|
||||||
|
|
||||||
|
memcpy(¶ms->addr, &bind_addr6, sizeof(bind_addr6));
|
||||||
|
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
||||||
|
params, params6_size - 1, &addr6, sizeof(addr6) - 1);
|
||||||
|
todo_wine ok(ret == STATUS_INVALID_ADDRESS, "got %#x\n", ret);
|
||||||
|
|
||||||
|
memcpy(¶ms->addr, &bind_addr6, sizeof(bind_addr6));
|
||||||
|
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
||||||
|
params, params6_size, &addr6, sizeof(struct sockaddr_in6_old));
|
||||||
|
todo_wine ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
|
||||||
|
|
||||||
|
memcpy(¶ms->addr, &bind_addr6, sizeof(bind_addr6));
|
||||||
|
memset(&io, 0xcc, sizeof(io));
|
||||||
|
memset(&addr6, 0xcc, sizeof(addr6));
|
||||||
|
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
||||||
|
params, params6_size, &addr6, sizeof(addr6));
|
||||||
|
todo_wine ok(ret == STATUS_PENDING, "got %#x\n", ret);
|
||||||
|
ret = WaitForSingleObject(event, 0);
|
||||||
|
todo_wine
|
||||||
|
{
|
||||||
|
ok(!ret, "got %#x\n", ret);
|
||||||
|
ok(!io.Status, "got %#x\n", io.Status);
|
||||||
|
ok(io.Information == sizeof(addr6), "got %#Ix\n", io.Information);
|
||||||
|
ok(addr6.sin6_family == AF_INET6, "got family %u\n", addr6.sin6_family);
|
||||||
|
ok(!memcmp(&addr6.sin6_addr, &bind_addr6.sin6_addr, sizeof(addr6.sin6_addr)), "address didn't match\n");
|
||||||
|
ok(!addr6.sin6_flowinfo, "got flow info %#x\n", addr6.sin6_flowinfo);
|
||||||
|
}
|
||||||
|
ok(addr6.sin6_port, "expected nonzero port\n");
|
||||||
|
|
||||||
|
/* getsockname() returns EINVAL here. Possibly the socket name is cached (in shared memory?) */
|
||||||
|
memset(&addr6_2, 0xcc, sizeof(addr6_2));
|
||||||
|
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io,
|
||||||
|
IOCTL_AFD_GETSOCKNAME, NULL, 0, &addr6_2, sizeof(addr6_2));
|
||||||
|
ok(!ret, "got %#x\n", ret);
|
||||||
|
todo_wine ok(!memcmp(&addr6, &addr6_2, sizeof(addr6)), "addresses didn't match\n");
|
||||||
|
|
||||||
|
ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
||||||
|
params, params6_size, &addr6, sizeof(addr6));
|
||||||
|
ok(ret == STATUS_ADDRESS_ALREADY_ASSOCIATED, "got %#x\n", ret);
|
||||||
|
|
||||||
|
s2 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
|
||||||
|
memcpy(¶ms->addr, &addr6_2, sizeof(addr6_2));
|
||||||
|
memset(&io, 0xcc, sizeof(io));
|
||||||
|
memset(&addr6, 0xcc, sizeof(addr6));
|
||||||
|
ret = NtDeviceIoControlFile((HANDLE)s2, event, NULL, NULL, &io, IOCTL_AFD_BIND,
|
||||||
|
params, params6_size, &addr6, sizeof(addr6));
|
||||||
|
todo_wine ok(ret == STATUS_PENDING, "got %#x\n", ret);
|
||||||
|
ret = WaitForSingleObject(event, 0);
|
||||||
|
ok(!ret, "got %#x\n", ret);
|
||||||
|
ok(io.Status == STATUS_SHARING_VIOLATION, "got %#x\n", io.Status);
|
||||||
|
ok(!io.Information, "got %#Ix\n", io.Information);
|
||||||
|
|
||||||
|
closesocket(s2);
|
||||||
|
closesocket(s);
|
||||||
|
|
||||||
CloseHandle(event);
|
CloseHandle(event);
|
||||||
|
free(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_getsockname(void)
|
static void test_getsockname(void)
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <winternl.h>
|
#include <winternl.h>
|
||||||
|
#include <iphlpapi.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include <wsipx.h>
|
#include <wsipx.h>
|
||||||
#include <wsnwlink.h>
|
#include <wsnwlink.h>
|
||||||
|
@ -3779,9 +3780,13 @@ static void test_getsockname(void)
|
||||||
ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
|
ok(!ret, "failed to bind, error %u\n", WSAGetLastError());
|
||||||
|
|
||||||
WSASetLastError(0xdeadbeef);
|
WSASetLastError(0xdeadbeef);
|
||||||
|
memset(&sa_get, 0, sizeof(sa_get));
|
||||||
ret = getsockname(sock, (struct sockaddr *) &sa_get, &sa_get_len);
|
ret = getsockname(sock, (struct sockaddr *) &sa_get, &sa_get_len);
|
||||||
ok(!ret, "got %d\n", ret);
|
ok(!ret, "got %d\n", ret);
|
||||||
ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
|
ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
|
||||||
|
ok(sa_get.sin_family == AF_INET, "got family %#x\n", sa_get.sin_family);
|
||||||
|
ok(sa_get.sin_port != 0, "got zero port\n");
|
||||||
|
ok(sa_get.sin_addr.s_addr == INADDR_ANY, "got addr %08x\n", sa_get.sin_addr.s_addr);
|
||||||
|
|
||||||
ret = memcmp(sa_get.sin_zero, null_padding, 8);
|
ret = memcmp(sa_get.sin_zero, null_padding, 8);
|
||||||
ok(ret == 0, "getsockname did not zero the sockaddr_in structure\n");
|
ok(ret == 0, "getsockname did not zero the sockaddr_in structure\n");
|
||||||
|
@ -10566,6 +10571,8 @@ static void test_bind(void)
|
||||||
{
|
{
|
||||||
const struct sockaddr_in invalid_addr = {.sin_family = AF_INET, .sin_addr.s_addr = inet_addr("192.0.2.0")};
|
const struct sockaddr_in invalid_addr = {.sin_family = AF_INET, .sin_addr.s_addr = inet_addr("192.0.2.0")};
|
||||||
const struct sockaddr_in bind_addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK)};
|
const struct sockaddr_in bind_addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK)};
|
||||||
|
IP_ADAPTER_ADDRESSES *adapters = NULL, *adapter;
|
||||||
|
ULONG ip_addrs_size = 0;
|
||||||
struct sockaddr addr;
|
struct sockaddr addr;
|
||||||
SOCKET s, s2;
|
SOCKET s, s2;
|
||||||
int ret, len;
|
int ret, len;
|
||||||
|
@ -10625,6 +10632,83 @@ static void test_bind(void)
|
||||||
ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* win <7 */, "got error %u\n", WSAGetLastError());
|
ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* win <7 */, "got error %u\n", WSAGetLastError());
|
||||||
|
|
||||||
closesocket(s);
|
closesocket(s);
|
||||||
|
|
||||||
|
ret = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, adapters, &ip_addrs_size);
|
||||||
|
ok(ret == ERROR_BUFFER_OVERFLOW, "got error %u\n", ret);
|
||||||
|
adapters = malloc(ip_addrs_size);
|
||||||
|
ret = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, adapters, &ip_addrs_size);
|
||||||
|
ok(!ret, "got error %u\n", ret);
|
||||||
|
|
||||||
|
for (adapter = adapters; adapter != NULL; adapter = adapter->Next)
|
||||||
|
{
|
||||||
|
const IP_ADAPTER_UNICAST_ADDRESS *unicast_addr;
|
||||||
|
|
||||||
|
for (unicast_addr = adapter->FirstUnicastAddress; unicast_addr != NULL; unicast_addr = unicast_addr->Next)
|
||||||
|
{
|
||||||
|
short family = unicast_addr->Address.lpSockaddr->sa_family;
|
||||||
|
|
||||||
|
s = socket(family, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
ok(s != -1, "failed to create socket, error %u\n", WSAGetLastError());
|
||||||
|
|
||||||
|
ret = bind(s, unicast_addr->Address.lpSockaddr, unicast_addr->Address.iSockaddrLength);
|
||||||
|
ok(!ret, "got error %u\n", WSAGetLastError());
|
||||||
|
|
||||||
|
closesocket(s);
|
||||||
|
|
||||||
|
if (family == AF_INET6)
|
||||||
|
{
|
||||||
|
struct sockaddr_in6 addr6, ret_addr6;
|
||||||
|
|
||||||
|
memcpy(&addr6, unicast_addr->Address.lpSockaddr, sizeof(addr6));
|
||||||
|
|
||||||
|
ok(unicast_addr->Address.iSockaddrLength == sizeof(struct sockaddr_in6),
|
||||||
|
"got unexpected length %u\n", unicast_addr->Address.iSockaddrLength);
|
||||||
|
|
||||||
|
s = socket(family, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
ok(s != -1, "failed to create socket, error %u\n", WSAGetLastError());
|
||||||
|
|
||||||
|
ret = bind(s, unicast_addr->Address.lpSockaddr, sizeof(struct sockaddr_in6_old));
|
||||||
|
todo_wine_if (!addr6.sin6_scope_id)
|
||||||
|
{
|
||||||
|
ok(ret == -1, "expected failure\n");
|
||||||
|
ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
addr6.sin6_scope_id = 0xabacab;
|
||||||
|
ret = bind(s, (struct sockaddr *)&addr6, sizeof(addr6));
|
||||||
|
ok(ret == -1, "expected failure\n");
|
||||||
|
todo_wine ok(WSAGetLastError() == WSAEADDRNOTAVAIL, "got error %u\n", WSAGetLastError());
|
||||||
|
|
||||||
|
addr6.sin6_scope_id = 0;
|
||||||
|
ret = bind(s, (struct sockaddr *)&addr6, sizeof(addr6));
|
||||||
|
todo_wine ok(!ret, "got error %u\n", WSAGetLastError());
|
||||||
|
|
||||||
|
memcpy(&addr6, unicast_addr->Address.lpSockaddr, sizeof(addr6));
|
||||||
|
|
||||||
|
len = sizeof(struct sockaddr_in6_old);
|
||||||
|
ret = getsockname(s, (struct sockaddr *)&ret_addr6, &len);
|
||||||
|
ok(ret == -1, "expected failure\n");
|
||||||
|
todo_wine_if (addr6.sin6_scope_id)
|
||||||
|
ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
|
||||||
|
|
||||||
|
len = sizeof(ret_addr6);
|
||||||
|
memset(&ret_addr6, 0, sizeof(ret_addr6));
|
||||||
|
ret = getsockname(s, (struct sockaddr *)&ret_addr6, &len);
|
||||||
|
todo_wine_if (addr6.sin6_scope_id)
|
||||||
|
{
|
||||||
|
ok(!ret, "got error %u\n", WSAGetLastError());
|
||||||
|
ok(ret_addr6.sin6_family == AF_INET6, "got family %u\n", ret_addr6.sin6_family);
|
||||||
|
ok(ret_addr6.sin6_port != 0, "expected nonzero port\n");
|
||||||
|
ok(!memcmp(&ret_addr6.sin6_addr, &addr6.sin6_addr, sizeof(addr6.sin6_addr)), "address didn't match\n");
|
||||||
|
ok(ret_addr6.sin6_scope_id == addr6.sin6_scope_id, "got scope %u\n", ret_addr6.sin6_scope_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
closesocket(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(adapters);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test calling methods on a socket which is currently connecting. */
|
/* Test calling methods on a socket which is currently connecting. */
|
||||||
|
|
Loading…
Reference in New Issue