/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*******************************************************************
** udpsrc.c -- Test basic function of UDP server
**
** udpsrv operates on the same machine with program udpclt.
** udpsrv is the server side of a udp sockets application.
** udpclt is the client side of a udp sockets application.
**
** The test is designed to assist developers in porting/debugging
** the UDP socket functions of NSPR.
**
** This test is not a stress test.
**
** main() starts two threads: UDP_Server() and UDP_Client();
** main() uses PR_JoinThread() to wait for the threads to complete.
**
** UDP_Server() does repeated recvfrom()s from a socket.
** He detects an EOF condition set by UDP_Client(). For each
** packet received by UDP_Server(), he checks its content for
** expected content, then sends the packet back to UDP_Client().
** 
** UDP_Client() sends packets to UDP_Server() using sendto()
** he recieves packets back from the server via recvfrom().
** After he sends enough packets containing UDP_AMOUNT_TO_WRITE
** bytes of data, he sends an EOF message.
** 
** The test issues a pass/fail message at end.
** 
** Notes:
** The variable "_debug_on" can be set to 1 to cause diagnostic
** messages related to client/server synchronization. Useful when
** the test hangs.
** 
** Error messages are written to stdout.
** 
********************************************************************
*/
/* --- include files --- */
#include "nspr.h"
#include "prpriv.h"

#include "plgetopt.h"
#include "prttools.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#ifdef XP_PC
#define mode_t int
#endif

#define UDP_BUF_SIZE            4096
#define UDP_DGRAM_SIZE          128
#define UDP_AMOUNT_TO_WRITE     (PRInt32)((UDP_DGRAM_SIZE * 1000l) +1)
#define NUM_UDP_CLIENTS         1
#define NUM_UDP_DATAGRAMS_PER_CLIENT    5
#define UDP_SERVER_PORT         9050
#define UDP_CLIENT_PORT         9053
#define MY_INADDR               PR_INADDR_ANY
#define PEER_INADDR             PR_INADDR_LOOPBACK

#define UDP_TIMEOUT             400000
/* #define UDP_TIMEOUT             PR_INTERVAL_NO_TIMEOUT */

/* --- static data --- */
static PRIntn _debug_on      = 0;
static PRBool passed         = PR_TRUE;
static PRUint32 cltBytesRead = 0;
static PRUint32 srvBytesRead = 0;
static PRFileDesc *output    = NULL;

/* --- static function declarations --- */
#define DPRINTF(arg) if (_debug_on) PR_fprintf(output, arg)



/*******************************************************************
** ListNetAddr() -- Display the Net Address on stdout
**
** Description: displays the component parts of a PRNetAddr struct
**
** Arguments:   address of PRNetAddr structure to display
**
** Returns: void
**
** Notes:
**
********************************************************************
*/
void ListNetAddr( char *msg, PRNetAddr *na )
{
    char    mbuf[256];
    
    sprintf( mbuf, "ListNetAddr: %s family: %d, port: %d, ip: %8.8X\n",
            msg, na->inet.family, PR_ntohs( na->inet.port), PR_ntohl(na->inet.ip) );
#if 0            
    DPRINTF( mbuf );            
#endif
} /* --- end ListNetAddr() --- */

