nsprpub/pr/tests/acceptreademu.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.

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

mercurial