/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is the Netscape Portable Runtime (NSPR).
 *
 * The Initial Developer of the Original Code is
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 1998-2000
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

/***********************************************************************
**
** Name: socket.c
**
** Description: Test socket functionality.
**
** Modification History:
*/
#include "primpl.h"

#include "plgetopt.h"

#include <stdio.h>
#include <string.h>
#include <errno.h>
#ifdef XP_UNIX
#include <sys/mman.h>
#endif
#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
#include <pthread.h>
#endif

#ifdef WIN32
#include <process.h>
#endif

static int _debug_on = 0;
static int test_cancelio = 0;

#include "obsolete/prsem.h"

#ifdef XP_PC
#define mode_t int
#endif

#define DPRINTF(arg) if (_debug_on) printf arg

#ifdef XP_PC
char *TEST_DIR = "prdir";
char *SMALL_FILE_NAME = "prsmallf";
char *LARGE_FILE_NAME = "prlargef";
#elif defined(SYMBIAN)
char *TEST_DIR = "c:\\data\\prsocket";
char *SMALL_FILE_NAME = "c:\\data\\prsocket\\small_file";
char *LARGE_FILE_NAME = "c:\\data\\prsocket\\large_file";
#else
char *TEST_DIR = "/tmp/prsocket_test_dir";
char *SMALL_FILE_NAME = "/tmp/prsocket_test_dir/small_file";
char *LARGE_FILE_NAME = "/tmp/prsocket_test_dir/large_file";
#endif
#define SMALL_FILE_SIZE				(3 * 1024)        /* 3 KB        */
#define SMALL_FILE_OFFSET_1			(512)
#define SMALL_FILE_LEN_1			(1 * 1024)        /* 1 KB        */
#define SMALL_FILE_OFFSET_2			(75)
#define SMALL_FILE_LEN_2			(758)
#define SMALL_FILE_OFFSET_3			(1024)
#define SMALL_FILE_LEN_3			(SMALL_FILE_SIZE - SMALL_FILE_OFFSET_3)
#define SMALL_FILE_HEADER_SIZE    	(64)            /* 64 bytes    */
#define SMALL_FILE_TRAILER_SIZE   	(128)           /* 128 bytes    */

#define LARGE_FILE_SIZE				(3 * 1024 * 1024)    /* 3 MB        */
#define LARGE_FILE_OFFSET_1			(0)
#define LARGE_FILE_LEN_1			(2 * 1024 * 1024)    /* 2 MB        */
#define LARGE_FILE_OFFSET_2			(64)
#define LARGE_FILE_LEN_2			(1 * 1024 * 1024 + 75)
#define LARGE_FILE_OFFSET_3			(2 * 1024 * 1024 - 128)
#define LARGE_FILE_LEN_3			(LARGE_FILE_SIZE - LARGE_FILE_OFFSET_3)
#define LARGE_FILE_OFFSET_4			PR_GetPageSize()
#define LARGE_FILE_LEN_4			769
#define LARGE_FILE_HEADER_SIZE    	(512)
#define LARGE_FILE_TRAILER_SIZE   	(64)

#define    BUF_DATA_SIZE    (2 * 1024)
#define TCP_MESG_SIZE    1024
/*
 * set UDP datagram size small enough that datagrams sent to a port on the
 * local host will not be lost
 */
#define UDP_DGRAM_SIZE            128
#define NUM_TCP_CLIENTS            5	/* for a listen queue depth of 5 */
#define NUM_UDP_CLIENTS            10

#ifdef SYMBIAN
#define NUM_TRANSMITFILE_CLIENTS    1
#else
#define NUM_TRANSMITFILE_CLIENTS    4
#endif

#define NUM_TCP_CONNECTIONS_PER_CLIENT    5
#define NUM_TCP_MESGS_PER_CONNECTION    10
#define NUM_UDP_DATAGRAMS_PER_CLIENT    5
#define TCP_SERVER_PORT            10000
#define UDP_SERVER_PORT            TCP_SERVER_PORT
#define SERVER_MAX_BIND_COUNT        100

#ifdef WINCE
#define perror(s)
#endif

static PRInt32 num_tcp_clients = NUM_TCP_CLIENTS;
static PRInt32 num_udp_clients = NUM_UDP_CLIENTS;
static PRInt32 num_transmitfile_clients = NUM_TRANSMITFILE_CLIENTS;
static PRInt32 num_tcp_connections_per_client = NUM_TCP_CONNECTIONS_PER_CLIENT;
static PRInt32 tcp_mesg_size = TCP_MESG_SIZE;
static PRInt32 num_tcp_mesgs_per_connection = NUM_TCP_MESGS_PER_CONNECTION;
static PRInt32 num_udp_datagrams_per_client = NUM_UDP_DATAGRAMS_PER_CLIENT;
static PRInt32 udp_datagram_size = UDP_DGRAM_SIZE;

static PRInt32 thread_count;
PRUint16 server_domain = PR_AF_INET, client_domain = PR_AF_INET;

/* an I/O layer that uses the emulated senfile method */
static PRDescIdentity emuSendFileIdentity;
static PRIOMethods emuSendFileMethods;

int failed_already=0;
typedef struct buffer {
    char    data[BUF_DATA_SIZE];
} buffer;

PRNetAddr tcp_server_addr, udp_server_addr;

typedef struct Serve_Client_Param {
    PRFileDesc *sockfd;    /* socket to read from/write to    */
    PRInt32    datalen;    /* bytes of data transfered in each read/write */
} Serve_Client_Param;

typedef struct Server_Param {
    PRSemaphore *addr_sem;    /* sem to post on, after setting up the address */
    PRMonitor *exit_mon;    /* monitor to signal on exit            */
    PRInt32 *exit_counter;    /* counter to decrement, before exit        */
    PRInt32    datalen;    /* bytes of data transfered in each read/write    */
} Server_Param;


typedef struct Client_Param {
    PRNetAddr server_addr;
    PRMonitor *exit_mon;    /* monitor to signal on exit */
    PRInt32 *exit_counter;    /* counter to decrement, before exit */
    PRInt32    datalen;
    PRInt32    udp_connect;    /* if set clients connect udp sockets */
} Client_Param;

/* the sendfile method in emuSendFileMethods */
static PRInt32 PR_CALLBACK
emu_SendFile(PRFileDesc *sd, PRSendFileData *sfd,
    PRTransmitFileFlags flags, PRIntervalTime timeout)
{
    return PR_EmulateSendFile(sd, sfd, flags, timeout);
}

/* the transmitfile method in emuSendFileMethods */
static PRInt32 PR_CALLBACK
emu_TransmitFile(PRFileDesc *sd, PRFileDesc *fd, const void *headers,
    PRInt32 hlen, PRTransmitFileFlags flags, PRIntervalTime timeout)
{
    PRSendFileData sfd;

    sfd.fd = fd;
    sfd.file_offset = 0;
    sfd.file_nbytes = 0;
    sfd.header = headers;
    sfd.hlen = hlen;
    sfd.trailer = NULL;
    sfd.tlen = 0;
    return emu_SendFile(sd, &sfd, flags, timeout);
}

/*
 * readn
 *    read data from sockfd into buf
 */
static PRInt32
readn(PRFileDesc *sockfd, char *buf, int len)
{
    int rem;
    int bytes;
    int offset = 0;
	int err;
	PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT;

	if (test_cancelio)
		timeout = PR_SecondsToInterval(2);

    for (rem=len; rem; offset += bytes, rem -= bytes) {
        DPRINTF(("thread = 0x%lx: calling PR_Recv, bytes = %d\n",
            PR_GetCurrentThread(), rem));
retry:
        bytes = PR_Recv(sockfd, buf + offset, rem, 0,
            	timeout);
        DPRINTF(("thread = 0x%lx: returning from PR_Recv, bytes = %d\n",
            PR_GetCurrentThread(), bytes));
        if (bytes < 0) {
#ifdef WINNT
			printf("PR_Recv: error = %d oserr = %d\n",(err = PR_GetError()),
									PR_GetOSError());
			if ((test_cancelio) && (err == PR_IO_TIMEOUT_ERROR)) {
				if (PR_NT_CancelIo(sockfd) != PR_SUCCESS)
					printf("PR_NT_CancelIO: error = %d\n",PR_GetError());
				timeout = PR_INTERVAL_NO_TIMEOUT;
				goto retry;
			}
#endif
			return -1;
		}	
    }
    return len;
}

/*
 * writen
 *    write data from buf to sockfd
 */
static PRInt32
writen(PRFileDesc *sockfd, char *buf, int len)
{
    int rem;
    int bytes;
    int offset = 0;

    for (rem=len; rem; offset += bytes, rem -= bytes) {
        DPRINTF(("thread = 0x%lx: calling PR_Send, bytes = %d\n",
            PR_GetCurrentThread(), rem));
        bytes = PR_Send(sockfd, buf + offset, rem, 0,
            PR_INTERVAL_NO_TIMEOUT);
        DPRINTF(("thread = 0x%lx: returning from PR_Send, bytes = %d\n",
            PR_GetCurrentThread(), bytes));
        if (bytes <= 0)
            return -1;
    }
    return len;
}

/*
 * Serve_Client
 *    Thread, started by the server, for serving a client connection.
 *    Reads data from socket and writes it back, unmodified, and
 *    closes the socket
 */
