(file) Return to sock.c CVS log (file) (dir) Up to [RizwankCVS] / wine4 / wine / dlls / winsock / tests

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

Rizwan Kassim
Powered by
ViewCVS 0.9.2