Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Typedefs | Functions | Variables
socket.c File Reference
#include "primpl.h"
#include "plgetopt.h"
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "obsolete/prsem.h"

Go to the source code of this file.

Classes

struct  buffer
struct  Serve_Client_Param
struct  Server_Param
struct  Client_Param

Defines

#define DPRINTF(arg)   if (_debug_on) printf arg
#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
#define UDP_DGRAM_SIZE   128
#define NUM_TCP_CLIENTS   5 /* for a listen queue depth of 5 */
#define NUM_UDP_CLIENTS   10
#define NUM_TRANSMITFILE_CLIENTS   4
#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
#define TRANSMITFILE_BUF_SIZE   (4 * 1024 - 11)

Typedefs

typedef struct buffer buffer
typedef struct Serve_Client_Param Serve_Client_Param
typedef struct Server_Param Server_Param
typedef struct Client_Param Client_Param

Functions

static PRInt32 PR_CALLBACK emu_SendFile (PRFileDesc *sd, PRSendFileData *sfd, PRTransmitFileFlags flags, PRIntervalTime timeout)
static PRInt32 PR_CALLBACK emu_TransmitFile (PRFileDesc *sd, PRFileDesc *fd, const void *headers, PRInt32 hlen, PRTransmitFileFlags flags, PRIntervalTime timeout)
static PRInt32 readn (PRFileDesc *sockfd, char *buf, int len)
static PRInt32 writen (PRFileDesc *sockfd, char *buf, int len)
static void PR_CALLBACK Serve_Client (void *arg)
PRThreadcreate_new_thread (PRThreadType type, void(*start)(void *arg), void *arg, PRThreadPriority priority, PRThreadScope scope, PRThreadState state, PRUint32 stackSize, PRInt32 index)
static void PR_CALLBACK TCP_Server (void *arg)
static void PR_CALLBACK UDP_Server (void *arg)
static void PR_CALLBACK TCP_Client (void *arg)
static void PR_CALLBACK UDP_Client (void *arg)
static PRInt32 TCP_Socket_Client_Server_Test (void)
static PRInt32 UDP_Socket_Client_Server_Test (void)
static void TransmitFile_Client (void *arg)
static void Serve_TransmitFile_Client (void *arg)
static void TransmitFile_Server (void *arg)
static PRInt32 Socket_Misc_Test (void)
int main (int argc, char **argv)
 The Xalan testcases app.

Variables

static int _debug_on = 0
static int test_cancelio = 0
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"
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
PRUint16 client_domain = PR_AF_INET
static PRDescIdentity emuSendFileIdentity
static PRIOMethods emuSendFileMethods
int failed_already = 0
PRNetAddr tcp_server_addr
PRNetAddr udp_server_addr
static PRFileDescsmall_file_fd
static PRFileDesclarge_file_fd
static voidsmall_file_addr
static voidsmall_file_header
static voidlarge_file_addr
static voidsmall_file_trailer
static voidlarge_file_header
static voidlarge_file_trailer

Class Documentation

struct buffer

Definition at line 159 of file socket.c.

Class Members
char data
struct Serve_Client_Param

Definition at line 165 of file socket.c.

Collaboration diagram for Serve_Client_Param:
Class Members
PRInt32 datalen
PRMonitor * exit_mon
PRJobIoDesc iod
PRInt32 * job_counterp
PRFileDesc * sockfd
PRThreadPool * tp
struct Server_Param

Definition at line 75 of file nbconn.c.

Collaboration diagram for Server_Param:
Class Members
PRSemaphore * addr_sem
PRInt32 conn_counter
PRInt32 datalen
PRInt32 * exit_counter
PRMonitor * exit_mon
PRJobIoDesc iod
PRInt32 * job_counterp
PRNetAddr netaddr
PRFileDesc * sp_fd
PRThreadPool * tp
struct Client_Param

Definition at line 178 of file socket.c.