/********************************************************************
** UDP_Server() -- Test a UDP server application
**
** Description: The Server side of a UDP Client/Server application.
**
** Arguments: none
**
** Returns: void
**
** Notes:
**
**
********************************************************************
*/
static void PR_CALLBACK UDP_Server( void *arg )
{
    static char     svrBuf[UDP_BUF_SIZE];
    PRFileDesc      *svrSock;
    PRInt32         rv;
    PRNetAddr       netaddr;
    PRBool          bound = PR_FALSE;
    PRBool          endOfInput = PR_FALSE;
    PRInt32         numBytes = UDP_DGRAM_SIZE;
    
    DPRINTF("udpsrv: UDP_Server(): starting\n" );

    /* --- Create the socket --- */
    DPRINTF("udpsrv: UDP_Server(): Creating UDP Socket\n" );
    svrSock = PR_NewUDPSocket();
    if ( svrSock == NULL )
    {
        passed = PR_FALSE;
        if (debug_mode)
            PR_fprintf(output,
                "udpsrv: UDP_Server(): PR_NewUDPSocket() returned NULL\n" );
        return;
    }
    
    /* --- Initialize the sockaddr_in structure --- */
    memset( &netaddr, 0, sizeof( netaddr )); 
    netaddr.inet.family = PR_AF_INET;
    netaddr.inet.port   = PR_htons( UDP_SERVER_PORT );
    netaddr.inet.ip     = PR_htonl( MY_INADDR );
    
    /* --- Bind the socket --- */
    while ( !bound )
    {
        DPRINTF("udpsrv: UDP_Server(): Binding socket\n" );
        rv = PR_Bind( svrSock, &netaddr );
        if ( rv < 0 )
        {
            if ( PR_GetError() == PR_ADDRESS_IN_USE_ERROR )
            {
                if (debug_mode) PR_fprintf(output, "udpsrv: UDP_Server(): \
						PR_Bind(): reports: PR_ADDRESS_IN_USE_ERROR\n");
                PR_Sleep( PR_MillisecondsToInterval( 2000 ));
                continue;
            }
            else
            {
                passed = PR_FALSE;
                if (debug_mode) PR_fprintf(output, "udpsrv: UDP_Server(): \
						PR_Bind(): failed: %ld with error: %ld\n",
                        rv, PR_GetError() );
                PR_Close( svrSock );
                return;
            }
        }
        else
            bound = PR_TRUE;
    }
    ListNetAddr( "UDP_Server: after bind", &netaddr );
    
    /* --- Recv the socket --- */
    while( !endOfInput )
    {
        DPRINTF("udpsrv: UDP_Server(): RecvFrom() socket\n" );
        rv = PR_RecvFrom( svrSock, svrBuf, numBytes, 0, &netaddr, UDP_TIMEOUT );
        if ( rv == -1 )
        {
            passed = PR_FALSE;
            if (debug_mode)
                PR_fprintf(output,
                    "udpsrv: UDP_Server(): PR_RecvFrom(): failed with error: %ld\n",
                    PR_GetError() );
            PR_Close( svrSock );
            return;
        }
        ListNetAddr( "UDP_Server after RecvFrom", &netaddr );
        
        srvBytesRead += rv;
        
        if ( svrBuf[0] == 'E' )
        {
            DPRINTF("udpsrv: UDP_Server(): EOF on input detected\n" );
            endOfInput = PR_TRUE;
        }
            
        /* --- Send the socket --- */
        DPRINTF("udpsrv: UDP_Server(): SendTo(): socket\n" );
        rv = PR_SendTo( svrSock, svrBuf, rv, 0, &netaddr, PR_INTERVAL_NO_TIMEOUT );
        if ( rv == -1 )
        {
            passed = PR_FALSE;
            if (debug_mode)
                PR_fprintf(output,
                    "udpsrv: UDP_Server(): PR_SendTo(): failed with error: %ld\n",
                    PR_GetError() );
            PR_Close( svrSock );
            return;
        }
        ListNetAddr( "UDP_Server after SendTo", &netaddr );
    }
    
    /* --- Close the socket --- */
    DPRINTF("udpsrv: UDP_Server(): Closing socket\n" );
    rv = PR_Close( svrSock );
    if ( rv != PR_SUCCESS )
    {
        passed = PR_FALSE;
        if (debug_mode)
            PR_fprintf(output,
                "udpsrv: UDP_Server(): PR_Close(): failed to close socket\n" );
        return;
    }
    
    DPRINTF("udpsrv: UDP_Server(): Normal end\n" );
} /* --- end UDP_Server() --- */


