include: Revise the Winsock include in windows.h to match the Windows SDK.
[wine/multimedia.git] / dlls / ws2_32 / tests / sock.c
blobac0a7d056a714215d32970c57d1c04f4649f4613
1 /*
2 * Unit test suite for winsock functions
4 * Copyright 2002 Martin Wilck
5 * Copyright 2005 Thomas Kho
6 * Copyright 2008 Jeff Zaroyko
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include <ntstatus.h>
24 #define WIN32_NO_STATUS
25 #include <winsock2.h>
26 #include <windows.h>
27 #include <ws2tcpip.h>
28 #include <mswsock.h>
29 #include <stdio.h>
30 #include "wine/test.h"
32 #define MAX_CLIENTS 4 /* Max number of clients */
33 #define NUM_TESTS 4 /* Number of tests performed */
34 #define FIRST_CHAR 'A' /* First character in transferred pattern */
35 #define BIND_SLEEP 10 /* seconds to wait between attempts to bind() */
36 #define BIND_TRIES 6 /* Number of bind() attempts */
37 #define TEST_TIMEOUT 30 /* seconds to wait before killing child threads
38 after server initialization, if something hangs */
40 #define NUM_UDP_PEERS 3 /* Number of UDP sockets to create and test > 1 */
42 #define NUM_THREADS 3 /* Number of threads to run getservbyname */
43 #define NUM_QUERIES 250 /* Number of getservbyname queries per thread */
45 #define SERVERIP "127.0.0.1" /* IP to bind to */
46 #define SERVERPORT 9374 /* Port number to bind to */
48 #define wsa_ok(op, cond, msg) \
49 do { \
50 int tmp, err = 0; \
51 tmp = op; \
52 if ( !(cond tmp) ) err = WSAGetLastError(); \
53 ok ( cond tmp, msg, GetCurrentThreadId(), err); \
54 } while (0);
56 /* Function pointers */
57 static void (WINAPI *pFreeAddrInfoW)(PADDRINFOW) = 0;
58 static int (WINAPI *pGetAddrInfoW)(LPCWSTR,LPCWSTR,const ADDRINFOW *,PADDRINFOW *) = 0;
59 static PCSTR (WINAPI *pInetNtop)(INT,LPVOID,LPSTR,ULONG) = 0;
61 /**************** Structs and typedefs ***************/
63 typedef struct thread_info
65 HANDLE thread;
66 DWORD id;
67 } thread_info;
69 /* Information in the server about open client connections */
70 typedef struct sock_info
72 SOCKET s;
73 struct sockaddr_in addr;
74 struct sockaddr_in peer;
75 char *buf;
76 int n_recvd;
77 int n_sent;
78 } sock_info;
80 /* Test parameters for both server & client */
81 typedef struct test_params
83 int sock_type;
84 int sock_prot;
85 const char *inet_addr;
86 short inet_port;
87 int chunk_size;
88 int n_chunks;
89 int n_clients;
90 } test_params;
92 /* server-specific test parameters */
93 typedef struct server_params
95 test_params *general;
96 DWORD sock_flags;
97 int buflen;
98 } server_params;
100 /* client-specific test parameters */
101 typedef struct client_params
103 test_params *general;
104 DWORD sock_flags;
105 int buflen;
106 } client_params;
108 /* This type combines all information for setting up a test scenario */
109 typedef struct test_setup
111 test_params general;
112 LPVOID srv;
113 server_params srv_params;
114 LPVOID clt;
115 client_params clt_params;
116 } test_setup;
118 /* Thread local storage for server */
119 typedef struct server_memory
121 SOCKET s;
122 struct sockaddr_in addr;
123 sock_info sock[MAX_CLIENTS];
124 } server_memory;
126 /* Thread local storage for client */
127 typedef struct client_memory
129 SOCKET s;
130 struct sockaddr_in addr;
131 char *send_buf;
132 char *recv_buf;
133 } client_memory;
135 /* SelectReadThread thread parameters */
136 typedef struct select_thread_params
138 SOCKET s;
139 BOOL ReadKilled;
140 } select_thread_params;
142 /**************** Static variables ***************/
144 static DWORD tls; /* Thread local storage index */
145 static HANDLE thread[1+MAX_CLIENTS];
146 static DWORD thread_id[1+MAX_CLIENTS];
147 static HANDLE server_ready;
148 static HANDLE client_ready[MAX_CLIENTS];
149 static int client_id;
151 /**************** General utility functions ***************/
153 static int tcp_socketpair(SOCKET *src, SOCKET *dst)
155 SOCKET server = INVALID_SOCKET;
156 struct sockaddr_in addr;
157 int len;
158 int ret;
160 *src = INVALID_SOCKET;
161 *dst = INVALID_SOCKET;
163 *src = socket(AF_INET, SOCK_STREAM, 0);
164 if (*src == INVALID_SOCKET)
165 goto end;
167 server = socket(AF_INET, SOCK_STREAM, 0);
168 if (server == INVALID_SOCKET)
169 goto end;
171 memset(&addr, 0, sizeof(addr));
172 addr.sin_family = AF_INET;
173 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
174 ret = bind(server, (struct sockaddr*)&addr, sizeof(addr));
175 if (ret != 0)
176 goto end;
178 len = sizeof(addr);
179 ret = getsockname(server, (struct sockaddr*)&addr, &len);
180 if (ret != 0)
181 goto end;
183 ret = listen(server, 1);
184 if (ret != 0)
185 goto end;
187 ret = connect(*src, (struct sockaddr*)&addr, sizeof(addr));
188 if (ret != 0)
189 goto end;
191 len = sizeof(addr);
192 *dst = accept(server, (struct sockaddr*)&addr, &len);
194 end:
195 if (server != INVALID_SOCKET)
196 closesocket(server);
197 if (*src != INVALID_SOCKET && *dst != INVALID_SOCKET)
198 return 0;
199 closesocket(*src);
200 closesocket(*dst);
201 return -1;
204 static void set_so_opentype ( BOOL overlapped )
206 int optval = !overlapped, newval, len = sizeof (int);
208 ok ( setsockopt ( INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE,
209 (LPVOID) &optval, sizeof (optval) ) == 0,
210 "setting SO_OPENTYPE failed\n" );
211 ok ( getsockopt ( INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE,
212 (LPVOID) &newval, &len ) == 0,
213 "getting SO_OPENTYPE failed\n" );
214 ok ( optval == newval, "failed to set SO_OPENTYPE\n" );
217 static int set_blocking ( SOCKET s, BOOL blocking )
219 u_long val = !blocking;
220 return ioctlsocket ( s, FIONBIO, &val );
223 static void fill_buffer ( char *buf, int chunk_size, int n_chunks )
225 char c, *p;
226 for ( c = FIRST_CHAR, p = buf; c < FIRST_CHAR + n_chunks; c++, p += chunk_size )
227 memset ( p, c, chunk_size );
230 static int test_buffer ( char *buf, int chunk_size, int n_chunks )
232 char c, *p;
233 int i;
234 for ( c = FIRST_CHAR, p = buf; c < FIRST_CHAR + n_chunks; c++, p += chunk_size )
236 for ( i = 0; i < chunk_size; i++ )
237 if ( p[i] != c ) return i;
239 return -1;
243 * This routine is called when a client / server does not expect any more data,
244 * but needs to acknowledge the closing of the connection (by reading 0 bytes).
246 static void read_zero_bytes ( SOCKET s )
248 char buf[256];
249 int tmp, n = 0;
250 while ( ( tmp = recv ( s, buf, 256, 0 ) ) > 0 )
251 n += tmp;
252 ok ( n <= 0, "garbage data received: %d bytes\n", n );
255 static int do_synchronous_send ( SOCKET s, char *buf, int buflen, int sendlen )
257 char* last = buf + buflen, *p;
258 int n = 1;
259 for ( p = buf; n > 0 && p < last; p += n )
260 n = send ( s, p, min ( sendlen, last - p ), 0 );
261 wsa_ok ( n, 0 <=, "do_synchronous_send (%x): error %d\n" );
262 return p - buf;
265 static int do_synchronous_recv ( SOCKET s, char *buf, int buflen, int recvlen )
267 char* last = buf + buflen, *p;
268 int n = 1;
269 for ( p = buf; n > 0 && p < last; p += n )
270 n = recv ( s, p, min ( recvlen, last - p ), 0 );
271 wsa_ok ( n, 0 <=, "do_synchronous_recv (%x): error %d:\n" );
272 return p - buf;
275 static int do_synchronous_recvfrom ( SOCKET s, char *buf, int buflen,int flags,struct sockaddr *from, int *fromlen, int recvlen )
277 char* last = buf + buflen, *p;
278 int n = 1;
279 for ( p = buf; n > 0 && p < last; p += n )
280 n = recvfrom ( s, p, min ( recvlen, last - p ), 0, from, fromlen );
281 wsa_ok ( n, 0 <=, "do_synchronous_recv (%x): error %d:\n" );
282 return p - buf;
286 * Call this routine right after thread startup.
287 * SO_OPENTYPE must by 0, regardless what the server did.
289 static void check_so_opentype (void)
291 int tmp = 1, len;
292 len = sizeof (tmp);
293 getsockopt ( INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (LPVOID) &tmp, &len );
294 ok ( tmp == 0, "check_so_opentype: wrong startup value of SO_OPENTYPE: %d\n", tmp );
297 /**************** Server utility functions ***************/
300 * Even if we have closed our server socket cleanly,
301 * the OS may mark the address "in use" for some time -
302 * this happens with native Linux apps, too.
304 static void do_bind ( SOCKET s, struct sockaddr* addr, int addrlen )
306 int err, wsaerr = 0, n_try = BIND_TRIES;
308 while ( ( err = bind ( s, addr, addrlen ) ) != 0 &&
309 ( wsaerr = WSAGetLastError () ) == WSAEADDRINUSE &&
310 n_try-- >= 0)
312 trace ( "address in use, waiting ...\n" );
313 Sleep ( 1000 * BIND_SLEEP );
315 ok ( err == 0, "failed to bind: %d\n", wsaerr );
318 static void server_start ( server_params *par )
320 int i;
321 test_params *gen = par->general;
322 server_memory *mem = LocalAlloc ( LPTR, sizeof ( server_memory ) );
324 TlsSetValue ( tls, mem );
325 mem->s = WSASocketA ( AF_INET, gen->sock_type, gen->sock_prot,
326 NULL, 0, par->sock_flags );
327 ok ( mem->s != INVALID_SOCKET, "Server: WSASocket failed\n" );
329 mem->addr.sin_family = AF_INET;
330 mem->addr.sin_addr.s_addr = inet_addr ( gen->inet_addr );
331 mem->addr.sin_port = htons ( gen->inet_port );
333 for (i = 0; i < MAX_CLIENTS; i++)
335 mem->sock[i].s = INVALID_SOCKET;
336 mem->sock[i].buf = LocalAlloc ( LPTR, gen->n_chunks * gen->chunk_size );
337 mem->sock[i].n_recvd = 0;
338 mem->sock[i].n_sent = 0;
341 if ( gen->sock_type == SOCK_STREAM )
342 do_bind ( mem->s, (struct sockaddr*) &mem->addr, sizeof (mem->addr) );
345 static void server_stop (void)
347 int i;
348 server_memory *mem = TlsGetValue ( tls );
350 for (i = 0; i < MAX_CLIENTS; i++ )
352 LocalFree ( mem->sock[i].buf );
353 if ( mem->sock[i].s != INVALID_SOCKET )
354 closesocket ( mem->sock[i].s );
356 ok ( closesocket ( mem->s ) == 0, "closesocket failed\n" );
357 LocalFree ( mem );
358 ExitThread ( GetCurrentThreadId () );
361 /**************** Client utilitiy functions ***************/
363 static void client_start ( client_params *par )
365 test_params *gen = par->general;
366 client_memory *mem = LocalAlloc (LPTR, sizeof (client_memory));
368 TlsSetValue ( tls, mem );
370 WaitForSingleObject ( server_ready, INFINITE );
372 mem->s = WSASocketA ( AF_INET, gen->sock_type, gen->sock_prot,
373 NULL, 0, par->sock_flags );
375 mem->addr.sin_family = AF_INET;
376 mem->addr.sin_addr.s_addr = inet_addr ( gen->inet_addr );
377 mem->addr.sin_port = htons ( gen->inet_port );
379 ok ( mem->s != INVALID_SOCKET, "Client: WSASocket failed\n" );
381 mem->send_buf = LocalAlloc ( LPTR, 2 * gen->n_chunks * gen->chunk_size );
382 mem->recv_buf = mem->send_buf + gen->n_chunks * gen->chunk_size;
383 fill_buffer ( mem->send_buf, gen->chunk_size, gen->n_chunks );
385 SetEvent ( client_ready[client_id] );
386 /* Wait for the other clients to come up */
387 WaitForMultipleObjects ( min ( gen->n_clients, MAX_CLIENTS ), client_ready, TRUE, INFINITE );
390 static void client_stop (void)
392 client_memory *mem = TlsGetValue ( tls );
393 wsa_ok ( closesocket ( mem->s ), 0 ==, "closesocket error (%x): %d\n" );
394 LocalFree ( mem->send_buf );
395 LocalFree ( mem );
396 ExitThread(0);
399 /**************** Servers ***************/
402 * simple_server: A very basic server doing synchronous IO.
404 static VOID WINAPI simple_server ( server_params *par )
406 test_params *gen = par->general;
407 server_memory *mem;
408 int pos, n_recvd, n_sent, n_expected = gen->n_chunks * gen->chunk_size, tmp, i,
409 id = GetCurrentThreadId();
411 trace ( "simple_server (%x) starting\n", id );
413 set_so_opentype ( FALSE ); /* non-overlapped */
414 server_start ( par );
415 mem = TlsGetValue ( tls );
417 wsa_ok ( set_blocking ( mem->s, TRUE ), 0 ==, "simple_server (%x): failed to set blocking mode: %d\n");
418 wsa_ok ( listen ( mem->s, SOMAXCONN ), 0 ==, "simple_server (%x): listen failed: %d\n");
420 trace ( "simple_server (%x) ready\n", id );
421 SetEvent ( server_ready ); /* notify clients */
423 for ( i = 0; i < min ( gen->n_clients, MAX_CLIENTS ); i++ )
425 trace ( "simple_server (%x): waiting for client\n", id );
427 /* accept a single connection */
428 tmp = sizeof ( mem->sock[0].peer );
429 mem->sock[0].s = accept ( mem->s, (struct sockaddr*) &mem->sock[0].peer, &tmp );
430 wsa_ok ( mem->sock[0].s, INVALID_SOCKET !=, "simple_server (%x): accept failed: %d\n" );
432 ok ( mem->sock[0].peer.sin_addr.s_addr == inet_addr ( gen->inet_addr ),
433 "simple_server (%x): strange peer address\n", id );
435 /* Receive data & check it */
436 n_recvd = do_synchronous_recv ( mem->sock[0].s, mem->sock[0].buf, n_expected, par->buflen );
437 ok ( n_recvd == n_expected,
438 "simple_server (%x): received less data than expected: %d of %d\n", id, n_recvd, n_expected );
439 pos = test_buffer ( mem->sock[0].buf, gen->chunk_size, gen->n_chunks );
440 ok ( pos == -1, "simple_server (%x): test pattern error: %d\n", id, pos);
442 /* Echo data back */
443 n_sent = do_synchronous_send ( mem->sock[0].s, mem->sock[0].buf, n_expected, par->buflen );
444 ok ( n_sent == n_expected,
445 "simple_server (%x): sent less data than expected: %d of %d\n", id, n_sent, n_expected );
447 /* cleanup */
448 read_zero_bytes ( mem->sock[0].s );
449 wsa_ok ( closesocket ( mem->sock[0].s ), 0 ==, "simple_server (%x): closesocket error: %d\n" );
450 mem->sock[0].s = INVALID_SOCKET;
453 trace ( "simple_server (%x) exiting\n", id );
454 server_stop ();
458 * select_server: A non-blocking server.
460 static VOID WINAPI select_server ( server_params *par )
462 test_params *gen = par->general;
463 server_memory *mem;
464 int n_expected = gen->n_chunks * gen->chunk_size, tmp, i,
465 id = GetCurrentThreadId(), n_connections = 0, n_sent, n_recvd,
466 n_set, delta, n_ready;
467 struct timeval timeout = {0,10}; /* wait for 10 milliseconds */
468 fd_set fds_recv, fds_send, fds_openrecv, fds_opensend;
470 trace ( "select_server (%x) starting\n", id );
472 set_so_opentype ( FALSE ); /* non-overlapped */
473 server_start ( par );
474 mem = TlsGetValue ( tls );
476 wsa_ok ( set_blocking ( mem->s, FALSE ), 0 ==, "select_server (%x): failed to set blocking mode: %d\n");
477 wsa_ok ( listen ( mem->s, SOMAXCONN ), 0 ==, "select_server (%x): listen failed: %d\n");
479 trace ( "select_server (%x) ready\n", id );
480 SetEvent ( server_ready ); /* notify clients */
482 FD_ZERO ( &fds_openrecv );
483 FD_ZERO ( &fds_recv );
484 FD_ZERO ( &fds_send );
485 FD_ZERO ( &fds_opensend );
487 FD_SET ( mem->s, &fds_openrecv );
489 while(1)
491 fds_recv = fds_openrecv;
492 fds_send = fds_opensend;
494 n_set = 0;
496 wsa_ok ( ( n_ready = select ( 0, &fds_recv, &fds_send, NULL, &timeout ) ), SOCKET_ERROR !=,
497 "select_server (%x): select() failed: %d\n" );
499 /* check for incoming requests */
500 if ( FD_ISSET ( mem->s, &fds_recv ) ) {
501 n_set += 1;
503 trace ( "select_server (%x): accepting client connection\n", id );
505 /* accept a single connection */
506 tmp = sizeof ( mem->sock[n_connections].peer );
507 mem->sock[n_connections].s = accept ( mem->s, (struct sockaddr*) &mem->sock[n_connections].peer, &tmp );
508 wsa_ok ( mem->sock[n_connections].s, INVALID_SOCKET !=, "select_server (%x): accept() failed: %d\n" );
510 ok ( mem->sock[n_connections].peer.sin_addr.s_addr == inet_addr ( gen->inet_addr ),
511 "select_server (%x): strange peer address\n", id );
513 /* add to list of open connections */
514 FD_SET ( mem->sock[n_connections].s, &fds_openrecv );
515 FD_SET ( mem->sock[n_connections].s, &fds_opensend );
517 n_connections++;
520 /* handle open requests */
522 for ( i = 0; i < n_connections; i++ )
524 if ( FD_ISSET( mem->sock[i].s, &fds_recv ) ) {
525 n_set += 1;
527 if ( mem->sock[i].n_recvd < n_expected ) {
528 /* Receive data & check it */
529 n_recvd = recv ( mem->sock[i].s, mem->sock[i].buf + mem->sock[i].n_recvd, min ( n_expected - mem->sock[i].n_recvd, par->buflen ), 0 );
530 ok ( n_recvd != SOCKET_ERROR, "select_server (%x): error in recv(): %d\n", id, WSAGetLastError() );
531 mem->sock[i].n_recvd += n_recvd;
533 if ( mem->sock[i].n_recvd == n_expected ) {
534 int pos = test_buffer ( mem->sock[i].buf, gen->chunk_size, gen->n_chunks );
535 ok ( pos == -1, "select_server (%x): test pattern error: %d\n", id, pos );
536 FD_CLR ( mem->sock[i].s, &fds_openrecv );
539 ok ( mem->sock[i].n_recvd <= n_expected, "select_server (%x): received too many bytes: %d\n", id, mem->sock[i].n_recvd );
543 /* only echo back what we've received */
544 delta = mem->sock[i].n_recvd - mem->sock[i].n_sent;
546 if ( FD_ISSET ( mem->sock[i].s, &fds_send ) ) {
547 n_set += 1;
549 if ( ( delta > 0 ) && ( mem->sock[i].n_sent < n_expected ) ) {
550 /* Echo data back */
551 n_sent = send ( mem->sock[i].s, mem->sock[i].buf + mem->sock[i].n_sent, min ( delta, par->buflen ), 0 );
552 ok ( n_sent != SOCKET_ERROR, "select_server (%x): error in send(): %d\n", id, WSAGetLastError() );
553 mem->sock[i].n_sent += n_sent;
555 if ( mem->sock[i].n_sent == n_expected ) {
556 FD_CLR ( mem->sock[i].s, &fds_opensend );
559 ok ( mem->sock[i].n_sent <= n_expected, "select_server (%x): sent too many bytes: %d\n", id, mem->sock[i].n_sent );
564 /* check that select returned the correct number of ready sockets */
565 ok ( ( n_set == n_ready ), "select_server (%x): select() returns wrong number of ready sockets\n", id );
567 /* check if all clients are done */
568 if ( ( fds_opensend.fd_count == 0 )
569 && ( fds_openrecv.fd_count == 1 ) /* initial socket that accepts clients */
570 && ( n_connections == min ( gen->n_clients, MAX_CLIENTS ) ) ) {
571 break;
575 for ( i = 0; i < min ( gen->n_clients, MAX_CLIENTS ); i++ )
577 /* cleanup */
578 read_zero_bytes ( mem->sock[i].s );
579 wsa_ok ( closesocket ( mem->sock[i].s ), 0 ==, "select_server (%x): closesocket error: %d\n" );
580 mem->sock[i].s = INVALID_SOCKET;
583 trace ( "select_server (%x) exiting\n", id );
584 server_stop ();
587 /**************** Clients ***************/
590 * simple_client: A very basic client doing synchronous IO.
592 static VOID WINAPI simple_client ( client_params *par )
594 test_params *gen = par->general;
595 client_memory *mem;
596 int pos, n_sent, n_recvd, n_expected = gen->n_chunks * gen->chunk_size, id;
598 id = GetCurrentThreadId();
599 trace ( "simple_client (%x): starting\n", id );
600 /* wait here because we want to call set_so_opentype before creating a socket */
601 WaitForSingleObject ( server_ready, INFINITE );
602 trace ( "simple_client (%x): server ready\n", id );
604 check_so_opentype ();
605 set_so_opentype ( FALSE ); /* non-overlapped */
606 client_start ( par );
607 mem = TlsGetValue ( tls );
609 /* Connect */
610 wsa_ok ( connect ( mem->s, (struct sockaddr*) &mem->addr, sizeof ( mem->addr ) ),
611 0 ==, "simple_client (%x): connect error: %d\n" );
612 ok ( set_blocking ( mem->s, TRUE ) == 0,
613 "simple_client (%x): failed to set blocking mode\n", id );
614 trace ( "simple_client (%x) connected\n", id );
616 /* send data to server */
617 n_sent = do_synchronous_send ( mem->s, mem->send_buf, n_expected, par->buflen );
618 ok ( n_sent == n_expected,
619 "simple_client (%x): sent less data than expected: %d of %d\n", id, n_sent, n_expected );
621 /* shutdown send direction */
622 wsa_ok ( shutdown ( mem->s, SD_SEND ), 0 ==, "simple_client (%x): shutdown failed: %d\n" );
624 /* Receive data echoed back & check it */
625 n_recvd = do_synchronous_recv ( mem->s, mem->recv_buf, n_expected, par->buflen );
626 ok ( n_recvd == n_expected,
627 "simple_client (%x): received less data than expected: %d of %d\n", id, n_recvd, n_expected );
629 /* check data */
630 pos = test_buffer ( mem->recv_buf, gen->chunk_size, gen->n_chunks );
631 ok ( pos == -1, "simple_client (%x): test pattern error: %d\n", id, pos);
633 /* cleanup */
634 read_zero_bytes ( mem->s );
635 trace ( "simple_client (%x) exiting\n", id );
636 client_stop ();
640 * simple_mixed_client: mixing send and recvfrom
642 static VOID WINAPI simple_mixed_client ( client_params *par )
644 test_params *gen = par->general;
645 client_memory *mem;
646 int pos, n_sent, n_recvd, n_expected = gen->n_chunks * gen->chunk_size, id;
647 int fromLen = sizeof(mem->addr);
648 struct sockaddr test;
650 id = GetCurrentThreadId();
651 trace ( "simple_client (%x): starting\n", id );
652 /* wait here because we want to call set_so_opentype before creating a socket */
653 WaitForSingleObject ( server_ready, INFINITE );
654 trace ( "simple_client (%x): server ready\n", id );
656 check_so_opentype ();
657 set_so_opentype ( FALSE ); /* non-overlapped */
658 client_start ( par );
659 mem = TlsGetValue ( tls );
661 /* Connect */
662 wsa_ok ( connect ( mem->s, (struct sockaddr*) &mem->addr, sizeof ( mem->addr ) ),
663 0 ==, "simple_client (%x): connect error: %d\n" );
664 ok ( set_blocking ( mem->s, TRUE ) == 0,
665 "simple_client (%x): failed to set blocking mode\n", id );
666 trace ( "simple_client (%x) connected\n", id );
668 /* send data to server */
669 n_sent = do_synchronous_send ( mem->s, mem->send_buf, n_expected, par->buflen );
670 ok ( n_sent == n_expected,
671 "simple_client (%x): sent less data than expected: %d of %d\n", id, n_sent, n_expected );
673 /* shutdown send direction */
674 wsa_ok ( shutdown ( mem->s, SD_SEND ), 0 ==, "simple_client (%x): shutdown failed: %d\n" );
676 /* this shouldn't change, since lpFrom, is not updated on
677 connection oriented sockets - exposed by bug 11640
679 ((struct sockaddr_in*)&test)->sin_addr.s_addr = inet_addr("0.0.0.0");
681 /* Receive data echoed back & check it */
682 n_recvd = do_synchronous_recvfrom ( mem->s,
683 mem->recv_buf,
684 n_expected,
686 (struct sockaddr *)&test,
687 &fromLen,
688 par->buflen );
689 ok ( n_recvd == n_expected,
690 "simple_client (%x): received less data than expected: %d of %d\n", id, n_recvd, n_expected );
692 /* check that lpFrom was not updated */
693 ok(0 ==
694 strcmp(
695 inet_ntoa(((struct sockaddr_in*)&test)->sin_addr),
696 "0.0.0.0"), "lpFrom shouldn't be updated on connection oriented sockets\n");
698 /* check data */
699 pos = test_buffer ( mem->recv_buf, gen->chunk_size, gen->n_chunks );
700 ok ( pos == -1, "simple_client (%x): test pattern error: %d\n", id, pos);
702 /* cleanup */
703 read_zero_bytes ( mem->s );
704 trace ( "simple_client (%x) exiting\n", id );
705 client_stop ();
709 * event_client: An event-driven client
711 static void WINAPI event_client ( client_params *par )
713 test_params *gen = par->general;
714 client_memory *mem;
715 int id = GetCurrentThreadId(), n_expected = gen->n_chunks * gen->chunk_size,
716 tmp, err, n;
717 HANDLE event;
718 WSANETWORKEVENTS wsa_events;
719 char *send_last, *recv_last, *send_p, *recv_p;
720 LONG mask = FD_READ | FD_WRITE | FD_CLOSE;
722 trace ( "event_client (%x): starting\n", id );
723 client_start ( par );
724 trace ( "event_client (%x): server ready\n", id );
726 mem = TlsGetValue ( tls );
728 /* Prepare event notification for connect, makes socket nonblocking */
729 event = WSACreateEvent ();
730 WSAEventSelect ( mem->s, event, FD_CONNECT );
731 tmp = connect ( mem->s, (struct sockaddr*) &mem->addr, sizeof ( mem->addr ) );
732 if ( tmp != 0 ) {
733 err = WSAGetLastError ();
734 ok ( err == WSAEWOULDBLOCK, "event_client (%x): connect error: %d\n", id, err );
735 tmp = WaitForSingleObject ( event, INFINITE );
736 ok ( tmp == WAIT_OBJECT_0, "event_client (%x): wait for connect event failed: %d\n", id, tmp );
737 err = WSAEnumNetworkEvents ( mem->s, event, &wsa_events );
738 ok ( err == 0, "event_client (%x): WSAEnumNetworkEvents error: %d\n", id, err );
739 err = wsa_events.iErrorCode[ FD_CONNECT_BIT ];
740 ok ( err == 0, "event_client (%x): connect error: %d\n", id, err );
741 if ( err ) goto out;
744 trace ( "event_client (%x) connected\n", id );
746 WSAEventSelect ( mem->s, event, mask );
748 recv_p = mem->recv_buf;
749 recv_last = mem->recv_buf + n_expected;
750 send_p = mem->send_buf;
751 send_last = mem->send_buf + n_expected;
753 while ( TRUE )
755 err = WaitForSingleObject ( event, INFINITE );
756 ok ( err == WAIT_OBJECT_0, "event_client (%x): wait failed\n", id );
758 err = WSAEnumNetworkEvents ( mem->s, event, &wsa_events );
759 ok( err == 0, "event_client (%x): WSAEnumNetworkEvents error: %d\n", id, err );
761 if ( wsa_events.lNetworkEvents & FD_WRITE )
763 err = wsa_events.iErrorCode[ FD_WRITE_BIT ];
764 ok ( err == 0, "event_client (%x): FD_WRITE error code: %d\n", id, err );
766 if ( err== 0 )
769 n = send ( mem->s, send_p, min ( send_last - send_p, par->buflen ), 0 );
770 if ( n < 0 )
772 err = WSAGetLastError ();
773 ok ( err == WSAEWOULDBLOCK, "event_client (%x): send error: %d\n", id, err );
775 else
776 send_p += n;
778 while ( n >= 0 && send_p < send_last );
780 if ( send_p == send_last )
782 trace ( "event_client (%x): all data sent - shutdown\n", id );
783 shutdown ( mem->s, SD_SEND );
784 mask &= ~FD_WRITE;
785 WSAEventSelect ( mem->s, event, mask );
788 if ( wsa_events.lNetworkEvents & FD_READ )
790 err = wsa_events.iErrorCode[ FD_READ_BIT ];
791 ok ( err == 0, "event_client (%x): FD_READ error code: %d\n", id, err );
792 if ( err != 0 ) break;
794 /* First read must succeed */
795 n = recv ( mem->s, recv_p, min ( recv_last - recv_p, par->buflen ), 0 );
796 wsa_ok ( n, 0 <=, "event_client (%x): recv error: %d\n" );
798 while ( n >= 0 ) {
799 recv_p += n;
800 if ( recv_p == recv_last )
802 mask &= ~FD_READ;
803 trace ( "event_client (%x): all data received\n", id );
804 WSAEventSelect ( mem->s, event, mask );
805 break;
807 n = recv ( mem->s, recv_p, min ( recv_last - recv_p, par->buflen ), 0 );
808 if ( n < 0 && ( err = WSAGetLastError()) != WSAEWOULDBLOCK )
809 ok ( 0, "event_client (%x): read error: %d\n", id, err );
813 if ( wsa_events.lNetworkEvents & FD_CLOSE )
815 trace ( "event_client (%x): close event\n", id );
816 err = wsa_events.iErrorCode[ FD_CLOSE_BIT ];
817 ok ( err == 0, "event_client (%x): FD_CLOSE error code: %d\n", id, err );
818 break;
822 n = send_p - mem->send_buf;
823 ok ( send_p == send_last,
824 "simple_client (%x): sent less data than expected: %d of %d\n", id, n, n_expected );
825 n = recv_p - mem->recv_buf;
826 ok ( recv_p == recv_last,
827 "simple_client (%x): received less data than expected: %d of %d\n", id, n, n_expected );
828 n = test_buffer ( mem->recv_buf, gen->chunk_size, gen->n_chunks );
829 ok ( n == -1, "event_client (%x): test pattern error: %d\n", id, n);
831 out:
832 WSACloseEvent ( event );
833 trace ( "event_client (%x) exiting\n", id );
834 client_stop ();
837 /* Tests for WSAStartup */
838 static void test_WithoutWSAStartup(void)
840 LPVOID ptr;
842 WSASetLastError(0xdeadbeef);
843 ptr = gethostbyname("localhost");
845 ok(ptr == NULL, "gethostbyname() succeeded unexpectedly: %d\n", WSAGetLastError());
846 ok(WSAGetLastError() == WSANOTINITIALISED, "gethostbyname() failed with unexpected error: %d\n",
847 WSAGetLastError());
850 static void test_WithWSAStartup(void)
852 WSADATA data;
853 WORD version = MAKEWORD( 2, 2 );
854 INT res;
855 LPVOID ptr;
857 res = WSAStartup( version, &data );
858 ok(res == 0, "WSAStartup() failed unexpectedly: %d\n", res);
860 ptr = gethostbyname("localhost");
861 ok(ptr != NULL, "gethostbyname() failed unexpectedly: %d\n", WSAGetLastError());
863 WSACleanup();
866 /**************** Main program utility functions ***************/
868 static void Init (void)
870 WORD ver = MAKEWORD (2, 2);
871 WSADATA data;
872 HMODULE hws2_32 = GetModuleHandle("ws2_32.dll");
874 pFreeAddrInfoW = (void *)GetProcAddress(hws2_32, "FreeAddrInfoW");
875 pGetAddrInfoW = (void *)GetProcAddress(hws2_32, "GetAddrInfoW");
876 pInetNtop = (void *)GetProcAddress(hws2_32, "inet_ntop");
878 ok ( WSAStartup ( ver, &data ) == 0, "WSAStartup failed\n" );
879 tls = TlsAlloc();
882 static void Exit (void)
884 INT ret, err;
885 TlsFree ( tls );
886 ret = WSACleanup();
887 err = WSAGetLastError();
888 ok ( ret == 0, "WSACleanup failed ret = %d GetLastError is %d\n", ret, err);
889 ret = WSACleanup();
890 err = WSAGetLastError();
891 ok ( (ret == SOCKET_ERROR && err == WSANOTINITIALISED) ||
892 broken(ret == 0), /* WinME */
893 "WSACleanup returned %d GetLastError is %d\n", ret, err);
896 static void StartServer (LPTHREAD_START_ROUTINE routine,
897 test_params *general, server_params *par)
899 par->general = general;
900 thread[0] = CreateThread ( NULL, 0, routine, par, 0, &thread_id[0] );
901 ok ( thread[0] != NULL, "Failed to create server thread\n" );
904 static void StartClients (LPTHREAD_START_ROUTINE routine,
905 test_params *general, client_params *par)
907 int i;
908 par->general = general;
909 for ( i = 1; i <= min ( general->n_clients, MAX_CLIENTS ); i++ )
911 client_id = i - 1;
912 thread[i] = CreateThread ( NULL, 0, routine, par, 0, &thread_id[i] );
913 ok ( thread[i] != NULL, "Failed to create client thread\n" );
914 /* Make sure the client is up and running */
915 WaitForSingleObject ( client_ready[client_id], INFINITE );
919 static void do_test( test_setup *test )
921 DWORD i, n = min (test->general.n_clients, MAX_CLIENTS);
922 DWORD wait;
924 server_ready = CreateEventA ( NULL, TRUE, FALSE, NULL );
925 for (i = 0; i <= n; i++)
926 client_ready[i] = CreateEventA ( NULL, TRUE, FALSE, NULL );
928 StartServer ( test->srv, &test->general, &test->srv_params );
929 StartClients ( test->clt, &test->general, &test->clt_params );
930 WaitForSingleObject ( server_ready, INFINITE );
932 wait = WaitForMultipleObjects ( 1 + n, thread, TRUE, 1000 * TEST_TIMEOUT );
933 ok ( wait <= WAIT_OBJECT_0 + n ,
934 "some threads have not completed: %x\n", wait );
936 if ( ! ( wait <= WAIT_OBJECT_0 + n ) )
938 for (i = 0; i <= n; i++)
940 if ( WaitForSingleObject ( thread[i], 0 ) != WAIT_OBJECT_0 )
942 trace ("terminating thread %08x\n", thread_id[i]);
943 TerminateThread ( thread [i], 0 );
947 CloseHandle ( server_ready );
948 for (i = 0; i <= n; i++)
949 CloseHandle ( client_ready[i] );
952 /********* some tests for getsockopt(setsockopt(X)) == X ***********/
953 /* optname = SO_LINGER */
954 static const LINGER linger_testvals[] = {
955 {0,0},
956 {0,73},
957 {1,0},
958 {5,189}
961 /* optname = SO_RCVTIMEO, SOSNDTIMEO */
962 #define SOCKTIMEOUT1 63000 /* 63 seconds. Do not test fractional part because of a
963 bug in the linux kernel (fixed in 2.6.8) */
964 #define SOCKTIMEOUT2 997000 /* 997 seconds */
966 static void test_set_getsockopt(void)
968 SOCKET s;
969 int i, err, lasterr;
970 int timeout;
971 LINGER lingval;
972 int size;
974 s = socket(AF_INET, SOCK_STREAM, 0);
975 ok(s!=INVALID_SOCKET, "socket() failed error: %d\n", WSAGetLastError());
976 if( s == INVALID_SOCKET) return;
977 /* SO_RCVTIMEO */
978 timeout = SOCKTIMEOUT1;
979 size = sizeof(timeout);
980 err = setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, size);
981 if( !err)
982 err = getsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, &size);
983 ok( !err, "get/setsockopt(SO_RCVTIMEO) failed error: %d\n", WSAGetLastError());
984 ok( timeout == SOCKTIMEOUT1, "getsockopt(SO_RCVTIMEO) returned wrong value %d\n", timeout);
986 timeout = 0;
987 size = sizeof(timeout);
988 err = setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, size);
989 if( !err)
990 err = getsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, &size);
991 ok( !err, "get/setsockopt(SO_RCVTIMEO) failed error: %d\n", WSAGetLastError());
992 ok( timeout == 0, "getsockopt(SO_RCVTIMEO) returned wrong value %d\n", timeout);
994 /* SO_SNDTIMEO */
995 timeout = SOCKTIMEOUT2; /* 997 seconds. See remark above */
996 size = sizeof(timeout);
997 err = setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char *) &timeout, size);
998 if( !err)
999 err = getsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char *) &timeout, &size);
1000 ok( !err, "get/setsockopt(SO_SNDTIMEO) failed error: %d\n", WSAGetLastError());
1001 ok( timeout == SOCKTIMEOUT2, "getsockopt(SO_SNDTIMEO) returned wrong value %d\n", timeout);
1002 /* SO_LINGER */
1003 for( i = 0; i < sizeof(linger_testvals)/sizeof(LINGER);i++) {
1004 size = sizeof(lingval);
1005 lingval = linger_testvals[i];
1006 err = setsockopt(s, SOL_SOCKET, SO_LINGER, (char *) &lingval, size);
1007 if( !err)
1008 err = getsockopt(s, SOL_SOCKET, SO_LINGER, (char *) &lingval, &size);
1009 ok( !err, "get/setsockopt(SO_LINGER) failed error: %d\n", WSAGetLastError());
1010 ok( !lingval.l_onoff == !linger_testvals[i].l_onoff &&
1011 (lingval.l_linger == linger_testvals[i].l_linger ||
1012 (!lingval.l_linger && !linger_testvals[i].l_onoff))
1013 , "getsockopt(SO_LINGER #%d) returned wrong value %d,%d not %d,%d\n", i,
1014 lingval.l_onoff, lingval.l_linger,
1015 linger_testvals[i].l_onoff, linger_testvals[i].l_linger);
1017 /* Test for erroneously passing a value instead of a pointer as optval */
1018 size = sizeof(char);
1019 err = setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *)1, size);
1020 ok(err == SOCKET_ERROR, "setsockopt with optval being a value passed "
1021 "instead of failing.\n");
1022 lasterr = WSAGetLastError();
1023 ok(lasterr == WSAEFAULT, "setsockopt with optval being a value "
1024 "returned 0x%08x, not WSAEFAULT(0x%08x)\n",
1025 lasterr, WSAEFAULT);
1027 /* SO_RCVTIMEO with invalid values for level */
1028 size = sizeof(timeout);
1029 timeout = SOCKTIMEOUT1;
1030 SetLastError(0xdeadbeef);
1031 err = setsockopt(s, 0xffffffff, SO_RCVTIMEO, (char *) &timeout, size);
1032 ok( (err == SOCKET_ERROR) && (WSAGetLastError() == WSAEINVAL),
1033 "got %d with %d (expected SOCKET_ERROR with WSAEINVAL\n",
1034 err, WSAGetLastError());
1036 timeout = SOCKTIMEOUT1;
1037 SetLastError(0xdeadbeef);
1038 err = setsockopt(s, 0x00008000, SO_RCVTIMEO, (char *) &timeout, size);
1039 ok( (err == SOCKET_ERROR) && (WSAGetLastError() == WSAEINVAL),
1040 "got %d with %d (expected SOCKET_ERROR with WSAEINVAL\n",
1041 err, WSAGetLastError());
1043 closesocket(s);
1046 static void test_so_reuseaddr(void)
1048 struct sockaddr_in saddr;
1049 SOCKET s1,s2;
1050 unsigned int rc,reuse;
1051 int size;
1053 saddr.sin_family = AF_INET;
1054 saddr.sin_port = htons(9375);
1055 saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
1057 s1=socket(AF_INET, SOCK_STREAM, 0);
1058 ok(s1!=INVALID_SOCKET, "socket() failed error: %d\n", WSAGetLastError());
1059 rc = bind(s1, (struct sockaddr*)&saddr, sizeof(saddr));
1060 ok(rc!=SOCKET_ERROR, "bind(s1) failed error: %d\n", WSAGetLastError());
1062 s2=socket(AF_INET, SOCK_STREAM, 0);
1063 ok(s2!=INVALID_SOCKET, "socket() failed error: %d\n", WSAGetLastError());
1065 reuse=0x1234;
1066 size=sizeof(reuse);
1067 rc=getsockopt(s2, SOL_SOCKET, SO_REUSEADDR, (char*)&reuse, &size );
1068 ok(rc==0 && reuse==0,"wrong result in getsockopt(SO_REUSEADDR): rc=%d reuse=%d\n",rc,reuse);
1070 rc = bind(s2, (struct sockaddr*)&saddr, sizeof(saddr));
1071 ok(rc==SOCKET_ERROR, "bind() succeeded\n");
1073 reuse = 1;
1074 rc = setsockopt(s2, SOL_SOCKET, SO_REUSEADDR, (char*)&reuse, sizeof(reuse));
1075 ok(rc==0, "setsockopt() failed error: %d\n", WSAGetLastError());
1077 /* On Win2k3 and above, all SO_REUSEADDR seems to do is to allow binding to
1078 * a port immediately after closing another socket on that port, so
1079 * basically following the BSD socket semantics here. */
1080 closesocket(s1);
1081 rc = bind(s2, (struct sockaddr*)&saddr, sizeof(saddr));
1082 ok(rc==0, "bind() failed error: %d\n", WSAGetLastError());
1084 closesocket(s2);
1087 #define IP_PKTINFO_LEN (sizeof(WSACMSGHDR) + WSA_CMSG_ALIGN(sizeof(struct in_pktinfo)))
1089 static void test_ip_pktinfo(void)
1091 ULONG addresses[2] = {inet_addr("127.0.0.1"), htonl(INADDR_ANY)};
1092 char recvbuf[10], pktbuf[512], msg[] = "HELLO";
1093 struct sockaddr_in s1addr, s2addr, s3addr;
1094 GUID WSARecvMsg_GUID = WSAID_WSARECVMSG;
1095 LPFN_WSARECVMSG pWSARecvMsg = NULL;
1096 unsigned int rc, foundhdr, yes = 1;
1097 DWORD dwBytes, dwSize, dwFlags;
1098 socklen_t addrlen;
1099 WSACMSGHDR *cmsg;
1100 WSAOVERLAPPED ov;
1101 WSABUF iovec[1];
1102 SOCKET s1, s2;
1103 WSAMSG hdr;
1104 int i, err;
1106 memset(&ov, 0, sizeof(ov));
1107 ov.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
1108 if (ov.hEvent == INVALID_HANDLE_VALUE)
1110 skip("Could not create event object, some tests will be skipped. errno = %d\n", GetLastError());
1111 return;
1114 memset(&hdr, 0x00, sizeof(hdr));
1115 s1addr.sin_family = AF_INET;
1116 s1addr.sin_port = htons(0);
1117 /* Note: s1addr.sin_addr is set below */
1118 iovec[0].buf = recvbuf;
1119 iovec[0].len = sizeof(recvbuf);
1120 hdr.name = (struct sockaddr*)&s3addr;
1121 hdr.namelen = sizeof(s3addr);
1122 hdr.lpBuffers = &iovec[0];
1123 hdr.dwBufferCount = 1;
1124 hdr.Control.buf = pktbuf;
1125 /* Note: hdr.Control.len is set below */
1126 hdr.dwFlags = 0;
1128 for (i=0;i<sizeof(addresses)/sizeof(UINT32);i++)
1130 s1addr.sin_addr.s_addr = addresses[i];
1132 /* Build "server" side socket */
1133 s1=socket(AF_INET, SOCK_DGRAM, 0);
1134 if (s1 == INVALID_SOCKET)
1136 skip("socket() failed error, some tests skipped: %d\n", WSAGetLastError());
1137 goto cleanup;
1140 /* Obtain the WSARecvMsg function */
1141 WSAIoctl(s1, SIO_GET_EXTENSION_FUNCTION_POINTER, &WSARecvMsg_GUID, sizeof(WSARecvMsg_GUID),
1142 &pWSARecvMsg, sizeof(pWSARecvMsg), &dwBytes, NULL, NULL);
1143 if (!pWSARecvMsg)
1145 win_skip("WSARecvMsg is unsupported, some tests will be skipped.\n");
1146 closesocket(s1);
1147 goto cleanup;
1150 /* Setup the server side socket */
1151 rc=bind(s1, (struct sockaddr*)&s1addr, sizeof(s1addr));
1152 ok(rc != SOCKET_ERROR, "bind() failed error: %d\n", WSAGetLastError());
1153 rc=setsockopt(s1, IPPROTO_IP, IP_PKTINFO, (const char*)&yes, sizeof(yes));
1154 ok(rc == 0, "failed to set IPPROTO_IP flag IP_PKTINFO!\n");
1156 /* Build "client" side socket */
1157 addrlen = sizeof(s2addr);
1158 if (getsockname(s1, (struct sockaddr *) &s2addr, &addrlen) != 0)
1160 skip("Failed to call getsockname, some tests skipped: %d\n", WSAGetLastError());
1161 closesocket(s1);
1162 goto cleanup;
1164 s2addr.sin_addr.s_addr = addresses[0]; /* Always target the local adapter address */
1165 s2=socket(AF_INET, SOCK_DGRAM, 0);
1166 if (s2 == INVALID_SOCKET)
1168 skip("socket() failed error, some tests skipped: %d\n", WSAGetLastError());
1169 closesocket(s1);
1170 goto cleanup;
1173 /* Test an empty message header */
1174 rc=pWSARecvMsg(s1, NULL, NULL, NULL, NULL);
1175 err=WSAGetLastError();
1176 ok(rc == SOCKET_ERROR && err == WSAEFAULT, "WSARecvMsg() failed error: %d (ret = %d)\n", err, rc);
1179 * Send a packet from the client to the server and test for specifying
1180 * a short control header.
1182 rc=sendto(s2, msg, sizeof(msg), 0, (struct sockaddr*)&s2addr, sizeof(s2addr));
1183 ok(rc == sizeof(msg), "sendto() failed error: %d\n", WSAGetLastError());
1184 hdr.Control.len = 1;
1185 rc=pWSARecvMsg(s1, &hdr, &dwSize, NULL, NULL);
1186 err=WSAGetLastError();
1187 ok(rc == SOCKET_ERROR && err == WSAEMSGSIZE && (hdr.dwFlags & MSG_CTRUNC),
1188 "WSARecvMsg() failed error: %d (ret: %d, flags: %d)\n", err, rc, hdr.dwFlags);
1189 hdr.dwFlags = 0; /* Reset flags */
1191 /* Perform another short control header test, this time with an overlapped receive */
1192 hdr.Control.len = 1;
1193 rc=pWSARecvMsg(s1, &hdr, NULL, &ov, NULL);
1194 err=WSAGetLastError();
1195 ok(rc != 0 && err == WSA_IO_PENDING, "WSARecvMsg() failed error: %d\n", err);
1196 rc=sendto(s2, msg, sizeof(msg), 0, (struct sockaddr*)&s2addr, sizeof(s2addr));
1197 ok(rc == sizeof(msg), "sendto() failed error: %d\n", WSAGetLastError());
1198 if (WaitForSingleObject(ov.hEvent, 100) != WAIT_OBJECT_0)
1200 skip("Server side did not receive packet, some tests skipped.\n");
1201 closesocket(s2);
1202 closesocket(s1);
1203 continue;
1205 dwFlags = 0;
1206 WSAGetOverlappedResult(s1, &ov, NULL, FALSE, &dwFlags);
1207 ok(dwFlags == 0,
1208 "WSAGetOverlappedResult() returned unexpected flags %d!\n", dwFlags);
1209 ok(hdr.dwFlags == MSG_CTRUNC,
1210 "WSARecvMsg() overlapped operation set unexpected flags %d.\n", hdr.dwFlags);
1211 hdr.dwFlags = 0; /* Reset flags */
1214 * Setup an overlapped receive, send a packet, then wait for the packet to be retrieved
1215 * on the server end and check that the returned packet matches what was sent.
1217 hdr.Control.len = sizeof(pktbuf);
1218 rc=pWSARecvMsg(s1, &hdr, NULL, &ov, NULL);
1219 err=WSAGetLastError();
1220 ok(rc != 0 && err == WSA_IO_PENDING, "WSARecvMsg() failed error: %d\n", err);
1221 ok(hdr.Control.len == sizeof(pktbuf),
1222 "WSARecvMsg() control length mismatch (%d != sizeof pktbuf).\n", hdr.Control.len);
1223 rc=sendto(s2, msg, sizeof(msg), 0, (struct sockaddr*)&s2addr, sizeof(s2addr));
1224 ok(rc == sizeof(msg), "sendto() failed error: %d\n", WSAGetLastError());
1225 if (WaitForSingleObject(ov.hEvent, 100) != WAIT_OBJECT_0)
1227 skip("Server side did not receive packet, some tests skipped.\n");
1228 closesocket(s2);
1229 closesocket(s1);
1230 continue;
1232 dwSize = 0;
1233 WSAGetOverlappedResult(s1, &ov, &dwSize, FALSE, NULL);
1234 ok(dwSize == sizeof(msg),
1235 "WSARecvMsg() buffer length does not match transmitted data!\n");
1236 ok(strncmp(iovec[0].buf, msg, sizeof(msg)) == 0,
1237 "WSARecvMsg() buffer does not match transmitted data!\n");
1238 ok(hdr.Control.len == IP_PKTINFO_LEN,
1239 "WSARecvMsg() control length mismatch (%d).\n", hdr.Control.len);
1241 /* Test for the expected IP_PKTINFO return information. */
1242 foundhdr = FALSE;
1243 for (cmsg = WSA_CMSG_FIRSTHDR(&hdr); cmsg != NULL; cmsg = WSA_CMSG_NXTHDR(&hdr, cmsg))
1245 if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO)
1247 struct in_pktinfo *pi = (struct in_pktinfo *)WSA_CMSG_DATA(cmsg);
1249 ok(pi->ipi_addr.s_addr == s2addr.sin_addr.s_addr, "destination ip mismatch!\n");
1250 foundhdr = TRUE;
1253 ok(foundhdr, "IP_PKTINFO header information was not returned!\n");
1255 closesocket(s2);
1256 closesocket(s1);
1259 cleanup:
1260 CloseHandle(ov.hEvent);
1263 /************* Array containing the tests to run **********/
1265 #define STD_STREAM_SOCKET \
1266 SOCK_STREAM, \
1267 0, \
1268 SERVERIP, \
1269 SERVERPORT
1271 static test_setup tests [NUM_TESTS] =
1273 /* Test 0: synchronous client and server */
1276 STD_STREAM_SOCKET,
1277 2048,
1281 simple_server,
1283 NULL,
1287 simple_client,
1289 NULL,
1294 /* Test 1: event-driven client, synchronous server */
1297 STD_STREAM_SOCKET,
1298 2048,
1302 simple_server,
1304 NULL,
1308 event_client,
1310 NULL,
1311 WSA_FLAG_OVERLAPPED,
1315 /* Test 2: synchronous client, non-blocking server via select() */
1318 STD_STREAM_SOCKET,
1319 2048,
1323 select_server,
1325 NULL,
1329 simple_client,
1331 NULL,
1336 /* Test 3: synchronous mixed client and server */
1339 STD_STREAM_SOCKET,
1340 2048,
1344 simple_server,
1346 NULL,
1350 simple_mixed_client,
1352 NULL,
1359 static void test_UDP(void)
1361 /* This function tests UDP sendto() and recvfrom(). UDP is unreliable, so it is
1362 possible that this test fails due to dropped packets. */
1364 /* peer 0 receives data from all other peers */
1365 struct sock_info peer[NUM_UDP_PEERS];
1366 char buf[16];
1367 int ss, i, n_recv, n_sent;
1369 memset (buf,0,sizeof(buf));
1370 for ( i = NUM_UDP_PEERS - 1; i >= 0; i-- ) {
1371 ok ( ( peer[i].s = socket ( AF_INET, SOCK_DGRAM, 0 ) ) != INVALID_SOCKET, "UDP: socket failed\n" );
1373 peer[i].addr.sin_family = AF_INET;
1374 peer[i].addr.sin_addr.s_addr = inet_addr ( SERVERIP );
1376 if ( i == 0 ) {
1377 peer[i].addr.sin_port = htons ( SERVERPORT );
1378 } else {
1379 peer[i].addr.sin_port = htons ( 0 );
1382 do_bind ( peer[i].s, (struct sockaddr *) &peer[i].addr, sizeof( peer[i].addr ) );
1384 /* test getsockname() to get peer's port */
1385 ss = sizeof ( peer[i].addr );
1386 ok ( getsockname ( peer[i].s, (struct sockaddr *) &peer[i].addr, &ss ) != SOCKET_ERROR, "UDP: could not getsockname()\n" );
1387 ok ( peer[i].addr.sin_port != htons ( 0 ), "UDP: bind() did not associate port\n" );
1390 /* test getsockname() */
1391 ok ( peer[0].addr.sin_port == htons ( SERVERPORT ), "UDP: getsockname returned incorrect peer port\n" );
1393 for ( i = 1; i < NUM_UDP_PEERS; i++ ) {
1394 /* send client's ip */
1395 memcpy( buf, &peer[i].addr.sin_port, sizeof(peer[i].addr.sin_port) );
1396 n_sent = sendto ( peer[i].s, buf, sizeof(buf), 0, (struct sockaddr*) &peer[0].addr, sizeof(peer[0].addr) );
1397 ok ( n_sent == sizeof(buf), "UDP: sendto() sent wrong amount of data or socket error: %d\n", n_sent );
1400 for ( i = 1; i < NUM_UDP_PEERS; i++ ) {
1401 n_recv = recvfrom ( peer[0].s, buf, sizeof(buf), 0,(struct sockaddr *) &peer[0].peer, &ss );
1402 ok ( n_recv == sizeof(buf), "UDP: recvfrom() received wrong amount of data or socket error: %d\n", n_recv );
1403 ok ( memcmp ( &peer[0].peer.sin_port, buf, sizeof(peer[0].addr.sin_port) ) == 0, "UDP: port numbers do not match\n" );
1407 static void WINAPI do_getservbyname( HANDLE *starttest )
1409 struct {
1410 const char *name;
1411 const char *proto;
1412 int port;
1413 } serv[2] = { {"domain", "udp", 53}, {"telnet", "tcp", 23} };
1415 int i, j;
1416 struct servent *pserv[2];
1418 ok ( WaitForSingleObject ( *starttest, TEST_TIMEOUT * 1000 ) != WAIT_TIMEOUT, "test_getservbyname: timeout waiting for start signal\n");
1420 /* ensure that necessary buffer resizes are completed */
1421 for ( j = 0; j < 2; j++) {
1422 pserv[j] = getservbyname ( serv[j].name, serv[j].proto );
1425 for ( i = 0; i < NUM_QUERIES / 2; i++ ) {
1426 for ( j = 0; j < 2; j++ ) {
1427 pserv[j] = getservbyname ( serv[j].name, serv[j].proto );
1428 ok ( pserv[j] != NULL, "getservbyname could not retrieve information for %s: %d\n", serv[j].name, WSAGetLastError() );
1429 ok ( pserv[j]->s_port == htons(serv[j].port), "getservbyname returned the wrong port for %s: %d\n", serv[j].name, ntohs(pserv[j]->s_port) );
1430 ok ( !strcmp ( pserv[j]->s_proto, serv[j].proto ), "getservbyname returned the wrong protocol for %s: %s\n", serv[j].name, pserv[j]->s_proto );
1431 ok ( !strcmp ( pserv[j]->s_name, serv[j].name ), "getservbyname returned the wrong name for %s: %s\n", serv[j].name, pserv[j]->s_name );
1434 ok ( pserv[0] == pserv[1], "getservbyname: winsock resized servent buffer when not necessary\n" );
1438 static void test_getservbyname(void)
1440 int i;
1441 HANDLE starttest, thread[NUM_THREADS];
1442 DWORD thread_id[NUM_THREADS];
1444 starttest = CreateEvent ( NULL, 1, 0, "test_getservbyname_starttest" );
1446 /* create threads */
1447 for ( i = 0; i < NUM_THREADS; i++ ) {
1448 thread[i] = CreateThread ( NULL, 0, (LPTHREAD_START_ROUTINE) &do_getservbyname, &starttest, 0, &thread_id[i] );
1451 /* signal threads to start */
1452 SetEvent ( starttest );
1454 for ( i = 0; i < NUM_THREADS; i++) {
1455 WaitForSingleObject ( thread[i], TEST_TIMEOUT * 1000 );
1459 static void test_WSASocket(void)
1461 SOCKET sock = INVALID_SOCKET;
1462 WSAPROTOCOL_INFOA *pi;
1463 int providers[] = {6, 0};
1464 int ret, err;
1465 UINT pi_size;
1467 /* Set pi_size explicitly to a value below 2*sizeof(WSAPROTOCOL_INFOA)
1468 * to avoid a crash on win98.
1470 pi_size = 0;
1471 ret = WSAEnumProtocolsA(providers, NULL, &pi_size);
1472 ok(ret == SOCKET_ERROR, "WSAEnumProtocolsA({6,0}, NULL, 0) returned %d\n",
1473 ret);
1474 err = WSAGetLastError();
1475 ok(err == WSAENOBUFS, "WSAEnumProtocolsA error is %d, not WSAENOBUFS(%d)\n",
1476 err, WSAENOBUFS);
1478 pi = HeapAlloc(GetProcessHeap(), 0, pi_size);
1479 ok(pi != NULL, "Failed to allocate memory\n");
1480 if (pi == NULL) {
1481 skip("Can't continue without memory.\n");
1482 return;
1485 ret = WSAEnumProtocolsA(providers, pi, &pi_size);
1486 ok(ret != SOCKET_ERROR, "WSAEnumProtocolsA failed, last error is %d\n",
1487 WSAGetLastError());
1489 if (ret == 0) {
1490 skip("No protocols enumerated.\n");
1491 HeapFree(GetProcessHeap(), 0, pi);
1492 return;
1495 sock = WSASocketA(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
1496 FROM_PROTOCOL_INFO, &pi[0], 0, 0);
1497 ok(sock != INVALID_SOCKET, "Failed to create socket: %d\n",
1498 WSAGetLastError());
1500 closesocket(sock);
1501 HeapFree(GetProcessHeap(), 0, pi);
1504 static void test_WSAAddressToStringA(void)
1506 SOCKET v6 = INVALID_SOCKET;
1507 INT ret;
1508 DWORD len;
1509 int GLE;
1510 SOCKADDR_IN sockaddr;
1511 CHAR address[22]; /* 12 digits + 3 dots + ':' + 5 digits + '\0' */
1513 CHAR expect1[] = "0.0.0.0";
1514 CHAR expect2[] = "255.255.255.255";
1515 CHAR expect3[] = "0.0.0.0:65535";
1516 CHAR expect4[] = "255.255.255.255:65535";
1518 SOCKADDR_IN6 sockaddr6;
1519 CHAR address6[54]; /* 32 digits + 7':' + '[' + '%" + 5 digits + ']:' + 5 digits + '\0' */
1521 CHAR addr6_1[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01};
1522 CHAR addr6_2[] = {0x20,0xab,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01};
1523 CHAR addr6_3[] = {0x20,0xab,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01};
1525 CHAR expect6_1[] = "::1";
1526 CHAR expect6_2[] = "20ab::1";
1527 CHAR expect6_3[] = "[20ab::2001]:33274";
1528 CHAR expect6_3_nt[] = "20ab::2001@33274";
1529 CHAR expect6_3_w2k[] = "20ab::2001";
1530 CHAR expect6_3_2[] = "[20ab::2001%4660]:33274";
1531 CHAR expect6_3_2_nt[] = "4660/20ab::2001@33274";
1532 CHAR expect6_3_2_w2k[] = "20ab::2001%4660";
1533 CHAR expect6_3_3[] = "20ab::2001%4660";
1534 CHAR expect6_3_3_nt[] = "4660/20ab::2001";
1536 len = 0;
1538 sockaddr.sin_family = AF_INET;
1539 sockaddr.sin_port = 0;
1540 sockaddr.sin_addr.s_addr = 0;
1542 ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
1543 GLE = WSAGetLastError();
1544 ok( (ret == SOCKET_ERROR && GLE == WSAEFAULT) || (ret == 0),
1545 "WSAAddressToStringA() failed unexpectedly: WSAGetLastError()=%d, ret=%d\n",
1546 GLE, ret );
1548 len = sizeof(address);
1550 sockaddr.sin_family = AF_INET;
1551 sockaddr.sin_port = 0;
1552 sockaddr.sin_addr.s_addr = 0;
1554 ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
1555 ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
1557 ok( !strcmp( address, expect1 ), "Expected: %s, got: %s\n", expect1, address );
1558 ok( len == sizeof( expect1 ), "Got size %d\n", len);
1560 len = sizeof(address);
1562 sockaddr.sin_family = AF_INET;
1563 sockaddr.sin_port = 0;
1564 sockaddr.sin_addr.s_addr = 0xffffffff;
1566 ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
1567 ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
1569 ok( !strcmp( address, expect2 ), "Expected: %s, got: %s\n", expect2, address );
1571 len = sizeof(address);
1573 sockaddr.sin_family = AF_INET;
1574 sockaddr.sin_port = 0xffff;
1575 sockaddr.sin_addr.s_addr = 0;
1577 ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
1578 ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
1580 ok( !strcmp( address, expect3 ), "Expected: %s, got: %s\n", expect3, address );
1582 len = sizeof(address);
1584 sockaddr.sin_family = AF_INET;
1585 sockaddr.sin_port = 0xffff;
1586 sockaddr.sin_addr.s_addr = 0xffffffff;
1588 ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
1589 ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
1591 ok( !strcmp( address, expect4 ), "Expected: %s, got: %s\n", expect4, address );
1592 ok( len == sizeof( expect4 ), "Got size %d\n", len);
1594 /*check to see it IPv6 is available */
1595 v6 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
1596 if (v6 == INVALID_SOCKET) {
1597 skip("Could not create IPv6 socket (LastError: %d; %d expected if IPv6 not available).\n",
1598 WSAGetLastError(), WSAEAFNOSUPPORT);
1599 goto end;
1601 /* Test a short IPv6 address */
1602 len = sizeof(address6);
1604 sockaddr6.sin6_family = AF_INET6;
1605 sockaddr6.sin6_port = 0x0000;
1606 sockaddr6.sin6_scope_id = 0;
1607 memcpy (sockaddr6.sin6_addr.s6_addr, addr6_1, sizeof(addr6_1));
1609 ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len );
1610 ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
1611 ok( !strcmp( address6, expect6_1 ), "Expected: %s, got: %s\n", expect6_1, address6 );
1612 ok( len == sizeof(expect6_1), "Got size %d\n", len);
1614 /* Test a longer IPv6 address */
1615 len = sizeof(address6);
1617 sockaddr6.sin6_family = AF_INET6;
1618 sockaddr6.sin6_port = 0x0000;
1619 sockaddr6.sin6_scope_id = 0;
1620 memcpy (sockaddr6.sin6_addr.s6_addr, addr6_2, sizeof(addr6_2));
1622 ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len );
1623 ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
1624 ok( !strcmp( address6, expect6_2 ), "Expected: %s, got: %s\n", expect6_2, address6 );
1625 ok( len == sizeof(expect6_2), "Got size %d\n", len);
1627 /* Test IPv6 address and port number */
1628 len = sizeof(address6);
1630 sockaddr6.sin6_family = AF_INET6;
1631 sockaddr6.sin6_port = 0xfa81;
1632 sockaddr6.sin6_scope_id = 0;
1633 memcpy (sockaddr6.sin6_addr.s6_addr, addr6_3, sizeof(addr6_3));
1635 ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len );
1636 ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
1637 ok( !strcmp( address6, expect6_3 ) ||
1638 broken( !strcmp( address6, expect6_3_nt ) ) || /* NT4 */
1639 broken( !strcmp( address6, expect6_3_w2k ) ), /* Win2000 */
1640 "Expected: %s, got: %s\n", expect6_3, address6 );
1641 ok( len == sizeof(expect6_3) ||
1642 broken( len == sizeof(expect6_3_nt) ) || /* NT4 */
1643 broken( len == sizeof(expect6_3_w2k) ), /* Win2000 */
1644 "Got size %d\n", len);
1646 /* Test IPv6 address, port number and scope_id */
1647 len = sizeof(address6);
1649 sockaddr6.sin6_family = AF_INET6;
1650 sockaddr6.sin6_port = 0xfa81;
1651 sockaddr6.sin6_scope_id = 0x1234;
1652 memcpy (sockaddr6.sin6_addr.s6_addr, addr6_3, sizeof(addr6_3));
1654 ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len );
1655 ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
1656 ok( !strcmp( address6, expect6_3_2 ) ||
1657 broken( !strcmp( address6, expect6_3_2_nt ) ) || /* NT4 */
1658 broken( !strcmp( address6, expect6_3_2_w2k ) ), /* Win2000 */
1659 "Expected: %s, got: %s\n", expect6_3_2, address6 );
1660 ok( len == sizeof(expect6_3_2) ||
1661 broken( len == sizeof(expect6_3_2_nt) ) || /* NT4 */
1662 broken( len == sizeof(expect6_3_2_w2k) ), /* Win2000 */
1663 "Got size %d\n", len);
1665 /* Test IPv6 address and scope_id */
1666 len = sizeof(address6);
1668 sockaddr6.sin6_family = AF_INET6;
1669 sockaddr6.sin6_port = 0x0000;
1670 sockaddr6.sin6_scope_id = 0x1234;
1671 memcpy (sockaddr6.sin6_addr.s6_addr, addr6_3, sizeof(addr6_3));
1673 ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len );
1674 ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
1675 ok( !strcmp( address6, expect6_3_3 ) ||
1676 broken( !strcmp( address6, expect6_3_3_nt ) ), /* NT4 */
1677 "Expected: %s, got: %s\n", expect6_3_3, address6 );
1678 ok( len == sizeof(expect6_3_3) ||
1679 broken( len == sizeof(expect6_3_3_nt) ), /* NT4 */
1680 "Got size %d\n", len);
1682 end:
1683 if (v6 != INVALID_SOCKET)
1684 closesocket(v6);
1687 static void test_WSAAddressToStringW(void)
1689 SOCKET v6 = INVALID_SOCKET;
1690 INT ret;
1691 DWORD len;
1692 int GLE;
1693 SOCKADDR_IN sockaddr;
1694 WCHAR address[22]; /* 12 digits + 3 dots + ':' + 5 digits + '\0' */
1696 WCHAR expect1[] = { '0','.','0','.','0','.','0', 0 };
1697 WCHAR expect2[] = { '2','5','5','.','2','5','5','.','2','5','5','.','2','5','5', 0 };
1698 WCHAR expect3[] = { '0','.','0','.','0','.','0', ':', '6', '5', '5', '3', '5', 0 };
1699 WCHAR expect4[] = { '2','5','5','.','2','5','5','.','2','5','5','.','2','5','5', ':',
1700 '6', '5', '5', '3', '5', 0 };
1702 SOCKADDR_IN6 sockaddr6;
1703 WCHAR address6[54]; /* 32 digits + 7':' + '[' + '%" + 5 digits + ']:' + 5 digits + '\0' */
1705 CHAR addr6_1[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01};
1706 CHAR addr6_2[] = {0x20,0xab,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01};
1707 CHAR addr6_3[] = {0x20,0xab,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01};
1709 WCHAR expect6_1[] = {':',':','1',0};
1710 WCHAR expect6_2[] = {'2','0','a','b',':',':','1',0};
1711 WCHAR expect6_3[] = {'[','2','0','a','b',':',':','2','0','0','1',']',':','3','3','2','7','4',0};
1712 WCHAR expect6_3_nt[] = {'2','0','a','b',':',':','2','0','0','1','@','3','3','2','7','4',0};
1713 WCHAR expect6_3_w2k[] = {'2','0','a','b',':',':','2','0','0','1',0};
1714 WCHAR expect6_3_2[] = {'[','2','0','a','b',':',':','2','0','0','1','%','4','6','6','0',']',':','3','3','2','7','4',0};
1715 WCHAR expect6_3_2_nt[] = {'4','6','6','0','/','2','0','a','b',':',':','2','0','0','1','@','3','3','2','7','4',0};
1716 WCHAR expect6_3_2_w2k[] = {'2','0','a','b',':',':','2','0','0','1','%','4','6','6','0',0};
1717 WCHAR expect6_3_3[] = {'2','0','a','b',':',':','2','0','0','1','%','6','5','5','3','4',0};
1718 WCHAR expect6_3_3_nt[] = {'6','5','5','3','4','/','2','0','a','b',':',':','2','0','0','1',0};
1720 len = 0;
1722 sockaddr.sin_family = AF_INET;
1723 sockaddr.sin_port = 0;
1724 sockaddr.sin_addr.s_addr = 0;
1726 ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
1727 GLE = WSAGetLastError();
1728 ok( (ret == SOCKET_ERROR && GLE == WSAEFAULT) || (ret == 0),
1729 "WSAAddressToStringW() failed unexpectedly: WSAGetLastError()=%d, ret=%d\n",
1730 GLE, ret );
1732 len = sizeof(address);
1734 sockaddr.sin_family = AF_INET;
1735 sockaddr.sin_port = 0;
1736 sockaddr.sin_addr.s_addr = 0;
1738 ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
1739 ok( !ret, "WSAAddressToStringW() failed unexpectedly: %d\n", WSAGetLastError() );
1741 ok( !lstrcmpW( address, expect1 ), "Expected different address string\n" );
1742 ok( len == sizeof( expect1 )/sizeof( WCHAR ), "Got size %d\n", len);
1744 len = sizeof(address);
1746 sockaddr.sin_family = AF_INET;
1747 sockaddr.sin_port = 0;
1748 sockaddr.sin_addr.s_addr = 0xffffffff;
1750 ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
1751 ok( !ret, "WSAAddressToStringW() failed unexpectedly: %d\n", WSAGetLastError() );
1753 ok( !lstrcmpW( address, expect2 ), "Expected different address string\n" );
1755 len = sizeof(address);
1757 sockaddr.sin_family = AF_INET;
1758 sockaddr.sin_port = 0xffff;
1759 sockaddr.sin_addr.s_addr = 0;
1761 ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
1762 ok( !ret, "WSAAddressToStringW() failed unexpectedly: %d\n", WSAGetLastError() );
1764 ok( !lstrcmpW( address, expect3 ), "Expected different address string\n" );
1766 len = sizeof(address);
1768 sockaddr.sin_family = AF_INET;
1769 sockaddr.sin_port = 0xffff;
1770 sockaddr.sin_addr.s_addr = 0xffffffff;
1772 ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
1773 ok( !ret, "WSAAddressToStringW() failed unexpectedly: %d\n", WSAGetLastError() );
1775 ok( !lstrcmpW( address, expect4 ), "Expected different address string\n" );
1776 ok( len == sizeof( expect4 )/sizeof( WCHAR ), "Got %d\n", len);
1778 /*check to see it IPv6 is available */
1779 v6 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
1780 if (v6 == INVALID_SOCKET) {
1781 skip("Could not create IPv6 socket (LastError: %d; %d expected if IPv6 not available).\n",
1782 WSAGetLastError(), WSAEAFNOSUPPORT);
1783 goto end;
1786 /* Test a short IPv6 address */
1787 len = sizeof(address6)/sizeof(WCHAR);
1789 sockaddr6.sin6_family = AF_INET6;
1790 sockaddr6.sin6_port = 0x0000;
1791 sockaddr6.sin6_scope_id = 0;
1792 memcpy (sockaddr6.sin6_addr.s6_addr, addr6_1, sizeof(addr6_1));
1794 ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len );
1795 ok( !ret, "WSAAddressToStringW() failed unexpectedly: %d\n", WSAGetLastError() );
1796 ok( !lstrcmpW( address6, expect6_1 ), "Wrong string returned\n" );
1797 ok( len == sizeof(expect6_1)/sizeof(WCHAR), "Got %d\n", len);
1799 /* Test a longer IPv6 address */
1800 len = sizeof(address6)/sizeof(WCHAR);
1802 sockaddr6.sin6_family = AF_INET6;
1803 sockaddr6.sin6_port = 0x0000;
1804 sockaddr6.sin6_scope_id = 0;
1805 memcpy (sockaddr6.sin6_addr.s6_addr, addr6_2, sizeof(addr6_2));
1807 ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len );
1808 ok( !ret, "WSAAddressToStringW() failed unexpectedly: %d\n", WSAGetLastError() );
1810 ok( !lstrcmpW( address6, expect6_2 ), "Wrong string returned\n" );
1811 ok( len == sizeof(expect6_2)/sizeof(WCHAR), "Got %d\n", len);
1813 /* Test IPv6 address and port number */
1814 len = sizeof(address6)/sizeof(WCHAR);
1816 sockaddr6.sin6_family = AF_INET6;
1817 sockaddr6.sin6_port = 0xfa81;
1818 sockaddr6.sin6_scope_id = 0;
1819 memcpy (sockaddr6.sin6_addr.s6_addr, addr6_3, sizeof(addr6_3));
1821 ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len );
1822 ok( !ret, "WSAAddressToStringW() failed unexpectedly: %d\n", WSAGetLastError() );
1823 ok( !lstrcmpW( address6, expect6_3 ) ||
1824 broken( !lstrcmpW( address6, expect6_3_nt ) ) || /* NT4 */
1825 broken( !lstrcmpW( address6, expect6_3_w2k ) ), /* Win2000 */
1826 "Expected: %s, got: %s\n", wine_dbgstr_w(expect6_3),
1827 wine_dbgstr_w(address6) );
1828 ok( len == sizeof(expect6_3)/sizeof(WCHAR) ||
1829 broken(len == sizeof(expect6_3_nt)/sizeof(WCHAR) ) || /* NT4 */
1830 broken(len == sizeof(expect6_3_w2k)/sizeof(WCHAR) ), /* Win2000 */
1831 "Got %d\n", len);
1833 /* Test IPv6 address, port number and scope_id */
1834 len = sizeof(address6)/sizeof(WCHAR);
1836 sockaddr6.sin6_family = AF_INET6;
1837 sockaddr6.sin6_port = 0xfa81;
1838 sockaddr6.sin6_scope_id = 0x1234;
1839 memcpy (sockaddr6.sin6_addr.s6_addr, addr6_3, sizeof(addr6_3));
1841 ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len );
1842 ok( !ret, "WSAAddressToStringW() failed unexpectedly: %d\n", WSAGetLastError() );
1843 ok( !lstrcmpW( address6, expect6_3_2 ) ||
1844 broken( !lstrcmpW( address6, expect6_3_2_nt ) ) || /* NT4 */
1845 broken( !lstrcmpW( address6, expect6_3_2_w2k ) ), /* Win2000 */
1846 "Expected: %s, got: %s\n", wine_dbgstr_w(expect6_3_2),
1847 wine_dbgstr_w(address6) );
1848 ok( len == sizeof(expect6_3_2)/sizeof(WCHAR) ||
1849 broken( len == sizeof(expect6_3_2_nt)/sizeof(WCHAR) ) || /* NT4 */
1850 broken( len == sizeof(expect6_3_2_w2k)/sizeof(WCHAR) ), /* Win2000 */
1851 "Got %d\n", len);
1853 /* Test IPv6 address and scope_id */
1854 len = sizeof(address6)/sizeof(WCHAR);
1856 sockaddr6.sin6_family = AF_INET6;
1857 sockaddr6.sin6_port = 0x0000;
1858 sockaddr6.sin6_scope_id = 0xfffe;
1859 memcpy (sockaddr6.sin6_addr.s6_addr, addr6_3, sizeof(addr6_3));
1861 ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len );
1862 ok( !ret, "WSAAddressToStringW() failed unexpectedly: %d\n", WSAGetLastError() );
1863 ok( !lstrcmpW( address6, expect6_3_3 ) ||
1864 broken( !lstrcmpW( address6, expect6_3_3_nt ) ), /* NT4 */
1865 "Expected: %s, got: %s\n", wine_dbgstr_w(expect6_3_3),
1866 wine_dbgstr_w(address6) );
1867 ok( len == sizeof(expect6_3_3)/sizeof(WCHAR) ||
1868 broken( len == sizeof(expect6_3_3_nt)/sizeof(WCHAR) ), /* NT4 */
1869 "Got %d\n", len);
1871 end:
1872 if (v6 != INVALID_SOCKET)
1873 closesocket(v6);
1876 static void test_WSAStringToAddressA(void)
1878 INT ret, len;
1879 SOCKADDR_IN sockaddr;
1880 SOCKADDR_IN6 sockaddr6;
1881 int GLE;
1883 CHAR address1[] = "0.0.0.0";
1884 CHAR address2[] = "127.127.127.127";
1885 CHAR address3[] = "255.255.255.255";
1886 CHAR address4[] = "127.127.127.127:65535";
1887 CHAR address5[] = "255.255.255.255:65535";
1888 CHAR address6[] = "::1";
1889 CHAR address7[] = "[::1]";
1890 CHAR address8[] = "[::1]:65535";
1892 len = 0;
1893 sockaddr.sin_family = AF_INET;
1895 ret = WSAStringToAddressA( address1, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
1896 ok( ret == SOCKET_ERROR, "WSAStringToAddressA() succeeded unexpectedly: %d\n",
1897 WSAGetLastError() );
1899 len = sizeof(sockaddr);
1900 sockaddr.sin_port = 0;
1901 sockaddr.sin_addr.s_addr = 0;
1903 ret = WSAStringToAddressA( address1, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
1904 ok( !ret && sockaddr.sin_addr.s_addr == 0,
1905 "WSAStringToAddressA() failed unexpectedly: %d\n", WSAGetLastError() );
1907 len = sizeof(sockaddr);
1908 sockaddr.sin_port = 0;
1909 sockaddr.sin_addr.s_addr = 0;
1911 ret = WSAStringToAddressA( address2, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
1912 ok( !ret && sockaddr.sin_addr.s_addr == 0x7f7f7f7f,
1913 "WSAStringToAddressA() failed unexpectedly: %d\n", WSAGetLastError() );
1915 len = sizeof(sockaddr);
1916 sockaddr.sin_port = 0;
1917 sockaddr.sin_addr.s_addr = 0;
1919 ret = WSAStringToAddressA( address3, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
1920 GLE = WSAGetLastError();
1921 ok( (ret == 0 && sockaddr.sin_addr.s_addr == 0xffffffff) ||
1922 (ret == SOCKET_ERROR && (GLE == ERROR_INVALID_PARAMETER || GLE == WSAEINVAL)),
1923 "WSAStringToAddressA() failed unexpectedly: %d\n", GLE );
1925 len = sizeof(sockaddr);
1926 sockaddr.sin_port = 0;
1927 sockaddr.sin_addr.s_addr = 0;
1929 ret = WSAStringToAddressA( address4, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
1930 ok( !ret && sockaddr.sin_addr.s_addr == 0x7f7f7f7f && sockaddr.sin_port == 0xffff,
1931 "WSAStringToAddressA() failed unexpectedly: %d\n", WSAGetLastError() );
1933 len = sizeof(sockaddr);
1934 sockaddr.sin_port = 0;
1935 sockaddr.sin_addr.s_addr = 0;
1937 ret = WSAStringToAddressA( address5, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
1938 GLE = WSAGetLastError();
1939 ok( (ret == 0 && sockaddr.sin_addr.s_addr == 0xffffffff && sockaddr.sin_port == 0xffff) ||
1940 (ret == SOCKET_ERROR && (GLE == ERROR_INVALID_PARAMETER || GLE == WSAEINVAL)),
1941 "WSAStringToAddressA() failed unexpectedly: %d\n", GLE );
1943 len = sizeof(sockaddr6);
1944 memset(&sockaddr6, 0, len);
1945 sockaddr6.sin6_family = AF_INET6;
1947 ret = WSAStringToAddressA( address6, AF_INET6, NULL, (SOCKADDR*)&sockaddr6,
1948 &len );
1949 GLE = WSAGetLastError();
1950 ok( ret == 0 || (ret == SOCKET_ERROR && GLE == WSAEINVAL),
1951 "WSAStringToAddressA() failed for IPv6 address: %d\n", GLE);
1953 len = sizeof(sockaddr6);
1954 memset(&sockaddr6, 0, len);
1955 sockaddr6.sin6_family = AF_INET6;
1957 ret = WSAStringToAddressA( address7, AF_INET6, NULL, (SOCKADDR*)&sockaddr6,
1958 &len );
1959 GLE = WSAGetLastError();
1960 ok( ret == 0 || (ret == SOCKET_ERROR && GLE == WSAEINVAL),
1961 "WSAStringToAddressA() failed for IPv6 address: %d\n", GLE);
1963 len = sizeof(sockaddr6);
1964 memset(&sockaddr6, 0, len);
1965 sockaddr6.sin6_family = AF_INET6;
1967 ret = WSAStringToAddressA( address8, AF_INET6, NULL, (SOCKADDR*)&sockaddr6,
1968 &len );
1969 GLE = WSAGetLastError();
1970 ok( (ret == 0 && sockaddr6.sin6_port == 0xffff) ||
1971 (ret == SOCKET_ERROR && GLE == WSAEINVAL),
1972 "WSAStringToAddressA() failed for IPv6 address: %d\n", GLE);
1976 static void test_WSAStringToAddressW(void)
1978 INT ret, len;
1979 SOCKADDR_IN sockaddr, *sin;
1980 SOCKADDR_IN6 sockaddr6;
1981 SOCKADDR_STORAGE sockaddr_storage;
1982 int GLE;
1984 WCHAR address1[] = { '0','.','0','.','0','.','0', 0 };
1985 WCHAR address2[] = { '1','2','7','.','1','2','7','.','1','2','7','.','1','2','7', 0 };
1986 WCHAR address3[] = { '2','5','5','.','2','5','5','.','2','5','5','.','2','5','5', 0 };
1987 WCHAR address4[] = { '1','2','7','.','1','2','7','.','1','2','7','.','1','2','7',
1988 ':', '6', '5', '5', '3', '5', 0 };
1989 WCHAR address5[] = { '2','5','5','.','2','5','5','.','2','5','5','.','2','5','5', ':',
1990 '6', '5', '5', '3', '5', 0 };
1991 WCHAR address6[] = {':',':','1','\0'};
1992 WCHAR address7[] = {'[',':',':','1',']','\0'};
1993 WCHAR address8[] = {'[',':',':','1',']',':','6','5','5','3','5','\0'};
1995 len = 0;
1996 sockaddr.sin_family = AF_INET;
1998 ret = WSAStringToAddressW( address1, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
1999 ok( ret == SOCKET_ERROR, "WSAStringToAddressW() failed unexpectedly: %d\n",
2000 WSAGetLastError() );
2002 len = sizeof(sockaddr);
2003 sockaddr.sin_port = 0;
2004 sockaddr.sin_addr.s_addr = 0;
2006 ret = WSAStringToAddressW( address1, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
2007 ok( !ret && sockaddr.sin_addr.s_addr == 0,
2008 "WSAStringToAddressW() failed unexpectedly: %d\n", WSAGetLastError() );
2010 len = sizeof(sockaddr);
2011 sockaddr.sin_port = 0;
2012 sockaddr.sin_addr.s_addr = 0;
2014 ret = WSAStringToAddressW( address2, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
2015 ok( !ret && sockaddr.sin_addr.s_addr == 0x7f7f7f7f,
2016 "WSAStringToAddressW() failed unexpectedly: %d\n", WSAGetLastError() );
2018 len = sizeof(sockaddr);
2019 sockaddr.sin_port = 0;
2020 sockaddr.sin_addr.s_addr = 0;
2022 ret = WSAStringToAddressW( address3, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
2023 GLE = WSAGetLastError();
2024 ok( (ret == 0 && sockaddr.sin_addr.s_addr == 0xffffffff) ||
2025 (ret == SOCKET_ERROR && (GLE == ERROR_INVALID_PARAMETER || GLE == WSAEINVAL)),
2026 "WSAStringToAddressW() failed unexpectedly: %d\n", GLE );
2028 len = sizeof(sockaddr);
2029 sockaddr.sin_port = 0;
2030 sockaddr.sin_addr.s_addr = 0;
2032 ret = WSAStringToAddressW( address4, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
2033 ok( !ret && sockaddr.sin_addr.s_addr == 0x7f7f7f7f && sockaddr.sin_port == 0xffff,
2034 "WSAStringToAddressW() failed unexpectedly: %d\n", WSAGetLastError() );
2036 len = sizeof(sockaddr);
2037 sockaddr.sin_port = 0;
2038 sockaddr.sin_addr.s_addr = 0;
2040 ret = WSAStringToAddressW( address5, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
2041 ok( (ret == 0 && sockaddr.sin_addr.s_addr == 0xffffffff && sockaddr.sin_port == 0xffff) ||
2042 (ret == SOCKET_ERROR && (GLE == ERROR_INVALID_PARAMETER || GLE == WSAEINVAL)),
2043 "WSAStringToAddressW() failed unexpectedly: %d\n", GLE );
2045 /* Test with a larger buffer than necessary */
2046 len = sizeof(sockaddr_storage);
2047 sin = (SOCKADDR_IN *)&sockaddr_storage;
2048 sin->sin_port = 0;
2049 sin->sin_addr.s_addr = 0;
2051 ret = WSAStringToAddressW( address5, AF_INET, NULL, (SOCKADDR*)sin, &len );
2052 ok( (ret == 0 && sin->sin_addr.s_addr == 0xffffffff && sin->sin_port == 0xffff) ||
2053 (ret == SOCKET_ERROR && (GLE == ERROR_INVALID_PARAMETER || GLE == WSAEINVAL)),
2054 "WSAStringToAddressW() failed unexpectedly: %d\n", GLE );
2055 ok( len == sizeof(SOCKADDR_IN) ||
2056 broken(len == sizeof(SOCKADDR_STORAGE)) /* NT4/2k */,
2057 "unexpected length %d\n", len );
2059 len = sizeof(sockaddr6);
2060 memset(&sockaddr6, 0, len);
2061 sockaddr6.sin6_family = AF_INET6;
2063 ret = WSAStringToAddressW( address6, AF_INET6, NULL, (SOCKADDR*)&sockaddr6,
2064 &len );
2065 GLE = WSAGetLastError();
2066 ok( ret == 0 || (ret == SOCKET_ERROR && GLE == WSAEINVAL),
2067 "WSAStringToAddressW() failed for IPv6 address: %d\n", GLE);
2069 len = sizeof(sockaddr6);
2070 memset(&sockaddr6, 0, len);
2071 sockaddr6.sin6_family = AF_INET6;
2073 ret = WSAStringToAddressW( address7, AF_INET6, NULL, (SOCKADDR*)&sockaddr6,
2074 &len );
2075 GLE = WSAGetLastError();
2076 ok( ret == 0 || (ret == SOCKET_ERROR && GLE == WSAEINVAL),
2077 "WSAStringToAddressW() failed for IPv6 address: %d\n", GLE);
2079 len = sizeof(sockaddr6);
2080 memset(&sockaddr6, 0, len);
2081 sockaddr6.sin6_family = AF_INET6;
2083 ret = WSAStringToAddressW( address8, AF_INET6, NULL, (SOCKADDR*)&sockaddr6,
2084 &len );
2085 GLE = WSAGetLastError();
2086 ok( (ret == 0 && sockaddr6.sin6_port == 0xffff) ||
2087 (ret == SOCKET_ERROR && GLE == WSAEINVAL),
2088 "WSAStringToAddressW() failed for IPv6 address: %d\n", GLE);
2092 static VOID WINAPI SelectReadThread(select_thread_params *par)
2094 fd_set readfds;
2095 int ret;
2096 struct sockaddr_in addr;
2097 struct timeval select_timeout;
2099 FD_ZERO(&readfds);
2100 FD_SET(par->s, &readfds);
2101 select_timeout.tv_sec=5;
2102 select_timeout.tv_usec=0;
2103 addr.sin_family = AF_INET;
2104 addr.sin_addr.s_addr = inet_addr(SERVERIP);
2105 addr.sin_port = htons(SERVERPORT);
2107 do_bind(par->s, (struct sockaddr *)&addr, sizeof(addr));
2108 wsa_ok(listen(par->s, SOMAXCONN ), 0 ==, "SelectReadThread (%x): listen failed: %d\n");
2110 SetEvent(server_ready);
2111 ret = select(par->s+1, &readfds, NULL, NULL, &select_timeout);
2112 par->ReadKilled = (ret == 1);
2115 static void test_select(void)
2117 SOCKET fdRead, fdWrite;
2118 fd_set readfds, writefds, exceptfds;
2119 unsigned int maxfd;
2120 int ret;
2121 struct timeval select_timeout;
2122 select_thread_params thread_params;
2123 HANDLE thread_handle;
2124 DWORD id;
2126 fdRead = socket(AF_INET, SOCK_STREAM, 0);
2127 ok( (fdRead != INVALID_SOCKET), "socket failed unexpectedly: %d\n", WSAGetLastError() );
2128 fdWrite = socket(AF_INET, SOCK_STREAM, 0);
2129 ok( (fdWrite != INVALID_SOCKET), "socket failed unexpectedly: %d\n", WSAGetLastError() );
2131 FD_ZERO(&readfds);
2132 FD_ZERO(&writefds);
2133 FD_ZERO(&exceptfds);
2134 FD_SET(fdRead, &readfds);
2135 FD_SET(fdWrite, &writefds);
2136 FD_SET(fdRead, &exceptfds);
2137 FD_SET(fdWrite, &exceptfds);
2138 select_timeout.tv_sec=0;
2139 select_timeout.tv_usec=500;
2141 maxfd = fdRead;
2142 if (fdWrite > maxfd)
2143 maxfd = fdWrite;
2145 todo_wine {
2146 ret = select(maxfd+1, &readfds, &writefds, &exceptfds, &select_timeout);
2147 ok ( (ret == 0), "select should not return any socket handles\n");
2148 ok ( !FD_ISSET(fdRead, &readfds), "FD should not be set\n");
2149 ok ( !FD_ISSET(fdWrite, &writefds), "FD should not be set\n");
2152 ok ( !FD_ISSET(fdRead, &exceptfds), "FD should not be set\n");
2153 ok ( !FD_ISSET(fdWrite, &exceptfds), "FD should not be set\n");
2155 todo_wine {
2156 ok ((listen(fdWrite, SOMAXCONN) == SOCKET_ERROR), "listen did not fail\n");
2158 ret = closesocket(fdWrite);
2159 ok ( (ret == 0), "closesocket failed unexpectedly: %d\n", ret);
2161 thread_params.s = fdRead;
2162 thread_params.ReadKilled = FALSE;
2163 server_ready = CreateEventA(NULL, TRUE, FALSE, NULL);
2164 thread_handle = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) &SelectReadThread, &thread_params, 0, &id );
2165 ok ( (thread_handle != NULL), "CreateThread failed unexpectedly: %d\n", GetLastError());
2167 WaitForSingleObject (server_ready, INFINITE);
2168 Sleep(200);
2169 ret = closesocket(fdRead);
2170 ok ( (ret == 0), "closesocket failed unexpectedly: %d\n", ret);
2172 WaitForSingleObject (thread_handle, 1000);
2173 ok ( (thread_params.ReadKilled) ||
2174 broken(thread_params.ReadKilled == 0), /*Win98*/
2175 "closesocket did not wakeup select\n");
2177 /* Test selecting invalid handles */
2178 FD_ZERO(&readfds);
2179 FD_ZERO(&writefds);
2180 FD_ZERO(&exceptfds);
2182 SetLastError(0);
2183 ret = select(maxfd+1, 0, 0, 0, &select_timeout);
2184 ok ( (ret == SOCKET_ERROR), "expected SOCKET_ERROR, got %i\n", ret);
2185 ok ( GetLastError() == WSAEINVAL, "expected WSAEINVAL, got %i\n", ret);
2187 SetLastError(0);
2188 ret = select(maxfd+1, &readfds, &writefds, &exceptfds, &select_timeout);
2189 ok ( (ret == SOCKET_ERROR), "expected SOCKET_ERROR, got %i\n", ret);
2190 ok ( GetLastError() == WSAEINVAL, "expected WSAEINVAL, got %i\n", ret);
2192 FD_SET(INVALID_SOCKET, &readfds);
2193 SetLastError(0);
2194 ret = select(maxfd+1, &readfds, &writefds, &exceptfds, &select_timeout);
2195 ok ( (ret == SOCKET_ERROR), "expected SOCKET_ERROR, got %i\n", ret);
2196 ok ( GetLastError() == WSAENOTSOCK, "expected WSAENOTSOCK, got %i\n", ret);
2197 ok ( !FD_ISSET(fdRead, &readfds), "FD should not be set\n");
2199 FD_ZERO(&readfds);
2200 FD_SET(INVALID_SOCKET, &writefds);
2201 SetLastError(0);
2202 ret = select(maxfd+1, &readfds, &writefds, &exceptfds, &select_timeout);
2203 ok ( (ret == SOCKET_ERROR), "expected SOCKET_ERROR, got %i\n", ret);
2204 ok ( GetLastError() == WSAENOTSOCK, "expected WSAENOTSOCK, got %i\n", ret);
2205 ok ( !FD_ISSET(fdRead, &writefds), "FD should not be set\n");
2207 FD_ZERO(&writefds);
2208 FD_SET(INVALID_SOCKET, &exceptfds);
2209 SetLastError(0);
2210 ret = select(maxfd+1, &readfds, &writefds, &exceptfds, &select_timeout);
2211 ok ( (ret == SOCKET_ERROR), "expected SOCKET_ERROR, got %i\n", ret);
2212 ok ( GetLastError() == WSAENOTSOCK, "expected WSAENOTSOCK, got %i\n", ret);
2213 ok ( !FD_ISSET(fdRead, &exceptfds), "FD should not be set\n");
2216 static DWORD WINAPI AcceptKillThread(select_thread_params *par)
2218 struct sockaddr_in address;
2219 int len = sizeof(address);
2220 SOCKET client_socket;
2222 SetEvent(server_ready);
2223 client_socket = accept(par->s, (struct sockaddr*) &address, &len);
2224 if (client_socket != INVALID_SOCKET)
2225 closesocket(client_socket);
2226 par->ReadKilled = (client_socket == INVALID_SOCKET);
2227 return 0;
2231 static int CALLBACK AlwaysDeferConditionFunc(LPWSABUF lpCallerId, LPWSABUF lpCallerData, LPQOS pQos,
2232 LPQOS lpGQOS, LPWSABUF lpCalleeId, LPWSABUF lpCalleeData,
2233 GROUP FAR * g, DWORD_PTR dwCallbackData)
2235 return CF_DEFER;
2238 static void test_accept(void)
2240 int ret;
2241 SOCKET server_socket = INVALID_SOCKET, accepted = INVALID_SOCKET, connector = INVALID_SOCKET;
2242 struct sockaddr_in address;
2243 int socklen;
2244 select_thread_params thread_params;
2245 HANDLE thread_handle = NULL;
2246 DWORD id;
2248 server_socket = socket(AF_INET, SOCK_STREAM, 0);
2249 if (server_socket == INVALID_SOCKET)
2251 trace("error creating server socket: %d\n", WSAGetLastError());
2252 goto done;
2255 memset(&address, 0, sizeof(address));
2256 address.sin_addr.s_addr = inet_addr("127.0.0.1");
2257 address.sin_family = AF_INET;
2258 ret = bind(server_socket, (struct sockaddr*) &address, sizeof(address));
2259 if (ret != 0)
2261 trace("error binding server socket: %d\n", WSAGetLastError());
2262 goto done;
2265 socklen = sizeof(address);
2266 ret = getsockname(server_socket, (struct sockaddr*)&address, &socklen);
2267 if (ret != 0) {
2268 skip("failed to lookup bind address, error %d\n", WSAGetLastError());
2269 goto done;
2272 ret = listen(server_socket, 5);
2273 if (ret != 0)
2275 trace("error making server socket listen: %d\n", WSAGetLastError());
2276 goto done;
2279 trace("Blocking accept next\n");
2281 connector = socket(AF_INET, SOCK_STREAM, 0);
2282 ok(connector != INVALID_SOCKET, "Failed to create connector socket, error %d\n", WSAGetLastError());
2284 ret = connect(connector, (struct sockaddr*)&address, sizeof(address));
2285 ok(ret == 0, "connecting to accepting socket failed, error %d\n", WSAGetLastError());
2287 accepted = WSAAccept(server_socket, NULL, NULL, (LPCONDITIONPROC) AlwaysDeferConditionFunc, 0);
2288 ok(accepted == INVALID_SOCKET && WSAGetLastError() == WSATRY_AGAIN, "Failed to defer connection, %d\n", WSAGetLastError());
2290 accepted = accept(server_socket, NULL, 0);
2291 ok(accepted != INVALID_SOCKET, "Failed to accept deferred connection, error %d\n", WSAGetLastError());
2293 server_ready = CreateEventA(NULL, TRUE, FALSE, NULL);
2294 if (server_ready == INVALID_HANDLE_VALUE)
2296 trace("error creating event: %d\n", GetLastError());
2297 goto done;
2300 thread_params.s = server_socket;
2301 thread_params.ReadKilled = FALSE;
2302 thread_handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) AcceptKillThread,
2303 &thread_params, 0, &id);
2304 if (thread_handle == NULL)
2306 trace("error creating thread: %d\n", GetLastError());
2307 goto done;
2310 WaitForSingleObject(server_ready, INFINITE);
2311 Sleep(200);
2312 ret = closesocket(server_socket);
2313 if (ret != 0)
2315 trace("closesocket failed: %d\n", WSAGetLastError());
2316 goto done;
2319 WaitForSingleObject(thread_handle, 1000);
2320 ok(thread_params.ReadKilled || broken(!thread_params.ReadKilled) /* Win98/ME, after accept */,
2321 "closesocket did not wakeup accept\n");
2323 done:
2324 if (accepted != INVALID_SOCKET)
2325 closesocket(accepted);
2326 if (connector != INVALID_SOCKET)
2327 closesocket(connector);
2328 if (thread_handle != NULL)
2329 CloseHandle(thread_handle);
2330 if (server_ready != INVALID_HANDLE_VALUE)
2331 CloseHandle(server_ready);
2332 if (server_socket != INVALID_SOCKET)
2333 closesocket(server_socket);
2336 static void test_extendedSocketOptions(void)
2338 WSADATA wsa;
2339 SOCKET sock;
2340 struct sockaddr_in sa;
2341 int sa_len = sizeof(struct sockaddr_in);
2342 int optval, optlen = sizeof(int), ret;
2343 BOOL bool_opt_val;
2344 LINGER linger_val;
2346 if(WSAStartup(MAKEWORD(2,0), &wsa)){
2347 trace("Winsock failed: %d. Aborting test\n", WSAGetLastError());
2348 return;
2351 memset(&sa, 0, sa_len);
2353 sa.sin_family = AF_INET;
2354 sa.sin_port = htons(0);
2355 sa.sin_addr.s_addr = htonl(INADDR_ANY);
2357 if((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) == INVALID_SOCKET) {
2358 trace("Creating the socket failed: %d\n", WSAGetLastError());
2359 WSACleanup();
2360 return;
2363 if(bind(sock, (struct sockaddr *) &sa, sa_len) < 0){
2364 trace("Failed to bind socket: %d\n", WSAGetLastError());
2365 closesocket(sock);
2366 WSACleanup();
2367 return;
2370 ret = getsockopt(sock, SOL_SOCKET, SO_MAX_MSG_SIZE, (char *)&optval, &optlen);
2372 ok(ret == 0, "getsockopt failed to query SO_MAX_MSG_SIZE, return value is 0x%08x\n", ret);
2373 ok((optval == 65507) || (optval == 65527),
2374 "SO_MAX_MSG_SIZE reported %d, expected 65507 or 65527\n", optval);
2376 /* IE 3 use 0xffffffff instead of SOL_SOCKET (0xffff) */
2377 SetLastError(0xdeadbeef);
2378 optval = 0xdeadbeef;
2379 optlen = sizeof(int);
2380 ret = getsockopt(sock, 0xffffffff, SO_MAX_MSG_SIZE, (char *)&optval, &optlen);
2381 ok( (ret == SOCKET_ERROR) && (WSAGetLastError() == WSAEINVAL),
2382 "got %d with %d and optval: 0x%x/%d (expected SOCKET_ERROR with WSAEINVAL)\n",
2383 ret, WSAGetLastError(), optval, optval);
2385 /* more invalid values for level */
2386 SetLastError(0xdeadbeef);
2387 optval = 0xdeadbeef;
2388 optlen = sizeof(int);
2389 ret = getsockopt(sock, 0x1234ffff, SO_MAX_MSG_SIZE, (char *)&optval, &optlen);
2390 ok( (ret == SOCKET_ERROR) && (WSAGetLastError() == WSAEINVAL),
2391 "got %d with %d and optval: 0x%x/%d (expected SOCKET_ERROR with WSAEINVAL)\n",
2392 ret, WSAGetLastError(), optval, optval);
2394 SetLastError(0xdeadbeef);
2395 optval = 0xdeadbeef;
2396 optlen = sizeof(int);
2397 ret = getsockopt(sock, 0x8000ffff, SO_MAX_MSG_SIZE, (char *)&optval, &optlen);
2398 ok( (ret == SOCKET_ERROR) && (WSAGetLastError() == WSAEINVAL),
2399 "got %d with %d and optval: 0x%x/%d (expected SOCKET_ERROR with WSAEINVAL)\n",
2400 ret, WSAGetLastError(), optval, optval);
2402 SetLastError(0xdeadbeef);
2403 optval = 0xdeadbeef;
2404 optlen = sizeof(int);
2405 ret = getsockopt(sock, 0x00008000, SO_MAX_MSG_SIZE, (char *)&optval, &optlen);
2406 ok( (ret == SOCKET_ERROR) && (WSAGetLastError() == WSAEINVAL),
2407 "got %d with %d and optval: 0x%x/%d (expected SOCKET_ERROR with WSAEINVAL)\n",
2408 ret, WSAGetLastError(), optval, optval);
2410 SetLastError(0xdeadbeef);
2411 optval = 0xdeadbeef;
2412 optlen = sizeof(int);
2413 ret = getsockopt(sock, 0x00000800, SO_MAX_MSG_SIZE, (char *)&optval, &optlen);
2414 ok( (ret == SOCKET_ERROR) && (WSAGetLastError() == WSAEINVAL),
2415 "got %d with %d and optval: 0x%x/%d (expected SOCKET_ERROR with WSAEINVAL)\n",
2416 ret, WSAGetLastError(), optval, optval);
2418 optlen = sizeof(LINGER);
2419 ret = getsockopt(sock, SOL_SOCKET, SO_LINGER, (char *)&linger_val, &optlen);
2420 todo_wine{
2421 ok(ret == SOCKET_ERROR, "getsockopt should fail for UDP sockets but return value is 0x%08x\n", ret);
2424 closesocket(sock);
2426 if((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_IP)) == INVALID_SOCKET) {
2427 trace("Creating the socket failed: %d\n", WSAGetLastError());
2428 WSACleanup();
2429 return;
2432 if(bind(sock, (struct sockaddr *) &sa, sa_len) < 0){
2433 trace("Failed to bind socket: %d\n", WSAGetLastError());
2434 closesocket(sock);
2435 WSACleanup();
2436 return;
2439 ret = getsockopt(sock, SOL_SOCKET, SO_LINGER, (char *)&linger_val, &optlen);
2440 ok(ret == 0, "getsockopt failed to query SO_LINGER, return value is 0x%08x\n", ret);
2442 optlen = sizeof(BOOL);
2443 ret = getsockopt(sock, SOL_SOCKET, SO_DONTLINGER, (char *)&bool_opt_val, &optlen);
2444 ok(ret == 0, "getsockopt failed to query SO_DONTLINGER, return value is 0x%08x\n", ret);
2445 ok((linger_val.l_onoff && !bool_opt_val) || (!linger_val.l_onoff && bool_opt_val),
2446 "Return value of SO_DONTLINGER is %d, but SO_LINGER returned l_onoff == %d.\n",
2447 bool_opt_val, linger_val.l_onoff);
2449 closesocket(sock);
2450 WSACleanup();
2453 static void test_getsockname(void)
2455 WSADATA wsa;
2456 SOCKET sock;
2457 struct sockaddr_in sa_set, sa_get;
2458 int sa_set_len = sizeof(struct sockaddr_in);
2459 int sa_get_len = sa_set_len;
2460 static const unsigned char null_padding[] = {0,0,0,0,0,0,0,0};
2461 int ret;
2463 if(WSAStartup(MAKEWORD(2,0), &wsa)){
2464 trace("Winsock failed: %d. Aborting test\n", WSAGetLastError());
2465 return;
2468 memset(&sa_set, 0, sa_set_len);
2470 sa_set.sin_family = AF_INET;
2471 sa_set.sin_port = htons(0);
2472 sa_set.sin_addr.s_addr = htonl(INADDR_ANY);
2474 if((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_IP)) == INVALID_SOCKET) {
2475 trace("Creating the socket failed: %d\n", WSAGetLastError());
2476 WSACleanup();
2477 return;
2480 memcpy(&sa_get, &sa_set, sizeof(sa_set));
2481 if (getsockname(sock, (struct sockaddr*) &sa_get, &sa_get_len) == 0)
2482 ok(0, "getsockname on unbound socket should fail\n");
2483 else {
2484 ok(WSAGetLastError() == WSAEINVAL, "getsockname on unbound socket "
2485 "failed with %d, expected %d\n", WSAGetLastError(), WSAEINVAL);
2486 ok(memcmp(&sa_get, &sa_set, sizeof(sa_get)) == 0,
2487 "failed getsockname modified sockaddr when it shouldn't\n");
2490 if(bind(sock, (struct sockaddr *) &sa_set, sa_set_len) < 0){
2491 trace("Failed to bind socket: %d\n", WSAGetLastError());
2492 closesocket(sock);
2493 WSACleanup();
2494 return;
2497 if(getsockname(sock, (struct sockaddr *) &sa_get, &sa_get_len) != 0){
2498 trace("Failed to call getsockname: %d\n", WSAGetLastError());
2499 closesocket(sock);
2500 WSACleanup();
2501 return;
2504 ret = memcmp(sa_get.sin_zero, null_padding, 8);
2505 ok(ret == 0 || broken(ret != 0), /* NT4 */
2506 "getsockname did not zero the sockaddr_in structure\n");
2508 closesocket(sock);
2509 WSACleanup();
2512 static void test_dns(void)
2514 struct hostent *h;
2516 h = gethostbyname("");
2517 ok(h != NULL, "gethostbyname(\"\") failed with %d\n", h_errno);
2520 /* Our winsock headers don't define gethostname because it conflicts with the
2521 * definition in unistd.h. Define it here to get rid of the warning. */
2523 int WINAPI gethostname(char *name, int namelen);
2525 static void test_gethostbyname_hack(void)
2527 struct hostent *he;
2528 char name[256];
2529 static BYTE loopback[] = {127, 0, 0, 1};
2530 static BYTE magic_loopback[] = {127, 12, 34, 56};
2531 int ret;
2533 ret = gethostname(name, 256);
2534 ok(ret == 0, "gethostname() call failed: %d\n", WSAGetLastError());
2536 he = gethostbyname("localhost");
2537 ok(he != NULL, "gethostbyname(\"localhost\") failed: %d\n", h_errno);
2538 if(he)
2540 if(he->h_length != 4)
2542 skip("h_length is %d, not IPv4, skipping test.\n", he->h_length);
2543 return;
2546 ok(memcmp(he->h_addr_list[0], loopback, he->h_length) == 0,
2547 "gethostbyname(\"localhost\") returned %d.%d.%d.%d\n",
2548 he->h_addr_list[0][0], he->h_addr_list[0][1], he->h_addr_list[0][2],
2549 he->h_addr_list[0][3]);
2552 if(strcmp(name, "localhost") == 0)
2554 skip("hostname seems to be \"localhost\", skipping test.\n");
2555 return;
2558 he = NULL;
2559 he = gethostbyname(name);
2560 ok(he != NULL, "gethostbyname(\"%s\") failed: %d\n", name, h_errno);
2561 if(he)
2563 if(he->h_length != 4)
2565 skip("h_length is %d, not IPv4, skipping test.\n", he->h_length);
2566 return;
2569 if (he->h_addr_list[0][0] == 127)
2571 ok(memcmp(he->h_addr_list[0], magic_loopback, he->h_length) == 0,
2572 "gethostbyname(\"%s\") returned %d.%d.%d.%d not 127.12.34.56\n",
2573 name, he->h_addr_list[0][0], he->h_addr_list[0][1],
2574 he->h_addr_list[0][2], he->h_addr_list[0][3]);
2578 gethostbyname("nonexistent.winehq.org");
2579 /* Don't check for the return value, as some braindead ISPs will kindly
2580 * resolve nonexistent host names to addresses of the ISP's spam pages. */
2583 static void test_inet_addr(void)
2585 u_long addr;
2587 addr = inet_addr(NULL);
2588 ok(addr == INADDR_NONE, "inet_addr succeeded unexpectedly\n");
2591 static void test_addr_to_print(void)
2593 char dst[16];
2594 char dst6[64];
2595 const char * pdst;
2596 struct in_addr in;
2597 struct in6_addr in6;
2599 u_long addr0_Num = 0x00000000;
2600 PCSTR addr0_Str = "0.0.0.0";
2601 u_long addr1_Num = 0x20201015;
2602 PCSTR addr1_Str = "21.16.32.32";
2603 u_char addr2_Num[16] = {0,0,0,0,0,0,0,0,0,0,0xff,0xfe,0xcC,0x98,0xbd,0x74};
2604 PCSTR addr2_Str = "::fffe:cc98:bd74";
2605 u_char addr3_Num[16] = {0x20,0x30,0xa4,0xb1};
2606 PCSTR addr3_Str = "2030:a4b1::";
2607 u_char addr4_Num[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0xcC,0x98,0xbd,0x74};
2608 PCSTR addr4_Str = "::204.152.189.116";
2610 /* Test IPv4 addresses */
2611 in.s_addr = addr0_Num;
2613 pdst = inet_ntoa(*((struct in_addr*)&in.s_addr));
2614 ok(pdst != NULL, "inet_ntoa failed %s\n", dst);
2615 ok(!strcmp(pdst, addr0_Str),"Address %s != %s\n", pdst, addr0_Str);
2617 /* Test that inet_ntoa and inet_ntop return the same value */
2618 in.S_un.S_addr = addr1_Num;
2619 pdst = inet_ntoa(*((struct in_addr*)&in.s_addr));
2620 ok(pdst != NULL, "inet_ntoa failed %s\n", dst);
2621 ok(!strcmp(pdst, addr1_Str),"Address %s != %s\n", pdst, addr1_Str);
2623 /* InetNtop became available in Vista and Win2008 */
2624 if (!pInetNtop)
2626 win_skip("InetNtop not present, not executing tests\n");
2627 return;
2630 /* Second part of test */
2631 pdst = pInetNtop(AF_INET,(void*)&in.s_addr, dst, sizeof(dst));
2632 ok(pdst != NULL, "InetNtop failed %s\n", dst);
2633 ok(!strcmp(pdst, addr1_Str),"Address %s != %s\n", pdst, addr1_Str);
2635 /* Test invalid parm conditions */
2636 pdst = pInetNtop(1, (void*)&in.s_addr, dst, sizeof(dst));
2637 ok(pdst == NULL, "The pointer should not be returned (%p)\n", pdst);
2638 ok(WSAGetLastError() == WSAEAFNOSUPPORT, "Should be WSAEAFNOSUPPORT\n");
2640 /* Test Null destination */
2641 pdst = NULL;
2642 pdst = pInetNtop(AF_INET, (void*)&in.s_addr, NULL, sizeof(dst));
2643 ok(pdst == NULL, "The pointer should not be returned (%p)\n", pdst);
2644 ok(WSAGetLastError() == STATUS_INVALID_PARAMETER || WSAGetLastError() == WSAEINVAL /* Win7 */,
2645 "Should be STATUS_INVALID_PARAMETER or WSAEINVAL not 0x%x\n", WSAGetLastError());
2647 /* Test zero length passed */
2648 WSASetLastError(0);
2649 pdst = NULL;
2650 pdst = pInetNtop(AF_INET, (void*)&in.s_addr, dst, 0);
2651 ok(pdst == NULL, "The pointer should not be returned (%p)\n", pdst);
2652 ok(WSAGetLastError() == STATUS_INVALID_PARAMETER || WSAGetLastError() == WSAEINVAL /* Win7 */,
2653 "Should be STATUS_INVALID_PARAMETER or WSAEINVAL not 0x%x\n", WSAGetLastError());
2655 /* Test length one shorter than the address length */
2656 WSASetLastError(0);
2657 pdst = NULL;
2658 pdst = pInetNtop(AF_INET, (void*)&in.s_addr, dst, 6);
2659 ok(pdst == NULL, "The pointer should not be returned (%p)\n", pdst);
2660 ok(WSAGetLastError() == STATUS_INVALID_PARAMETER || WSAGetLastError() == WSAEINVAL /* Win7 */,
2661 "Should be STATUS_INVALID_PARAMETER or WSAEINVAL not 0x%x\n", WSAGetLastError());
2663 /* Test longer length is ok */
2664 WSASetLastError(0);
2665 pdst = NULL;
2666 pdst = pInetNtop(AF_INET, (void*)&in.s_addr, dst, sizeof(dst)+1);
2667 ok(pdst != NULL, "The pointer should be returned (%p)\n", pdst);
2668 ok(!strcmp(pdst, addr1_Str),"Address %s != %s\n", pdst, addr1_Str);
2670 /* Test the IPv6 addresses */
2672 /* Test an zero prefixed IPV6 address */
2673 memcpy(in6.u.Byte, addr2_Num, sizeof(addr2_Num));
2674 pdst = pInetNtop(AF_INET6,(void*)&in6.s6_addr, dst6, sizeof(dst6));
2675 ok(pdst != NULL, "InetNtop failed %s\n", dst6);
2676 ok(!strcmp(pdst, addr2_Str),"Address %s != %s\n", pdst, addr2_Str);
2678 /* Test an zero suffixed IPV6 address */
2679 memcpy(in6.s6_addr, addr3_Num, sizeof(addr3_Num));
2680 pdst = pInetNtop(AF_INET6,(void*)&in6.s6_addr, dst6, sizeof(dst6));
2681 ok(pdst != NULL, "InetNtop failed %s\n", dst6);
2682 ok(!strcmp(pdst, addr3_Str),"Address %s != %s\n", pdst, addr3_Str);
2684 /* Test the IPv6 address contains the IPv4 address in IPv4 notation */
2685 memcpy(in6.s6_addr, addr4_Num, sizeof(addr4_Num));
2686 pdst = pInetNtop(AF_INET6, (void*)&in6.s6_addr, dst6, sizeof(dst6));
2687 ok(pdst != NULL, "InetNtop failed %s\n", dst6);
2688 ok(!strcmp(pdst, addr4_Str),"Address %s != %s\n", pdst, addr4_Str);
2690 /* Test invalid parm conditions */
2691 memcpy(in6.u.Byte, addr2_Num, sizeof(addr2_Num));
2693 /* Test Null destination */
2694 pdst = NULL;
2695 pdst = pInetNtop(AF_INET6, (void*)&in6.s6_addr, NULL, sizeof(dst6));
2696 ok(pdst == NULL, "The pointer should not be returned (%p)\n", pdst);
2697 ok(WSAGetLastError() == STATUS_INVALID_PARAMETER || WSAGetLastError() == WSAEINVAL /* Win7 */,
2698 "Should be STATUS_INVALID_PARAMETER or WSAEINVAL not 0x%x\n", WSAGetLastError());
2700 /* Test zero length passed */
2701 WSASetLastError(0);
2702 pdst = NULL;
2703 pdst = pInetNtop(AF_INET6, (void*)&in6.s6_addr, dst6, 0);
2704 ok(pdst == NULL, "The pointer should not be returned (%p)\n", pdst);
2705 ok(WSAGetLastError() == STATUS_INVALID_PARAMETER || WSAGetLastError() == WSAEINVAL /* Win7 */,
2706 "Should be STATUS_INVALID_PARAMETER or WSAEINVAL not 0x%x\n", WSAGetLastError());
2708 /* Test length one shorter than the address length */
2709 WSASetLastError(0);
2710 pdst = NULL;
2711 pdst = pInetNtop(AF_INET6, (void*)&in6.s6_addr, dst6, 16);
2712 ok(pdst == NULL, "The pointer should not be returned (%p)\n", pdst);
2713 ok(WSAGetLastError() == STATUS_INVALID_PARAMETER || WSAGetLastError() == WSAEINVAL /* Win7 */,
2714 "Should be STATUS_INVALID_PARAMETER or WSAEINVAL not 0x%x\n", WSAGetLastError());
2716 /* Test longer length is ok */
2717 WSASetLastError(0);
2718 pdst = NULL;
2719 pdst = pInetNtop(AF_INET6, (void*)&in6.s6_addr, dst6, 18);
2720 ok(pdst != NULL, "The pointer should be returned (%p)\n", pdst);
2723 static void test_ioctlsocket(void)
2725 SOCKET sock;
2726 int ret;
2727 static const LONG cmds[] = {FIONBIO, FIONREAD, SIOCATMARK};
2728 UINT i;
2729 u_long arg = 0;
2731 sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
2732 ok(sock != INVALID_SOCKET, "Creating the socket failed: %d\n", WSAGetLastError());
2733 if(sock == INVALID_SOCKET)
2735 skip("Can't continue without a socket.\n");
2736 return;
2739 for(i = 0; i < sizeof(cmds)/sizeof(cmds[0]); i++)
2741 /* broken apps like defcon pass the argp value directly instead of a pointer to it */
2742 ret = ioctlsocket(sock, cmds[i], (u_long *)1);
2743 ok(ret == SOCKET_ERROR, "ioctlsocket succeeded unexpectedly\n");
2744 ret = WSAGetLastError();
2745 ok(ret == WSAEFAULT, "expected WSAEFAULT, got %d instead\n", ret);
2748 /* A fresh and not connected socket has no urgent data, this test shows
2749 * that normal(not urgent) data returns a non-zero value for SIOCATMARK. */
2751 ret = ioctlsocket(sock, SIOCATMARK, &arg);
2752 if(ret != SOCKET_ERROR)
2753 todo_wine ok(arg, "expected a non-zero value\n");
2756 static int drain_pause=0;
2757 static DWORD WINAPI drain_socket_thread(LPVOID arg)
2759 char buffer[1024];
2760 SOCKET sock = *(SOCKET*)arg;
2761 int ret;
2763 while ((ret = recv(sock, buffer, sizeof(buffer), 0)) != 0)
2765 if (ret < 0)
2767 if (WSAGetLastError() == WSAEWOULDBLOCK)
2769 fd_set readset;
2770 FD_ZERO(&readset);
2771 FD_SET(sock, &readset);
2772 select(0, &readset, NULL, NULL, NULL);
2773 while (drain_pause)
2774 Sleep(100);
2776 else
2777 break;
2780 return 0;
2783 static void test_send(void)
2785 SOCKET src = INVALID_SOCKET;
2786 SOCKET dst = INVALID_SOCKET;
2787 HANDLE hThread = NULL;
2788 const int buflen = 1024*1024;
2789 char *buffer = NULL;
2790 int ret, i, zero = 0;
2791 WSABUF buf;
2792 OVERLAPPED ov;
2793 BOOL bret;
2794 DWORD id, bytes_sent, dwRet;
2796 memset(&ov, 0, sizeof(ov));
2798 if (tcp_socketpair(&src, &dst) != 0)
2800 ok(0, "creating socket pair failed, skipping test\n");
2801 return;
2804 set_blocking(dst, FALSE);
2805 /* force disable buffering so we can get a pending overlapped request */
2806 ret = setsockopt(dst, SOL_SOCKET, SO_SNDBUF, (char *) &zero, sizeof(zero));
2807 ok(!ret, "setsockopt SO_SNDBUF failed: %d - %d\n", ret, GetLastError());
2809 hThread = CreateThread(NULL, 0, drain_socket_thread, &dst, 0, &id);
2810 if (hThread == NULL)
2812 ok(0, "CreateThread failed, error %d\n", GetLastError());
2813 goto end;
2816 buffer = HeapAlloc(GetProcessHeap(), 0, buflen);
2817 if (buffer == NULL)
2819 ok(0, "HeapAlloc failed, error %d\n", GetLastError());
2820 goto end;
2823 /* fill the buffer with some nonsense */
2824 for (i = 0; i < buflen; ++i)
2826 buffer[i] = (char) i;
2829 ret = send(src, buffer, buflen, 0);
2830 if (ret >= 0)
2831 ok(ret == buflen, "send should have sent %d bytes, but it only sent %d\n", buflen, ret);
2832 else
2833 ok(0, "send failed, error %d\n", WSAGetLastError());
2835 buf.buf = buffer;
2836 buf.len = buflen;
2838 ov.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
2839 ok(ov.hEvent != NULL, "could not create event object, errno = %d\n", GetLastError());
2840 if (!ov.hEvent)
2841 goto end;
2843 bytes_sent = 0;
2844 ret = WSASend(dst, &buf, 1, &bytes_sent, 0, &ov, NULL);
2845 ok((ret == SOCKET_ERROR && GetLastError() == ERROR_IO_PENDING) || broken(bytes_sent == buflen),
2846 "Failed to start overlapped send %d - %d - %d/%d\n", ret, WSAGetLastError(), bytes_sent, buflen);
2848 /* don't check for completion yet, we may need to drain the buffer while still sending */
2849 set_blocking(src, FALSE);
2850 for (i = 0; i < buflen; ++i)
2852 int j = 0;
2854 ret = recv(src, buffer, 1, 0);
2855 while (ret == SOCKET_ERROR && GetLastError() == WSAEWOULDBLOCK && j < 100)
2857 j++;
2858 Sleep(50);
2859 ret = recv(src, buffer, 1, 0);
2862 ok(ret == 1, "Failed to receive data %d - %d (got %d/%d)\n", ret, GetLastError(), i, buflen);
2863 if (ret != 1)
2864 break;
2866 ok(buffer[0] == (char) i, "Received bad data at position %d\n", i);
2869 dwRet = WaitForSingleObject(ov.hEvent, 1000);
2870 ok(dwRet == WAIT_OBJECT_0, "Failed to wait for recv message: %d - %d\n", dwRet, GetLastError());
2871 if (dwRet == WAIT_OBJECT_0)
2873 bret = GetOverlappedResult((HANDLE)dst, &ov, &bytes_sent, FALSE);
2874 ok((bret && bytes_sent == buflen) || broken(!bret && GetLastError() == ERROR_IO_INCOMPLETE) /* win9x */,
2875 "Got %d instead of %d (%d - %d)\n", bytes_sent, buflen, bret, GetLastError());
2878 end:
2879 if (src != INVALID_SOCKET)
2880 closesocket(src);
2881 if (dst != INVALID_SOCKET)
2882 closesocket(dst);
2883 if (hThread != NULL)
2884 CloseHandle(hThread);
2885 if (ov.hEvent)
2886 CloseHandle(ov.hEvent);
2887 HeapFree(GetProcessHeap(), 0, buffer);
2890 typedef struct async_message
2892 SOCKET socket;
2893 LPARAM lparam;
2894 struct async_message *next;
2895 } async_message;
2897 static struct async_message *messages_received;
2899 #define WM_SOCKET (WM_USER+100)
2900 static LRESULT CALLBACK ws2_test_WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
2902 struct async_message *message;
2904 switch (msg)
2906 case WM_SOCKET:
2907 message = HeapAlloc(GetProcessHeap(), 0, sizeof(*message));
2908 message->socket = (SOCKET) wparam;
2909 message->lparam = lparam;
2910 message->next = NULL;
2912 if (messages_received)
2914 struct async_message *last = messages_received;
2915 while (last->next) last = last->next;
2916 last->next = message;
2918 else
2919 messages_received = message;
2920 return 0;
2923 return DefWindowProc(hwnd, msg, wparam, lparam);
2926 static void get_event_details(int event, int *bit, char *name)
2928 switch (event)
2930 case FD_ACCEPT:
2931 if (bit) *bit = FD_ACCEPT_BIT;
2932 if (name) strcpy(name, "FD_ACCEPT");
2933 break;
2934 case FD_CONNECT:
2935 if (bit) *bit = FD_CONNECT_BIT;
2936 if (name) strcpy(name, "FD_CONNECT");
2937 break;
2938 case FD_READ:
2939 if (bit) *bit = FD_READ_BIT;
2940 if (name) strcpy(name, "FD_READ");
2941 break;
2942 case FD_OOB:
2943 if (bit) *bit = FD_OOB_BIT;
2944 if (name) strcpy(name, "FD_OOB");
2945 break;
2946 case FD_WRITE:
2947 if (bit) *bit = FD_WRITE_BIT;
2948 if (name) strcpy(name, "FD_WRITE");
2949 break;
2950 case FD_CLOSE:
2951 if (bit) *bit = FD_CLOSE_BIT;
2952 if (name) strcpy(name, "FD_CLOSE");
2953 break;
2954 default:
2955 if (bit) *bit = -1;
2956 if (name) sprintf(name, "bad%x", event);
2960 static const char *dbgstr_event_seq(const LPARAM *seq)
2962 static char message[1024];
2963 char name[12];
2964 int len = 1;
2966 message[0] = '[';
2967 message[1] = 0;
2968 while (*seq)
2970 get_event_details(WSAGETSELECTEVENT(*seq), NULL, name);
2971 len += sprintf(message + len, "%s(%d) ", name, WSAGETSELECTERROR(*seq));
2972 seq++;
2974 if (len > 1) len--;
2975 strcpy( message + len, "]" );
2976 return message;
2979 static char *dbgstr_event_seq_result(SOCKET s, WSANETWORKEVENTS *netEvents)
2981 static char message[1024];
2982 struct async_message *curr = messages_received;
2983 int index, error, bit = 0;
2984 char name[12];
2985 int len = 1;
2987 message[0] = '[';
2988 message[1] = 0;
2989 while (1)
2991 if (netEvents)
2993 if (bit >= FD_MAX_EVENTS) break;
2994 if ( !(netEvents->lNetworkEvents & (1 << bit)) )
2996 bit++;
2997 continue;
2999 get_event_details(1 << bit, &index, name);
3000 error = netEvents->iErrorCode[index];
3001 bit++;
3003 else
3005 if (!curr) break;
3006 if (curr->socket != s)
3008 curr = curr->next;
3009 continue;
3011 get_event_details(WSAGETSELECTEVENT(curr->lparam), NULL, name);
3012 error = WSAGETSELECTERROR(curr->lparam);
3013 curr = curr->next;
3016 len += sprintf(message + len, "%s(%d) ", name, error);
3018 if (len > 1) len--;
3019 strcpy( message + len, "]" );
3020 return message;
3023 static void flush_events(SOCKET s, HANDLE hEvent)
3025 WSANETWORKEVENTS netEvents;
3026 struct async_message *prev = NULL, *curr = messages_received;
3027 int ret;
3028 DWORD dwRet;
3030 if (hEvent != INVALID_HANDLE_VALUE)
3032 dwRet = WaitForSingleObject(hEvent, 100);
3033 if (dwRet == WAIT_OBJECT_0)
3035 ret = WSAEnumNetworkEvents(s, hEvent, &netEvents);
3036 if (ret)
3037 ok(0, "WSAEnumNetworkEvents failed, error %d\n", ret);
3040 else
3042 while (curr)
3044 if (curr->socket == s)
3046 if (prev) prev->next = curr->next;
3047 else messages_received = curr->next;
3049 HeapFree(GetProcessHeap(), 0, curr);
3051 if (prev) curr = prev->next;
3052 else curr = messages_received;
3054 else
3056 prev = curr;
3057 curr = curr->next;
3063 static int match_event_sequence(SOCKET s, WSANETWORKEVENTS *netEvents, const LPARAM *seq)
3065 int event, index, error, events;
3066 struct async_message *curr;
3068 if (netEvents)
3070 events = netEvents->lNetworkEvents;
3071 while (*seq)
3073 event = WSAGETSELECTEVENT(*seq);
3074 error = WSAGETSELECTERROR(*seq);
3075 get_event_details(event, &index, NULL);
3077 if (!(events & event) && index != -1)
3078 return 0;
3079 if (events & event && index != -1)
3081 if (netEvents->iErrorCode[index] != error)
3082 return 0;
3084 events &= ~event;
3085 seq++;
3087 if (events)
3088 return 0;
3090 else
3092 curr = messages_received;
3093 while (curr)
3095 if (curr->socket == s)
3097 if (!*seq) return 0;
3098 if (*seq != curr->lparam) return 0;
3099 seq++;
3101 curr = curr->next;
3103 if (*seq)
3104 return 0;
3106 return 1;
3109 /* checks for a sequence of events, (order only checked if window is used) */
3110 static void ok_event_sequence(SOCKET s, HANDLE hEvent, const LPARAM *seq, const LPARAM **broken_seqs, int completelyBroken)
3112 MSG msg;
3113 WSANETWORKEVENTS events, *netEvents = NULL;
3114 int ret;
3115 DWORD dwRet;
3117 if (hEvent != INVALID_HANDLE_VALUE)
3119 netEvents = &events;
3121 dwRet = WaitForSingleObject(hEvent, 200);
3122 if (dwRet == WAIT_OBJECT_0)
3124 ret = WSAEnumNetworkEvents(s, hEvent, netEvents);
3125 if (ret)
3127 winetest_ok(0, "WSAEnumNetworkEvents failed, error %d\n", ret);
3128 return;
3131 else
3132 memset(netEvents, 0, sizeof(*netEvents));
3134 else
3136 Sleep(200);
3137 /* Run the message loop a little */
3138 while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE ))
3140 DispatchMessageA(&msg);
3144 if (match_event_sequence(s, netEvents, seq))
3146 winetest_ok(1, "Sequence matches expected: %s\n", dbgstr_event_seq(seq));
3147 flush_events(s, hEvent);
3148 return;
3151 if (broken_seqs)
3153 for (; *broken_seqs; broken_seqs++)
3155 if (match_event_sequence(s, netEvents, *broken_seqs))
3157 winetest_ok(broken(1), "Sequence matches broken: %s, expected %s\n", dbgstr_event_seq_result(s, netEvents), dbgstr_event_seq(seq));
3158 flush_events(s, hEvent);
3159 return;
3164 winetest_ok(broken(completelyBroken), "Expected event sequence %s, got %s\n", dbgstr_event_seq(seq),
3165 dbgstr_event_seq_result(s, netEvents));
3166 flush_events(s, hEvent);
3169 #define ok_event_seq (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : ok_event_sequence
3171 static void test_events(int useMessages)
3173 SOCKET server = INVALID_SOCKET;
3174 SOCKET src = INVALID_SOCKET, src2 = INVALID_SOCKET;
3175 SOCKET dst = INVALID_SOCKET, dst2 = INVALID_SOCKET;
3176 struct sockaddr_in addr;
3177 HANDLE hThread = NULL;
3178 HANDLE hEvent = INVALID_HANDLE_VALUE, hEvent2 = INVALID_HANDLE_VALUE;
3179 WNDCLASSEX wndclass;
3180 HWND hWnd = NULL;
3181 char *buffer = NULL;
3182 int bufferSize = 1024*1024;
3183 WSABUF bufs;
3184 OVERLAPPED ov, ov2;
3185 DWORD flags = 0;
3186 DWORD bytesReturned;
3187 DWORD id;
3188 int len;
3189 int ret;
3190 DWORD dwRet;
3191 BOOL bret;
3192 static char szClassName[] = "wstestclass";
3193 const LPARAM *broken_seq[3];
3194 static const LPARAM empty_seq[] = { 0 };
3195 static const LPARAM close_seq[] = { WSAMAKESELECTREPLY(FD_CLOSE, 0), 0 };
3196 static const LPARAM write_seq[] = { WSAMAKESELECTREPLY(FD_WRITE, 0), 0 };
3197 static const LPARAM read_seq[] = { WSAMAKESELECTREPLY(FD_READ, 0), 0 };
3198 static const LPARAM oob_seq[] = { WSAMAKESELECTREPLY(FD_OOB, 0), 0 };
3199 static const LPARAM connect_seq[] = { WSAMAKESELECTREPLY(FD_CONNECT, 0),
3200 WSAMAKESELECTREPLY(FD_WRITE, 0), 0 };
3201 static const LPARAM read_read_seq[] = { WSAMAKESELECTREPLY(FD_READ, 0),
3202 WSAMAKESELECTREPLY(FD_READ, 0), 0 };
3203 static const LPARAM read_write_seq[] = { WSAMAKESELECTREPLY(FD_READ, 0),
3204 WSAMAKESELECTREPLY(FD_WRITE, 0), 0 };
3205 static const LPARAM read_close_seq[] = { WSAMAKESELECTREPLY(FD_READ, 0),
3206 WSAMAKESELECTREPLY(FD_CLOSE, 0), 0 };
3208 memset(&ov, 0, sizeof(ov));
3209 memset(&ov2, 0, sizeof(ov2));
3211 /* don't use socketpair, we want connection event */
3212 src = socket(AF_INET, SOCK_STREAM, 0);
3213 if (src == INVALID_SOCKET)
3215 ok(0, "creating socket pair failed (%d), skipping test\n", GetLastError());
3216 goto end;
3219 src2 = socket(AF_INET, SOCK_STREAM, 0);
3220 if (src2 == INVALID_SOCKET)
3222 ok(0, "creating socket pair failed (%d), skipping test\n", GetLastError());
3223 goto end;
3226 len = sizeof(BOOL);
3227 if (getsockopt(src, SOL_SOCKET, SO_OOBINLINE, (void *)&bret, &len) == SOCKET_ERROR)
3229 ok(0, "failed to get oobinline status, %d\n", GetLastError());
3230 goto end;
3232 ok(bret == FALSE, "OOB not inline\n");
3234 if (useMessages)
3236 trace("Event test using messages\n");
3238 wndclass.cbSize = sizeof(wndclass);
3239 wndclass.style = CS_HREDRAW | CS_VREDRAW;
3240 wndclass.lpfnWndProc = ws2_test_WndProc;
3241 wndclass.cbClsExtra = 0;
3242 wndclass.cbWndExtra = 0;
3243 wndclass.hInstance = GetModuleHandle(NULL);
3244 wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
3245 wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
3246 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
3247 wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
3248 wndclass.lpszClassName = szClassName;
3249 wndclass.lpszMenuName = NULL;
3250 RegisterClassEx(&wndclass);
3252 hWnd = CreateWindow(szClassName, "WS2Test", WS_OVERLAPPEDWINDOW, 0, 0, 500, 500, NULL, NULL, GetModuleHandle(NULL), NULL);
3253 if (!hWnd)
3255 ok(0, "failed to create window: %d\n", GetLastError());
3256 return;
3259 ret = WSAAsyncSelect(src, hWnd, WM_SOCKET, FD_CONNECT | FD_READ | FD_OOB | FD_WRITE | FD_CLOSE);
3260 if (ret)
3262 ok(0, "WSAAsyncSelect failed, error %d\n", ret);
3263 goto end;
3266 ret = WSAAsyncSelect(src2, hWnd, WM_SOCKET, FD_CONNECT | FD_READ | FD_OOB | FD_WRITE | FD_CLOSE);
3267 if (ret)
3269 ok(0, "WSAAsyncSelect failed, error %d\n", ret);
3270 goto end;
3273 else
3275 trace("Event test using events\n");
3277 hEvent = WSACreateEvent();
3278 if (hEvent == INVALID_HANDLE_VALUE)
3280 ok(0, "WSACreateEvent failed, error %d\n", GetLastError());
3281 goto end;
3284 hEvent2 = WSACreateEvent();
3285 if (hEvent2 == INVALID_HANDLE_VALUE)
3287 ok(0, "WSACreateEvent failed, error %d\n", GetLastError());
3288 goto end;
3291 ret = WSAEventSelect(src, hEvent, FD_CONNECT | FD_READ | FD_OOB | FD_WRITE | FD_CLOSE);
3292 if (ret)
3294 ok(0, "WSAEventSelect failed, error %d\n", ret);
3295 goto end;
3298 ret = WSAEventSelect(src2, hEvent2, FD_CONNECT | FD_READ | FD_OOB | FD_WRITE | FD_CLOSE);
3299 if (ret)
3301 ok(0, "WSAEventSelect failed, error %d\n", ret);
3302 goto end;
3306 server = socket(AF_INET, SOCK_STREAM, 0);
3307 if (server == INVALID_SOCKET)
3309 ok(0, "creating socket pair failed (%d), skipping test\n", GetLastError());
3310 goto end;
3313 memset(&addr, 0, sizeof(addr));
3314 addr.sin_family = AF_INET;
3315 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
3316 ret = bind(server, (struct sockaddr*)&addr, sizeof(addr));
3317 if (ret != 0)
3319 ok(0, "creating socket pair failed (%d), skipping test\n", GetLastError());
3320 goto end;
3323 len = sizeof(addr);
3324 ret = getsockname(server, (struct sockaddr*)&addr, &len);
3325 if (ret != 0)
3327 ok(0, "creating socket pair failed (%d), skipping test\n", GetLastError());
3328 goto end;
3331 ret = listen(server, 2);
3332 if (ret != 0)
3334 ok(0, "creating socket pair failed (%d), skipping test\n", GetLastError());
3335 goto end;
3338 ret = connect(src, (struct sockaddr*)&addr, sizeof(addr));
3339 if (ret == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
3341 ok(0, "creating socket pair failed (%d), skipping test\n", GetLastError());
3342 goto end;
3345 ret = connect(src2, (struct sockaddr*)&addr, sizeof(addr));
3346 if (ret == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
3348 ok(0, "creating socket pair failed (%d), skipping test\n", GetLastError());
3349 goto end;
3352 len = sizeof(addr);
3353 dst = accept(server, (struct sockaddr*)&addr, &len);
3354 if (dst == INVALID_SOCKET)
3356 ok(0, "creating socket pair failed (%d), skipping test\n", GetLastError());
3357 goto end;
3360 len = sizeof(addr);
3361 dst2 = accept(server, (struct sockaddr*)&addr, &len);
3362 if (dst2 == INVALID_SOCKET)
3364 ok(0, "creating socket pair failed (%d), skipping test\n", GetLastError());
3365 goto end;
3368 closesocket(server);
3369 server = INVALID_SOCKET;
3371 /* On Windows it seems when a non-blocking socket sends to a
3372 blocking socket on the same host, the send() is BLOCKING,
3373 so make both sockets non-blocking. src is already non-blocking
3374 from the async select */
3376 if (set_blocking(dst, FALSE))
3378 ok(0, "ioctlsocket failed, error %d\n", WSAGetLastError());
3379 goto end;
3382 buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bufferSize);
3383 if (buffer == NULL)
3385 ok(0, "could not allocate memory for test\n");
3386 goto end;
3389 ov.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
3390 if (ov.hEvent == NULL)
3392 ok(0, "could not create event object, errno = %d\n", GetLastError());
3393 goto end;
3396 ov2.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
3397 if (ov2.hEvent == NULL)
3399 ok(0, "could not create event object, errno = %d\n", GetLastError());
3400 goto end;
3403 /* FD_WRITE should be set initially, and allow us to send at least 1 byte */
3404 ok_event_seq(src, hEvent, connect_seq, NULL, 1);
3405 ok_event_seq(src2, hEvent2, connect_seq, NULL, 1);
3406 /* broken on all windows - FD_CONNECT error is garbage */
3408 /* Test simple send/recv */
3409 ret = send(dst, buffer, 100, 0);
3410 ok(ret == 100, "Failed to send buffer %d err %d\n", ret, GetLastError());
3411 ok_event_seq(src, hEvent, read_seq, NULL, 0);
3413 ret = recv(src, buffer, 50, 0);
3414 ok(ret == 50, "Failed to recv buffer %d err %d\n", ret, GetLastError());
3415 ok_event_seq(src, hEvent, read_seq, NULL, 0);
3417 ret = recv(src, buffer, 50, 0);
3418 ok(ret == 50, "Failed to recv buffer %d err %d\n", ret, GetLastError());
3419 ok_event_seq(src, hEvent, empty_seq, NULL, 0);
3421 /* fun fact - events are reenabled even on failure, but only for messages */
3422 ret = send(dst, "1", 1, 0);
3423 ok(ret == 1, "Failed to send buffer %d err %d\n", ret, GetLastError());
3424 ok_event_seq(src, hEvent, read_seq, NULL, 0);
3426 ret = recv(src, buffer, -1, 0);
3427 ok(ret == SOCKET_ERROR && (GetLastError() == WSAEFAULT || GetLastError() == WSAENOBUFS),
3428 "Failed to recv buffer %d err %d\n", ret, GetLastError());
3429 if (useMessages)
3431 broken_seq[0] = empty_seq; /* win9x */
3432 broken_seq[1] = NULL;
3433 todo_wine ok_event_seq(src, hEvent, read_seq, broken_seq, 0);
3435 else
3436 ok_event_seq(src, hEvent, empty_seq, NULL, 0);
3438 ret = recv(src, buffer, 1, 0);
3439 ok(ret == 1, "Failed to recv buffer %d err %d\n", ret, GetLastError());
3440 ok_event_seq(src, hEvent, empty_seq, NULL, 0);
3442 /* Interaction with overlapped */
3443 bufs.len = sizeof(char);
3444 bufs.buf = buffer;
3445 ret = WSARecv(src, &bufs, 1, &bytesReturned, &flags, &ov, NULL);
3446 ok(ret == SOCKET_ERROR && GetLastError() == ERROR_IO_PENDING,
3447 "WSARecv failed - %d error %d\n", ret, GetLastError());
3449 bufs.len = sizeof(char);
3450 bufs.buf = buffer+1;
3451 ret = WSARecv(src, &bufs, 1, &bytesReturned, &flags, &ov2, NULL);
3452 ok(ret == SOCKET_ERROR && GetLastError() == ERROR_IO_PENDING,
3453 "WSARecv failed - %d error %d\n", ret, GetLastError());
3455 ret = send(dst, "12", 2, 0);
3456 ok(ret == 2, "Failed to send buffer %d err %d\n", ret, GetLastError());
3457 broken_seq[0] = read_read_seq; /* win9x */
3458 broken_seq[1] = NULL;
3459 ok_event_seq(src, hEvent, empty_seq, broken_seq, 0);
3461 dwRet = WaitForSingleObject(ov.hEvent, 100);
3462 ok(dwRet == WAIT_OBJECT_0, "Failed to wait for recv message: %d - %d\n", dwRet, GetLastError());
3463 if (dwRet == WAIT_OBJECT_0)
3465 bret = GetOverlappedResult((HANDLE)src, &ov, &bytesReturned, FALSE);
3466 ok((bret && bytesReturned == 1) || broken(!bret && GetLastError() == ERROR_IO_INCOMPLETE) /* win9x */,
3467 "Got %d instead of 1 (%d - %d)\n", bytesReturned, bret, GetLastError());
3468 ok(buffer[0] == '1', "Got %c instead of 1\n", buffer[0]);
3471 dwRet = WaitForSingleObject(ov2.hEvent, 100);
3472 ok(dwRet == WAIT_OBJECT_0, "Failed to wait for recv message: %d - %d\n", dwRet, GetLastError());
3473 if (dwRet == WAIT_OBJECT_0)
3475 bret = GetOverlappedResult((HANDLE)src, &ov2, &bytesReturned, FALSE);
3476 ok((bret && bytesReturned == 1) || broken(!bret && GetLastError() == ERROR_IO_INCOMPLETE) /* win9x */,
3477 "Got %d instead of 1 (%d - %d)\n", bytesReturned, bret, GetLastError());
3478 ok(buffer[1] == '2', "Got %c instead of 2\n", buffer[1]);
3481 ret = send(dst, "1", 1, 0);
3482 ok(ret == 1, "Failed to send buffer %d err %d\n", ret, GetLastError());
3483 ok_event_seq(src, hEvent, read_seq, NULL, 0);
3485 ret = recv(src, buffer, 1, 0);
3486 ok(ret == 1, "Failed to empty buffer: %d - %d\n", ret, GetLastError());
3487 ok_event_seq(src, hEvent, empty_seq, NULL, 0);
3489 /* Notifications are delivered as soon as possible, blocked only on
3490 * async requests on the same type */
3491 bufs.len = sizeof(char);
3492 bufs.buf = buffer;
3493 ret = WSARecv(src, &bufs, 1, &bytesReturned, &flags, &ov, NULL);
3494 ok(ret == SOCKET_ERROR && GetLastError() == ERROR_IO_PENDING,
3495 "WSARecv failed - %d error %d\n", ret, GetLastError());
3497 if (0) {
3498 ret = send(dst, "1", 1, MSG_OOB);
3499 ok(ret == 1, "Failed to send buffer %d err %d\n", ret, GetLastError());
3500 ok_event_seq(src, hEvent, oob_seq, NULL, 0);
3503 dwRet = WaitForSingleObject(ov.hEvent, 100);
3504 ok(dwRet == WAIT_TIMEOUT, "OOB message activated read?: %d - %d\n", dwRet, GetLastError());
3506 ret = send(dst, "2", 1, 0);
3507 ok(ret == 1, "Failed to send buffer %d err %d\n", ret, GetLastError());
3508 broken_seq[0] = read_seq; /* win98 */
3509 broken_seq[1] = NULL;
3510 ok_event_seq(src, hEvent, empty_seq, broken_seq, 0);
3512 dwRet = WaitForSingleObject(ov.hEvent, 100);
3513 ok(dwRet == WAIT_OBJECT_0 || broken(dwRet == WAIT_TIMEOUT),
3514 "Failed to wait for recv message: %d - %d\n", dwRet, GetLastError());
3515 if (dwRet == WAIT_OBJECT_0)
3517 bret = GetOverlappedResult((HANDLE)src, &ov, &bytesReturned, FALSE);
3518 ok((bret && bytesReturned == 1) || broken(!bret && GetLastError() == ERROR_IO_INCOMPLETE) /* win9x */,
3519 "Got %d instead of 1 (%d - %d)\n", bytesReturned, bret, GetLastError());
3520 ok(buffer[0] == '2', "Got %c instead of 2\n", buffer[0]);
3522 else if (dwRet == WAIT_TIMEOUT)
3524 /* this happens on win98. We get an FD_READ later on the next test */
3525 CancelIo((HANDLE) src);
3528 if (0) {
3529 ret = recv(src, buffer, 1, MSG_OOB);
3530 todo_wine ok(ret == 1, "Failed to empty buffer: %d - %d\n", ret, GetLastError());
3531 /* We get OOB notification, but no data on wine */
3532 ok_event_seq(src, hEvent, empty_seq, NULL, 0);
3535 /* Flood the send queue */
3536 hThread = CreateThread(NULL, 0, drain_socket_thread, &dst, 0, &id);
3537 if (hThread == NULL)
3539 ok(0, "CreateThread failed, error %d\n", GetLastError());
3540 goto end;
3543 /* Now FD_WRITE should not be set, because the socket send buffer isn't full yet */
3544 ok_event_seq(src, hEvent, empty_seq, NULL, 0);
3546 /* Now if we send a ton of data and the 'server' does not drain it fast
3547 * enough (set drain_pause to be sure), the socket send buffer will only
3548 * take some of it, and we will get a short write. This will trigger
3549 * another FD_WRITE event as soon as data is sent and more space becomes
3550 * available, but not any earlier. */
3551 drain_pause=1;
3554 ret = send(src, buffer, bufferSize, 0);
3555 } while (ret == bufferSize);
3556 drain_pause=0;
3557 if (ret >= 0 || WSAGetLastError() == WSAEWOULDBLOCK)
3559 Sleep(400); /* win9x */
3560 broken_seq[0] = read_write_seq;
3561 broken_seq[1] = NULL;
3562 ok_event_seq(src, hEvent, write_seq, broken_seq, 0);
3564 else
3566 ok(0, "sending a lot of data failed with error %d\n", WSAGetLastError());
3569 /* Test how FD_CLOSE is handled */
3570 ret = send(dst, "12", 2, 0);
3571 ok(ret == 2, "Failed to send buffer %d err %d\n", ret, GetLastError());
3573 /* Wait a little and let the send complete */
3574 Sleep(100);
3575 closesocket(dst);
3576 dst = INVALID_SOCKET;
3577 Sleep(100);
3579 /* We can never implement this in wine, best we can hope for is
3580 sending FD_CLOSE after the reads complete */
3581 broken_seq[0] = read_seq; /* win9x */
3582 broken_seq[1] = NULL;
3583 todo_wine ok_event_seq(src, hEvent, read_close_seq, broken_seq, 0);
3585 ret = recv(src, buffer, 1, 0);
3586 ok(ret == 1, "Failed to empty buffer: %d - %d\n", ret, GetLastError());
3587 ok_event_seq(src, hEvent, read_seq, NULL, 0);
3589 ret = recv(src, buffer, 1, 0);
3590 ok(ret == 1, "Failed to empty buffer: %d - %d\n", ret, GetLastError());
3591 /* want it? it's here, but you can't have it */
3592 broken_seq[0] = close_seq; /* win9x */
3593 broken_seq[1] = NULL;
3594 todo_wine ok_event_seq(src, hEvent, empty_seq, /* wine sends FD_CLOSE here */
3595 broken_seq, 0);
3597 /* Test how FD_CLOSE is handled */
3598 ret = send(dst2, "12", 2, 0);
3599 ok(ret == 2, "Failed to send buffer %d err %d\n", ret, GetLastError());
3601 Sleep(200);
3602 shutdown(dst2, SD_SEND);
3603 Sleep(200);
3605 /* Some of the below are technically todo_wine, but our event sequence is still valid, so to prevent
3606 regressions, don't mark them as todo_wine, and mark windows as broken */
3607 broken_seq[0] = read_close_seq;
3608 broken_seq[1] = close_seq;
3609 broken_seq[2] = NULL;
3610 ok_event_seq(src2, hEvent2, read_seq, broken_seq, 0);
3612 ret = recv(src2, buffer, 1, 0);
3613 ok(ret == 1 || broken(!ret), "Failed to empty buffer: %d - %d\n", ret, GetLastError());
3614 broken_seq[0] = close_seq; /* win98 */
3615 broken_seq[1] = NULL;
3616 ok_event_seq(src2, hEvent2, read_seq, broken_seq, 0);
3618 ret = recv(src2, buffer, 1, 0);
3619 ok(ret == 1 || broken(!ret), "Failed to empty buffer: %d - %d\n", ret, GetLastError());
3620 broken_seq[0] = empty_seq;
3621 broken_seq[1] = NULL;
3622 ok_event_seq(src2, hEvent2, close_seq, broken_seq, 0);
3624 ret = send(src2, "1", 1, 0);
3625 ok(ret == 1, "Sending to half-closed socket failed %d err %d\n", ret, GetLastError());
3626 ok_event_seq(src2, hEvent2, empty_seq, NULL, 0);
3628 ret = send(src2, "1", 1, 0);
3629 ok(ret == 1, "Sending to half-closed socket failed %d err %d\n", ret, GetLastError());
3630 ok_event_seq(src2, hEvent2, empty_seq, NULL, 0);
3632 end:
3633 if (src != INVALID_SOCKET)
3635 flush_events(src, hEvent);
3636 closesocket(src);
3638 if (src2 != INVALID_SOCKET)
3640 flush_events(src2, hEvent2);
3641 closesocket(src2);
3643 HeapFree(GetProcessHeap(), 0, buffer);
3644 if (server != INVALID_SOCKET)
3645 closesocket(server);
3646 if (dst != INVALID_SOCKET)
3647 closesocket(dst);
3648 if (dst2 != INVALID_SOCKET)
3649 closesocket(dst2);
3650 if (hThread != NULL)
3651 CloseHandle(hThread);
3652 if (hWnd != NULL)
3653 CloseHandle(hWnd);
3654 if (hEvent != NULL)
3655 CloseHandle(hEvent);
3656 if (hEvent2 != NULL)
3657 CloseHandle(hEvent2);
3658 if (ov.hEvent != NULL)
3659 CloseHandle(ov.hEvent);
3660 if (ov2.hEvent != NULL)
3661 CloseHandle(ov2.hEvent);
3664 static void test_ipv6only(void)
3666 SOCKET v4 = INVALID_SOCKET,
3667 v6 = INVALID_SOCKET;
3668 struct sockaddr_in sin4;
3669 struct sockaddr_in6 sin6;
3670 int ret;
3672 memset(&sin4, 0, sizeof(sin4));
3673 sin4.sin_family = AF_INET;
3674 sin4.sin_port = htons(SERVERPORT);
3676 memset(&sin6, 0, sizeof(sin6));
3677 sin6.sin6_family = AF_INET6;
3678 sin6.sin6_port = htons(SERVERPORT);
3680 v6 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
3681 if (v6 == INVALID_SOCKET) {
3682 skip("Could not create IPv6 socket (LastError: %d; %d expected if IPv6 not available).\n",
3683 WSAGetLastError(), WSAEAFNOSUPPORT);
3684 goto end;
3686 ret = bind(v6, (struct sockaddr*)&sin6, sizeof(sin6));
3687 if (ret) {
3688 skip("Could not bind IPv6 address (LastError: %d).\n",
3689 WSAGetLastError());
3690 goto end;
3693 v4 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
3694 if (v4 == INVALID_SOCKET) {
3695 skip("Could not create IPv4 socket (LastError: %d).\n",
3696 WSAGetLastError());
3697 goto end;
3699 ret = bind(v4, (struct sockaddr*)&sin4, sizeof(sin4));
3700 ok(!ret, "Could not bind IPv4 address (LastError: %d; %d expected if IPv6 binds to IPv4 as well).\n",
3701 WSAGetLastError(), WSAEADDRINUSE);
3703 end:
3704 if (v4 != INVALID_SOCKET)
3705 closesocket(v4);
3706 if (v6 != INVALID_SOCKET)
3707 closesocket(v6);
3710 static void test_WSASendTo(void)
3712 SOCKET s;
3713 struct sockaddr_in addr;
3714 char buf[12] = "hello world";
3715 WSABUF data_buf;
3716 DWORD bytesSent;
3718 addr.sin_family = AF_INET;
3719 addr.sin_port = htons(139);
3720 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
3721 data_buf.len = sizeof(buf);
3722 data_buf.buf = buf;
3724 if( (s = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) {
3725 ok(0, "socket() failed error: %d\n", WSAGetLastError());
3726 return;
3729 WSASetLastError(12345);
3730 if(WSASendTo(s, &data_buf, 1, &bytesSent, 0, (struct sockaddr*)&addr, sizeof(addr), NULL, NULL)) {
3731 ok(0, "WSASendTo() failed error: %d\n", WSAGetLastError());
3732 return;
3734 ok(!WSAGetLastError(), "WSAGetLastError() should return zero after "
3735 "a successful call to WSASendTo()\n");
3738 static void test_WSARecv(void)
3740 SOCKET src, dest;
3741 char buf[20];
3742 WSABUF bufs;
3743 WSAOVERLAPPED ov;
3744 DWORD bytesReturned;
3745 DWORD flags;
3746 struct linger ling;
3747 int iret;
3748 DWORD dwret;
3749 BOOL bret;
3751 tcp_socketpair(&src, &dest);
3752 if (src == INVALID_SOCKET || dest == INVALID_SOCKET)
3754 skip("failed to create sockets\n");
3755 goto end;
3758 bufs.len = sizeof(buf);
3759 bufs.buf = buf;
3760 flags = 0;
3762 memset(&ov, 0, sizeof(ov));
3763 ov.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
3764 ok(ov.hEvent != NULL, "could not create event object, errno = %d\n", GetLastError());
3765 if (!ov.hEvent)
3766 goto end;
3768 ling.l_onoff = 1;
3769 ling.l_linger = 0;
3770 iret = setsockopt (src, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
3771 ok(!iret, "Failed to set linger %d\n", GetLastError());
3773 iret = WSARecv(dest, &bufs, 1, &bytesReturned, &flags, &ov, NULL);
3774 ok(iret == SOCKET_ERROR && GetLastError() == ERROR_IO_PENDING, "WSARecv failed - %d error %d\n", iret, GetLastError());
3776 closesocket(src);
3777 src = INVALID_SOCKET;
3779 dwret = WaitForSingleObject(ov.hEvent, 1000);
3780 ok(dwret == WAIT_OBJECT_0, "Waiting for disconnect event failed with %d + errno %d\n", dwret, GetLastError());
3782 bret = GetOverlappedResult((HANDLE)dest, &ov, &bytesReturned, FALSE);
3783 todo_wine ok(!bret && (GetLastError() == ERROR_NETNAME_DELETED || broken(GetLastError() == ERROR_IO_INCOMPLETE) /* win9x */),
3784 "Did not get disconnect event: %d, error %d\n", bret, GetLastError());
3785 ok(bytesReturned == 0, "Bytes received is %d\n", bytesReturned);
3787 end:
3788 if (dest != INVALID_SOCKET)
3789 closesocket(dest);
3790 if (src != INVALID_SOCKET)
3791 closesocket(src);
3792 if (ov.hEvent)
3793 WSACloseEvent(ov.hEvent);
3796 static void test_GetAddrInfoW(void)
3798 static const WCHAR port[] = {'8','0',0};
3799 static const WCHAR empty[] = {0};
3800 static const WCHAR localhost[] = {'l','o','c','a','l','h','o','s','t',0};
3802 int ret;
3803 ADDRINFOW *result, hint;
3805 if (!pGetAddrInfoW || !pFreeAddrInfoW)
3807 win_skip("GetAddrInfoW and/or FreeAddrInfoW not present\n");
3808 return;
3811 memset(&hint, 0, sizeof(ADDRINFOW));
3813 ret = pGetAddrInfoW(NULL, NULL, NULL, &result);
3814 ok(ret == WSAHOST_NOT_FOUND, "got %d expected WSAHOST_NOT_FOUND\n", ret);
3816 result = NULL;
3817 ret = pGetAddrInfoW(empty, NULL, NULL, &result);
3818 todo_wine
3820 ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError());
3821 ok(result != NULL, "GetAddrInfoW failed\n");
3823 pFreeAddrInfoW(result);
3825 ret = pGetAddrInfoW(localhost, NULL, NULL, &result);
3826 ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError());
3827 pFreeAddrInfoW(result);
3829 ret = pGetAddrInfoW(localhost, port, NULL, &result);
3830 ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError());
3831 pFreeAddrInfoW(result);
3833 ret = pGetAddrInfoW(localhost, port, &hint, &result);
3834 ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError());
3835 pFreeAddrInfoW(result);
3838 static void test_ConnectEx(void)
3840 SOCKET listener = INVALID_SOCKET;
3841 SOCKET acceptor = INVALID_SOCKET;
3842 SOCKET connector = INVALID_SOCKET;
3843 struct sockaddr_in address, conaddress;
3844 int addrlen;
3845 OVERLAPPED overlapped;
3846 LPFN_CONNECTEX pConnectEx;
3847 GUID connectExGuid = WSAID_CONNECTEX;
3848 DWORD bytesReturned;
3849 char buffer[1024];
3850 BOOL bret;
3851 DWORD dwret;
3852 int iret;
3854 memset(&overlapped, 0, sizeof(overlapped));
3856 listener = socket(AF_INET, SOCK_STREAM, 0);
3857 if (listener == INVALID_SOCKET) {
3858 skip("could not create listener socket, error %d\n", WSAGetLastError());
3859 goto end;
3862 connector = socket(AF_INET, SOCK_STREAM, 0);
3863 if (connector == INVALID_SOCKET) {
3864 skip("could not create connector socket, error %d\n", WSAGetLastError());
3865 goto end;
3868 memset(&address, 0, sizeof(address));
3869 address.sin_family = AF_INET;
3870 address.sin_addr.s_addr = inet_addr("127.0.0.1");
3871 iret = bind(listener, (struct sockaddr*)&address, sizeof(address));
3872 if (iret != 0) {
3873 skip("failed to bind, error %d\n", WSAGetLastError());
3874 goto end;
3877 addrlen = sizeof(address);
3878 iret = getsockname(listener, (struct sockaddr*)&address, &addrlen);
3879 if (iret != 0) {
3880 skip("failed to lookup bind address, error %d\n", WSAGetLastError());
3881 goto end;
3884 if (set_blocking(listener, TRUE)) {
3885 skip("couldn't make socket non-blocking, error %d\n", WSAGetLastError());
3886 goto end;
3889 iret = WSAIoctl(connector, SIO_GET_EXTENSION_FUNCTION_POINTER, &connectExGuid, sizeof(connectExGuid),
3890 &pConnectEx, sizeof(pConnectEx), &bytesReturned, NULL, NULL);
3891 if (iret) {
3892 win_skip("WSAIoctl failed to get ConnectEx with ret %d + errno %d\n", iret, WSAGetLastError());
3893 goto end;
3896 bret = pConnectEx(INVALID_SOCKET, (struct sockaddr*)&address, addrlen, NULL, 0, &bytesReturned, &overlapped);
3897 ok(bret == FALSE && WSAGetLastError() == WSAENOTSOCK, "ConnectEx on invalid socket "
3898 "returned %d + errno %d\n", bret, WSAGetLastError());
3900 bret = pConnectEx(connector, (struct sockaddr*)&address, addrlen, NULL, 0, &bytesReturned, &overlapped);
3901 todo_wine ok(bret == FALSE && WSAGetLastError() == WSAEINVAL, "ConnectEx on a unbound socket "
3902 "returned %d + errno %d\n", bret, WSAGetLastError());
3903 if (bret == TRUE || WSAGetLastError() != WSAEINVAL)
3905 acceptor = accept(listener, NULL, NULL);
3906 if (acceptor != INVALID_SOCKET) {
3907 closesocket(acceptor);
3908 acceptor = INVALID_SOCKET;
3911 closesocket(connector);
3912 connector = socket(AF_INET, SOCK_STREAM, 0);
3913 if (connector == INVALID_SOCKET) {
3914 skip("could not create connector socket, error %d\n", WSAGetLastError());
3915 goto end;
3919 /* ConnectEx needs a bound socket */
3920 memset(&conaddress, 0, sizeof(conaddress));
3921 conaddress.sin_family = AF_INET;
3922 conaddress.sin_addr.s_addr = inet_addr("127.0.0.1");
3923 iret = bind(connector, (struct sockaddr*)&conaddress, sizeof(conaddress));
3924 if (iret != 0) {
3925 skip("failed to bind, error %d\n", WSAGetLastError());
3926 goto end;
3929 bret = pConnectEx(connector, (struct sockaddr*)&address, addrlen, NULL, 0, &bytesReturned, NULL);
3930 ok(bret == FALSE && WSAGetLastError() == ERROR_INVALID_PARAMETER, "ConnectEx on a NULL overlapped "
3931 "returned %d + errno %d\n", bret, WSAGetLastError());
3933 overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
3934 if (overlapped.hEvent == NULL) {
3935 skip("could not create event object, errno = %d\n", GetLastError());
3936 goto end;
3939 iret = listen(listener, 1);
3940 if (iret != 0) {
3941 skip("listening failed, errno = %d\n", WSAGetLastError());
3942 goto end;
3945 bret = pConnectEx(connector, (struct sockaddr*)&address, addrlen, NULL, 0, &bytesReturned, &overlapped);
3946 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "ConnectEx failed: "
3947 "returned %d + errno %d\n", bret, WSAGetLastError());
3948 dwret = WaitForSingleObject(overlapped.hEvent, 15000);
3949 ok(dwret == WAIT_OBJECT_0, "Waiting for connect event failed with %d + errno %d\n", dwret, GetLastError());
3951 bret = GetOverlappedResult((HANDLE)connector, &overlapped, &bytesReturned, FALSE);
3952 ok(bret, "Connecting failed, error %d\n", GetLastError());
3953 ok(bytesReturned == 0, "Bytes sent is %d\n", bytesReturned);
3955 closesocket(connector);
3956 connector = socket(AF_INET, SOCK_STREAM, 0);
3957 if (connector == INVALID_SOCKET) {
3958 skip("could not create connector socket, error %d\n", WSAGetLastError());
3959 goto end;
3961 /* ConnectEx needs a bound socket */
3962 memset(&conaddress, 0, sizeof(conaddress));
3963 conaddress.sin_family = AF_INET;
3964 conaddress.sin_addr.s_addr = inet_addr("127.0.0.1");
3965 iret = bind(connector, (struct sockaddr*)&conaddress, sizeof(conaddress));
3966 if (iret != 0) {
3967 skip("failed to bind, error %d\n", WSAGetLastError());
3968 goto end;
3971 acceptor = accept(listener, NULL, NULL);
3972 if (acceptor != INVALID_SOCKET) {
3973 closesocket(acceptor);
3976 buffer[0] = '1';
3977 buffer[1] = '2';
3978 buffer[2] = '3';
3979 bret = pConnectEx(connector, (struct sockaddr*)&address, addrlen, buffer, 3, &bytesReturned, &overlapped);
3980 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "ConnectEx failed: "
3981 "returned %d + errno %d\n", bret, WSAGetLastError());
3982 dwret = WaitForSingleObject(overlapped.hEvent, 15000);
3983 ok(dwret == WAIT_OBJECT_0, "Waiting for connect event failed with %d + errno %d\n", dwret, GetLastError());
3985 bret = GetOverlappedResult((HANDLE)connector, &overlapped, &bytesReturned, FALSE);
3986 ok(bret, "Connecting failed, error %d\n", GetLastError());
3987 ok(bytesReturned == 3, "Bytes sent is %d\n", bytesReturned);
3989 acceptor = accept(listener, NULL, NULL);
3990 ok(acceptor != INVALID_SOCKET, "could not accept socket error %d\n", WSAGetLastError());
3992 bytesReturned = recv(acceptor, buffer, 3, 0);
3993 buffer[4] = 0;
3994 ok(bytesReturned == 3, "Didn't get all sent data, got only %d\n", bytesReturned);
3995 ok(buffer[0] == '1' && buffer[1] == '2' && buffer[2] == '3',
3996 "Failed to get the right data, expected '123', got '%s'\n", buffer);
3998 closesocket(connector);
3999 connector = socket(AF_INET, SOCK_STREAM, 0);
4000 if (connector == INVALID_SOCKET) {
4001 skip("could not create connector socket, error %d\n", WSAGetLastError());
4002 goto end;
4004 /* ConnectEx needs a bound socket */
4005 memset(&conaddress, 0, sizeof(conaddress));
4006 conaddress.sin_family = AF_INET;
4007 conaddress.sin_addr.s_addr = inet_addr("127.0.0.1");
4008 iret = bind(connector, (struct sockaddr*)&conaddress, sizeof(conaddress));
4009 if (iret != 0) {
4010 skip("failed to bind, error %d\n", WSAGetLastError());
4011 goto end;
4014 if (acceptor != INVALID_SOCKET) {
4015 closesocket(acceptor);
4016 acceptor = INVALID_SOCKET;
4019 /* Connect with error */
4020 closesocket(listener);
4021 listener = INVALID_SOCKET;
4023 address.sin_port = htons(1);
4025 bret = pConnectEx(connector, (struct sockaddr*)&address, addrlen, NULL, 0, &bytesReturned, &overlapped);
4026 ok(bret == FALSE && GetLastError(), "ConnectEx to bad destination failed: "
4027 "returned %d + errno %d\n", bret, GetLastError());
4029 if (GetLastError() == ERROR_IO_PENDING)
4031 dwret = WaitForSingleObject(overlapped.hEvent, 15000);
4032 ok(dwret == WAIT_OBJECT_0, "Waiting for connect event failed with %d + errno %d\n", dwret, GetLastError());
4034 bret = GetOverlappedResult((HANDLE)connector, &overlapped, &bytesReturned, FALSE);
4035 ok(bret == FALSE && GetLastError() == ERROR_CONNECTION_REFUSED,
4036 "Connecting to a disconnected host returned error %d - %d\n", bret, WSAGetLastError());
4038 else {
4039 ok(GetLastError() == WSAECONNREFUSED,
4040 "Connecting to a disconnected host returned error %d - %d\n", bret, WSAGetLastError());
4043 end:
4044 if (overlapped.hEvent)
4045 WSACloseEvent(overlapped.hEvent);
4046 if (listener != INVALID_SOCKET)
4047 closesocket(listener);
4048 if (acceptor != INVALID_SOCKET)
4049 closesocket(acceptor);
4050 if (connector != INVALID_SOCKET)
4051 closesocket(connector);
4054 static void test_AcceptEx(void)
4056 SOCKET listener = INVALID_SOCKET;
4057 SOCKET acceptor = INVALID_SOCKET;
4058 SOCKET connector = INVALID_SOCKET;
4059 SOCKET connector2 = INVALID_SOCKET;
4060 struct sockaddr_in bindAddress;
4061 int socklen;
4062 GUID acceptExGuid = WSAID_ACCEPTEX;
4063 LPFN_ACCEPTEX pAcceptEx = NULL;
4064 fd_set fds_accept, fds_send;
4065 struct timeval timeout = {0,10}; /* wait for 10 milliseconds */
4066 int got, conn1, i;
4067 DWORD bytesReturned;
4068 char buffer[1024];
4069 OVERLAPPED overlapped;
4070 int iret;
4071 BOOL bret;
4072 DWORD dwret;
4074 memset(&overlapped, 0, sizeof(overlapped));
4076 listener = socket(AF_INET, SOCK_STREAM, 0);
4077 if (listener == INVALID_SOCKET) {
4078 skip("could not create listener socket, error %d\n", WSAGetLastError());
4079 goto end;
4082 acceptor = socket(AF_INET, SOCK_STREAM, 0);
4083 if (acceptor == INVALID_SOCKET) {
4084 skip("could not create acceptor socket, error %d\n", WSAGetLastError());
4085 goto end;
4088 connector = socket(AF_INET, SOCK_STREAM, 0);
4089 if (connector == INVALID_SOCKET) {
4090 skip("could not create connector socket, error %d\n", WSAGetLastError());
4091 goto end;
4094 memset(&bindAddress, 0, sizeof(bindAddress));
4095 bindAddress.sin_family = AF_INET;
4096 bindAddress.sin_addr.s_addr = inet_addr("127.0.0.1");
4097 iret = bind(listener, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
4098 if (iret != 0) {
4099 skip("failed to bind, error %d\n", WSAGetLastError());
4100 goto end;
4103 socklen = sizeof(bindAddress);
4104 iret = getsockname(listener, (struct sockaddr*)&bindAddress, &socklen);
4105 if (iret != 0) {
4106 skip("failed to lookup bind address, error %d\n", WSAGetLastError());
4107 goto end;
4110 if (set_blocking(listener, FALSE)) {
4111 skip("couldn't make socket non-blocking, error %d\n", WSAGetLastError());
4112 goto end;
4115 iret = WSAIoctl(listener, SIO_GET_EXTENSION_FUNCTION_POINTER, &acceptExGuid, sizeof(acceptExGuid),
4116 &pAcceptEx, sizeof(pAcceptEx), &bytesReturned, NULL, NULL);
4117 if (iret) {
4118 skip("WSAIoctl failed to get AcceptEx with ret %d + errno %d\n", iret, WSAGetLastError());
4119 goto end;
4122 bret = pAcceptEx(INVALID_SOCKET, acceptor, buffer, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
4123 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
4124 &bytesReturned, &overlapped);
4125 ok(bret == FALSE && WSAGetLastError() == WSAENOTSOCK, "AcceptEx on invalid listening socket "
4126 "returned %d + errno %d\n", bret, WSAGetLastError());
4128 bret = pAcceptEx(listener, INVALID_SOCKET, buffer, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
4129 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
4130 &bytesReturned, &overlapped);
4131 ok(bret == FALSE && WSAGetLastError() == WSAEINVAL, "AcceptEx on invalid accepting socket "
4132 "returned %d + errno %d\n", bret, WSAGetLastError());
4134 bret = pAcceptEx(listener, acceptor, NULL, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
4135 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
4136 &bytesReturned, &overlapped);
4137 ok(bret == FALSE &&
4138 (WSAGetLastError() == WSAEINVAL ||
4139 broken(WSAGetLastError() == WSAEFAULT)), /* NT4 */
4140 "AcceptEx on NULL buffer returned %d + errno %d\n", bret, WSAGetLastError());
4142 bret = pAcceptEx(listener, acceptor, buffer, 0, 0, sizeof(struct sockaddr_in) + 16,
4143 &bytesReturned, &overlapped);
4144 todo_wine ok(bret == FALSE && WSAGetLastError() == WSAEINVAL, "AcceptEx on too small local address size "
4145 "returned %d + errno %d\n", bret, WSAGetLastError());
4147 bret = pAcceptEx(listener, acceptor, buffer, 0, sizeof(struct sockaddr_in) + 16, 0,
4148 &bytesReturned, &overlapped);
4149 todo_wine ok(bret == FALSE && WSAGetLastError() == WSAEINVAL, "AcceptEx on too small remote address size "
4150 "returned %d + errno %d\n", bret, WSAGetLastError());
4152 bret = pAcceptEx(listener, acceptor, buffer, 0,
4153 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
4154 &bytesReturned, NULL);
4155 ok(bret == FALSE && WSAGetLastError() == ERROR_INVALID_PARAMETER, "AcceptEx on a NULL overlapped "
4156 "returned %d + errno %d\n", bret, WSAGetLastError());
4158 bret = pAcceptEx(listener, acceptor, buffer, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
4159 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
4160 &bytesReturned, &overlapped);
4161 todo_wine ok(bret == FALSE && WSAGetLastError() == WSAEINVAL, "AcceptEx on a non-listening socket "
4162 "returned %d + errno %d\n", bret, WSAGetLastError());
4164 iret = listen(listener, 5);
4165 if (iret != 0) {
4166 skip("listening failed, errno = %d\n", WSAGetLastError());
4167 goto end;
4170 overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
4171 if (overlapped.hEvent == NULL) {
4172 skip("could not create event object, errno = %d\n", GetLastError());
4173 goto end;
4176 bret = pAcceptEx(listener, acceptor, buffer, 0,
4177 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
4178 &bytesReturned, &overlapped);
4179 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
4181 bret = pAcceptEx(listener, acceptor, buffer, 0,
4182 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
4183 &bytesReturned, &overlapped);
4184 todo_wine ok((bret == FALSE && WSAGetLastError() == WSAEINVAL) || broken(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING) /* NT4 */,
4185 "AcceptEx on already pending socket returned %d + errno %d\n", bret, WSAGetLastError());
4186 if (bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING) {
4187 /* We need to cancel this call, otherwise things fail */
4188 bret = CancelIo((HANDLE) listener);
4189 ok(bret, "Failed to cancel failed test. Bailing...\n");
4190 if (!bret) return;
4191 WaitForSingleObject(overlapped.hEvent, 0);
4193 bret = pAcceptEx(listener, acceptor, buffer, 0,
4194 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
4195 &bytesReturned, &overlapped);
4196 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
4199 iret = connect(acceptor, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
4200 todo_wine ok((iret == SOCKET_ERROR && WSAGetLastError() == WSAEINVAL) || broken(!iret) /* NT4 */,
4201 "connecting to acceptex acceptor succeeded? return %d + errno %d\n", iret, WSAGetLastError());
4202 if (!iret || (iret == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK)) {
4203 /* We need to cancel this call, otherwise things fail */
4204 closesocket(acceptor);
4205 acceptor = socket(AF_INET, SOCK_STREAM, 0);
4206 if (acceptor == INVALID_SOCKET) {
4207 skip("could not create acceptor socket, error %d\n", WSAGetLastError());
4208 goto end;
4211 bret = CancelIo((HANDLE) listener);
4212 ok(bret, "Failed to cancel failed test. Bailing...\n");
4213 if (!bret) return;
4215 bret = pAcceptEx(listener, acceptor, buffer, 0,
4216 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
4217 &bytesReturned, &overlapped);
4218 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
4221 iret = connect(connector, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
4222 ok(iret == 0, "connecting to accepting socket failed, error %d\n", WSAGetLastError());
4224 dwret = WaitForSingleObject(overlapped.hEvent, INFINITE);
4225 ok(dwret == WAIT_OBJECT_0, "Waiting for accept event failed with %d + errno %d\n", dwret, GetLastError());
4227 bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
4228 ok(bret, "GetOverlappedResult failed, error %d\n", GetLastError());
4229 ok(bytesReturned == 0, "bytesReturned isn't supposed to be %d\n", bytesReturned);
4231 closesocket(connector);
4232 connector = INVALID_SOCKET;
4233 closesocket(acceptor);
4235 /* Test short reads */
4237 acceptor = socket(AF_INET, SOCK_STREAM, 0);
4238 if (acceptor == INVALID_SOCKET) {
4239 skip("could not create acceptor socket, error %d\n", WSAGetLastError());
4240 goto end;
4242 connector = socket(AF_INET, SOCK_STREAM, 0);
4243 if (connector == INVALID_SOCKET) {
4244 skip("could not create connector socket, error %d\n", WSAGetLastError());
4245 goto end;
4247 bret = pAcceptEx(listener, acceptor, buffer, 2,
4248 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
4249 &bytesReturned, &overlapped);
4250 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
4252 iret = connect(connector, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
4253 ok(iret == 0, "connecting to accepting socket failed, error %d\n", WSAGetLastError());
4255 dwret = WaitForSingleObject(overlapped.hEvent, 0);
4256 ok(dwret == WAIT_TIMEOUT, "Waiting for accept event timeout failed with %d + errno %d\n", dwret, GetLastError());
4258 iret = send(connector, buffer, 1, 0);
4259 ok(iret == 1, "could not send 1 byte: send %d errno %d\n", iret, WSAGetLastError());
4261 dwret = WaitForSingleObject(overlapped.hEvent, 1000);
4262 ok(dwret == WAIT_OBJECT_0, "Waiting for accept event failed with %d + errno %d\n", dwret, GetLastError());
4264 bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
4265 ok(bret, "GetOverlappedResult failed, error %d\n", GetLastError());
4266 ok(bytesReturned == 1, "bytesReturned isn't supposed to be %d\n", bytesReturned);
4268 closesocket(connector);
4269 connector = INVALID_SOCKET;
4270 closesocket(acceptor);
4272 /* Test CF_DEFER & AcceptEx interaction */
4274 acceptor = socket(AF_INET, SOCK_STREAM, 0);
4275 if (acceptor == INVALID_SOCKET) {
4276 skip("could not create acceptor socket, error %d\n", WSAGetLastError());
4277 goto end;
4279 connector = socket(AF_INET, SOCK_STREAM, 0);
4280 if (connector == INVALID_SOCKET) {
4281 skip("could not create connector socket, error %d\n", WSAGetLastError());
4282 goto end;
4284 connector2 = socket(AF_INET, SOCK_STREAM, 0);
4285 if (connector == INVALID_SOCKET) {
4286 skip("could not create connector socket, error %d\n", WSAGetLastError());
4287 goto end;
4290 if (set_blocking(connector, FALSE)) {
4291 skip("couldn't make socket non-blocking, error %d\n", WSAGetLastError());
4292 goto end;
4295 if (set_blocking(connector2, FALSE)) {
4296 skip("couldn't make socket non-blocking, error %d\n", WSAGetLastError());
4297 goto end;
4300 /* Connect socket #1 */
4301 iret = connect(connector, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
4302 ok(iret == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK, "connecting to accepting socket failed, error %d\n", WSAGetLastError());
4304 FD_ZERO ( &fds_accept );
4305 FD_ZERO ( &fds_send );
4307 FD_SET ( listener, &fds_accept );
4308 FD_SET ( connector, &fds_send );
4310 buffer[0] = '0';
4311 got = 0;
4312 conn1 = 0;
4314 for (i = 0; i < 4000; ++i)
4316 fd_set fds_openaccept = fds_accept, fds_opensend = fds_send;
4318 wsa_ok ( ( select ( 0, &fds_openaccept, &fds_opensend, NULL, &timeout ) ), SOCKET_ERROR !=,
4319 "acceptex test(%d): could not select on socket, errno %d\n" );
4321 /* check for incoming requests */
4322 if ( FD_ISSET ( listener, &fds_openaccept ) ) {
4323 got++;
4324 if (got == 1) {
4325 SOCKET tmp = WSAAccept(listener, NULL, NULL, (LPCONDITIONPROC) AlwaysDeferConditionFunc, 0);
4326 ok(tmp == INVALID_SOCKET && WSAGetLastError() == WSATRY_AGAIN, "Failed to defer connection, %d\n", WSAGetLastError());
4327 bret = pAcceptEx(listener, acceptor, buffer, 0,
4328 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
4329 &bytesReturned, &overlapped);
4330 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
4332 else if (got == 2) {
4333 /* this should be socket #2 */
4334 SOCKET tmp = accept(listener, NULL, NULL);
4335 ok(tmp != INVALID_SOCKET, "accept failed %d\n", WSAGetLastError());
4336 closesocket(tmp);
4338 else {
4339 ok(FALSE, "Got more than 2 connections?\n");
4342 if ( conn1 && FD_ISSET ( connector2, &fds_opensend ) ) {
4343 /* Send data on second socket, and stop */
4344 send(connector2, "2", 1, 0);
4345 FD_CLR ( connector2, &fds_send );
4347 break;
4349 if ( FD_ISSET ( connector, &fds_opensend ) ) {
4350 /* Once #1 is connected, allow #2 to connect */
4351 conn1 = 1;
4353 send(connector, "1", 1, 0);
4354 FD_CLR ( connector, &fds_send );
4356 iret = connect(connector2, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
4357 ok(iret == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK, "connecting to accepting socket failed, error %d\n", WSAGetLastError());
4358 FD_SET ( connector2, &fds_send );
4362 ok (got == 2 || broken(got == 1) /* NT4 */,
4363 "Did not get both connections, got %d\n", got);
4365 dwret = WaitForSingleObject(overlapped.hEvent, 0);
4366 ok(dwret == WAIT_OBJECT_0, "Waiting for accept event failed with %d + errno %d\n", dwret, GetLastError());
4368 bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
4369 ok(bret, "GetOverlappedResult failed, error %d\n", GetLastError());
4370 ok(bytesReturned == 0, "bytesReturned isn't supposed to be %d\n", bytesReturned);
4372 set_blocking(acceptor, TRUE);
4373 iret = recv( acceptor, buffer, 2, 0);
4374 ok(iret == 1, "Failed to get data, %d, errno: %d\n", iret, WSAGetLastError());
4376 ok(buffer[0] == '1', "The wrong first client was accepted by acceptex: %c != 1\n", buffer[0]);
4378 closesocket(connector);
4379 connector = INVALID_SOCKET;
4380 closesocket(acceptor);
4382 /* clean up in case of failures */
4383 while ((acceptor = accept(listener, NULL, NULL)) != INVALID_SOCKET)
4384 closesocket(acceptor);
4386 /* Disconnect during receive? */
4388 acceptor = socket(AF_INET, SOCK_STREAM, 0);
4389 if (acceptor == INVALID_SOCKET) {
4390 skip("could not create acceptor socket, error %d\n", WSAGetLastError());
4391 goto end;
4393 connector = socket(AF_INET, SOCK_STREAM, 0);
4394 if (connector == INVALID_SOCKET) {
4395 skip("could not create connector socket, error %d\n", WSAGetLastError());
4396 goto end;
4398 bret = pAcceptEx(listener, acceptor, buffer, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
4399 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
4400 &bytesReturned, &overlapped);
4401 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
4403 iret = connect(connector, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
4404 ok(iret == 0, "connecting to accepting socket failed, error %d\n", WSAGetLastError());
4406 closesocket(connector);
4407 connector = INVALID_SOCKET;
4409 dwret = WaitForSingleObject(overlapped.hEvent, 1000);
4410 ok(dwret == WAIT_OBJECT_0, "Waiting for accept event failed with %d + errno %d\n", dwret, GetLastError());
4412 bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
4413 ok(bret, "GetOverlappedResult failed, error %d\n", GetLastError());
4414 ok(bytesReturned == 0, "bytesReturned isn't supposed to be %d\n", bytesReturned);
4416 closesocket(acceptor);
4418 /* Test closing with pending requests */
4420 acceptor = socket(AF_INET, SOCK_STREAM, 0);
4421 if (acceptor == INVALID_SOCKET) {
4422 skip("could not create acceptor socket, error %d\n", WSAGetLastError());
4423 goto end;
4425 bret = pAcceptEx(listener, acceptor, buffer, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
4426 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
4427 &bytesReturned, &overlapped);
4428 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
4430 closesocket(acceptor);
4432 dwret = WaitForSingleObject(overlapped.hEvent, 1000);
4433 todo_wine ok(dwret == WAIT_OBJECT_0 || broken(dwret == WAIT_TIMEOUT) /* NT4/2000 */,
4434 "Waiting for accept event failed with %d + errno %d\n", dwret, GetLastError());
4436 if (dwret != WAIT_TIMEOUT) {
4437 bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
4438 ok(!bret && GetLastError() == ERROR_OPERATION_ABORTED, "GetOverlappedResult failed, error %d\n", GetLastError());
4440 else {
4441 bret = CancelIo((HANDLE) listener);
4442 ok(bret, "Failed to cancel failed test. Bailing...\n");
4443 if (!bret) return;
4444 WaitForSingleObject(overlapped.hEvent, 0);
4447 acceptor = socket(AF_INET, SOCK_STREAM, 0);
4448 if (acceptor == INVALID_SOCKET) {
4449 skip("could not create acceptor socket, error %d\n", WSAGetLastError());
4450 goto end;
4452 bret = pAcceptEx(listener, acceptor, buffer, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
4453 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
4454 &bytesReturned, &overlapped);
4455 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
4457 CancelIo((HANDLE) acceptor);
4459 dwret = WaitForSingleObject(overlapped.hEvent, 1000);
4460 ok(dwret == WAIT_TIMEOUT, "Waiting for timeout failed with %d + errno %d\n", dwret, GetLastError());
4462 closesocket(acceptor);
4464 acceptor = socket(AF_INET, SOCK_STREAM, 0);
4465 if (acceptor == INVALID_SOCKET) {
4466 skip("could not create acceptor socket, error %d\n", WSAGetLastError());
4467 goto end;
4469 bret = pAcceptEx(listener, acceptor, buffer, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16),
4470 sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
4471 &bytesReturned, &overlapped);
4472 ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
4474 closesocket(listener);
4475 listener = INVALID_SOCKET;
4477 dwret = WaitForSingleObject(overlapped.hEvent, 1000);
4478 ok(dwret == WAIT_OBJECT_0, "Waiting for accept event failed with %d + errno %d\n", dwret, GetLastError());
4480 bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
4481 ok(!bret && GetLastError() == ERROR_OPERATION_ABORTED, "GetOverlappedResult failed, error %d\n", GetLastError());
4483 end:
4484 if (overlapped.hEvent)
4485 WSACloseEvent(overlapped.hEvent);
4486 if (listener != INVALID_SOCKET)
4487 closesocket(listener);
4488 if (acceptor != INVALID_SOCKET)
4489 closesocket(acceptor);
4490 if (connector != INVALID_SOCKET)
4491 closesocket(connector);
4492 if (connector2 != INVALID_SOCKET)
4493 closesocket(connector2);
4496 static void test_getpeername(void)
4498 SOCKET sock;
4499 struct sockaddr_in sa, sa_out;
4500 int sa_len;
4501 const char buf[] = "hello world";
4502 int ret;
4504 /* Test the parameter validation order. */
4505 ret = getpeername(INVALID_SOCKET, NULL, NULL);
4506 ok(ret == SOCKET_ERROR, "Expected getpeername to return SOCKET_ERROR, got %d\n", ret);
4507 ok(WSAGetLastError() == WSAENOTSOCK,
4508 "Expected WSAGetLastError() to return WSAENOTSOCK, got %d\n", WSAGetLastError());
4510 sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
4511 ok(sock != INVALID_SOCKET, "Expected socket to return a valid socket\n");
4512 if (sock == INVALID_SOCKET)
4514 skip("Socket creation failed with %d\n", WSAGetLastError());
4515 return;
4518 ret = getpeername(sock, NULL, NULL);
4519 ok(ret == SOCKET_ERROR, "Expected getpeername to return SOCKET_ERROR, got %d\n", ret);
4520 ok(WSAGetLastError() == WSAENOTCONN ||
4521 broken(WSAGetLastError() == WSAEFAULT), /* Win9x and WinMe */
4522 "Expected WSAGetLastError() to return WSAENOTCONN, got %d\n", WSAGetLastError());
4524 memset(&sa, 0, sizeof(sa));
4525 sa.sin_family = AF_INET;
4526 sa.sin_port = htons(139);
4527 sa.sin_addr.s_addr = inet_addr("127.0.0.1");
4529 /* sendto does not change a socket's connection state. */
4530 ret = sendto(sock, buf, sizeof(buf), 0, (struct sockaddr*)&sa, sizeof(sa));
4531 ok(ret != SOCKET_ERROR,
4532 "Expected sendto to succeed, WSAGetLastError() = %d\n", WSAGetLastError());
4534 ret = getpeername(sock, NULL, NULL);
4535 ok(ret == SOCKET_ERROR, "Expected getpeername to return SOCKET_ERROR, got %d\n", ret);
4536 ok(WSAGetLastError() == WSAENOTCONN ||
4537 broken(WSAGetLastError() == WSAEFAULT), /* Win9x and WinMe */
4538 "Expected WSAGetLastError() to return WSAENOTCONN, got %d\n", WSAGetLastError());
4540 ret = connect(sock, (struct sockaddr*)&sa, sizeof(sa));
4541 ok(ret == 0,
4542 "Expected connect to succeed, WSAGetLastError() = %d\n", WSAGetLastError());
4544 ret = getpeername(sock, NULL, NULL);
4545 ok(ret == SOCKET_ERROR, "Expected getpeername to return SOCKET_ERROR, got %d\n", ret);
4546 ok(WSAGetLastError() == WSAEFAULT,
4547 "Expected WSAGetLastError() to return WSAEFAULT, got %d\n", WSAGetLastError());
4549 /* Test crashes on Wine. */
4550 if (0)
4552 ret = getpeername(sock, (void*)0xdeadbeef, (void*)0xcafebabe);
4553 ok(ret == SOCKET_ERROR, "Expected getpeername to return SOCKET_ERROR, got %d\n", ret);
4554 ok(WSAGetLastError() == WSAEFAULT,
4555 "Expected WSAGetLastError() to return WSAEFAULT, got %d\n", WSAGetLastError());
4558 sa_len = 0;
4559 ret = getpeername(sock, (struct sockaddr*)&sa_out, &sa_len);
4560 ok(ret == SOCKET_ERROR, "Expected getpeername to return 0, got %d\n", ret);
4561 ok(WSAGetLastError() == WSAEFAULT,
4562 "Expected WSAGetLastError() to return WSAEFAULT, got %d\n", WSAGetLastError());
4564 sa_len = sizeof(sa_out);
4565 ret = getpeername(sock, (struct sockaddr*)&sa_out, &sa_len);
4566 ok(ret == 0, "Expected getpeername to return 0, got %d\n", ret);
4567 ok(!memcmp(&sa, &sa_out, sizeof(sa)),
4568 "Expected the returned structure to be identical to the connect structure\n");
4570 closesocket(sock);
4573 static void test_sioRoutingInterfaceQuery(void)
4575 int ret;
4576 SOCKET sock;
4577 SOCKADDR_IN sin = { 0 }, sout = { 0 };
4578 DWORD bytesReturned;
4580 sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
4581 ok(sock != INVALID_SOCKET, "Expected socket to return a valid socket\n");
4582 if (sock == INVALID_SOCKET)
4584 skip("Socket creation failed with %d\n", WSAGetLastError());
4585 return;
4587 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, NULL, 0, NULL, 0, NULL,
4588 NULL, NULL);
4589 ok(ret == SOCKET_ERROR && WSAGetLastError() == WSAEFAULT,
4590 "expected WSAEFAULT, got %d\n", WSAGetLastError());
4591 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &sin, sizeof(sin),
4592 NULL, 0, NULL, NULL, NULL);
4593 ok(ret == SOCKET_ERROR && WSAGetLastError() == WSAEFAULT,
4594 "expected WSAEFAULT, got %d\n", WSAGetLastError());
4595 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &sin, sizeof(sin),
4596 NULL, 0, &bytesReturned, NULL, NULL);
4597 ok(ret == SOCKET_ERROR &&
4598 (WSAGetLastError() == WSAEFAULT /* Win98 */ ||
4599 WSAGetLastError() == WSAEINVAL /* NT4 */||
4600 WSAGetLastError() == WSAEAFNOSUPPORT),
4601 "expected WSAEFAULT or WSAEINVAL or WSAEAFNOSUPPORT, got %d\n",
4602 WSAGetLastError());
4603 sin.sin_family = AF_INET;
4604 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &sin, sizeof(sin),
4605 NULL, 0, &bytesReturned, NULL, NULL);
4606 ok(ret == SOCKET_ERROR &&
4607 (WSAGetLastError() == WSAEFAULT /* Win98 */ ||
4608 WSAGetLastError() == WSAEINVAL),
4609 "expected WSAEFAULT or WSAEINVAL, got %d\n", WSAGetLastError());
4610 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
4611 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &sin, sizeof(sin),
4612 NULL, 0, &bytesReturned, NULL, NULL);
4613 ok(ret == SOCKET_ERROR &&
4614 (WSAGetLastError() == WSAEINVAL /* NT4 */ ||
4615 WSAGetLastError() == WSAEFAULT),
4616 "expected WSAEINVAL or WSAEFAULT, got %d\n", WSAGetLastError());
4617 ret = WSAIoctl(sock, SIO_ROUTING_INTERFACE_QUERY, &sin, sizeof(sin),
4618 &sout, sizeof(sout), &bytesReturned, NULL, NULL);
4619 ok(!ret || broken(WSAGetLastError() == WSAEINVAL /* NT4 */),
4620 "WSAIoctl failed: %d\n", WSAGetLastError());
4621 if (!ret)
4623 ok(sout.sin_family == AF_INET, "expected AF_INET, got %d\n",
4624 sout.sin_family);
4625 /* We expect the source address to be INADDR_LOOPBACK as well, but
4626 * there's no guarantee that a route to the loopback address exists,
4627 * so rather than introduce spurious test failures we do not test the
4628 * source address.
4631 closesocket(sock);
4634 static void test_synchronous_WSAIoctl(void)
4636 HANDLE previous_port, io_port;
4637 WSAOVERLAPPED overlapped, *olp;
4638 SOCKET socket;
4639 ULONG on;
4640 ULONG_PTR key;
4641 DWORD num_bytes;
4642 BOOL ret;
4643 int res;
4645 previous_port = CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, 0, 0 );
4646 ok( previous_port != NULL, "failed to create completion port %u\n", GetLastError() );
4648 socket = WSASocketW( AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED );
4649 ok( socket != INVALID_SOCKET, "failed to create socket %d\n", WSAGetLastError() );
4651 io_port = CreateIoCompletionPort( (HANDLE)socket, previous_port, 0, 0 );
4652 ok( io_port != NULL, "failed to create completion port %u\n", GetLastError() );
4654 on = 1;
4655 memset( &overlapped, 0, sizeof(overlapped) );
4656 res = WSAIoctl( socket, FIONBIO, &on, sizeof(on), NULL, 0, &num_bytes, &overlapped, NULL );
4657 ok( !res, "WSAIoctl failed %d\n", WSAGetLastError() );
4659 ret = GetQueuedCompletionStatus( io_port, &num_bytes, &key, &olp, 10000 );
4660 ok( ret, "failed to get completion status %u\n", GetLastError() );
4662 CloseHandle( io_port );
4663 closesocket( socket );
4664 CloseHandle( previous_port );
4667 /**************** Main program ***************/
4669 START_TEST( sock )
4671 int i;
4673 /* Leave these tests at the beginning. They depend on WSAStartup not having been
4674 * called, which is done by Init() below. */
4675 test_WithoutWSAStartup();
4676 test_WithWSAStartup();
4678 Init();
4680 test_set_getsockopt();
4681 test_so_reuseaddr();
4682 test_ip_pktinfo();
4683 test_extendedSocketOptions();
4685 for (i = 0; i < NUM_TESTS; i++)
4687 trace ( " **** STARTING TEST %d ****\n", i );
4688 do_test ( &tests[i] );
4689 trace ( " **** TEST %d COMPLETE ****\n", i );
4692 test_UDP();
4694 test_getservbyname();
4695 test_WSASocket();
4697 test_WSAAddressToStringA();
4698 test_WSAAddressToStringW();
4700 test_WSAStringToAddressA();
4701 test_WSAStringToAddressW();
4703 test_select();
4704 test_accept();
4705 test_getpeername();
4706 test_getsockname();
4707 test_inet_addr();
4708 test_addr_to_print();
4709 test_ioctlsocket();
4710 test_dns();
4711 test_gethostbyname_hack();
4713 test_WSASendTo();
4714 test_WSARecv();
4716 test_events(0);
4717 test_events(1);
4719 test_ipv6only();
4720 test_GetAddrInfoW();
4722 test_AcceptEx();
4723 test_ConnectEx();
4725 test_sioRoutingInterfaceQuery();
4727 /* this is a io heavy test, do it at the end so the kernel doesn't start dropping packets */
4728 test_send();
4729 test_synchronous_WSAIoctl();
4731 Exit();