static void PR_CALLBACK
Serve_Client(void *arg)
{
    Serve_Client_Param *scp = (Serve_Client_Param *) arg;
    PRFileDesc *sockfd;
    buffer *in_buf;
    PRInt32 bytes, j;

    sockfd = scp->sockfd;
    bytes = scp->datalen;
    in_buf = PR_NEW(buffer);
    if (in_buf == NULL) {
        fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n");
        failed_already=1;
        goto exit;
    }


    for (j = 0; j < num_tcp_mesgs_per_connection; j++) {
        /*
         * Read data from client and send it back to the client unmodified
         */
        if (readn(sockfd, in_buf->data, bytes) < bytes) {
            fprintf(stderr,"prsocket_test: ERROR - Serve_Client:readn\n");
            failed_already=1;
            goto exit;
        }
        /* Shutdown only RCV will cause error on Symbian OS */
#if !defined(SYMBIAN)
        /*
         * shutdown reads, after the last read
         */
        if (j == num_tcp_mesgs_per_connection - 1)
            if (PR_Shutdown(sockfd, PR_SHUTDOWN_RCV) < 0) {
                fprintf(stderr,"prsocket_test: ERROR - PR_Shutdown\n");
            }
#endif
        DPRINTF(("Serve_Client [0x%lx]: inbuf[0] = 0x%lx\n",PR_GetCurrentThread(),
            (*((int *) in_buf->data))));
        if (writen(sockfd, in_buf->data, bytes) < bytes) {
            fprintf(stderr,"prsocket_test: ERROR - Serve_Client:writen\n");
            failed_already=1;
            goto exit;
        }
    }
    /*
     * shutdown reads and writes
     */
    if (PR_Shutdown(sockfd, PR_SHUTDOWN_BOTH) < 0) {
        fprintf(stderr,"prsocket_test: ERROR - PR_Shutdown\n");
        failed_already=1;
    }

exit:
    PR_Close(sockfd);
    if (in_buf) {
        PR_DELETE(in_buf);
    }
}

PRThread* create_new_thread(PRThreadType type,
							void (*start)(void *arg),
							void *arg,
							PRThreadPriority priority,
							PRThreadScope scope,
							PRThreadState state,
							PRUint32 stackSize, PRInt32 index)
{
PRInt32 native_thread = 0;

	PR_ASSERT(state == PR_UNJOINABLE_THREAD);
#if (defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)) || defined(WIN32)
	switch(index %  4) {
		case 0:
			scope = (PR_LOCAL_THREAD);
			break;
		case 1:
			scope = (PR_GLOBAL_THREAD);
			break;
		case 2:
			scope = (PR_GLOBAL_BOUND_THREAD);
			break;
		case 3:
			native_thread = 1;
			break;
		default:
			PR_ASSERT(!"Invalid scope");
			break;
	}
	if (native_thread) {
#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
		pthread_t tid;
		if (!pthread_create(&tid, NULL, (void * (*)(void *)) start, arg))
			return((PRThread *) tid);
		else
			return (NULL);
#else
		HANDLE thandle;
		unsigned tid;
		
		thandle = (HANDLE) _beginthreadex(
						NULL,
						stackSize,
						(unsigned (__stdcall *)(void *))start,
						arg,
						0,
						&tid);		
		return((PRThread *) thandle);
#endif
	} else {
		return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize));
	}
#else
	return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize));
#endif
}

/*
 * TCP Server
 *    Server Thread
 *    Bind an address to a socket and listen for incoming connections
 *    Start a Serve_Client thread for each incoming connection.
 */
static void PR_CALLBACK
TCP_Server(void *arg)
{
    PRThread *t;
    Server_Param *sp = (Server_Param *) arg;
    Serve_Client_Param *scp;
    PRFileDesc *sockfd, *newsockfd;
    PRNetAddr netaddr;
    PRInt32 i;
    /*
     * Create a tcp socket
     */
	if ((sockfd = PR_OpenTCPSocket(server_domain)) == NULL) {
        fprintf(stderr,"prsocket_test: PR_NewTCPSocket failed\n");
        goto exit;
    }
    memset(&netaddr, 0 , sizeof(netaddr));
	
	if (PR_SetNetAddr(PR_IpAddrAny, server_domain, TCP_SERVER_PORT,
									&netaddr) == PR_FAILURE) {
        fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n");
        goto exit;
	}
    /*
     * try a few times to bind server's address, if addresses are in
     * use
     */
    i = 0;
	
    while (PR_Bind(sockfd, &netaddr) < 0) {
        if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) {
            netaddr.inet.port += 2;
            if (i++ < SERVER_MAX_BIND_COUNT)
                continue;
        }
        fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n");
        perror("PR_Bind");
        failed_already=1;
        goto exit;
    }

    if (PR_Listen(sockfd, 32) < 0) {
        fprintf(stderr,"prsocket_test: ERROR - PR_Listen failed\n");
        failed_already=1;
        goto exit;
    }

    if (PR_GetSockName(sockfd, &netaddr) < 0) {
        fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n");
        failed_already=1;
        goto exit;
    }

    DPRINTF(("TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",
        netaddr.inet.ip, netaddr.inet.port));
	if (PR_SetNetAddr(PR_IpAddrLoopback, client_domain,
									PR_ntohs(PR_NetAddrInetPort(&netaddr)),
									&tcp_server_addr) == PR_FAILURE) {
        fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n");
        goto exit;
	}
	if ((client_domain == PR_AF_INET6) && (server_domain == PR_AF_INET))
		PR_ConvertIPv4AddrToIPv6(PR_htonl(INADDR_LOOPBACK),
								&tcp_server_addr.ipv6.ip);

    /*
     * Wake up parent thread because server address is bound and made
     * available in the global variable 'tcp_server_addr'
     */
    PR_PostSem(sp->addr_sem);

    for (i = 0; i < (num_tcp_clients * num_tcp_connections_per_client); i++) {
        /* test both null and non-null 'addr' argument to PR_Accept */
        PRNetAddr *addrp = (i%2 ? &netaddr: NULL);

    DPRINTF(("TCP_Server: Accepting connection\n"));
        if ((newsockfd = PR_Accept(sockfd, addrp,
            PR_INTERVAL_NO_TIMEOUT)) == NULL) {
            fprintf(stderr,"prsocket_test: ERROR - PR_Accept failed\n");
            goto exit;
        }
    DPRINTF(("TCP_Server: Accepted connection\n"));
        scp = PR_NEW(Serve_Client_Param);
        if (scp == NULL) {
            fprintf(stderr,"prsocket_test: PR_NEW failed\n");
            goto exit;
        }

        /*
         * Start a Serve_Client thread for each incoming connection
         */
        scp->sockfd = newsockfd;
        scp->datalen = sp->datalen;

        t = create_new_thread(PR_USER_THREAD,
            Serve_Client, (void *)scp, 
            PR_PRIORITY_NORMAL,
            PR_LOCAL_THREAD,
            PR_UNJOINABLE_THREAD,
            0, i);
        if (t == NULL) {
            fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
            failed_already=1;
            goto exit;
        }
        DPRINTF(("TCP_Server: Created Serve_Client = 0x%lx\n", t));
    }

exit:
    if (sockfd) {
        PR_Close(sockfd);
    }

    /*
     * Decrement exit_counter and notify parent thread
     */

    PR_EnterMonitor(sp->exit_mon);
    --(*sp->exit_counter);
    PR_Notify(sp->exit_mon);
    PR_ExitMonitor(sp->exit_mon);
    DPRINTF(("TCP_Server [0x%lx] exiting\n", PR_GetCurrentThread()));
}

/*
 * UDP Server
 *    Server Thread
 *    Bind an address to a socket, read data from clients and send data
 *    back to clients
 */
static void PR_CALLBACK
UDP_Server(void *arg)
{
    Server_Param *sp = (Server_Param *) arg;
    PRFileDesc *sockfd;
    buffer *in_buf;
    PRNetAddr netaddr;
    PRInt32 bytes, i, rv = 0;


    bytes = sp->datalen;
    /*
     * Create a udp socket
     */
	if ((sockfd = PR_OpenUDPSocket(server_domain)) == NULL) {
        fprintf(stderr,"prsocket_test: PR_NewUDPSocket failed\n");
        failed_already=1;
        return;
    }
    memset(&netaddr, 0 , sizeof(netaddr));
	if (PR_SetNetAddr(PR_IpAddrAny, server_domain, UDP_SERVER_PORT,
									&netaddr) == PR_FAILURE) {
        fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n");
        failed_already=1;
        return;
	}
    /*
     * try a few times to bind server's address, if addresses are in
     * use
     */
    i = 0;
    while (PR_Bind(sockfd, &netaddr) < 0) {
        if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) {
            netaddr.inet.port += 2;
            if (i++ < SERVER_MAX_BIND_COUNT)
                continue;
        }
        fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n");
        perror("PR_Bind");
        failed_already=1;
        return;
    }

    if (PR_GetSockName(sockfd, &netaddr) < 0) {
        fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n");
        failed_already=1;
        return;
    }

    DPRINTF(("PR_Bind: UDP Server netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",
        netaddr.inet.ip, netaddr.inet.port));
    /*
     * We can't use the IP address returned by PR_GetSockName in
     * netaddr.inet.ip because netaddr.inet.ip is returned
     * as 0 (= PR_INADDR_ANY).
     */

	if (PR_SetNetAddr(PR_IpAddrLoopback, client_domain,
									PR_ntohs(PR_NetAddrInetPort(&netaddr)),
									&udp_server_addr) == PR_FAILURE) {
        fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n");
        failed_already=1;
        return;
	}
	if ((client_domain == PR_AF_INET6) && (server_domain == PR_AF_INET))
		PR_ConvertIPv4AddrToIPv6(PR_htonl(INADDR_LOOPBACK),
								&udp_server_addr.ipv6.ip);
		
    /*
     * Wake up parent thread because server address is bound and made
     * available in the global variable 'udp_server_addr'
     */
    PR_PostSem(sp->addr_sem);

    bytes = sp->datalen;
    in_buf = PR_NEW(buffer);
    if (in_buf == NULL) {
        fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n");
        failed_already=1;
        return;
    }
    /*
     * Receive datagrams from clients and send them back, unmodified, to the
     * clients
     */
    memset(&netaddr, 0 , sizeof(netaddr));
    for (i = 0; i < (num_udp_clients * num_udp_datagrams_per_client); i++) {
        DPRINTF(("UDP_Server: calling PR_RecvFrom client  - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n",
            netaddr.inet.ip, netaddr.inet.port, bytes, in_buf->data,
            in_buf->data[0]));

        rv = PR_RecvFrom(sockfd, in_buf->data, bytes, 0, &netaddr,
            PR_INTERVAL_NO_TIMEOUT);
        DPRINTF(("UDP_Server: PR_RecvFrom client  - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n",
            netaddr.inet.ip, netaddr.inet.port, rv, in_buf->data,
            in_buf->data[0]));
        if (rv != bytes) {
            return;
        }
        rv = PR_SendTo(sockfd, in_buf->data, bytes, 0, &netaddr,
            PR_INTERVAL_NO_TIMEOUT);
        if (rv != bytes) {
            return;
        }
    }

    PR_DELETE(in_buf);
    PR_Close(sockfd);

    /*
     * Decrement exit_counter and notify parent thread
     */
    PR_EnterMonitor(sp->exit_mon);
    --(*sp->exit_counter);
    PR_Notify(sp->exit_mon);
    PR_ExitMonitor(sp->exit_mon);
    DPRINTF(("UDP_Server [0x%x] exiting\n", PR_GetCurrentThread()));
}

