From: Zebediah Figura zfigura@codeweavers.com
--- dlls/ws2_32/tests/sock.c | 90 +++++++++++++++++++++++++++++++++------- 1 file changed, 74 insertions(+), 16 deletions(-)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 3ec0ab67040..230f719d975 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -7822,7 +7822,7 @@ static void test_AcceptEx(void) const struct sockaddr_in bind_addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK)}; SOCKET listener, acceptor, acceptor2, connector, connector2; struct sockaddr_in bindAddress, peerAddress, *readBindAddress, *readRemoteAddress; - int socklen, optlen; + int socklen, iret, localSize = sizeof(struct sockaddr_in), remoteSize = localSize; GUID acceptExGuid = WSAID_ACCEPTEX, getAcceptExGuid = WSAID_GETACCEPTEXSOCKADDRS; GUID connectex_guid = WSAID_CONNECTEX; LPFN_ACCEPTEX pAcceptEx = NULL; @@ -7830,12 +7830,10 @@ static void test_AcceptEx(void) LPFN_CONNECTEX pConnectEx = NULL; fd_set fds_accept, fds_send; static const struct timeval timeout = {1, 0}; - DWORD bytesReturned, connect_time; char buffer[1024], ipbuffer[32]; OVERLAPPED overlapped = {0}, overlapped2 = {0}; - int iret, localSize = sizeof(struct sockaddr_in), remoteSize = localSize; + DWORD bytesReturned, dwret; BOOL bret; - DWORD dwret;
overlapped.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL); overlapped2.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL); @@ -8169,22 +8167,10 @@ static void test_AcceptEx(void) ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError()); ok(overlapped.Internal == STATUS_PENDING, "got %08lx\n", (ULONG)overlapped.Internal);
- connect_time = 0xdeadbeef; - optlen = sizeof(connect_time); - iret = getsockopt(connector, SOL_SOCKET, SO_CONNECT_TIME, (char *)&connect_time, &optlen); - ok(!iret, "getsockopt failed %d\n", WSAGetLastError()); - ok(connect_time == ~0u, "unexpected connect time %lu\n", connect_time); - /* AcceptEx() still won't complete until we send data */ iret = connect(connector, (struct sockaddr*)&bindAddress, sizeof(bindAddress)); ok(iret == 0, "connecting to accepting socket failed, error %d\n", WSAGetLastError());
- connect_time = 0xdeadbeef; - optlen = sizeof(connect_time); - iret = getsockopt(connector, SOL_SOCKET, SO_CONNECT_TIME, (char *)&connect_time, &optlen); - ok(!iret, "getsockopt failed %d\n", WSAGetLastError()); - ok(connect_time < 0xdeadbeef, "unexpected connect time %lu\n", connect_time); - dwret = WaitForSingleObject(overlapped.hEvent, 0); ok(dwret == WAIT_TIMEOUT, "Waiting for accept event timeout failed with %ld + errno %ld\n", dwret, GetLastError()); ok(overlapped.Internal == STATUS_PENDING, "got %08lx\n", (ULONG)overlapped.Internal); @@ -12797,6 +12783,77 @@ static void test_tcp_reset(void) CloseHandle(overlapped.hEvent); }
+static void test_connect_time(void) +{ + struct sockaddr_in addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK)}; + SOCKET client, server; + unsigned int time; + int ret, len; + + client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + + len = sizeof(time); + SetLastError(0xdeadbeef); + ret = getsockopt(client, SOL_SOCKET, SO_CONNECT_TIME, (char *)&time, &len); + ok(!ret, "got %d\n", ret); + ok(!GetLastError(), "got error %lu\n", GetLastError()); + ok(len == sizeof(time), "got len %d\n", len); + ok(time == ~0u, "got time %u\n", time); + + closesocket(client); + + tcp_socketpair(&client, &server); + + len = sizeof(time); + SetLastError(0xdeadbeef); + ret = getsockopt(client, SOL_SOCKET, SO_CONNECT_TIME, (char *)&time, &len); + ok(!ret, "got %d\n", ret); + ok(!GetLastError(), "got error %lu\n", GetLastError()); + ok(len == sizeof(time), "got len %d\n", len); + ok(time == 0, "got time %u\n", time); + + len = sizeof(time); + SetLastError(0xdeadbeef); + ret = getsockopt(server, SOL_SOCKET, SO_CONNECT_TIME, (char *)&time, &len); + ok(!ret, "got %d\n", ret); + ok(!GetLastError(), "got error %lu\n", GetLastError()); + ok(len == sizeof(time), "got len %d\n", len); + ok(time == 0, "got time %u\n", time); + + closesocket(client); + closesocket(server); + + client = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + server = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + + ret = bind(server, (struct sockaddr *)&addr, sizeof(addr)); + ok(!ret, "got error %lu\n", GetLastError()); + len = sizeof(addr); + ret = getsockname(server, (struct sockaddr *)&addr, &len); + ok(!ret, "got error %lu\n", GetLastError()); + ret = connect(client, (struct sockaddr *)&addr, sizeof(addr)); + ok(!ret, "got error %lu\n", GetLastError()); + + len = sizeof(time); + SetLastError(0xdeadbeef); + ret = getsockopt(client, SOL_SOCKET, SO_CONNECT_TIME, (char *)&time, &len); + ok(!ret, "got %d\n", ret); + ok(!GetLastError(), "got error %lu\n", GetLastError()); + ok(len == sizeof(time), "got len %d\n", len); + todo_wine ok(time == ~0u, "got time %u\n", time); + + len = sizeof(time); + SetLastError(0xdeadbeef); + ret = getsockopt(server, SOL_SOCKET, SO_CONNECT_TIME, (char *)&time, &len); + ok(!ret, "got %d\n", ret); + ok(!GetLastError(), "got error %lu\n", GetLastError()); + ok(len == sizeof(time), "got len %d\n", len); + ok(time == ~0u, "got time %u\n", time); + + closesocket(server); + closesocket(client); +} + START_TEST( sock ) { int i; @@ -12816,6 +12873,7 @@ START_TEST( sock ) test_extendedSocketOptions(); test_so_debug(); test_sockopt_validity(); + test_connect_time();
for (i = 0; i < ARRAY_SIZE(tests); i++) do_test(&tests[i]);
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/ws2_32/tests/sock.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 230f719d975..b7188d631ce 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -5859,7 +5859,7 @@ static void test_connect_events(struct event_test_ctx *ctx)
check_events(ctx, FD_WRITE, 0, 200);
- select_events(ctx, client, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ | FD_WRITE); + select_events(ctx, client, FD_ACCEPT | FD_CONNECT | FD_OOB | FD_READ | FD_WRITE);
if (ctx->is_message) check_events(ctx, FD_WRITE, 0, 200); @@ -5869,6 +5869,33 @@ static void test_connect_events(struct event_test_ctx *ctx) closesocket(client); closesocket(server);
+ /* Test with UDP sockets. */ + + client = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + server = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + + select_events(ctx, client, FD_ACCEPT | FD_CONNECT | FD_OOB | FD_READ | FD_WRITE); + if (ctx->is_message) + check_events(ctx, FD_WRITE, 0, 200); + check_events_todo_event(ctx, 0, 0, 0); + + ret = bind(server, (const struct sockaddr *)&addr, sizeof(addr)); + ok(!ret, "failed to bind, error %u\n", WSAGetLastError()); + len = sizeof(destaddr); + ret = getsockname(server, (struct sockaddr *)&destaddr, &len); + ok(!ret, "failed to get address, error %u\n", WSAGetLastError()); + ret = connect(client, (struct sockaddr *)&addr, sizeof(addr)); + ok(!ret, "got error %lu\n", GetLastError()); + + if (ctx->is_message) + check_events_todo(ctx, FD_WRITE, 0, 200); + else + check_events_todo(ctx, FD_CONNECT, FD_WRITE, 200); + check_events(ctx, 0, 0, 0); + + closesocket(client); + closesocket(server); + closesocket(listener); }
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/ws2_32/tests/sock.c | 86 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index b7188d631ce..f6feb0fa8b4 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -12881,6 +12881,91 @@ static void test_connect_time(void) closesocket(client); }
+static void test_connect_udp(void) +{ + const struct sockaddr_in bind_addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK)}; + struct sockaddr_in addr, ret_addr; + SOCKET client, server; + char buffer[5]; + int ret, len; + + client = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + server = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + set_blocking(client, FALSE); + set_blocking(server, FALSE); + + SetLastError(0xdeadbeef); + ret = send(client, "data", 4, 0); + ok(ret == -1, "got %d\n", ret); + todo_wine ok(GetLastError() == WSAENOTCONN, "got error %lu\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = recv(server, buffer, sizeof(buffer), 0); + ok(ret == -1, "got %d\n", ret); + todo_wine ok(GetLastError() == WSAEINVAL, "got error %lu\n", GetLastError()); + + ret = bind(server, (const struct sockaddr *)&bind_addr, sizeof(bind_addr)); + ok(!ret, "got error %lu\n", GetLastError()); + len = sizeof(addr); + ret = getsockname(server, (struct sockaddr *)&addr, &len); + ok(!ret, "got error %lu\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = recv(server, buffer, sizeof(buffer), 0); + ok(ret == -1, "got %d\n", ret); + ok(GetLastError() == WSAEWOULDBLOCK, "got error %lu\n", GetLastError()); + + ret = connect(client, (struct sockaddr *)&addr, sizeof(addr)); + ok(!ret, "got error %lu\n", GetLastError()); + ret = getpeername(client, (struct sockaddr *)&ret_addr, &len); + ok(!ret, "got error %lu\n", GetLastError()); + ok(!memcmp(&ret_addr, &addr, sizeof(addr)), "addresses didn't match\n"); + + ret = getsockname(client, (struct sockaddr *)&ret_addr, &len); + ok(!ret, "got error %lu\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = getpeername(server, (struct sockaddr *)&ret_addr, &len); + ok(ret == -1, "got %d\n", ret); + ok(GetLastError() == WSAENOTCONN, "got error %lu\n", GetLastError()); + + ret = send(client, "data", 4, 0); + ok(ret == 4, "got %d\n", ret); + + memset(buffer, 0xcc, sizeof(buffer)); + ret = recv(server, buffer, sizeof(buffer), 0); + ok(ret == 4, "got %d\n", ret); + ok(!memcmp(buffer, "data", 4), "got %s\n", debugstr_an(buffer, ret)); + + SetLastError(0xdeadbeef); + ret = recv(server, buffer, sizeof(buffer), 0); + ok(ret == -1, "got %d\n", ret); + ok(GetLastError() == WSAEWOULDBLOCK, "got error %lu\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = send(server, "data", 4, 0); + ok(ret == -1, "got %d\n", ret); + todo_wine ok(GetLastError() == WSAENOTCONN, "got error %lu\n", GetLastError()); + + ret = connect(client, (struct sockaddr *)&addr, sizeof(addr)); + todo_wine ok(!ret, "got error %lu\n", GetLastError()); + ++addr.sin_port; + ret = connect(client, (struct sockaddr *)&addr, sizeof(addr)); + todo_wine ok(!ret, "got error %lu\n", GetLastError()); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_UNSPEC; + ret = connect(client, (struct sockaddr *)&addr, sizeof(addr)); + todo_wine ok(!ret, "got error %lu\n", GetLastError()); + + ret = getpeername(client, (struct sockaddr *)&ret_addr, &len); + todo_wine ok(ret == -1, "got %d\n", ret); + todo_wine ok(GetLastError() == WSAENOTCONN, "got error %lu\n", GetLastError()); + + closesocket(server); + closesocket(client); +} + START_TEST( sock ) { int i; @@ -12958,6 +13043,7 @@ START_TEST( sock ) test_empty_recv(); test_timeout(); test_tcp_reset(); + test_connect_udp();
/* this is an io heavy test, do it at the end so the kernel doesn't start dropping packets */ test_send();
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/ws2_32/tests/afd.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+)
diff --git a/dlls/ws2_32/tests/afd.c b/dlls/ws2_32/tests/afd.c index 334c2c41be6..f2dccd465a3 100644 --- a/dlls/ws2_32/tests/afd.c +++ b/dlls/ws2_32/tests/afd.c @@ -829,6 +829,37 @@ static void test_poll(void) ok(out_params->sockets[0].flags == AFD_POLL_READ, "got flags %#x\n", out_params->sockets[0].flags); ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
+ in_params->timeout = -1000 * 10000; + in_params->count = 1; + in_params->sockets[0].socket = server; + in_params->sockets[0].flags = AFD_POLL_CONNECT; + params_size = offsetof(struct afd_poll_params, sockets[1]); + + ret = NtDeviceIoControlFile((HANDLE)server, event, NULL, NULL, &io, + IOCTL_AFD_POLL, in_params, params_size, out_params, params_size); + ok(ret == STATUS_PENDING, "got %#x\n", ret); + + ret = connect(server, (struct sockaddr *)&addr, sizeof(addr)); + ok(!ret, "got error %lu\n", GetLastError()); + + ret = WaitForSingleObject(event, 100); + todo_wine ok(!ret, "got %#x\n", ret); + if (!ret) + { + ok(!io.Status, "got %#lx\n", io.Status); + ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information); + ok(out_params->count == 1, "got count %u\n", out_params->count); + ok(out_params->sockets[0].socket == server, "got socket %#Ix\n", out_params->sockets[0].socket); + ok(out_params->sockets[0].flags == AFD_POLL_CONNECT, "got flags %#x\n", out_params->sockets[0].flags); + ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status); + } + else + { + CancelIo((HANDLE)server); + ret = WaitForSingleObject(event, 100); + ok(!ret, "wait timed out\n"); + } + closesocket(client); closesocket(server);
From: Zebediah Figura zfigura@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53058 --- dlls/ws2_32/tests/sock.c | 12 ++++++------ server/sock.c | 10 +++++++--- 2 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index f6feb0fa8b4..6c24202ad3b 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -12867,7 +12867,7 @@ static void test_connect_time(void) ok(!ret, "got %d\n", ret); ok(!GetLastError(), "got error %lu\n", GetLastError()); ok(len == sizeof(time), "got len %d\n", len); - todo_wine ok(time == ~0u, "got time %u\n", time); + ok(time == ~0u, "got time %u\n", time);
len = sizeof(time); SetLastError(0xdeadbeef); @@ -12948,19 +12948,19 @@ static void test_connect_udp(void) todo_wine ok(GetLastError() == WSAENOTCONN, "got error %lu\n", GetLastError());
ret = connect(client, (struct sockaddr *)&addr, sizeof(addr)); - todo_wine ok(!ret, "got error %lu\n", GetLastError()); + ok(!ret, "got error %lu\n", GetLastError()); ++addr.sin_port; ret = connect(client, (struct sockaddr *)&addr, sizeof(addr)); - todo_wine ok(!ret, "got error %lu\n", GetLastError()); + ok(!ret, "got error %lu\n", GetLastError());
memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_UNSPEC; ret = connect(client, (struct sockaddr *)&addr, sizeof(addr)); - todo_wine ok(!ret, "got error %lu\n", GetLastError()); + ok(!ret, "got error %lu\n", GetLastError());
ret = getpeername(client, (struct sockaddr *)&ret_addr, &len); - todo_wine ok(ret == -1, "got %d\n", ret); - todo_wine ok(GetLastError() == WSAENOTCONN, "got error %lu\n", GetLastError()); + ok(ret == -1, "got %d\n", ret); + ok(GetLastError() == WSAENOTCONN, "got error %lu\n", GetLastError());
closesocket(server); closesocket(client); diff --git a/server/sock.c b/server/sock.c index fed8e3b3093..7bb72119dc4 100644 --- a/server/sock.c +++ b/server/sock.c @@ -2358,13 +2358,17 @@ static void sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
if (!ret) { - sock->state = SOCK_CONNECTED; - sock->connect_time = current_time; + if (sock->type != WS_SOCK_DGRAM) + { + sock->state = SOCK_CONNECTED; + sock->connect_time = current_time; + }
if (!send_len) return; }
- sock->state = SOCK_CONNECTING; + if (sock->type != WS_SOCK_DGRAM) + sock->state = SOCK_CONNECTING;
if (params->synchronous && sock->nonblocking) {