/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Netscape Portable Runtime (NSPR).
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*******************************************************************
** 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 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.
**
**
** Notes:
** The variable "_debug_on" can be set to 1 to cause diagnostic
** 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_TIMEOUT PR_INTERVAL_NO_TIMEOUT */
/* --- static data --- */
/* --- static function declarations --- */
/*******************************************************************
** 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:
**
********************************************************************
*/
{
#if 0
#endif
} /* --- end ListNetAddr() --- */
/********************************************************************
** UDP_Server() -- Test a UDP server application
**
**
** Arguments: none
**
** Returns: void
**
** Notes:
**
**
********************************************************************
*/
{
DPRINTF("udpsrv: UDP_Server(): starting\n" );
/* --- Create the socket --- */
DPRINTF("udpsrv: UDP_Server(): Creating UDP Socket\n" );
svrSock = PR_NewUDPSocket();
{
if (debug_mode)
"udpsrv: UDP_Server(): PR_NewUDPSocket() returned NULL\n" );
return;
}
/* --- Initialize the sockaddr_in structure --- */
/* --- Bind the socket --- */
while ( !bound )
{
DPRINTF("udpsrv: UDP_Server(): Binding socket\n" );
if ( rv < 0 )
{
if ( PR_GetError() == PR_ADDRESS_IN_USE_ERROR )
{
PR_Bind(): reports: PR_ADDRESS_IN_USE_ERROR\n");
continue;
}
else
{
PR_Bind(): failed: %ld with error: %ld\n",
rv, PR_GetError() );
return;
}
}
else
}
/* --- Recv the socket --- */
while( !endOfInput )
{
DPRINTF("udpsrv: UDP_Server(): RecvFrom() socket\n" );
if ( rv == -1 )
{
if (debug_mode)
"udpsrv: UDP_Server(): PR_RecvFrom(): failed with error: %ld\n",
PR_GetError() );
return;
}
srvBytesRead += rv;
if ( svrBuf[0] == 'E' )
{
DPRINTF("udpsrv: UDP_Server(): EOF on input detected\n" );
}
/* --- Send the socket --- */
DPRINTF("udpsrv: UDP_Server(): SendTo(): socket\n" );
if ( rv == -1 )
{
if (debug_mode)
"udpsrv: UDP_Server(): PR_SendTo(): failed with error: %ld\n",
PR_GetError() );
return;
}
}
/* --- Close the socket --- */
DPRINTF("udpsrv: UDP_Server(): Closing socket\n" );
if ( rv != PR_SUCCESS )
{
if (debug_mode)
"udpsrv: UDP_Server(): PR_Close(): failed to close socket\n" );
return;
}
DPRINTF("udpsrv: UDP_Server(): Normal end\n" );
} /* --- end UDP_Server() --- */
/********************************************************************
** UDP_Client() -- Test a UDP client application
**
** Description:
**
** Arguments:
**
**
** Returns:
** 0 -- Successful execution
** 1 -- Test failed.
**
** Notes:
**
**
********************************************************************
*/
{
int i;
DPRINTF("udpsrv: UDP_Client(): starting\n" );
/* --- Create the socket --- */
cltSock = PR_NewUDPSocket();
{
if (debug_mode)
"udpsrv: UDP_Client(): PR_NewUDPSocket() returned NULL\n" );
return;
}
/* --- Initialize the sockaddr_in structure --- */
/* --- 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" );
if ( rv < 0 )
{
if ( PR_GetError() == PR_ADDRESS_IN_USE_ERROR )
{
if (debug_mode)
"udpsrv: UDP_Client(): PR_Bind(): reports: PR_ADDRESS_IN_USE_ERROR\n");
continue;
}
else
{
if (debug_mode)
"udpsrv: UDP_Client(): PR_Bind(): failed: %ld with error: %ld\n",
rv, PR_GetError() );
return;
}
}
else
}
/* --- Initialize the sockaddr_in structure --- */
/* --- 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';
}
/* --- SendTo the socket --- */
if ( writeThisMany > UDP_DGRAM_SIZE )
else
{
}
DPRINTF("udpsrv: UDP_Client(): SendTo(): socket\n" );
if ( rv == -1 )
{
if (debug_mode)
"udpsrv: UDP_Client(): PR_SendTo(): failed with error: %ld\n",
PR_GetError() );
return;
}
/* --- RecvFrom the socket --- */
DPRINTF("udpsrv: UDP_Client(): RecvFrom(): socket\n" );
if ( rv == -1 )
{
"udpsrv: UDP_Client(): PR_RecvFrom(): failed with error: %ld\n",
PR_GetError() );
return;
}
cltBytesRead += rv;
/* --- verify buffer --- */
for ( i = 0; i < rv ; i++ )
{
if ( cltBufin[i] != i )
{
/* --- special case, end of input --- */
continue;
"udpsrv: UDP_Client(): return data mismatch\n" );
return;
}
}
}
/* --- Close the socket --- */
DPRINTF("udpsrv: UDP_Server(): Closing socket\n" );
if ( rv != PR_SUCCESS )
{
"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()
**
********************************************************************
*/
{
/* 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
*/
{
if (PL_OPT_BAD == os) continue;
{
case 'd': /* debug mode */
debug_mode = 1;
break;
case 'v': /* verbose mode */
_debug_on = 1;
break;
default:
break;
}
}
#ifdef XP_MAC
SetupMacPrintfLog("udpsrv.log");
#endif
/*
** Create the Server thread
*/
DPRINTF( "udpsrv: Creating Server Thread\n" );
(void *) 0,
0 );
{
}
/*
** Give the Server time to Start
*/
DPRINTF( "udpsrv: Pausing to allow Server to start\n" );
/*
** Create the Client thread
*/
DPRINTF( "udpsrv: Creating Client Thread\n" );
(void *) 0,
0 );
{
}
/*
**
*/
DPRINTF("udpsrv: Waiting to join Server & Client Threads\n" );
PR_JoinThread( srv );
PR_JoinThread( clt );
/*
** Evaluate test results
*/
srvBytesRead(%ld), expected(%ld)\n",
{
}
PR_Cleanup();
if ( passed )
return 0;
else
return 1;
} /* --- end main() --- */