/*
 * TCP_Client
 *    Client Thread
 *    Connect to the server at the address specified in the argument.
 *    Fill in a buffer, write data to server, read it back and check
 *    for data corruption.
 *    Close the socket for server connection
 */
static void PR_CALLBACK
TCP_Client(void *arg)
{
    Client_Param *cp = (Client_Param *) arg;
    PRFileDesc *sockfd;
    buffer *in_buf, *out_buf;
    union PRNetAddr netaddr;
    PRInt32 bytes, i, j;


    bytes = cp->datalen;
    out_buf = PR_NEW(buffer);
    if (out_buf == NULL) {
        fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n");
        failed_already=1;
        return;
    }
    in_buf = PR_NEW(buffer);
    if (in_buf == NULL) {
        fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n");
        failed_already=1;
        return;
    }
    netaddr = cp->server_addr;

    for (i = 0; i < num_tcp_connections_per_client; i++) {
        if ((sockfd = PR_OpenTCPSocket(client_domain)) == NULL) {
            fprintf(stderr,"prsocket_test: PR_OpenTCPSocket failed\n");
            failed_already=1;
            return;
        }
        if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){
        	fprintf(stderr, "PR_Connect failed: (%ld, %ld)\n",
            		PR_GetError(), PR_GetOSError());
            failed_already=1;
            return;
        }
        for (j = 0; j < num_tcp_mesgs_per_connection; j++) {
            /*
             * fill in random data
             */
            memset(out_buf->data, ((PRInt32) (&netaddr)) + i + j, bytes);
            /*
             * write to server
             */
#ifdef WINNT
			if (test_cancelio && (j == 0))
				PR_Sleep(PR_SecondsToInterval(12));
#endif
            if (writen(sockfd, out_buf->data, bytes) < bytes) {
                fprintf(stderr,"prsocket_test: ERROR - TCP_Client:writen\n");
                failed_already=1;
                return;
            }
            DPRINTF(("TCP Client [0x%lx]: out_buf = 0x%lx out_buf[0] = 0x%lx\n",
                PR_GetCurrentThread(), out_buf, (*((int *) out_buf->data))));
            if (readn(sockfd, in_buf->data, bytes) < bytes) {
                fprintf(stderr,"prsocket_test: ERROR - TCP_Client:readn\n");
                failed_already=1;
                return;
            }
            /*
             * verify the data read
             */
            if (memcmp(in_buf->data, out_buf->data, bytes) != 0) {
                fprintf(stderr,"prsocket_test: ERROR - data corruption\n");
                failed_already=1;
                return;
            }
        }
        /*
         * shutdown reads and writes
         */
        if (PR_Shutdown(sockfd, PR_SHUTDOWN_BOTH) < 0) {
            fprintf(stderr,"prsocket_test: ERROR - PR_Shutdown\n");
#if defined(SYMBIAN)
            if (EPIPE != errno)
#endif
            failed_already=1;
        }
        PR_Close(sockfd);
    }

    PR_DELETE(out_buf);
    PR_DELETE(in_buf);

    /*
     * Decrement exit_counter and notify parent thread
     */

    PR_EnterMonitor(cp->exit_mon);
    --(*cp->exit_counter);
    PR_Notify(cp->exit_mon);
    PR_ExitMonitor(cp->exit_mon);
    DPRINTF(("TCP_Client [0x%x] exiting\n", PR_GetCurrentThread()));
}

/*
 * UDP_Client
 *    Client Thread
 *    Create a socket and bind an address 
 *    Communicate with the server at the address specified in the argument.
 *    Fill in a buffer, write data to server, read it back and check
 *    for data corruption.
 *    Close the socket
 */
static void PR_CALLBACK
UDP_Client(void *arg)
{
    Client_Param *cp = (Client_Param *) arg;
    PRFileDesc *sockfd;
    buffer *in_buf, *out_buf;
    union PRNetAddr netaddr;
    PRInt32 bytes, i, rv;


    bytes = cp->datalen;
    out_buf = PR_NEW(buffer);
    if (out_buf == NULL) {
        fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n");
        failed_already=1;
        return;
    }
    in_buf = PR_NEW(buffer);
    if (in_buf == NULL) {
        fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n");
        failed_already=1;
        return;
    }
    if ((sockfd = PR_OpenUDPSocket(client_domain)) == NULL) {
        fprintf(stderr,"prsocket_test: PR_OpenUDPSocket failed\n");
        failed_already=1;
        return;
    }

    /*
     * bind an address for the client, let the system chose the port
     * number
     */
    memset(&netaddr, 0 , sizeof(netaddr));
	if (PR_SetNetAddr(PR_IpAddrAny, client_domain, 0,
									&netaddr) == PR_FAILURE) {
        fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n");
        failed_already=1;
        return;
	}
    if (PR_Bind(sockfd, &netaddr) < 0) {
        fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n");
        perror("PR_Bind");
        return;
    }

    if (PR_GetSockName(sockfd, &netaddr) < 0) {
        fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n");
        failed_already=1;
        return;
    }

    DPRINTF(("PR_Bind: UDP Client netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",
        netaddr.inet.ip, netaddr.inet.port));

    netaddr = cp->server_addr;

    if (cp->udp_connect) {
        if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){
            fprintf(stderr,"prsocket_test: PR_Connect failed\n");
            failed_already=1;
            return;
        }
    }

    for (i = 0; i < num_udp_datagrams_per_client; i++) {
        /*
         * fill in random data
         */
        DPRINTF(("UDP_Client [0x%lx]: out_buf = 0x%lx bytes = 0x%lx\n",
            PR_GetCurrentThread(), out_buf->data, bytes));
        memset(out_buf->data, ((PRInt32) (&netaddr)) + i, bytes);
        /*
         * write to server
         */
        if (cp->udp_connect)
            rv = PR_Send(sockfd, out_buf->data, bytes, 0,
                PR_INTERVAL_NO_TIMEOUT);
        else
            rv = PR_SendTo(sockfd, out_buf->data, bytes, 0, &netaddr,
                PR_INTERVAL_NO_TIMEOUT);
        if (rv != bytes) {
            return;
        }
        DPRINTF(("UDP_Client [0x%lx]: out_buf = 0x%lx out_buf[0] = 0x%lx\n",
            PR_GetCurrentThread(), out_buf, (*((int *) out_buf->data))));
        if (cp->udp_connect)
            rv = PR_Recv(sockfd, in_buf->data, bytes, 0,
                PR_INTERVAL_NO_TIMEOUT);
        else
            rv = PR_RecvFrom(sockfd, in_buf->data, bytes, 0, &netaddr,
                PR_INTERVAL_NO_TIMEOUT);
        if (rv != bytes) {
            return;
        }
        DPRINTF(("UDP_Client [0x%lx]: in_buf = 0x%lx in_buf[0] = 0x%lx\n",
            PR_GetCurrentThread(), in_buf, (*((int *) in_buf->data))));
        /*
         * verify the data read
         */
        if (memcmp(in_buf->data, out_buf->data, bytes) != 0) {
            fprintf(stderr,"prsocket_test: ERROR - UDP data corruption\n");
            failed_already=1;
            return;
        }
    }
    PR_Close(sockfd);

    PR_DELETE(in_buf);
    PR_DELETE(out_buf);

    /*
     * Decrement exit_counter and notify parent thread
     */

    PR_EnterMonitor(cp->exit_mon);
    --(*cp->exit_counter);
    PR_Notify(cp->exit_mon);
    PR_ExitMonitor(cp->exit_mon);
    PR_DELETE(cp);
    DPRINTF(("UDP_Client [0x%x] exiting\n", PR_GetCurrentThread()));
}

/*
 * TCP_Socket_Client_Server_Test    - concurrent server test
 *    
 *    One server and several clients are started
 *    Each client connects to the server and sends a chunk of data
 *    For each connection, server starts another thread to read the data
 *    from the client and send it back to the client, unmodified.
 *    Each client checks that data received from server is same as the
 *    data it sent to the server.
 *
 */

