nsprpub/pr/tests/acceptread.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include <prio.h>
     7 #include <prprf.h>
     8 #include <prinit.h>
     9 #include <prnetdb.h>
    10 #include <prinrval.h>
    11 #include <prthread.h>
    13 #include <plerror.h>
    15 #include <stdlib.h>
    17 #define DEFAULT_PORT 12273
    18 #define GET "GET / HTTP/1.0\n\n"
    19 static PRFileDesc *std_out, *err_out;
    20 static PRIntervalTime write_dally, accept_timeout;
    22 static PRStatus PrintAddress(const PRNetAddr* address)
    23 {
    24     char buffer[100];
    25     PRStatus rv = PR_NetAddrToString(address, buffer, sizeof(buffer));
    26     if (PR_FAILURE == rv) PL_FPrintError(err_out, "PR_NetAddrToString");
    27     else PR_fprintf(
    28         std_out, "Accepted connection from (0x%p)%s:%d\n",
    29         address, buffer, address->inet.port);
    30     return rv;
    31 }  /* PrintAddress */
    33 static void ConnectingThread(void *arg)
    34 {
    35     PRInt32 nbytes;
    36 #ifdef SYMBIAN
    37     char buf[256];
    38 #else
    39     char buf[1024];
    40 #endif
    41     PRFileDesc *sock;
    42     PRNetAddr peer_addr, *addr;
    44     addr = (PRNetAddr*)arg;
    46     sock = PR_NewTCPSocket();
    47     if (sock == NULL)
    48     {
    49         PL_FPrintError(err_out, "PR_NewTCPSocket (client) failed");
    50         PR_ProcessExit(1);
    51     }
    53     if (PR_Connect(sock, addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE)
    54     {
    55         PL_FPrintError(err_out, "PR_Connect (client) failed");
    56         PR_ProcessExit(1);
    57     }
    58     if (PR_GetPeerName(sock, &peer_addr) == PR_FAILURE)
    59     {
    60         PL_FPrintError(err_out, "PR_GetPeerName (client) failed");
    61         PR_ProcessExit(1);
    62     }
    64     /*
    65     ** Then wait between the connection coming up and sending the expected
    66     ** data. At some point in time, the server should fail due to a timeou
    67     ** on the AcceptRead() operation, which according to the document is
    68     ** only due to the read() portion.
    69     */
    70     PR_Sleep(write_dally);
    72     nbytes = PR_Send(sock, GET, sizeof(GET), 0, PR_INTERVAL_NO_TIMEOUT);
    73     if (nbytes == -1) PL_FPrintError(err_out, "PR_Send (client) failed");
    75     nbytes = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT);
    76     if (nbytes == -1) PL_FPrintError(err_out, "PR_Recv (client) failed");
    77     else
    78     {
    79         PR_fprintf(std_out, "PR_Recv (client) succeeded: %d bytes\n", nbytes);
    80         buf[sizeof(buf) - 1] = '\0';
    81         PR_fprintf(std_out, "%s\n", buf);
    82     }
    84     if (PR_FAILURE == PR_Shutdown(sock, PR_SHUTDOWN_BOTH))
    85         PL_FPrintError(err_out, "PR_Shutdown (client) failed");
    87     if (PR_FAILURE == PR_Close(sock))
    88         PL_FPrintError(err_out, "PR_Close (client) failed");
    90     return;
    91 }  /* ConnectingThread */
    93 #define BUF_SIZE 117
    94 static void AcceptingThread(void *arg)
    95 {
    96     PRStatus rv;
    97     PRInt32 bytes;
    98     PRSize buf_size = BUF_SIZE;
    99     PRUint8 buf[BUF_SIZE + (2 * sizeof(PRNetAddr)) + 32];
   100     PRNetAddr *accept_addr, *listen_addr = (PRNetAddr*)arg;
   101     PRFileDesc *accept_sock, *listen_sock = PR_NewTCPSocket();
   102     PRSocketOptionData sock_opt;
   104     if (NULL == listen_sock)
   105     {
   106         PL_FPrintError(err_out, "PR_NewTCPSocket (server) failed");
   107         PR_ProcessExit(1);        
   108     }
   109     sock_opt.option = PR_SockOpt_Reuseaddr;
   110     sock_opt.value.reuse_addr = PR_TRUE;
   111     rv = PR_SetSocketOption(listen_sock, &sock_opt);
   112     if (PR_FAILURE == rv)
   113     {
   114         PL_FPrintError(err_out, "PR_SetSocketOption (server) failed");
   115         PR_ProcessExit(1);        
   116     }
   117     rv = PR_Bind(listen_sock, listen_addr);
   118     if (PR_FAILURE == rv)
   119     {
   120         PL_FPrintError(err_out, "PR_Bind (server) failed");
   121         PR_ProcessExit(1);        
   122     }
   123     rv = PR_Listen(listen_sock, 10);
   124     if (PR_FAILURE == rv)
   125     {
   126         PL_FPrintError(err_out, "PR_Listen (server) failed");
   127         PR_ProcessExit(1);        
   128     }
   129     bytes = PR_AcceptRead(
   130         listen_sock, &accept_sock, &accept_addr, buf, buf_size, accept_timeout);
   132     if (-1 == bytes) PL_FPrintError(err_out, "PR_AcceptRead (server) failed");
   133     else
   134     {
   135         PrintAddress(accept_addr);
   136         PR_fprintf(
   137             std_out, "(Server) read [0x%p..0x%p) %s\n",
   138             buf, &buf[BUF_SIZE], buf);
   139         bytes = PR_Write(accept_sock, buf, bytes);
   140         rv = PR_Shutdown(accept_sock, PR_SHUTDOWN_BOTH);
   141         if (PR_FAILURE == rv)
   142             PL_FPrintError(err_out, "PR_Shutdown (server) failed");
   143     }
   145     if (-1 != bytes)
   146     {
   147         rv = PR_Close(accept_sock);
   148         if (PR_FAILURE == rv)
   149             PL_FPrintError(err_out, "PR_Close (server) failed");
   150     }
   152     rv = PR_Close(listen_sock);
   153     if (PR_FAILURE == rv)
   154         PL_FPrintError(err_out, "PR_Close (server) failed");
   155 }  /* AcceptingThread */
   157 int main(int argc, char **argv)
   158 {
   159     PRHostEnt he;
   160     PRStatus status;
   161     PRIntn next_index;
   162     PRUint16 port_number;
   163     char netdb_buf[PR_NETDB_BUF_SIZE];
   164     PRNetAddr client_addr, server_addr;
   165     PRThread *client_thread, *server_thread;
   166     PRIntervalTime delta = PR_MillisecondsToInterval(500);
   168     err_out = PR_STDERR;
   169     std_out = PR_STDOUT;
   170     accept_timeout = PR_SecondsToInterval(2);
   172     if (argc != 2 && argc != 3) port_number = DEFAULT_PORT;
   173     else port_number = (PRUint16)atoi(argv[(argc == 2) ? 1 : 2]);
   175     status = PR_InitializeNetAddr(PR_IpAddrAny, port_number, &server_addr);
   176     if (PR_SUCCESS != status)
   177     {
   178         PL_FPrintError(err_out, "PR_InitializeNetAddr failed");
   179         PR_ProcessExit(1);
   180     }
   181     if (argc < 3)
   182     {
   183         status = PR_InitializeNetAddr(
   184             PR_IpAddrLoopback, port_number, &client_addr);
   185         if (PR_SUCCESS != status)
   186         {
   187             PL_FPrintError(err_out, "PR_InitializeNetAddr failed");
   188             PR_ProcessExit(1);
   189         }
   190     }
   191     else
   192     {
   193         status = PR_GetHostByName(
   194             argv[1], netdb_buf, sizeof(netdb_buf), &he);
   195         if (status == PR_FAILURE)
   196         {
   197             PL_FPrintError(err_out, "PR_GetHostByName failed");
   198             PR_ProcessExit(1);
   199         }
   200         next_index = PR_EnumerateHostEnt(0, &he, port_number, &client_addr);
   201         if (next_index == -1)
   202         {
   203             PL_FPrintError(err_out, "PR_EnumerateHostEnt failed");
   204             PR_ProcessExit(1);
   205         }
   206     }
   208     for (
   209         write_dally = 0;
   210         write_dally < accept_timeout + (2 * delta);
   211         write_dally += delta)
   212     {
   213         PR_fprintf(
   214             std_out, "Testing w/ write_dally = %d msec\n",
   215             PR_IntervalToMilliseconds(write_dally));
   216         server_thread = PR_CreateThread(
   217             PR_USER_THREAD, AcceptingThread, &server_addr,
   218             PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
   219         if (server_thread == NULL)
   220         {
   221             PL_FPrintError(err_out, "PR_CreateThread (server) failed");
   222             PR_ProcessExit(1);
   223         }
   225         PR_Sleep(delta);  /* let the server pot thicken */
   227         client_thread = PR_CreateThread(
   228             PR_USER_THREAD, ConnectingThread, &client_addr,
   229             PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
   230         if (client_thread == NULL)
   231         {
   232             PL_FPrintError(err_out, "PR_CreateThread (client) failed");
   233             PR_ProcessExit(1);
   234         }
   236         if (PR_JoinThread(client_thread) == PR_FAILURE)
   237             PL_FPrintError(err_out, "PR_JoinThread (client) failed");
   239         if (PR_JoinThread(server_thread) == PR_FAILURE)
   240             PL_FPrintError(err_out, "PR_JoinThread (server) failed");
   241     }
   243     return 0;
   244 }

mercurial