Collaboration diagram for Client_Param:
Class Members
PRInt32 datalen
PRInt32 * exit_counter
PRMonitor * exit_mon
PRNetAddr server_addr
PRInt32 udp_connect

Define Documentation

#define BUF_DATA_SIZE   (2 * 1024)

Definition at line 118 of file socket.c.

Definition at line 85 of file socket.c.

Definition at line 115 of file socket.c.

#define LARGE_FILE_LEN_1   (2 * 1024 * 1024) /* 2 MB */

Definition at line 108 of file socket.c.

#define LARGE_FILE_LEN_2   (1 * 1024 * 1024 + 75)

Definition at line 110 of file socket.c.

Definition at line 112 of file socket.c.

Definition at line 114 of file socket.c.

Definition at line 107 of file socket.c.

Definition at line 109 of file socket.c.

#define LARGE_FILE_OFFSET_3   (2 * 1024 * 1024 - 128)

Definition at line 111 of file socket.c.

#define LARGE_FILE_OFFSET_4   PR_GetPageSize()

Definition at line 113 of file socket.c.

#define LARGE_FILE_SIZE   (3 * 1024 * 1024) /* 3 MB */

Definition at line 106 of file socket.c.

Definition at line 116 of file socket.c.

#define NUM_TCP_CLIENTS   5 /* for a listen queue depth of 5 */

Definition at line 125 of file socket.c.

Definition at line 135 of file socket.c.

Definition at line 136 of file socket.c.

Definition at line 129 of file socket.c.

Definition at line 126 of file socket.c.

Definition at line 137 of file socket.c.

Definition at line 140 of file socket.c.

#define SMALL_FILE_HEADER_SIZE   (64) /* 64 bytes */

Definition at line 103 of file socket.c.

#define SMALL_FILE_LEN_1   (1 * 1024) /* 1 KB */

Definition at line 98 of file socket.c.

#define SMALL_FILE_LEN_2   (758)

Definition at line 100 of file socket.c.

Definition at line 102 of file socket.c.

Definition at line 97 of file socket.c.

Definition at line 99 of file socket.c.

Definition at line 101 of file socket.c.

#define SMALL_FILE_SIZE   (3 * 1024) /* 3 KB */

Definition at line 96 of file socket.c.

#define SMALL_FILE_TRAILER_SIZE   (128) /* 128 bytes */

Definition at line 104 of file socket.c.

#define TCP_MESG_SIZE   1024

Definition at line 119 of file socket.c.

#define TCP_SERVER_PORT   10000

Definition at line 138 of file socket.c.

#define TRANSMITFILE_BUF_SIZE   (4 * 1024 - 11)

Definition at line 124 of file socket.c.

Definition at line 139 of file socket.c.


Typedef Documentation

typedef struct buffer buffer
typedef struct Client_Param Client_Param
typedef struct Server_Param Server_Param

Function Documentation

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

Definition at line 339 of file socket.c.