static PRInt32
TCP_Socket_Client_Server_Test(void)
{
    int i;
    PRThread *t;
    PRSemaphore *server_sem;
    Server_Param *sparamp;
    Client_Param *cparamp;
    PRMonitor *mon2;
    PRInt32    datalen;


    datalen = tcp_mesg_size;
    thread_count = 0;
    /*
     * start the server thread
     */
    sparamp = PR_NEW(Server_Param);
    if (sparamp == NULL) {
        fprintf(stderr,"prsocket_test: PR_NEW failed\n");
        failed_already=1;
        return -1;
    }
    server_sem = PR_NewSem(0);
    if (server_sem == NULL) {
        fprintf(stderr,"prsocket_test: PR_NewSem failed\n");
        failed_already=1;
        return -1;
    }
    mon2 = PR_NewMonitor();
    if (mon2 == NULL) {
        fprintf(stderr,"prsocket_test: PR_NewMonitor failed\n");
        failed_already=1;
        return -1;
    }
    PR_EnterMonitor(mon2);

    sparamp->addr_sem = server_sem;
    sparamp->exit_mon = mon2;
    sparamp->exit_counter = &thread_count;
    sparamp->datalen = datalen;
    t = PR_CreateThread(PR_USER_THREAD,
        TCP_Server, (void *)sparamp, 
        PR_PRIORITY_NORMAL,
        PR_LOCAL_THREAD,
        PR_UNJOINABLE_THREAD,
        0);
    if (t == NULL) {
        fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
        failed_already=1;
        return -1;
    }
    DPRINTF(("Created TCP server = 0x%lx\n", t));
    thread_count++;

    /*
     * wait till the server address is setup
     */
    PR_WaitSem(server_sem);

    /*
     * Now start a bunch of client threads
     */

    cparamp = PR_NEW(Client_Param);
    if (cparamp == NULL) {
        fprintf(stderr,"prsocket_test: PR_NEW failed\n");
        failed_already=1;
        return -1;
    }
    cparamp->server_addr = tcp_server_addr;
    cparamp->exit_mon = mon2;
    cparamp->exit_counter = &thread_count;
    cparamp->datalen = datalen;
    for (i = 0; i < num_tcp_clients; i++) {
        t = create_new_thread(PR_USER_THREAD,
            TCP_Client, (void *) cparamp,
            PR_PRIORITY_NORMAL,
            PR_LOCAL_THREAD,
            PR_UNJOINABLE_THREAD,
            0, i);
        if (t == NULL) {
            fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
            failed_already=1;
            return -1;
        }
        DPRINTF(("Created TCP client = 0x%lx\n", t));
        thread_count++;
    }
    /* Wait for server and client threads to exit */
    while (thread_count) {
        PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT);
        DPRINTF(("TCP Server - thread_count  = %d\n", thread_count));
    }
    PR_ExitMonitor(mon2);
    printf("%30s","TCP_Socket_Client_Server_Test:");
    printf("%2ld Server %2ld Clients %2ld connections_per_client\n",1l,
        num_tcp_clients, num_tcp_connections_per_client);
    printf("%30s %2ld messages_per_connection %4ld bytes_per_message\n",":",
        num_tcp_mesgs_per_connection, tcp_mesg_size);

    return 0;
}

/*
 * UDP_Socket_Client_Server_Test    - iterative server test
 *    
 *    One server and several clients are started
 *    Each client connects to the server and sends a chunk of data
 *    For each connection, server starts another thread to read the data
 *    from the client and send it back to the client, unmodified.
 *    Each client checks that data received from server is same as the
 *    data it sent to the server.
 *
 */

static PRInt32
UDP_Socket_Client_Server_Test(void)
{
    int i;
    PRThread *t;
    PRSemaphore *server_sem;
    Server_Param *sparamp;
    Client_Param *cparamp;
    PRMonitor *mon2;
    PRInt32    datalen;
    PRInt32    udp_connect = 1;


    datalen = udp_datagram_size;
    thread_count = 0;
    /*
     * start the server thread
     */
    sparamp = PR_NEW(Server_Param);
    if (sparamp == NULL) {
        fprintf(stderr,"prsocket_test: PR_NEW failed\n");
        failed_already=1;
        return -1;
    }
    server_sem = PR_NewSem(0);
    if (server_sem == NULL) {
        fprintf(stderr,"prsocket_test: PR_NewSem failed\n");
        failed_already=1;
        return -1;
    }
    mon2 = PR_NewMonitor();
    if (mon2 == NULL) {
        fprintf(stderr,"prsocket_test: PR_NewMonitor failed\n");
        failed_already=1;
        return -1;
    }
    PR_EnterMonitor(mon2);

    sparamp->addr_sem = server_sem;
    sparamp->exit_mon = mon2;
    sparamp->exit_counter = &thread_count;
    sparamp->datalen = datalen;
    DPRINTF(("Creating UDP server"));
    t = PR_CreateThread(PR_USER_THREAD,
        UDP_Server, (void *)sparamp, 
        PR_PRIORITY_NORMAL,
        PR_LOCAL_THREAD,
        PR_UNJOINABLE_THREAD,
        0);
    if (t == NULL) {
        fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
        failed_already=1;
        return -1;
    }
    thread_count++;

    /*
     * wait till the server address is setup
     */
    PR_WaitSem(server_sem);

    /*
     * Now start a bunch of client threads
     */

    for (i = 0; i < num_udp_clients; i++) {
        cparamp = PR_NEW(Client_Param);
        if (cparamp == NULL) {
            fprintf(stderr,"prsocket_test: PR_NEW failed\n");
            failed_already=1;
            return -1;
        }
        cparamp->server_addr = udp_server_addr;
        cparamp->exit_mon = mon2;
        cparamp->exit_counter = &thread_count;
        cparamp->datalen = datalen;
        /*
         * Cause every other client thread to connect udp sockets
         */
        cparamp->udp_connect = udp_connect;
        if (udp_connect)
            udp_connect = 0;
        else
            udp_connect = 1;
        DPRINTF(("Creating UDP client %d\n", i));
        t = PR_CreateThread(PR_USER_THREAD,
            UDP_Client, (void *) cparamp,
            PR_PRIORITY_NORMAL,
            PR_LOCAL_THREAD,
            PR_UNJOINABLE_THREAD,
            0);
        if (t == NULL) {
            fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
            failed_already=1;
            return -1;
        }
        thread_count++;
    }
    /* Wait for server and client threads to exit */
    while (thread_count) {
        PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT);
        DPRINTF(("UDP Server - thread_count  = %d\n", thread_count));
    }
    PR_ExitMonitor(mon2);
    printf("%30s","UDP_Socket_Client_Server_Test: ");
    printf("%2ld Server %2ld Clients\n",1l, num_udp_clients);
    printf("%30s %2ld datagrams_per_client %4ld bytes_per_datagram\n",":",
        num_udp_datagrams_per_client, udp_datagram_size);

    return 0;
}

static PRFileDesc *small_file_fd, *large_file_fd;
static void *small_file_addr, *small_file_header, *large_file_addr;
static void *small_file_trailer, *large_file_header, *large_file_trailer;
/*
 * TransmitFile_Client
 *    Client Thread
 */
static void
TransmitFile_Client(void *arg)
{
    PRFileDesc *sockfd;
    union PRNetAddr netaddr;
    char *small_buf, *large_buf;
    Client_Param *cp = (Client_Param *) arg;
	PRInt32 rlen;

    small_buf = (char*)PR_Malloc(SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE +
										SMALL_FILE_TRAILER_SIZE);
    if (small_buf == NULL) {
        fprintf(stderr,"prsocket_test: failed to alloc buffer\n");
        failed_already=1;
        return;
    }
    large_buf = (char*)PR_Malloc(LARGE_FILE_SIZE + LARGE_FILE_HEADER_SIZE +
												LARGE_FILE_TRAILER_SIZE);
    if (large_buf == NULL) {
        fprintf(stderr,"prsocket_test: failed to alloc buffer\n");
        failed_already=1;
        return;
    }
    netaddr.inet.family = cp->server_addr.inet.family;
    netaddr.inet.port = cp->server_addr.inet.port;
    netaddr.inet.ip = cp->server_addr.inet.ip;

    if ((sockfd = PR_NewTCPSocket()) == NULL) {
        fprintf(stderr,"prsocket_test: PR_NewTCPSocket failed\n");
        failed_already=1;
        return;
    }

    if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){
        fprintf(stderr,"prsocket_test: PR_Connect failed\n");
        failed_already=1;
        return;
    }
    /*
     * read the small file and verify the data
     */
    if (readn(sockfd, small_buf, SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE)
        != (SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE)) {
        fprintf(stderr,
            "prsocket_test: TransmitFile_Client failed to receive file\n");
        failed_already=1;
        return;
    }
#if defined(XP_UNIX) && !defined(SYMBIAN)
    /* File transmission test can not be done because of large file's size */
    if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE) != 0){
        fprintf(stderr,
            "prsocket_test: TransmitFile_Client ERROR - small file header data corruption\n");
        failed_already=1;
        return;
    }
    if (memcmp(small_file_addr, small_buf + SMALL_FILE_HEADER_SIZE,
        SMALL_FILE_SIZE) != 0) {
        fprintf(stderr,
            "prsocket_test: TransmitFile_Client ERROR - small file data corruption\n");
        failed_already=1;
        return;
    }
#endif
    /*
     * read the large file and verify the data
     */
    if (readn(sockfd, large_buf, LARGE_FILE_SIZE) != LARGE_FILE_SIZE) {
        fprintf(stderr,
            "prsocket_test: TransmitFile_Client failed to receive file\n");
        failed_already=1;
        return;
    }
#if defined(XP_UNIX) && !defined(SYMBIAN)
    if (memcmp(large_file_addr, large_buf, LARGE_FILE_SIZE) != 0) {
        fprintf(stderr,
            "prsocket_test: TransmitFile_Client ERROR - large file data corruption\n");
        failed_already=1;
    }
#endif


	/*
	 * receive data from PR_SendFile
	 */
	/*
	 * case 1: small file with header and trailer
	 */
    rlen = SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE +
									SMALL_FILE_TRAILER_SIZE;
    if (readn(sockfd, small_buf, rlen) != rlen) {
        fprintf(stderr,
            "prsocket_test: SendFile_Client failed to receive file\n");
        failed_already=1;
        return;
    }
#if defined(XP_UNIX) && !defined(SYMBIAN)
    if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE) != 0){
        fprintf(stderr,
            "SendFile 1. ERROR - small file header corruption\n");
        failed_already=1;
        return;
    }
    if (memcmp(small_file_addr, small_buf + SMALL_FILE_HEADER_SIZE,
        								SMALL_FILE_SIZE) != 0) {
        fprintf(stderr,
            "SendFile 1. ERROR - small file data corruption\n");
        failed_already=1;
        return;
    }
    if (memcmp(small_file_trailer,
				small_buf + SMALL_FILE_HEADER_SIZE + SMALL_FILE_SIZE,
        				SMALL_FILE_TRAILER_SIZE) != 0) {
        fprintf(stderr,
            "SendFile 1. ERROR - small file trailer corruption\n");
        failed_already=1;
        return;
    }
