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