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
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/
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
15 * The Original Code is the Netscape Portable Runtime (NSPR).
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.
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.
36 * ***** END LICENSE BLOCK ***** */
38 /***********************************************************************
42 ** Description: Test socket functionality.
44 ** Modification History:
56 #if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
64 static int _debug_on
= 0;
65 static int test_cancelio
= 0;
70 int fprintf(FILE *stream
, const char *fmt
, ...)
75 #define printf PR_LogPrint
76 extern void SetupMacPrintfLog(char *logFile
);
78 #include "obsolete/prsem.h"
85 #define DPRINTF(arg) if (_debug_on) printf arg
88 char *TEST_DIR
= "prdir";
89 char *SMALL_FILE_NAME
= "prsmallf";
90 char *LARGE_FILE_NAME
= "prlargef";
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";
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 */
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)
118 #define BUF_DATA_SIZE (2 * 1024)
119 #define TCP_MESG_SIZE 1024
121 * set UDP datagram size small enough that datagrams sent to a port on the
122 * local host will not be lost
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
129 #define NUM_TRANSMITFILE_CLIENTS 4
131 /* Mac can't handle more than 2* (3Mb) allocations for large file size buffers */
132 #define NUM_TRANSMITFILE_CLIENTS 2
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
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
;
151 static PRInt32 thread_count
;
152 PRUint16 server_domain
= PR_AF_INET
, client_domain
= PR_AF_INET
;
154 /* an I/O layer that uses the emulated senfile method */
155 static PRDescIdentity emuSendFileIdentity
;
156 static PRIOMethods emuSendFileMethods
;
158 int failed_already
=0;
159 typedef struct buffer
{
160 char data
[BUF_DATA_SIZE
];
163 PRNetAddr tcp_server_addr
, udp_server_addr
;
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
;
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 */
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 */
183 PRInt32 udp_connect
; /* if set clients connect udp sockets */
186 /* the sendfile method in emuSendFileMethods */
187 static PRInt32 PR_CALLBACK
188 emu_SendFile(PRFileDesc
*sd
, PRSendFileData
*sfd
,
189 PRTransmitFileFlags flags
, PRIntervalTime timeout
)
191 return PR_EmulateSendFile(sd
, sfd
, flags
, timeout
);
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
)
204 sfd
.header
= headers
;
208 return emu_SendFile(sd
, &sfd
, flags
, timeout
);
213 * read data from sockfd into buf
216 readn(PRFileDesc
*sockfd
, char *buf
, int len
)
222 PRIntervalTime timeout
= PR_INTERVAL_NO_TIMEOUT
;
225 timeout
= PR_SecondsToInterval(2);
227 for (rem
=len
; rem
; offset
+= bytes
, rem
-= bytes
) {
228 DPRINTF(("thread = 0x%lx: calling PR_Recv, bytes = %d\n",
229 PR_GetCurrentThread(), rem
));
231 bytes
= PR_Recv(sockfd
, buf
+ offset
, rem
, 0,
233 DPRINTF(("thread = 0x%lx: returning from PR_Recv, bytes = %d\n",
234 PR_GetCurrentThread(), bytes
));
237 printf("PR_Recv: error = %d oserr = %d\n",(err
= PR_GetError()),
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
;
254 * write data from buf to sockfd
257 writen(PRFileDesc
*sockfd
, char *buf
, int len
)
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
));
278 * Thread, started by the server, for serving a client connection.
279 * Reads data from socket and writes it back, unmodified, and
282 static void PR_CALLBACK
283 Serve_Client(void *arg
)
285 Serve_Client_Param
*scp
= (Serve_Client_Param
*) arg
;
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");
300 for (j
= 0; j
< num_tcp_mesgs_per_connection
; j
++) {
302 * Read data from client and send it back to the client unmodified
304 if (readn(sockfd
, in_buf
->data
, bytes
) < bytes
) {
305 fprintf(stderr
,"prsocket_test: ERROR - Serve_Client:readn\n");
310 * shutdown reads, after the last read
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");
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");
325 * shutdown reads and writes
327 if (PR_Shutdown(sockfd
, PR_SHUTDOWN_BOTH
) < 0) {
328 fprintf(stderr
,"prsocket_test: ERROR - PR_Shutdown\n");
339 PRThread
* create_new_thread(PRThreadType type
,
340 void (*start
)(void *arg
),
342 PRThreadPriority priority
,
345 PRUint32 stackSize
, PRInt32 index
)
347 PRInt32 native_thread
= 0;
349 PR_ASSERT(state
== PR_UNJOINABLE_THREAD
);
350 #if (defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)) || defined(WIN32)
353 scope
= (PR_LOCAL_THREAD
);
356 scope
= (PR_GLOBAL_THREAD
);
359 scope
= (PR_GLOBAL_BOUND_THREAD
);
365 PR_ASSERT(!"Invalid scope");
369 #if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
371 if (!pthread_create(&tid
, NULL
, (void * (*)(void *)) start
, arg
))
372 return((PRThread
*) tid
);
379 thandle
= (HANDLE
) _beginthreadex(
382 (unsigned (__stdcall
*)(void *))start
,
386 return((PRThread
*) thandle
);
389 return(PR_CreateThread(type
,start
,arg
,priority
,scope
,state
,stackSize
));
392 return(PR_CreateThread(type
,start
,arg
,priority
,scope
,state
,stackSize
));
399 * Bind an address to a socket and listen for incoming connections
400 * Start a Serve_Client thread for each incoming connection.
402 static void PR_CALLBACK
403 TCP_Server(void *arg
)
406 Server_Param
*sp
= (Server_Param
*) arg
;
407 Serve_Client_Param
*scp
;
408 PRFileDesc
*sockfd
, *newsockfd
;
412 * Create a tcp socket
414 if ((sockfd
= PR_OpenTCPSocket(server_domain
)) == NULL
) {
415 fprintf(stderr
,"prsocket_test: PR_NewTCPSocket failed\n");
418 memset(&netaddr
, 0 , sizeof(netaddr
));
420 if (PR_SetNetAddr(PR_IpAddrAny
, server_domain
, TCP_SERVER_PORT
,
421 &netaddr
) == PR_FAILURE
) {
422 fprintf(stderr
,"prsocket_test: PR_SetNetAddr failed\n");
426 * try a few times to bind server's address, if addresses are in
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
)
437 fprintf(stderr
,"prsocket_test: ERROR - PR_Bind failed\n");
443 if (PR_Listen(sockfd
, 32) < 0) {
444 fprintf(stderr
,"prsocket_test: ERROR - PR_Listen failed\n");
449 if (PR_GetSockName(sockfd
, &netaddr
) < 0) {
450 fprintf(stderr
,"prsocket_test: ERROR - PR_GetSockName failed\n");
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");
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
);
468 * Wake up parent thread because server address is bound and made
469 * available in the global variable 'tcp_server_addr'
471 PR_PostSem(sp
->addr_sem
);
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
);
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");
483 DPRINTF(("TCP_Server: Accepted connection\n"));
484 scp
= PR_NEW(Serve_Client_Param
);
486 fprintf(stderr
,"prsocket_test: PR_NEW failed\n");
491 * Start a Serve_Client thread for each incoming connection
493 scp
->sockfd
= newsockfd
;
494 scp
->datalen
= sp
->datalen
;
496 t
= create_new_thread(PR_USER_THREAD
,
497 Serve_Client
, (void *)scp
,
500 PR_UNJOINABLE_THREAD
,
503 fprintf(stderr
,"prsocket_test: PR_CreateThread failed\n");
507 DPRINTF(("TCP_Server: Created Serve_Client = 0x%lx\n", t
));
516 * Decrement exit_counter and notify parent thread
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()));
529 * Bind an address to a socket, read data from clients and send data
532 static void PR_CALLBACK
533 UDP_Server(void *arg
)
535 Server_Param
*sp
= (Server_Param
*) arg
;
539 PRInt32 bytes
, i
, rv
= 0;
544 * Create a udp socket
546 if ((sockfd
= PR_OpenUDPSocket(server_domain
)) == NULL
) {
547 fprintf(stderr
,"prsocket_test: PR_NewUDPSocket failed\n");
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");
559 * try a few times to bind server's address, if addresses are in
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
)
569 fprintf(stderr
,"prsocket_test: ERROR - PR_Bind failed\n");
575 if (PR_GetSockName(sockfd
, &netaddr
) < 0) {
576 fprintf(stderr
,"prsocket_test: ERROR - PR_GetSockName failed\n");
581 DPRINTF(("PR_Bind: UDP Server netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",
582 netaddr
.inet
.ip
, netaddr
.inet
.port
));
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).
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");
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
);
601 * Wake up parent thread because server address is bound and made
602 * available in the global variable 'udp_server_addr'
604 PR_PostSem(sp
->addr_sem
);
607 in_buf
= PR_NEW(buffer
);
608 if (in_buf
== NULL
) {
609 fprintf(stderr
,"prsocket_test: failed to alloc buffer struct\n");
614 * Receive datagrams from clients and send them back, unmodified, to the
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
,
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
,
631 rv
= PR_SendTo(sockfd
, in_buf
->data
, bytes
, 0, &netaddr
,
632 PR_INTERVAL_NO_TIMEOUT
);
642 * Decrement exit_counter and notify parent thread
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()));
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
659 static void PR_CALLBACK
660 TCP_Client(void *arg
)
662 Client_Param
*cp
= (Client_Param
*) arg
;
664 buffer
*in_buf
, *out_buf
;
665 union PRNetAddr netaddr
;
670 out_buf
= PR_NEW(buffer
);
671 if (out_buf
== NULL
) {
672 fprintf(stderr
,"prsocket_test: failed to alloc buffer struct\n");
676 in_buf
= PR_NEW(buffer
);
677 if (in_buf
== NULL
) {
678 fprintf(stderr
,"prsocket_test: failed to alloc buffer struct\n");
682 netaddr
= cp
->server_addr
;
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");
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());
696 for (j
= 0; j
< num_tcp_mesgs_per_connection
; j
++) {
698 * fill in random data
700 memset(out_buf
->data
, ((PRInt32
) (&netaddr
)) + i
+ j
, bytes
);
705 if (test_cancelio
&& (j
== 0))
706 PR_Sleep(PR_SecondsToInterval(12));
708 if (writen(sockfd
, out_buf
->data
, bytes
) < bytes
) {
709 fprintf(stderr
,"prsocket_test: ERROR - TCP_Client:writen\n");
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");
721 * verify the data read
723 if (memcmp(in_buf
->data
, out_buf
->data
, bytes
) != 0) {
724 fprintf(stderr
,"prsocket_test: ERROR - data corruption\n");
730 * shutdown reads and writes
732 if (PR_Shutdown(sockfd
, PR_SHUTDOWN_BOTH
) < 0) {
733 fprintf(stderr
,"prsocket_test: ERROR - PR_Shutdown\n");
743 * Decrement exit_counter and notify parent thread
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()));
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.
762 static void PR_CALLBACK
763 UDP_Client(void *arg
)
765 Client_Param
*cp
= (Client_Param
*) arg
;
767 buffer
*in_buf
, *out_buf
;
768 union PRNetAddr netaddr
;
769 PRInt32 bytes
, i
, rv
;
773 out_buf
= PR_NEW(buffer
);
774 if (out_buf
== NULL
) {
775 fprintf(stderr
,"prsocket_test: failed to alloc buffer struct\n");
779 in_buf
= PR_NEW(buffer
);
780 if (in_buf
== NULL
) {
781 fprintf(stderr
,"prsocket_test: failed to alloc buffer struct\n");
785 if ((sockfd
= PR_OpenUDPSocket(client_domain
)) == NULL
) {
786 fprintf(stderr
,"prsocket_test: PR_OpenUDPSocket failed\n");
792 * bind an address for the client, let the system chose the port
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");
802 if (PR_Bind(sockfd
, &netaddr
) < 0) {
803 fprintf(stderr
,"prsocket_test: ERROR - PR_Bind failed\n");
808 if (PR_GetSockName(sockfd
, &netaddr
) < 0) {
809 fprintf(stderr
,"prsocket_test: ERROR - PR_GetSockName failed\n");
814 DPRINTF(("PR_Bind: UDP Client netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",
815 netaddr
.inet
.ip
, netaddr
.inet
.port
));
817 netaddr
= cp
->server_addr
;
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");
827 for (i
= 0; i
< num_udp_datagrams_per_client
; i
++) {
829 * fill in random data
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
);
838 rv
= PR_Send(sockfd
, out_buf
->data
, bytes
, 0,
839 PR_INTERVAL_NO_TIMEOUT
);
841 rv
= PR_SendTo(sockfd
, out_buf
->data
, bytes
, 0, &netaddr
,
842 PR_INTERVAL_NO_TIMEOUT
);
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
))));
849 rv
= PR_Recv(sockfd
, in_buf
->data
, bytes
, 0,
850 PR_INTERVAL_NO_TIMEOUT
);
852 rv
= PR_RecvFrom(sockfd
, in_buf
->data
, bytes
, 0, &netaddr
,
853 PR_INTERVAL_NO_TIMEOUT
);
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
))));
860 * verify the data read
862 if (memcmp(in_buf
->data
, out_buf
->data
, bytes
) != 0) {
863 fprintf(stderr
,"prsocket_test: ERROR - UDP data corruption\n");
874 * Decrement exit_counter and notify parent thread
877 PR_EnterMonitor(cp
->exit_mon
);
878 --(*cp
->exit_counter
);
879 PR_Notify(cp
->exit_mon
);
880 PR_ExitMonitor(cp
->exit_mon
);
882 DPRINTF(("UDP_Client [0x%x] exiting\n", PR_GetCurrentThread()));
886 * TCP_Socket_Client_Server_Test - concurrent server test
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.
898 TCP_Socket_Client_Server_Test(void)
902 PRSemaphore
*server_sem
;
903 Server_Param
*sparamp
;
904 Client_Param
*cparamp
;
909 datalen
= tcp_mesg_size
;
912 * start the server thread
914 sparamp
= PR_NEW(Server_Param
);
915 if (sparamp
== NULL
) {
916 fprintf(stderr
,"prsocket_test: PR_NEW failed\n");
920 server_sem
= PR_NewSem(0);
921 if (server_sem
== NULL
) {
922 fprintf(stderr
,"prsocket_test: PR_NewSem failed\n");
926 mon2
= PR_NewMonitor();
928 fprintf(stderr
,"prsocket_test: PR_NewMonitor failed\n");
932 PR_EnterMonitor(mon2
);
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
,
942 PR_UNJOINABLE_THREAD
,
945 fprintf(stderr
,"prsocket_test: PR_CreateThread failed\n");
949 DPRINTF(("Created TCP server = 0x%lx\n", t
));
953 * wait till the server address is setup
955 PR_WaitSem(server_sem
);
958 * Now start a bunch of client threads
961 cparamp
= PR_NEW(Client_Param
);
962 if (cparamp
== NULL
) {
963 fprintf(stderr
,"prsocket_test: PR_NEW failed\n");
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
,
976 PR_UNJOINABLE_THREAD
,
979 fprintf(stderr
,"prsocket_test: PR_CreateThread failed\n");
983 DPRINTF(("Created TCP client = 0x%lx\n", t
));
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
));
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
);
1002 * UDP_Socket_Client_Server_Test - iterative server test
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.
1014 UDP_Socket_Client_Server_Test(void)
1018 PRSemaphore
*server_sem
;
1019 Server_Param
*sparamp
;
1020 Client_Param
*cparamp
;
1023 PRInt32 udp_connect
= 1;
1026 datalen
= udp_datagram_size
;
1029 * start the server thread
1031 sparamp
= PR_NEW(Server_Param
);
1032 if (sparamp
== NULL
) {
1033 fprintf(stderr
,"prsocket_test: PR_NEW failed\n");
1037 server_sem
= PR_NewSem(0);
1038 if (server_sem
== NULL
) {
1039 fprintf(stderr
,"prsocket_test: PR_NewSem failed\n");
1043 mon2
= PR_NewMonitor();
1045 fprintf(stderr
,"prsocket_test: PR_NewMonitor failed\n");
1049 PR_EnterMonitor(mon2
);
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
,
1060 PR_UNJOINABLE_THREAD
,
1063 fprintf(stderr
,"prsocket_test: PR_CreateThread failed\n");
1070 * wait till the server address is setup
1072 PR_WaitSem(server_sem
);
1075 * Now start a bunch of client threads
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");
1085 cparamp
->server_addr
= udp_server_addr
;
1086 cparamp
->exit_mon
= mon2
;
1087 cparamp
->exit_counter
= &thread_count
;
1088 cparamp
->datalen
= datalen
;
1090 * Cause every other client thread to connect udp sockets
1093 cparamp
->udp_connect
= udp_connect
;
1095 /* No support for UDP connects on Mac */
1096 cparamp
->udp_connect
= 0;
1102 DPRINTF(("Creating UDP client %d\n", i
));
1103 t
= PR_CreateThread(PR_USER_THREAD
,
1104 UDP_Client
, (void *) cparamp
,
1107 PR_UNJOINABLE_THREAD
,
1110 fprintf(stderr
,"prsocket_test: PR_CreateThread failed\n");
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
));
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
);
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
;
1134 * TransmitFile_Client
1138 TransmitFile_Client(void *arg
)
1141 union PRNetAddr netaddr
;
1142 char *small_buf
, *large_buf
;
1143 Client_Param
*cp
= (Client_Param
*) arg
;
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");
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");
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
;
1164 if ((sockfd
= PR_NewTCPSocket()) == NULL
) {
1165 fprintf(stderr
,"prsocket_test: PR_NewTCPSocket failed\n");
1170 if (PR_Connect(sockfd
, &netaddr
,PR_INTERVAL_NO_TIMEOUT
) < 0){
1171 fprintf(stderr
,"prsocket_test: PR_Connect failed\n");
1176 * read the small file and verify the data
1178 if (readn(sockfd
, small_buf
, SMALL_FILE_SIZE
+ SMALL_FILE_HEADER_SIZE
)
1179 != (SMALL_FILE_SIZE
+ SMALL_FILE_HEADER_SIZE
)) {
1181 "prsocket_test: TransmitFile_Client failed to receive file\n");
1186 if (memcmp(small_file_header
, small_buf
, SMALL_FILE_HEADER_SIZE
) != 0){
1188 "prsocket_test: TransmitFile_Client ERROR - small file header data corruption\n");
1192 if (memcmp(small_file_addr
, small_buf
+ SMALL_FILE_HEADER_SIZE
,
1193 SMALL_FILE_SIZE
) != 0) {
1195 "prsocket_test: TransmitFile_Client ERROR - small file data corruption\n");
1201 * read the large file and verify the data
1203 if (readn(sockfd
, large_buf
, LARGE_FILE_SIZE
) != LARGE_FILE_SIZE
) {
1205 "prsocket_test: TransmitFile_Client failed to receive file\n");
1210 if (memcmp(large_file_addr
, large_buf
, LARGE_FILE_SIZE
) != 0) {
1212 "prsocket_test: TransmitFile_Client ERROR - large file data corruption\n");
1219 * receive data from PR_SendFile
1222 * case 1: small file with header and trailer
1224 rlen
= SMALL_FILE_SIZE
+ SMALL_FILE_HEADER_SIZE
+
1225 SMALL_FILE_TRAILER_SIZE
;
1226 if (readn(sockfd
, small_buf
, rlen
) != rlen
) {
1228 "prsocket_test: SendFile_Client failed to receive file\n");
1233 if (memcmp(small_file_header
, small_buf
, SMALL_FILE_HEADER_SIZE
) != 0){
1235 "SendFile 1. ERROR - small file header corruption\n");
1239 if (memcmp(small_file_addr
, small_buf
+ SMALL_FILE_HEADER_SIZE
,
1240 SMALL_FILE_SIZE
) != 0) {
1242 "SendFile 1. ERROR - small file data corruption\n");
1246 if (memcmp(small_file_trailer
,
1247 small_buf
+ SMALL_FILE_HEADER_SIZE
+ SMALL_FILE_SIZE
,
1248 SMALL_FILE_TRAILER_SIZE
) != 0) {
1250 "SendFile 1. ERROR - small file trailer corruption\n");
1256 * case 2: partial large file at zero offset, file with header and trailer
1258 rlen
= LARGE_FILE_LEN_1
+ LARGE_FILE_HEADER_SIZE
+
1259 LARGE_FILE_TRAILER_SIZE
;
1260 if (readn(sockfd
, large_buf
, rlen
) != rlen
) {
1262 "prsocket_test: SendFile_Client failed to receive file\n");
1267 if (memcmp(large_file_header
, large_buf
, LARGE_FILE_HEADER_SIZE
) != 0){
1269 "SendFile 2. ERROR - large file header corruption\n");
1273 if (memcmp(large_file_addr
, large_buf
+ LARGE_FILE_HEADER_SIZE
,
1274 LARGE_FILE_LEN_1
) != 0) {
1276 "SendFile 2. ERROR - large file data corruption\n");
1280 if (memcmp(large_file_trailer
,
1281 large_buf
+ LARGE_FILE_HEADER_SIZE
+ LARGE_FILE_LEN_1
,
1282 LARGE_FILE_TRAILER_SIZE
) != 0) {
1284 "SendFile 2. ERROR - large file trailer corruption\n");
1290 * case 3: partial small file at non-zero offset, with header
1292 rlen
= SMALL_FILE_LEN_1
+ SMALL_FILE_HEADER_SIZE
;
1293 if (readn(sockfd
, small_buf
, rlen
) != rlen
) {
1295 "prsocket_test: SendFile_Client failed to receive file\n");
1300 if (memcmp(small_file_header
, small_buf
, SMALL_FILE_HEADER_SIZE
) != 0){
1302 "SendFile 3. ERROR - small file header corruption\n");
1306 if (memcmp((char *) small_file_addr
+ SMALL_FILE_OFFSET_1
,
1307 small_buf
+ SMALL_FILE_HEADER_SIZE
, SMALL_FILE_LEN_1
) != 0) {
1309 "SendFile 3. ERROR - small file data corruption\n");
1315 * case 4: partial small file at non-zero offset, with trailer
1317 rlen
= SMALL_FILE_LEN_2
+ SMALL_FILE_TRAILER_SIZE
;
1318 if (readn(sockfd
, small_buf
, rlen
) != rlen
) {
1320 "prsocket_test: SendFile_Client failed to receive file\n");
1325 if (memcmp((char *) small_file_addr
+ SMALL_FILE_OFFSET_2
, small_buf
,
1326 SMALL_FILE_LEN_2
) != 0) {
1328 "SendFile 4. ERROR - small file data corruption\n");
1332 if (memcmp(small_file_trailer
, small_buf
+ SMALL_FILE_LEN_2
,
1333 SMALL_FILE_TRAILER_SIZE
) != 0) {
1335 "SendFile 4. ERROR - small file trailer corruption\n");
1341 * case 5: partial large file at non-zero offset, file with header
1343 rlen
= LARGE_FILE_LEN_2
+ LARGE_FILE_HEADER_SIZE
;
1344 if (readn(sockfd
, large_buf
, rlen
) != rlen
) {
1346 "prsocket_test: SendFile_Client failed to receive file\n");
1351 if (memcmp(large_file_header
, large_buf
, LARGE_FILE_HEADER_SIZE
) != 0){
1353 "SendFile 5. ERROR - large file header corruption\n");
1357 if (memcmp((char *)large_file_addr
+ LARGE_FILE_OFFSET_2
,
1358 large_buf
+ LARGE_FILE_HEADER_SIZE
,
1359 LARGE_FILE_LEN_2
) != 0) {
1361 "SendFile 5. ERROR - large file data corruption\n");
1367 * case 6: partial small file at non-zero offset, with header
1369 rlen
= SMALL_FILE_LEN_3
+ SMALL_FILE_HEADER_SIZE
;
1370 if (readn(sockfd
, small_buf
, rlen
) != rlen
) {
1372 "prsocket_test: SendFile_Client failed to receive file\n");
1377 if (memcmp(small_file_header
, small_buf
, SMALL_FILE_HEADER_SIZE
) != 0){
1379 "SendFile 6. ERROR - small file header corruption\n");
1382 if (memcmp((char *) small_file_addr
+ SMALL_FILE_OFFSET_3
,
1383 small_buf
+ SMALL_FILE_HEADER_SIZE
, SMALL_FILE_LEN_3
) != 0) {
1388 i
= (char *) small_file_addr
+ SMALL_FILE_OFFSET_3
;
1389 j
= small_buf
+ SMALL_FILE_HEADER_SIZE
;
1390 k
= SMALL_FILE_LEN_3
;
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
)));
1399 "SendFile 6. ERROR - small file data corruption\n");
1405 * case 7: partial large file at non-zero offset, with header
1407 rlen
= LARGE_FILE_LEN_3
+ LARGE_FILE_HEADER_SIZE
;
1408 if (readn(sockfd
, large_buf
, rlen
) != rlen
) {
1410 "prsocket_test: SendFile_Client failed to receive file\n");
1415 if (memcmp(large_file_header
, large_buf
, LARGE_FILE_HEADER_SIZE
) != 0){
1417 "SendFile 7. ERROR - large file header corruption\n");
1421 if (memcmp((char *)large_file_addr
+ LARGE_FILE_OFFSET_3
,
1422 large_buf
+ LARGE_FILE_HEADER_SIZE
,
1423 LARGE_FILE_LEN_3
) != 0) {
1425 "SendFile 7. ERROR - large file data corruption\n");
1431 * case 8: partial large file at non-zero, page-aligned offset, with
1432 * header and trailer
1434 rlen
= LARGE_FILE_LEN_4
+ LARGE_FILE_HEADER_SIZE
+
1435 LARGE_FILE_TRAILER_SIZE
;
1436 if (readn(sockfd
, large_buf
, rlen
) != rlen
) {
1438 "prsocket_test: SendFile_Client failed to receive file\n");
1443 if (memcmp(large_file_header
, large_buf
, LARGE_FILE_HEADER_SIZE
) != 0){
1445 "SendFile 2. ERROR - large file header corruption\n");
1449 if (memcmp((char *)large_file_addr
+ LARGE_FILE_OFFSET_4
,
1450 large_buf
+ LARGE_FILE_HEADER_SIZE
,
1451 LARGE_FILE_LEN_4
) != 0) {
1453 "SendFile 2. ERROR - large file data corruption\n");
1457 if (memcmp(large_file_trailer
,
1458 large_buf
+ LARGE_FILE_HEADER_SIZE
+ LARGE_FILE_LEN_4
,
1459 LARGE_FILE_TRAILER_SIZE
) != 0) {
1461 "SendFile 2. ERROR - large file trailer corruption\n");
1466 PR_DELETE(small_buf
);
1467 PR_DELETE(large_buf
);
1472 * Decrement exit_counter and notify parent thread
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()));
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
1489 Serve_TransmitFile_Client(void *arg
)
1491 Serve_Client_Param
*scp
= (Serve_Client_Param
*) arg
;
1494 PRFileDesc
*local_small_file_fd
=NULL
;
1495 PRFileDesc
*local_large_file_fd
=NULL
;
1499 sockfd
= scp
->sockfd
;
1500 local_small_file_fd
= PR_Open(SMALL_FILE_NAME
, PR_RDONLY
,0);
1502 if (local_small_file_fd
== NULL
) {
1503 fprintf(stderr
,"prsocket_test failed to open file for transmitting %s\n",
1508 local_large_file_fd
= PR_Open(LARGE_FILE_NAME
, PR_RDONLY
,0);
1510 if (local_large_file_fd
== NULL
) {
1511 fprintf(stderr
,"prsocket_test failed to open file for transmitting %s\n",
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
)) {
1521 "prsocet_test: PR_TransmitFile failed: (%ld, %ld)\n",
1522 PR_GetError(), PR_GetOSError());
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
) {
1529 "prsocket_test: PR_TransmitFile failed: (%ld, %ld)\n",
1530 PR_GetError(), PR_GetOSError());
1535 * PR_SendFile test cases
1539 * case 1: small file with header and trailer
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
) {
1554 "socket: Error - 1. PR_SendFile send_size = %d, bytes sent = %d\n",
1557 "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
1558 PR_GetError(), PR_GetOSError());
1563 * case 2: partial large file at zero offset, file with header and trailer
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
) {
1578 "socket: Error - 2. PR_SendFile send_size = %d, bytes sent = %d\n",
1581 "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
1582 PR_GetError(), PR_GetOSError());
1586 * case 3: partial small file at non-zero offset, with header
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
;
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
) {
1600 "socket: Error - 3. PR_SendFile send_size = %d, bytes sent = %d\n",
1603 "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
1604 PR_GetError(), PR_GetOSError());
1608 * case 4: partial small file at non-zero offset, with trailer
1610 sfd
.fd
= local_small_file_fd
;
1611 sfd
.file_offset
= SMALL_FILE_OFFSET_2
;
1612 sfd
.file_nbytes
= SMALL_FILE_LEN_2
;
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
) {
1622 "socket: Error - 4. PR_SendFile send_size = %d, bytes sent = %d\n",
1625 "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
1626 PR_GetError(), PR_GetOSError());
1630 * case 5: partial large file at non-zero offset, file with header
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
;
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
) {
1644 "socket: Error - 5. PR_SendFile send_size = %d, bytes sent = %d\n",
1647 "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
1648 PR_GetError(), PR_GetOSError());
1652 * case 6: partial small file from non-zero offset till end of file, with header
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
;
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
) {
1666 "socket: Error - 6. PR_SendFile send_size = %d, bytes sent = %d\n",
1669 "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
1670 PR_GetError(), PR_GetOSError());
1674 * case 7: partial large file at non-zero offset till end-of-file, with header
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
;
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
) {
1688 "socket: Error - 7. PR_SendFile send_size = %d, bytes sent = %d\n",
1691 "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
1692 PR_GetError(), PR_GetOSError());
1696 * case 8: partial large file at non-zero page-aligned offset,
1697 * with header and trailer
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
) {
1712 "socket: Error - 2. PR_SendFile send_size = %d, bytes sent = %d\n",
1715 "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
1716 PR_GetError(), PR_GetOSError());
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
);
1727 * TransmitFile Server
1729 * Bind an address to a socket and listen for incoming connections
1730 * Create worker threads to service clients
1733 TransmitFile_Server(void *arg
)
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
;
1742 t
= (PRThread
**)PR_MALLOC(num_transmitfile_clients
* sizeof(PRThread
*));
1744 fprintf(stderr
, "prsocket_test: run out of memory\n");
1749 * Create a tcp socket
1751 if ((sockfd
= PR_OpenTCPSocket(PR_AF_INET
)) == NULL
) {
1752 fprintf(stderr
,"prsocket_test: PR_OpenTCPSocket failed\n");
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
);
1761 * try a few times to bind server's address, if addresses are in
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
)
1771 fprintf(stderr
,"prsocket_test: ERROR - PR_Bind failed\n");
1777 if (PR_Listen(sockfd
, 32) < 0) {
1778 fprintf(stderr
,"prsocket_test: ERROR - PR_Listen failed\n");
1783 if (PR_GetSockName(sockfd
, &netaddr
) < 0) {
1785 "prsocket_test: ERROR - PR_GetSockName failed\n");
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
;
1797 * Wake up parent thread because server address is bound and made
1798 * available in the global variable 'tcp_server_addr'
1800 PR_PostSem(sp
->addr_sem
);
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
);
1806 if ((newsockfd
= PR_Accept(sockfd
, addrp
,
1807 PR_INTERVAL_NO_TIMEOUT
)) == NULL
) {
1809 "prsocket_test: ERROR - PR_Accept failed\n");
1813 /* test both regular and emulated PR_SendFile */
1815 PRFileDesc
*layer
= PR_CreateIOLayerStub(
1816 emuSendFileIdentity
, &emuSendFileMethods
);
1817 if (layer
== NULL
) {
1819 "prsocket_test: ERROR - PR_CreateIOLayerStub failed\n");
1823 if (PR_PushIOLayer(newsockfd
, PR_TOP_IO_LAYER
, layer
)
1826 "prsocket_test: ERROR - PR_PushIOLayer failed\n");
1831 scp
= PR_NEW(Serve_Client_Param
);
1833 fprintf(stderr
,"prsocket_test: PR_NEW failed\n");
1839 * Start a Serve_Client thread for each incoming connection
1841 scp
->sockfd
= newsockfd
;
1842 scp
->datalen
= sp
->datalen
;
1844 t
[i
] = PR_CreateThread(PR_USER_THREAD
,
1845 Serve_TransmitFile_Client
, (void *)scp
,
1852 "prsocket_test: PR_CreateThread failed\n");
1856 DPRINTF(("TransmitFile_Server: Created Serve_TransmitFile_Client = 0x%lx\n", t
));
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.
1864 for (i
= 0; i
< num_transmitfile_clients
; i
++) {
1865 PR_JoinThread(t
[i
]);
1877 * Decrement exit_counter and notify parent thread
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()));
1888 * Socket_Misc_Test - test miscellaneous functions
1892 Socket_Misc_Test(void)
1894 PRIntn i
, rv
= 0, bytes
, count
, len
;
1896 PRSemaphore
*server_sem
;
1897 Server_Param
*sparamp
;
1898 Client_Param
*cparamp
;
1903 * We deliberately pick a buffer size that is not a nice multiple
1906 #define TRANSMITFILE_BUF_SIZE (4 * 1024 - 11)
1909 char data
[TRANSMITFILE_BUF_SIZE
];
1911 file_buf
*buf
= NULL
;
1914 * create file(s) to be transmitted
1916 if ((PR_MkDir(TEST_DIR
, 0777)) < 0) {
1917 printf("prsocket_test failed to create dir %s\n",TEST_DIR
);
1922 small_file_fd
= PR_Open(SMALL_FILE_NAME
, PR_RDWR
| PR_CREATE_FILE
,0777);
1924 if (small_file_fd
== NULL
) {
1925 fprintf(stderr
,"prsocket_test failed to create/open file %s\n",
1931 buf
= PR_NEW(file_buf
);
1933 fprintf(stderr
,"prsocket_test failed to allocate buffer\n");
1939 * fill in random data
1941 for (i
= 0; i
< TRANSMITFILE_BUF_SIZE
; i
++) {
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
);
1951 "prsocket_test failed to write to file %s\n",
1958 } while (count
< SMALL_FILE_SIZE
);
1961 * map the small file; used in checking for data corruption
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",
1974 * header for small file
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");
1983 memset(small_file_header
, (int) PR_IntervalNow(),
1984 SMALL_FILE_HEADER_SIZE
);
1986 * trailer for small file
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");
1995 memset(small_file_trailer
, (int) PR_IntervalNow(),
1996 SMALL_FILE_TRAILER_SIZE
);
2000 large_file_fd
= PR_Open(LARGE_FILE_NAME
, PR_RDWR
| PR_CREATE_FILE
,0777);
2002 if (large_file_fd
== NULL
) {
2003 fprintf(stderr
,"prsocket_test failed to create/open file %s\n",
2010 * fill in random data
2012 for (i
= 0; i
< TRANSMITFILE_BUF_SIZE
; i
++) {
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
);
2022 "prsocket_test failed to write to file %s: (%ld, %ld)\n",
2024 PR_GetError(), PR_GetOSError());
2030 } while (count
< LARGE_FILE_SIZE
);
2033 * map the large file; used in checking for data corruption
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",
2046 * header for large file
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");
2055 memset(large_file_header
, (int) PR_IntervalNow(),
2056 LARGE_FILE_HEADER_SIZE
);
2058 * trailer for large file
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");
2067 memset(large_file_trailer
, (int) PR_IntervalNow(),
2068 LARGE_FILE_TRAILER_SIZE
);
2070 datalen
= tcp_mesg_size
;
2073 * start the server thread
2075 sparamp
= PR_NEW(Server_Param
);
2076 if (sparamp
== NULL
) {
2077 fprintf(stderr
,"prsocket_test: PR_NEW failed\n");
2082 server_sem
= PR_NewSem(0);
2083 if (server_sem
== NULL
) {
2084 fprintf(stderr
,"prsocket_test: PR_NewSem failed\n");
2089 mon2
= PR_NewMonitor();
2091 fprintf(stderr
,"prsocket_test: PR_NewMonitor failed\n");
2096 PR_EnterMonitor(mon2
);
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
,
2106 PR_UNJOINABLE_THREAD
,
2109 fprintf(stderr
,"prsocket_test: PR_CreateThread failed\n");
2114 DPRINTF(("Created TCP server = 0x%x\n", t
));
2118 * wait till the server address is setup
2120 PR_WaitSem(server_sem
);
2123 * Now start a bunch of client threads
2126 cparamp
= PR_NEW(Client_Param
);
2127 if (cparamp
== NULL
) {
2128 fprintf(stderr
,"prsocket_test: PR_NEW failed\n");
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
,
2143 PR_UNJOINABLE_THREAD
,
2146 fprintf(stderr
,"prsocket_test: PR_CreateThread failed\n");
2151 DPRINTF(("Created TransmitFile client = 0x%lx\n", t
));
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
));
2159 PR_ExitMonitor(mon2
);
2165 munmap((char*)small_file_addr
, SMALL_FILE_SIZE
);
2166 munmap((char*)large_file_addr
, LARGE_FILE_SIZE
);
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",
2175 if ((PR_Delete(LARGE_FILE_NAME
)) == PR_FAILURE
) {
2176 fprintf(stderr
,"prsocket_test: failed to unlink file %s\n",
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());
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));
2194 /************************************************************************/
2197 * Test Socket NSPR APIs
2201 main(int argc
, char **argv
)
2208 PLOptState
*opt
= PL_CreateOptState(argc
, argv
, "d");
2209 while (PL_OPT_EOL
!= (os
= PL_GetNextOpt(opt
)))
2211 if (PL_OPT_BAD
== os
) continue;
2212 switch (opt
->option
)
2214 case 'd': /* debug mode */
2221 PL_DestroyOptState(opt
);
2223 PR_Init(PR_USER_THREAD
, PR_PRIORITY_NORMAL
, 0);
2227 SetupMacPrintfLog("socket.log");
2229 PR_SetConcurrency(4);
2231 emuSendFileIdentity
= PR_GetUniqueIdentity("Emulated SendFile");
2232 emuSendFileMethods
= *PR_GetDefaultIOMethods();
2233 emuSendFileMethods
.transmitfile
= emu_TransmitFile
;
2234 emuSendFileMethods
.sendfile
= emu_SendFile
;
2237 * run client-server test with TCP, Ipv4-Ipv4
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");
2244 printf("TCP_Socket_Client_Server_Test Passed\n");
2246 * client-server test, Ipv6-Ipv4
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");
2254 printf("TCP_Socket_Client_Server_Test Passed\n");
2256 * client-server test, Ipv4-Ipv6
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");
2265 printf("TCP_Socket_Client_Server_Test Passed\n");
2267 * client-server test, Ipv6-Ipv6
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");
2276 printf("TCP_Socket_Client_Server_Test Passed\n");
2279 * run client-server test with UDP, IPv4/IPv4
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");
2288 printf("UDP_Socket_Client_Server_Test Passed\n");
2290 * run client-server test with UDP, IPv6/IPv4
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");
2299 printf("UDP_Socket_Client_Server_Test Passed\n");
2301 * run client-server test with UDP,IPv4-IPv6
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");
2310 printf("UDP_Socket_Client_Server_Test Passed\n");
2312 * run client-server test with UDP,IPv6-IPv6
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");
2321 printf("UDP_Socket_Client_Server_Test Passed\n");
2323 * Misc socket tests - including transmitfile, etc.
2328 ** The 'transmit file' test does not run because
2329 ** transmit file is not implemented in NSPR yet.
2332 if (Socket_Misc_Test() < 0) {
2333 printf("Socket_Misc_Test failed\n");
2337 printf("Socket_Misc_Test passed\n");
2340 * run client-server test with TCP again to test
2341 * recycling used sockets from PR_TransmitFile().
2343 if (TCP_Socket_Client_Server_Test() < 0) {
2344 printf("TCP_Socket_Client_Server_Test failed\n");
2347 printf("TCP_Socket_Client_Server_Test Passed\n");
2352 if (failed_already
) return 1;