nsprpub/pr/tests/peek.c

Wed, 31 Dec 2014 07:53:36 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:53:36 +0100
branch
TOR_BUG_3246
changeset 5
4ab42b5ab56c
permissions
-rw-r--r--

Correct small whitespace inconsistency, lost while renaming variables.

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 * A test case for the PR_MSG_PEEK flag of PR_Recv().
michael@0 8 *
michael@0 9 * Test both blocking and non-blocking sockets.
michael@0 10 */
michael@0 11
michael@0 12 #include "nspr.h"
michael@0 13
michael@0 14 #include <stdio.h>
michael@0 15 #include <stdlib.h>
michael@0 16 #include <string.h>
michael@0 17
michael@0 18 #define BUFFER_SIZE 1024
michael@0 19
michael@0 20 static int iterations = 10;
michael@0 21
michael@0 22 /*
michael@0 23 * In iteration i, recv_amount[i] is the number of bytes we
michael@0 24 * wish to receive, and send_amount[i] is the number of bytes
michael@0 25 * we actually send. Therefore, the number of elements in the
michael@0 26 * recv_amount or send_amount array should equal to 'iterations'.
michael@0 27 * For this test to pass we need to ensure that
michael@0 28 * recv_amount[i] <= BUFFER_SIZE,
michael@0 29 * send_amount[i] <= BUFFER_SIZE,
michael@0 30 * send_amount[i] <= recv_amount[i].
michael@0 31 */
michael@0 32 static PRInt32 recv_amount[10] = {
michael@0 33 16, 128, 256, 1024, 512, 512, 128, 256, 32, 32};
michael@0 34 static PRInt32 send_amount[10] = {
michael@0 35 16, 64, 128, 1024, 512, 256, 128, 64, 16, 32};
michael@0 36
michael@0 37 /* Blocking I/O */
michael@0 38 static void ServerB(void *arg)
michael@0 39 {
michael@0 40 PRFileDesc *listenSock = (PRFileDesc *) arg;
michael@0 41 PRFileDesc *sock;
michael@0 42 char buf[BUFFER_SIZE];
michael@0 43 PRInt32 nbytes;
michael@0 44 int i;
michael@0 45 int j;
michael@0 46
michael@0 47 sock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT);
michael@0 48 if (NULL == sock) {
michael@0 49 fprintf(stderr, "PR_Accept failed\n");
michael@0 50 exit(1);
michael@0 51 }
michael@0 52
michael@0 53 for (i = 0; i < iterations; i++) {
michael@0 54 memset(buf, 0, sizeof(buf));
michael@0 55 nbytes = PR_Recv(sock, buf, recv_amount[i],
michael@0 56 PR_MSG_PEEK, PR_INTERVAL_NO_TIMEOUT);
michael@0 57 if (-1 == nbytes) {
michael@0 58 fprintf(stderr, "PR_Recv failed\n");
michael@0 59 exit(1);
michael@0 60 }
michael@0 61 if (send_amount[i] != nbytes) {
michael@0 62 fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes);
michael@0 63 exit(1);
michael@0 64 }
michael@0 65 for (j = 0; j < nbytes; j++) {
michael@0 66 if (buf[j] != 2*i) {
michael@0 67 fprintf(stderr, "byte %d should be %d but is %d\n",
michael@0 68 j, 2*i, buf[j]);
michael@0 69 exit(1);
michael@0 70 }
michael@0 71 }
michael@0 72 fprintf(stderr, "server: peeked expected data\n");
michael@0 73
michael@0 74 memset(buf, 0, sizeof(buf));
michael@0 75 nbytes = PR_Recv(sock, buf, recv_amount[i],
michael@0 76 PR_MSG_PEEK, PR_INTERVAL_NO_TIMEOUT);
michael@0 77 if (-1 == nbytes) {
michael@0 78 fprintf(stderr, "PR_Recv failed\n");
michael@0 79 exit(1);
michael@0 80 }
michael@0 81 if (send_amount[i] != nbytes) {
michael@0 82 fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes);
michael@0 83 exit(1);
michael@0 84 }
michael@0 85 for (j = 0; j < nbytes; j++) {
michael@0 86 if (buf[j] != 2*i) {
michael@0 87 fprintf(stderr, "byte %d should be %d but is %d\n",
michael@0 88 j, 2*i, buf[j]);
michael@0 89 exit(1);
michael@0 90 }
michael@0 91 }
michael@0 92 fprintf(stderr, "server: peeked expected data\n");
michael@0 93
michael@0 94 memset(buf, 0, sizeof(buf));
michael@0 95 nbytes = PR_Recv(sock, buf, recv_amount[i],
michael@0 96 0, PR_INTERVAL_NO_TIMEOUT);
michael@0 97 if (-1 == nbytes) {
michael@0 98 fprintf(stderr, "PR_Recv failed\n");
michael@0 99 exit(1);
michael@0 100 }
michael@0 101 if (send_amount[i] != nbytes) {
michael@0 102 fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes);
michael@0 103 exit(1);
michael@0 104 }
michael@0 105 for (j = 0; j < nbytes; j++) {
michael@0 106 if (buf[j] != 2*i) {
michael@0 107 fprintf(stderr, "byte %d should be %d but is %d\n",
michael@0 108 j, 2*i, buf[j]);
michael@0 109 exit(1);
michael@0 110 }
michael@0 111 }
michael@0 112 fprintf(stderr, "server: received expected data\n");
michael@0 113
michael@0 114 PR_Sleep(PR_SecondsToInterval(1));
michael@0 115 memset(buf, 2*i+1, send_amount[i]);
michael@0 116 nbytes = PR_Send(sock, buf, send_amount[i],
michael@0 117 0, PR_INTERVAL_NO_TIMEOUT);
michael@0 118 if (-1 == nbytes) {
michael@0 119 fprintf(stderr, "PR_Send failed\n");
michael@0 120 exit(1);
michael@0 121 }
michael@0 122 if (send_amount[i] != nbytes) {
michael@0 123 fprintf(stderr, "PR_Send returned %d, absurd!\n", nbytes);
michael@0 124 exit(1);
michael@0 125 }
michael@0 126 }
michael@0 127 if (PR_Close(sock) == PR_FAILURE) {
michael@0 128 fprintf(stderr, "PR_Close failed\n");
michael@0 129 exit(1);
michael@0 130 }
michael@0 131 }
michael@0 132
michael@0 133 /* Non-blocking I/O */
michael@0 134 static void ClientNB(void *arg)
michael@0 135 {
michael@0 136 PRFileDesc *sock;
michael@0 137 PRSocketOptionData opt;
michael@0 138 PRUint16 port = (PRUint16) arg;
michael@0 139 PRNetAddr addr;
michael@0 140 char buf[BUFFER_SIZE];
michael@0 141 PRPollDesc pd;
michael@0 142 PRInt32 npds;
michael@0 143 PRInt32 nbytes;
michael@0 144 int i;
michael@0 145 int j;
michael@0 146
michael@0 147 sock = PR_OpenTCPSocket(PR_AF_INET6);
michael@0 148 if (NULL == sock) {
michael@0 149 fprintf(stderr, "PR_OpenTCPSocket failed\n");
michael@0 150 exit(1);
michael@0 151 }
michael@0 152 opt.option = PR_SockOpt_Nonblocking;
michael@0 153 opt.value.non_blocking = PR_TRUE;
michael@0 154 if (PR_SetSocketOption(sock, &opt) == PR_FAILURE) {
michael@0 155 fprintf(stderr, "PR_SetSocketOption failed\n");
michael@0 156 exit(1);
michael@0 157 }
michael@0 158 memset(&addr, 0, sizeof(addr));
michael@0 159 if (PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET6, port, &addr)
michael@0 160 == PR_FAILURE) {
michael@0 161 fprintf(stderr, "PR_SetNetAddr failed\n");
michael@0 162 exit(1);
michael@0 163 }
michael@0 164 if (PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) {
michael@0 165 if (PR_GetError() != PR_IN_PROGRESS_ERROR) {
michael@0 166 fprintf(stderr, "PR_Connect failed\n");
michael@0 167 exit(1);
michael@0 168 }
michael@0 169 pd.fd = sock;
michael@0 170 pd.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;
michael@0 171 npds = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
michael@0 172 if (-1 == npds) {
michael@0 173 fprintf(stderr, "PR_Poll failed\n");
michael@0 174 exit(1);
michael@0 175 }
michael@0 176 if (1 != npds) {
michael@0 177 fprintf(stderr, "PR_Poll returned %d, absurd!\n", npds);
michael@0 178 exit(1);
michael@0 179 }
michael@0 180 if (PR_GetConnectStatus(&pd) == PR_FAILURE) {
michael@0 181 fprintf(stderr, "PR_GetConnectStatus failed\n");
michael@0 182 exit(1);
michael@0 183 }
michael@0 184 }
michael@0 185
michael@0 186 for (i = 0; i < iterations; i++) {
michael@0 187 PR_Sleep(PR_SecondsToInterval(1));
michael@0 188 memset(buf, 2*i, send_amount[i]);
michael@0 189 while ((nbytes = PR_Send(sock, buf, send_amount[i],
michael@0 190 0, PR_INTERVAL_NO_TIMEOUT)) == -1) {
michael@0 191 if (PR_GetError() != PR_WOULD_BLOCK_ERROR) {
michael@0 192 fprintf(stderr, "PR_Send failed\n");
michael@0 193 exit(1);
michael@0 194 }
michael@0 195 pd.fd = sock;
michael@0 196 pd.in_flags = PR_POLL_WRITE;
michael@0 197 npds = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
michael@0 198 if (-1 == npds) {
michael@0 199 fprintf(stderr, "PR_Poll failed\n");
michael@0 200 exit(1);
michael@0 201 }
michael@0 202 if (1 != npds) {
michael@0 203 fprintf(stderr, "PR_Poll returned %d, absurd!\n", npds);
michael@0 204 exit(1);
michael@0 205 }
michael@0 206 }
michael@0 207 if (send_amount[i] != nbytes) {
michael@0 208 fprintf(stderr, "PR_Send returned %d, absurd!\n", nbytes);
michael@0 209 exit(1);
michael@0 210 }
michael@0 211
michael@0 212 memset(buf, 0, sizeof(buf));
michael@0 213 while ((nbytes = PR_Recv(sock, buf, recv_amount[i],
michael@0 214 PR_MSG_PEEK, PR_INTERVAL_NO_TIMEOUT)) == -1) {
michael@0 215 if (PR_GetError() != PR_WOULD_BLOCK_ERROR) {
michael@0 216 fprintf(stderr, "PR_Recv failed\n");
michael@0 217 exit(1);
michael@0 218 }
michael@0 219 pd.fd = sock;
michael@0 220 pd.in_flags = PR_POLL_READ;
michael@0 221 npds = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
michael@0 222 if (-1 == npds) {
michael@0 223 fprintf(stderr, "PR_Poll failed\n");
michael@0 224 exit(1);
michael@0 225 }
michael@0 226 if (1 != npds) {
michael@0 227 fprintf(stderr, "PR_Poll returned %d, absurd!\n", npds);
michael@0 228 exit(1);
michael@0 229 }
michael@0 230 }
michael@0 231 if (send_amount[i] != nbytes) {
michael@0 232 fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes);
michael@0 233 exit(1);
michael@0 234 }
michael@0 235 for (j = 0; j < nbytes; j++) {
michael@0 236 if (buf[j] != 2*i+1) {
michael@0 237 fprintf(stderr, "byte %d should be %d but is %d\n",
michael@0 238 j, 2*i+1, buf[j]);
michael@0 239 exit(1);
michael@0 240 }
michael@0 241 }
michael@0 242 fprintf(stderr, "client: peeked expected data\n");
michael@0 243
michael@0 244 memset(buf, 0, sizeof(buf));
michael@0 245 nbytes = PR_Recv(sock, buf, recv_amount[i],
michael@0 246 PR_MSG_PEEK, PR_INTERVAL_NO_TIMEOUT);
michael@0 247 if (-1 == nbytes) {
michael@0 248 fprintf(stderr, "PR_Recv failed\n");
michael@0 249 exit(1);
michael@0 250 }
michael@0 251 if (send_amount[i] != nbytes) {
michael@0 252 fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes);
michael@0 253 exit(1);
michael@0 254 }
michael@0 255 for (j = 0; j < nbytes; j++) {
michael@0 256 if (buf[j] != 2*i+1) {
michael@0 257 fprintf(stderr, "byte %d should be %d but is %d\n",
michael@0 258 j, 2*i+1, buf[j]);
michael@0 259 exit(1);
michael@0 260 }
michael@0 261 }
michael@0 262 fprintf(stderr, "client: peeked expected data\n");
michael@0 263
michael@0 264 memset(buf, 0, sizeof(buf));
michael@0 265 nbytes = PR_Recv(sock, buf, recv_amount[i],
michael@0 266 0, PR_INTERVAL_NO_TIMEOUT);
michael@0 267 if (-1 == nbytes) {
michael@0 268 fprintf(stderr, "PR_Recv failed\n");
michael@0 269 exit(1);
michael@0 270 }
michael@0 271 if (send_amount[i] != nbytes) {
michael@0 272 fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes);
michael@0 273 exit(1);
michael@0 274 }
michael@0 275 for (j = 0; j < nbytes; j++) {
michael@0 276 if (buf[j] != 2*i+1) {
michael@0 277 fprintf(stderr, "byte %d should be %d but is %d\n",
michael@0 278 j, 2*i+1, buf[j]);
michael@0 279 exit(1);
michael@0 280 }
michael@0 281 }
michael@0 282 fprintf(stderr, "client: received expected data\n");
michael@0 283 }
michael@0 284 if (PR_Close(sock) == PR_FAILURE) {
michael@0 285 fprintf(stderr, "PR_Close failed\n");
michael@0 286 exit(1);
michael@0 287 }
michael@0 288 }
michael@0 289
michael@0 290 static void
michael@0 291 RunTest(PRThreadScope scope, PRFileDesc *listenSock, PRUint16 port)
michael@0 292 {
michael@0 293 PRThread *server, *client;
michael@0 294
michael@0 295 server = PR_CreateThread(PR_USER_THREAD, ServerB, listenSock,
michael@0 296 PR_PRIORITY_NORMAL, scope, PR_JOINABLE_THREAD, 0);
michael@0 297 if (NULL == server) {
michael@0 298 fprintf(stderr, "PR_CreateThread failed\n");
michael@0 299 exit(1);
michael@0 300 }
michael@0 301 client = PR_CreateThread(
michael@0 302 PR_USER_THREAD, ClientNB, (void *) port,
michael@0 303 PR_PRIORITY_NORMAL, scope, PR_JOINABLE_THREAD, 0);
michael@0 304 if (NULL == client) {
michael@0 305 fprintf(stderr, "PR_CreateThread failed\n");
michael@0 306 exit(1);
michael@0 307 }
michael@0 308
michael@0 309 if (PR_JoinThread(server) == PR_FAILURE) {
michael@0 310 fprintf(stderr, "PR_JoinThread failed\n");
michael@0 311 exit(1);
michael@0 312 }
michael@0 313 if (PR_JoinThread(client) == PR_FAILURE) {
michael@0 314 fprintf(stderr, "PR_JoinThread failed\n");
michael@0 315 exit(1);
michael@0 316 }
michael@0 317 }
michael@0 318
michael@0 319 int main(int argc, char **argv)
michael@0 320 {
michael@0 321 PRFileDesc *listenSock;
michael@0 322 PRNetAddr addr;
michael@0 323 PRUint16 port;
michael@0 324
michael@0 325 listenSock = PR_OpenTCPSocket(PR_AF_INET6);
michael@0 326 if (NULL == listenSock) {
michael@0 327 fprintf(stderr, "PR_OpenTCPSocket failed\n");
michael@0 328 exit(1);
michael@0 329 }
michael@0 330 memset(&addr, 0, sizeof(addr));
michael@0 331 if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, 0, &addr) == PR_FAILURE) {
michael@0 332 fprintf(stderr, "PR_SetNetAddr failed\n");
michael@0 333 exit(1);
michael@0 334 }
michael@0 335 if (PR_Bind(listenSock, &addr) == PR_FAILURE) {
michael@0 336 fprintf(stderr, "PR_Bind failed\n");
michael@0 337 exit(1);
michael@0 338 }
michael@0 339 if (PR_GetSockName(listenSock, &addr) == PR_FAILURE) {
michael@0 340 fprintf(stderr, "PR_GetSockName failed\n");
michael@0 341 exit(1);
michael@0 342 }
michael@0 343 port = PR_ntohs(addr.ipv6.port);
michael@0 344 if (PR_Listen(listenSock, 5) == PR_FAILURE) {
michael@0 345 fprintf(stderr, "PR_Listen failed\n");
michael@0 346 exit(1);
michael@0 347 }
michael@0 348
michael@0 349 fprintf(stderr, "Running the test with local threads\n");
michael@0 350 RunTest(PR_LOCAL_THREAD, listenSock, port);
michael@0 351 fprintf(stderr, "Running the test with global threads\n");
michael@0 352 RunTest(PR_GLOBAL_THREAD, listenSock, port);
michael@0 353
michael@0 354 if (PR_Close(listenSock) == PR_FAILURE) {
michael@0 355 fprintf(stderr, "PR_Close failed\n");
michael@0 356 exit(1);
michael@0 357 }
michael@0 358 printf("PASS\n");
michael@0 359 return 0;
michael@0 360 }

mercurial