{
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
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRInt32 PR_CALLBACK emu_SendFile ( PRFileDesc sd,
PRSendFileData sfd,
PRTransmitFileFlags  flags,
PRIntervalTime  timeout 
) [static]

Definition at line 188 of file socket.c.

{
    return PR_EmulateSendFile(sd, sfd, flags, timeout);
}

Here is the caller graph for this function:

static PRInt32 PR_CALLBACK emu_TransmitFile ( PRFileDesc sd,
PRFileDesc fd,
const void headers,
PRInt32  hlen,
PRTransmitFileFlags  flags,
PRIntervalTime  timeout 
) [static]

Definition at line 196 of file socket.c.

{
    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);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int main ( int  argc,
char **  argv 
)

The Xalan testcases app.

Definition at line 2201 of file socket.c.

{
    /*
     * -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();

#ifdef XP_MAC
    SetupMacPrintfLog("socket.log");
#endif
    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;
    /*
     * 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");
    /*
     * Misc socket tests - including transmitfile, etc.
     */

#if !defined(WIN16)
    /*
** 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;
}

Here is the call graph for this function:

static PRInt32 readn ( PRFileDesc sockfd,
char *  buf,
int  len 
) [static]

Definition at line 216 of file socket.c.

{
    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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void PR_CALLBACK Serve_Client ( void arg) [static]

Definition at line 283 of file socket.c.

{
    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 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");
            }
        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);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void Serve_TransmitFile_Client ( void arg) [static]

Definition at line 1489 of file socket.c.

{
    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);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRInt32 Socket_Misc_Test ( void  ) [static]

Definition at line 1892 of file socket.c.

{
    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);
#ifdef XP_UNIX
    /*
     * 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);
    }
#ifdef XP_UNIX
    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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void PR_CALLBACK TCP_Client ( void arg) [static]

Definition at line 660 of file socket.c.

{
    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");
            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()));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void PR_CALLBACK TCP_Server ( void arg) [static]

Definition at line 403 of file socket.c.

{
    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()));
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 898 of file socket.c.

{
    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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void TransmitFile_Client ( void arg) [static]

Definition at line 1138 of file socket.c.

{
    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;
    }
#ifdef XP_UNIX
    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;
    }
#ifdef XP_UNIX
    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;
    }
#ifdef XP_UNIX
    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;
    }
#ifdef XP_UNIX
    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;
    }
#ifdef XP_UNIX
    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;
    }
#ifdef XP_UNIX
    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;
    }
#ifdef XP_UNIX
    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;
    }
#ifdef XP_UNIX
    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;
    }
#ifdef XP_UNIX
    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;
    }
#ifdef XP_UNIX
    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()));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void TransmitFile_Server ( void arg) [static]

Definition at line 1733 of file socket.c.

{
    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()));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void PR_CALLBACK UDP_Client ( void arg) [static]

Definition at line 763 of file socket.c.

{
    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()));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void PR_CALLBACK UDP_Server ( void arg) [static]

Definition at line 533 of file socket.c.

{
    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()));
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1014 of file socket.c.

{
    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
         */
#ifndef XP_MAC
        cparamp->udp_connect = udp_connect;
#else
        /* No support for UDP connects on Mac */
        cparamp->udp_connect = 0;
#endif
        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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRInt32 writen ( PRFileDesc sockfd,
char *  buf,
int  len 
) [static]

Definition at line 257 of file socket.c.

{
    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;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

int _debug_on = 0 [static]

Definition at line 64 of file socket.c.

Definition at line 152 of file socket.c.

Definition at line 155 of file socket.c.

Definition at line 156 of file socket.c.

Definition at line 158 of file socket.c.

void * large_file_addr [static]

Definition at line 1131 of file socket.c.

Definition at line 1130 of file socket.c.

void * large_file_header [static]

Definition at line 1132 of file socket.c.

char* LARGE_FILE_NAME = "/tmp/prsocket_test_dir/large_file"

Definition at line 94 of file socket.c.

Definition at line 1132 of file socket.c.

Definition at line 142 of file socket.c.

Definition at line 145 of file socket.c.

Definition at line 147 of file socket.c.

Definition at line 144 of file socket.c.

Definition at line 143 of file socket.c.

Definition at line 148 of file socket.c.

Definition at line 152 of file socket.c.

void* small_file_addr [static]

Definition at line 1131 of file socket.c.

Definition at line 1130 of file socket.c.

void * small_file_header [static]

Definition at line 1131 of file socket.c.

char* SMALL_FILE_NAME = "/tmp/prsocket_test_dir/small_file"

Definition at line 93 of file socket.c.

Definition at line 1132 of file socket.c.

Definition at line 146 of file socket.c.

Definition at line 163 of file socket.c.

int test_cancelio = 0 [static]

Definition at line 65 of file socket.c.

char* TEST_DIR = "/tmp/prsocket_test_dir"

Definition at line 92 of file socket.c.

Definition at line 151 of file socket.c.

Definition at line 149 of file socket.c.

Definition at line 163 of file socket.c.