michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /*********************************************************************** michael@0: ** michael@0: ** Name: socket.c michael@0: ** michael@0: ** Description: Test socket functionality. michael@0: ** michael@0: ** Modification History: michael@0: */ michael@0: #include "primpl.h" michael@0: michael@0: #include "plgetopt.h" michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: #ifdef XP_UNIX michael@0: #include michael@0: #endif michael@0: #if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) michael@0: #include michael@0: #endif michael@0: michael@0: #ifdef WIN32 michael@0: #include michael@0: #endif michael@0: michael@0: static int _debug_on = 0; michael@0: static int test_cancelio = 0; michael@0: michael@0: #include "obsolete/prsem.h" michael@0: michael@0: #ifdef XP_PC michael@0: #define mode_t int michael@0: #endif michael@0: michael@0: #define DPRINTF(arg) if (_debug_on) printf arg michael@0: michael@0: #ifdef XP_PC michael@0: char *TEST_DIR = "prdir"; michael@0: char *SMALL_FILE_NAME = "prsmallf"; michael@0: char *LARGE_FILE_NAME = "prlargef"; michael@0: #elif defined(SYMBIAN) michael@0: char *TEST_DIR = "c:\\data\\prsocket"; michael@0: char *SMALL_FILE_NAME = "c:\\data\\prsocket\\small_file"; michael@0: char *LARGE_FILE_NAME = "c:\\data\\prsocket\\large_file"; michael@0: #else michael@0: char *TEST_DIR = "/tmp/prsocket_test_dir"; michael@0: char *SMALL_FILE_NAME = "/tmp/prsocket_test_dir/small_file"; michael@0: char *LARGE_FILE_NAME = "/tmp/prsocket_test_dir/large_file"; michael@0: #endif michael@0: #define SMALL_FILE_SIZE (3 * 1024) /* 3 KB */ michael@0: #define SMALL_FILE_OFFSET_1 (512) michael@0: #define SMALL_FILE_LEN_1 (1 * 1024) /* 1 KB */ michael@0: #define SMALL_FILE_OFFSET_2 (75) michael@0: #define SMALL_FILE_LEN_2 (758) michael@0: #define SMALL_FILE_OFFSET_3 (1024) michael@0: #define SMALL_FILE_LEN_3 (SMALL_FILE_SIZE - SMALL_FILE_OFFSET_3) michael@0: #define SMALL_FILE_HEADER_SIZE (64) /* 64 bytes */ michael@0: #define SMALL_FILE_TRAILER_SIZE (128) /* 128 bytes */ michael@0: michael@0: #define LARGE_FILE_SIZE (3 * 1024 * 1024) /* 3 MB */ michael@0: #define LARGE_FILE_OFFSET_1 (0) michael@0: #define LARGE_FILE_LEN_1 (2 * 1024 * 1024) /* 2 MB */ michael@0: #define LARGE_FILE_OFFSET_2 (64) michael@0: #define LARGE_FILE_LEN_2 (1 * 1024 * 1024 + 75) michael@0: #define LARGE_FILE_OFFSET_3 (2 * 1024 * 1024 - 128) michael@0: #define LARGE_FILE_LEN_3 (LARGE_FILE_SIZE - LARGE_FILE_OFFSET_3) michael@0: #define LARGE_FILE_OFFSET_4 PR_GetPageSize() michael@0: #define LARGE_FILE_LEN_4 769 michael@0: #define LARGE_FILE_HEADER_SIZE (512) michael@0: #define LARGE_FILE_TRAILER_SIZE (64) michael@0: michael@0: #define BUF_DATA_SIZE (2 * 1024) michael@0: #define TCP_MESG_SIZE 1024 michael@0: /* michael@0: * set UDP datagram size small enough that datagrams sent to a port on the michael@0: * local host will not be lost michael@0: */ michael@0: #define UDP_DGRAM_SIZE 128 michael@0: #define NUM_TCP_CLIENTS 5 /* for a listen queue depth of 5 */ michael@0: #define NUM_UDP_CLIENTS 10 michael@0: michael@0: #ifdef SYMBIAN michael@0: #define NUM_TRANSMITFILE_CLIENTS 1 michael@0: #else michael@0: #define NUM_TRANSMITFILE_CLIENTS 4 michael@0: #endif michael@0: michael@0: #define NUM_TCP_CONNECTIONS_PER_CLIENT 5 michael@0: #define NUM_TCP_MESGS_PER_CONNECTION 10 michael@0: #define NUM_UDP_DATAGRAMS_PER_CLIENT 5 michael@0: #define TCP_SERVER_PORT 10000 michael@0: #define UDP_SERVER_PORT TCP_SERVER_PORT michael@0: #define SERVER_MAX_BIND_COUNT 100 michael@0: michael@0: #ifdef WINCE michael@0: #define perror(s) michael@0: #endif michael@0: michael@0: static PRInt32 num_tcp_clients = NUM_TCP_CLIENTS; michael@0: static PRInt32 num_udp_clients = NUM_UDP_CLIENTS; michael@0: static PRInt32 num_transmitfile_clients = NUM_TRANSMITFILE_CLIENTS; michael@0: static PRInt32 num_tcp_connections_per_client = NUM_TCP_CONNECTIONS_PER_CLIENT; michael@0: static PRInt32 tcp_mesg_size = TCP_MESG_SIZE; michael@0: static PRInt32 num_tcp_mesgs_per_connection = NUM_TCP_MESGS_PER_CONNECTION; michael@0: static PRInt32 num_udp_datagrams_per_client = NUM_UDP_DATAGRAMS_PER_CLIENT; michael@0: static PRInt32 udp_datagram_size = UDP_DGRAM_SIZE; michael@0: michael@0: static PRInt32 thread_count; michael@0: PRUint16 server_domain = PR_AF_INET, client_domain = PR_AF_INET; michael@0: michael@0: /* an I/O layer that uses the emulated senfile method */ michael@0: static PRDescIdentity emuSendFileIdentity; michael@0: static PRIOMethods emuSendFileMethods; michael@0: michael@0: int failed_already=0; michael@0: typedef struct buffer { michael@0: char data[BUF_DATA_SIZE]; michael@0: } buffer; michael@0: michael@0: PRNetAddr tcp_server_addr, udp_server_addr; michael@0: michael@0: typedef struct Serve_Client_Param { michael@0: PRFileDesc *sockfd; /* socket to read from/write to */ michael@0: PRInt32 datalen; /* bytes of data transfered in each read/write */ michael@0: } Serve_Client_Param; michael@0: michael@0: typedef struct Server_Param { michael@0: PRSemaphore *addr_sem; /* sem to post on, after setting up the address */ michael@0: PRMonitor *exit_mon; /* monitor to signal on exit */ michael@0: PRInt32 *exit_counter; /* counter to decrement, before exit */ michael@0: PRInt32 datalen; /* bytes of data transfered in each read/write */ michael@0: } Server_Param; michael@0: michael@0: michael@0: typedef struct Client_Param { michael@0: PRNetAddr server_addr; michael@0: PRMonitor *exit_mon; /* monitor to signal on exit */ michael@0: PRInt32 *exit_counter; /* counter to decrement, before exit */ michael@0: PRInt32 datalen; michael@0: PRInt32 udp_connect; /* if set clients connect udp sockets */ michael@0: } Client_Param; michael@0: michael@0: /* the sendfile method in emuSendFileMethods */ michael@0: static PRInt32 PR_CALLBACK michael@0: emu_SendFile(PRFileDesc *sd, PRSendFileData *sfd, michael@0: PRTransmitFileFlags flags, PRIntervalTime timeout) michael@0: { michael@0: return PR_EmulateSendFile(sd, sfd, flags, timeout); michael@0: } michael@0: michael@0: /* the transmitfile method in emuSendFileMethods */ michael@0: static PRInt32 PR_CALLBACK michael@0: emu_TransmitFile(PRFileDesc *sd, PRFileDesc *fd, const void *headers, michael@0: PRInt32 hlen, PRTransmitFileFlags flags, PRIntervalTime timeout) michael@0: { michael@0: PRSendFileData sfd; michael@0: michael@0: sfd.fd = fd; michael@0: sfd.file_offset = 0; michael@0: sfd.file_nbytes = 0; michael@0: sfd.header = headers; michael@0: sfd.hlen = hlen; michael@0: sfd.trailer = NULL; michael@0: sfd.tlen = 0; michael@0: return emu_SendFile(sd, &sfd, flags, timeout); michael@0: } michael@0: michael@0: /* michael@0: * readn michael@0: * read data from sockfd into buf michael@0: */ michael@0: static PRInt32 michael@0: readn(PRFileDesc *sockfd, char *buf, int len) michael@0: { michael@0: int rem; michael@0: int bytes; michael@0: int offset = 0; michael@0: int err; michael@0: PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT; michael@0: michael@0: if (test_cancelio) michael@0: timeout = PR_SecondsToInterval(2); michael@0: michael@0: for (rem=len; rem; offset += bytes, rem -= bytes) { michael@0: DPRINTF(("thread = 0x%lx: calling PR_Recv, bytes = %d\n", michael@0: PR_GetCurrentThread(), rem)); michael@0: retry: michael@0: bytes = PR_Recv(sockfd, buf + offset, rem, 0, michael@0: timeout); michael@0: DPRINTF(("thread = 0x%lx: returning from PR_Recv, bytes = %d\n", michael@0: PR_GetCurrentThread(), bytes)); michael@0: if (bytes < 0) { michael@0: #ifdef WINNT michael@0: printf("PR_Recv: error = %d oserr = %d\n",(err = PR_GetError()), michael@0: PR_GetOSError()); michael@0: if ((test_cancelio) && (err == PR_IO_TIMEOUT_ERROR)) { michael@0: if (PR_NT_CancelIo(sockfd) != PR_SUCCESS) michael@0: printf("PR_NT_CancelIO: error = %d\n",PR_GetError()); michael@0: timeout = PR_INTERVAL_NO_TIMEOUT; michael@0: goto retry; michael@0: } michael@0: #endif michael@0: return -1; michael@0: } michael@0: } michael@0: return len; michael@0: } michael@0: michael@0: /* michael@0: * writen michael@0: * write data from buf to sockfd michael@0: */ michael@0: static PRInt32 michael@0: writen(PRFileDesc *sockfd, char *buf, int len) michael@0: { michael@0: int rem; michael@0: int bytes; michael@0: int offset = 0; michael@0: michael@0: for (rem=len; rem; offset += bytes, rem -= bytes) { michael@0: DPRINTF(("thread = 0x%lx: calling PR_Send, bytes = %d\n", michael@0: PR_GetCurrentThread(), rem)); michael@0: bytes = PR_Send(sockfd, buf + offset, rem, 0, michael@0: PR_INTERVAL_NO_TIMEOUT); michael@0: DPRINTF(("thread = 0x%lx: returning from PR_Send, bytes = %d\n", michael@0: PR_GetCurrentThread(), bytes)); michael@0: if (bytes <= 0) michael@0: return -1; michael@0: } michael@0: return len; michael@0: } michael@0: michael@0: /* michael@0: * Serve_Client michael@0: * Thread, started by the server, for serving a client connection. michael@0: * Reads data from socket and writes it back, unmodified, and michael@0: * closes the socket michael@0: */ michael@0: static void PR_CALLBACK michael@0: Serve_Client(void *arg) michael@0: { michael@0: Serve_Client_Param *scp = (Serve_Client_Param *) arg; michael@0: PRFileDesc *sockfd; michael@0: buffer *in_buf; michael@0: PRInt32 bytes, j; michael@0: michael@0: sockfd = scp->sockfd; michael@0: bytes = scp->datalen; michael@0: in_buf = PR_NEW(buffer); michael@0: if (in_buf == NULL) { michael@0: fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n"); michael@0: failed_already=1; michael@0: goto exit; michael@0: } michael@0: michael@0: michael@0: for (j = 0; j < num_tcp_mesgs_per_connection; j++) { michael@0: /* michael@0: * Read data from client and send it back to the client unmodified michael@0: */ michael@0: if (readn(sockfd, in_buf->data, bytes) < bytes) { michael@0: fprintf(stderr,"prsocket_test: ERROR - Serve_Client:readn\n"); michael@0: failed_already=1; michael@0: goto exit; michael@0: } michael@0: /* Shutdown only RCV will cause error on Symbian OS */ michael@0: #if !defined(SYMBIAN) michael@0: /* michael@0: * shutdown reads, after the last read michael@0: */ michael@0: if (j == num_tcp_mesgs_per_connection - 1) michael@0: if (PR_Shutdown(sockfd, PR_SHUTDOWN_RCV) < 0) { michael@0: fprintf(stderr,"prsocket_test: ERROR - PR_Shutdown\n"); michael@0: } michael@0: #endif michael@0: DPRINTF(("Serve_Client [0x%lx]: inbuf[0] = 0x%lx\n",PR_GetCurrentThread(), michael@0: (*((int *) in_buf->data)))); michael@0: if (writen(sockfd, in_buf->data, bytes) < bytes) { michael@0: fprintf(stderr,"prsocket_test: ERROR - Serve_Client:writen\n"); michael@0: failed_already=1; michael@0: goto exit; michael@0: } michael@0: } michael@0: /* michael@0: * shutdown reads and writes michael@0: */ michael@0: if (PR_Shutdown(sockfd, PR_SHUTDOWN_BOTH) < 0) { michael@0: fprintf(stderr,"prsocket_test: ERROR - PR_Shutdown\n"); michael@0: failed_already=1; michael@0: } michael@0: michael@0: exit: michael@0: PR_Close(sockfd); michael@0: if (in_buf) { michael@0: PR_DELETE(in_buf); michael@0: } michael@0: } michael@0: michael@0: PRThread* create_new_thread(PRThreadType type, michael@0: void (*start)(void *arg), michael@0: void *arg, michael@0: PRThreadPriority priority, michael@0: PRThreadScope scope, michael@0: PRThreadState state, michael@0: PRUint32 stackSize, PRInt32 index) michael@0: { michael@0: PRInt32 native_thread = 0; michael@0: michael@0: PR_ASSERT(state == PR_UNJOINABLE_THREAD); michael@0: #if (defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)) || defined(WIN32) michael@0: switch(index % 4) { michael@0: case 0: michael@0: scope = (PR_LOCAL_THREAD); michael@0: break; michael@0: case 1: michael@0: scope = (PR_GLOBAL_THREAD); michael@0: break; michael@0: case 2: michael@0: scope = (PR_GLOBAL_BOUND_THREAD); michael@0: break; michael@0: case 3: michael@0: native_thread = 1; michael@0: break; michael@0: default: michael@0: PR_ASSERT(!"Invalid scope"); michael@0: break; michael@0: } michael@0: if (native_thread) { michael@0: #if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) michael@0: pthread_t tid; michael@0: if (!pthread_create(&tid, NULL, (void * (*)(void *)) start, arg)) michael@0: return((PRThread *) tid); michael@0: else michael@0: return (NULL); michael@0: #else michael@0: HANDLE thandle; michael@0: unsigned tid; michael@0: michael@0: thandle = (HANDLE) _beginthreadex( michael@0: NULL, michael@0: stackSize, michael@0: (unsigned (__stdcall *)(void *))start, michael@0: arg, michael@0: STACK_SIZE_PARAM_IS_A_RESERVATION, michael@0: &tid); michael@0: return((PRThread *) thandle); michael@0: #endif michael@0: } else { michael@0: return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize)); michael@0: } michael@0: #else michael@0: return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize)); michael@0: #endif michael@0: } michael@0: michael@0: /* michael@0: * TCP Server michael@0: * Server Thread michael@0: * Bind an address to a socket and listen for incoming connections michael@0: * Start a Serve_Client thread for each incoming connection. michael@0: */ michael@0: static void PR_CALLBACK michael@0: TCP_Server(void *arg) michael@0: { michael@0: PRThread *t; michael@0: Server_Param *sp = (Server_Param *) arg; michael@0: Serve_Client_Param *scp; michael@0: PRFileDesc *sockfd, *newsockfd; michael@0: PRNetAddr netaddr; michael@0: PRInt32 i; michael@0: /* michael@0: * Create a tcp socket michael@0: */ michael@0: if ((sockfd = PR_OpenTCPSocket(server_domain)) == NULL) { michael@0: fprintf(stderr,"prsocket_test: PR_NewTCPSocket failed\n"); michael@0: goto exit; michael@0: } michael@0: memset(&netaddr, 0 , sizeof(netaddr)); michael@0: michael@0: if (PR_SetNetAddr(PR_IpAddrAny, server_domain, TCP_SERVER_PORT, michael@0: &netaddr) == PR_FAILURE) { michael@0: fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n"); michael@0: goto exit; michael@0: } michael@0: /* michael@0: * try a few times to bind server's address, if addresses are in michael@0: * use michael@0: */ michael@0: i = 0; michael@0: michael@0: while (PR_Bind(sockfd, &netaddr) < 0) { michael@0: if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) { michael@0: netaddr.inet.port += 2; michael@0: if (i++ < SERVER_MAX_BIND_COUNT) michael@0: continue; michael@0: } michael@0: fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n"); michael@0: perror("PR_Bind"); michael@0: failed_already=1; michael@0: goto exit; michael@0: } michael@0: michael@0: if (PR_Listen(sockfd, 32) < 0) { michael@0: fprintf(stderr,"prsocket_test: ERROR - PR_Listen failed\n"); michael@0: failed_already=1; michael@0: goto exit; michael@0: } michael@0: michael@0: if (PR_GetSockName(sockfd, &netaddr) < 0) { michael@0: fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n"); michael@0: failed_already=1; michael@0: goto exit; michael@0: } michael@0: michael@0: DPRINTF(("TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n", michael@0: netaddr.inet.ip, netaddr.inet.port)); michael@0: if (PR_SetNetAddr(PR_IpAddrLoopback, client_domain, michael@0: PR_ntohs(PR_NetAddrInetPort(&netaddr)), michael@0: &tcp_server_addr) == PR_FAILURE) { michael@0: fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n"); michael@0: goto exit; michael@0: } michael@0: if ((client_domain == PR_AF_INET6) && (server_domain == PR_AF_INET)) michael@0: PR_ConvertIPv4AddrToIPv6(PR_htonl(INADDR_LOOPBACK), michael@0: &tcp_server_addr.ipv6.ip); michael@0: michael@0: /* michael@0: * Wake up parent thread because server address is bound and made michael@0: * available in the global variable 'tcp_server_addr' michael@0: */ michael@0: PR_PostSem(sp->addr_sem); michael@0: michael@0: for (i = 0; i < (num_tcp_clients * num_tcp_connections_per_client); i++) { michael@0: /* test both null and non-null 'addr' argument to PR_Accept */ michael@0: PRNetAddr *addrp = (i%2 ? &netaddr: NULL); michael@0: michael@0: DPRINTF(("TCP_Server: Accepting connection\n")); michael@0: if ((newsockfd = PR_Accept(sockfd, addrp, michael@0: PR_INTERVAL_NO_TIMEOUT)) == NULL) { michael@0: fprintf(stderr,"prsocket_test: ERROR - PR_Accept failed\n"); michael@0: goto exit; michael@0: } michael@0: DPRINTF(("TCP_Server: Accepted connection\n")); michael@0: scp = PR_NEW(Serve_Client_Param); michael@0: if (scp == NULL) { michael@0: fprintf(stderr,"prsocket_test: PR_NEW failed\n"); michael@0: goto exit; michael@0: } michael@0: michael@0: /* michael@0: * Start a Serve_Client thread for each incoming connection michael@0: */ michael@0: scp->sockfd = newsockfd; michael@0: scp->datalen = sp->datalen; michael@0: michael@0: t = create_new_thread(PR_USER_THREAD, michael@0: Serve_Client, (void *)scp, michael@0: PR_PRIORITY_NORMAL, michael@0: PR_LOCAL_THREAD, michael@0: PR_UNJOINABLE_THREAD, michael@0: 0, i); michael@0: if (t == NULL) { michael@0: fprintf(stderr,"prsocket_test: PR_CreateThread failed\n"); michael@0: failed_already=1; michael@0: goto exit; michael@0: } michael@0: DPRINTF(("TCP_Server: Created Serve_Client = 0x%lx\n", t)); michael@0: } michael@0: michael@0: exit: michael@0: if (sockfd) { michael@0: PR_Close(sockfd); michael@0: } michael@0: michael@0: /* michael@0: * Decrement exit_counter and notify parent thread michael@0: */ michael@0: michael@0: PR_EnterMonitor(sp->exit_mon); michael@0: --(*sp->exit_counter); michael@0: PR_Notify(sp->exit_mon); michael@0: PR_ExitMonitor(sp->exit_mon); michael@0: DPRINTF(("TCP_Server [0x%lx] exiting\n", PR_GetCurrentThread())); michael@0: } michael@0: michael@0: /* michael@0: * UDP Server michael@0: * Server Thread michael@0: * Bind an address to a socket, read data from clients and send data michael@0: * back to clients michael@0: */ michael@0: static void PR_CALLBACK michael@0: UDP_Server(void *arg) michael@0: { michael@0: Server_Param *sp = (Server_Param *) arg; michael@0: PRFileDesc *sockfd; michael@0: buffer *in_buf; michael@0: PRNetAddr netaddr; michael@0: PRInt32 bytes, i, rv = 0; michael@0: michael@0: michael@0: bytes = sp->datalen; michael@0: /* michael@0: * Create a udp socket michael@0: */ michael@0: if ((sockfd = PR_OpenUDPSocket(server_domain)) == NULL) { michael@0: fprintf(stderr,"prsocket_test: PR_NewUDPSocket failed\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: memset(&netaddr, 0 , sizeof(netaddr)); michael@0: if (PR_SetNetAddr(PR_IpAddrAny, server_domain, UDP_SERVER_PORT, michael@0: &netaddr) == PR_FAILURE) { michael@0: fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: /* michael@0: * try a few times to bind server's address, if addresses are in michael@0: * use michael@0: */ michael@0: i = 0; michael@0: while (PR_Bind(sockfd, &netaddr) < 0) { michael@0: if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) { michael@0: netaddr.inet.port += 2; michael@0: if (i++ < SERVER_MAX_BIND_COUNT) michael@0: continue; michael@0: } michael@0: fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n"); michael@0: perror("PR_Bind"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: michael@0: if (PR_GetSockName(sockfd, &netaddr) < 0) { michael@0: fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: michael@0: DPRINTF(("PR_Bind: UDP Server netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n", michael@0: netaddr.inet.ip, netaddr.inet.port)); michael@0: /* michael@0: * We can't use the IP address returned by PR_GetSockName in michael@0: * netaddr.inet.ip because netaddr.inet.ip is returned michael@0: * as 0 (= PR_INADDR_ANY). michael@0: */ michael@0: michael@0: if (PR_SetNetAddr(PR_IpAddrLoopback, client_domain, michael@0: PR_ntohs(PR_NetAddrInetPort(&netaddr)), michael@0: &udp_server_addr) == PR_FAILURE) { michael@0: fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: if ((client_domain == PR_AF_INET6) && (server_domain == PR_AF_INET)) michael@0: PR_ConvertIPv4AddrToIPv6(PR_htonl(INADDR_LOOPBACK), michael@0: &udp_server_addr.ipv6.ip); michael@0: michael@0: /* michael@0: * Wake up parent thread because server address is bound and made michael@0: * available in the global variable 'udp_server_addr' michael@0: */ michael@0: PR_PostSem(sp->addr_sem); michael@0: michael@0: bytes = sp->datalen; michael@0: in_buf = PR_NEW(buffer); michael@0: if (in_buf == NULL) { michael@0: fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: /* michael@0: * Receive datagrams from clients and send them back, unmodified, to the michael@0: * clients michael@0: */ michael@0: memset(&netaddr, 0 , sizeof(netaddr)); michael@0: for (i = 0; i < (num_udp_clients * num_udp_datagrams_per_client); i++) { michael@0: DPRINTF(("UDP_Server: calling PR_RecvFrom client - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n", michael@0: netaddr.inet.ip, netaddr.inet.port, bytes, in_buf->data, michael@0: in_buf->data[0])); michael@0: michael@0: rv = PR_RecvFrom(sockfd, in_buf->data, bytes, 0, &netaddr, michael@0: PR_INTERVAL_NO_TIMEOUT); michael@0: DPRINTF(("UDP_Server: PR_RecvFrom client - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n", michael@0: netaddr.inet.ip, netaddr.inet.port, rv, in_buf->data, michael@0: in_buf->data[0])); michael@0: if (rv != bytes) { michael@0: return; michael@0: } michael@0: rv = PR_SendTo(sockfd, in_buf->data, bytes, 0, &netaddr, michael@0: PR_INTERVAL_NO_TIMEOUT); michael@0: if (rv != bytes) { michael@0: return; michael@0: } michael@0: } michael@0: michael@0: PR_DELETE(in_buf); michael@0: PR_Close(sockfd); michael@0: michael@0: /* michael@0: * Decrement exit_counter and notify parent thread michael@0: */ michael@0: PR_EnterMonitor(sp->exit_mon); michael@0: --(*sp->exit_counter); michael@0: PR_Notify(sp->exit_mon); michael@0: PR_ExitMonitor(sp->exit_mon); michael@0: DPRINTF(("UDP_Server [0x%x] exiting\n", PR_GetCurrentThread())); michael@0: } michael@0: michael@0: /* michael@0: * TCP_Client michael@0: * Client Thread michael@0: * Connect to the server at the address specified in the argument. michael@0: * Fill in a buffer, write data to server, read it back and check michael@0: * for data corruption. michael@0: * Close the socket for server connection michael@0: */ michael@0: static void PR_CALLBACK michael@0: TCP_Client(void *arg) michael@0: { michael@0: Client_Param *cp = (Client_Param *) arg; michael@0: PRFileDesc *sockfd; michael@0: buffer *in_buf, *out_buf; michael@0: union PRNetAddr netaddr; michael@0: PRInt32 bytes, i, j; michael@0: michael@0: michael@0: bytes = cp->datalen; michael@0: out_buf = PR_NEW(buffer); michael@0: if (out_buf == NULL) { michael@0: fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: in_buf = PR_NEW(buffer); michael@0: if (in_buf == NULL) { michael@0: fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: netaddr = cp->server_addr; michael@0: michael@0: for (i = 0; i < num_tcp_connections_per_client; i++) { michael@0: if ((sockfd = PR_OpenTCPSocket(client_domain)) == NULL) { michael@0: fprintf(stderr,"prsocket_test: PR_OpenTCPSocket failed\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){ michael@0: fprintf(stderr, "PR_Connect failed: (%ld, %ld)\n", michael@0: PR_GetError(), PR_GetOSError()); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: for (j = 0; j < num_tcp_mesgs_per_connection; j++) { michael@0: /* michael@0: * fill in random data michael@0: */ michael@0: memset(out_buf->data, ((PRInt32) (&netaddr)) + i + j, bytes); michael@0: /* michael@0: * write to server michael@0: */ michael@0: #ifdef WINNT michael@0: if (test_cancelio && (j == 0)) michael@0: PR_Sleep(PR_SecondsToInterval(12)); michael@0: #endif michael@0: if (writen(sockfd, out_buf->data, bytes) < bytes) { michael@0: fprintf(stderr,"prsocket_test: ERROR - TCP_Client:writen\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: DPRINTF(("TCP Client [0x%lx]: out_buf = 0x%lx out_buf[0] = 0x%lx\n", michael@0: PR_GetCurrentThread(), out_buf, (*((int *) out_buf->data)))); michael@0: if (readn(sockfd, in_buf->data, bytes) < bytes) { michael@0: fprintf(stderr,"prsocket_test: ERROR - TCP_Client:readn\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: /* michael@0: * verify the data read michael@0: */ michael@0: if (memcmp(in_buf->data, out_buf->data, bytes) != 0) { michael@0: fprintf(stderr,"prsocket_test: ERROR - data corruption\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: } michael@0: /* michael@0: * shutdown reads and writes michael@0: */ michael@0: if (PR_Shutdown(sockfd, PR_SHUTDOWN_BOTH) < 0) { michael@0: fprintf(stderr,"prsocket_test: ERROR - PR_Shutdown\n"); michael@0: #if defined(SYMBIAN) michael@0: if (EPIPE != errno) michael@0: #endif michael@0: failed_already=1; michael@0: } michael@0: PR_Close(sockfd); michael@0: } michael@0: michael@0: PR_DELETE(out_buf); michael@0: PR_DELETE(in_buf); michael@0: michael@0: /* michael@0: * Decrement exit_counter and notify parent thread michael@0: */ michael@0: michael@0: PR_EnterMonitor(cp->exit_mon); michael@0: --(*cp->exit_counter); michael@0: PR_Notify(cp->exit_mon); michael@0: PR_ExitMonitor(cp->exit_mon); michael@0: DPRINTF(("TCP_Client [0x%x] exiting\n", PR_GetCurrentThread())); michael@0: } michael@0: michael@0: /* michael@0: * UDP_Client michael@0: * Client Thread michael@0: * Create a socket and bind an address michael@0: * Communicate with the server at the address specified in the argument. michael@0: * Fill in a buffer, write data to server, read it back and check michael@0: * for data corruption. michael@0: * Close the socket michael@0: */ michael@0: static void PR_CALLBACK michael@0: UDP_Client(void *arg) michael@0: { michael@0: Client_Param *cp = (Client_Param *) arg; michael@0: PRFileDesc *sockfd; michael@0: buffer *in_buf, *out_buf; michael@0: union PRNetAddr netaddr; michael@0: PRInt32 bytes, i, rv; michael@0: michael@0: michael@0: bytes = cp->datalen; michael@0: out_buf = PR_NEW(buffer); michael@0: if (out_buf == NULL) { michael@0: fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: in_buf = PR_NEW(buffer); michael@0: if (in_buf == NULL) { michael@0: fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: if ((sockfd = PR_OpenUDPSocket(client_domain)) == NULL) { michael@0: fprintf(stderr,"prsocket_test: PR_OpenUDPSocket failed\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: michael@0: /* michael@0: * bind an address for the client, let the system chose the port michael@0: * number michael@0: */ michael@0: memset(&netaddr, 0 , sizeof(netaddr)); michael@0: if (PR_SetNetAddr(PR_IpAddrAny, client_domain, 0, michael@0: &netaddr) == PR_FAILURE) { michael@0: fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: if (PR_Bind(sockfd, &netaddr) < 0) { michael@0: fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n"); michael@0: perror("PR_Bind"); michael@0: return; michael@0: } michael@0: michael@0: if (PR_GetSockName(sockfd, &netaddr) < 0) { michael@0: fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: michael@0: DPRINTF(("PR_Bind: UDP Client netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n", michael@0: netaddr.inet.ip, netaddr.inet.port)); michael@0: michael@0: netaddr = cp->server_addr; michael@0: michael@0: if (cp->udp_connect) { michael@0: if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){ michael@0: fprintf(stderr,"prsocket_test: PR_Connect failed\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: } michael@0: michael@0: for (i = 0; i < num_udp_datagrams_per_client; i++) { michael@0: /* michael@0: * fill in random data michael@0: */ michael@0: DPRINTF(("UDP_Client [0x%lx]: out_buf = 0x%lx bytes = 0x%lx\n", michael@0: PR_GetCurrentThread(), out_buf->data, bytes)); michael@0: memset(out_buf->data, ((PRInt32) (&netaddr)) + i, bytes); michael@0: /* michael@0: * write to server michael@0: */ michael@0: if (cp->udp_connect) michael@0: rv = PR_Send(sockfd, out_buf->data, bytes, 0, michael@0: PR_INTERVAL_NO_TIMEOUT); michael@0: else michael@0: rv = PR_SendTo(sockfd, out_buf->data, bytes, 0, &netaddr, michael@0: PR_INTERVAL_NO_TIMEOUT); michael@0: if (rv != bytes) { michael@0: return; michael@0: } michael@0: DPRINTF(("UDP_Client [0x%lx]: out_buf = 0x%lx out_buf[0] = 0x%lx\n", michael@0: PR_GetCurrentThread(), out_buf, (*((int *) out_buf->data)))); michael@0: if (cp->udp_connect) michael@0: rv = PR_Recv(sockfd, in_buf->data, bytes, 0, michael@0: PR_INTERVAL_NO_TIMEOUT); michael@0: else michael@0: rv = PR_RecvFrom(sockfd, in_buf->data, bytes, 0, &netaddr, michael@0: PR_INTERVAL_NO_TIMEOUT); michael@0: if (rv != bytes) { michael@0: return; michael@0: } michael@0: DPRINTF(("UDP_Client [0x%lx]: in_buf = 0x%lx in_buf[0] = 0x%lx\n", michael@0: PR_GetCurrentThread(), in_buf, (*((int *) in_buf->data)))); michael@0: /* michael@0: * verify the data read michael@0: */ michael@0: if (memcmp(in_buf->data, out_buf->data, bytes) != 0) { michael@0: fprintf(stderr,"prsocket_test: ERROR - UDP data corruption\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: } michael@0: PR_Close(sockfd); michael@0: michael@0: PR_DELETE(in_buf); michael@0: PR_DELETE(out_buf); michael@0: michael@0: /* michael@0: * Decrement exit_counter and notify parent thread michael@0: */ michael@0: michael@0: PR_EnterMonitor(cp->exit_mon); michael@0: --(*cp->exit_counter); michael@0: PR_Notify(cp->exit_mon); michael@0: PR_ExitMonitor(cp->exit_mon); michael@0: PR_DELETE(cp); michael@0: DPRINTF(("UDP_Client [0x%x] exiting\n", PR_GetCurrentThread())); michael@0: } michael@0: michael@0: /* michael@0: * TCP_Socket_Client_Server_Test - concurrent server test michael@0: * michael@0: * One server and several clients are started michael@0: * Each client connects to the server and sends a chunk of data michael@0: * For each connection, server starts another thread to read the data michael@0: * from the client and send it back to the client, unmodified. michael@0: * Each client checks that data received from server is same as the michael@0: * data it sent to the server. michael@0: * michael@0: */ michael@0: michael@0: static PRInt32 michael@0: TCP_Socket_Client_Server_Test(void) michael@0: { michael@0: int i; michael@0: PRThread *t; michael@0: PRSemaphore *server_sem; michael@0: Server_Param *sparamp; michael@0: Client_Param *cparamp; michael@0: PRMonitor *mon2; michael@0: PRInt32 datalen; michael@0: michael@0: michael@0: datalen = tcp_mesg_size; michael@0: thread_count = 0; michael@0: /* michael@0: * start the server thread michael@0: */ michael@0: sparamp = PR_NEW(Server_Param); michael@0: if (sparamp == NULL) { michael@0: fprintf(stderr,"prsocket_test: PR_NEW failed\n"); michael@0: failed_already=1; michael@0: return -1; michael@0: } michael@0: server_sem = PR_NewSem(0); michael@0: if (server_sem == NULL) { michael@0: fprintf(stderr,"prsocket_test: PR_NewSem failed\n"); michael@0: failed_already=1; michael@0: return -1; michael@0: } michael@0: mon2 = PR_NewMonitor(); michael@0: if (mon2 == NULL) { michael@0: fprintf(stderr,"prsocket_test: PR_NewMonitor failed\n"); michael@0: failed_already=1; michael@0: return -1; michael@0: } michael@0: PR_EnterMonitor(mon2); michael@0: michael@0: sparamp->addr_sem = server_sem; michael@0: sparamp->exit_mon = mon2; michael@0: sparamp->exit_counter = &thread_count; michael@0: sparamp->datalen = datalen; michael@0: t = PR_CreateThread(PR_USER_THREAD, michael@0: TCP_Server, (void *)sparamp, michael@0: PR_PRIORITY_NORMAL, michael@0: PR_LOCAL_THREAD, michael@0: PR_UNJOINABLE_THREAD, michael@0: 0); michael@0: if (t == NULL) { michael@0: fprintf(stderr,"prsocket_test: PR_CreateThread failed\n"); michael@0: failed_already=1; michael@0: return -1; michael@0: } michael@0: DPRINTF(("Created TCP server = 0x%lx\n", t)); michael@0: thread_count++; michael@0: michael@0: /* michael@0: * wait till the server address is setup michael@0: */ michael@0: PR_WaitSem(server_sem); michael@0: michael@0: /* michael@0: * Now start a bunch of client threads michael@0: */ michael@0: michael@0: cparamp = PR_NEW(Client_Param); michael@0: if (cparamp == NULL) { michael@0: fprintf(stderr,"prsocket_test: PR_NEW failed\n"); michael@0: failed_already=1; michael@0: return -1; michael@0: } michael@0: cparamp->server_addr = tcp_server_addr; michael@0: cparamp->exit_mon = mon2; michael@0: cparamp->exit_counter = &thread_count; michael@0: cparamp->datalen = datalen; michael@0: for (i = 0; i < num_tcp_clients; i++) { michael@0: t = create_new_thread(PR_USER_THREAD, michael@0: TCP_Client, (void *) cparamp, michael@0: PR_PRIORITY_NORMAL, michael@0: PR_LOCAL_THREAD, michael@0: PR_UNJOINABLE_THREAD, michael@0: 0, i); michael@0: if (t == NULL) { michael@0: fprintf(stderr,"prsocket_test: PR_CreateThread failed\n"); michael@0: failed_already=1; michael@0: return -1; michael@0: } michael@0: DPRINTF(("Created TCP client = 0x%lx\n", t)); michael@0: thread_count++; michael@0: } michael@0: /* Wait for server and client threads to exit */ michael@0: while (thread_count) { michael@0: PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT); michael@0: DPRINTF(("TCP Server - thread_count = %d\n", thread_count)); michael@0: } michael@0: PR_ExitMonitor(mon2); michael@0: printf("%30s","TCP_Socket_Client_Server_Test:"); michael@0: printf("%2ld Server %2ld Clients %2ld connections_per_client\n",1l, michael@0: num_tcp_clients, num_tcp_connections_per_client); michael@0: printf("%30s %2ld messages_per_connection %4ld bytes_per_message\n",":", michael@0: num_tcp_mesgs_per_connection, tcp_mesg_size); michael@0: michael@0: return 0; michael@0: } michael@0: michael@0: /* michael@0: * UDP_Socket_Client_Server_Test - iterative server test michael@0: * michael@0: * One server and several clients are started michael@0: * Each client connects to the server and sends a chunk of data michael@0: * For each connection, server starts another thread to read the data michael@0: * from the client and send it back to the client, unmodified. michael@0: * Each client checks that data received from server is same as the michael@0: * data it sent to the server. michael@0: * michael@0: */ michael@0: michael@0: static PRInt32 michael@0: UDP_Socket_Client_Server_Test(void) michael@0: { michael@0: int i; michael@0: PRThread *t; michael@0: PRSemaphore *server_sem; michael@0: Server_Param *sparamp; michael@0: Client_Param *cparamp; michael@0: PRMonitor *mon2; michael@0: PRInt32 datalen; michael@0: PRInt32 udp_connect = 1; michael@0: michael@0: michael@0: datalen = udp_datagram_size; michael@0: thread_count = 0; michael@0: /* michael@0: * start the server thread michael@0: */ michael@0: sparamp = PR_NEW(Server_Param); michael@0: if (sparamp == NULL) { michael@0: fprintf(stderr,"prsocket_test: PR_NEW failed\n"); michael@0: failed_already=1; michael@0: return -1; michael@0: } michael@0: server_sem = PR_NewSem(0); michael@0: if (server_sem == NULL) { michael@0: fprintf(stderr,"prsocket_test: PR_NewSem failed\n"); michael@0: failed_already=1; michael@0: return -1; michael@0: } michael@0: mon2 = PR_NewMonitor(); michael@0: if (mon2 == NULL) { michael@0: fprintf(stderr,"prsocket_test: PR_NewMonitor failed\n"); michael@0: failed_already=1; michael@0: return -1; michael@0: } michael@0: PR_EnterMonitor(mon2); michael@0: michael@0: sparamp->addr_sem = server_sem; michael@0: sparamp->exit_mon = mon2; michael@0: sparamp->exit_counter = &thread_count; michael@0: sparamp->datalen = datalen; michael@0: DPRINTF(("Creating UDP server")); michael@0: t = PR_CreateThread(PR_USER_THREAD, michael@0: UDP_Server, (void *)sparamp, michael@0: PR_PRIORITY_NORMAL, michael@0: PR_LOCAL_THREAD, michael@0: PR_UNJOINABLE_THREAD, michael@0: 0); michael@0: if (t == NULL) { michael@0: fprintf(stderr,"prsocket_test: PR_CreateThread failed\n"); michael@0: failed_already=1; michael@0: return -1; michael@0: } michael@0: thread_count++; michael@0: michael@0: /* michael@0: * wait till the server address is setup michael@0: */ michael@0: PR_WaitSem(server_sem); michael@0: michael@0: /* michael@0: * Now start a bunch of client threads michael@0: */ michael@0: michael@0: for (i = 0; i < num_udp_clients; i++) { michael@0: cparamp = PR_NEW(Client_Param); michael@0: if (cparamp == NULL) { michael@0: fprintf(stderr,"prsocket_test: PR_NEW failed\n"); michael@0: failed_already=1; michael@0: return -1; michael@0: } michael@0: cparamp->server_addr = udp_server_addr; michael@0: cparamp->exit_mon = mon2; michael@0: cparamp->exit_counter = &thread_count; michael@0: cparamp->datalen = datalen; michael@0: /* michael@0: * Cause every other client thread to connect udp sockets michael@0: */ michael@0: cparamp->udp_connect = udp_connect; michael@0: if (udp_connect) michael@0: udp_connect = 0; michael@0: else michael@0: udp_connect = 1; michael@0: DPRINTF(("Creating UDP client %d\n", i)); michael@0: t = PR_CreateThread(PR_USER_THREAD, michael@0: UDP_Client, (void *) cparamp, michael@0: PR_PRIORITY_NORMAL, michael@0: PR_LOCAL_THREAD, michael@0: PR_UNJOINABLE_THREAD, michael@0: 0); michael@0: if (t == NULL) { michael@0: fprintf(stderr,"prsocket_test: PR_CreateThread failed\n"); michael@0: failed_already=1; michael@0: return -1; michael@0: } michael@0: thread_count++; michael@0: } michael@0: /* Wait for server and client threads to exit */ michael@0: while (thread_count) { michael@0: PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT); michael@0: DPRINTF(("UDP Server - thread_count = %d\n", thread_count)); michael@0: } michael@0: PR_ExitMonitor(mon2); michael@0: printf("%30s","UDP_Socket_Client_Server_Test: "); michael@0: printf("%2ld Server %2ld Clients\n",1l, num_udp_clients); michael@0: printf("%30s %2ld datagrams_per_client %4ld bytes_per_datagram\n",":", michael@0: num_udp_datagrams_per_client, udp_datagram_size); michael@0: michael@0: return 0; michael@0: } michael@0: michael@0: static PRFileDesc *small_file_fd, *large_file_fd; michael@0: static void *small_file_addr, *small_file_header, *large_file_addr; michael@0: static void *small_file_trailer, *large_file_header, *large_file_trailer; michael@0: /* michael@0: * TransmitFile_Client michael@0: * Client Thread michael@0: */ michael@0: static void michael@0: TransmitFile_Client(void *arg) michael@0: { michael@0: PRFileDesc *sockfd; michael@0: union PRNetAddr netaddr; michael@0: char *small_buf, *large_buf; michael@0: Client_Param *cp = (Client_Param *) arg; michael@0: PRInt32 rlen; michael@0: michael@0: small_buf = (char*)PR_Malloc(SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE + michael@0: SMALL_FILE_TRAILER_SIZE); michael@0: if (small_buf == NULL) { michael@0: fprintf(stderr,"prsocket_test: failed to alloc buffer\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: large_buf = (char*)PR_Malloc(LARGE_FILE_SIZE + LARGE_FILE_HEADER_SIZE + michael@0: LARGE_FILE_TRAILER_SIZE); michael@0: if (large_buf == NULL) { michael@0: fprintf(stderr,"prsocket_test: failed to alloc buffer\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: netaddr.inet.family = cp->server_addr.inet.family; michael@0: netaddr.inet.port = cp->server_addr.inet.port; michael@0: netaddr.inet.ip = cp->server_addr.inet.ip; michael@0: michael@0: if ((sockfd = PR_NewTCPSocket()) == NULL) { michael@0: fprintf(stderr,"prsocket_test: PR_NewTCPSocket failed\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: michael@0: if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){ michael@0: fprintf(stderr,"prsocket_test: PR_Connect failed\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: /* michael@0: * read the small file and verify the data michael@0: */ michael@0: if (readn(sockfd, small_buf, SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE) michael@0: != (SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE)) { michael@0: fprintf(stderr, michael@0: "prsocket_test: TransmitFile_Client failed to receive file\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: #if defined(XP_UNIX) && !defined(SYMBIAN) michael@0: /* File transmission test can not be done because of large file's size */ michael@0: if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE) != 0){ michael@0: fprintf(stderr, michael@0: "prsocket_test: TransmitFile_Client ERROR - small file header data corruption\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: if (memcmp(small_file_addr, small_buf + SMALL_FILE_HEADER_SIZE, michael@0: SMALL_FILE_SIZE) != 0) { michael@0: fprintf(stderr, michael@0: "prsocket_test: TransmitFile_Client ERROR - small file data corruption\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: #endif michael@0: /* michael@0: * read the large file and verify the data michael@0: */ michael@0: if (readn(sockfd, large_buf, LARGE_FILE_SIZE) != LARGE_FILE_SIZE) { michael@0: fprintf(stderr, michael@0: "prsocket_test: TransmitFile_Client failed to receive file\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: #if defined(XP_UNIX) && !defined(SYMBIAN) michael@0: if (memcmp(large_file_addr, large_buf, LARGE_FILE_SIZE) != 0) { michael@0: fprintf(stderr, michael@0: "prsocket_test: TransmitFile_Client ERROR - large file data corruption\n"); michael@0: failed_already=1; michael@0: } michael@0: #endif michael@0: michael@0: michael@0: /* michael@0: * receive data from PR_SendFile michael@0: */ michael@0: /* michael@0: * case 1: small file with header and trailer michael@0: */ michael@0: rlen = SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE + michael@0: SMALL_FILE_TRAILER_SIZE; michael@0: if (readn(sockfd, small_buf, rlen) != rlen) { michael@0: fprintf(stderr, michael@0: "prsocket_test: SendFile_Client failed to receive file\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: #if defined(XP_UNIX) && !defined(SYMBIAN) michael@0: if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE) != 0){ michael@0: fprintf(stderr, michael@0: "SendFile 1. ERROR - small file header corruption\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: if (memcmp(small_file_addr, small_buf + SMALL_FILE_HEADER_SIZE, michael@0: SMALL_FILE_SIZE) != 0) { michael@0: fprintf(stderr, michael@0: "SendFile 1. ERROR - small file data corruption\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: if (memcmp(small_file_trailer, michael@0: small_buf + SMALL_FILE_HEADER_SIZE + SMALL_FILE_SIZE, michael@0: SMALL_FILE_TRAILER_SIZE) != 0) { michael@0: fprintf(stderr, michael@0: "SendFile 1. ERROR - small file trailer corruption\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: #endif michael@0: /* michael@0: * case 2: partial large file at zero offset, file with header and trailer michael@0: */ michael@0: rlen = LARGE_FILE_LEN_1 + LARGE_FILE_HEADER_SIZE + michael@0: LARGE_FILE_TRAILER_SIZE; michael@0: if (readn(sockfd, large_buf, rlen) != rlen) { michael@0: fprintf(stderr, michael@0: "prsocket_test: SendFile_Client failed to receive file\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: #if defined(XP_UNIX) && !defined(SYMBIAN) michael@0: if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE) != 0){ michael@0: fprintf(stderr, michael@0: "SendFile 2. ERROR - large file header corruption\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: if (memcmp(large_file_addr, large_buf + LARGE_FILE_HEADER_SIZE, michael@0: LARGE_FILE_LEN_1) != 0) { michael@0: fprintf(stderr, michael@0: "SendFile 2. ERROR - large file data corruption\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: if (memcmp(large_file_trailer, michael@0: large_buf + LARGE_FILE_HEADER_SIZE + LARGE_FILE_LEN_1, michael@0: LARGE_FILE_TRAILER_SIZE) != 0) { michael@0: fprintf(stderr, michael@0: "SendFile 2. ERROR - large file trailer corruption\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: #endif michael@0: /* michael@0: * case 3: partial small file at non-zero offset, with header michael@0: */ michael@0: rlen = SMALL_FILE_LEN_1 + SMALL_FILE_HEADER_SIZE; michael@0: if (readn(sockfd, small_buf, rlen) != rlen) { michael@0: fprintf(stderr, michael@0: "prsocket_test: SendFile_Client failed to receive file\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: #if defined(XP_UNIX) && !defined(SYMBIAN) michael@0: if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE) != 0){ michael@0: fprintf(stderr, michael@0: "SendFile 3. ERROR - small file header corruption\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: if (memcmp((char *) small_file_addr + SMALL_FILE_OFFSET_1, michael@0: small_buf + SMALL_FILE_HEADER_SIZE, SMALL_FILE_LEN_1) != 0) { michael@0: fprintf(stderr, michael@0: "SendFile 3. ERROR - small file data corruption\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: #endif michael@0: /* michael@0: * case 4: partial small file at non-zero offset, with trailer michael@0: */ michael@0: rlen = SMALL_FILE_LEN_2 + SMALL_FILE_TRAILER_SIZE; michael@0: if (readn(sockfd, small_buf, rlen) != rlen) { michael@0: fprintf(stderr, michael@0: "prsocket_test: SendFile_Client failed to receive file\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: #if defined(XP_UNIX) && !defined(SYMBIAN) michael@0: if (memcmp((char *) small_file_addr + SMALL_FILE_OFFSET_2, small_buf, michael@0: SMALL_FILE_LEN_2) != 0) { michael@0: fprintf(stderr, michael@0: "SendFile 4. ERROR - small file data corruption\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: if (memcmp(small_file_trailer, small_buf + SMALL_FILE_LEN_2, michael@0: SMALL_FILE_TRAILER_SIZE) != 0) { michael@0: fprintf(stderr, michael@0: "SendFile 4. ERROR - small file trailer corruption\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: #endif michael@0: /* michael@0: * case 5: partial large file at non-zero offset, file with header michael@0: */ michael@0: rlen = LARGE_FILE_LEN_2 + LARGE_FILE_HEADER_SIZE; michael@0: if (readn(sockfd, large_buf, rlen) != rlen) { michael@0: fprintf(stderr, michael@0: "prsocket_test: SendFile_Client failed to receive file\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: #if defined(XP_UNIX) && !defined(SYMBIAN) michael@0: if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE) != 0){ michael@0: fprintf(stderr, michael@0: "SendFile 5. ERROR - large file header corruption\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: if (memcmp((char *)large_file_addr + LARGE_FILE_OFFSET_2, michael@0: large_buf + LARGE_FILE_HEADER_SIZE, michael@0: LARGE_FILE_LEN_2) != 0) { michael@0: fprintf(stderr, michael@0: "SendFile 5. ERROR - large file data corruption\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: #endif michael@0: /* michael@0: * case 6: partial small file at non-zero offset, with header michael@0: */ michael@0: rlen = SMALL_FILE_LEN_3 + SMALL_FILE_HEADER_SIZE; michael@0: if (readn(sockfd, small_buf, rlen) != rlen) { michael@0: fprintf(stderr, michael@0: "prsocket_test: SendFile_Client failed to receive file\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: #if defined(XP_UNIX) && !defined(SYMBIAN) michael@0: if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE) != 0){ michael@0: fprintf(stderr, michael@0: "SendFile 6. ERROR - small file header corruption\n"); michael@0: return; michael@0: } michael@0: if (memcmp((char *) small_file_addr + SMALL_FILE_OFFSET_3, michael@0: small_buf + SMALL_FILE_HEADER_SIZE, SMALL_FILE_LEN_3) != 0) { michael@0: #if 0 michael@0: char *i, *j; michael@0: int k; michael@0: michael@0: i = (char *) small_file_addr + SMALL_FILE_OFFSET_3; michael@0: j = small_buf + SMALL_FILE_HEADER_SIZE; michael@0: k = SMALL_FILE_LEN_3; michael@0: while (k-- > 0) { michael@0: if (*i++ != *j++) michael@0: printf("i = %d j = %d\n", michael@0: (int) (i - ((char *) small_file_addr + SMALL_FILE_OFFSET_3)), michael@0: (int) (j - (small_buf + SMALL_FILE_HEADER_SIZE))); michael@0: } michael@0: #endif michael@0: fprintf(stderr, michael@0: "SendFile 6. ERROR - small file data corruption\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: #endif michael@0: /* michael@0: * case 7: partial large file at non-zero offset, with header michael@0: */ michael@0: rlen = LARGE_FILE_LEN_3 + LARGE_FILE_HEADER_SIZE; michael@0: if (readn(sockfd, large_buf, rlen) != rlen) { michael@0: fprintf(stderr, michael@0: "prsocket_test: SendFile_Client failed to receive file\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: #if defined(XP_UNIX) && !defined(SYMBIAN) michael@0: if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE) != 0){ michael@0: fprintf(stderr, michael@0: "SendFile 7. ERROR - large file header corruption\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: if (memcmp((char *)large_file_addr + LARGE_FILE_OFFSET_3, michael@0: large_buf + LARGE_FILE_HEADER_SIZE, michael@0: LARGE_FILE_LEN_3) != 0) { michael@0: fprintf(stderr, michael@0: "SendFile 7. ERROR - large file data corruption\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: #endif michael@0: /* michael@0: * case 8: partial large file at non-zero, page-aligned offset, with michael@0: * header and trailer michael@0: */ michael@0: rlen = LARGE_FILE_LEN_4 + LARGE_FILE_HEADER_SIZE + michael@0: LARGE_FILE_TRAILER_SIZE; michael@0: if (readn(sockfd, large_buf, rlen) != rlen) { michael@0: fprintf(stderr, michael@0: "prsocket_test: SendFile_Client failed to receive file\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: #if defined(XP_UNIX) && !defined(SYMBIAN) michael@0: if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE) != 0){ michael@0: fprintf(stderr, michael@0: "SendFile 2. ERROR - large file header corruption\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: if (memcmp((char *)large_file_addr + LARGE_FILE_OFFSET_4, michael@0: large_buf + LARGE_FILE_HEADER_SIZE, michael@0: LARGE_FILE_LEN_4) != 0) { michael@0: fprintf(stderr, michael@0: "SendFile 2. ERROR - large file data corruption\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: if (memcmp(large_file_trailer, michael@0: large_buf + LARGE_FILE_HEADER_SIZE + LARGE_FILE_LEN_4, michael@0: LARGE_FILE_TRAILER_SIZE) != 0) { michael@0: fprintf(stderr, michael@0: "SendFile 2. ERROR - large file trailer corruption\n"); michael@0: failed_already=1; michael@0: return; michael@0: } michael@0: #endif michael@0: PR_DELETE(small_buf); michael@0: PR_DELETE(large_buf); michael@0: PR_Close(sockfd); michael@0: michael@0: michael@0: /* michael@0: * Decrement exit_counter and notify parent thread michael@0: */ michael@0: michael@0: PR_EnterMonitor(cp->exit_mon); michael@0: --(*cp->exit_counter); michael@0: PR_Notify(cp->exit_mon); michael@0: PR_ExitMonitor(cp->exit_mon); michael@0: DPRINTF(("TransmitFile_Client [0x%lx] exiting\n", PR_GetCurrentThread())); michael@0: } michael@0: michael@0: /* michael@0: * Serve_TransmitFile_Client michael@0: * Thread, started by the server, for serving a client connection. michael@0: * Trasmits a small file, with a header, and a large file, without michael@0: * a header michael@0: */ michael@0: static void michael@0: Serve_TransmitFile_Client(void *arg) michael@0: { michael@0: Serve_Client_Param *scp = (Serve_Client_Param *) arg; michael@0: PRFileDesc *sockfd; michael@0: PRInt32 bytes; michael@0: PRFileDesc *local_small_file_fd=NULL; michael@0: PRFileDesc *local_large_file_fd=NULL; michael@0: PRSendFileData sfd; michael@0: PRInt32 slen; michael@0: michael@0: sockfd = scp->sockfd; michael@0: local_small_file_fd = PR_Open(SMALL_FILE_NAME, PR_RDONLY,0); michael@0: michael@0: if (local_small_file_fd == NULL) { michael@0: fprintf(stderr,"prsocket_test failed to open file for transmitting %s\n", michael@0: SMALL_FILE_NAME); michael@0: failed_already=1; michael@0: goto done; michael@0: } michael@0: local_large_file_fd = PR_Open(LARGE_FILE_NAME, PR_RDONLY,0); michael@0: michael@0: if (local_large_file_fd == NULL) { michael@0: fprintf(stderr,"prsocket_test failed to open file for transmitting %s\n", michael@0: LARGE_FILE_NAME); michael@0: failed_already=1; michael@0: goto done; michael@0: } michael@0: bytes = PR_TransmitFile(sockfd, local_small_file_fd, small_file_header, michael@0: SMALL_FILE_HEADER_SIZE, PR_TRANSMITFILE_KEEP_OPEN, michael@0: PR_INTERVAL_NO_TIMEOUT); michael@0: if (bytes != (SMALL_FILE_SIZE+ SMALL_FILE_HEADER_SIZE)) { michael@0: fprintf(stderr, michael@0: "prsocet_test: PR_TransmitFile failed: (%ld, %ld)\n", michael@0: PR_GetError(), PR_GetOSError()); michael@0: failed_already=1; michael@0: } michael@0: bytes = PR_TransmitFile(sockfd, local_large_file_fd, NULL, 0, michael@0: PR_TRANSMITFILE_KEEP_OPEN, PR_INTERVAL_NO_TIMEOUT); michael@0: if (bytes != LARGE_FILE_SIZE) { michael@0: fprintf(stderr, michael@0: "prsocket_test: PR_TransmitFile failed: (%ld, %ld)\n", michael@0: PR_GetError(), PR_GetOSError()); michael@0: failed_already=1; michael@0: } michael@0: michael@0: /* michael@0: * PR_SendFile test cases michael@0: */ michael@0: michael@0: /* michael@0: * case 1: small file with header and trailer michael@0: */ michael@0: sfd.fd = local_small_file_fd; michael@0: sfd.file_offset = 0; michael@0: sfd.file_nbytes = 0; michael@0: sfd.header = small_file_header; michael@0: sfd.hlen = SMALL_FILE_HEADER_SIZE; michael@0: sfd.trailer = small_file_trailer; michael@0: sfd.tlen = SMALL_FILE_TRAILER_SIZE; michael@0: bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN, michael@0: PR_INTERVAL_NO_TIMEOUT); michael@0: slen = SMALL_FILE_SIZE+ SMALL_FILE_HEADER_SIZE + michael@0: SMALL_FILE_TRAILER_SIZE; michael@0: if (bytes != slen) { michael@0: fprintf(stderr, michael@0: "socket: Error - 1. PR_SendFile send_size = %d, bytes sent = %d\n", michael@0: slen, bytes); michael@0: fprintf(stderr, michael@0: "prsocket_test: PR_SendFile failed: (%ld, %ld)\n", michael@0: PR_GetError(), PR_GetOSError()); michael@0: failed_already=1; michael@0: } michael@0: michael@0: /* michael@0: * case 2: partial large file at zero offset, file with header and trailer michael@0: */ michael@0: sfd.fd = local_large_file_fd; michael@0: sfd.file_offset = 0; michael@0: sfd.file_nbytes = LARGE_FILE_LEN_1; michael@0: sfd.header = large_file_header; michael@0: sfd.hlen = LARGE_FILE_HEADER_SIZE; michael@0: sfd.trailer = large_file_trailer; michael@0: sfd.tlen = LARGE_FILE_TRAILER_SIZE; michael@0: bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN, michael@0: PR_INTERVAL_NO_TIMEOUT); michael@0: slen = LARGE_FILE_LEN_1 + LARGE_FILE_HEADER_SIZE + michael@0: LARGE_FILE_TRAILER_SIZE; michael@0: if (bytes != slen) { michael@0: fprintf(stderr, michael@0: "socket: Error - 2. PR_SendFile send_size = %d, bytes sent = %d\n", michael@0: slen, bytes); michael@0: fprintf(stderr, michael@0: "prsocket_test: PR_SendFile failed: (%ld, %ld)\n", michael@0: PR_GetError(), PR_GetOSError()); michael@0: failed_already=1; michael@0: } michael@0: /* michael@0: * case 3: partial small file at non-zero offset, with header michael@0: */ michael@0: sfd.fd = local_small_file_fd; michael@0: sfd.file_offset = SMALL_FILE_OFFSET_1; michael@0: sfd.file_nbytes = SMALL_FILE_LEN_1; michael@0: sfd.header = small_file_header; michael@0: sfd.hlen = SMALL_FILE_HEADER_SIZE; michael@0: sfd.trailer = NULL; michael@0: sfd.tlen = 0; michael@0: bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN, michael@0: PR_INTERVAL_NO_TIMEOUT); michael@0: slen = SMALL_FILE_LEN_1 + SMALL_FILE_HEADER_SIZE; michael@0: if (bytes != slen) { michael@0: fprintf(stderr, michael@0: "socket: Error - 3. PR_SendFile send_size = %d, bytes sent = %d\n", michael@0: slen, bytes); michael@0: fprintf(stderr, michael@0: "prsocket_test: PR_SendFile failed: (%ld, %ld)\n", michael@0: PR_GetError(), PR_GetOSError()); michael@0: failed_already=1; michael@0: } michael@0: /* michael@0: * case 4: partial small file at non-zero offset, with trailer michael@0: */ michael@0: sfd.fd = local_small_file_fd; michael@0: sfd.file_offset = SMALL_FILE_OFFSET_2; michael@0: sfd.file_nbytes = SMALL_FILE_LEN_2; michael@0: sfd.header = NULL; michael@0: sfd.hlen = 0; michael@0: sfd.trailer = small_file_trailer; michael@0: sfd.tlen = SMALL_FILE_TRAILER_SIZE; michael@0: bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN, michael@0: PR_INTERVAL_NO_TIMEOUT); michael@0: slen = SMALL_FILE_LEN_2 + SMALL_FILE_TRAILER_SIZE; michael@0: if (bytes != slen) { michael@0: fprintf(stderr, michael@0: "socket: Error - 4. PR_SendFile send_size = %d, bytes sent = %d\n", michael@0: slen, bytes); michael@0: fprintf(stderr, michael@0: "prsocket_test: PR_SendFile failed: (%ld, %ld)\n", michael@0: PR_GetError(), PR_GetOSError()); michael@0: failed_already=1; michael@0: } michael@0: /* michael@0: * case 5: partial large file at non-zero offset, file with header michael@0: */ michael@0: sfd.fd = local_large_file_fd; michael@0: sfd.file_offset = LARGE_FILE_OFFSET_2; michael@0: sfd.file_nbytes = LARGE_FILE_LEN_2; michael@0: sfd.header = large_file_header; michael@0: sfd.hlen = LARGE_FILE_HEADER_SIZE; michael@0: sfd.trailer = NULL; michael@0: sfd.tlen = 0; michael@0: bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN, michael@0: PR_INTERVAL_NO_TIMEOUT); michael@0: slen = LARGE_FILE_LEN_2 + LARGE_FILE_HEADER_SIZE; michael@0: if (bytes != slen) { michael@0: fprintf(stderr, michael@0: "socket: Error - 5. PR_SendFile send_size = %d, bytes sent = %d\n", michael@0: slen, bytes); michael@0: fprintf(stderr, michael@0: "prsocket_test: PR_SendFile failed: (%ld, %ld)\n", michael@0: PR_GetError(), PR_GetOSError()); michael@0: failed_already=1; michael@0: } michael@0: /* michael@0: * case 6: partial small file from non-zero offset till end of file, with header michael@0: */ michael@0: sfd.fd = local_small_file_fd; michael@0: sfd.file_offset = SMALL_FILE_OFFSET_3; michael@0: sfd.file_nbytes = 0; /* data from offset to end-of-file */ michael@0: sfd.header = small_file_header; michael@0: sfd.hlen = SMALL_FILE_HEADER_SIZE; michael@0: sfd.trailer = NULL; michael@0: sfd.tlen = 0; michael@0: bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN, michael@0: PR_INTERVAL_NO_TIMEOUT); michael@0: slen = SMALL_FILE_LEN_3 + SMALL_FILE_HEADER_SIZE; michael@0: if (bytes != slen) { michael@0: fprintf(stderr, michael@0: "socket: Error - 6. PR_SendFile send_size = %d, bytes sent = %d\n", michael@0: slen, bytes); michael@0: fprintf(stderr, michael@0: "prsocket_test: PR_SendFile failed: (%ld, %ld)\n", michael@0: PR_GetError(), PR_GetOSError()); michael@0: failed_already=1; michael@0: } michael@0: /* michael@0: * case 7: partial large file at non-zero offset till end-of-file, with header michael@0: */ michael@0: sfd.fd = local_large_file_fd; michael@0: sfd.file_offset = LARGE_FILE_OFFSET_3; michael@0: sfd.file_nbytes = 0; /* data until end-of-file */ michael@0: sfd.header = large_file_header; michael@0: sfd.hlen = LARGE_FILE_HEADER_SIZE; michael@0: sfd.trailer = NULL; michael@0: sfd.tlen = 0; michael@0: bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN, michael@0: PR_INTERVAL_NO_TIMEOUT); michael@0: slen = LARGE_FILE_LEN_3 + LARGE_FILE_HEADER_SIZE; michael@0: if (bytes != slen) { michael@0: fprintf(stderr, michael@0: "socket: Error - 7. PR_SendFile send_size = %d, bytes sent = %d\n", michael@0: slen, bytes); michael@0: fprintf(stderr, michael@0: "prsocket_test: PR_SendFile failed: (%ld, %ld)\n", michael@0: PR_GetError(), PR_GetOSError()); michael@0: failed_already=1; michael@0: } michael@0: /* michael@0: * case 8: partial large file at non-zero page-aligned offset, michael@0: * with header and trailer michael@0: */ michael@0: sfd.fd = local_large_file_fd; michael@0: sfd.file_offset = LARGE_FILE_OFFSET_4; michael@0: sfd.file_nbytes = LARGE_FILE_LEN_4; michael@0: sfd.header = large_file_header; michael@0: sfd.hlen = LARGE_FILE_HEADER_SIZE; michael@0: sfd.trailer = large_file_trailer; michael@0: sfd.tlen = LARGE_FILE_TRAILER_SIZE; michael@0: bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_CLOSE_SOCKET, michael@0: PR_INTERVAL_NO_TIMEOUT); michael@0: slen = LARGE_FILE_LEN_4 + LARGE_FILE_HEADER_SIZE + michael@0: LARGE_FILE_TRAILER_SIZE; michael@0: if (bytes != slen) { michael@0: fprintf(stderr, michael@0: "socket: Error - 2. PR_SendFile send_size = %d, bytes sent = %d\n", michael@0: slen, bytes); michael@0: fprintf(stderr, michael@0: "prsocket_test: PR_SendFile failed: (%ld, %ld)\n", michael@0: PR_GetError(), PR_GetOSError()); michael@0: failed_already=1; michael@0: } michael@0: done: michael@0: if (local_small_file_fd != NULL) michael@0: PR_Close(local_small_file_fd); michael@0: if (local_large_file_fd != NULL) michael@0: PR_Close(local_large_file_fd); michael@0: } michael@0: michael@0: /* michael@0: * TransmitFile Server michael@0: * Server Thread michael@0: * Bind an address to a socket and listen for incoming connections michael@0: * Create worker threads to service clients michael@0: */ michael@0: static void michael@0: TransmitFile_Server(void *arg) michael@0: { michael@0: PRThread **t = NULL; /* an array of PRThread pointers */ michael@0: Server_Param *sp = (Server_Param *) arg; michael@0: Serve_Client_Param *scp; michael@0: PRFileDesc *sockfd = NULL, *newsockfd; michael@0: PRNetAddr netaddr; michael@0: PRInt32 i; michael@0: michael@0: t = (PRThread**)PR_MALLOC(num_transmitfile_clients * sizeof(PRThread *)); michael@0: if (t == NULL) { michael@0: fprintf(stderr, "prsocket_test: run out of memory\n"); michael@0: failed_already=1; michael@0: goto exit; michael@0: } michael@0: /* michael@0: * Create a tcp socket michael@0: */ michael@0: if ((sockfd = PR_OpenTCPSocket(PR_AF_INET)) == NULL) { michael@0: fprintf(stderr,"prsocket_test: PR_OpenTCPSocket failed\n"); michael@0: failed_already=1; michael@0: goto exit; michael@0: } michael@0: memset(&netaddr, 0 , sizeof(netaddr)); michael@0: netaddr.inet.family = PR_AF_INET; michael@0: netaddr.inet.port = PR_htons(TCP_SERVER_PORT); michael@0: netaddr.inet.ip = PR_htonl(PR_INADDR_ANY); michael@0: /* michael@0: * try a few times to bind server's address, if addresses are in michael@0: * use michael@0: */ michael@0: i = 0; michael@0: while (PR_Bind(sockfd, &netaddr) < 0) { michael@0: if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) { michael@0: netaddr.inet.port += 2; michael@0: if (i++ < SERVER_MAX_BIND_COUNT) michael@0: continue; michael@0: } michael@0: fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n"); michael@0: failed_already=1; michael@0: perror("PR_Bind"); michael@0: goto exit; michael@0: } michael@0: michael@0: if (PR_Listen(sockfd, 32) < 0) { michael@0: fprintf(stderr,"prsocket_test: ERROR - PR_Listen failed\n"); michael@0: failed_already=1; michael@0: goto exit; michael@0: } michael@0: michael@0: if (PR_GetSockName(sockfd, &netaddr) < 0) { michael@0: fprintf(stderr, michael@0: "prsocket_test: ERROR - PR_GetSockName failed\n"); michael@0: failed_already=1; michael@0: goto exit; michael@0: } michael@0: michael@0: DPRINTF(("TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n", michael@0: netaddr.inet.ip, netaddr.inet.port)); michael@0: tcp_server_addr.inet.family = netaddr.inet.family; michael@0: tcp_server_addr.inet.port = netaddr.inet.port; michael@0: tcp_server_addr.inet.ip = netaddr.inet.ip; michael@0: michael@0: /* michael@0: * Wake up parent thread because server address is bound and made michael@0: * available in the global variable 'tcp_server_addr' michael@0: */ michael@0: PR_PostSem(sp->addr_sem); michael@0: michael@0: for (i = 0; i < num_transmitfile_clients ; i++) { michael@0: /* test both null and non-null 'addr' argument to PR_Accept */ michael@0: PRNetAddr *addrp = (i%2 ? &netaddr: NULL); michael@0: michael@0: if ((newsockfd = PR_Accept(sockfd, addrp, michael@0: PR_INTERVAL_NO_TIMEOUT)) == NULL) { michael@0: fprintf(stderr, michael@0: "prsocket_test: ERROR - PR_Accept failed\n"); michael@0: failed_already=1; michael@0: goto exit; michael@0: } michael@0: /* test both regular and emulated PR_SendFile */ michael@0: if (i%2) { michael@0: PRFileDesc *layer = PR_CreateIOLayerStub( michael@0: emuSendFileIdentity, &emuSendFileMethods); michael@0: if (layer == NULL) { michael@0: fprintf(stderr, michael@0: "prsocket_test: ERROR - PR_CreateIOLayerStub failed\n"); michael@0: failed_already=1; michael@0: goto exit; michael@0: } michael@0: if (PR_PushIOLayer(newsockfd, PR_TOP_IO_LAYER, layer) michael@0: == PR_FAILURE) { michael@0: fprintf(stderr, michael@0: "prsocket_test: ERROR - PR_PushIOLayer failed\n"); michael@0: failed_already=1; michael@0: goto exit; michael@0: } michael@0: } michael@0: scp = PR_NEW(Serve_Client_Param); michael@0: if (scp == NULL) { michael@0: fprintf(stderr,"prsocket_test: PR_NEW failed\n"); michael@0: failed_already=1; michael@0: goto exit; michael@0: } michael@0: michael@0: /* michael@0: * Start a Serve_Client thread for each incoming connection michael@0: */ michael@0: scp->sockfd = newsockfd; michael@0: scp->datalen = sp->datalen; michael@0: michael@0: t[i] = PR_CreateThread(PR_USER_THREAD, michael@0: Serve_TransmitFile_Client, (void *)scp, michael@0: PR_PRIORITY_NORMAL, michael@0: PR_LOCAL_THREAD, michael@0: PR_JOINABLE_THREAD, michael@0: 0); michael@0: if (t[i] == NULL) { michael@0: fprintf(stderr, michael@0: "prsocket_test: PR_CreateThread failed\n"); michael@0: failed_already=1; michael@0: goto exit; michael@0: } michael@0: DPRINTF(("TransmitFile_Server: Created Serve_TransmitFile_Client = 0x%lx\n", t)); michael@0: } michael@0: michael@0: /* michael@0: * Wait for all the worker threads to end, so that we know michael@0: * they are no longer using the small and large file fd's. michael@0: */ michael@0: michael@0: for (i = 0; i < num_transmitfile_clients; i++) { michael@0: PR_JoinThread(t[i]); michael@0: } michael@0: michael@0: exit: michael@0: if (t) { michael@0: PR_DELETE(t); michael@0: } michael@0: if (sockfd) { michael@0: PR_Close(sockfd); michael@0: } michael@0: michael@0: /* michael@0: * Decrement exit_counter and notify parent thread michael@0: */ michael@0: michael@0: PR_EnterMonitor(sp->exit_mon); michael@0: --(*sp->exit_counter); michael@0: PR_Notify(sp->exit_mon); michael@0: PR_ExitMonitor(sp->exit_mon); michael@0: DPRINTF(("TransmitFile_Server [0x%lx] exiting\n", PR_GetCurrentThread())); michael@0: } michael@0: michael@0: /* michael@0: * Socket_Misc_Test - test miscellaneous functions michael@0: * michael@0: */ michael@0: static PRInt32 michael@0: Socket_Misc_Test(void) michael@0: { michael@0: PRIntn i, rv = 0, bytes, count, len; michael@0: PRThread *t; michael@0: PRSemaphore *server_sem; michael@0: Server_Param *sparamp; michael@0: Client_Param *cparamp; michael@0: PRMonitor *mon2; michael@0: PRInt32 datalen; michael@0: michael@0: /* michael@0: * We deliberately pick a buffer size that is not a nice multiple michael@0: * of 1024. michael@0: */ michael@0: #define TRANSMITFILE_BUF_SIZE (4 * 1024 - 11) michael@0: michael@0: typedef struct { michael@0: char data[TRANSMITFILE_BUF_SIZE]; michael@0: } file_buf; michael@0: file_buf *buf = NULL; michael@0: michael@0: /* michael@0: * create file(s) to be transmitted michael@0: */ michael@0: if ((PR_MkDir(TEST_DIR, 0777)) < 0) { michael@0: printf("prsocket_test failed to create dir %s\n",TEST_DIR); michael@0: failed_already=1; michael@0: return -1; michael@0: } michael@0: michael@0: small_file_fd = PR_Open(SMALL_FILE_NAME, PR_RDWR | PR_CREATE_FILE,0777); michael@0: michael@0: if (small_file_fd == NULL) { michael@0: fprintf(stderr,"prsocket_test failed to create/open file %s\n", michael@0: SMALL_FILE_NAME); michael@0: failed_already=1; michael@0: rv = -1; michael@0: goto done; michael@0: } michael@0: buf = PR_NEW(file_buf); michael@0: if (buf == NULL) { michael@0: fprintf(stderr,"prsocket_test failed to allocate buffer\n"); michael@0: failed_already=1; michael@0: rv = -1; michael@0: goto done; michael@0: } michael@0: /* michael@0: * fill in random data michael@0: */ michael@0: for (i = 0; i < TRANSMITFILE_BUF_SIZE; i++) { michael@0: buf->data[i] = i; michael@0: } michael@0: count = 0; michael@0: do { michael@0: len = (SMALL_FILE_SIZE - count) > TRANSMITFILE_BUF_SIZE ? michael@0: TRANSMITFILE_BUF_SIZE : (SMALL_FILE_SIZE - count); michael@0: bytes = PR_Write(small_file_fd, buf->data, len); michael@0: if (bytes <= 0) { michael@0: fprintf(stderr, michael@0: "prsocket_test failed to write to file %s\n", michael@0: SMALL_FILE_NAME); michael@0: failed_already=1; michael@0: rv = -1; michael@0: goto done; michael@0: } michael@0: count += bytes; michael@0: } while (count < SMALL_FILE_SIZE); michael@0: #ifdef XP_UNIX michael@0: /* michael@0: * map the small file; used in checking for data corruption michael@0: */ michael@0: small_file_addr = mmap(0, SMALL_FILE_SIZE, PROT_READ, michael@0: MAP_SHARED, small_file_fd->secret->md.osfd, 0); michael@0: if (small_file_addr == (void *) -1) { michael@0: fprintf(stderr,"prsocket_test failed to mmap file %s\n", michael@0: SMALL_FILE_NAME); michael@0: failed_already=1; michael@0: rv = -1; michael@0: goto done; michael@0: } michael@0: #endif michael@0: /* michael@0: * header for small file michael@0: */ michael@0: small_file_header = PR_MALLOC(SMALL_FILE_HEADER_SIZE); michael@0: if (small_file_header == NULL) { michael@0: fprintf(stderr,"prsocket_test failed to malloc header file\n"); michael@0: failed_already=1; michael@0: rv = -1; michael@0: goto done; michael@0: } michael@0: memset(small_file_header, (int) PR_IntervalNow(), michael@0: SMALL_FILE_HEADER_SIZE); michael@0: /* michael@0: * trailer for small file michael@0: */ michael@0: small_file_trailer = PR_MALLOC(SMALL_FILE_TRAILER_SIZE); michael@0: if (small_file_trailer == NULL) { michael@0: fprintf(stderr,"prsocket_test failed to malloc header trailer\n"); michael@0: failed_already=1; michael@0: rv = -1; michael@0: goto done; michael@0: } michael@0: memset(small_file_trailer, (int) PR_IntervalNow(), michael@0: SMALL_FILE_TRAILER_SIZE); michael@0: /* michael@0: * setup large file michael@0: */ michael@0: large_file_fd = PR_Open(LARGE_FILE_NAME, PR_RDWR | PR_CREATE_FILE,0777); michael@0: michael@0: if (large_file_fd == NULL) { michael@0: fprintf(stderr,"prsocket_test failed to create/open file %s\n", michael@0: LARGE_FILE_NAME); michael@0: failed_already=1; michael@0: rv = -1; michael@0: goto done; michael@0: } michael@0: /* michael@0: * fill in random data michael@0: */ michael@0: for (i = 0; i < TRANSMITFILE_BUF_SIZE; i++) { michael@0: buf->data[i] = i; michael@0: } michael@0: count = 0; michael@0: do { michael@0: len = (LARGE_FILE_SIZE - count) > TRANSMITFILE_BUF_SIZE ? michael@0: TRANSMITFILE_BUF_SIZE : (LARGE_FILE_SIZE - count); michael@0: bytes = PR_Write(large_file_fd, buf->data, len); michael@0: if (bytes <= 0) { michael@0: fprintf(stderr, michael@0: "prsocket_test failed to write to file %s: (%ld, %ld)\n", michael@0: LARGE_FILE_NAME, michael@0: PR_GetError(), PR_GetOSError()); michael@0: failed_already=1; michael@0: rv = -1; michael@0: goto done; michael@0: } michael@0: count += bytes; michael@0: } while (count < LARGE_FILE_SIZE); michael@0: #if defined(XP_UNIX) && !defined(SYMBIAN) michael@0: /* michael@0: * map the large file; used in checking for data corruption michael@0: */ michael@0: large_file_addr = mmap(0, LARGE_FILE_SIZE, PROT_READ, michael@0: MAP_SHARED, large_file_fd->secret->md.osfd, 0); michael@0: if (large_file_addr == (void *) -1) { michael@0: fprintf(stderr,"prsocket_test failed to mmap file %s\n", michael@0: LARGE_FILE_NAME); michael@0: failed_already=1; michael@0: rv = -1; michael@0: goto done; michael@0: } michael@0: #endif michael@0: /* michael@0: * header for large file michael@0: */ michael@0: large_file_header = PR_MALLOC(LARGE_FILE_HEADER_SIZE); michael@0: if (large_file_header == NULL) { michael@0: fprintf(stderr,"prsocket_test failed to malloc header file\n"); michael@0: failed_already=1; michael@0: rv = -1; michael@0: goto done; michael@0: } michael@0: memset(large_file_header, (int) PR_IntervalNow(), michael@0: LARGE_FILE_HEADER_SIZE); michael@0: /* michael@0: * trailer for large file michael@0: */ michael@0: large_file_trailer = PR_MALLOC(LARGE_FILE_TRAILER_SIZE); michael@0: if (large_file_trailer == NULL) { michael@0: fprintf(stderr,"prsocket_test failed to malloc header trailer\n"); michael@0: failed_already=1; michael@0: rv = -1; michael@0: goto done; michael@0: } michael@0: memset(large_file_trailer, (int) PR_IntervalNow(), michael@0: LARGE_FILE_TRAILER_SIZE); michael@0: michael@0: datalen = tcp_mesg_size; michael@0: thread_count = 0; michael@0: /* michael@0: * start the server thread michael@0: */ michael@0: sparamp = PR_NEW(Server_Param); michael@0: if (sparamp == NULL) { michael@0: fprintf(stderr,"prsocket_test: PR_NEW failed\n"); michael@0: failed_already=1; michael@0: rv = -1; michael@0: goto done; michael@0: } michael@0: server_sem = PR_NewSem(0); michael@0: if (server_sem == NULL) { michael@0: fprintf(stderr,"prsocket_test: PR_NewSem failed\n"); michael@0: failed_already=1; michael@0: rv = -1; michael@0: goto done; michael@0: } michael@0: mon2 = PR_NewMonitor(); michael@0: if (mon2 == NULL) { michael@0: fprintf(stderr,"prsocket_test: PR_NewMonitor failed\n"); michael@0: failed_already=1; michael@0: rv = -1; michael@0: goto done; michael@0: } michael@0: PR_EnterMonitor(mon2); michael@0: michael@0: sparamp->addr_sem = server_sem; michael@0: sparamp->exit_mon = mon2; michael@0: sparamp->exit_counter = &thread_count; michael@0: sparamp->datalen = datalen; michael@0: t = PR_CreateThread(PR_USER_THREAD, michael@0: TransmitFile_Server, (void *)sparamp, michael@0: PR_PRIORITY_NORMAL, michael@0: PR_LOCAL_THREAD, michael@0: PR_UNJOINABLE_THREAD, michael@0: 0); michael@0: if (t == NULL) { michael@0: fprintf(stderr,"prsocket_test: PR_CreateThread failed\n"); michael@0: failed_already=1; michael@0: rv = -1; michael@0: goto done; michael@0: } michael@0: DPRINTF(("Created TCP server = 0x%x\n", t)); michael@0: thread_count++; michael@0: michael@0: /* michael@0: * wait till the server address is setup michael@0: */ michael@0: PR_WaitSem(server_sem); michael@0: michael@0: /* michael@0: * Now start a bunch of client threads michael@0: */ michael@0: michael@0: cparamp = PR_NEW(Client_Param); michael@0: if (cparamp == NULL) { michael@0: fprintf(stderr,"prsocket_test: PR_NEW failed\n"); michael@0: failed_already=1; michael@0: rv = -1; michael@0: goto done; michael@0: } michael@0: cparamp->server_addr = tcp_server_addr; michael@0: cparamp->server_addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK); michael@0: cparamp->exit_mon = mon2; michael@0: cparamp->exit_counter = &thread_count; michael@0: cparamp->datalen = datalen; michael@0: for (i = 0; i < num_transmitfile_clients; i++) { michael@0: t = create_new_thread(PR_USER_THREAD, michael@0: TransmitFile_Client, (void *) cparamp, michael@0: PR_PRIORITY_NORMAL, michael@0: PR_LOCAL_THREAD, michael@0: PR_UNJOINABLE_THREAD, michael@0: 0, i); michael@0: if (t == NULL) { michael@0: fprintf(stderr,"prsocket_test: PR_CreateThread failed\n"); michael@0: rv = -1; michael@0: failed_already=1; michael@0: goto done; michael@0: } michael@0: DPRINTF(("Created TransmitFile client = 0x%lx\n", t)); michael@0: thread_count++; michael@0: } michael@0: /* Wait for server and client threads to exit */ michael@0: while (thread_count) { michael@0: PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT); michael@0: DPRINTF(("Socket_Misc_Test - thread_count = %d\n", thread_count)); michael@0: } michael@0: PR_ExitMonitor(mon2); michael@0: done: michael@0: if (buf) { michael@0: PR_DELETE(buf); michael@0: } michael@0: #if defined(XP_UNIX) && !defined(SYMBIAN) michael@0: munmap((char*)small_file_addr, SMALL_FILE_SIZE); michael@0: munmap((char*)large_file_addr, LARGE_FILE_SIZE); michael@0: #endif michael@0: PR_Close(small_file_fd); michael@0: PR_Close(large_file_fd); michael@0: if ((PR_Delete(SMALL_FILE_NAME)) == PR_FAILURE) { michael@0: fprintf(stderr,"prsocket_test: failed to unlink file %s\n", michael@0: SMALL_FILE_NAME); michael@0: failed_already=1; michael@0: } michael@0: if ((PR_Delete(LARGE_FILE_NAME)) == PR_FAILURE) { michael@0: fprintf(stderr,"prsocket_test: failed to unlink file %s\n", michael@0: LARGE_FILE_NAME); michael@0: failed_already=1; michael@0: } michael@0: if ((PR_RmDir(TEST_DIR)) == PR_FAILURE) { michael@0: fprintf(stderr,"prsocket_test failed to rmdir %s: (%ld, %ld)\n", michael@0: TEST_DIR, PR_GetError(), PR_GetOSError()); michael@0: failed_already=1; michael@0: } michael@0: michael@0: printf("%-29s%s","Socket_Misc_Test",":"); michael@0: printf("%2d Server %2d Clients\n",1, num_transmitfile_clients); michael@0: printf("%30s Sizes of Transmitted Files - %4d KB, %2d MB \n",":", michael@0: SMALL_FILE_SIZE/1024, LARGE_FILE_SIZE/(1024 * 1024)); michael@0: michael@0: michael@0: return rv; michael@0: } michael@0: /************************************************************************/ michael@0: michael@0: /* michael@0: * Test Socket NSPR APIs michael@0: */ michael@0: michael@0: int main(int argc, char **argv) michael@0: { michael@0: /* michael@0: * -d debug mode michael@0: */ michael@0: michael@0: PLOptStatus os; michael@0: PLOptState *opt = PL_CreateOptState(argc, argv, "d"); michael@0: while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) michael@0: { michael@0: if (PL_OPT_BAD == os) continue; michael@0: switch (opt->option) michael@0: { michael@0: case 'd': /* debug mode */ michael@0: _debug_on = 1; michael@0: break; michael@0: default: michael@0: break; michael@0: } michael@0: } michael@0: PL_DestroyOptState(opt); michael@0: michael@0: PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); michael@0: PR_STDIO_INIT(); michael@0: michael@0: PR_SetConcurrency(4); michael@0: michael@0: emuSendFileIdentity = PR_GetUniqueIdentity("Emulated SendFile"); michael@0: emuSendFileMethods = *PR_GetDefaultIOMethods(); michael@0: emuSendFileMethods.transmitfile = emu_TransmitFile; michael@0: emuSendFileMethods.sendfile = emu_SendFile; michael@0: michael@0: /* michael@0: * run client-server test with TCP, Ipv4-Ipv4 michael@0: */ michael@0: printf("TCP Client/Server Test - IPv4/Ipv4\n"); michael@0: if (TCP_Socket_Client_Server_Test() < 0) { michael@0: printf("TCP_Socket_Client_Server_Test failed\n"); michael@0: goto done; michael@0: } else michael@0: printf("TCP_Socket_Client_Server_Test Passed\n"); michael@0: /* michael@0: * client-server test, Ipv6-Ipv4 michael@0: */ michael@0: client_domain = PR_AF_INET6; michael@0: printf("TCP Client/Server Test - IPv6/Ipv4\n"); michael@0: if (TCP_Socket_Client_Server_Test() < 0) { michael@0: printf("TCP_Socket_Client_Server_Test failed\n"); michael@0: goto done; michael@0: } else michael@0: printf("TCP_Socket_Client_Server_Test Passed\n"); michael@0: /* michael@0: * client-server test, Ipv4-Ipv6 michael@0: */ michael@0: client_domain = PR_AF_INET; michael@0: server_domain = PR_AF_INET6; michael@0: printf("TCP Client/Server Test - IPv4/Ipv6\n"); michael@0: if (TCP_Socket_Client_Server_Test() < 0) { michael@0: printf("TCP_Socket_Client_Server_Test failed\n"); michael@0: goto done; michael@0: } else michael@0: printf("TCP_Socket_Client_Server_Test Passed\n"); michael@0: /* michael@0: * client-server test, Ipv6-Ipv6 michael@0: */ michael@0: client_domain = PR_AF_INET6; michael@0: server_domain = PR_AF_INET6; michael@0: printf("TCP Client/Server Test - IPv6/Ipv6\n"); michael@0: if (TCP_Socket_Client_Server_Test() < 0) { michael@0: printf("TCP_Socket_Client_Server_Test failed\n"); michael@0: goto done; michael@0: } else michael@0: printf("TCP_Socket_Client_Server_Test Passed\n"); michael@0: test_cancelio = 0; michael@0: michael@0: #if defined(SYMBIAN) && !defined(__WINSCW__) michael@0: /* UDP tests only run on Symbian devices but not emulator */ michael@0: /* michael@0: * run client-server test with UDP, IPv4/IPv4 michael@0: */ michael@0: printf("UDP Client/Server Test - IPv4/Ipv4\n"); michael@0: client_domain = PR_AF_INET; michael@0: server_domain = PR_AF_INET; michael@0: if (UDP_Socket_Client_Server_Test() < 0) { michael@0: printf("UDP_Socket_Client_Server_Test failed\n"); michael@0: goto done; michael@0: } else michael@0: printf("UDP_Socket_Client_Server_Test Passed\n"); michael@0: /* michael@0: * run client-server test with UDP, IPv6/IPv4 michael@0: */ michael@0: printf("UDP Client/Server Test - IPv6/Ipv4\n"); michael@0: client_domain = PR_AF_INET6; michael@0: server_domain = PR_AF_INET; michael@0: if (UDP_Socket_Client_Server_Test() < 0) { michael@0: printf("UDP_Socket_Client_Server_Test failed\n"); michael@0: goto done; michael@0: } else michael@0: printf("UDP_Socket_Client_Server_Test Passed\n"); michael@0: /* michael@0: * run client-server test with UDP,IPv4-IPv6 michael@0: */ michael@0: printf("UDP Client/Server Test - IPv4/Ipv6\n"); michael@0: client_domain = PR_AF_INET; michael@0: server_domain = PR_AF_INET6; michael@0: if (UDP_Socket_Client_Server_Test() < 0) { michael@0: printf("UDP_Socket_Client_Server_Test failed\n"); michael@0: goto done; michael@0: } else michael@0: printf("UDP_Socket_Client_Server_Test Passed\n"); michael@0: /* michael@0: * run client-server test with UDP,IPv6-IPv6 michael@0: */ michael@0: printf("UDP Client/Server Test - IPv6/Ipv6\n"); michael@0: client_domain = PR_AF_INET6; michael@0: server_domain = PR_AF_INET6; michael@0: if (UDP_Socket_Client_Server_Test() < 0) { michael@0: printf("UDP_Socket_Client_Server_Test failed\n"); michael@0: goto done; michael@0: } else michael@0: printf("UDP_Socket_Client_Server_Test Passed\n"); michael@0: #endif michael@0: michael@0: /* michael@0: * Misc socket tests - including transmitfile, etc. michael@0: */ michael@0: michael@0: /* File transmission test can not be done in Symbian OS because of michael@0: * large file's size and the incomplete mmap() implementation. */ michael@0: #if !defined(WIN16) && !defined(SYMBIAN) michael@0: /* michael@0: ** The 'transmit file' test does not run because michael@0: ** transmit file is not implemented in NSPR yet. michael@0: ** michael@0: */ michael@0: if (Socket_Misc_Test() < 0) { michael@0: printf("Socket_Misc_Test failed\n"); michael@0: failed_already=1; michael@0: goto done; michael@0: } else michael@0: printf("Socket_Misc_Test passed\n"); michael@0: michael@0: /* michael@0: * run client-server test with TCP again to test michael@0: * recycling used sockets from PR_TransmitFile(). michael@0: */ michael@0: if (TCP_Socket_Client_Server_Test() < 0) { michael@0: printf("TCP_Socket_Client_Server_Test failed\n"); michael@0: goto done; michael@0: } else michael@0: printf("TCP_Socket_Client_Server_Test Passed\n"); michael@0: #endif michael@0: michael@0: done: michael@0: PR_Cleanup(); michael@0: if (failed_already) return 1; michael@0: else return 0; michael@0: }