static char         cltBuf[UDP_BUF_SIZE];
static char         cltBufin[UDP_BUF_SIZE];
/********************************************************************
** UDP_Client() -- Test a UDP client application
**
** Description:
**
** Arguments:
**
**
** Returns:
** 0 -- Successful execution
** 1 -- Test failed.
**
** Notes:
**
**
********************************************************************
*/
static void PR_CALLBACK UDP_Client( void *arg )
{
    PRFileDesc   *cltSock;
    PRInt32      rv;
    PRBool       bound = PR_FALSE;
    PRNetAddr    netaddr;
    PRNetAddr    netaddrx;
    PRBool       endOfInput = PR_FALSE;
    PRInt32      numBytes = UDP_DGRAM_SIZE;
    PRInt32      writeThisMany = UDP_AMOUNT_TO_WRITE;
    int          i;
    
    
    DPRINTF("udpsrv: UDP_Client(): starting\n" );
    
    /* --- Create the socket --- */
    cltSock = PR_NewUDPSocket();
    if ( cltSock == NULL )
    {
        passed = PR_FALSE;
        if (debug_mode)
            PR_fprintf(output,
                "udpsrv: UDP_Client(): PR_NewUDPSocket() returned NULL\n" );
        return;
    }
    
    /* --- Initialize the sockaddr_in structure --- */
    memset( &netaddr, 0, sizeof( netaddr )); 
    netaddr.inet.family = PR_AF_INET;
    netaddr.inet.ip     = PR_htonl( MY_INADDR );
    netaddr.inet.port   = PR_htons( UDP_CLIENT_PORT );
    
    /* --- Initialize the write buffer --- */    
    for ( i = 0; i < UDP_BUF_SIZE ; i++ )
        cltBuf[i] = i;
    
    /* --- Bind the socket --- */
    while ( !bound )
    {
        DPRINTF("udpsrv: UDP_Client(): Binding socket\n" );
        rv = PR_Bind( cltSock, &netaddr );
        if ( rv < 0 )
        {
            if ( PR_GetError() == PR_ADDRESS_IN_USE_ERROR )
            {
                if (debug_mode)
                    PR_fprintf(output,
                        "udpsrv: UDP_Client(): PR_Bind(): reports: PR_ADDRESS_IN_USE_ERROR\n");
                PR_Sleep( PR_MillisecondsToInterval( 2000 ));
                continue;
            }
            else
            {
                passed = PR_FALSE;
                if (debug_mode)
                    PR_fprintf(output,
                        "udpsrv: UDP_Client(): PR_Bind(): failed: %ld with error: %ld\n",
                        rv, PR_GetError() );
                PR_Close( cltSock );
                return;
            }
        }
        else
            bound = PR_TRUE;
    }
    ListNetAddr( "UDP_Client after Bind", &netaddr );
    
    /* --- Initialize the sockaddr_in structure --- */
    memset( &netaddr, 0, sizeof( netaddr )); 
    netaddr.inet.family = PR_AF_INET;
    netaddr.inet.ip     = PR_htonl( PEER_INADDR );
    netaddr.inet.port   = PR_htons( UDP_SERVER_PORT );
    
    /* --- send and receive packets until no more data left */    
    while( !endOfInput )
    {
        /*
        ** Signal EOF in the data stream on the last packet
        */        
        if ( writeThisMany <= UDP_DGRAM_SIZE )
        {
            DPRINTF("udpsrv: UDP_Client(): Send EOF packet\n" );
            cltBuf[0] = 'E';
            endOfInput = PR_TRUE;
        }
        
        /* --- SendTo the socket --- */
        if ( writeThisMany > UDP_DGRAM_SIZE )
            numBytes = UDP_DGRAM_SIZE;
        else
            numBytes = writeThisMany;
        writeThisMany -= numBytes;
        {
            char   mbuf[256];
            sprintf( mbuf, "udpsrv: UDP_Client(): write_this_many: %d, numbytes: %d\n", 
                writeThisMany, numBytes );
            DPRINTF( mbuf );
        }
        
        DPRINTF("udpsrv: UDP_Client(): SendTo(): socket\n" );
        rv = PR_SendTo( cltSock, cltBuf, numBytes, 0, &netaddr, UDP_TIMEOUT );
        if ( rv == -1 )
        {
            passed = PR_FALSE;
            if (debug_mode)
                PR_fprintf(output,
                    "udpsrv: UDP_Client(): PR_SendTo(): failed with error: %ld\n",
                        PR_GetError() );
            PR_Close( cltSock );
            return;
        }
        ListNetAddr( "UDP_Client after SendTo", &netaddr );

        /* --- RecvFrom the socket --- */
        memset( cltBufin, 0, UDP_BUF_SIZE );
        DPRINTF("udpsrv: UDP_Client(): RecvFrom(): socket\n" );
        rv = PR_RecvFrom( cltSock, cltBufin, numBytes, 0, &netaddrx, UDP_TIMEOUT );
        if ( rv == -1 )
        {
            passed = PR_FALSE;
            if (debug_mode) PR_fprintf(output,
                "udpsrv: UDP_Client(): PR_RecvFrom(): failed with error: %ld\n",
                   PR_GetError() );
            PR_Close( cltSock );
            return;
        }
        ListNetAddr( "UDP_Client after RecvFrom()", &netaddr );
        cltBytesRead += rv;
        
        /* --- verify buffer --- */
        for ( i = 0; i < rv ; i++ )
        {
            if ( cltBufin[i] != i )
            {
                /* --- special case, end of input --- */
                if ( endOfInput && i == 0 && cltBufin[0] == 'E' )
                    continue;
                passed = PR_FALSE;
                if (debug_mode) PR_fprintf(output,
                    "udpsrv: UDP_Client(): return data mismatch\n" );
                PR_Close( cltSock );
                return;
            }
        }
        if (debug_mode) PR_fprintf(output, ".");
    }
    
    /* --- Close the socket --- */
    DPRINTF("udpsrv: UDP_Server(): Closing socket\n" );
    rv = PR_Close( cltSock );
    if ( rv != PR_SUCCESS )
    {
        passed = PR_FALSE;
        if (debug_mode) PR_fprintf(output,
            "udpsrv: UDP_Client(): PR_Close(): failed to close socket\n" );
        return;
    }
    DPRINTF("udpsrv: UDP_Client(): ending\n" );
} /* --- end UDP_Client() --- */