#endif
	/*
	 * case 2: partial large file at zero offset, file with header and trailer
	 */
    rlen = LARGE_FILE_LEN_1 + LARGE_FILE_HEADER_SIZE +
									LARGE_FILE_TRAILER_SIZE;
    if (readn(sockfd, large_buf, rlen) != rlen) {
        fprintf(stderr,
            "prsocket_test: SendFile_Client failed to receive file\n");
        failed_already=1;
        return;
    }
#if defined(XP_UNIX) && !defined(SYMBIAN)
    if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE) != 0){
        fprintf(stderr,
            "SendFile 2. ERROR - large file header corruption\n");
        failed_already=1;
        return;
    }
    if (memcmp(large_file_addr, large_buf + LARGE_FILE_HEADER_SIZE,
        								LARGE_FILE_LEN_1) != 0) {
        fprintf(stderr,
            "SendFile 2. ERROR - large file data corruption\n");
        failed_already=1;
        return;
    }
    if (memcmp(large_file_trailer,
				large_buf + LARGE_FILE_HEADER_SIZE + LARGE_FILE_LEN_1,
        				LARGE_FILE_TRAILER_SIZE) != 0) {
        fprintf(stderr,
            "SendFile 2. ERROR - large file trailer corruption\n");
        failed_already=1;
        return;
    }
#endif
	/*
	 * case 3: partial small file at non-zero offset, with header
	 */
    rlen = SMALL_FILE_LEN_1 + SMALL_FILE_HEADER_SIZE;
    if (readn(sockfd, small_buf, rlen) != rlen) {
        fprintf(stderr,
            "prsocket_test: SendFile_Client failed to receive file\n");
        failed_already=1;
        return;
    }
#if defined(XP_UNIX) && !defined(SYMBIAN)
    if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE) != 0){
        fprintf(stderr,
            "SendFile 3. ERROR - small file header corruption\n");
        failed_already=1;
        return;
    }
    if (memcmp((char *) small_file_addr + SMALL_FILE_OFFSET_1,
				small_buf + SMALL_FILE_HEADER_SIZE, SMALL_FILE_LEN_1) != 0) {
        fprintf(stderr,
            "SendFile 3. ERROR - small file data corruption\n");
        failed_already=1;
        return;
    }
#endif
	/*
	 * case 4: partial small file at non-zero offset, with trailer
	 */
    rlen = SMALL_FILE_LEN_2 + SMALL_FILE_TRAILER_SIZE;
    if (readn(sockfd, small_buf, rlen) != rlen) {
        fprintf(stderr,
            "prsocket_test: SendFile_Client failed to receive file\n");
        failed_already=1;
        return;
    }
#if defined(XP_UNIX) && !defined(SYMBIAN)
    if (memcmp((char *) small_file_addr + SMALL_FILE_OFFSET_2, small_buf,
        								SMALL_FILE_LEN_2) != 0) {
        fprintf(stderr,
            "SendFile 4. ERROR - small file data corruption\n");
        failed_already=1;
        return;
    }
    if (memcmp(small_file_trailer, small_buf + SMALL_FILE_LEN_2,
        				SMALL_FILE_TRAILER_SIZE) != 0) {
        fprintf(stderr,
            "SendFile 4. ERROR - small file trailer corruption\n");
        failed_already=1;
        return;
    }
#endif
	/*
	 * case 5: partial large file at non-zero offset, file with header
	 */
    rlen = LARGE_FILE_LEN_2 + LARGE_FILE_HEADER_SIZE;
    if (readn(sockfd, large_buf, rlen) != rlen) {
        fprintf(stderr,
            "prsocket_test: SendFile_Client failed to receive file\n");
        failed_already=1;
        return;
    }
#if defined(XP_UNIX) && !defined(SYMBIAN)
    if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE) != 0){
        fprintf(stderr,
            "SendFile 5. ERROR - large file header corruption\n");
        failed_already=1;
        return;
    }
    if (memcmp((char *)large_file_addr + LARGE_FILE_OFFSET_2,
					large_buf + LARGE_FILE_HEADER_SIZE,
        								LARGE_FILE_LEN_2) != 0) {
        fprintf(stderr,
            "SendFile 5. ERROR - large file data corruption\n");
        failed_already=1;
        return;
    }
#endif
	/*
	 * case 6: partial small file at non-zero offset, with header
	 */
    rlen = SMALL_FILE_LEN_3 + SMALL_FILE_HEADER_SIZE;
    if (readn(sockfd, small_buf, rlen) != rlen) {
        fprintf(stderr,
            "prsocket_test: SendFile_Client failed to receive file\n");
        failed_already=1;
        return;
    }
#if defined(XP_UNIX) && !defined(SYMBIAN)
    if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE) != 0){
        fprintf(stderr,
            "SendFile 6. ERROR - small file header corruption\n");
        return;
    }
    if (memcmp((char *) small_file_addr + SMALL_FILE_OFFSET_3,
				small_buf + SMALL_FILE_HEADER_SIZE, SMALL_FILE_LEN_3) != 0) {
#if 0
		char *i, *j;
		int k;

		i = (char *) small_file_addr + SMALL_FILE_OFFSET_3;
		j = small_buf + SMALL_FILE_HEADER_SIZE;
		k = SMALL_FILE_LEN_3;
		while (k-- > 0) {
			if (*i++ != *j++)
			printf("i = %d j = %d\n",
				(int) (i - ((char *) small_file_addr + SMALL_FILE_OFFSET_3)),
				(int) (j - (small_buf + SMALL_FILE_HEADER_SIZE)));
		}
#endif
        fprintf(stderr,
            "SendFile 6. ERROR - small file data corruption\n");
        failed_already=1;
        return;
    }
#endif
	/*
	 * case 7: partial large file at non-zero offset, with header
	 */
    rlen = LARGE_FILE_LEN_3 + LARGE_FILE_HEADER_SIZE;
    if (readn(sockfd, large_buf, rlen) != rlen) {
        fprintf(stderr,
            "prsocket_test: SendFile_Client failed to receive file\n");
        failed_already=1;
        return;
    }
#if defined(XP_UNIX) && !defined(SYMBIAN)
    if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE) != 0){
        fprintf(stderr,
            "SendFile 7. ERROR - large file header corruption\n");
        failed_already=1;
        return;
    }
    if (memcmp((char *)large_file_addr + LARGE_FILE_OFFSET_3,
					large_buf + LARGE_FILE_HEADER_SIZE,
        								LARGE_FILE_LEN_3) != 0) {
        fprintf(stderr,
            "SendFile 7. ERROR - large file data corruption\n");
        failed_already=1;
        return;
    }
#endif
	/*
	 * case 8: partial large file at non-zero, page-aligned offset, with
	 * header and trailer
	 */
    rlen = LARGE_FILE_LEN_4 + LARGE_FILE_HEADER_SIZE +
									LARGE_FILE_TRAILER_SIZE;
    if (readn(sockfd, large_buf, rlen) != rlen) {
        fprintf(stderr,
            "prsocket_test: SendFile_Client failed to receive file\n");
        failed_already=1;
        return;
    }
#if defined(XP_UNIX) && !defined(SYMBIAN)
    if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE) != 0){
        fprintf(stderr,
            "SendFile 2. ERROR - large file header corruption\n");
        failed_already=1;
        return;
    }
    if (memcmp((char *)large_file_addr + LARGE_FILE_OFFSET_4,
				large_buf + LARGE_FILE_HEADER_SIZE,
        								LARGE_FILE_LEN_4) != 0) {
        fprintf(stderr,
            "SendFile 2. ERROR - large file data corruption\n");
        failed_already=1;
        return;
    }
    if (memcmp(large_file_trailer,
				large_buf + LARGE_FILE_HEADER_SIZE + LARGE_FILE_LEN_4,
        				LARGE_FILE_TRAILER_SIZE) != 0) {
        fprintf(stderr,
            "SendFile 2. ERROR - large file trailer corruption\n");
        failed_already=1;
        return;
    }
#endif
    PR_DELETE(small_buf);
    PR_DELETE(large_buf);
    PR_Close(sockfd);


    /*
     * Decrement exit_counter and notify parent thread
     */

    PR_EnterMonitor(cp->exit_mon);
    --(*cp->exit_counter);
    PR_Notify(cp->exit_mon);
    PR_ExitMonitor(cp->exit_mon);
    DPRINTF(("TransmitFile_Client [0x%lx] exiting\n", PR_GetCurrentThread()));
}

/*
 * Serve_TransmitFile_Client
 *    Thread, started by the server, for serving a client connection.
 *    Trasmits a small file, with a header, and a large file, without
 *    a header
 */
