1 cs130_ryutaro 1.1 /*
2 * Unit test suite for winsock functions
3 *
4 * Copyright 2002 Martin Wilck
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include <stdarg.h>
22 cs130_ryutaro 1.1
23 #include <windef.h>
24 #include <winbase.h>
25 #include <winsock2.h>
26 #include <mswsock.h>
27 #include "wine/test.h"
28 #include <winnt.h>
29 #include <winerror.h>
30
31 #define MAX_CLIENTS 4 /* Max number of clients */
32 #define NUM_TESTS 3 /* Number of tests performed */
33 #define FIRST_CHAR 'A' /* First character in transferred pattern */
34 #define BIND_SLEEP 10 /* seconds to wait between attempts to bind() */
35 #define BIND_TRIES 6 /* Number of bind() attempts */
36 #define TEST_TIMEOUT 30 /* seconds to wait before killing child threads
37 after server initialization, if something hangs */
38 #define ASYNC_EVENT (WM_USER +5) /* the message we'll use for our async notification */
39
40 #define wsa_ok(op, cond, msg) \
41 do { \
42 int tmp, err = 0; \
43 cs130_ryutaro 1.1 tmp = op; \
44 if ( !(cond tmp) ) err = WSAGetLastError(); \
45 ok ( cond tmp, msg, GetCurrentThreadId(), err); \
46 } while (0);
47
48
49 /**************** Structs and typedefs ***************/
50
51 typedef struct thread_info
52 {
53 HANDLE thread;
54 DWORD id;
55 } thread_info;
56
57 /* Information in the server about open client connections */
58 typedef struct sock_info
59 {
60 SOCKET s;
61 struct sockaddr_in addr;
62 struct sockaddr_in peer;
63 char *buf;
64 cs130_ryutaro 1.1 int nread;
65 } sock_info;
66
67 /* Test parameters for both server & client */
68 typedef struct test_params
69 {
70 int sock_type;
71 int sock_prot;
72 const char *inet_addr;
73 short inet_port;
74 int chunk_size;
75 int n_chunks;
76 int n_clients;
77 } test_params;
78
79 /* server-specific test parameters */
80 typedef struct server_params
81 {
82 test_params *general;
83 DWORD sock_flags;
84 int buflen;
85 cs130_ryutaro 1.1 } server_params;
86
87 /* client-specific test parameters */
88 typedef struct client_params
89 {
90 test_params *general;
91 DWORD sock_flags;
92 int buflen;
93 } client_params;
94
95 /* This type combines all information for setting up a test scenario */
96 typedef struct test_setup
97 {
98 test_params general;
99 LPVOID srv;
100 server_params srv_params;
101 LPVOID clt;
102 client_params clt_params;
103 } test_setup;
104
105 /* Thread local storage for server */
106 cs130_ryutaro 1.1 typedef struct server_memory
107 {
108 SOCKET s;
109 struct sockaddr_in addr;
110 sock_info sock[MAX_CLIENTS];
111 } server_memory;
112
113 /* Thread local storage for client */
114 typedef struct client_memory
115 {
116 SOCKET s;
117 struct sockaddr_in addr;
118 char *send_buf;
119 char *recv_buf;
120 } client_memory;
121
122 /* Things specific to async tests */
123 typedef struct async_param_t
124 {
125 server_params *svc_params;
126 int numClients;
127 cs130_ryutaro 1.1 char *fileBuf;
128 } async_param_t;
129
130 /**************** Static variables ***************/
131
132 static DWORD tls; /* Thread local storage index */
133 static HANDLE thread[1+MAX_CLIENTS];
134 static DWORD thread_id[1+MAX_CLIENTS];
135 static HANDLE server_ready;
136 static HANDLE client_ready[MAX_CLIENTS];
137 static int client_id;
138 static async_param_t async_params; /* async structure */
139
140 /**************** General utility functions ***************/
141
142 static void set_so_opentype ( BOOL overlapped )
143 {
144 int optval = !overlapped, newval, len = sizeof (int);
145
146 ok ( setsockopt ( INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE,
147 (LPVOID) &optval, sizeof (optval) ) == 0,
148 cs130_ryutaro 1.1 "setting SO_OPENTYPE failed\n" );
149 ok ( getsockopt ( INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE,
150 (LPVOID) &newval, &len ) == 0,
151 "getting SO_OPENTYPE failed\n" );
152 ok ( optval == newval, "failed to set SO_OPENTYPE\n" );
153 }
154
155 static int set_blocking ( SOCKET s, BOOL blocking )
156 {
157 u_long val = !blocking;
158 return ioctlsocket ( s, FIONBIO, &val );
159 }
160
161 static void fill_buffer ( char *buf, int chunk_size, int n_chunks )
162 {
163 char c, *p;
164 for ( c = FIRST_CHAR, p = buf; c < FIRST_CHAR + n_chunks; c++, p += chunk_size )
165 memset ( p, c, chunk_size );
166 }
167
168 static char* test_buffer ( char *buf, int chunk_size, int n_chunks )
169 cs130_ryutaro 1.1 {
170 char c, *p;
171 int i;
172 for ( c = FIRST_CHAR, p = buf; c < FIRST_CHAR + n_chunks; c++, p += chunk_size )
173 {
174 for ( i = 0; i < chunk_size; i++ )
175 if ( p[i] != c ) return p + i;
176 }
177 return NULL;
178 }
179
180 /*
181 * This routine is called when a client / server does not expect any more data,
182 * but needs to acknowedge the closing of the connection (by reasing 0 bytes).
183 */
184 static void read_zero_bytes ( SOCKET s )
185 {
186 char buf[256];
187 int tmp, n = 0;
188 while ( ( tmp = recv ( s, buf, 256, 0 ) ) > 0 )
189 n += tmp;
190 cs130_ryutaro 1.1 ok ( n <= 0, "garbage data received: %d bytes\n", n );
191 }
192
193 static int do_synchronous_send ( SOCKET s, char *buf, int buflen, int sendlen )
194 {
195 char* last = buf + buflen, *p;
196 int n = 1;
197 for ( p = buf; n > 0 && p < last; p += n )
198 n = send ( s, p, min ( sendlen, last - p ), 0 );
199 wsa_ok ( n, 0 <=, "do_synchronous_send (%lx): error %d\n" );
200 return p - buf;
201 }
202
203 static int do_synchronous_recv ( SOCKET s, char *buf, int buflen, int recvlen )
204 {
205 char* last = buf + buflen, *p;
206 int n = 1;
207 for ( p = buf; n > 0 && p < last; p += n )
208 n = recv ( s, p, min ( recvlen, last - p ), 0 );
209 wsa_ok ( n, 0 <=, "do_synchronous_recv (%lx): error %d:\n" );
210 return p - buf;
211 cs130_ryutaro 1.1 }
212
213 /*
214 * Call this routine right after thread startup.
215 * SO_OPENTYPE must by 0, regardless what the server did.
216 */
217 static void check_so_opentype (void)
218 {
219 int tmp = 1, len;
220 len = sizeof (tmp);
221 getsockopt ( INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (LPVOID) &tmp, &len );
222 ok ( tmp == 0, "check_so_opentype: wrong startup value of SO_OPENTYPE: %d\n", tmp );
223 }
224
225 /**************** Server utility functions ***************/
226
227 /*
228 * Even if we have closed our server socket cleanly,
229 * the OS may mark the address "in use" for some time -
230 * this happens with native Linux apps, too.
231 */
232 cs130_ryutaro 1.1 static void do_bind ( SOCKET s, struct sockaddr* addr, int addrlen )
233 {
234 int err, wsaerr = 0, n_try = BIND_TRIES;
235
236 while ( ( err = bind ( s, addr, addrlen ) ) != 0 &&
237 ( wsaerr = WSAGetLastError () ) == WSAEADDRINUSE &&
238 n_try-- >= 0)
239 {
240 trace ( "address in use, waiting ...\n" );
241 Sleep ( 1000 * BIND_SLEEP );
242 }
243 ok ( err == 0, "failed to bind: %d\n", wsaerr );
244 }
245
246 static void server_start ( server_params *par )
247 {
248 int i;
249 test_params *gen = par->general;
250 server_memory *mem = (LPVOID) LocalAlloc ( LPTR, sizeof (server_memory));
251
252 TlsSetValue ( tls, mem );
253 cs130_ryutaro 1.1 mem->s = WSASocketA ( AF_INET, gen->sock_type, gen->sock_prot,
254 NULL, 0, par->sock_flags );
255 ok ( mem->s != INVALID_SOCKET, "Server: WSASocket failed\n" );
256
257 mem->addr.sin_family = AF_INET;
258 mem->addr.sin_addr.s_addr = inet_addr ( gen->inet_addr );
259 mem->addr.sin_port = htons ( gen->inet_port );
260
261 for (i = 0; i < MAX_CLIENTS; i++)
262 {
263 mem->sock[i].s = INVALID_SOCKET;
264 mem->sock[i].buf = (LPVOID) LocalAlloc ( LPTR, gen->n_chunks * gen->chunk_size );
265 mem->sock[i].nread = 0;
266 }
267
268 if ( gen->sock_type == SOCK_STREAM )
269 do_bind ( mem->s, (struct sockaddr*) &mem->addr, sizeof (mem->addr) );
270 }
271
272 static void server_stop (void)
273 {
274 cs130_ryutaro 1.1 int i;
275 server_memory *mem = TlsGetValue ( tls );
276 for (i = 0; i < MAX_CLIENTS; i++ )
277 {
278 LocalFree ( (HANDLE) mem->sock[i].buf );
279 if ( mem->sock[i].s != INVALID_SOCKET )
280 closesocket ( mem->sock[i].s );
281 }
282 ok ( closesocket ( mem->s ) == 0, "closesocket failed\n" );
283 LocalFree ( (HANDLE) mem );
284 ExitThread ( GetCurrentThreadId () );
285 }
286
287 /**************** Client utilitiy functions ***************/
288
289 static void client_start ( client_params *par )
290 {
291 test_params *gen = par->general;
292 client_memory *mem = (LPVOID) LocalAlloc (LPTR, sizeof (client_memory));
293
294 TlsSetValue ( tls, mem );
295 cs130_ryutaro 1.1
296 WaitForSingleObject ( server_ready, INFINITE );
297
298 mem->s = WSASocketA ( AF_INET, gen->sock_type, gen->sock_prot,
299 NULL, 0, par->sock_flags );
300
301 mem->addr.sin_family = AF_INET;
302 mem->addr.sin_addr.s_addr = inet_addr ( gen->inet_addr );
303 mem->addr.sin_port = htons ( gen->inet_port );
304
305 ok ( mem->s != INVALID_SOCKET, "Client: WSASocket failed\n" );
306
307 mem->send_buf = (LPVOID) LocalAlloc ( LPTR, 2 * gen->n_chunks * gen->chunk_size );
308 mem->recv_buf = mem->send_buf + gen->n_chunks * gen->chunk_size;
309 fill_buffer ( mem->send_buf, gen->chunk_size, gen->n_chunks );
310
311 SetEvent ( client_ready[client_id] );
312 /* Wait for the other clients to come up */
313 WaitForMultipleObjects ( min ( gen->n_clients, MAX_CLIENTS ), client_ready, TRUE, INFINITE );
314 }
315
316 cs130_ryutaro 1.1 static void client_stop (void)
317 {
318 client_memory *mem = TlsGetValue ( tls );
319 wsa_ok ( closesocket ( mem->s ), 0 ==, "closesocket error (%lx): %d\n" );
320 LocalFree ( (HANDLE) mem->send_buf );
321 LocalFree ( (HANDLE) mem );
322 ExitThread(0);
323 }
324
325 /**************** Servers ***************/
326
327 /*
328 * simple_server: A very basic server doing synchronous IO.
329 */
330 static VOID WINAPI simple_server ( server_params *par )
331 {
332 test_params *gen = par->general;
333 server_memory *mem;
334 int n_recvd, n_sent, n_expected = gen->n_chunks * gen->chunk_size, tmp, i,
335 id = GetCurrentThreadId();
336 char *p;
337 cs130_ryutaro 1.1
338 trace ( "simple_server (%x) starting\n", id );
339
340 set_so_opentype ( FALSE ); /* non-overlapped */
341 server_start ( par );
342 mem = TlsGetValue ( tls );
343
344 wsa_ok ( set_blocking ( mem->s, TRUE ), 0 ==, "simple_server (%lx): failed to set blocking mode: %d\n");
345 wsa_ok ( listen ( mem->s, SOMAXCONN ), 0 ==, "simple_server (%lx): listen failed: %d\n");
346
347 trace ( "simple_server (%x) ready\n", id );
348 SetEvent ( server_ready ); /* notify clients */
349
350 for ( i = 0; i < min ( gen->n_clients, MAX_CLIENTS ); i++ )
351 {
352 trace ( "simple_server (%x): waiting for client\n", id );
353
354 /* accept a single connection */
355 tmp = sizeof ( mem->sock[0].peer );
356 mem->sock[0].s = accept ( mem->s, (struct sockaddr*) &mem->sock[0].peer, &tmp );
357 wsa_ok ( mem->sock[0].s, INVALID_SOCKET !=, "simple_server (%lx): accept failed: %d\n" );
358 cs130_ryutaro 1.1
359 ok ( mem->sock[0].peer.sin_addr.s_addr == inet_addr ( gen->inet_addr ),
360 "simple_server (%x): strange peer address\n", id );
361
362 /* Receive data & check it */
363 n_recvd = do_synchronous_recv ( mem->sock[0].s, mem->sock[0].buf, n_expected, par->buflen );
364 ok ( n_recvd == n_expected,
365 "simple_server (%x): received less data than expected: %d of %d\n", id, n_recvd, n_expected );
366 p = test_buffer ( mem->sock[0].buf, gen->chunk_size, gen->n_chunks );
367 ok ( p == NULL, "simple_server (%x): test pattern error: %d\n", id, p - mem->sock[0].buf);
368
369 /* Echo data back */
370 n_sent = do_synchronous_send ( mem->sock[0].s, mem->sock[0].buf, n_expected, par->buflen );
371 ok ( n_sent == n_expected,
372 "simple_server (%x): sent less data than expected: %d of %d\n", id, n_sent, n_expected );
373
374 /* cleanup */
375 read_zero_bytes ( mem->sock[0].s );
376 wsa_ok ( closesocket ( mem->sock[0].s ), 0 ==, "simple_server (%lx): closesocket error: %d\n" );
377 mem->sock[0].s = INVALID_SOCKET;
378 }
379 cs130_ryutaro 1.1
380 trace ( "simple_server (%x) exiting\n", id );
381 server_stop ();
382 }
383
384 /*
385 Call back event handler for asynchronous server
386 */
387 static LRESULT CALLBACK async_server_proc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
388 {
389 SOCKET socket = (SOCKET) wParam;
390 server_memory* mem = TlsGetValue( tls );
391 struct sockaddr_in peer;
392 char *file_buf = async_params.fileBuf;
393 char *inetAddr = (char*)((async_params.svc_params)->general)->inet_addr;
394 int n_recvd, n_sent, addrLen, id = GetCurrentThreadId();
395 int eventCode, packet_len = (async_params.svc_params)->buflen;;
396
397 switch( msg ){
398
399 case ASYNC_EVENT:
400 cs130_ryutaro 1.1
401 eventCode = WSAGETSELECTEVENT( lParam );
402 switch( eventCode ){
403
404 case FD_ACCEPT:
405
406 // accept connection
407 trace( "async_server (%x): accept event\n", id );
408 addrLen = sizeof ( peer );
409 socket = accept( mem->s, (struct sockaddr*) &peer, &addrLen );
410 wsa_ok( socket, INVALID_SOCKET !=, "async_server (%lx): accept failed: %d\n" );
411
412 if( socket == INVALID_SOCKET ){
413
414 trace( "async_server (%x): exiting\n", id );
415 server_stop();
416
417 }
418
419 ok( peer.sin_addr.s_addr == inet_addr ( inetAddr ),
420 "async_server (%x): strange peer address\n", id );
421 cs130_ryutaro 1.1 break;
422
423 case FD_READ:
424
425 // server has data waiting to be read
426 n_recvd = recv( socket, file_buf, packet_len, 0 );
427 wsa_ok( n_recvd, SOCKET_ERROR !=, "recv (%lx): error %d:\n" );
428
429 if( n_recvd == SOCKET_ERROR ){
430
431 trace( "async_server (%x) exiting\n", id );
432 server_stop();
433
434 }
435
436 // Send the packet back
437 n_sent = send( socket, file_buf, n_recvd, 0 );
|
454 cs130_ryutaro 1.1
455 if( --async_params.numClients == 0 ){
456
457 trace( "async_server (%x) exiting\n", id );
458 server_stop();
459
460 }
461 }
462 }
463
464 return DefWindowProc( hWnd, msg, wParam, lParam );
465 }
466
467 /*
468 * async_server: An event-driven server
469 */
470 static void WINAPI async_server( server_params *par )
471 {
472 int id = GetCurrentThreadId(), err;
473 test_params* gen = par->general;
474
475 cs130_ryutaro 1.1 // set up async_params structure
476 memset( &async_params, 0, sizeof( async_params ) );
477 async_params.svc_params = par;
478 async_params.numClients = gen->n_clients;
479 async_params.fileBuf = (LPVOID) LocalAlloc( LPTR, gen->n_chunks * gen->chunk_size );
480
481 trace( "async_server (%x) starting\n", id );
482 set_so_opentype( FALSE ); /* non-overlapped */
483 server_start( par );
484 server_memory *mem = TlsGetValue( tls );
485
486 wsa_ok( listen ( mem->s, SOMAXCONN ), 0 ==, "async_server (%lx): listen failed: %d\n");
487
488 // Get the current instance
489 HINSTANCE instance = GetModuleHandle( NULL );
490 if( instance == NULL ){
491
492 trace( "async_server (%x) exiting\n", id );
493 server_stop();
494
495 }
496 cs130_ryutaro 1.1
497 // Create a hiddent window to handle async events
498 WNDCLASS windowClass;
499 windowClass.lpszClassName = "Hidden_Winsock_Window";
500 windowClass.style = CS_HREDRAW | CS_VREDRAW;
501 windowClass.lpfnWndProc = async_server_proc;
502 windowClass.cbClsExtra = 0;
503 windowClass.cbWndExtra = 0;
504 windowClass.hInstance = instance;
505 windowClass.hIcon = NULL;
506 windowClass.hCursor = NULL;
507 windowClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
508 windowClass.lpszMenuName = NULL;
509 ATOM classAtom = RegisterClass( &windowClass );
510 if( classAtom == 0 ){
511
512 trace( "async_server (%x) exiting\n", id );
513 server_stop();
514
515 }
516
517 cs130_ryutaro 1.1 HWND hwnd = CreateWindow( "Hidden_Winsock_Window",
518 "Winsock Window",
519 WS_OVERLAPPEDWINDOW,
520 CW_USEDEFAULT,
521 CW_USEDEFAULT,
522 CW_USEDEFAULT,
523 CW_USEDEFAULT,
524 NULL,
525 NULL,
526 instance,
527 NULL );
528
529 if( hwnd == NULL ){
530
531 trace ( "async_server (%x) exiting\n", id );
532 server_stop();
533
534 }
535
536 /* make the socket asynchronous */
537 err = WSAAsyncSelect( mem->s, hwnd, ASYNC_EVENT, FD_ACCEPT | FD_READ | FD_CLOSE );
538 cs130_ryutaro 1.1 wsa_ok( err, SOCKET_ERROR !=, "async_server (%lx): WSAAsyncSelect failed: %d\n" );
539 if( err == SOCKET_ERROR ){
540
541 trace( "async_server (%x) exiting\n", id );
542 server_stop();
543
544 }
545
546 trace( "async_server (%x) ready\n", id );
547 SetEvent( server_ready ); /* notify clients */
548
549 /* Wait for any event and process it when it occurs */
550 BOOL retVal;
551 MSG msg;
552 while( ( retVal = GetMessage( &msg, NULL, 0, 0 ) ) != 0 ){
553
554 if( retVal == -1 ){
555
556 // error: exit
557 trace( "async_server (%x) exiting\n", id );
558 server_stop();
559 cs130_ryutaro 1.1
560 }
561
562 // Translate and dispatch the message
563 TranslateMessage( &msg );
564 DispatchMessage( &msg );
565
566 }
567 }
568
569 /**************** Clients ***************/
570
571 /*
572 * simple_client: A very basic client doing synchronous IO.
573 */
574 static VOID WINAPI simple_client ( client_params *par )
575 {
576 test_params *gen = par->general;
577 client_memory *mem;
578 int n_sent, n_recvd, n_expected = gen->n_chunks * gen->chunk_size, id;
579 char *p;
580 cs130_ryutaro 1.1
581 id = GetCurrentThreadId();
582 trace ( "simple_client (%x): starting\n", id );
583 /* wait here because we want to call set_so_opentype before creating a socket */
584 WaitForSingleObject ( server_ready, INFINITE );
585 trace ( "simple_client (%x): server ready\n", id );
586
587 check_so_opentype ();
588 set_so_opentype ( FALSE ); /* non-overlapped */
589 client_start ( par );
590 mem = TlsGetValue ( tls );
591
592 /* Connect */
593 wsa_ok ( connect ( mem->s, (struct sockaddr*) &mem->addr, sizeof ( mem->addr ) ),
594 0 ==, "simple_client (%lx): connect error: %d\n" );
595 ok ( set_blocking ( mem->s, TRUE ) == 0,
596 "simple_client (%x): failed to set blocking mode\n", id );
597 trace ( "simple_client (%x) connected\n", id );
598
599 /* send data to server */
600 n_sent = do_synchronous_send ( mem->s, mem->send_buf, n_expected, par->buflen );
601 cs130_ryutaro 1.1 ok ( n_sent == n_expected,
602 "simple_client (%x): sent less data than expected: %d of %d\n", id, n_sent, n_expected );
603
604 /* shutdown send direction */
605 wsa_ok ( shutdown ( mem->s, SD_SEND ), 0 ==, "simple_client (%lx): shutdown failed: %d\n" );
606
607 /* Receive data echoed back & check it */
608 n_recvd = do_synchronous_recv ( mem->s, mem->recv_buf, n_expected, par->buflen );
609 ok ( n_recvd == n_expected,
610 "simple_client (%x): received less data than expected: %d of %d\n", id, n_recvd, n_expected );
611
612 /* check data */
613 p = test_buffer ( mem->recv_buf, gen->chunk_size, gen->n_chunks );
614 ok ( p == NULL, "simple_client (%x): test pattern error: %d\n", id, p - mem->recv_buf);
615
616 /* cleanup */
617 read_zero_bytes ( mem->s );
618 trace ( "simple_client (%x) exiting\n", id );
619 client_stop ();
620 }
621
622 cs130_ryutaro 1.1 /*
623 * event_client: An event-driven client
624 */
625 static void WINAPI event_client ( client_params *par )
626 {
627 test_params *gen = par->general;
628 client_memory *mem;
629 int id = GetCurrentThreadId(), n_expected = gen->n_chunks * gen->chunk_size,
630 tmp, err, n;
631 HANDLE event;
632 WSANETWORKEVENTS wsa_events;
633 char *send_last, *recv_last, *send_p, *recv_p;
634 long mask = FD_READ | FD_WRITE | FD_CLOSE;
635
636 trace ( "event_client (%x): starting\n", id );
637 client_start ( par );
638 trace ( "event_client (%x): server ready\n", id );
639
640 mem = TlsGetValue ( tls );
641
642 /* Prepare event notification for connect, makes socket nonblocking */
643 cs130_ryutaro 1.1 event = WSACreateEvent ();
644 WSAEventSelect ( mem->s, event, FD_CONNECT );
645 tmp = connect ( mem->s, (struct sockaddr*) &mem->addr, sizeof ( mem->addr ) );
646 if ( tmp != 0 && ( err = WSAGetLastError () ) != WSAEWOULDBLOCK )
647 ok ( 0, "event_client (%x): connect error: %d\n", id, err );
648
649 tmp = WaitForSingleObject ( event, INFINITE );
650 ok ( tmp == WAIT_OBJECT_0, "event_client (%x): wait for connect event failed: %d\n", id, tmp );
651 err = WSAEnumNetworkEvents ( mem->s, event, &wsa_events );
652 wsa_ok ( err, 0 ==, "event_client (%lx): WSAEnumNetworkEvents error: %d\n" );
653
654 err = wsa_events.iErrorCode[ FD_CONNECT_BIT ];
655 ok ( err == 0, "event_client (%x): connect error: %d\n", id, err );
656 if ( err ) goto out;
657
658 trace ( "event_client (%x) connected\n", id );
659
660 WSAEventSelect ( mem->s, event, mask );
661
662 recv_p = mem->recv_buf;
663 recv_last = mem->recv_buf + n_expected;
664 cs130_ryutaro 1.1 send_p = mem->send_buf;
665 send_last = mem->send_buf + n_expected;
666
667 while ( TRUE )
668 {
669 err = WaitForSingleObject ( event, INFINITE );
670 ok ( err == WAIT_OBJECT_0, "event_client (%x): wait failed\n", id );
671
672 err = WSAEnumNetworkEvents ( mem->s, event, &wsa_events );
673 wsa_ok ( err, 0 ==, "event_client (%lx): WSAEnumNetworkEvents error: %d\n" );
674
675 if ( wsa_events.lNetworkEvents & FD_WRITE )
676 {
677 err = wsa_events.iErrorCode[ FD_WRITE_BIT ];
678 ok ( err == 0, "event_client (%x): FD_WRITE error code: %d\n", id, err );
679
680 if ( err== 0 )
681 do
682 {
683 n = send ( mem->s, send_p, min ( send_last - send_p, par->buflen ), 0 );
684 if ( n < 0 )
685 cs130_ryutaro 1.1 {
686 err = WSAGetLastError ();
687 ok ( err == WSAEWOULDBLOCK, "event_client (%x): send error: %d\n", id, err );
688 }
689 else
690 send_p += n;
691 }
692 while ( n >= 0 && send_p < send_last );
693
694 if ( send_p == send_last )
695 {
696 trace ( "event_client (%x): all data sent - shutdown\n", id );
697 shutdown ( mem->s, SD_SEND );
698 mask &= ~FD_WRITE;
699 WSAEventSelect ( mem->s, event, mask );
700 }
701 }
702 if ( wsa_events.lNetworkEvents & FD_READ )
703 {
704 err = wsa_events.iErrorCode[ FD_READ_BIT ];
705 ok ( err == 0, "event_client (%x): FD_READ error code: %d\n", id, err );
706 cs130_ryutaro 1.1 if ( err != 0 ) break;
707
708 /* First read must succeed */
709 n = recv ( mem->s, recv_p, min ( recv_last - recv_p, par->buflen ), 0 );
710 wsa_ok ( n, 0 <=, "event_client (%lx): recv error: %d\n" );
711
712 while ( n >= 0 ) {
713 recv_p += n;
714 if ( recv_p == recv_last )
715 {
716 mask &= ~FD_READ;
717 trace ( "event_client (%x): all data received\n", id );
718 WSAEventSelect ( mem->s, event, mask );
719 break;
720 }
721 n = recv ( mem->s, recv_p, min ( recv_last - recv_p, par->buflen ), 0 );
722 if ( n < 0 && ( err = WSAGetLastError()) != WSAEWOULDBLOCK )
723 ok ( 0, "event_client (%x): read error: %d\n", id, err );
724
725 }
726 }
727 cs130_ryutaro 1.1 if ( wsa_events.lNetworkEvents & FD_CLOSE )
728 {
729 trace ( "event_client (%x): close event\n", id );
730 err = wsa_events.iErrorCode[ FD_CLOSE_BIT ];
731 ok ( err == 0, "event_client (%x): FD_CLOSE error code: %d\n", id, err );
732 break;
733 }
734 }
735
736 ok ( send_p == send_last,
737 "simple_client (%x): sent less data than expected: %d of %d\n",
738 id, send_p - mem->send_buf, n_expected );
739 ok ( recv_p == recv_last,
740 "simple_client (%x): received less data than expected: %d of %d\n",
741 id, recv_p - mem->recv_buf, n_expected );
742 recv_p = test_buffer ( mem->recv_buf, gen->chunk_size, gen->n_chunks );
743 ok ( recv_p == NULL, "event_client (%x): test pattern error: %d\n", id, recv_p - mem->recv_buf);
744
745 out:
746 WSACloseEvent ( event );
747 trace ( "event_client (%x) exiting\n", id );
748 cs130_ryutaro 1.1 client_stop ();
749 }
750
751 /**************** Main program utility functions ***************/
752
753 static void Init (void)
754 {
755 WORD ver = MAKEWORD (2, 2);
756 WSADATA data;
757
758 ok ( WSAStartup ( ver, &data ) == 0, "WSAStartup failed\n" );
759 tls = TlsAlloc();
760 }
761
762 static void Exit (void)
763 {
764 TlsFree ( tls );
765 ok ( WSACleanup() == 0, "WSACleanup failed\n" );
766 }
767
768 static void StartServer (LPTHREAD_START_ROUTINE routine,
769 cs130_ryutaro 1.1 test_params *general, server_params *par)
770 {
771 par->general = general;
772 thread[0] = CreateThread ( NULL, 0, routine, par, 0, &thread_id[0] );
773 ok ( thread[0] != NULL, "Failed to create server thread\n" );
774 }
775
776 static void StartClients (LPTHREAD_START_ROUTINE routine,
777 test_params *general, client_params *par)
778 {
779 int i;
780 par->general = general;
781 for ( i = 1; i <= min ( general->n_clients, MAX_CLIENTS ); i++ )
782 {
783 client_id = i - 1;
784 thread[i] = CreateThread ( NULL, 0, routine, par, 0, &thread_id[i] );
785 ok ( thread[i] != NULL, "Failed to create client thread\n" );
786 /* Make sure the client is up and running */
787 WaitForSingleObject ( client_ready[client_id], INFINITE );
788 };
789 }
790 cs130_ryutaro 1.1
791 static void do_test( test_setup *test )
792 {
793 DWORD i, n = min (test->general.n_clients, MAX_CLIENTS);
794 DWORD wait;
795
796 server_ready = CreateEventW ( NULL, TRUE, FALSE, NULL );
797 for (i = 0; i <= n; i++)
798 client_ready[i] = CreateEventW ( NULL, TRUE, FALSE, NULL );
799
800 StartServer ( test->srv, &test->general, &test->srv_params );
801 StartClients ( test->clt, &test->general, &test->clt_params );
802 WaitForSingleObject ( server_ready, INFINITE );
803
804 wait = WaitForMultipleObjects ( 1 + n, thread, TRUE, 1000 * TEST_TIMEOUT );
805 ok ( wait >= WAIT_OBJECT_0 && wait <= WAIT_OBJECT_0 + n ,
806 "some threads have not completed: %lx\n", wait );
807
808 if ( ! ( wait >= WAIT_OBJECT_0 && wait <= WAIT_OBJECT_0 + n ) )
809 {
810 for (i = 0; i <= n; i++)
811 cs130_ryutaro 1.1 {
812 trace ("terminating thread %08lx\n", thread_id[i]);
813 if ( WaitForSingleObject ( thread[i], 0 ) != WAIT_OBJECT_0 )
814 TerminateThread ( thread [i], 0 );
815 }
816 }
817 CloseHandle ( server_ready );
818 for (i = 0; i <= n; i++)
819 CloseHandle ( client_ready[i] );
820 }
821
822 /********* some tests for getsockopt(setsockopt(X)) == X ***********/
823 /* optname = SO_LINGER */
824 LINGER linger_testvals[] = {
825 {0,0},
826 {0,73},
827 {1,0},
828 {5,189}
829 };
830
831 /* optname = SO_RCVTIMEO, SOSNDTIMEO */
832 cs130_ryutaro 1.1 #define SOCKTIMEOUT1 63000 /* 63 seconds. Do not test fractional part because of a
833 bug in the linux kernel (fixed in 2.6.8) */
834 #define SOCKTIMEOUT2 997000 /* 997 seconds */
835
836 static void test_set_getsockopt()
837 {
838 SOCKET s;
839 int i, err;
840 int timeout;
841 LINGER lingval;
842 int size;
843
844 s = socket(AF_INET, SOCK_STREAM, 0);
845 ok(s!=INVALID_SOCKET, "socket() failed error: %d\n", WSAGetLastError());
846 if( s == INVALID_SOCKET) return;
847 /* SO_RCVTIMEO */
848 timeout = SOCKTIMEOUT1;
849 size = sizeof(timeout);
850 err = setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, size);
851 if( !err)
852 err = getsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, &size);
853 cs130_ryutaro 1.1 ok( !err, "get/setsockopt(SO_RCVTIMEO) failed error: %d\n", WSAGetLastError());
854 ok( timeout == SOCKTIMEOUT1, "getsockopt(SO_RCVTIMEO) returned wrong value %d\n", timeout);
855 /* SO_SNDTIMEO */
856 timeout = SOCKTIMEOUT2; /* 54 seconds. See remark above */
857 size = sizeof(timeout);
858 err = setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char *) &timeout, size);
859 if( !err)
860 err = getsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char *) &timeout, &size);
861 ok( !err, "get/setsockopt(SO_SNDTIMEO) failed error: %d\n", WSAGetLastError());
862 ok( timeout == SOCKTIMEOUT2, "getsockopt(SO_SNDTIMEO) returned wrong value %d\n", timeout);
863 /* SO_LINGER */
864 for( i = 0; i < sizeof(linger_testvals)/sizeof(LINGER);i++) {
865 size = sizeof(lingval);
866 lingval = linger_testvals[i];
867 err = setsockopt(s, SOL_SOCKET, SO_LINGER, (char *) &lingval, size);
868 if( !err)
869 err = getsockopt(s, SOL_SOCKET, SO_LINGER, (char *) &lingval, &size);
870 ok( !err, "get/setsockopt(SO_LINGER) failed error: %d\n", WSAGetLastError());
871 ok( !lingval.l_onoff == !linger_testvals[i].l_onoff &&
872 (lingval.l_linger == linger_testvals[i].l_linger ||
873 (!lingval.l_linger && !linger_testvals[i].l_onoff))
874 cs130_ryutaro 1.1 , "getsockopt(SO_LINGER #%d) returned wrong value %d,%d not %d,%d \n", i,
875 lingval.l_onoff, lingval.l_linger,
876 linger_testvals[i].l_onoff, linger_testvals[i].l_linger);
877 }
878 closesocket(s);
879 }
880
881 static void test_so_reuseaddr()
882 {
883 struct sockaddr_in saddr;
884 SOCKET s1,s2;
885 unsigned int rc,reuse,size;
886
887 saddr.sin_family = AF_INET;
888 saddr.sin_port = htons(9375);
889 saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
890
891 s1=socket(AF_INET, SOCK_STREAM, 0);
892 ok(s1!=INVALID_SOCKET, "socket() failed error: %d\n", WSAGetLastError());
893 rc = bind(s1, (struct sockaddr*)&saddr, sizeof(saddr));
894 ok(rc!=SOCKET_ERROR, "bind(s1) failed error: %d\n", WSAGetLastError());
895 cs130_ryutaro 1.1
896 s2=socket(AF_INET, SOCK_STREAM, 0);
897 ok(s2!=INVALID_SOCKET, "socket() failed error: %d\n", WSAGetLastError());
898
899 reuse=0x1234;
900 size=sizeof(reuse);
901 rc=getsockopt(s2, SOL_SOCKET, SO_REUSEADDR, (char*)&reuse, &size );
902 ok(rc==0 && reuse==0,"wrong result in getsockopt(SO_REUSEADDR): rc=%d reuse=%d\n",rc,reuse);
903
904 rc = bind(s2, (struct sockaddr*)&saddr, sizeof(saddr));
905 ok(rc==SOCKET_ERROR, "bind() succeeded\n");
906
907 reuse = 1;
908 rc = setsockopt(s2, SOL_SOCKET, SO_REUSEADDR, (char*)&reuse, sizeof(reuse));
909 ok(rc==0, "setsockopt() failed error: %d\n", WSAGetLastError());
910
911 todo_wine {
912 rc = bind(s2, (struct sockaddr*)&saddr, sizeof(saddr));
913 ok(rc==0, "bind() failed error: %d\n", WSAGetLastError());
914 }
915
916 cs130_ryutaro 1.1 closesocket(s2);
917 closesocket(s1);
918 }
919
920 /************* Array containing the tests to run **********/
921
922 #define STD_STREAM_SOCKET \
923 SOCK_STREAM, \
924 0, \
925 "127.0.0.1", \
926 9374
927
928 static test_setup tests [NUM_TESTS] =
929 {
930 /* Test 0: synchronous client and server */
931 {
932 {
933 STD_STREAM_SOCKET,
934 2048,
935 16,
936 2
937 cs130_ryutaro 1.1 },
938 simple_server,
939 {
940 NULL,
941 0,
942 64
943 },
944 simple_client,
945 {
946 NULL,
947 0,
948 128
949 }
950 },
951 /* Test 1: event-driven client, synchronous server */
952 {
953 {
954 STD_STREAM_SOCKET,
955 2048,
956 16,
957 2
958 cs130_ryutaro 1.1 },
959 simple_server,
960 {
961 NULL,
962 0,
963 64
964 },
965 event_client,
966 {
967 NULL,
968 WSA_FLAG_OVERLAPPED,
969 128
970 }
971 },
972
973 /* Test 2: synchronous client and asynchronous server */
974 {
975 {
976 STD_STREAM_SOCKET,
977 2048,
978 16,
979 cs130_ryutaro 1.1 2
980 },
981 async_server,
982 {
983 NULL,
984 0,
985 64
986 },
987 simple_client,
988 {
989 NULL,
990 0,
991 128
992 }
993 }
994 };
995
996 static void test_WSAAddressToStringA()
997 {
998 INT ret;
999 DWORD len;
1000 cs130_ryutaro 1.1 SOCKADDR_IN sockaddr;
1001 CHAR address[22]; /* 12 digits + 3 dots + ':' + 5 digits + '\0' */
1002
1003 CHAR expect1[] = "0.0.0.0";
1004 CHAR expect2[] = "255.255.255.255";
1005 CHAR expect3[] = "0.0.0.0:65535";
1006 CHAR expect4[] = "255.255.255.255:65535";
1007
1008 len = 0;
1009
1010 sockaddr.sin_family = AF_INET;
1011 sockaddr.sin_port = 0;
1012 sockaddr.sin_addr.s_addr = 0;
1013
1014 ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
1015 ok( ret == SOCKET_ERROR, "WSAAddressToStringA() succeeded unexpectedly: %d\n", WSAGetLastError() );
1016
1017 len = sizeof(address);
1018
1019 sockaddr.sin_family = AF_INET;
1020 sockaddr.sin_port = 0;
1021 cs130_ryutaro 1.1 sockaddr.sin_addr.s_addr = 0;
1022
1023 ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
1024 ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
1025
1026 ok( !strcmp( address, expect1 ), "Expected: %s, got: %s\n", expect1, address );
1027
1028 len = sizeof(address);
1029
1030 sockaddr.sin_family = AF_INET;
1031 sockaddr.sin_port = 0;
1032 sockaddr.sin_addr.s_addr = 0xffffffff;
1033
1034 ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
1035 ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
1036
1037 ok( !strcmp( address, expect2 ), "Expected: %s, got: %s\n", expect2, address );
1038
1039 len = sizeof(address);
1040
1041 sockaddr.sin_family = AF_INET;
1042 cs130_ryutaro 1.1 sockaddr.sin_port = 0xffff;
1043 sockaddr.sin_addr.s_addr = 0;
1044
1045 ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
1046 ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
1047
1048 ok( !strcmp( address, expect3 ), "Expected: %s, got: %s\n", expect3, address );
1049
1050 len = sizeof(address);
1051
1052 sockaddr.sin_family = AF_INET;
1053 sockaddr.sin_port = 0xffff;
1054 sockaddr.sin_addr.s_addr = 0xffffffff;
1055
1056 ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
1057 ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
1058
1059 ok( !strcmp( address, expect4 ), "Expected: %s, got: %s\n", expect4, address );
1060 }
1061
1062 static void test_WSAAddressToStringW()
1063 cs130_ryutaro 1.1 {
1064 INT ret;
1065 DWORD len;
1066 SOCKADDR_IN sockaddr;
1067 WCHAR address[22]; /* 12 digits + 3 dots + ':' + 5 digits + '\0' */
1068
1069 WCHAR expect1[] = { '0','.','0','.','0','.','0', 0 };
1070 WCHAR expect2[] = { '2','5','5','.','2','5','5','.','2','5','5','.','2','5','5', 0 };
1071 WCHAR expect3[] = { '0','.','0','.','0','.','0', ':', '6', '5', '5', '3', '5', 0 };
1072 WCHAR expect4[] = { '2','5','5','.','2','5','5','.','2','5','5','.','2','5','5', ':',
1073 '6', '5', '5', '3', '5', 0 };
1074
1075 len = 0;
1076
1077 sockaddr.sin_family = AF_INET;
1078 sockaddr.sin_port = 0;
1079 sockaddr.sin_addr.s_addr = 0;
1080
1081 ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
1082 ok( ret == SOCKET_ERROR, "WSAAddressToStringW() succeeded unexpectedly: %x\n", WSAGetLastError() );
1083
1084 cs130_ryutaro 1.1 len = sizeof(address);
1085
1086 sockaddr.sin_family = AF_INET;
1087 sockaddr.sin_port = 0;
1088 sockaddr.sin_addr.s_addr = 0;
1089
1090 ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
1091 ok( !ret, "WSAAddressToStringW() failed unexpectedly: %x\n", WSAGetLastError() );
1092
1093 ok( !lstrcmpW( address, expect1 ), "Expected different address string\n" );
1094
1095 len = sizeof(address);
1096
1097 sockaddr.sin_family = AF_INET;
1098 sockaddr.sin_port = 0;
1099 sockaddr.sin_addr.s_addr = 0xffffffff;
1100
1101 ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
1102 ok( !ret, "WSAAddressToStringW() failed unexpectedly: %x\n", WSAGetLastError() );
1103
1104 ok( !lstrcmpW( address, expect2 ), "Expected different address string\n" );
1105 cs130_ryutaro 1.1
1106 len = sizeof(address);
1107
1108 sockaddr.sin_family = AF_INET;
1109 sockaddr.sin_port = 0xffff;
1110 sockaddr.sin_addr.s_addr = 0;
1111
1112 ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
1113 ok( !ret, "WSAAddressToStringW() failed unexpectedly: %x\n", WSAGetLastError() );
1114
1115 ok( !lstrcmpW( address, expect3 ), "Expected different address string\n" );
1116
1117 len = sizeof(address);
1118
1119 sockaddr.sin_family = AF_INET;
1120 sockaddr.sin_port = 0xffff;
1121 sockaddr.sin_addr.s_addr = 0xffffffff;
1122
1123 ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
1124 ok( !ret, "WSAAddressToStringW() failed unexpectedly: %x\n", WSAGetLastError() );
1125
1126 cs130_ryutaro 1.1 ok( !lstrcmpW( address, expect4 ), "Expected different address string\n" );
1127 }
1128
1129 static void test_WSAStringToAddressA()
1130 {
1131 INT ret, len;
1132 SOCKADDR_IN sockaddr;
1133
1134 CHAR address1[] = "0.0.0.0";
1135 CHAR address2[] = "127.127.127.127";
1136 CHAR address3[] = "255.255.255.255";
1137 CHAR address4[] = "127.127.127.127:65535";
1138 CHAR address5[] = "255.255.255.255:65535";
1139
1140 len = 0;
1141 sockaddr.sin_family = AF_INET;
1142
1143 ret = WSAStringToAddressA( address1, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
1144 ok( ret == SOCKET_ERROR, "WSAStringToAddressA() succeeded unexpectedly: %x\n",
1145 WSAGetLastError() );
1146
1147 cs130_ryutaro 1.1 len = sizeof(sockaddr);
1148 sockaddr.sin_port = 0;
1149 sockaddr.sin_addr.s_addr = 0;
1150
1151 ret = WSAStringToAddressA( address1, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
1152 ok( !ret && sockaddr.sin_addr.s_addr == 0,
1153 "WSAStringToAddressA() failed unexpectedly: %d\n", WSAGetLastError() );
1154
1155 len = sizeof(sockaddr);
1156 sockaddr.sin_port = 0;
1157 sockaddr.sin_addr.s_addr = 0;
1158
1159 ret = WSAStringToAddressA( address2, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
1160 ok( !ret && sockaddr.sin_addr.s_addr == 0x7f7f7f7f,
1161 "WSAStringToAddressA() failed unexpectedly: %d\n", WSAGetLastError() );
1162
1163 len = sizeof(sockaddr);
1164
1165 ret = WSAStringToAddressA( address3, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
1166 ok( ret, "WSAStringToAddressA() succeeded unexpectedly: %d\n", WSAGetLastError() );
1167
1168 cs130_ryutaro 1.1 len = sizeof(sockaddr);
1169 sockaddr.sin_port = 0;
1170 sockaddr.sin_addr.s_addr = 0;
1171
1172 ret = WSAStringToAddressA( address4, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
1173 ok( !ret && sockaddr.sin_addr.s_addr == 0x7f7f7f7f && sockaddr.sin_port == 0xffff,
1174 "WSAStringToAddressA() failed unexpectedly: %d\n", WSAGetLastError() );
1175
1176 len = sizeof(sockaddr);
1177
1178 ret = WSAStringToAddressA( address5, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
1179 ok( ret, "WSAStringToAddressA() succeeded unexpectedly: %d\n", WSAGetLastError() );
1180 }
1181
1182 static void test_WSAStringToAddressW()
1183 {
1184 INT ret, len;
1185 SOCKADDR_IN sockaddr;
1186
1187 WCHAR address1[] = { '0','.','0','.','0','.','0', 0 };
1188 WCHAR address2[] = { '1','2','7','.','1','2','7','.','1','2','7','.','1','2','7', 0 };
1189 cs130_ryutaro 1.1 WCHAR address3[] = { '2','5','5','.','2','5','5','.','2','5','5','.','2','5','5', 0 };
1190 WCHAR address4[] = { '1','2','7','.','1','2','7','.','1','2','7','.','1','2','7',
1191 ':', '6', '5', '5', '3', '5', 0 };
1192 WCHAR address5[] = { '2','5','5','.','2','5','5','.','2','5','5','.','2','5','5', ':',
1193 '6', '5', '5', '3', '5', 0 };
1194
1195 len = 0;
1196 sockaddr.sin_family = AF_INET;
1197
1198 ret = WSAStringToAddressW( address1, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
1199 ok( ret == SOCKET_ERROR, "WSAStringToAddressW() failed unexpectedly: %d\n",
1200 WSAGetLastError() );
1201
1202 len = sizeof(sockaddr);
1203 sockaddr.sin_port = 0;
1204 sockaddr.sin_addr.s_addr = 0;
1205
1206 ret = WSAStringToAddressW( address1, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
1207 ok( !ret && sockaddr.sin_addr.s_addr == 0,
1208 "WSAStringToAddressW() failed unexpectedly: %d\n", WSAGetLastError() );
1209
1210 cs130_ryutaro 1.1 len = sizeof(sockaddr);
1211
1212 sockaddr.sin_port = 0;
1213 sockaddr.sin_addr.s_addr = 0;
1214
1215 ret = WSAStringToAddressW( address2, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
1216 ok( !ret && sockaddr.sin_addr.s_addr == 0x7f7f7f7f,
1217 "WSAStringToAddressW() failed unexpectedly: %d\n", WSAGetLastError() );
1218
1219 len = sizeof(sockaddr);
1220
1221 ret = WSAStringToAddressW( address3, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
1222 ok( ret, "WSAStringToAddressW() failed unexpectedly: %d\n", WSAGetLastError() );
1223
1224 len = sizeof(sockaddr);
1225 sockaddr.sin_port = 0;
1226 sockaddr.sin_addr.s_addr = 0;
1227
1228 ret = WSAStringToAddressW( address4, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
1229 ok( !ret && sockaddr.sin_addr.s_addr == 0x7f7f7f7f && sockaddr.sin_port == 0xffff,
1230 "WSAStringToAddressW() failed unexpectedly: %d\n", WSAGetLastError() );
1231 cs130_ryutaro 1.1
1232 len = sizeof(sockaddr);
1233
1234 ret = WSAStringToAddressW( address5, AF_INET, NULL, (SOCKADDR*)&sockaddr, &len );
1235 ok( ret, "WSAStringToAddressW() succeeded unexpectedly: %d\n", WSAGetLastError() );
1236 }
1237
1238 /**************** Main program ***************/
1239
1240 START_TEST( sock )
1241 {
1242 int i;
1243 Init();
1244
1245 test_set_getsockopt();
1246 test_so_reuseaddr();
1247
1248 for (i = 0; i < NUM_TESTS; i++)
1249 {
1250 trace ( " **** STARTING TEST %d **** \n", i );
1251 do_test ( &tests[i] );
1252 cs130_ryutaro 1.1 trace ( " **** TEST %d COMPLETE **** \n", i );
1253 }
1254
1255 test_WSAAddressToStringA();
1256 test_WSAAddressToStringW();
1257
1258 test_WSAStringToAddressA();
1259 test_WSAStringToAddressW();
1260
1261 Exit();
1262 }
|