/********************************************************************
** main() -- udpsrv
**
** arguments:
**
** Returns:
** 0 -- Successful execution
** 1 -- Test failed.
**
** Description:
**
** Standard test case setup.
**
** Calls the function UDP_Server()
**
********************************************************************
*/

int main(int argc, char **argv)
{
    PRThread    *srv, *clt;
/* The command line argument: -d is used to determine if the test is being run
	in debug mode. The regress tool requires only one line output:PASS or FAIL.
	All of the printfs associated with this test has been handled with a if (debug_mode)
	test.
	Usage: test_name -d -v
	*/
	PLOptStatus os;
	PLOptState *opt = PL_CreateOptState(argc, argv, "dv");
	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
    {
		if (PL_OPT_BAD == os) continue;
        switch (opt->option)
        {
        case 'd':  /* debug mode */
			debug_mode = 1;
            break;
        case 'v':  /* verbose mode */
			_debug_on = 1;
            break;
         default:
            break;
        }
    }
	PL_DestroyOptState(opt);
		
    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
    PR_STDIO_INIT();
    output = PR_STDERR;

    PR_SetConcurrency(4);
    
    /*
    ** Create the Server thread
    */    
    DPRINTF( "udpsrv: Creating Server Thread\n" );
    srv =  PR_CreateThread( PR_USER_THREAD,
            UDP_Server,
            (void *) 0,
            PR_PRIORITY_LOW,
            PR_LOCAL_THREAD,
            PR_JOINABLE_THREAD,
            0 );
    if ( srv == NULL )
    {
        if (debug_mode) PR_fprintf(output, "udpsrv: Cannot create server thread\n" );
        passed = PR_FALSE;
    }
    
    /*
    ** Give the Server time to Start
    */    
    DPRINTF( "udpsrv: Pausing to allow Server to start\n" );
    PR_Sleep( PR_MillisecondsToInterval(200) );
    
    /*
    ** Create the Client thread
    */    
    DPRINTF( "udpsrv: Creating Client Thread\n" );
    clt = PR_CreateThread( PR_USER_THREAD,
            UDP_Client,
            (void *) 0,
            PR_PRIORITY_LOW,
            PR_LOCAL_THREAD,
            PR_JOINABLE_THREAD,
            0 );
    if ( clt == NULL )
    {
        if (debug_mode) PR_fprintf(output, "udpsrv: Cannot create server thread\n" );
        passed = PR_FALSE;
    }
    
    /*
    **
    */
    DPRINTF("udpsrv: Waiting to join Server & Client Threads\n" );
    PR_JoinThread( srv );
    PR_JoinThread( clt );    
    
    /*
    ** Evaluate test results
    */
    if (debug_mode) PR_fprintf(output, "\n\nudpsrv: main(): cltBytesRead(%ld), \
		srvBytesRead(%ld), expected(%ld)\n",
         cltBytesRead, srvBytesRead, UDP_AMOUNT_TO_WRITE );
    if ( cltBytesRead != srvBytesRead || cltBytesRead != UDP_AMOUNT_TO_WRITE )
    {
        passed = PR_FALSE;
    }
    PR_Cleanup();
    if ( passed )
        return 0;
    else
		return 1;
} /* --- end main() --- */