static void
Serve_TransmitFile_Client(void *arg)
{
    Serve_Client_Param *scp = (Serve_Client_Param *) arg;
    PRFileDesc *sockfd;
    PRInt32 bytes;
    PRFileDesc *local_small_file_fd=NULL;
    PRFileDesc *local_large_file_fd=NULL;
	PRSendFileData sfd;
	PRInt32 slen;

    sockfd = scp->sockfd;
    local_small_file_fd = PR_Open(SMALL_FILE_NAME, PR_RDONLY,0);

    if (local_small_file_fd == NULL) {
        fprintf(stderr,"prsocket_test failed to open file for transmitting %s\n",
            SMALL_FILE_NAME);
        failed_already=1;
        goto done;
    }
    local_large_file_fd = PR_Open(LARGE_FILE_NAME, PR_RDONLY,0);

    if (local_large_file_fd == NULL) {
        fprintf(stderr,"prsocket_test failed to open file for transmitting %s\n",
            LARGE_FILE_NAME);
        failed_already=1;
        goto done;
    }
    bytes = PR_TransmitFile(sockfd, local_small_file_fd, small_file_header,
        SMALL_FILE_HEADER_SIZE, PR_TRANSMITFILE_KEEP_OPEN,
        PR_INTERVAL_NO_TIMEOUT);
    if (bytes != (SMALL_FILE_SIZE+ SMALL_FILE_HEADER_SIZE)) {
        fprintf(stderr,
            "prsocet_test: PR_TransmitFile failed: (%ld, %ld)\n",
            PR_GetError(), PR_GetOSError());
        failed_already=1;
    }
    bytes = PR_TransmitFile(sockfd, local_large_file_fd, NULL, 0,
        PR_TRANSMITFILE_KEEP_OPEN, PR_INTERVAL_NO_TIMEOUT);
    if (bytes != LARGE_FILE_SIZE) {
        fprintf(stderr,
            "prsocket_test: PR_TransmitFile failed: (%ld, %ld)\n",
            PR_GetError(), PR_GetOSError());
        failed_already=1;
    }

	/*
	 * PR_SendFile test cases
	 */

	/*
	 * case 1: small file with header and trailer
	 */
	sfd.fd = local_small_file_fd;
	sfd.file_offset = 0;
	sfd.file_nbytes = 0;
	sfd.header = small_file_header;
	sfd.hlen = SMALL_FILE_HEADER_SIZE;
	sfd.trailer = small_file_trailer;
	sfd.tlen = SMALL_FILE_TRAILER_SIZE;
    bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
        				PR_INTERVAL_NO_TIMEOUT);
    slen = SMALL_FILE_SIZE+ SMALL_FILE_HEADER_SIZE +
						SMALL_FILE_TRAILER_SIZE;
    if (bytes != slen) {
        fprintf(stderr,
			"socket: Error - 1. PR_SendFile  send_size = %d, bytes sent = %d\n",
									slen, bytes);
        fprintf(stderr,
            "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
            PR_GetError(), PR_GetOSError());
        failed_already=1;
    }

	/*
	 * case 2: partial large file at zero offset, file with header and trailer
	 */
	sfd.fd = local_large_file_fd;
	sfd.file_offset = 0;
	sfd.file_nbytes = LARGE_FILE_LEN_1;
	sfd.header = large_file_header;
	sfd.hlen = LARGE_FILE_HEADER_SIZE;
	sfd.trailer = large_file_trailer;
	sfd.tlen = LARGE_FILE_TRAILER_SIZE;
    bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
        				PR_INTERVAL_NO_TIMEOUT);
    slen = LARGE_FILE_LEN_1 + LARGE_FILE_HEADER_SIZE +
						LARGE_FILE_TRAILER_SIZE;
    if (bytes != slen) {
        fprintf(stderr,
			"socket: Error - 2. PR_SendFile send_size = %d, bytes sent = %d\n",
									slen, bytes);
        fprintf(stderr,
            "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
            PR_GetError(), PR_GetOSError());
        failed_already=1;
    }
	/*
	 * case 3: partial small file at non-zero offset, with header
	 */
	sfd.fd = local_small_file_fd;
	sfd.file_offset = SMALL_FILE_OFFSET_1;
	sfd.file_nbytes = SMALL_FILE_LEN_1;
	sfd.header = small_file_header;
	sfd.hlen = SMALL_FILE_HEADER_SIZE;
	sfd.trailer = NULL;
	sfd.tlen = 0;
    bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
        				PR_INTERVAL_NO_TIMEOUT);
    slen = SMALL_FILE_LEN_1 + SMALL_FILE_HEADER_SIZE;
    if (bytes != slen) {
        fprintf(stderr,
			"socket: Error - 3. PR_SendFile send_size = %d, bytes sent = %d\n",
									slen, bytes);
        fprintf(stderr,
            "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
            PR_GetError(), PR_GetOSError());
        failed_already=1;
    }
	/*
	 * case 4: partial small file at non-zero offset, with trailer
	 */
	sfd.fd = local_small_file_fd;
	sfd.file_offset = SMALL_FILE_OFFSET_2;
	sfd.file_nbytes = SMALL_FILE_LEN_2;
	sfd.header = NULL;
	sfd.hlen = 0;
	sfd.trailer = small_file_trailer;
	sfd.tlen = SMALL_FILE_TRAILER_SIZE;
    bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
        				PR_INTERVAL_NO_TIMEOUT);
    slen = SMALL_FILE_LEN_2 + SMALL_FILE_TRAILER_SIZE;
    if (bytes != slen) {
        fprintf(stderr,
			"socket: Error - 4. PR_SendFile send_size = %d, bytes sent = %d\n",
									slen, bytes);
        fprintf(stderr,
            "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
            PR_GetError(), PR_GetOSError());
        failed_already=1;
    }
	/*
	 * case 5: partial large file at non-zero offset, file with header
	 */
	sfd.fd = local_large_file_fd;
	sfd.file_offset = LARGE_FILE_OFFSET_2;
	sfd.file_nbytes = LARGE_FILE_LEN_2;
	sfd.header = large_file_header;
	sfd.hlen = LARGE_FILE_HEADER_SIZE;
	sfd.trailer = NULL;
	sfd.tlen = 0;
    bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
        				PR_INTERVAL_NO_TIMEOUT);
    slen = LARGE_FILE_LEN_2 + LARGE_FILE_HEADER_SIZE;
    if (bytes != slen) {
        fprintf(stderr,
			"socket: Error - 5. PR_SendFile send_size = %d, bytes sent = %d\n",
									slen, bytes);
        fprintf(stderr,
            "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
            PR_GetError(), PR_GetOSError());
        failed_already=1;
    }
	/*
	 * case 6: partial small file from non-zero offset till end of file, with header
	 */
	sfd.fd = local_small_file_fd;
	sfd.file_offset = SMALL_FILE_OFFSET_3;
	sfd.file_nbytes = 0;				/* data from offset to end-of-file */
	sfd.header = small_file_header;
	sfd.hlen = SMALL_FILE_HEADER_SIZE;
	sfd.trailer = NULL;
	sfd.tlen = 0;
    bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
        				PR_INTERVAL_NO_TIMEOUT);
    slen = SMALL_FILE_LEN_3 + SMALL_FILE_HEADER_SIZE;
    if (bytes != slen) {
        fprintf(stderr,
			"socket: Error - 6. PR_SendFile send_size = %d, bytes sent = %d\n",
									slen, bytes);
        fprintf(stderr,
            "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
            PR_GetError(), PR_GetOSError());
        failed_already=1;
    }
	/*
	 * case 7: partial large file at non-zero offset till end-of-file, with header
	 */
	sfd.fd = local_large_file_fd;
	sfd.file_offset = LARGE_FILE_OFFSET_3;
	sfd.file_nbytes = 0;				/* data until end-of-file */
	sfd.header = large_file_header;
	sfd.hlen = LARGE_FILE_HEADER_SIZE;
	sfd.trailer = NULL;
	sfd.tlen = 0;
    bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
        									PR_INTERVAL_NO_TIMEOUT);
    slen = LARGE_FILE_LEN_3 + LARGE_FILE_HEADER_SIZE;
    if (bytes != slen) {
        fprintf(stderr,
			"socket: Error - 7. PR_SendFile send_size = %d, bytes sent = %d\n",
									slen, bytes);
        fprintf(stderr,
            "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
            PR_GetError(), PR_GetOSError());
        failed_already=1;
    }
	/*
	 * case 8: partial large file at non-zero page-aligned offset,
	 * with header and trailer
	 */
	sfd.fd = local_large_file_fd;
	sfd.file_offset = LARGE_FILE_OFFSET_4;
	sfd.file_nbytes = LARGE_FILE_LEN_4;
	sfd.header = large_file_header;
	sfd.hlen = LARGE_FILE_HEADER_SIZE;
	sfd.trailer = large_file_trailer;
	sfd.tlen = LARGE_FILE_TRAILER_SIZE;
    bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_CLOSE_SOCKET,
        				PR_INTERVAL_NO_TIMEOUT);
    slen = LARGE_FILE_LEN_4 + LARGE_FILE_HEADER_SIZE +
						LARGE_FILE_TRAILER_SIZE;
    if (bytes != slen) {
        fprintf(stderr,
			"socket: Error - 2. PR_SendFile send_size = %d, bytes sent = %d\n",
									slen, bytes);
        fprintf(stderr,
            "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
            PR_GetError(), PR_GetOSError());
        failed_already=1;
    }
done:
    if (local_small_file_fd != NULL)
        PR_Close(local_small_file_fd);
    if (local_large_file_fd != NULL)
        PR_Close(local_large_file_fd);
}

/*
 * TransmitFile Server
 *    Server Thread
 *    Bind an address to a socket and listen for incoming connections
 *    Create worker threads to service clients
 */
