Bug Summary

File:pr/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/pr/tests/../../../pr/tests/socket.c
Warning:line 504, column 5
Value stored to 'bytes' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name socket.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nspr/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/pr/tests -fcoverage-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nspr/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/pr/tests -resource-dir /usr/lib/llvm-18/lib/clang/18 -U NDEBUG -D DEBUG_jenkins -D PACKAGE_NAME="" -D PACKAGE_TARNAME="" -D PACKAGE_VERSION="" -D PACKAGE_STRING="" -D PACKAGE_BUGREPORT="" -D PACKAGE_URL="" -D DEBUG=1 -D HAVE_VISIBILITY_HIDDEN_ATTRIBUTE=1 -D HAVE_VISIBILITY_PRAGMA=1 -D XP_UNIX=1 -D _GNU_SOURCE=1 -D HAVE_FCNTL_FILE_LOCKING=1 -D HAVE_POINTER_LOCALTIME_R=1 -D LINUX=1 -D HAVE_DLADDR=1 -D HAVE_GETTID=1 -D HAVE_LCHOWN=1 -D HAVE_SETPRIORITY=1 -D HAVE_STRERROR=1 -D HAVE_SYSCALL=1 -D HAVE_SECURE_GETENV=1 -D _REENTRANT=1 -D FORCE_PR_LOG -D _PR_PTHREADS -U HAVE_CVAR_BUILT_ON_SEM -I /var/lib/jenkins/workspace/nss-scan-build/nss/../dist/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/include -I ../../../pr/include -I ../../../pr/include/private -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -ferror-limit 19 -fvisibility=hidden -fgnuc-version=4.2.1 -fno-inline -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-05-18-082241-28900-1 -x c ../../../pr/tests/socket.c
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/. */
5
6/***********************************************************************
7**
8** Name: socket.c
9**
10** Description: Test socket functionality.
11**
12** Modification History:
13*/
14#include "primpl.h"
15
16#include "plgetopt.h"
17
18#include <stdio.h>
19#include <string.h>
20#include <errno(*__errno_location ()).h>
21#ifdef XP_UNIX1
22#include <sys/mman.h>
23#endif
24#if defined(_PR_PTHREADS1)
25#include <pthread.h>
26#endif
27
28#ifdef WIN32
29#include <process.h>
30#endif
31
32static int _debug_on = 0;
33static int test_cancelio = 0;
34
35#include "obsolete/prsem.h"
36
37#ifdef XP_PC
38#define mode_t int
39#endif
40
41#define DPRINTF(arg)if (_debug_on) printf arg if (_debug_on) printf arg
42
43#ifdef XP_PC
44char *TEST_DIR = "prdir";
45char *SMALL_FILE_NAME = "prsmallf";
46char *LARGE_FILE_NAME = "prlargef";
47#else
48char *TEST_DIR = "./tmp-prsocket_test_dir";
49char *SMALL_FILE_NAME = "./tmp-prsocket_test_dir/small_file";
50char *LARGE_FILE_NAME = "./tmp-prsocket_test_dir/large_file";
51#endif
52#define SMALL_FILE_SIZE(3 * 1024) (3 * 1024) /* 3 KB */
53#define SMALL_FILE_OFFSET_1(512) (512)
54#define SMALL_FILE_LEN_1(1 * 1024) (1 * 1024) /* 1 KB */
55#define SMALL_FILE_OFFSET_2(75) (75)
56#define SMALL_FILE_LEN_2(758) (758)
57#define SMALL_FILE_OFFSET_3(1024) (1024)
58#define SMALL_FILE_LEN_3((3 * 1024) - (1024)) (SMALL_FILE_SIZE(3 * 1024) - SMALL_FILE_OFFSET_3(1024))
59#define SMALL_FILE_HEADER_SIZE(64) (64) /* 64 bytes */
60#define SMALL_FILE_TRAILER_SIZE(128) (128) /* 128 bytes */
61
62#define LARGE_FILE_SIZE(3 * 1024 * 1024) (3 * 1024 * 1024) /* 3 MB */
63#define LARGE_FILE_OFFSET_1(0) (0)
64#define LARGE_FILE_LEN_1(2 * 1024 * 1024) (2 * 1024 * 1024) /* 2 MB */
65#define LARGE_FILE_OFFSET_2(64) (64)
66#define LARGE_FILE_LEN_2(1 * 1024 * 1024 + 75) (1 * 1024 * 1024 + 75)
67#define LARGE_FILE_OFFSET_3(2 * 1024 * 1024 - 128) (2 * 1024 * 1024 - 128)
68#define LARGE_FILE_LEN_3((3 * 1024 * 1024) - (2 * 1024 * 1024 - 128)) (LARGE_FILE_SIZE(3 * 1024 * 1024) - LARGE_FILE_OFFSET_3(2 * 1024 * 1024 - 128))
69#define LARGE_FILE_OFFSET_4PR_GetPageSize() PR_GetPageSize()
70#define LARGE_FILE_LEN_4769 769
71#define LARGE_FILE_HEADER_SIZE(512) (512)
72#define LARGE_FILE_TRAILER_SIZE(64) (64)
73
74#define BUF_DATA_SIZE(2 * 1024) (2 * 1024)
75#define TCP_MESG_SIZE1024 1024
76/*
77 * set UDP datagram size small enough that datagrams sent to a port on the
78 * local host will not be lost
79 */
80#define UDP_DGRAM_SIZE128 128
81#define NUM_TCP_CLIENTS5 5 /* for a listen queue depth of 5 */
82#define NUM_UDP_CLIENTS10 10
83
84#define NUM_TRANSMITFILE_CLIENTS4 4
85
86#define NUM_TCP_CONNECTIONS_PER_CLIENT5 5
87#define NUM_TCP_MESGS_PER_CONNECTION10 10
88#define NUM_UDP_DATAGRAMS_PER_CLIENT5 5
89#define TCP_SERVER_PORT10000 10000
90#define UDP_SERVER_PORT10000 TCP_SERVER_PORT10000
91#define SERVER_MAX_BIND_COUNT100 100
92
93#ifdef WINCE
94#define perror(s)
95#endif
96
97static PRInt32 num_tcp_clients = NUM_TCP_CLIENTS5;
98static PRInt32 num_udp_clients = NUM_UDP_CLIENTS10;
99static PRInt32 num_transmitfile_clients = NUM_TRANSMITFILE_CLIENTS4;
100static PRInt32 num_tcp_connections_per_client = NUM_TCP_CONNECTIONS_PER_CLIENT5;
101static PRInt32 tcp_mesg_size = TCP_MESG_SIZE1024;
102static PRInt32 num_tcp_mesgs_per_connection = NUM_TCP_MESGS_PER_CONNECTION10;
103static PRInt32 num_udp_datagrams_per_client = NUM_UDP_DATAGRAMS_PER_CLIENT5;
104static PRInt32 udp_datagram_size = UDP_DGRAM_SIZE128;
105
106static PRInt32 thread_count;
107PRUint16 server_domain = PR_AF_INET2, client_domain = PR_AF_INET2;
108
109/* an I/O layer that uses the emulated senfile method */
110static PRDescIdentity emuSendFileIdentity;
111static PRIOMethods emuSendFileMethods;
112
113int failed_already=0;
114typedef struct buffer {
115 char data[BUF_DATA_SIZE(2 * 1024)];
116} buffer;
117
118PRNetAddr tcp_server_addr, udp_server_addr;
119
120typedef struct Serve_Client_Param {
121 PRFileDesc *sockfd; /* socket to read from/write to */
122 PRInt32 datalen; /* bytes of data transfered in each read/write */
123} Serve_Client_Param;
124
125typedef struct Server_Param {
126 PRSemaphore *addr_sem; /* sem to post on, after setting up the address */
127 PRMonitor *exit_mon; /* monitor to signal on exit */
128 PRInt32 *exit_counter; /* counter to decrement, before exit */
129 PRInt32 datalen; /* bytes of data transfered in each read/write */
130} Server_Param;
131
132
133typedef struct Client_Param {
134 PRNetAddr server_addr;
135 PRMonitor *exit_mon; /* monitor to signal on exit */
136 PRInt32 *exit_counter; /* counter to decrement, before exit */
137 PRInt32 datalen;
138 PRInt32 udp_connect; /* if set clients connect udp sockets */
139} Client_Param;
140
141/* the sendfile method in emuSendFileMethods */
142static PRInt32 PR_CALLBACK
143emu_SendFile(PRFileDesc *sd, PRSendFileData *sfd,
144 PRTransmitFileFlags flags, PRIntervalTime timeout)
145{
146 return PR_EmulateSendFile(sd, sfd, flags, timeout);
147}
148
149/* the transmitfile method in emuSendFileMethods */
150static PRInt32 PR_CALLBACK
151emu_TransmitFile(PRFileDesc *sd, PRFileDesc *fd, const void *headers,
152 PRInt32 hlen, PRTransmitFileFlags flags, PRIntervalTime timeout)
153{
154 PRSendFileData sfd;
155
156 sfd.fd = fd;
157 sfd.file_offset = 0;
158 sfd.file_nbytes = 0;
159 sfd.header = headers;
160 sfd.hlen = hlen;
161 sfd.trailer = NULL((void*)0);
162 sfd.tlen = 0;
163 return emu_SendFile(sd, &sfd, flags, timeout);
164}
165
166/*
167 * readn
168 * read data from sockfd into buf
169 */
170static PRInt32
171readn(PRFileDesc *sockfd, char *buf, int len)
172{
173 int rem;
174 int bytes;
175 int offset = 0;
176 int err;
177 PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT0xffffffffUL;
178
179 if (test_cancelio) {
180 timeout = PR_SecondsToInterval(2);
181 }
182
183 for (rem=len; rem; offset += bytes, rem -= bytes) {
184 DPRINTF(("thread = 0x%lx: calling PR_Recv, bytes = %d\n",if (_debug_on) printf ("thread = 0x%lx: calling PR_Recv, bytes = %d\n"
, PR_GetCurrentThread(), rem)
185 PR_GetCurrentThread(), rem))if (_debug_on) printf ("thread = 0x%lx: calling PR_Recv, bytes = %d\n"
, PR_GetCurrentThread(), rem)
;
186retry:
187 bytes = PR_Recv(sockfd, buf + offset, rem, 0,
188 timeout);
189 DPRINTF(("thread = 0x%lx: returning from PR_Recv, bytes = %d\n",if (_debug_on) printf ("thread = 0x%lx: returning from PR_Recv, bytes = %d\n"
, PR_GetCurrentThread(), bytes)
190 PR_GetCurrentThread(), bytes))if (_debug_on) printf ("thread = 0x%lx: returning from PR_Recv, bytes = %d\n"
, PR_GetCurrentThread(), bytes)
;
191 if (bytes < 0) {
192#ifdef WINNT
193 printf("PR_Recv: error = %d oserr = %d\n",(err = PR_GetError()),
194 PR_GetOSError());
195 if ((test_cancelio) && (err == PR_IO_TIMEOUT_ERROR(-5990L))) {
196 if (PR_NT_CancelIo(sockfd) != PR_SUCCESS) {
197 printf("PR_NT_CancelIO: error = %d\n",PR_GetError());
198 }
199 timeout = PR_INTERVAL_NO_TIMEOUT0xffffffffUL;
200 goto retry;
201 }
202#endif
203 return -1;
204 }
205 }
206 return len;
207}
208
209/*
210 * writen
211 * write data from buf to sockfd
212 */
213static PRInt32
214writen(PRFileDesc *sockfd, char *buf, int len)
215{
216 int rem;
217 int bytes;
218 int offset = 0;
219
220 for (rem=len; rem; offset += bytes, rem -= bytes) {
221 DPRINTF(("thread = 0x%lx: calling PR_Send, bytes = %d\n",if (_debug_on) printf ("thread = 0x%lx: calling PR_Send, bytes = %d\n"
, PR_GetCurrentThread(), rem)
222 PR_GetCurrentThread(), rem))if (_debug_on) printf ("thread = 0x%lx: calling PR_Send, bytes = %d\n"
, PR_GetCurrentThread(), rem)
;
223 bytes = PR_Send(sockfd, buf + offset, rem, 0,
224 PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
225 DPRINTF(("thread = 0x%lx: returning from PR_Send, bytes = %d\n",if (_debug_on) printf ("thread = 0x%lx: returning from PR_Send, bytes = %d\n"
, PR_GetCurrentThread(), bytes)
226 PR_GetCurrentThread(), bytes))if (_debug_on) printf ("thread = 0x%lx: returning from PR_Send, bytes = %d\n"
, PR_GetCurrentThread(), bytes)
;
227 if (bytes <= 0) {
228 return -1;
229 }
230 }
231 return len;
232}
233
234/*
235 * Serve_Client
236 * Thread, started by the server, for serving a client connection.
237 * Reads data from socket and writes it back, unmodified, and
238 * closes the socket
239 */
240static void PR_CALLBACK
241Serve_Client(void *arg)
242{
243 Serve_Client_Param *scp = (Serve_Client_Param *) arg;
244 PRFileDesc *sockfd;
245 buffer *in_buf;
246 PRInt32 bytes, j;
247
248 sockfd = scp->sockfd;
249 bytes = scp->datalen;
250 in_buf = PR_NEW(buffer)((buffer *) (PR_Malloc((sizeof(buffer)))));
251 if (in_buf == NULL((void*)0)) {
252 fprintf(stderrstderr,"prsocket_test: failed to alloc buffer struct\n");
253 failed_already=1;
254 goto exit;
255 }
256
257
258 for (j = 0; j < num_tcp_mesgs_per_connection; j++) {
259 /*
260 * Read data from client and send it back to the client unmodified
261 */
262 if (readn(sockfd, in_buf->data, bytes) < bytes) {
263 fprintf(stderrstderr,"prsocket_test: ERROR - Serve_Client:readn\n");
264 failed_already=1;
265 goto exit;
266 }
267 /* Shutdown only RCV will cause error on Symbian OS */
268 /*
269 * shutdown reads, after the last read
270 */
271 if (j == num_tcp_mesgs_per_connection - 1)
272 if (PR_Shutdown(sockfd, PR_SHUTDOWN_RCV) < 0) {
273 fprintf(stderrstderr,"prsocket_test: ERROR - PR_Shutdown\n");
274 }
275 DPRINTF(("Serve_Client [0x%lx]: inbuf[0] = 0x%lx\n",PR_GetCurrentThread(),if (_debug_on) printf ("Serve_Client [0x%lx]: inbuf[0] = 0x%lx\n"
,PR_GetCurrentThread(), (*((int *) in_buf->data)))
276 (*((int *) in_buf->data))))if (_debug_on) printf ("Serve_Client [0x%lx]: inbuf[0] = 0x%lx\n"
,PR_GetCurrentThread(), (*((int *) in_buf->data)))
;
277 if (writen(sockfd, in_buf->data, bytes) < bytes) {
278 fprintf(stderrstderr,"prsocket_test: ERROR - Serve_Client:writen\n");
279 failed_already=1;
280 goto exit;
281 }
282 }
283 /*
284 * shutdown reads and writes
285 */
286 if (PR_Shutdown(sockfd, PR_SHUTDOWN_BOTH) < 0) {
287 fprintf(stderrstderr,"prsocket_test: ERROR - PR_Shutdown\n");
288 failed_already=1;
289 }
290
291exit:
292 PR_Close(sockfd);
293 if (in_buf) {
294 PR_DELETE(in_buf){ PR_Free(in_buf); (in_buf) = ((void*)0); };
295 }
296}
297
298PRThread* create_new_thread(PRThreadType type,
299 void (*start)(void *arg),
300 void *arg,
301 PRThreadPriority priority,
302 PRThreadScope scope,
303 PRThreadState state,
304 PRUint32 stackSize, PRInt32 index)
305{
306 PRInt32 native_thread = 0;
307
308 PR_ASSERT(state == PR_UNJOINABLE_THREAD)((state == PR_UNJOINABLE_THREAD)?((void)0):PR_Assert("state == PR_UNJOINABLE_THREAD"
,"../../../pr/tests/socket.c",308))
;
309#if defined(_PR_PTHREADS1) || defined(WIN32)
310 switch(index % 4) {
311 case 0:
312 scope = (PR_LOCAL_THREAD);
313 break;
314 case 1:
315 scope = (PR_GLOBAL_THREAD);
316 break;
317 case 2:
318 scope = (PR_GLOBAL_BOUND_THREAD);
319 break;
320 case 3:
321 native_thread = 1;
322 break;
323 default:
324 PR_NOT_REACHED("Invalid scope")PR_Assert("Invalid scope","../../../pr/tests/socket.c",324);
325 break;
326 }
327 if (native_thread) {
328#if defined(_PR_PTHREADS1)
329 pthread_t tid;
330 if (!pthread_create(&tid, NULL((void*)0), (void * (*)(void *)) start, arg)) {
331 return((PRThread *) tid);
332 }
333 else {
334 return (NULL((void*)0));
335 }
336#else
337 HANDLE thandle;
338 unsigned tid;
339
340 thandle = (HANDLE) _beginthreadex(
341 NULL((void*)0),
342 stackSize,
343 (unsigned (__stdcall *)(void *))start,
344 arg,
345 STACK_SIZE_PARAM_IS_A_RESERVATION,
346 &tid);
347 return((PRThread *) thandle);
348#endif
349 } else {
350 return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize));
351 }
352#else
353 return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize));
354#endif
355}
356
357/*
358 * TCP Server
359 * Server Thread
360 * Bind an address to a socket and listen for incoming connections
361 * Start a Serve_Client thread for each incoming connection.
362 */
363static void PR_CALLBACK
364TCP_Server(void *arg)
365{
366 PRThread *t;
367 Server_Param *sp = (Server_Param *) arg;
368 Serve_Client_Param *scp;
369 PRFileDesc *sockfd, *newsockfd;
370 PRNetAddr netaddr;
371 PRInt32 i;
372 /*
373 * Create a tcp socket
374 */
375 if ((sockfd = PR_OpenTCPSocket(server_domain)) == NULL((void*)0)) {
376 fprintf(stderrstderr,"prsocket_test: PR_NewTCPSocket failed\n");
377 goto exit;
378 }
379 memset(&netaddr, 0, sizeof(netaddr));
380
381 if (PR_SetNetAddr(PR_IpAddrAny, server_domain, TCP_SERVER_PORT10000,
382 &netaddr) == PR_FAILURE) {
383 fprintf(stderrstderr,"prsocket_test: PR_SetNetAddr failed\n");
384 goto exit;
385 }
386 /*
387 * try a few times to bind server's address, if addresses are in
388 * use
389 */
390 i = 0;
391
392 while (PR_Bind(sockfd, &netaddr) < 0) {
393 if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR(-5982L)) {
394 netaddr.inet.port += 2;
395 if (i++ < SERVER_MAX_BIND_COUNT100) {
396 continue;
397 }
398 }
399 fprintf(stderrstderr,"prsocket_test: ERROR - PR_Bind failed\n");
400 perror("PR_Bind");
401 failed_already=1;
402 goto exit;
403 }
404
405 if (PR_Listen(sockfd, 32) < 0) {
406 fprintf(stderrstderr,"prsocket_test: ERROR - PR_Listen failed\n");
407 failed_already=1;
408 goto exit;
409 }
410
411 if (PR_GetSockName(sockfd, &netaddr) < 0) {
412 fprintf(stderrstderr,"prsocket_test: ERROR - PR_GetSockName failed\n");
413 failed_already=1;
414 goto exit;
415 }
416
417 DPRINTF(("TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",if (_debug_on) printf ("TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n"
, netaddr.inet.ip, netaddr.inet.port)
418 netaddr.inet.ip, netaddr.inet.port))if (_debug_on) printf ("TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n"
, netaddr.inet.ip, netaddr.inet.port)
;
419 if (PR_SetNetAddr(PR_IpAddrLoopback, client_domain,
420 PR_ntohs(PR_NetAddrInetPort(&netaddr)((&netaddr)->raw.family == 10 ? (&netaddr)->ipv6
.port : (&netaddr)->inet.port)
),
421 &tcp_server_addr) == PR_FAILURE) {
422 fprintf(stderrstderr,"prsocket_test: PR_SetNetAddr failed\n");
423 goto exit;
424 }
425 if ((client_domain == PR_AF_INET610) && (server_domain == PR_AF_INET2))
426 PR_ConvertIPv4AddrToIPv6(PR_htonl(INADDR_LOOPBACK((in_addr_t) 0x7f000001)),
427 &tcp_server_addr.ipv6.ip);
428
429 /*
430 * Wake up parent thread because server address is bound and made
431 * available in the global variable 'tcp_server_addr'
432 */
433 PR_PostSem(sp->addr_sem);
434
435 for (i = 0; i < (num_tcp_clients * num_tcp_connections_per_client); i++) {
436 /* test both null and non-null 'addr' argument to PR_Accept */
437 PRNetAddr *addrp = (i%2 ? &netaddr: NULL((void*)0));
438
439 DPRINTF(("TCP_Server: Accepting connection\n"))if (_debug_on) printf ("TCP_Server: Accepting connection\n");
440 if ((newsockfd = PR_Accept(sockfd, addrp,
441 PR_INTERVAL_NO_TIMEOUT0xffffffffUL)) == NULL((void*)0)) {
442 fprintf(stderrstderr,"prsocket_test: ERROR - PR_Accept failed\n");
443 goto exit;
444 }
445 DPRINTF(("TCP_Server: Accepted connection\n"))if (_debug_on) printf ("TCP_Server: Accepted connection\n");
446 scp = PR_NEW(Serve_Client_Param)((Serve_Client_Param *) (PR_Malloc((sizeof(Serve_Client_Param
)))))
;
447 if (scp == NULL((void*)0)) {
448 fprintf(stderrstderr,"prsocket_test: PR_NEW failed\n");
449 goto exit;
450 }
451
452 /*
453 * Start a Serve_Client thread for each incoming connection
454 */
455 scp->sockfd = newsockfd;
456 scp->datalen = sp->datalen;
457
458 t = create_new_thread(PR_USER_THREAD,
459 Serve_Client, (void *)scp,
460 PR_PRIORITY_NORMAL,
461 PR_LOCAL_THREAD,
462 PR_UNJOINABLE_THREAD,
463 0, i);
464 if (t == NULL((void*)0)) {
465 fprintf(stderrstderr,"prsocket_test: PR_CreateThread failed\n");
466 failed_already=1;
467 goto exit;
468 }
469 DPRINTF(("TCP_Server: Created Serve_Client = 0x%lx\n", t))if (_debug_on) printf ("TCP_Server: Created Serve_Client = 0x%lx\n"
, t)
;
470 }
471
472exit:
473 if (sockfd) {
474 PR_Close(sockfd);
475 }
476
477 /*
478 * Decrement exit_counter and notify parent thread
479 */
480
481 PR_EnterMonitor(sp->exit_mon);
482 --(*sp->exit_counter);
483 PR_Notify(sp->exit_mon);
484 PR_ExitMonitor(sp->exit_mon);
485 DPRINTF(("TCP_Server [0x%lx] exiting\n", PR_GetCurrentThread()))if (_debug_on) printf ("TCP_Server [0x%lx] exiting\n", PR_GetCurrentThread
())
;
486}
487
488/*
489 * UDP Server
490 * Server Thread
491 * Bind an address to a socket, read data from clients and send data
492 * back to clients
493 */
494static void PR_CALLBACK
495UDP_Server(void *arg)
496{
497 Server_Param *sp = (Server_Param *) arg;
498 PRFileDesc *sockfd;
499 buffer *in_buf;
500 PRNetAddr netaddr;
501 PRInt32 bytes, i, rv = 0;
502
503
504 bytes = sp->datalen;
Value stored to 'bytes' is never read
505 /*
506 * Create a udp socket
507 */
508 if ((sockfd = PR_OpenUDPSocket(server_domain)) == NULL((void*)0)) {
509 fprintf(stderrstderr,"prsocket_test: PR_NewUDPSocket failed\n");
510 failed_already=1;
511 return;
512 }
513 memset(&netaddr, 0, sizeof(netaddr));
514 if (PR_SetNetAddr(PR_IpAddrAny, server_domain, UDP_SERVER_PORT10000,
515 &netaddr) == PR_FAILURE) {
516 fprintf(stderrstderr,"prsocket_test: PR_SetNetAddr failed\n");
517 failed_already=1;
518 return;
519 }
520 /*
521 * try a few times to bind server's address, if addresses are in
522 * use
523 */
524 i = 0;
525 while (PR_Bind(sockfd, &netaddr) < 0) {
526 if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR(-5982L)) {
527 netaddr.inet.port += 2;
528 if (i++ < SERVER_MAX_BIND_COUNT100) {
529 continue;
530 }
531 }
532 fprintf(stderrstderr,"prsocket_test: ERROR - PR_Bind failed\n");
533 perror("PR_Bind");
534 failed_already=1;
535 return;
536 }
537
538 if (PR_GetSockName(sockfd, &netaddr) < 0) {
539 fprintf(stderrstderr,"prsocket_test: ERROR - PR_GetSockName failed\n");
540 failed_already=1;
541 return;
542 }
543
544 DPRINTF(("PR_Bind: UDP Server netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",if (_debug_on) printf ("PR_Bind: UDP Server netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n"
, netaddr.inet.ip, netaddr.inet.port)
545 netaddr.inet.ip, netaddr.inet.port))if (_debug_on) printf ("PR_Bind: UDP Server netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n"
, netaddr.inet.ip, netaddr.inet.port)
;
546 /*
547 * We can't use the IP address returned by PR_GetSockName in
548 * netaddr.inet.ip because netaddr.inet.ip is returned
549 * as 0 (= PR_INADDR_ANY).
550 */
551
552 if (PR_SetNetAddr(PR_IpAddrLoopback, client_domain,
553 PR_ntohs(PR_NetAddrInetPort(&netaddr)((&netaddr)->raw.family == 10 ? (&netaddr)->ipv6
.port : (&netaddr)->inet.port)
),
554 &udp_server_addr) == PR_FAILURE) {
555 fprintf(stderrstderr,"prsocket_test: PR_SetNetAddr failed\n");
556 failed_already=1;
557 return;
558 }
559 if ((client_domain == PR_AF_INET610) && (server_domain == PR_AF_INET2))
560 PR_ConvertIPv4AddrToIPv6(PR_htonl(INADDR_LOOPBACK((in_addr_t) 0x7f000001)),
561 &udp_server_addr.ipv6.ip);
562
563 /*
564 * Wake up parent thread because server address is bound and made
565 * available in the global variable 'udp_server_addr'
566 */
567 PR_PostSem(sp->addr_sem);
568
569 bytes = sp->datalen;
570 in_buf = PR_NEW(buffer)((buffer *) (PR_Malloc((sizeof(buffer)))));
571 if (in_buf == NULL((void*)0)) {
572 fprintf(stderrstderr,"prsocket_test: failed to alloc buffer struct\n");
573 failed_already=1;
574 return;
575 }
576 /*
577 * Receive datagrams from clients and send them back, unmodified, to the
578 * clients
579 */
580 memset(&netaddr, 0, sizeof(netaddr));
581 for (i = 0; i < (num_udp_clients * num_udp_datagrams_per_client); i++) {
582 DPRINTF(("UDP_Server: calling PR_RecvFrom client - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n",if (_debug_on) printf ("UDP_Server: calling PR_RecvFrom client - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n"
, netaddr.inet.ip, netaddr.inet.port, bytes, in_buf->data,
in_buf->data[0])
583 netaddr.inet.ip, netaddr.inet.port, bytes, in_buf->data,if (_debug_on) printf ("UDP_Server: calling PR_RecvFrom client - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n"
, netaddr.inet.ip, netaddr.inet.port, bytes, in_buf->data,
in_buf->data[0])
584 in_buf->data[0]))if (_debug_on) printf ("UDP_Server: calling PR_RecvFrom client - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n"
, netaddr.inet.ip, netaddr.inet.port, bytes, in_buf->data,
in_buf->data[0])
;
585
586 rv = PR_RecvFrom(sockfd, in_buf->data, bytes, 0, &netaddr,
587 PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
588 DPRINTF(("UDP_Server: PR_RecvFrom client - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n",if (_debug_on) printf ("UDP_Server: PR_RecvFrom client - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n"
, netaddr.inet.ip, netaddr.inet.port, rv, in_buf->data, in_buf
->data[0])
589 netaddr.inet.ip, netaddr.inet.port, rv, in_buf->data,if (_debug_on) printf ("UDP_Server: PR_RecvFrom client - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n"
, netaddr.inet.ip, netaddr.inet.port, rv, in_buf->data, in_buf
->data[0])
590 in_buf->data[0]))if (_debug_on) printf ("UDP_Server: PR_RecvFrom client - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n"
, netaddr.inet.ip, netaddr.inet.port, rv, in_buf->data, in_buf
->data[0])
;
591 if (rv != bytes) {
592 return;
593 }
594 rv = PR_SendTo(sockfd, in_buf->data, bytes, 0, &netaddr,
595 PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
596 if (rv != bytes) {
597 return;
598 }
599 }
600
601 PR_DELETE(in_buf){ PR_Free(in_buf); (in_buf) = ((void*)0); };
602 PR_Close(sockfd);
603
604 /*
605 * Decrement exit_counter and notify parent thread
606 */
607 PR_EnterMonitor(sp->exit_mon);
608 --(*sp->exit_counter);
609 PR_Notify(sp->exit_mon);
610 PR_ExitMonitor(sp->exit_mon);
611 DPRINTF(("UDP_Server [0x%x] exiting\n", PR_GetCurrentThread()))if (_debug_on) printf ("UDP_Server [0x%x] exiting\n", PR_GetCurrentThread
())
;
612}
613
614/*
615 * TCP_Client
616 * Client Thread
617 * Connect to the server at the address specified in the argument.
618 * Fill in a buffer, write data to server, read it back and check
619 * for data corruption.
620 * Close the socket for server connection
621 */
622static void PR_CALLBACK
623TCP_Client(void *arg)
624{
625 Client_Param *cp = (Client_Param *) arg;
626 PRFileDesc *sockfd;
627 buffer *in_buf, *out_buf;
628 union PRNetAddr netaddr;
629 PRInt32 bytes, i, j;
630
631
632 bytes = cp->datalen;
633 out_buf = PR_NEW(buffer)((buffer *) (PR_Malloc((sizeof(buffer)))));
634 if (out_buf == NULL((void*)0)) {
635 fprintf(stderrstderr,"prsocket_test: failed to alloc buffer struct\n");
636 failed_already=1;
637 return;
638 }
639 in_buf = PR_NEW(buffer)((buffer *) (PR_Malloc((sizeof(buffer)))));
640 if (in_buf == NULL((void*)0)) {
641 fprintf(stderrstderr,"prsocket_test: failed to alloc buffer struct\n");
642 failed_already=1;
643 return;
644 }
645 netaddr = cp->server_addr;
646
647 for (i = 0; i < num_tcp_connections_per_client; i++) {
648 if ((sockfd = PR_OpenTCPSocket(client_domain)) == NULL((void*)0)) {
649 fprintf(stderrstderr,"prsocket_test: PR_OpenTCPSocket failed\n");
650 failed_already=1;
651 return;
652 }
653 if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT0xffffffffUL) < 0) {
654 fprintf(stderrstderr, "PR_Connect failed: (%ld, %ld)\n",
655 PR_GetError(), PR_GetOSError());
656 failed_already=1;
657 return;
658 }
659 for (j = 0; j < num_tcp_mesgs_per_connection; j++) {
660 /*
661 * fill in random data
662 */
663 memset(out_buf->data, ((PRInt32) (&netaddr)) + i + j, bytes);
664 /*
665 * write to server
666 */
667#ifdef WINNT
668 if (test_cancelio && (j == 0)) {
669 PR_Sleep(PR_SecondsToInterval(12));
670 }
671#endif
672 if (writen(sockfd, out_buf->data, bytes) < bytes) {
673 fprintf(stderrstderr,"prsocket_test: ERROR - TCP_Client:writen\n");
674 failed_already=1;
675 return;
676 }
677 DPRINTF(("TCP Client [0x%lx]: out_buf = 0x%lx out_buf[0] = 0x%lx\n",if (_debug_on) printf ("TCP Client [0x%lx]: out_buf = 0x%lx out_buf[0] = 0x%lx\n"
, PR_GetCurrentThread(), out_buf, (*((int *) out_buf->data
)))
678 PR_GetCurrentThread(), out_buf, (*((int *) out_buf->data))))if (_debug_on) printf ("TCP Client [0x%lx]: out_buf = 0x%lx out_buf[0] = 0x%lx\n"
, PR_GetCurrentThread(), out_buf, (*((int *) out_buf->data
)))
;
679 if (readn(sockfd, in_buf->data, bytes) < bytes) {
680 fprintf(stderrstderr,"prsocket_test: ERROR - TCP_Client:readn\n");
681 failed_already=1;
682 return;
683 }
684 /*
685 * verify the data read
686 */
687 if (memcmp(in_buf->data, out_buf->data, bytes) != 0) {
688 fprintf(stderrstderr,"prsocket_test: ERROR - data corruption\n");
689 failed_already=1;
690 return;
691 }
692 }
693 /*
694 * shutdown reads and writes
695 */
696 if (PR_Shutdown(sockfd, PR_SHUTDOWN_BOTH) < 0) {
697 fprintf(stderrstderr,"prsocket_test: ERROR - PR_Shutdown\n");
698 failed_already=1;
699 }
700 PR_Close(sockfd);
701 }
702
703 PR_DELETE(out_buf){ PR_Free(out_buf); (out_buf) = ((void*)0); };
704 PR_DELETE(in_buf){ PR_Free(in_buf); (in_buf) = ((void*)0); };
705
706 /*
707 * Decrement exit_counter and notify parent thread
708 */
709
710 PR_EnterMonitor(cp->exit_mon);
711 --(*cp->exit_counter);
712 PR_Notify(cp->exit_mon);
713 PR_ExitMonitor(cp->exit_mon);
714 DPRINTF(("TCP_Client [0x%x] exiting\n", PR_GetCurrentThread()))if (_debug_on) printf ("TCP_Client [0x%x] exiting\n", PR_GetCurrentThread
())
;
715}
716
717/*
718 * UDP_Client
719 * Client Thread
720 * Create a socket and bind an address
721 * Communicate with the server at the address specified in the argument.
722 * Fill in a buffer, write data to server, read it back and check
723 * for data corruption.
724 * Close the socket
725 */
726static void PR_CALLBACK
727UDP_Client(void *arg)
728{
729 Client_Param *cp = (Client_Param *) arg;
730 PRFileDesc *sockfd;
731 buffer *in_buf, *out_buf;
732 union PRNetAddr netaddr;
733 PRInt32 bytes, i, rv;
734
735
736 bytes = cp->datalen;
737 out_buf = PR_NEW(buffer)((buffer *) (PR_Malloc((sizeof(buffer)))));
738 if (out_buf == NULL((void*)0)) {
739 fprintf(stderrstderr,"prsocket_test: failed to alloc buffer struct\n");
740 failed_already=1;
741 return;
742 }
743 in_buf = PR_NEW(buffer)((buffer *) (PR_Malloc((sizeof(buffer)))));
744 if (in_buf == NULL((void*)0)) {
745 fprintf(stderrstderr,"prsocket_test: failed to alloc buffer struct\n");
746 failed_already=1;
747 return;
748 }
749 if ((sockfd = PR_OpenUDPSocket(client_domain)) == NULL((void*)0)) {
750 fprintf(stderrstderr,"prsocket_test: PR_OpenUDPSocket failed\n");
751 failed_already=1;
752 return;
753 }
754
755 /*
756 * bind an address for the client, let the system chose the port
757 * number
758 */
759 memset(&netaddr, 0, sizeof(netaddr));
760 if (PR_SetNetAddr(PR_IpAddrAny, client_domain, 0,
761 &netaddr) == PR_FAILURE) {
762 fprintf(stderrstderr,"prsocket_test: PR_SetNetAddr failed\n");
763 failed_already=1;
764 return;
765 }
766 if (PR_Bind(sockfd, &netaddr) < 0) {
767 fprintf(stderrstderr,"prsocket_test: ERROR - PR_Bind failed\n");
768 perror("PR_Bind");
769 return;
770 }
771
772 if (PR_GetSockName(sockfd, &netaddr) < 0) {
773 fprintf(stderrstderr,"prsocket_test: ERROR - PR_GetSockName failed\n");
774 failed_already=1;
775 return;
776 }
777
778 DPRINTF(("PR_Bind: UDP Client netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",if (_debug_on) printf ("PR_Bind: UDP Client netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n"
, netaddr.inet.ip, netaddr.inet.port)
779 netaddr.inet.ip, netaddr.inet.port))if (_debug_on) printf ("PR_Bind: UDP Client netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n"
, netaddr.inet.ip, netaddr.inet.port)
;
780
781 netaddr = cp->server_addr;
782
783 if (cp->udp_connect) {
784 if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT0xffffffffUL) < 0) {
785 fprintf(stderrstderr,"prsocket_test: PR_Connect failed\n");
786 failed_already=1;
787 return;
788 }
789 }
790
791 for (i = 0; i < num_udp_datagrams_per_client; i++) {
792 /*
793 * fill in random data
794 */
795 DPRINTF(("UDP_Client [0x%lx]: out_buf = 0x%lx bytes = 0x%lx\n",if (_debug_on) printf ("UDP_Client [0x%lx]: out_buf = 0x%lx bytes = 0x%lx\n"
, PR_GetCurrentThread(), out_buf->data, bytes)
796 PR_GetCurrentThread(), out_buf->data, bytes))if (_debug_on) printf ("UDP_Client [0x%lx]: out_buf = 0x%lx bytes = 0x%lx\n"
, PR_GetCurrentThread(), out_buf->data, bytes)
;
797 memset(out_buf->data, ((PRInt32) (&netaddr)) + i, bytes);
798 /*
799 * write to server
800 */
801 if (cp->udp_connect)
802 rv = PR_Send(sockfd, out_buf->data, bytes, 0,
803 PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
804 else
805 rv = PR_SendTo(sockfd, out_buf->data, bytes, 0, &netaddr,
806 PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
807 if (rv != bytes) {
808 return;
809 }
810 DPRINTF(("UDP_Client [0x%lx]: out_buf = 0x%lx out_buf[0] = 0x%lx\n",if (_debug_on) printf ("UDP_Client [0x%lx]: out_buf = 0x%lx out_buf[0] = 0x%lx\n"
, PR_GetCurrentThread(), out_buf, (*((int *) out_buf->data
)))
811 PR_GetCurrentThread(), out_buf, (*((int *) out_buf->data))))if (_debug_on) printf ("UDP_Client [0x%lx]: out_buf = 0x%lx out_buf[0] = 0x%lx\n"
, PR_GetCurrentThread(), out_buf, (*((int *) out_buf->data
)))
;
812 if (cp->udp_connect)
813 rv = PR_Recv(sockfd, in_buf->data, bytes, 0,
814 PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
815 else
816 rv = PR_RecvFrom(sockfd, in_buf->data, bytes, 0, &netaddr,
817 PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
818 if (rv != bytes) {
819 return;
820 }
821 DPRINTF(("UDP_Client [0x%lx]: in_buf = 0x%lx in_buf[0] = 0x%lx\n",if (_debug_on) printf ("UDP_Client [0x%lx]: in_buf = 0x%lx in_buf[0] = 0x%lx\n"
, PR_GetCurrentThread(), in_buf, (*((int *) in_buf->data))
)
822 PR_GetCurrentThread(), in_buf, (*((int *) in_buf->data))))if (_debug_on) printf ("UDP_Client [0x%lx]: in_buf = 0x%lx in_buf[0] = 0x%lx\n"
, PR_GetCurrentThread(), in_buf, (*((int *) in_buf->data))
)
;
823 /*
824 * verify the data read
825 */
826 if (memcmp(in_buf->data, out_buf->data, bytes) != 0) {
827 fprintf(stderrstderr,"prsocket_test: ERROR - UDP data corruption\n");
828 failed_already=1;
829 return;
830 }
831 }
832 PR_Close(sockfd);
833
834 PR_DELETE(in_buf){ PR_Free(in_buf); (in_buf) = ((void*)0); };
835 PR_DELETE(out_buf){ PR_Free(out_buf); (out_buf) = ((void*)0); };
836
837 /*
838 * Decrement exit_counter and notify parent thread
839 */
840
841 PR_EnterMonitor(cp->exit_mon);
842 --(*cp->exit_counter);
843 PR_Notify(cp->exit_mon);
844 PR_ExitMonitor(cp->exit_mon);
845 PR_DELETE(cp){ PR_Free(cp); (cp) = ((void*)0); };
846 DPRINTF(("UDP_Client [0x%x] exiting\n", PR_GetCurrentThread()))if (_debug_on) printf ("UDP_Client [0x%x] exiting\n", PR_GetCurrentThread
())
;
847}
848
849/*
850 * TCP_Socket_Client_Server_Test - concurrent server test
851 *
852 * One server and several clients are started
853 * Each client connects to the server and sends a chunk of data
854 * For each connection, server starts another thread to read the data
855 * from the client and send it back to the client, unmodified.
856 * Each client checks that data received from server is same as the
857 * data it sent to the server.
858 *
859 */
860
861static PRInt32
862TCP_Socket_Client_Server_Test(void)
863{
864 int i;
865 PRThread *t;
866 PRSemaphore *server_sem;
867 Server_Param *sparamp;
868 Client_Param *cparamp;
869 PRMonitor *mon2;
870 PRInt32 datalen;
871
872
873 datalen = tcp_mesg_size;
874 thread_count = 0;
875 /*
876 * start the server thread
877 */
878 sparamp = PR_NEW(Server_Param)((Server_Param *) (PR_Malloc((sizeof(Server_Param)))));
879 if (sparamp == NULL((void*)0)) {
880 fprintf(stderrstderr,"prsocket_test: PR_NEW failed\n");
881 failed_already=1;
882 return -1;
883 }
884 server_sem = PR_NewSem(0);
885 if (server_sem == NULL((void*)0)) {
886 fprintf(stderrstderr,"prsocket_test: PR_NewSem failed\n");
887 failed_already=1;
888 return -1;
889 }
890 mon2 = PR_NewMonitor();
891 if (mon2 == NULL((void*)0)) {
892 fprintf(stderrstderr,"prsocket_test: PR_NewMonitor failed\n");
893 failed_already=1;
894 return -1;
895 }
896 PR_EnterMonitor(mon2);
897
898 sparamp->addr_sem = server_sem;
899 sparamp->exit_mon = mon2;
900 sparamp->exit_counter = &thread_count;
901 sparamp->datalen = datalen;
902 t = PR_CreateThread(PR_USER_THREAD,
903 TCP_Server, (void *)sparamp,
904 PR_PRIORITY_NORMAL,
905 PR_LOCAL_THREAD,
906 PR_UNJOINABLE_THREAD,
907 0);
908 if (t == NULL((void*)0)) {
909 fprintf(stderrstderr,"prsocket_test: PR_CreateThread failed\n");
910 failed_already=1;
911 return -1;
912 }
913 DPRINTF(("Created TCP server = 0x%lx\n", t))if (_debug_on) printf ("Created TCP server = 0x%lx\n", t);
914 thread_count++;
915
916 /*
917 * wait till the server address is setup
918 */
919 PR_WaitSem(server_sem);
920
921 /*
922 * Now start a bunch of client threads
923 */
924
925 cparamp = PR_NEW(Client_Param)((Client_Param *) (PR_Malloc((sizeof(Client_Param)))));
926 if (cparamp == NULL((void*)0)) {
927 fprintf(stderrstderr,"prsocket_test: PR_NEW failed\n");
928 failed_already=1;
929 return -1;
930 }
931 cparamp->server_addr = tcp_server_addr;
932 cparamp->exit_mon = mon2;
933 cparamp->exit_counter = &thread_count;
934 cparamp->datalen = datalen;
935 for (i = 0; i < num_tcp_clients; i++) {
936 t = create_new_thread(PR_USER_THREAD,
937 TCP_Client, (void *) cparamp,
938 PR_PRIORITY_NORMAL,
939 PR_LOCAL_THREAD,
940 PR_UNJOINABLE_THREAD,
941 0, i);
942 if (t == NULL((void*)0)) {
943 fprintf(stderrstderr,"prsocket_test: PR_CreateThread failed\n");
944 failed_already=1;
945 return -1;
946 }
947 DPRINTF(("Created TCP client = 0x%lx\n", t))if (_debug_on) printf ("Created TCP client = 0x%lx\n", t);
948 thread_count++;
949 }
950 /* Wait for server and client threads to exit */
951 while (thread_count) {
952 PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
953 DPRINTF(("TCP Server - thread_count = %d\n", thread_count))if (_debug_on) printf ("TCP Server - thread_count = %d\n", thread_count
)
;
954 }
955 PR_ExitMonitor(mon2);
956 printf("%30s","TCP_Socket_Client_Server_Test:");
957 printf("%2ld Server %2ld Clients %2ld connections_per_client\n",1l,
958 num_tcp_clients, num_tcp_connections_per_client);
959 printf("%30s %2ld messages_per_connection %4ld bytes_per_message\n",":",
960 num_tcp_mesgs_per_connection, tcp_mesg_size);
961
962 return 0;
963}
964
965/*
966 * UDP_Socket_Client_Server_Test - iterative server test
967 *
968 * One server and several clients are started
969 * Each client connects to the server and sends a chunk of data
970 * For each connection, server starts another thread to read the data
971 * from the client and send it back to the client, unmodified.
972 * Each client checks that data received from server is same as the
973 * data it sent to the server.
974 *
975 */
976
977static PRInt32
978UDP_Socket_Client_Server_Test(void)
979{
980 int i;
981 PRThread *t;
982 PRSemaphore *server_sem;
983 Server_Param *sparamp;
984 Client_Param *cparamp;
985 PRMonitor *mon2;
986 PRInt32 datalen;
987 PRInt32 udp_connect = 1;
988
989
990 datalen = udp_datagram_size;
991 thread_count = 0;
992 /*
993 * start the server thread
994 */
995 sparamp = PR_NEW(Server_Param)((Server_Param *) (PR_Malloc((sizeof(Server_Param)))));
996 if (sparamp == NULL((void*)0)) {
997 fprintf(stderrstderr,"prsocket_test: PR_NEW failed\n");
998 failed_already=1;
999 return -1;
1000 }
1001 server_sem = PR_NewSem(0);
1002 if (server_sem == NULL((void*)0)) {
1003 fprintf(stderrstderr,"prsocket_test: PR_NewSem failed\n");
1004 failed_already=1;
1005 return -1;
1006 }
1007 mon2 = PR_NewMonitor();
1008 if (mon2 == NULL((void*)0)) {
1009 fprintf(stderrstderr,"prsocket_test: PR_NewMonitor failed\n");
1010 failed_already=1;
1011 return -1;
1012 }
1013 PR_EnterMonitor(mon2);
1014
1015 sparamp->addr_sem = server_sem;
1016 sparamp->exit_mon = mon2;
1017 sparamp->exit_counter = &thread_count;
1018 sparamp->datalen = datalen;
1019 DPRINTF(("Creating UDP server"))if (_debug_on) printf ("Creating UDP server");
1020 t = PR_CreateThread(PR_USER_THREAD,
1021 UDP_Server, (void *)sparamp,
1022 PR_PRIORITY_NORMAL,
1023 PR_LOCAL_THREAD,
1024 PR_UNJOINABLE_THREAD,
1025 0);
1026 if (t == NULL((void*)0)) {
1027 fprintf(stderrstderr,"prsocket_test: PR_CreateThread failed\n");
1028 failed_already=1;
1029 return -1;
1030 }
1031 thread_count++;
1032
1033 /*
1034 * wait till the server address is setup
1035 */
1036 PR_WaitSem(server_sem);
1037
1038 /*
1039 * Now start a bunch of client threads
1040 */
1041
1042 for (i = 0; i < num_udp_clients; i++) {
1043 cparamp = PR_NEW(Client_Param)((Client_Param *) (PR_Malloc((sizeof(Client_Param)))));
1044 if (cparamp == NULL((void*)0)) {
1045 fprintf(stderrstderr,"prsocket_test: PR_NEW failed\n");
1046 failed_already=1;
1047 return -1;
1048 }
1049 cparamp->server_addr = udp_server_addr;
1050 cparamp->exit_mon = mon2;
1051 cparamp->exit_counter = &thread_count;
1052 cparamp->datalen = datalen;
1053 /*
1054 * Cause every other client thread to connect udp sockets
1055 */
1056 cparamp->udp_connect = udp_connect;
1057 if (udp_connect) {
1058 udp_connect = 0;
1059 }
1060 else {
1061 udp_connect = 1;
1062 }
1063 DPRINTF(("Creating UDP client %d\n", i))if (_debug_on) printf ("Creating UDP client %d\n", i);
1064 t = PR_CreateThread(PR_USER_THREAD,
1065 UDP_Client, (void *) cparamp,
1066 PR_PRIORITY_NORMAL,
1067 PR_LOCAL_THREAD,
1068 PR_UNJOINABLE_THREAD,
1069 0);
1070 if (t == NULL((void*)0)) {
1071 fprintf(stderrstderr,"prsocket_test: PR_CreateThread failed\n");
1072 failed_already=1;
1073 return -1;
1074 }
1075 thread_count++;
1076 }
1077 /* Wait for server and client threads to exit */
1078 while (thread_count) {
1079 PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
1080 DPRINTF(("UDP Server - thread_count = %d\n", thread_count))if (_debug_on) printf ("UDP Server - thread_count = %d\n", thread_count
)
;
1081 }
1082 PR_ExitMonitor(mon2);
1083 printf("%30s","UDP_Socket_Client_Server_Test: ");
1084 printf("%2ld Server %2ld Clients\n",1l, num_udp_clients);
1085 printf("%30s %2ld datagrams_per_client %4ld bytes_per_datagram\n",":",
1086 num_udp_datagrams_per_client, udp_datagram_size);
1087
1088 return 0;
1089}
1090
1091static PRFileDesc *small_file_fd, *large_file_fd;
1092static void *small_file_addr, *small_file_header, *large_file_addr;
1093static void *small_file_trailer, *large_file_header, *large_file_trailer;
1094/*
1095 * TransmitFile_Client
1096 * Client Thread
1097 */
1098static void
1099TransmitFile_Client(void *arg)
1100{
1101 PRFileDesc *sockfd;
1102 union PRNetAddr netaddr;
1103 char *small_buf, *large_buf;
1104 Client_Param *cp = (Client_Param *) arg;
1105 PRInt32 rlen;
1106
1107 small_buf = (char*)PR_Malloc(SMALL_FILE_SIZE(3 * 1024) + SMALL_FILE_HEADER_SIZE(64) +
1108 SMALL_FILE_TRAILER_SIZE(128));
1109 if (small_buf == NULL((void*)0)) {
1110 fprintf(stderrstderr,"prsocket_test: failed to alloc buffer\n");
1111 failed_already=1;
1112 return;
1113 }
1114 large_buf = (char*)PR_Malloc(LARGE_FILE_SIZE(3 * 1024 * 1024) + LARGE_FILE_HEADER_SIZE(512) +
1115 LARGE_FILE_TRAILER_SIZE(64));
1116 if (large_buf == NULL((void*)0)) {
1117 fprintf(stderrstderr,"prsocket_test: failed to alloc buffer\n");
1118 failed_already=1;
1119 return;
1120 }
1121 netaddr.inet.family = cp->server_addr.inet.family;
1122 netaddr.inet.port = cp->server_addr.inet.port;
1123 netaddr.inet.ip = cp->server_addr.inet.ip;
1124
1125 if ((sockfd = PR_NewTCPSocket()) == NULL((void*)0)) {
1126 fprintf(stderrstderr,"prsocket_test: PR_NewTCPSocket failed\n");
1127 failed_already=1;
1128 return;
1129 }
1130
1131 if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT0xffffffffUL) < 0) {
1132 fprintf(stderrstderr,"prsocket_test: PR_Connect failed\n");
1133 failed_already=1;
1134 return;
1135 }
1136 /*
1137 * read the small file and verify the data
1138 */
1139 if (readn(sockfd, small_buf, SMALL_FILE_SIZE(3 * 1024) + SMALL_FILE_HEADER_SIZE(64))
1140 != (SMALL_FILE_SIZE(3 * 1024) + SMALL_FILE_HEADER_SIZE(64))) {
1141 fprintf(stderrstderr,
1142 "prsocket_test: TransmitFile_Client failed to receive file\n");
1143 failed_already=1;
1144 return;
1145 }
1146#if defined(XP_UNIX1)
1147 /* File transmission test can not be done because of large file's size */
1148 if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE(64)) != 0) {
1149 fprintf(stderrstderr,
1150 "prsocket_test: TransmitFile_Client ERROR - small file header data corruption\n");
1151 failed_already=1;
1152 return;
1153 }
1154 if (memcmp(small_file_addr, small_buf + SMALL_FILE_HEADER_SIZE(64),
1155 SMALL_FILE_SIZE(3 * 1024)) != 0) {
1156 fprintf(stderrstderr,
1157 "prsocket_test: TransmitFile_Client ERROR - small file data corruption\n");
1158 failed_already=1;
1159 return;
1160 }
1161#endif
1162 /*
1163 * read the large file and verify the data
1164 */
1165 if (readn(sockfd, large_buf, LARGE_FILE_SIZE(3 * 1024 * 1024)) != LARGE_FILE_SIZE(3 * 1024 * 1024)) {
1166 fprintf(stderrstderr,
1167 "prsocket_test: TransmitFile_Client failed to receive file\n");
1168 failed_already=1;
1169 return;
1170 }
1171#if defined(XP_UNIX1)
1172 if (memcmp(large_file_addr, large_buf, LARGE_FILE_SIZE(3 * 1024 * 1024)) != 0) {
1173 fprintf(stderrstderr,
1174 "prsocket_test: TransmitFile_Client ERROR - large file data corruption\n");
1175 failed_already=1;
1176 }
1177#endif
1178
1179
1180 /*
1181 * receive data from PR_SendFile
1182 */
1183 /*
1184 * case 1: small file with header and trailer
1185 */
1186 rlen = SMALL_FILE_SIZE(3 * 1024) + SMALL_FILE_HEADER_SIZE(64) +
1187 SMALL_FILE_TRAILER_SIZE(128);
1188 if (readn(sockfd, small_buf, rlen) != rlen) {
1189 fprintf(stderrstderr,
1190 "prsocket_test: SendFile_Client failed to receive file\n");
1191 failed_already=1;
1192 return;
1193 }
1194#if defined(XP_UNIX1)
1195 if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE(64)) != 0) {
1196 fprintf(stderrstderr,
1197 "SendFile 1. ERROR - small file header corruption\n");
1198 failed_already=1;
1199 return;
1200 }
1201 if (memcmp(small_file_addr, small_buf + SMALL_FILE_HEADER_SIZE(64),
1202 SMALL_FILE_SIZE(3 * 1024)) != 0) {
1203 fprintf(stderrstderr,
1204 "SendFile 1. ERROR - small file data corruption\n");
1205 failed_already=1;
1206 return;
1207 }
1208 if (memcmp(small_file_trailer,
1209 small_buf + SMALL_FILE_HEADER_SIZE(64) + SMALL_FILE_SIZE(3 * 1024),
1210 SMALL_FILE_TRAILER_SIZE(128)) != 0) {
1211 fprintf(stderrstderr,
1212 "SendFile 1. ERROR - small file trailer corruption\n");
1213 failed_already=1;
1214 return;
1215 }
1216#endif
1217 /*
1218 * case 2: partial large file at zero offset, file with header and trailer
1219 */
1220 rlen = LARGE_FILE_LEN_1(2 * 1024 * 1024) + LARGE_FILE_HEADER_SIZE(512) +
1221 LARGE_FILE_TRAILER_SIZE(64);
1222 if (readn(sockfd, large_buf, rlen) != rlen) {
1223 fprintf(stderrstderr,
1224 "prsocket_test: SendFile_Client failed to receive file\n");
1225 failed_already=1;
1226 return;
1227 }
1228#if defined(XP_UNIX1)
1229 if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE(512)) != 0) {
1230 fprintf(stderrstderr,
1231 "SendFile 2. ERROR - large file header corruption\n");
1232 failed_already=1;
1233 return;
1234 }
1235 if (memcmp(large_file_addr, large_buf + LARGE_FILE_HEADER_SIZE(512),
1236 LARGE_FILE_LEN_1(2 * 1024 * 1024)) != 0) {
1237 fprintf(stderrstderr,
1238 "SendFile 2. ERROR - large file data corruption\n");
1239 failed_already=1;
1240 return;
1241 }
1242 if (memcmp(large_file_trailer,
1243 large_buf + LARGE_FILE_HEADER_SIZE(512) + LARGE_FILE_LEN_1(2 * 1024 * 1024),
1244 LARGE_FILE_TRAILER_SIZE(64)) != 0) {
1245 fprintf(stderrstderr,
1246 "SendFile 2. ERROR - large file trailer corruption\n");
1247 failed_already=1;
1248 return;
1249 }
1250#endif
1251 /*
1252 * case 3: partial small file at non-zero offset, with header
1253 */
1254 rlen = SMALL_FILE_LEN_1(1 * 1024) + SMALL_FILE_HEADER_SIZE(64);
1255 if (readn(sockfd, small_buf, rlen) != rlen) {
1256 fprintf(stderrstderr,
1257 "prsocket_test: SendFile_Client failed to receive file\n");
1258 failed_already=1;
1259 return;
1260 }
1261#if defined(XP_UNIX1)
1262 if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE(64)) != 0) {
1263 fprintf(stderrstderr,
1264 "SendFile 3. ERROR - small file header corruption\n");
1265 failed_already=1;
1266 return;
1267 }
1268 if (memcmp((char *) small_file_addr + SMALL_FILE_OFFSET_1(512),
1269 small_buf + SMALL_FILE_HEADER_SIZE(64), SMALL_FILE_LEN_1(1 * 1024)) != 0) {
1270 fprintf(stderrstderr,
1271 "SendFile 3. ERROR - small file data corruption\n");
1272 failed_already=1;
1273 return;
1274 }
1275#endif
1276 /*
1277 * case 4: partial small file at non-zero offset, with trailer
1278 */
1279 rlen = SMALL_FILE_LEN_2(758) + SMALL_FILE_TRAILER_SIZE(128);
1280 if (readn(sockfd, small_buf, rlen) != rlen) {
1281 fprintf(stderrstderr,
1282 "prsocket_test: SendFile_Client failed to receive file\n");
1283 failed_already=1;
1284 return;
1285 }
1286#if defined(XP_UNIX1)
1287 if (memcmp((char *) small_file_addr + SMALL_FILE_OFFSET_2(75), small_buf,
1288 SMALL_FILE_LEN_2(758)) != 0) {
1289 fprintf(stderrstderr,
1290 "SendFile 4. ERROR - small file data corruption\n");
1291 failed_already=1;
1292 return;
1293 }
1294 if (memcmp(small_file_trailer, small_buf + SMALL_FILE_LEN_2(758),
1295 SMALL_FILE_TRAILER_SIZE(128)) != 0) {
1296 fprintf(stderrstderr,
1297 "SendFile 4. ERROR - small file trailer corruption\n");
1298 failed_already=1;
1299 return;
1300 }
1301#endif
1302 /*
1303 * case 5: partial large file at non-zero offset, file with header
1304 */
1305 rlen = LARGE_FILE_LEN_2(1 * 1024 * 1024 + 75) + LARGE_FILE_HEADER_SIZE(512);
1306 if (readn(sockfd, large_buf, rlen) != rlen) {
1307 fprintf(stderrstderr,
1308 "prsocket_test: SendFile_Client failed to receive file\n");
1309 failed_already=1;
1310 return;
1311 }
1312#if defined(XP_UNIX1)
1313 if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE(512)) != 0) {
1314 fprintf(stderrstderr,
1315 "SendFile 5. ERROR - large file header corruption\n");
1316 failed_already=1;
1317 return;
1318 }
1319 if (memcmp((char *)large_file_addr + LARGE_FILE_OFFSET_2(64),
1320 large_buf + LARGE_FILE_HEADER_SIZE(512),
1321 LARGE_FILE_LEN_2(1 * 1024 * 1024 + 75)) != 0) {
1322 fprintf(stderrstderr,
1323 "SendFile 5. ERROR - large file data corruption\n");
1324 failed_already=1;
1325 return;
1326 }
1327#endif
1328 /*
1329 * case 6: partial small file at non-zero offset, with header
1330 */
1331 rlen = SMALL_FILE_LEN_3((3 * 1024) - (1024)) + SMALL_FILE_HEADER_SIZE(64);
1332 if (readn(sockfd, small_buf, rlen) != rlen) {
1333 fprintf(stderrstderr,
1334 "prsocket_test: SendFile_Client failed to receive file\n");
1335 failed_already=1;
1336 return;
1337 }
1338#if defined(XP_UNIX1)
1339 if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE(64)) != 0) {
1340 fprintf(stderrstderr,
1341 "SendFile 6. ERROR - small file header corruption\n");
1342 return;
1343 }
1344 if (memcmp((char *) small_file_addr + SMALL_FILE_OFFSET_3(1024),
1345 small_buf + SMALL_FILE_HEADER_SIZE(64), SMALL_FILE_LEN_3((3 * 1024) - (1024))) != 0) {
1346#if 0
1347 char *i, *j;
1348 int k;
1349
1350 i = (char *) small_file_addr + SMALL_FILE_OFFSET_3(1024);
1351 j = small_buf + SMALL_FILE_HEADER_SIZE(64);
1352 k = SMALL_FILE_LEN_3((3 * 1024) - (1024));
1353 while (k-- > 0) {
1354 if (*i++ != *j++)
1355 printf("i = %d j = %d\n",
1356 (int) (i - ((char *) small_file_addr + SMALL_FILE_OFFSET_3(1024))),
1357 (int) (j - (small_buf + SMALL_FILE_HEADER_SIZE(64))));
1358 }
1359#endif
1360 fprintf(stderrstderr,
1361 "SendFile 6. ERROR - small file data corruption\n");
1362 failed_already=1;
1363 return;
1364 }
1365#endif
1366 /*
1367 * case 7: partial large file at non-zero offset, with header
1368 */
1369 rlen = LARGE_FILE_LEN_3((3 * 1024 * 1024) - (2 * 1024 * 1024 - 128)) + LARGE_FILE_HEADER_SIZE(512);
1370 if (readn(sockfd, large_buf, rlen) != rlen) {
1371 fprintf(stderrstderr,
1372 "prsocket_test: SendFile_Client failed to receive file\n");
1373 failed_already=1;
1374 return;
1375 }
1376#if defined(XP_UNIX1)
1377 if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE(512)) != 0) {
1378 fprintf(stderrstderr,
1379 "SendFile 7. ERROR - large file header corruption\n");
1380 failed_already=1;
1381 return;
1382 }
1383 if (memcmp((char *)large_file_addr + LARGE_FILE_OFFSET_3(2 * 1024 * 1024 - 128),
1384 large_buf + LARGE_FILE_HEADER_SIZE(512),
1385 LARGE_FILE_LEN_3((3 * 1024 * 1024) - (2 * 1024 * 1024 - 128))) != 0) {
1386 fprintf(stderrstderr,
1387 "SendFile 7. ERROR - large file data corruption\n");
1388 failed_already=1;
1389 return;
1390 }
1391#endif
1392 /*
1393 * case 8: partial large file at non-zero, page-aligned offset, with
1394 * header and trailer
1395 */
1396 rlen = LARGE_FILE_LEN_4769 + LARGE_FILE_HEADER_SIZE(512) +
1397 LARGE_FILE_TRAILER_SIZE(64);
1398 if (readn(sockfd, large_buf, rlen) != rlen) {
1399 fprintf(stderrstderr,
1400 "prsocket_test: SendFile_Client failed to receive file\n");
1401 failed_already=1;
1402 return;
1403 }
1404#if defined(XP_UNIX1)
1405 if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE(512)) != 0) {
1406 fprintf(stderrstderr,
1407 "SendFile 2. ERROR - large file header corruption\n");
1408 failed_already=1;
1409 return;
1410 }
1411 if (memcmp((char *)large_file_addr + LARGE_FILE_OFFSET_4PR_GetPageSize(),
1412 large_buf + LARGE_FILE_HEADER_SIZE(512),
1413 LARGE_FILE_LEN_4769) != 0) {
1414 fprintf(stderrstderr,
1415 "SendFile 2. ERROR - large file data corruption\n");
1416 failed_already=1;
1417 return;
1418 }
1419 if (memcmp(large_file_trailer,
1420 large_buf + LARGE_FILE_HEADER_SIZE(512) + LARGE_FILE_LEN_4769,
1421 LARGE_FILE_TRAILER_SIZE(64)) != 0) {
1422 fprintf(stderrstderr,
1423 "SendFile 2. ERROR - large file trailer corruption\n");
1424 failed_already=1;
1425 return;
1426 }
1427#endif
1428 PR_DELETE(small_buf){ PR_Free(small_buf); (small_buf) = ((void*)0); };
1429 PR_DELETE(large_buf){ PR_Free(large_buf); (large_buf) = ((void*)0); };
1430 PR_Close(sockfd);
1431
1432
1433 /*
1434 * Decrement exit_counter and notify parent thread
1435 */
1436
1437 PR_EnterMonitor(cp->exit_mon);
1438 --(*cp->exit_counter);
1439 PR_Notify(cp->exit_mon);
1440 PR_ExitMonitor(cp->exit_mon);
1441 DPRINTF(("TransmitFile_Client [0x%lx] exiting\n", PR_GetCurrentThread()))if (_debug_on) printf ("TransmitFile_Client [0x%lx] exiting\n"
, PR_GetCurrentThread())
;
1442}
1443
1444/*
1445 * Serve_TransmitFile_Client
1446 * Thread, started by the server, for serving a client connection.
1447 * Trasmits a small file, with a header, and a large file, without
1448 * a header
1449 */
1450static void
1451Serve_TransmitFile_Client(void *arg)
1452{
1453 Serve_Client_Param *scp = (Serve_Client_Param *) arg;
1454 PRFileDesc *sockfd;
1455 PRInt32 bytes;
1456 PRFileDesc *local_small_file_fd=NULL((void*)0);
1457 PRFileDesc *local_large_file_fd=NULL((void*)0);
1458 PRSendFileData sfd;
1459 PRInt32 slen;
1460
1461 sockfd = scp->sockfd;
1462 local_small_file_fd = PR_Open(SMALL_FILE_NAME, PR_RDONLY0x01,0);
1463
1464 if (local_small_file_fd == NULL((void*)0)) {
1465 fprintf(stderrstderr,"prsocket_test failed to open file for transmitting %s\n",
1466 SMALL_FILE_NAME);
1467 failed_already=1;
1468 goto done;
1469 }
1470 local_large_file_fd = PR_Open(LARGE_FILE_NAME, PR_RDONLY0x01,0);
1471
1472 if (local_large_file_fd == NULL((void*)0)) {
1473 fprintf(stderrstderr,"prsocket_test failed to open file for transmitting %s\n",
1474 LARGE_FILE_NAME);
1475 failed_already=1;
1476 goto done;
1477 }
1478 bytes = PR_TransmitFile(sockfd, local_small_file_fd, small_file_header,
1479 SMALL_FILE_HEADER_SIZE(64), PR_TRANSMITFILE_KEEP_OPEN,
1480 PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
1481 if (bytes != (SMALL_FILE_SIZE(3 * 1024)+ SMALL_FILE_HEADER_SIZE(64))) {
1482 fprintf(stderrstderr,
1483 "prsocet_test: PR_TransmitFile failed: (%ld, %ld)\n",
1484 PR_GetError(), PR_GetOSError());
1485 failed_already=1;
1486 }
1487 bytes = PR_TransmitFile(sockfd, local_large_file_fd, NULL((void*)0), 0,
1488 PR_TRANSMITFILE_KEEP_OPEN, PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
1489 if (bytes != LARGE_FILE_SIZE(3 * 1024 * 1024)) {
1490 fprintf(stderrstderr,
1491 "prsocket_test: PR_TransmitFile failed: (%ld, %ld)\n",
1492 PR_GetError(), PR_GetOSError());
1493 failed_already=1;
1494 }
1495
1496 /*
1497 * PR_SendFile test cases
1498 */
1499
1500 /*
1501 * case 1: small file with header and trailer
1502 */
1503 sfd.fd = local_small_file_fd;
1504 sfd.file_offset = 0;
1505 sfd.file_nbytes = 0;
1506 sfd.header = small_file_header;
1507 sfd.hlen = SMALL_FILE_HEADER_SIZE(64);
1508 sfd.trailer = small_file_trailer;
1509 sfd.tlen = SMALL_FILE_TRAILER_SIZE(128);
1510 bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
1511 PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
1512 slen = SMALL_FILE_SIZE(3 * 1024)+ SMALL_FILE_HEADER_SIZE(64) +
1513 SMALL_FILE_TRAILER_SIZE(128);
1514 if (bytes != slen) {
1515 fprintf(stderrstderr,
1516 "socket: Error - 1. PR_SendFile send_size = %d, bytes sent = %d\n",
1517 slen, bytes);
1518 fprintf(stderrstderr,
1519 "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
1520 PR_GetError(), PR_GetOSError());
1521 failed_already=1;
1522 }
1523
1524 /*
1525 * case 2: partial large file at zero offset, file with header and trailer
1526 */
1527 sfd.fd = local_large_file_fd;
1528 sfd.file_offset = 0;
1529 sfd.file_nbytes = LARGE_FILE_LEN_1(2 * 1024 * 1024);
1530 sfd.header = large_file_header;
1531 sfd.hlen = LARGE_FILE_HEADER_SIZE(512);
1532 sfd.trailer = large_file_trailer;
1533 sfd.tlen = LARGE_FILE_TRAILER_SIZE(64);
1534 bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
1535 PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
1536 slen = LARGE_FILE_LEN_1(2 * 1024 * 1024) + LARGE_FILE_HEADER_SIZE(512) +
1537 LARGE_FILE_TRAILER_SIZE(64);
1538 if (bytes != slen) {
1539 fprintf(stderrstderr,
1540 "socket: Error - 2. PR_SendFile send_size = %d, bytes sent = %d\n",
1541 slen, bytes);
1542 fprintf(stderrstderr,
1543 "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
1544 PR_GetError(), PR_GetOSError());
1545 failed_already=1;
1546 }
1547 /*
1548 * case 3: partial small file at non-zero offset, with header
1549 */
1550 sfd.fd = local_small_file_fd;
1551 sfd.file_offset = SMALL_FILE_OFFSET_1(512);
1552 sfd.file_nbytes = SMALL_FILE_LEN_1(1 * 1024);
1553 sfd.header = small_file_header;
1554 sfd.hlen = SMALL_FILE_HEADER_SIZE(64);
1555 sfd.trailer = NULL((void*)0);
1556 sfd.tlen = 0;
1557 bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
1558 PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
1559 slen = SMALL_FILE_LEN_1(1 * 1024) + SMALL_FILE_HEADER_SIZE(64);
1560 if (bytes != slen) {
1561 fprintf(stderrstderr,
1562 "socket: Error - 3. PR_SendFile send_size = %d, bytes sent = %d\n",
1563 slen, bytes);
1564 fprintf(stderrstderr,
1565 "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
1566 PR_GetError(), PR_GetOSError());
1567 failed_already=1;
1568 }
1569 /*
1570 * case 4: partial small file at non-zero offset, with trailer
1571 */
1572 sfd.fd = local_small_file_fd;
1573 sfd.file_offset = SMALL_FILE_OFFSET_2(75);
1574 sfd.file_nbytes = SMALL_FILE_LEN_2(758);
1575 sfd.header = NULL((void*)0);
1576 sfd.hlen = 0;
1577 sfd.trailer = small_file_trailer;
1578 sfd.tlen = SMALL_FILE_TRAILER_SIZE(128);
1579 bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
1580 PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
1581 slen = SMALL_FILE_LEN_2(758) + SMALL_FILE_TRAILER_SIZE(128);
1582 if (bytes != slen) {
1583 fprintf(stderrstderr,
1584 "socket: Error - 4. PR_SendFile send_size = %d, bytes sent = %d\n",
1585 slen, bytes);
1586 fprintf(stderrstderr,
1587 "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
1588 PR_GetError(), PR_GetOSError());
1589 failed_already=1;
1590 }
1591 /*
1592 * case 5: partial large file at non-zero offset, file with header
1593 */
1594 sfd.fd = local_large_file_fd;
1595 sfd.file_offset = LARGE_FILE_OFFSET_2(64);
1596 sfd.file_nbytes = LARGE_FILE_LEN_2(1 * 1024 * 1024 + 75);
1597 sfd.header = large_file_header;
1598 sfd.hlen = LARGE_FILE_HEADER_SIZE(512);
1599 sfd.trailer = NULL((void*)0);
1600 sfd.tlen = 0;
1601 bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
1602 PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
1603 slen = LARGE_FILE_LEN_2(1 * 1024 * 1024 + 75) + LARGE_FILE_HEADER_SIZE(512);
1604 if (bytes != slen) {
1605 fprintf(stderrstderr,
1606 "socket: Error - 5. PR_SendFile send_size = %d, bytes sent = %d\n",
1607 slen, bytes);
1608 fprintf(stderrstderr,
1609 "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
1610 PR_GetError(), PR_GetOSError());
1611 failed_already=1;
1612 }
1613 /*
1614 * case 6: partial small file from non-zero offset till end of file, with header
1615 */
1616 sfd.fd = local_small_file_fd;
1617 sfd.file_offset = SMALL_FILE_OFFSET_3(1024);
1618 sfd.file_nbytes = 0; /* data from offset to end-of-file */
1619 sfd.header = small_file_header;
1620 sfd.hlen = SMALL_FILE_HEADER_SIZE(64);
1621 sfd.trailer = NULL((void*)0);
1622 sfd.tlen = 0;
1623 bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
1624 PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
1625 slen = SMALL_FILE_LEN_3((3 * 1024) - (1024)) + SMALL_FILE_HEADER_SIZE(64);
1626 if (bytes != slen) {
1627 fprintf(stderrstderr,
1628 "socket: Error - 6. PR_SendFile send_size = %d, bytes sent = %d\n",
1629 slen, bytes);
1630 fprintf(stderrstderr,
1631 "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
1632 PR_GetError(), PR_GetOSError());
1633 failed_already=1;
1634 }
1635 /*
1636 * case 7: partial large file at non-zero offset till end-of-file, with header
1637 */
1638 sfd.fd = local_large_file_fd;
1639 sfd.file_offset = LARGE_FILE_OFFSET_3(2 * 1024 * 1024 - 128);
1640 sfd.file_nbytes = 0; /* data until end-of-file */
1641 sfd.header = large_file_header;
1642 sfd.hlen = LARGE_FILE_HEADER_SIZE(512);
1643 sfd.trailer = NULL((void*)0);
1644 sfd.tlen = 0;
1645 bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
1646 PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
1647 slen = LARGE_FILE_LEN_3((3 * 1024 * 1024) - (2 * 1024 * 1024 - 128)) + LARGE_FILE_HEADER_SIZE(512);
1648 if (bytes != slen) {
1649 fprintf(stderrstderr,
1650 "socket: Error - 7. PR_SendFile send_size = %d, bytes sent = %d\n",
1651 slen, bytes);
1652 fprintf(stderrstderr,
1653 "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
1654 PR_GetError(), PR_GetOSError());
1655 failed_already=1;
1656 }
1657 /*
1658 * case 8: partial large file at non-zero page-aligned offset,
1659 * with header and trailer
1660 */
1661 sfd.fd = local_large_file_fd;
1662 sfd.file_offset = LARGE_FILE_OFFSET_4PR_GetPageSize();
1663 sfd.file_nbytes = LARGE_FILE_LEN_4769;
1664 sfd.header = large_file_header;
1665 sfd.hlen = LARGE_FILE_HEADER_SIZE(512);
1666 sfd.trailer = large_file_trailer;
1667 sfd.tlen = LARGE_FILE_TRAILER_SIZE(64);
1668 bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_CLOSE_SOCKET,
1669 PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
1670 slen = LARGE_FILE_LEN_4769 + LARGE_FILE_HEADER_SIZE(512) +
1671 LARGE_FILE_TRAILER_SIZE(64);
1672 if (bytes != slen) {
1673 fprintf(stderrstderr,
1674 "socket: Error - 2. PR_SendFile send_size = %d, bytes sent = %d\n",
1675 slen, bytes);
1676 fprintf(stderrstderr,
1677 "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
1678 PR_GetError(), PR_GetOSError());
1679 failed_already=1;
1680 }
1681done:
1682 if (local_small_file_fd != NULL((void*)0)) {
1683 PR_Close(local_small_file_fd);
1684 }
1685 if (local_large_file_fd != NULL((void*)0)) {
1686 PR_Close(local_large_file_fd);
1687 }
1688}
1689
1690/*
1691 * TransmitFile Server
1692 * Server Thread
1693 * Bind an address to a socket and listen for incoming connections
1694 * Create worker threads to service clients
1695 */
1696static void
1697TransmitFile_Server(void *arg)
1698{
1699 PRThread **t = NULL((void*)0); /* an array of PRThread pointers */
1700 Server_Param *sp = (Server_Param *) arg;
1701 Serve_Client_Param *scp;
1702 PRFileDesc *sockfd = NULL((void*)0), *newsockfd;
1703 PRNetAddr netaddr;
1704 PRInt32 i;
1705
1706 t = (PRThread**)PR_MALLOC(num_transmitfile_clients * sizeof(PRThread *))(PR_Malloc((num_transmitfile_clients * sizeof(PRThread *))));
1707 if (t == NULL((void*)0)) {
1708 fprintf(stderrstderr, "prsocket_test: run out of memory\n");
1709 failed_already=1;
1710 goto exit;
1711 }
1712 /*
1713 * Create a tcp socket
1714 */
1715 if ((sockfd = PR_OpenTCPSocket(PR_AF_INET2)) == NULL((void*)0)) {
1716 fprintf(stderrstderr,"prsocket_test: PR_OpenTCPSocket failed\n");
1717 failed_already=1;
1718 goto exit;
1719 }
1720 memset(&netaddr, 0, sizeof(netaddr));
1721 netaddr.inet.family = PR_AF_INET2;
1722 netaddr.inet.port = PR_htons(TCP_SERVER_PORT10000);
1723 netaddr.inet.ip = PR_htonl(PR_INADDR_ANY((in_addr_t) 0x00000000));
1724 /*
1725 * try a few times to bind server's address, if addresses are in
1726 * use
1727 */
1728 i = 0;
1729 while (PR_Bind(sockfd, &netaddr) < 0) {
1730 if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR(-5982L)) {
1731 netaddr.inet.port += 2;
1732 if (i++ < SERVER_MAX_BIND_COUNT100) {
1733 continue;
1734 }
1735 }
1736 fprintf(stderrstderr,"prsocket_test: ERROR - PR_Bind failed\n");
1737 failed_already=1;
1738 perror("PR_Bind");
1739 goto exit;
1740 }
1741
1742 if (PR_Listen(sockfd, 32) < 0) {
1743 fprintf(stderrstderr,"prsocket_test: ERROR - PR_Listen failed\n");
1744 failed_already=1;
1745 goto exit;
1746 }
1747
1748 if (PR_GetSockName(sockfd, &netaddr) < 0) {
1749 fprintf(stderrstderr,
1750 "prsocket_test: ERROR - PR_GetSockName failed\n");
1751 failed_already=1;
1752 goto exit;
1753 }
1754
1755 DPRINTF(("TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",if (_debug_on) printf ("TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n"
, netaddr.inet.ip, netaddr.inet.port)
1756 netaddr.inet.ip, netaddr.inet.port))if (_debug_on) printf ("TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n"
, netaddr.inet.ip, netaddr.inet.port)
;
1757 tcp_server_addr.inet.family = netaddr.inet.family;
1758 tcp_server_addr.inet.port = netaddr.inet.port;
1759 tcp_server_addr.inet.ip = netaddr.inet.ip;
1760
1761 /*
1762 * Wake up parent thread because server address is bound and made
1763 * available in the global variable 'tcp_server_addr'
1764 */
1765 PR_PostSem(sp->addr_sem);
1766
1767 for (i = 0; i < num_transmitfile_clients ; i++) {
1768 /* test both null and non-null 'addr' argument to PR_Accept */
1769 PRNetAddr *addrp = (i%2 ? &netaddr: NULL((void*)0));
1770
1771 if ((newsockfd = PR_Accept(sockfd, addrp,
1772 PR_INTERVAL_NO_TIMEOUT0xffffffffUL)) == NULL((void*)0)) {
1773 fprintf(stderrstderr,
1774 "prsocket_test: ERROR - PR_Accept failed\n");
1775 failed_already=1;
1776 goto exit;
1777 }
1778 /* test both regular and emulated PR_SendFile */
1779 if (i%2) {
1780 PRFileDesc *layer = PR_CreateIOLayerStub(
1781 emuSendFileIdentity, &emuSendFileMethods);
1782 if (layer == NULL((void*)0)) {
1783 fprintf(stderrstderr,
1784 "prsocket_test: ERROR - PR_CreateIOLayerStub failed\n");
1785 failed_already=1;
1786 goto exit;
1787 }
1788 if (PR_PushIOLayer(newsockfd, PR_TOP_IO_LAYER(PRDescIdentity)-2, layer)
1789 == PR_FAILURE) {
1790 fprintf(stderrstderr,
1791 "prsocket_test: ERROR - PR_PushIOLayer failed\n");
1792 failed_already=1;
1793 goto exit;
1794 }
1795 }
1796 scp = PR_NEW(Serve_Client_Param)((Serve_Client_Param *) (PR_Malloc((sizeof(Serve_Client_Param
)))))
;
1797 if (scp == NULL((void*)0)) {
1798 fprintf(stderrstderr,"prsocket_test: PR_NEW failed\n");
1799 failed_already=1;
1800 goto exit;
1801 }
1802
1803 /*
1804 * Start a Serve_Client thread for each incoming connection
1805 */
1806 scp->sockfd = newsockfd;
1807 scp->datalen = sp->datalen;
1808
1809 t[i] = PR_CreateThread(PR_USER_THREAD,
1810 Serve_TransmitFile_Client, (void *)scp,
1811 PR_PRIORITY_NORMAL,
1812 PR_LOCAL_THREAD,
1813 PR_JOINABLE_THREAD,
1814 0);
1815 if (t[i] == NULL((void*)0)) {
1816 fprintf(stderrstderr,
1817 "prsocket_test: PR_CreateThread failed\n");
1818 failed_already=1;
1819 goto exit;
1820 }
1821 DPRINTF(("TransmitFile_Server: Created Serve_TransmitFile_Client = 0x%lx\n", t))if (_debug_on) printf ("TransmitFile_Server: Created Serve_TransmitFile_Client = 0x%lx\n"
, t)
;
1822 }
1823
1824 /*
1825 * Wait for all the worker threads to end, so that we know
1826 * they are no longer using the small and large file fd's.
1827 */
1828
1829 for (i = 0; i < num_transmitfile_clients; i++) {
1830 PR_JoinThread(t[i]);
1831 }
1832
1833exit:
1834 if (t) {
1835 PR_DELETE(t){ PR_Free(t); (t) = ((void*)0); };
1836 }
1837 if (sockfd) {
1838 PR_Close(sockfd);
1839 }
1840
1841 /*
1842 * Decrement exit_counter and notify parent thread
1843 */
1844
1845 PR_EnterMonitor(sp->exit_mon);
1846 --(*sp->exit_counter);
1847 PR_Notify(sp->exit_mon);
1848 PR_ExitMonitor(sp->exit_mon);
1849 DPRINTF(("TransmitFile_Server [0x%lx] exiting\n", PR_GetCurrentThread()))if (_debug_on) printf ("TransmitFile_Server [0x%lx] exiting\n"
, PR_GetCurrentThread())
;
1850}
1851
1852/*
1853 * Socket_Misc_Test - test miscellaneous functions
1854 *
1855 */
1856static PRInt32
1857Socket_Misc_Test(void)
1858{
1859 PRIntn i, rv = 0, bytes, count, len;
1860 PRThread *t;
1861 PRSemaphore *server_sem;
1862 Server_Param *sparamp;
1863 Client_Param *cparamp;
1864 PRMonitor *mon2;
1865 PRInt32 datalen;
1866
1867 /*
1868 * We deliberately pick a buffer size that is not a nice multiple
1869 * of 1024.
1870 */
1871#define TRANSMITFILE_BUF_SIZE(4 * 1024 - 11) (4 * 1024 - 11)
1872
1873 typedef struct {
1874 char data[TRANSMITFILE_BUF_SIZE(4 * 1024 - 11)];
1875 } file_buf;
1876 file_buf *buf = NULL((void*)0);
1877
1878 /*
1879 * create file(s) to be transmitted
1880 */
1881 if ((PR_MkDir(TEST_DIR, 0777)) < 0) {
1882 printf("prsocket_test failed to create dir %s\n",TEST_DIR);
1883 failed_already=1;
1884 return -1;
1885 }
1886
1887 small_file_fd = PR_Open(SMALL_FILE_NAME, PR_RDWR0x04 | PR_CREATE_FILE0x08,0777);
1888
1889 if (small_file_fd == NULL((void*)0)) {
1890 fprintf(stderrstderr,"prsocket_test failed to create/open file %s\n",
1891 SMALL_FILE_NAME);
1892 failed_already=1;
1893 rv = -1;
1894 goto done;
1895 }
1896 buf = PR_NEW(file_buf)((file_buf *) (PR_Malloc((sizeof(file_buf)))));
1897 if (buf == NULL((void*)0)) {
1898 fprintf(stderrstderr,"prsocket_test failed to allocate buffer\n");
1899 failed_already=1;
1900 rv = -1;
1901 goto done;
1902 }
1903 /*
1904 * fill in random data
1905 */
1906 for (i = 0; i < TRANSMITFILE_BUF_SIZE(4 * 1024 - 11); i++) {
1907 buf->data[i] = i;
1908 }
1909 count = 0;
1910 do {
1911 len = (SMALL_FILE_SIZE(3 * 1024) - count) > TRANSMITFILE_BUF_SIZE(4 * 1024 - 11) ?
1912 TRANSMITFILE_BUF_SIZE(4 * 1024 - 11) : (SMALL_FILE_SIZE(3 * 1024) - count);
1913 bytes = PR_Write(small_file_fd, buf->data, len);
1914 if (bytes <= 0) {
1915 fprintf(stderrstderr,
1916 "prsocket_test failed to write to file %s\n",
1917 SMALL_FILE_NAME);
1918 failed_already=1;
1919 rv = -1;
1920 goto done;
1921 }
1922 count += bytes;
1923 } while (count < SMALL_FILE_SIZE(3 * 1024));
1924#ifdef XP_UNIX1
1925 /*
1926 * map the small file; used in checking for data corruption
1927 */
1928 small_file_addr = mmap(0, SMALL_FILE_SIZE(3 * 1024), PROT_READ0x1,
1929 MAP_SHARED0x01, small_file_fd->secret->md.osfd, 0);
1930 if (small_file_addr == (void *) -1) {
1931 fprintf(stderrstderr,"prsocket_test failed to mmap file %s\n",
1932 SMALL_FILE_NAME);
1933 failed_already=1;
1934 rv = -1;
1935 goto done;
1936 }
1937#endif
1938 /*
1939 * header for small file
1940 */
1941 small_file_header = PR_MALLOC(SMALL_FILE_HEADER_SIZE)(PR_Malloc(((64))));
1942 if (small_file_header == NULL((void*)0)) {
1943 fprintf(stderrstderr,"prsocket_test failed to malloc header file\n");
1944 failed_already=1;
1945 rv = -1;
1946 goto done;
1947 }
1948 memset(small_file_header, (int) PR_IntervalNow(),
1949 SMALL_FILE_HEADER_SIZE(64));
1950 /*
1951 * trailer for small file
1952 */
1953 small_file_trailer = PR_MALLOC(SMALL_FILE_TRAILER_SIZE)(PR_Malloc(((128))));
1954 if (small_file_trailer == NULL((void*)0)) {
1955 fprintf(stderrstderr,"prsocket_test failed to malloc header trailer\n");
1956 failed_already=1;
1957 rv = -1;
1958 goto done;
1959 }
1960 memset(small_file_trailer, (int) PR_IntervalNow(),
1961 SMALL_FILE_TRAILER_SIZE(128));
1962 /*
1963 * setup large file
1964 */
1965 large_file_fd = PR_Open(LARGE_FILE_NAME, PR_RDWR0x04 | PR_CREATE_FILE0x08,0777);
1966
1967 if (large_file_fd == NULL((void*)0)) {
1968 fprintf(stderrstderr,"prsocket_test failed to create/open file %s\n",
1969 LARGE_FILE_NAME);
1970 failed_already=1;
1971 rv = -1;
1972 goto done;
1973 }
1974 /*
1975 * fill in random data
1976 */
1977 for (i = 0; i < TRANSMITFILE_BUF_SIZE(4 * 1024 - 11); i++) {
1978 buf->data[i] = i;
1979 }
1980 count = 0;
1981 do {
1982 len = (LARGE_FILE_SIZE(3 * 1024 * 1024) - count) > TRANSMITFILE_BUF_SIZE(4 * 1024 - 11) ?
1983 TRANSMITFILE_BUF_SIZE(4 * 1024 - 11) : (LARGE_FILE_SIZE(3 * 1024 * 1024) - count);
1984 bytes = PR_Write(large_file_fd, buf->data, len);
1985 if (bytes <= 0) {
1986 fprintf(stderrstderr,
1987 "prsocket_test failed to write to file %s: (%ld, %ld)\n",
1988 LARGE_FILE_NAME,
1989 PR_GetError(), PR_GetOSError());
1990 failed_already=1;
1991 rv = -1;
1992 goto done;
1993 }
1994 count += bytes;
1995 } while (count < LARGE_FILE_SIZE(3 * 1024 * 1024));
1996#if defined(XP_UNIX1)
1997 /*
1998 * map the large file; used in checking for data corruption
1999 */
2000 large_file_addr = mmap(0, LARGE_FILE_SIZE(3 * 1024 * 1024), PROT_READ0x1,
2001 MAP_SHARED0x01, large_file_fd->secret->md.osfd, 0);
2002 if (large_file_addr == (void *) -1) {
2003 fprintf(stderrstderr,"prsocket_test failed to mmap file %s\n",
2004 LARGE_FILE_NAME);
2005 failed_already=1;
2006 rv = -1;
2007 goto done;
2008 }
2009#endif
2010 /*
2011 * header for large file
2012 */
2013 large_file_header = PR_MALLOC(LARGE_FILE_HEADER_SIZE)(PR_Malloc(((512))));
2014 if (large_file_header == NULL((void*)0)) {
2015 fprintf(stderrstderr,"prsocket_test failed to malloc header file\n");
2016 failed_already=1;
2017 rv = -1;
2018 goto done;
2019 }
2020 memset(large_file_header, (int) PR_IntervalNow(),
2021 LARGE_FILE_HEADER_SIZE(512));
2022 /*
2023 * trailer for large file
2024 */
2025 large_file_trailer = PR_MALLOC(LARGE_FILE_TRAILER_SIZE)(PR_Malloc(((64))));
2026 if (large_file_trailer == NULL((void*)0)) {
2027 fprintf(stderrstderr,"prsocket_test failed to malloc header trailer\n");
2028 failed_already=1;
2029 rv = -1;
2030 goto done;
2031 }
2032 memset(large_file_trailer, (int) PR_IntervalNow(),
2033 LARGE_FILE_TRAILER_SIZE(64));
2034
2035 datalen = tcp_mesg_size;
2036 thread_count = 0;
2037 /*
2038 * start the server thread
2039 */
2040 sparamp = PR_NEW(Server_Param)((Server_Param *) (PR_Malloc((sizeof(Server_Param)))));
2041 if (sparamp == NULL((void*)0)) {
2042 fprintf(stderrstderr,"prsocket_test: PR_NEW failed\n");
2043 failed_already=1;
2044 rv = -1;
2045 goto done;
2046 }
2047 server_sem = PR_NewSem(0);
2048 if (server_sem == NULL((void*)0)) {
2049 fprintf(stderrstderr,"prsocket_test: PR_NewSem failed\n");
2050 failed_already=1;
2051 rv = -1;
2052 goto done;
2053 }
2054 mon2 = PR_NewMonitor();
2055 if (mon2 == NULL((void*)0)) {
2056 fprintf(stderrstderr,"prsocket_test: PR_NewMonitor failed\n");
2057 failed_already=1;
2058 rv = -1;
2059 goto done;
2060 }
2061 PR_EnterMonitor(mon2);
2062
2063 sparamp->addr_sem = server_sem;
2064 sparamp->exit_mon = mon2;
2065 sparamp->exit_counter = &thread_count;
2066 sparamp->datalen = datalen;
2067 t = PR_CreateThread(PR_USER_THREAD,
2068 TransmitFile_Server, (void *)sparamp,
2069 PR_PRIORITY_NORMAL,
2070 PR_LOCAL_THREAD,
2071 PR_UNJOINABLE_THREAD,
2072 0);
2073 if (t == NULL((void*)0)) {
2074 fprintf(stderrstderr,"prsocket_test: PR_CreateThread failed\n");
2075 failed_already=1;
2076 rv = -1;
2077 goto done;
2078 }
2079 DPRINTF(("Created TCP server = 0x%x\n", t))if (_debug_on) printf ("Created TCP server = 0x%x\n", t);
2080 thread_count++;
2081
2082 /*
2083 * wait till the server address is setup
2084 */
2085 PR_WaitSem(server_sem);
2086
2087 /*
2088 * Now start a bunch of client threads
2089 */
2090
2091 cparamp = PR_NEW(Client_Param)((Client_Param *) (PR_Malloc((sizeof(Client_Param)))));
2092 if (cparamp == NULL((void*)0)) {
2093 fprintf(stderrstderr,"prsocket_test: PR_NEW failed\n");
2094 failed_already=1;
2095 rv = -1;
2096 goto done;
2097 }
2098 cparamp->server_addr = tcp_server_addr;
2099 cparamp->server_addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK((in_addr_t) 0x7f000001));
2100 cparamp->exit_mon = mon2;
2101 cparamp->exit_counter = &thread_count;
2102 cparamp->datalen = datalen;
2103 for (i = 0; i < num_transmitfile_clients; i++) {
2104 t = create_new_thread(PR_USER_THREAD,
2105 TransmitFile_Client, (void *) cparamp,
2106 PR_PRIORITY_NORMAL,
2107 PR_LOCAL_THREAD,
2108 PR_UNJOINABLE_THREAD,
2109 0, i);
2110 if (t == NULL((void*)0)) {
2111 fprintf(stderrstderr,"prsocket_test: PR_CreateThread failed\n");
2112 rv = -1;
2113 failed_already=1;
2114 goto done;
2115 }
2116 DPRINTF(("Created TransmitFile client = 0x%lx\n", t))if (_debug_on) printf ("Created TransmitFile client = 0x%lx\n"
, t)
;
2117 thread_count++;
2118 }
2119 /* Wait for server and client threads to exit */
2120 while (thread_count) {
2121 PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
2122 DPRINTF(("Socket_Misc_Test - thread_count = %d\n", thread_count))if (_debug_on) printf ("Socket_Misc_Test - thread_count = %d\n"
, thread_count)
;
2123 }
2124 PR_ExitMonitor(mon2);
2125done:
2126 if (buf) {
2127 PR_DELETE(buf){ PR_Free(buf); (buf) = ((void*)0); };
2128 }
2129#if defined(XP_UNIX1)
2130 munmap((char*)small_file_addr, SMALL_FILE_SIZE(3 * 1024));
2131 munmap((char*)large_file_addr, LARGE_FILE_SIZE(3 * 1024 * 1024));
2132#endif
2133 PR_Close(small_file_fd);
2134 PR_Close(large_file_fd);
2135 if ((PR_Delete(SMALL_FILE_NAME)) == PR_FAILURE) {
2136 fprintf(stderrstderr,"prsocket_test: failed to unlink file %s\n",
2137 SMALL_FILE_NAME);
2138 failed_already=1;
2139 }
2140 if ((PR_Delete(LARGE_FILE_NAME)) == PR_FAILURE) {
2141 fprintf(stderrstderr,"prsocket_test: failed to unlink file %s\n",
2142 LARGE_FILE_NAME);
2143 failed_already=1;
2144 }
2145 if ((PR_RmDir(TEST_DIR)) == PR_FAILURE) {
2146 fprintf(stderrstderr,"prsocket_test failed to rmdir %s: (%ld, %ld)\n",
2147 TEST_DIR, PR_GetError(), PR_GetOSError());
2148 failed_already=1;
2149 }
2150
2151 printf("%-29s%s","Socket_Misc_Test",":");
2152 printf("%2d Server %2d Clients\n",1, num_transmitfile_clients);
2153 printf("%30s Sizes of Transmitted Files - %4d KB, %2d MB \n",":",
2154 SMALL_FILE_SIZE(3 * 1024)/1024, LARGE_FILE_SIZE(3 * 1024 * 1024)/(1024 * 1024));
2155
2156
2157 return rv;
2158}
2159/************************************************************************/
2160
2161/*
2162 * Test Socket NSPR APIs
2163 */
2164
2165int main(int argc, char **argv)
2166{
2167 /*
2168 * -d debug mode
2169 */
2170
2171 PLOptStatus os;
2172 PLOptState *opt = PL_CreateOptState(argc, argv, "d");
2173 while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
2174 {
2175 if (PL_OPT_BAD == os) {
2176 continue;
2177 }
2178 switch (opt->option)
2179 {
2180 case 'd': /* debug mode */
2181 _debug_on = 1;
2182 break;
2183 default:
2184 break;
2185 }
2186 }
2187 PL_DestroyOptState(opt);
2188
2189 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
2190 PR_STDIO_INIT();
2191
2192 PR_SetConcurrency(4);
2193
2194 emuSendFileIdentity = PR_GetUniqueIdentity("Emulated SendFile");
2195 emuSendFileMethods = *PR_GetDefaultIOMethods();
2196 emuSendFileMethods.transmitfile = emu_TransmitFile;
2197 emuSendFileMethods.sendfile = emu_SendFile;
2198
2199 /*
2200 * run client-server test with TCP, Ipv4-Ipv4
2201 */
2202 printf("TCP Client/Server Test - IPv4/Ipv4\n");
2203 if (TCP_Socket_Client_Server_Test() < 0) {
2204 printf("TCP_Socket_Client_Server_Test failed\n");
2205 goto done;
2206 } else {
2207 printf("TCP_Socket_Client_Server_Test Passed\n");
2208 }
2209 /*
2210 * client-server test, Ipv6-Ipv4
2211 */
2212 client_domain = PR_AF_INET610;
2213 printf("TCP Client/Server Test - IPv6/Ipv4\n");
2214 if (TCP_Socket_Client_Server_Test() < 0) {
2215 printf("TCP_Socket_Client_Server_Test failed\n");
2216 goto done;
2217 } else {
2218 printf("TCP_Socket_Client_Server_Test Passed\n");
2219 }
2220 /*
2221 * client-server test, Ipv4-Ipv6
2222 */
2223 client_domain = PR_AF_INET2;
2224 server_domain = PR_AF_INET610;
2225 printf("TCP Client/Server Test - IPv4/Ipv6\n");
2226 if (TCP_Socket_Client_Server_Test() < 0) {
2227 printf("TCP_Socket_Client_Server_Test failed\n");
2228 goto done;
2229 } else {
2230 printf("TCP_Socket_Client_Server_Test Passed\n");
2231 }
2232 /*
2233 * client-server test, Ipv6-Ipv6
2234 */
2235 client_domain = PR_AF_INET610;
2236 server_domain = PR_AF_INET610;
2237 printf("TCP Client/Server Test - IPv6/Ipv6\n");
2238 if (TCP_Socket_Client_Server_Test() < 0) {
2239 printf("TCP_Socket_Client_Server_Test failed\n");
2240 goto done;
2241 } else {
2242 printf("TCP_Socket_Client_Server_Test Passed\n");
2243 }
2244 test_cancelio = 0;
2245
2246 /*
2247 * Misc socket tests - including transmitfile, etc.
2248 */
2249
2250 /* File transmission test can not be done in Symbian OS because of
2251 * large file's size and the incomplete mmap() implementation. */
2252#if !defined(WIN16)
2253 /*
2254 ** The 'transmit file' test does not run because
2255 ** transmit file is not implemented in NSPR yet.
2256 **
2257 */
2258 if (Socket_Misc_Test() < 0) {
2259 printf("Socket_Misc_Test failed\n");
2260 failed_already=1;
2261 goto done;
2262 } else {
2263 printf("Socket_Misc_Test passed\n");
2264 }
2265
2266 /*
2267 * run client-server test with TCP again to test
2268 * recycling used sockets from PR_TransmitFile().
2269 */
2270 if (TCP_Socket_Client_Server_Test() < 0) {
2271 printf("TCP_Socket_Client_Server_Test failed\n");
2272 goto done;
2273 } else {
2274 printf("TCP_Socket_Client_Server_Test Passed\n");
2275 }
2276#endif
2277
2278done:
2279 PR_Cleanup();
2280 if (failed_already) {
2281 return 1;
2282 }
2283 else {
2284 return 0;
2285 }
2286}