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