static void
TransmitFile_Server(void *arg)
{
    PRThread **t = NULL;  /* an array of PRThread pointers */
    Server_Param *sp = (Server_Param *) arg;
    Serve_Client_Param *scp;
    PRFileDesc *sockfd = NULL, *newsockfd;
    PRNetAddr netaddr;
    PRInt32 i;

    t = (PRThread**)PR_MALLOC(num_transmitfile_clients * sizeof(PRThread *));
    if (t == NULL) {
        fprintf(stderr, "prsocket_test: run out of memory\n");
        failed_already=1;
        goto exit;
    }
    /*
     * Create a tcp socket
     */
    if ((sockfd = PR_OpenTCPSocket(PR_AF_INET)) == NULL) {
        fprintf(stderr,"prsocket_test: PR_OpenTCPSocket failed\n");
        failed_already=1;
        goto exit;
    }
    memset(&netaddr, 0 , sizeof(netaddr));
    netaddr.inet.family = PR_AF_INET;
    netaddr.inet.port = PR_htons(TCP_SERVER_PORT);
    netaddr.inet.ip = PR_htonl(PR_INADDR_ANY);
    /*
     * try a few times to bind server's address, if addresses are in
     * use
     */
    i = 0;
    while (PR_Bind(sockfd, &netaddr) < 0) {
        if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) {
            netaddr.inet.port += 2;
            if (i++ < SERVER_MAX_BIND_COUNT)
                continue;
        }
        fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n");
        failed_already=1;
        perror("PR_Bind");
        goto exit;
    }

    if (PR_Listen(sockfd, 32) < 0) {
        fprintf(stderr,"prsocket_test: ERROR - PR_Listen failed\n");
        failed_already=1;
        goto exit;
    }

    if (PR_GetSockName(sockfd, &netaddr) < 0) {
        fprintf(stderr,
            "prsocket_test: ERROR - PR_GetSockName failed\n");
        failed_already=1;
        goto exit;
    }

    DPRINTF(("TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",
        netaddr.inet.ip, netaddr.inet.port));
    tcp_server_addr.inet.family = netaddr.inet.family;
    tcp_server_addr.inet.port = netaddr.inet.port;
    tcp_server_addr.inet.ip = netaddr.inet.ip;

    /*
     * Wake up parent thread because server address is bound and made
     * available in the global variable 'tcp_server_addr'
     */
    PR_PostSem(sp->addr_sem);

    for (i = 0; i < num_transmitfile_clients ; i++) {
        /* test both null and non-null 'addr' argument to PR_Accept */
        PRNetAddr *addrp = (i%2 ? &netaddr: NULL);

        if ((newsockfd = PR_Accept(sockfd, addrp,
            PR_INTERVAL_NO_TIMEOUT)) == NULL) {
            fprintf(stderr,
                "prsocket_test: ERROR - PR_Accept failed\n");
            failed_already=1;
            goto exit;
        }
        /* test both regular and emulated PR_SendFile */
        if (i%2) {
            PRFileDesc *layer = PR_CreateIOLayerStub(
                emuSendFileIdentity, &emuSendFileMethods);
            if (layer == NULL) {
                fprintf(stderr,
                    "prsocket_test: ERROR - PR_CreateIOLayerStub failed\n");
                failed_already=1;
                goto exit;
            }
            if (PR_PushIOLayer(newsockfd, PR_TOP_IO_LAYER, layer)
                    == PR_FAILURE) {
                fprintf(stderr,
                    "prsocket_test: ERROR - PR_PushIOLayer failed\n");
                failed_already=1;
                goto exit;
            }
        }
        scp = PR_NEW(Serve_Client_Param);
        if (scp == NULL) {
            fprintf(stderr,"prsocket_test: PR_NEW failed\n");
            failed_already=1;
            goto exit;
        }

        /*
         * Start a Serve_Client thread for each incoming connection
         */
        scp->sockfd = newsockfd;
        scp->datalen = sp->datalen;

        t[i] = PR_CreateThread(PR_USER_THREAD,
            Serve_TransmitFile_Client, (void *)scp, 
            PR_PRIORITY_NORMAL,
            PR_LOCAL_THREAD,
            PR_JOINABLE_THREAD,
            0);
        if (t[i] == NULL) {
            fprintf(stderr,
                "prsocket_test: PR_CreateThread failed\n");
            failed_already=1;
            goto exit;
        }
        DPRINTF(("TransmitFile_Server: Created Serve_TransmitFile_Client = 0x%lx\n", t));
    }

    /*
     * Wait for all the worker threads to end, so that we know
     * they are no longer using the small and large file fd's.
     */

    for (i = 0; i < num_transmitfile_clients; i++) {
        PR_JoinThread(t[i]);
    }

exit:
    if (t) {
        PR_DELETE(t);
    }
    if (sockfd) {
        PR_Close(sockfd);
    }

    /*
     * Decrement exit_counter and notify parent thread
     */

    PR_EnterMonitor(sp->exit_mon);
    --(*sp->exit_counter);
    PR_Notify(sp->exit_mon);
    PR_ExitMonitor(sp->exit_mon);
    DPRINTF(("TransmitFile_Server [0x%lx] exiting\n", PR_GetCurrentThread()));
}

/*
 * Socket_Misc_Test    - test miscellaneous functions 
 *    
 */
static PRInt32
Socket_Misc_Test(void)
{
    PRIntn i, rv = 0, bytes, count, len;
    PRThread *t;
    PRSemaphore *server_sem;
    Server_Param *sparamp;
    Client_Param *cparamp;
    PRMonitor *mon2;
    PRInt32    datalen;

    /*
 * We deliberately pick a buffer size that is not a nice multiple
 * of 1024.
 */
#define TRANSMITFILE_BUF_SIZE    (4 * 1024 - 11)

    typedef struct {
        char    data[TRANSMITFILE_BUF_SIZE];
    } file_buf;
    file_buf *buf = NULL;

    /*
     * create file(s) to be transmitted
     */
    if ((PR_MkDir(TEST_DIR, 0777)) < 0) {
        printf("prsocket_test failed to create dir %s\n",TEST_DIR);
        failed_already=1;
        return -1;
    }

    small_file_fd = PR_Open(SMALL_FILE_NAME, PR_RDWR | PR_CREATE_FILE,0777);

    if (small_file_fd == NULL) {
        fprintf(stderr,"prsocket_test failed to create/open file %s\n",
            SMALL_FILE_NAME);
        failed_already=1;
        rv = -1;
        goto done;
    }
    buf = PR_NEW(file_buf);
    if (buf == NULL) {
        fprintf(stderr,"prsocket_test failed to allocate buffer\n");
        failed_already=1;
        rv = -1;
        goto done;
    }
    /*
     * fill in random data
     */
    for (i = 0; i < TRANSMITFILE_BUF_SIZE; i++) {
        buf->data[i] = i;
    }
    count = 0;
    do {
        len = (SMALL_FILE_SIZE - count) > TRANSMITFILE_BUF_SIZE ?
            TRANSMITFILE_BUF_SIZE : (SMALL_FILE_SIZE - count);
        bytes = PR_Write(small_file_fd, buf->data, len);
        if (bytes <= 0) {
            fprintf(stderr,
                "prsocket_test failed to write to file %s\n",
                SMALL_FILE_NAME);
            failed_already=1;
            rv = -1;
            goto done;
        }
        count += bytes;
    } while (count < SMALL_FILE_SIZE);
#ifdef XP_UNIX
    /*
     * map the small file; used in checking for data corruption
     */
    small_file_addr = mmap(0, SMALL_FILE_SIZE, PROT_READ,
        MAP_SHARED, small_file_fd->secret->md.osfd, 0);
    if (small_file_addr == (void *) -1) {
        fprintf(stderr,"prsocket_test failed to mmap file %s\n",
            SMALL_FILE_NAME);
        failed_already=1;
        rv = -1;
        goto done;
    }
#endif
    /*
     * header for small file
     */
    small_file_header = PR_MALLOC(SMALL_FILE_HEADER_SIZE);
    if (small_file_header == NULL) {
        fprintf(stderr,"prsocket_test failed to malloc header file\n");
        failed_already=1;
        rv = -1;
        goto done;
    }
    memset(small_file_header, (int) PR_IntervalNow(),
        SMALL_FILE_HEADER_SIZE);
    /*
     * trailer for small file
     */
    small_file_trailer = PR_MALLOC(SMALL_FILE_TRAILER_SIZE);
    if (small_file_trailer == NULL) {
        fprintf(stderr,"prsocket_test failed to malloc header trailer\n");
        failed_already=1;
        rv = -1;
        goto done;
    }
    memset(small_file_trailer, (int) PR_IntervalNow(),
        SMALL_FILE_TRAILER_SIZE);
    /*
     * setup large file
     */
    large_file_fd = PR_Open(LARGE_FILE_NAME, PR_RDWR | PR_CREATE_FILE,0777);

    if (large_file_fd == NULL) {
        fprintf(stderr,"prsocket_test failed to create/open file %s\n",
            LARGE_FILE_NAME);
        failed_already=1;
        rv = -1;
        goto done;
    }
    /*
     * fill in random data
     */
    for (i = 0; i < TRANSMITFILE_BUF_SIZE; i++) {
        buf->data[i] = i;
    }
    count = 0;
    do {
        len = (LARGE_FILE_SIZE - count) > TRANSMITFILE_BUF_SIZE ?
            TRANSMITFILE_BUF_SIZE : (LARGE_FILE_SIZE - count);
        bytes = PR_Write(large_file_fd, buf->data, len);
        if (bytes <= 0) {
            fprintf(stderr,
                "prsocket_test failed to write to file %s: (%ld, %ld)\n",
                LARGE_FILE_NAME,
                PR_GetError(), PR_GetOSError());
            failed_already=1;
            rv = -1;
            goto done;
        }
        count += bytes;
    } while (count < LARGE_FILE_SIZE);
#if defined(XP_UNIX) && !defined(SYMBIAN)
    /*
     * map the large file; used in checking for data corruption
     */
    large_file_addr = mmap(0, LARGE_FILE_SIZE, PROT_READ,
        MAP_SHARED, large_file_fd->secret->md.osfd, 0);
    if (large_file_addr == (void *) -1) {
        fprintf(stderr,"prsocket_test failed to mmap file %s\n",
            LARGE_FILE_NAME);
        failed_already=1;
        rv = -1;
        goto done;
    }
#endif
    /*
     * header for large file
     */
    large_file_header = PR_MALLOC(LARGE_FILE_HEADER_SIZE);
    if (large_file_header == NULL) {
        fprintf(stderr,"prsocket_test failed to malloc header file\n");
        failed_already=1;
        rv = -1;
        goto done;
    }
    memset(large_file_header, (int) PR_IntervalNow(),
        LARGE_FILE_HEADER_SIZE);
    /*
     * trailer for large file
     */
    large_file_trailer = PR_MALLOC(LARGE_FILE_TRAILER_SIZE);
    if (large_file_trailer == NULL) {
        fprintf(stderr,"prsocket_test failed to malloc header trailer\n");
        failed_already=1;
        rv = -1;
        goto done;
    }
    memset(large_file_trailer, (int) PR_IntervalNow(),
        LARGE_FILE_TRAILER_SIZE);

    datalen = tcp_mesg_size;
    thread_count = 0;
    /*
     * start the server thread
     */
    sparamp = PR_NEW(Server_Param);
    if (sparamp == NULL) {
        fprintf(stderr,"prsocket_test: PR_NEW failed\n");
        failed_already=1;
        rv = -1;
        goto done;
    }
    server_sem = PR_NewSem(0);
    if (server_sem == NULL) {
        fprintf(stderr,"prsocket_test: PR_NewSem failed\n");
        failed_already=1;
        rv = -1;
        goto done;
    }
    mon2 = PR_NewMonitor();
    if (mon2 == NULL) {
        fprintf(stderr,"prsocket_test: PR_NewMonitor failed\n");
        failed_already=1;
        rv = -1;
        goto done;
    }
    PR_EnterMonitor(mon2);

    sparamp->addr_sem = server_sem;
    sparamp->exit_mon = mon2;
    sparamp->exit_counter = &thread_count;
    sparamp->datalen = datalen;
    t = PR_CreateThread(PR_USER_THREAD,
        TransmitFile_Server, (void *)sparamp, 
        PR_PRIORITY_NORMAL,
        PR_LOCAL_THREAD,
        PR_UNJOINABLE_THREAD,
        0);
    if (t == NULL) {
        fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
        failed_already=1;
        rv = -1;
        goto done;
    }
    DPRINTF(("Created TCP server = 0x%x\n", t));
    thread_count++;

    /*
     * wait till the server address is setup
     */
    PR_WaitSem(server_sem);

    /*
     * Now start a bunch of client threads
     */

    cparamp = PR_NEW(Client_Param);
    if (cparamp == NULL) {
        fprintf(stderr,"prsocket_test: PR_NEW failed\n");
        failed_already=1;
        rv = -1;
        goto done;
    }
    cparamp->server_addr = tcp_server_addr;
    cparamp->server_addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
    cparamp->exit_mon = mon2;
    cparamp->exit_counter = &thread_count;
    cparamp->datalen = datalen;
    for (i = 0; i < num_transmitfile_clients; i++) {
        t = create_new_thread(PR_USER_THREAD,
            TransmitFile_Client, (void *) cparamp,
            PR_PRIORITY_NORMAL,
            PR_LOCAL_THREAD,
            PR_UNJOINABLE_THREAD,
            0, i);
        if (t == NULL) {
            fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
            rv = -1;
            failed_already=1;
            goto done;
        }
        DPRINTF(("Created TransmitFile client = 0x%lx\n", t));
        thread_count++;
    }
    /* Wait for server and client threads to exit */
    while (thread_count) {
        PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT);
        DPRINTF(("Socket_Misc_Test - thread_count  = %d\n", thread_count));
    }
    PR_ExitMonitor(mon2);
