DAST library
Mark Gates
Alex Warshavsky
Ajay Tirumala
Jon Dugan
Kevin Gibbs
Introduction
In developing Iperf and other network programs, a number of C++
classes, C utilities, and autoconf macros were developed that are
generic. The C++ classes are intended to be similar in design to the
corresponding Java classes. These are packaged in the lib directory,
and may be included in other projects, subject to the UI license.
(This page is slightly out of date. Refer to the source files
for some new functions.)
Socket class
The socket class represents a socket end point of a TCP or UDP
connection. It has wrappers around the common socket functions to
create a socket connection. Typically I have Server, Listener, and
Client sub-classes of Socket.
Functions:
- Socket( short inPort,
bool inUDP = false )
- Constructor. Stores the port number and whether this will be a UDP
(true) or TCP (false) socket.
- virtual ~Socket()
- Destructor. Closes the socket if it has not been closed yet.
- void Listen(
const char *inLocalhost = NULL )
- Creates a socket, binds it to a local address and port, and starts
listening on it. If inLocalhost is null, the socket is bound to the
wildcard address, so the socket will listen for connections on any
interface. If inLocalhost is not null, that address is DNS resolved
and used to bind the socket, to specify the local interface to listen
on.
- int Accept(
void )
- Accept is a wrapper around the socket accept call. It provides
the additional facilty of restarting an accept call if it interupted.
Assumes the socket is setup with Listen() first.
- void Connect(
const char *inHostname,
const char *inLocalhost = NULL )
- Connects the socket to the server. inHostname is DNS resolved
to get the server's IP address. If inLocalhost is not null, it is
also DNS resolved and used to bind the socket to a local interface,
which specifies the outgoing interface to use.
- void Close(
void )
- Closes the socket
- virtual void SetSocketOptions(
void )
- A virtual function that subclasses may override to set socket
options at the appropriate time. Several socket options, including TCP
window sizes, must be set before calling the socket connect() or
listen() calls. SetSocketOptions is called in the Listen() and
Connect() functions. The default implementation is empty.
Queue class
The queue class stores arbitrary pointers in a queue, and provides
functions to make the queue thread-safe using pthreads.
- Queue( int inSize )
- Constructor. Creates a queue with space allocated for inSize pointers.
Note that an array of inSize+1 is allocated; one space is unusable.
- ~Queue()
- Destructor. Deletes the array of pointers. Does nothing with
the pointers themselves; the caller is responsible for removing and
deleting all pointers before deleting the queue.
- bool Enqueue(
void* inItem )
- Stores a pointer into the queue. Returns true if the operation
was successful. If the queue is full, returns false and does not
store the pointer.
- void* Dequeue(
void )
- Removes and returns the front pointer from the queue. If the
queue is empty, returns null and does not change the queue.
- void* Front(
void )
- Returns (but does not remove) the front pointer from the queue.
If the queue is empty, returns null and does not change the queue.
- int Size(
void )
- Returns the number of items in the queue.
- bool IsEmpty(
void )
- Returns true if the queue is empty.
- bool IsFull(
void )
- Returns true if the queue is full.
- void BlockUntilSignal(
time_t inAbsTimeout = 0 )
- Blocks the calling thread until a condition signal is sent.
The condition signal is sent whenever the queue is unlocked, and
usually indicates the queue has been changed.
- void Lock(
void )
- Puts a mutual exclusion lock (pthread mutex) on the queue.
- void Unlock(
void )
- Releases a mutual exclusion lock (pthread mutex) on the queue
and sends a condition signal to wake up any threads blocked in
BlockUntilSignal().
Thread class
Used to create and run a new thread. Currently this
implementation uses pthreads.
- Thread( void )
- Constructor. Initializes the thread class. Does not actually
create a new thread.
- virtual ~Thread()
- Destructor. Immediately exits the thread if it is still running.
- void Start(
void )
- Create a new thread and call its Run() function.
- void Stop(
void )
- Immediately stop the thread. The thread itself may call this to
call pthread_exit. Other threads may call this to call pthread_cancel.
- virtual void Run(
void ) = 0;
- Pure virtual function which subclasses must implement. This
is called by Start() and should be the main loop for the thread.
- void Join(
void )
- Wait for the thread to exit.
- static void Joinall(
void )
- Wait for all threads (which are created by the Thread class) to
exit.
- void DeleteSelfAfterRun(
void )
- Sets a flag so the Thread object will delete itself when it
exits. The caller no longer has responsibility for deleting the Thread
object.
- static void* Run_Wrapper(
void* objectPtr )
- Lov level function which starts the new thread. This is necesary
because pthread_create is a C library function and does not understand
C++ classes. A pointer the the Thread object is passed in as the
argument in pthread_create.
Timestamp class
The timestamp class is a wrapper around the unix gettimeofday
second/microsecond time. (TODO how to implement on Windows?) This
is intended as a platform-independant API. It offers both integer
second/microsecond access and floating point access. All functions
are inlined for optimal performance.
- Timestamp( void )
- Create a timestamp, with the current time in it.
- Timestamp( unsigned long sec,
unsigned long usec )
- Create a timestamp, with the given seconds/microseconds.
- Timestamp( double sec )
- Create a timestamp, with the given seconds.
- void setnow(
void
- Set timestamp to current time.
- void set(
unsigned long sec,
unsigned long usec )
- Set timestamp to the given seconds/microseconds.
- void set(
double sec )
- Set timestamp to the given seconds.
- unsigned long getSecs(
void )
- Return seconds portion of timestamp.
- unsigned long getUsecs(
void )
- Return microseconds portion of timestamp.
- double get(
void )
- Return timestamp as a floating point seconds.
- unsigned long subUsec(
Timestamp right )
- Subtract the right timestamp from my timestamp.
Return the difference in microseconds.
- double subSec(
Timestamp right )
- Subtract the right timestamp from my timestamp.
Return the difference in seconds as a floating point.
- void add(
Timestamp right )
- Add the right timestamp to my timestamp.
- void add(
double sec )
- Add the seconds to my timestamp.
- bool before(
Timestamp right )
- Return true if my timestamp is before the right timestamp.
- bool after(
Timestamp right )
- Return true if my timestamp is after the right timestamp.
C utilities
These are a number of utility functions of varying usefulness
for other applications. All are declared in util.h, but the
implementations are defined in a variety of C source files.
- void ntoh(
void *buffer,
int len,
int inSizeof )
- void hton(
void *buffer,
int len,
int inSizeof )
- Convert the endian-ness of an entire array of elements, each of
size inSizeof, between network byte order and the host's native byte
order. ntoh translates from network byte order, hton translates to
network byte order. (Actually, it is the same translation, the names
are merely descriptive.) On big-endian hosts, these are null
macros. On little endian hosts, each takes O(n) time.
- int setsock_tcp_windowsize(
int inSock,
int inTCPWin )
- Set the send and receive TCP window size for a socket. This
handles verifying the TCP window size was set correctly, and prints a
warning on stderr if the OS did not accept the exact specified window
size. If the window size is zero (0), nothing is done. Has special
code for UNICOS and AIX.
- int getsock_tcp_windowsize(
int inSock )
- Returns the TCP window size, as specified by the send buffer size,
for the given socket. If inSock is invalid (inSock < 0), a new TCP
socket is created and the OS's default TCP window size is returned.
- void setsock_tcp_mss(
int inSock,
int inTCPWin )
- Set the TCP maximum segment size. The MTU is the MSS + 40 bytes
for the IP header. Many OSes do not support setting this option, and
the MSS may only be lowered, not raised, since the MTU is a physical
characteristic of the network interface. This handles verifying
the TCP mss was set correctly, and prints a warning on stderr if
the OS did not accept the specified mss.
- int getsock_tcp_mss(
int inSock )
- Returns the TCP maximum segment size for the given socket.
Usually this will not be valid until after the socket has been
connected, since before that the interface is unspecified.
- ssize_t readn(
int inSock,
void *outBuf,
size_t inLen )
- Read a complete buffer, rather than returning prematurely with the
buffer only partially filled as socket read call usually does. This
code is from Stevens, 1998, section 3.9.
- ssize_t writen(
int inSock,
const void *inBuf,
size_t inLen )
- Write a complete buffer, rather than returning prematurely with
only part of the buffer written. The socket write call never returns
before writing the complete buffer, but nothing in the specification
disallows that behaviour, so this is for our safety. This code is from
Stevens, 1998, section 3.9.
- unsigned long delay_loop(
unsigned long usecs )
- An (more) accurate microsecond delay function. With very small
values, usleep often sleeps for much more time than requested, since
it gives up time to the OS. delay_loop iterates a very small loop, so it
often is much more accurate for small values. Similar to the linux
BogoMips code. For best accuracy, delay_loop_calibrate should be called first.
This is a new implementation since Iperf 1.0.
- void delay_loop_calibrate(
void )
- Calibrates the delay_loop() function for this processor. It samples
the delay_loop for various times, and corrects for the function call
and other overhead.
- typedef void Sigfunc(
int)
SigfuncPtr my_signal(
int inSigno,
SigfuncPtr inFunc )
- Exactly the same as signal(), but internally uses sigaction
which has a POSIX standard and so is more likely to be portable.
- void die(
const char *inMessage,
const char *inFile,
int inLine )
- Print the message on stderr and call exit(1). If compiled without
defining NDEBUG, also prints out the filename and line number where it
was called from.
- void die_errno(
const char *inMessage,
const char *inFile,
int inLine )
- Print the message, errno and its strerror description, and call
exit(1). If compiled without defining NDEBUG, also prints out the
filename and line number where it was called from.
- FAIL( cond, msg ) [macro]
- Calls die if the condition is true.
- FAIL_errno( cond, msg ) [macro]
- Calls die_errno if the condition is true.
- void pattern(
char *outBuf,
int inBytes )
- Fill a character buffer with some data. Currently the data
is the digits 0 through 9 repeated.
- void replace(
char *position,
int poslen,
const char *replacement )
- Starting at position, remove poslen number of characters
and insert the replacement string. Characters after poslen
are shifted to fit after the replacement string.
TODO this assumes position is allocated long enough to
fit the replacement string.
- char *concat(
char *dest,
int len,
const char *src )
- Append the src string to the dest string, without overwriting
the allocated length, len, of the dest string and ensuring a null
terminating character is always stored.
- double byte_atof(
const char *inString )
- Given a string of form #x where # is a number and x is a format
character listed below, this returns the interpreted floating point
number. Gg, Mm, Kk are giga, mega, kilo-bytes respectively. (Iperf
v1.0 had a byte_atoi function, but the atof is more general.)
- void byte_printf(
double inNum,
char inFormat )
- Given a number in bytes and a format, converts the number and
prints it out with a bits or bytes label.
B, K, M, G, A for Byte, Kbyte, Mbyte, Gbyte, adaptive byte
b, k, m, g, a for bit, Kbit, Mbit, Gbit, adaptive bit
adaptive picks the "best" one based on the number.
- DELETE( ptr ) [macro]
- If ptr is not null, delete it and set it to null. This prevents
deleting the same object twice, at least using that pointer.
autoconf macros
- DAST_CHECK_BOOL
- Checks if bool, true, and false are defined. Defines bool as int,
true as 1, false as 0 if not defined. Often it is helpful to call for
just C++ code:
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
DAST_CHECK_BOOL
AC_LANG_RESTORE
- DAST_CHECK_TYPE( type, includes )
- Does a similar check to AC_CHECK_TYPE( type, default ), but if
type isn't defined it doesn't define it. Also you may specify what
header files to include. Default includes are <sys/types>,
<stdlib.h>, or <stddef.h>. This defines
HAVE_<type>. For example, DAST_CHECK_TYPE( int32_t ) will define
HAVE_INT32_T on machines with int32_t defined. This is useful if there
is no single default value to use; in the case of int32_t it depends
on what integer type has sizeof == 4.
- DAST_ASK( message, variable, default )
- Prompts the user for input, with a default value in square
brackets, and reads the result into the given variable.
- DAST_PROG_CC
DAST_PROG_CXX
- These two prompt the user for what compiler to use. Define the
CFLAGS and CXXFLAGS to be 2nd level optimization (-O2 or similar). If
the compiler is gcc, also add -Wall. Currently recognizes HP-UX and
SunOS special cases for the optimization flags. Does not include the
-g debug flag as AC_PROG_CC and AC_PROG_CXX do.
- DAST_CHECK_PTHREAD
- Check for pthreads in either -lpthread or -lpthreads. If found,
add -lpthread(s) to LIBS and -D_REENTRANT to CFLAGS and CXXFLAGS.
- DAST_CHECK_LIB
- Similar to AC_CHECK_LIB, but try to link the code without
the library first. Some OSes include functions in a library (like
socket in -lsocket) but do not require explicitly compiling with that
library.
Bugs and Comments
While these functions have been extensively tested, there may be
bugs in this code; if any arise, or if unexpected behaviour results,
please contact us at
<dast@nlanr.net>. There are
also a number of issues this code does not yet consider. We would like
to implement these as they become important to our users, so please
send in requests for features. If these do not work on a particular
platform or host, we can probably help solve those issues.
Copyright 1999, 2000, 2001, 2002
The Board of Trustees of the University of Illinois
All rights reserved
See UI License for complete details.
dast@nlanr.net
Last modified: Jan 3, 2003
NLANR ||
applications support ||
engineering support ||
measurement and operations