done:
    if (buf) {
        PR_DELETE(buf);
    }
#if defined(XP_UNIX) && !defined(SYMBIAN)
    munmap((char*)small_file_addr, SMALL_FILE_SIZE);
    munmap((char*)large_file_addr, LARGE_FILE_SIZE);
#endif
    PR_Close(small_file_fd);
    PR_Close(large_file_fd);
    if ((PR_Delete(SMALL_FILE_NAME)) == PR_FAILURE) {
        fprintf(stderr,"prsocket_test: failed to unlink file %s\n",
            SMALL_FILE_NAME);
        failed_already=1;
    }
    if ((PR_Delete(LARGE_FILE_NAME)) == PR_FAILURE) {
        fprintf(stderr,"prsocket_test: failed to unlink file %s\n",
            LARGE_FILE_NAME);
        failed_already=1;
    }
    if ((PR_RmDir(TEST_DIR)) == PR_FAILURE) {
        fprintf(stderr,"prsocket_test failed to rmdir %s: (%ld, %ld)\n",
            TEST_DIR, PR_GetError(), PR_GetOSError());
        failed_already=1;
    }

    printf("%-29s%s","Socket_Misc_Test",":");
    printf("%2d Server %2d Clients\n",1, num_transmitfile_clients);
    printf("%30s Sizes of Transmitted Files  - %4d KB, %2d MB \n",":",
        SMALL_FILE_SIZE/1024, LARGE_FILE_SIZE/(1024 * 1024));


    return rv;
}
/************************************************************************/

/*
 * Test Socket NSPR APIs
 */

int main(int argc, char **argv)
{
    /*
     * -d           debug mode
     */

    PLOptStatus os;
    PLOptState *opt = PL_CreateOptState(argc, argv, "d");
    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
    {
        if (PL_OPT_BAD == os) continue;
        switch (opt->option)
        {
        case 'd':  /* debug mode */
            _debug_on = 1;
            break;
        default:
            break;
        }
    }
    PL_DestroyOptState(opt);

    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
    PR_STDIO_INIT();

    PR_SetConcurrency(4);

    emuSendFileIdentity = PR_GetUniqueIdentity("Emulated SendFile");
    emuSendFileMethods = *PR_GetDefaultIOMethods();
    emuSendFileMethods.transmitfile = emu_TransmitFile;
    emuSendFileMethods.sendfile = emu_SendFile;

    /*
     * run client-server test with TCP, Ipv4-Ipv4
     */
	printf("TCP Client/Server Test - IPv4/Ipv4\n");
    if (TCP_Socket_Client_Server_Test() < 0) {
        printf("TCP_Socket_Client_Server_Test failed\n");
        goto done;
    } else
        printf("TCP_Socket_Client_Server_Test Passed\n");
    /*
     * client-server test, Ipv6-Ipv4
     */
	client_domain = PR_AF_INET6;
	printf("TCP Client/Server Test - IPv6/Ipv4\n");
    if (TCP_Socket_Client_Server_Test() < 0) {
        printf("TCP_Socket_Client_Server_Test failed\n");
        goto done;
    } else
        printf("TCP_Socket_Client_Server_Test Passed\n");
    /*
     * client-server test, Ipv4-Ipv6
     */
	client_domain = PR_AF_INET;
	server_domain = PR_AF_INET6;
	printf("TCP Client/Server Test - IPv4/Ipv6\n");
    if (TCP_Socket_Client_Server_Test() < 0) {
        printf("TCP_Socket_Client_Server_Test failed\n");
        goto done;
    } else
        printf("TCP_Socket_Client_Server_Test Passed\n");
    /*
     * client-server test, Ipv6-Ipv6
     */
	client_domain = PR_AF_INET6;
	server_domain = PR_AF_INET6;
	printf("TCP Client/Server Test - IPv6/Ipv6\n");
    if (TCP_Socket_Client_Server_Test() < 0) {
        printf("TCP_Socket_Client_Server_Test failed\n");
        goto done;
    } else
        printf("TCP_Socket_Client_Server_Test Passed\n");
	test_cancelio = 0;
	
#if defined(SYMBIAN) && !defined(__WINSCW__)
	/* UDP tests only run on Symbian devices but not emulator */
    /*
     * run client-server test with UDP, IPv4/IPv4
     */
	printf("UDP Client/Server Test - IPv4/Ipv4\n");
	client_domain = PR_AF_INET;
	server_domain = PR_AF_INET;
    if (UDP_Socket_Client_Server_Test() < 0) {
        printf("UDP_Socket_Client_Server_Test failed\n");
        goto done;
    } else
        printf("UDP_Socket_Client_Server_Test Passed\n");
    /*
     * run client-server test with UDP, IPv6/IPv4
     */
	printf("UDP Client/Server Test - IPv6/Ipv4\n");
	client_domain = PR_AF_INET6;
	server_domain = PR_AF_INET;
    if (UDP_Socket_Client_Server_Test() < 0) {
        printf("UDP_Socket_Client_Server_Test failed\n");
        goto done;
    } else
        printf("UDP_Socket_Client_Server_Test Passed\n");
    /*
     * run client-server test with UDP,IPv4-IPv6
     */
	printf("UDP Client/Server Test - IPv4/Ipv6\n");
	client_domain = PR_AF_INET;
	server_domain = PR_AF_INET6;
    if (UDP_Socket_Client_Server_Test() < 0) {
        printf("UDP_Socket_Client_Server_Test failed\n");
        goto done;
    } else
        printf("UDP_Socket_Client_Server_Test Passed\n");
    /*
     * run client-server test with UDP,IPv6-IPv6
     */
	printf("UDP Client/Server Test - IPv6/Ipv6\n");
	client_domain = PR_AF_INET6;
	server_domain = PR_AF_INET6;
    if (UDP_Socket_Client_Server_Test() < 0) {
        printf("UDP_Socket_Client_Server_Test failed\n");
        goto done;
    } else
        printf("UDP_Socket_Client_Server_Test Passed\n");
#endif
    
    /*
     * Misc socket tests - including transmitfile, etc.
     */

    /* File transmission test can not be done in Symbian OS because of 
     * large file's size and the incomplete mmap() implementation. */
#if !defined(WIN16) && !defined(SYMBIAN)
    /*
** The 'transmit file' test does not run because
** transmit file is not implemented in NSPR yet.
**
*/
    if (Socket_Misc_Test() < 0) {
        printf("Socket_Misc_Test failed\n");
        failed_already=1;
        goto done;
    } else
        printf("Socket_Misc_Test passed\n");

    /*
     * run client-server test with TCP again to test
     * recycling used sockets from PR_TransmitFile().
     */
    if (TCP_Socket_Client_Server_Test() < 0) {
        printf("TCP_Socket_Client_Server_Test failed\n");
        goto done;
    } else
        printf("TCP_Socket_Client_Server_Test Passed\n");
#endif

done:
    PR_Cleanup();
    if (failed_already) return 1;
    else return 0;
}
