remove old, obsolete cruft

This commit is contained in:
Jon Dugan 2009-12-02 02:05:36 +00:00
parent 90f2aa7216
commit 536a0804dc
66 changed files with 0 additions and 14795 deletions

View File

@ -1,21 +0,0 @@
noinst_LIBRARIES = libcompat.a
AM_CPPFLAGS = @STRIP_BEGIN@ \
-I$(top_srcdir)/include \
-I$(top_builddir)/include \
@STRIP_END@
AM_CXXFLAGS = -Wall
AM_CFLAGS = -Wall
libcompat_a_SOURCES = \
Thread.c \
error.c \
delay.cpp \
gettimeofday.c \
headers_slim.h \
inet_ntop.c \
inet_pton.c \
signal.c \
snprintf.c \
string.c

View File

@ -1,451 +0,0 @@
# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = compat
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \
$(top_srcdir)/m4/ax_create_stdint_h.m4 \
$(top_srcdir)/m4/dast.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
LIBRARIES = $(noinst_LIBRARIES)
AR = ar
ARFLAGS = cru
libcompat_a_AR = $(AR) $(ARFLAGS)
libcompat_a_LIBADD =
am_libcompat_a_OBJECTS = Thread.$(OBJEXT) error.$(OBJEXT) \
delay.$(OBJEXT) gettimeofday.$(OBJEXT) inet_ntop.$(OBJEXT) \
inet_pton.$(OBJEXT) signal.$(OBJEXT) snprintf.$(OBJEXT) \
string.$(OBJEXT)
libcompat_a_OBJECTS = $(am_libcompat_a_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
-o $@
SOURCES = $(libcompat_a_SOURCES)
DIST_SOURCES = $(libcompat_a_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GREP = @GREP@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
STRIP_BEGIN = @STRIP_BEGIN@
STRIP_DUMMY = @STRIP_DUMMY@
STRIP_END = @STRIP_END@
VERSION = @VERSION@
WEB100_CFLAGS = @WEB100_CFLAGS@
WEB100_CONFIG = @WEB100_CONFIG@
WEB100_LIBS = @WEB100_LIBS@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
acx_pthread_config = @acx_pthread_config@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
noinst_LIBRARIES = libcompat.a
AM_CPPFLAGS = @STRIP_BEGIN@ \
-I$(top_srcdir)/include \
-I$(top_builddir)/include \
@STRIP_END@
AM_CXXFLAGS = -Wall
AM_CFLAGS = -Wall
libcompat_a_SOURCES = \
Thread.c \
error.c \
delay.cpp \
gettimeofday.c \
headers_slim.h \
inet_ntop.c \
inet_pton.c \
signal.c \
snprintf.c \
string.c
all: all-am
.SUFFIXES:
.SUFFIXES: .c .cpp .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign compat/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --foreign compat/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
clean-noinstLIBRARIES:
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
libcompat.a: $(libcompat_a_OBJECTS) $(libcompat_a_DEPENDENCIES)
-rm -f libcompat.a
$(libcompat_a_AR) libcompat.a $(libcompat_a_OBJECTS) $(libcompat_a_LIBADD)
$(RANLIB) libcompat.a
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Thread.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/delay.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/error.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gettimeofday.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inet_ntop.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inet_pton.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signal.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/snprintf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
.cpp.o:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
.cpp.obj:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
uninstall-info-am:
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LIBRARIES)
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am:
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-noinstLIBRARIES ctags distclean distclean-compile \
distclean-generic distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-exec install-exec-am install-info \
install-info-am install-man install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
uninstall-am uninstall-info-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -1,423 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Thread.c
* by Kevin Gibbs <kgibbs@nlanr.net>
*
* Based on:
* Thread.cpp
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* The thread subsystem is responsible for all thread functions. It
* provides a thread implementation agnostic interface to Iperf. If
* threads are not available (HAVE_THREAD is undefined), thread_start
* does not start a new thread but just launches the specified object
* in the current thread. Everything that defines a thread of
* execution in Iperf is contained in an thread_Settings structure. To
* start a thread simply pass one such structure into thread_start.
* -------------------------------------------------------------------
* headers
* uses
* <stdlib.h>
* <stdio.h>
* <assert.h>
* <errno.h>
* Thread.h may include <pthread.h>
* ------------------------------------------------------------------- */
#include "headers.h"
#include "Thread.h"
#include "Locale.h"
#include "util.h"
#ifdef __cplusplus
extern "C" {
#endif
/* -------------------------------------------------------------------
* define static variables.
* ------------------------------------------------------------------- */
// number of currently running threads
int thread_sNum = 0;
// number of non-terminating running threads (ie listener thread)
int nonterminating_num = 0;
// condition to protect updating the above and alerting on
// changes to above
Condition thread_sNum_cond;
/* -------------------------------------------------------------------
* Initialize the thread subsystems variables and set the concurrency
* level in solaris.
* ------------------------------------------------------------------- */
void thread_init( ) {
Condition_Initialize( &thread_sNum_cond );
#if defined( sun )
/* Solaris apparently doesn't default to timeslicing threads,
* as such we force it to play nice. This may not work perfectly
* when _sending_ multiple _UDP_ streams.
*/
pthread_setconcurrency (3);
#endif
}
/* -------------------------------------------------------------------
* Destroy the thread subsystems variables.
* ------------------------------------------------------------------- */
void thread_destroy( ) {
Condition_Destroy( &thread_sNum_cond );
}
/* -------------------------------------------------------------------
* Start the specified object's thread execution. Increments thread
* count, spawns new thread, and stores thread ID.
* ------------------------------------------------------------------- */
void thread_start( struct thread_Settings* thread ) {
// Make sure this object has not been started already
if ( thread_equalid( thread->mTID, thread_zeroid() ) ) {
// Check if we need to start another thread before this one
if ( thread->runNow != NULL ) {
thread_start( thread->runNow );
}
// increment thread count
Condition_Lock( thread_sNum_cond );
thread_sNum++;
Condition_Unlock( thread_sNum_cond );
#if defined( HAVE_POSIX_THREAD )
// pthreads -- spawn new thread
if ( pthread_create( &thread->mTID, NULL, thread_run_wrapper, thread ) != 0 ) {
WARN( 1, "pthread_create" );
// decrement thread count
Condition_Lock( thread_sNum_cond );
thread_sNum--;
Condition_Unlock( thread_sNum_cond );
}
#elif defined( HAVE_WIN32_THREAD )
// Win32 threads -- spawn new thread
// Win32 has a thread handle in addition to the thread ID
thread->mHandle = CreateThread( NULL, 0, thread_run_wrapper, thread, 0, &thread->mTID );
if ( thread->mHandle == NULL ) {
WARN( 1, "CreateThread" );
// decrement thread count
Condition_Lock( thread_sNum_cond );
thread_sNum--;
Condition_Unlock( thread_sNum_cond );
}
#else
// single-threaded -- call Run_Wrapper in this thread
thread_run_wrapper( thread );
#endif
}
} // end thread_start
/* -------------------------------------------------------------------
* Stop the specified object's thread execution (if any) immediately.
* Decrements thread count and resets the thread ID.
* ------------------------------------------------------------------- */
void thread_stop( struct thread_Settings* thread ) {
#ifdef HAVE_THREAD
// Make sure we have been started
if ( ! thread_equalid( thread->mTID, thread_zeroid() ) ) {
// decrement thread count
Condition_Lock( thread_sNum_cond );
thread_sNum--;
Condition_Signal( &thread_sNum_cond );
Condition_Unlock( thread_sNum_cond );
// use exit() if called from within this thread
// use cancel() if called from a different thread
if ( thread_equalid( thread_getid(), thread->mTID ) ) {
// Destroy the object
Settings_Destroy( thread );
// Exit
#if defined( HAVE_POSIX_THREAD )
pthread_exit( NULL );
#else // Win32
CloseHandle( thread->mHandle );
ExitThread( 0 );
#endif
} else {
// Cancel
#if defined( HAVE_POSIX_THREAD )
// Cray J90 doesn't have pthread_cancel; Iperf works okay without
#ifdef HAVE_PTHREAD_CANCEL
pthread_cancel( thread->mTID );
#endif
#else // Win32
// this is a somewhat dangerous function; it's not
// suggested to Stop() threads a lot.
TerminateThread( thread->mHandle, 0 );
#endif
// Destroy the object only after killing the thread
Settings_Destroy( thread );
}
}
#endif
} // end Stop
/* -------------------------------------------------------------------
* This function is the entry point for new threads created in
* thread_start.
* ------------------------------------------------------------------- */
#if defined( HAVE_WIN32_THREAD )
DWORD WINAPI
#else
void*
#endif
thread_run_wrapper( void* paramPtr ) {
struct thread_Settings* thread = (struct thread_Settings*) paramPtr;
// which type of object are we
switch ( thread->mThreadMode ) {
case kMode_Server:
{
/* Spawn a Server thread with these settings */
server_spawn( thread );
} break;
case kMode_Client:
{
/* Spawn a Client thread with these settings */
client_spawn( thread );
} break;
case kMode_Reporter:
{
/* Spawn a Reporter thread with these settings */
reporter_spawn( thread );
} break;
case kMode_Listener:
{
// Increment the non-terminating thread count
thread_register_nonterm();
/* Spawn a Listener thread with these settings */
listener_spawn( thread );
// Decrement the non-terminating thread count
thread_unregister_nonterm();
} break;
default:
{
FAIL(1, "Unknown Thread Type!\n", thread);
} break;
}
#ifdef HAVE_POSIX_THREAD
// detach Thread. If someone already joined it will not do anything
// If noone has then it will free resources upon return from this
// function (Run_Wrapper)
pthread_detach(thread->mTID);
#endif
// decrement thread count and send condition signal
Condition_Lock( thread_sNum_cond );
thread_sNum--;
Condition_Signal( &thread_sNum_cond );
Condition_Unlock( thread_sNum_cond );
// Check if we need to start up a thread after executing this one
if ( thread->runNext != NULL ) {
thread_start( thread->runNext );
}
// Destroy this thread object
Settings_Destroy( thread );
return 0;
} // end run_wrapper
/* -------------------------------------------------------------------
* Wait for all thread object's execution to complete. Depends on the
* thread count being accurate and the threads sending a condition
* signal when they terminate.
* ------------------------------------------------------------------- */
void thread_joinall( void ) {
Condition_Lock( thread_sNum_cond );
while ( thread_sNum > 0 ) {
Condition_Wait( &thread_sNum_cond );
}
Condition_Unlock( thread_sNum_cond );
} // end Joinall
/* -------------------------------------------------------------------
* Compare the thread ID's (inLeft == inRight); return true if they
* are equal. On some OS's nthread_t is a struct so == will not work.
* TODO use pthread_equal. Any Win32 equivalent??
* ------------------------------------------------------------------- */
int thread_equalid( nthread_t inLeft, nthread_t inRight ) {
return(memcmp( &inLeft, &inRight, sizeof(inLeft)) == 0);
}
/* -------------------------------------------------------------------
* Return a zero'd out thread ID. On some OS's nthread_t is a struct
* so == 0 will not work.
* [static]
* ------------------------------------------------------------------- */
nthread_t thread_zeroid( void ) {
nthread_t a;
memset( &a, 0, sizeof(a));
return a;
}
/* -------------------------------------------------------------------
* set a thread to be ignorable, so joinall won't wait on it
* this simply decrements the thread count that joinall uses.
* This is utilized by the reporter thread which knows when it
* is ok to quit (aka no pending reports).
* ------------------------------------------------------------------- */
void thread_setignore( ) {
Condition_Lock( thread_sNum_cond );
thread_sNum--;
Condition_Signal( &thread_sNum_cond );
Condition_Unlock( thread_sNum_cond );
}
/* -------------------------------------------------------------------
* unset a thread from being ignorable, so joinall will wait on it
* this simply increments the thread count that joinall uses.
* This is utilized by the reporter thread which knows when it
* is ok to quit (aka no pending reports).
* ------------------------------------------------------------------- */
void thread_unsetignore( void ) {
Condition_Lock( thread_sNum_cond );
thread_sNum++;
Condition_Signal( &thread_sNum_cond );
Condition_Unlock( thread_sNum_cond );
}
/* -------------------------------------------------------------------
* set a thread to be non-terminating, so if you cancel through
* Ctrl-C they can be ignored by the joinall.
* ------------------------------------------------------------------- */
void thread_register_nonterm( void ) {
Condition_Lock( thread_sNum_cond );
nonterminating_num++;
Condition_Unlock( thread_sNum_cond );
}
/* -------------------------------------------------------------------
* unset a thread from being non-terminating, so if you cancel through
* Ctrl-C they can be ignored by the joinall.
* ------------------------------------------------------------------- */
void thread_unregister_nonterm( void ) {
Condition_Lock( thread_sNum_cond );
if ( nonterminating_num == 0 ) {
// nonterminating has been released with release_nonterm
// Add back to the threads to wait on
thread_sNum++;
} else {
nonterminating_num--;
}
Condition_Unlock( thread_sNum_cond );
}
/* -------------------------------------------------------------------
* this function releases all non-terminating threads from the list
* of active threads, so that when all terminating threads quit
* the joinall will complete. This is called on a Ctrl-C input. It is
* also used by the -P usage on the server side
* ------------------------------------------------------------------- */
int thread_release_nonterm( int interrupt ) {
Condition_Lock( thread_sNum_cond );
thread_sNum -= nonterminating_num;
if ( thread_sNum > 1 && nonterminating_num > 0 && interrupt != 0 ) {
fprintf( stderr, wait_server_threads );
}
nonterminating_num = 0;
Condition_Signal( &thread_sNum_cond );
Condition_Unlock( thread_sNum_cond );
return thread_sNum;
}
/* -------------------------------------------------------------------
* Return the number of threads currently running (doesn't include
* active threads that have called setdaemon (aka reporter thread))
* ------------------------------------------------------------------- */
int thread_numuserthreads( void ) {
return thread_sNum;
}
/*
* -------------------------------------------------------------------
* Allow another thread to execute. If no other threads are runable this
* is not guarenteed to actually rest.
* ------------------------------------------------------------------- */
void thread_rest ( void ) {
#if defined( HAVE_THREAD )
#if defined( HAVE_POSIX_THREAD )
#if defined( _POSIX_PRIORITY_SCHEDULING )
sched_yield();
#else
usleep( 0 );
#endif
#else // Win32
SwitchToThread( );
#endif
#endif
}
#ifdef __cplusplus
} /* end extern "C" */
#endif

View File

@ -1,76 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* delay.c
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* accurate microsecond delay
* ------------------------------------------------------------------- */
#include "Timestamp.hpp"
#include "util.h"
#include "delay.hpp"
/* -------------------------------------------------------------------
* A micro-second delay function using POSIX nanosleep(). This allows a
* higher timing resolution (under Linux e.g. it uses hrtimers), does not
* affect any signals, and will use up remaining time when interrupted.
* ------------------------------------------------------------------- */
void delay_loop(unsigned long usec)
{
struct timespec requested, remaining;
requested.tv_sec = 0;
requested.tv_nsec = usec * 1000L;
while (nanosleep(&requested, &remaining) == -1)
if (errno == EINTR)
requested = remaining;
else {
WARN_errno(1, "nanosleep");
break;
}
}

View File

@ -1,210 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* error.c
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* error handlers
* ------------------------------------------------------------------- */
#include "headers.h"
#include "util.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef WIN32
/* -------------------------------------------------------------------
* Implement a simple Win32 strerror function for our purposes.
* These error values weren't handled by FormatMessage;
* any particular reason why not??
* ------------------------------------------------------------------- */
struct mesg {
DWORD err;
const char* str;
};
const struct mesg error_mesgs[] =
{
{ WSAEACCES, "Permission denied"},
{ WSAEADDRINUSE, "Address already in use"},
{ WSAEADDRNOTAVAIL, "Cannot assign requested address"},
{ WSAEAFNOSUPPORT, "Address family not supported by protocol family"},
{ WSAEALREADY, "Operation already in progress"},
{ WSAECONNABORTED, "Software caused connection abort"},
{ WSAECONNREFUSED, "Connection refused"},
{ WSAECONNRESET, "Connection reset by peer"},
{ WSAEDESTADDRREQ, "Destination address required"},
{ WSAEFAULT, "Bad address"},
{ WSAEHOSTDOWN, "Host is down"},
{ WSAEHOSTUNREACH, "No route to host"},
{ WSAEINPROGRESS, "Operation now in progress"},
{ WSAEINTR, "Interrupted function call."},
{ WSAEINVAL, "Invalid argument."},
{ WSAEISCONN, "Socket is already connected."},
{ WSAEMFILE, "Too many open files."},
{ WSAEMSGSIZE, "Message too long"},
{ WSAENETDOWN, "Network is down"},
{ WSAENETRESET, "Network dropped connection on reset"},
{ WSAENETUNREACH, "Network is unreachable"},
{ WSAENOBUFS, "No buffer space available."},
{ WSAENOPROTOOPT, "Bad protocol option."},
{ WSAENOTCONN, "Socket is not connected"},
{ WSAENOTSOCK, "Socket operation on non-socket."},
{ WSAEOPNOTSUPP, "Operation not supported"},
{ WSAEPFNOSUPPORT, "Protocol family not supported"},
{ WSAEPROCLIM, "Too many processes."},
{ WSAEPROTONOSUPPORT, "Protocol not supported"},
{ WSAEPROTOTYPE, "Protocol wrong type for socket"},
{ WSAESHUTDOWN, "Cannot send after socket shutdown"},
{ WSAESOCKTNOSUPPORT, "Socket type not supported."},
{ WSAETIMEDOUT, "Connection timed out."},
{ WSATYPE_NOT_FOUND, "Class type not found."},
{ WSAEWOULDBLOCK, "Resource temporarily unavailable"},
{ WSAHOST_NOT_FOUND, "Host not found."},
{ WSA_INVALID_HANDLE, "Specified event object handle is invalid."},
{ WSA_INVALID_PARAMETER, "One or more parameters are invalid."},
{ WSA_IO_INCOMPLETE, "Overlapped I/O event object not in signaled state."},
{ WSA_IO_PENDING, "Overlapped operations will complete later."},
{ WSA_NOT_ENOUGH_MEMORY, "Insufficient memory available."},
{ WSANOTINITIALISED, "Successful WSAStartup not yet performed."},
{ WSANO_DATA, "Valid name, no data record of requested type."},
{ WSANO_RECOVERY, "This is a non-recoverable error."},
{ WSASYSCALLFAILURE, "System call failure."},
{ WSASYSNOTREADY, "Network subsystem is unavailable."},
{ WSATRY_AGAIN, "Non-authoritative host not found."},
{ WSAVERNOTSUPPORTED, "WINSOCK.DLL version out of range."},
{ WSAEDISCON, "Graceful shutdown in progress."},
{ WSA_OPERATION_ABORTED, "Overlapped operation aborted."},
{ 0, "No error."}
/* These appeared in the documentation, but didn't compile.
* { WSAINVALIDPROCTABLE, "Invalid procedure table from service provider." },
* { WSAINVALIDPROVIDER, "Invalid service provider version number." },
* { WSAPROVIDERFAILEDINIT, "Unable to initialize a service provider." },
*/
}; /* end error_mesgs[] */
const char* winsock_strerror( DWORD inErrno );
/* -------------------------------------------------------------------
* winsock_strerror
*
* returns a string representing the error code. The error messages
* were taken from Microsoft's online developer library.
* ------------------------------------------------------------------- */
const char* winsock_strerror( DWORD inErrno ) {
const char* str = "Unknown error";
int i;
for ( i = 0; i < sizeof(error_mesgs); i++ ) {
if ( error_mesgs[i].err == inErrno ) {
str = error_mesgs[i].str;
break;
}
}
return str;
} /* end winsock_strerror */
#endif /* WIN32 */
/* -------------------------------------------------------------------
* warn
*
* Prints message and return
* ------------------------------------------------------------------- */
void warn( const char *inMessage, const char *inFile, int inLine ) {
fflush( 0 );
#ifdef NDEBUG
fprintf( stderr, "%s failed\n", inMessage );
#else
/* while debugging output file/line number also */
fprintf( stderr, "%s failed (%s:%d)\n", inMessage, inFile, inLine );
#endif
} /* end warn */
/* -------------------------------------------------------------------
* warn_errno
*
* Prints message and errno message, and return.
* ------------------------------------------------------------------- */
void warn_errno( const char *inMessage, const char *inFile, int inLine ) {
int my_err;
const char* my_str;
/* get platform's errno and error message */
#ifdef WIN32
my_err = WSAGetLastError();
my_str = winsock_strerror( my_err );
#else
my_err = errno;
my_str = strerror( my_err );
#endif
fflush( 0 );
#ifdef NDEBUG
fprintf( stderr, "%s failed: %s\n", inMessage, my_str );
#else
/* while debugging output file/line number and errno value also */
fprintf( stderr, "%s failed (%s:%d): %s (%d)\n",
inMessage, inFile, inLine, my_str, my_err );
#endif
} /* end warn_errno */
#ifdef __cplusplus
} /* end extern "C" */
#endif

View File

@ -1,92 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* gettimeofday.c
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* A (hack) implementation of gettimeofday for Windows.
* Since I send sec/usec in UDP packets, this made the most sense.
* ------------------------------------------------------------------- */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifndef HAVE_GETTIMEOFDAY
#include "headers.h"
#include "gettimeofday.h"
#ifdef __cplusplus
extern "C" {
#endif
int gettimeofday( struct timeval* tv, void* timezone ) {
FILETIME time;
double timed;
GetSystemTimeAsFileTime( &time );
// Apparently Win32 has units of 1e-7 sec (tenths of microsecs)
// 4294967296 is 2^32, to shift high word over
// 11644473600 is the number of seconds between
// the Win32 epoch 1601-Jan-01 and the Unix epoch 1970-Jan-01
// Tests found floating point to be 10x faster than 64bit int math.
timed = ((time.dwHighDateTime * 4294967296e-7) - 11644473600.0) +
(time.dwLowDateTime * 1e-7);
tv->tv_sec = (long) timed;
tv->tv_usec = (long) ((timed - tv->tv_sec) * 1e6);
return 0;
}
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif /* HAVE_GETTIMEOFDAY */

View File

@ -1,39 +0,0 @@
#ifndef HEADERS_SLIM_H
#define HEADERS_SLIM_H
/* -------------------------------------------------------------------
* headers_slim.h
* by Mark Gates <mgates@nlanr.net>
* Copyright 1999, Board of Trustees of the University of Illinois.
* $Id: headers_slim.h,v 1.1.1.1 2001/12/12 23:37:48 jdugan Exp $
* -------------------------------------------------------------------
* headers
*
* Most system headers required by iperf.
* This is a subset of lib/headers.h, to be used only while running
* configure. It excludes things conditional on having _already_
* run configure, and Win32 stuff.
* ------------------------------------------------------------------- */
/* standard C headers */
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <math.h>
/* unix headers */
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <signal.h>
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h> /* netinet/in.h must be before this on SunOS */
#endif /* HEADERS_SLIM_H */

View File

@ -1,183 +0,0 @@
#include "inet_aton.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Copyright (C) 1996-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
* INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef HAVE_INET_NTOP
#define NS_INT16SZ 2
#define NS_INADDRSZ 4
#define NS_IN6ADDRSZ 16
/*
* WARNING: Don't even consider trying to compile this on a system where
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
*/
/* char *
* isc_net_ntop(af, src, dst, size)
* convert a network format address to presentation format.
* return:
* pointer to presentation format address (`dst'), or NULL (see errno).
* author:
* Paul Vixie, 1996.
*/
int
inet_ntop(int af, const void *src, char *dst, size_t size) {
switch ( af ) {
case AF_INET:
return(inet_ntop4(src, dst, size));
#ifdef HAVE_IPV6
case AF_INET6:
return(inet_ntop6(src, dst, size));
#endif
default:
return 0;
}
/* NOTREACHED */
}
/* const char *
* inet_ntop4(src, dst, size)
* format an IPv4 address
* return:
* `dst' (as a const)
* notes:
* (1) uses no statics
* (2) takes a unsigned char* not an in_addr as input
* author:
* Paul Vixie, 1996.
*/
int
inet_ntop4(const unsigned char *src, char *dst, size_t size) {
static const char *fmt = "%u.%u.%u.%u";
char tmp[sizeof "255.255.255.255"];
if ( (size_t)sprintf(tmp, fmt, src[0], src[1], src[2], src[3]) >= size ) {
return 0;
}
strcpy(dst, tmp);
return 1;
}
/* const char *
* isc_inet_ntop6(src, dst, size)
* convert IPv6 binary address into presentation (printable) format
* author:
* Paul Vixie, 1996.
*/
#ifdef HAVE_IPV6
int
inet_ntop6(const unsigned char *src, char *dst, size_t size) {
/*
* Note that int32_t and int16_t need only be "at least" large enough
* to contain a value of the specified size. On some systems, like
* Crays, there is no such thing as an integer variable with 16 bits.
* Keep this in mind if you think this function should have been coded
* to use pointer overlays. All the world's not a VAX.
*/
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
struct {
int base, len;
} best, cur;
unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ];
int i;
/*
* Preprocess:
* Copy the input (bytewise) array into a wordwise array.
* Find the longest run of 0x00's in src[] for :: shorthanding.
*/
memset(words, '\0', sizeof words);
for ( i = 0; i < NS_IN6ADDRSZ; i++ )
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
best.base = -1;
cur.base = -1;
for ( i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++ ) {
if ( words[i] == 0 ) {
if ( cur.base == -1 )
cur.base = i, cur.len = 1;
else
cur.len++;
} else {
if ( cur.base != -1 ) {
if ( best.base == -1 || cur.len > best.len )
best = cur;
cur.base = -1;
}
}
}
if ( cur.base != -1 ) {
if ( best.base == -1 || cur.len > best.len )
best = cur;
}
if ( best.base != -1 && best.len < 2 )
best.base = -1;
/*
* Format the result.
*/
tp = tmp;
for ( i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++ ) {
/* Are we inside the best run of 0x00's? */
if ( best.base != -1 && i >= best.base &&
i < (best.base + best.len) ) {
if ( i == best.base )
*tp++ = ':';
continue;
}
/* Are we following an initial run of 0x00s or any real hex? */
if ( i != 0 )
*tp++ = ':';
/* Is this address an encapsulated IPv4? */
if ( i == 6 && best.base == 0 &&
(best.len == 6 || (best.len == 5 && words[5] == 0xffff)) ) {
if ( !inet_ntop4(src+12, tp,
sizeof tmp - (tp - tmp)) )
return 0;
tp += strlen(tp);
break;
}
tp += sprintf(tp, "%x", words[i]);
}
/* Was it a trailing run of 0x00's? */
if ( best.base != -1 && (best.base + best.len) ==
(NS_IN6ADDRSZ / NS_INT16SZ) )
*tp++ = ':';
*tp++ = '\0';
/*
* Check for overflow, copy, and we're done.
*/
if ( (size_t)(tp - tmp) > size ) {
errno = ENOSPC;
return 0;
}
strcpy(dst, tmp);
return 1;
}
#endif /* HAVE_IPV6 */
#endif /* HAVE_INET_NTOP */
#ifdef __cplusplus
} /* end extern "C" */
#endif

View File

@ -1,209 +0,0 @@
#include "inet_aton.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Copyright (C) 1996-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
* INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef HAVE_INET_PTON
#define NS_INT16SZ 2
#define NS_INADDRSZ 4
#define NS_IN6ADDRSZ 16
/* int
* isc_net_pton(af, src, dst)
* convert from presentation format (which usually means ASCII printable)
* to network format (which is usually some kind of binary format).
* return:
* 1 if the address was valid for the specified address family
* 0 if the address wasn't valid (`dst' is untouched in this case)
* author:
* Paul Vixie, 1996.
*/
int
inet_pton(int af,
const char *src,
void *dst) {
switch ( af ) {
case AF_INET:
return(inet_pton4(src, dst));
#ifdef HAVE_IPV6
case AF_INET6:
return(inet_pton6(src, dst));
#endif
default:
return 0;
}
/* NOTREACHED */
}
/* int
* inet_pton4(src, dst)
* like inet_aton() but without all the hexadecimal and shorthand.
* return:
* 1 if `src' is a valid dotted quad, else 0.
* notice:
* does not touch `dst' unless it's returning 1.
* author:
* Paul Vixie, 1996.
*/
int
inet_pton4(src, dst)
const char *src;
unsigned char *dst;
{
static const char digits[] = "0123456789";
int saw_digit, octets, ch;
unsigned char tmp[NS_INADDRSZ], *tp;
saw_digit = 0;
octets = 0;
*(tp = tmp) = 0;
while ( (ch = *src++) != '\0' ) {
const char *pch;
if ( (pch = strchr(digits, ch)) != NULL ) {
unsigned int new = *tp * 10 + (pch - digits);
if ( new > 255 )
return(0);
*tp = new;
if ( ! saw_digit ) {
if ( ++octets > 4 )
return(0);
saw_digit = 1;
}
} else if ( ch == '.' && saw_digit ) {
if ( octets == 4 )
return(0);
*++tp = 0;
saw_digit = 0;
} else
return(0);
}
if ( octets < 4 )
return(0);
memcpy(dst, tmp, NS_INADDRSZ);
return(1);
}
/* int
* inet_pton6(src, dst)
* convert presentation level address to network order binary form.
* return:
* 1 if `src' is a valid [RFC1884 2.2] address, else 0.
* notice:
* (1) does not touch `dst' unless it's returning 1.
* (2) :: in a full address is silently ignored.
* credit:
* inspired by Mark Andrews.
* author:
* Paul Vixie, 1996.
*/
#ifdef HAVE_IPV6
int
inet_pton6(src, dst)
const char *src;
unsigned char *dst;
{
static const char xdigits_l[] = "0123456789abcdef",
xdigits_u[] = "0123456789ABCDEF";
unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
const char *xdigits, *curtok;
int ch, saw_xdigit;
unsigned int val;
memset((tp = tmp), '\0', NS_IN6ADDRSZ);
endp = tp + NS_IN6ADDRSZ;
colonp = NULL;
/* Leading :: requires some special handling. */
if ( *src == ':' )
if ( *++src != ':' )
return(0);
curtok = src;
saw_xdigit = 0;
val = 0;
while ( (ch = *src++) != '\0' ) {
const char *pch;
if ( (pch = strchr((xdigits = xdigits_l), ch)) == NULL )
pch = strchr((xdigits = xdigits_u), ch);
if ( pch != NULL ) {
val <<= 4;
val |= (pch - xdigits);
if ( val > 0xffff )
return(0);
saw_xdigit = 1;
continue;
}
if ( ch == ':' ) {
curtok = src;
if ( !saw_xdigit ) {
if ( colonp )
return(0);
colonp = tp;
continue;
}
if ( tp + NS_INT16SZ > endp )
return(0);
*tp++ = (unsigned char) (val >> 8) & 0xff;
*tp++ = (unsigned char) val & 0xff;
saw_xdigit = 0;
val = 0;
continue;
}
if ( ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
inet_pton4(curtok, tp) > 0 ) {
tp += NS_INADDRSZ;
saw_xdigit = 0;
break; /* '\0' was seen by inet_pton4(). */
}
return(0);
}
if ( saw_xdigit ) {
if ( tp + NS_INT16SZ > endp )
return(0);
*tp++ = (unsigned char) (val >> 8) & 0xff;
*tp++ = (unsigned char) val & 0xff;
}
if ( colonp != NULL ) {
/*
* Since some memmove()'s erroneously fail to handle
* overlapping regions, we'll do the shift by hand.
*/
const int n = tp - colonp;
int i;
for ( i = 1; i <= n; i++ ) {
endp[- i] = colonp[n - i];
colonp[n - i] = 0;
}
tp = endp;
}
if ( tp != endp )
return(0);
memcpy(dst, tmp, NS_IN6ADDRSZ);
return(1);
}
#endif
#endif /* HAVE_INET_PTON */
#ifdef __cplusplus
} /* end extern "C" */
#endif

View File

@ -1,180 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* signal.c
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* standard signal installer
* ------------------------------------------------------------------- */
#include "headers.h"
#include "util.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef WIN32
/* list of signal handlers. _NSIG is number of signals defined. */
static SigfuncPtr handlers[ _NSIG ] = { 0};
/* -------------------------------------------------------------------
* sig_dispatcher
*
* dispatches the signal to appropriate signal handler. This emulates
* the signal handling of Unix.
*
* ------------------------------------------------------------------- */
BOOL WINAPI sig_dispatcher( DWORD type ) {
SigfuncPtr h = NULL;
int signo;
switch ( type ) {
case CTRL_C_EVENT:
signo = SIGINT;
h = handlers[ SIGINT ];
break;
case CTRL_CLOSE_EVENT:
case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT:
signo = SIGTERM;
h = handlers[ SIGTERM ];
break;
default:
break;
}
if ( h != NULL ) {
// call the signal handler
h( signo );
return true;
} else {
return false;
}
}
/* -------------------------------------------------------------------
* my_signal
*
* installs a signal handler. I emulate Unix signals by storing the
* function pointers and dispatching events myself, using the
* sig_dispatcher above.
* ------------------------------------------------------------------- */
SigfuncPtr my_signal( int inSigno, SigfuncPtr inFunc ) {
SigfuncPtr old = NULL;
if ( inSigno >= 0 && inSigno < _NSIG ) {
old = handlers[ inSigno ];
handlers[ inSigno ] = inFunc;
}
return old;
} /* end my_signal */
#else /* not WIN32 */
/* -------------------------------------------------------------------
* my_signal
*
* installs a signal handler, and returns the old handler.
* This emulates the semi-standard signal() function in a
* standard way using the Posix sigaction function.
*
* from Stevens, 1998, section 5.8
* ------------------------------------------------------------------- */
SigfuncPtr my_signal( int inSigno, SigfuncPtr inFunc ) {
struct sigaction theNewAction, theOldAction;
assert( inFunc != NULL );
theNewAction.sa_handler = inFunc;
sigemptyset( &theNewAction.sa_mask );
theNewAction.sa_flags = 0;
if ( inSigno == SIGALRM ) {
#ifdef SA_INTERRUPT
theNewAction.sa_flags |= SA_INTERRUPT; /* SunOS 4.x */
#endif
} else {
#ifdef SA_RESTART
theNewAction.sa_flags |= SA_RESTART; /* SVR4, 4.4BSD */
#endif
}
if ( sigaction( inSigno, &theNewAction, &theOldAction ) < 0 ) {
return SIG_ERR;
} else {
return theOldAction.sa_handler;
}
} /* end my_signal */
#endif /* not WIN32 */
/* -------------------------------------------------------------------
* sig_exit
*
* Quietly exits. This protects some against being called multiple
* times. (TODO: should use a mutex to ensure (num++ == 0) is atomic.)
* ------------------------------------------------------------------- */
void sig_exit( int inSigno ) {
static int num = 0;
if ( num++ == 0 ) {
fflush( 0 );
exit( 0 );
}
} /* end sig_exit */
#ifdef __cplusplus
} /* end extern "C" */
#endif

View File

@ -1,101 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
* Author: Mark Gates
*
* snprintf.c
*
* This is from
* W. Richard Stevens, 'UNIX Network Programming', Vol 1, 2nd Edition,
* Prentice Hall, 1998.
*
*
* Throughout the book I use snprintf() because it's safer than sprintf().
* But as of the time of this writing, not all systems provide this
* function. The function below should only be built on those systems
* that do not provide a real snprintf().
* The function below just acts like sprintf(); it is not safe, but it
* tries to detect overflow.
* ________________________________________________________________ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifndef HAVE_SNPRINTF
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include "snprintf.h"
#ifdef __cplusplus
extern "C" {
#endif
int snprintf(char *buf, size_t size, const char *fmt, ...) {
int n;
va_list ap;
va_start(ap, fmt);
vsprintf(buf, fmt, ap); /* Sigh, some vsprintf's return ptr, not length */
n = strlen(buf);
va_end(ap);
if ( n >= size ) {
fprintf( stderr, "snprintf: overflowed array\n" );
exit(1);
}
return(n);
}
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif /* HAVE_SNPRINTF */

View File

@ -1,76 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* string.c
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* various string utilities
* ------------------------------------------------------------------- */
#include "headers.h"
#include "util.h"
#ifdef __cplusplus
extern "C" {
#endif
/* -------------------------------------------------------------------
* pattern
*
* Initialize the buffer with a pattern of (index mod 10).
* ------------------------------------------------------------------- */
void pattern( char *outBuf, int inBytes ) {
assert( outBuf != NULL );
while ( inBytes-- > 0 ) {
outBuf[ inBytes ] = (inBytes % 10) + '0';
}
} /* end pattern */
#ifdef __cplusplus
} /* end extern "C" */
#endif

View File

@ -1 +0,0 @@
EXTRA_DIST = index.html ui_license.html dast.gif

View File

@ -1,308 +0,0 @@
# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = doc
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \
$(top_srcdir)/m4/ax_create_stdint_h.m4 \
$(top_srcdir)/m4/dast.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
SOURCES =
DIST_SOURCES =
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GREP = @GREP@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
STRIP_BEGIN = @STRIP_BEGIN@
STRIP_DUMMY = @STRIP_DUMMY@
STRIP_END = @STRIP_END@
VERSION = @VERSION@
WEB100_CFLAGS = @WEB100_CFLAGS@
WEB100_CONFIG = @WEB100_CONFIG@
WEB100_LIBS = @WEB100_LIBS@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
acx_pthread_config = @acx_pthread_config@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
EXTRA_DIST = index.html ui_license.html dast.gif
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --foreign doc/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
uninstall-info-am:
tags: TAGS
TAGS:
ctags: CTAGS
CTAGS:
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am:
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am
.PHONY: all all-am check check-am clean clean-generic distclean \
distclean-generic distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-exec \
install-exec-am install-info install-info-am install-man \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \
uninstall-info-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

View File

@ -1,758 +0,0 @@
<HTML>
<HEAD>
<TITLE>Iperf version 2.0.0</TITLE>
<!-- $Id: index.html,v 1.1.1.1 2004/05/18 01:50:44 kgibbs Exp $ -->
</HEAD>
<BODY BGCOLOR="#FFFFFF" LINK="#006633" VLINK="#669900" ALINK="#669966">
<CENTER>
<P><IMG SRC="dast.gif"
ALT="Distributed Applications Support Team"></P>
</CENTER>
<H1>Iperf version 2.0.0</H1>
<H3>May 2004</H3>
<HR><!-- ----- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- -->
<H3>NLANR applications support
<BR><A HREF="http://dast.nlanr.net/">http://dast.nlanr.net/</A>
<BR><A HREF="mailto:dast@nlanr.net">&lt;dast@nlanr.net&gt;</A>
</H3>
<P><FONT face="arial,helvetica">
<H1>Iperf User Docs</H1>
<H4>Mark Gates<br>
Ajay Tirumala<BR>
Jon Dugan<BR>
Kevin Gibbs<BR> </H4>
May 2004
<P></CENTER>
[<a href="#compiling">Compiling</A> |
<A href="#features">Features</A>&nbsp; |
<A href="#tuningtcp">Tuning a TCP connection</A> |
<A href="#tuningudp">Tuning a UDP connection</A> |
<A href="#multicast">Running multicast servers and clients</A> |
<A href="#ipv6">IPv6 Mode</A> |
<A href="#repmode">Representative Streams</A> |
<A href="#daemon"> Running Iperf as a daemon</A> |
<!--<A href="#adaptive">Adaptive Window Sizes</A> | -->
<A href="#service">Running Iperf as a Windows Service</A> ]
<HR>
<!-- ----- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- -->
<H2><A name=compiling></A>Compiling</H2>
Once you have the distribution, on UNIX,
unpack it using gzip and tar. That will create a new directory
'iperf-&lt;version#&gt;' with the source files and documentation.
<P>
Iperf compiles cleanly on many systems including Linux, SGI IRIX, HP-UX,
Solaris, AIX, and Cray UNICOS. Use '<TT>make</TT>' to configure for your OS and
compile the source code.
<BLOCKQUOTE><PRE>
gunzip -c iperf-&lt;version&gt;.tar.gz | tar -xvf -
cd iperf-&lt;version&gt;
./configure
make
</PRE></BLOCKQUOTE>
To install iperf, use '<TT>make install</TT>',
which will ask you where to install it. To recompile, the easiest way is to
start over. Do '<TT>make distclean</TT>' then '<TT>./configure; make</TT>'. See the Makefile
for more options.
<P>
If you have problems, please report them to <A href="mailto:dast@nlanr.net">dast@nlanr.net</A> and
we will try to fix them quickly. <BR>
<HR>
<!-- ----- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- -->
<H2><A name=features></A>Features</H2>
<UL>
<LI>TCP
<UL>
<LI>Measure bandwidth
<LI>Report MSS/MTU size and observed read sizes.
<LI>Support for TCP window size via socket buffers.
<LI>Multi-threaded if pthreads or Win32 threads are available. Client and
server can have multiple simultaneous connections.
<!-- <LI>Suggest the optimal window size for a connection where the OS allows
setting window sizes in the granularity of bytes. </LI>--></UL>
<LI>UDP
<UL>
<LI>Client can create UDP streams of specified bandwidth.
<LI>Measure packet loss
<LI>Measure delay jitter
<LI>Multicast capable
<LI>Multi-threaded if pthreads are available. Client and server can have
multiple simultaneous connections. (This doesn't work in Windows.) </LI></UL>
<LI>Where appropriate, options can be specified with K (kilo-) and M (mega-)
suffices. So 128K instead of 131072 bytes.
<LI>Can run for specified time, rather than a set amount of data to transfer.
<LI>Picks the best units for the size of data being reported.
<LI>Server handles multiple connections, rather than quitting after a single
test.
<LI>Print periodic, intermediate bandwidth, jitter, and loss reports at
specified intervals.
<LI>Run the server as a daemon (Check out <A
href="http://www-itg.lbl.gov/nettest">Nettest</A> for running it as a secure
daemon).
<LI>Run the server as a Windows NT Service
<LI>Use representative streams to test out how link layer compression affects
your achievable bandwidth.
<!-- <LI>A library of <A
href="lib.html">useful functions and C++
classes.</A> </LI>
-->
</UL>
<HR>
<!-- ----- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- --><BR>&nbsp;
<TABLE cellPadding=3 border=1>
<TBODY>
<TR vAlign=top>
<TH align=left>Command line option</TH>
<TH align=left>Environment variable option</TH>
<TH align=left>Description</TH></TR>
<TR>
<TH bgColor=#cccccc colSpan=3>Client and Server options</TH></TR>
<TR vAlign=top>
<TD><A name=format></A><TT>-f, --format <I>[bkmaBKMA]</I></TT></TD>
<TD><TT>$IPERF_FORMAT</TT></TD>
<TD>A letter specifying the format to print bandwidth numbers in.
Supported formats are&nbsp;
<PRE>
&nbsp;&nbsp;&nbsp; 'b' = bits/sec&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'B' = Bytes/sec
&nbsp;&nbsp;&nbsp; 'k' = Kbits/sec&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'K' = KBytes/sec
&nbsp;&nbsp;&nbsp; 'm' = Mbits/sec&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'M' = MBytes/sec
&nbsp;&nbsp;&nbsp; 'g' = Gbits/sec&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'G' = GBytes/sec
&nbsp;&nbsp;&nbsp; 'a' = adaptive bits/sec&nbsp;&nbsp; 'A' = adaptive Bytes/sec
</PRE>
The adaptive formats choose between kilo- and mega- as appropriate. Fields
other than bandwidth always print bytes, but otherwise follow the
requested format. Default is 'a'.&nbsp; <BR><I>NOTE:</I> here Kilo = 1024,
Mega = 1024^2 and Giga = 1024^3 when dealing with bytes. Commonly in networking,
Kilo = 1000, Mega = 1000^2, and Giga = 1000^3 so we use this when dealing with
bits. If this really bothers you, use -f b and do the math.</TD></TR>
<TR vAlign=top>
<TD><A name=interval></A><TT>-i, --interval <I>#</I></TT></TD>
<TD><TT>$IPERF_INTERVAL</TT></TD>
<TD>Sets the interval time in seconds between periodic bandwidth, jitter,
and loss reports. If non-zero, a report is made every <I>interval</I>
seconds of the bandwidth since the last report. If zero, no periodic
reports are printed. Default is zero.</TD></TR>
<TR vAlign=top>
<TD><A name=len></A><TT>-l, --len <I>#[KM]</I></TT></TD>
<TD><TT>$IPERF_LEN</TT></TD>
<TD>The length of buffers to read or write. Iperf works by writing an
array of <I>len</I> bytes a number of times. Default is 8 KB for TCP, 1470
bytes for UDP. Note for UDP, this is the datagram size and needs to be lowered when using
IPv6 addressing to 1450 or less to avoid fragmentation. See also the <A
href="#num">-n</A>
and <A
href="#time">-t</A>
options.</TD></TR>
<TR vAlign=top>
<TD><A name=print_mss></A><TT>-m, --print_mss</TT></TD>
<TD><TT>$IPERF_PRINT_MSS</TT></TD>
<TD>Print the reported TCP MSS size (via the TCP_MAXSEG option) and the
observed read sizes which often correlate with the MSS. The MSS is usually
the MTU - 40 bytes for the TCP/IP header. Often a slightly smaller MSS is
reported because of extra header space from IP options. The interface type
corresponding to the MTU is also printed (ethernet, FDDI, etc.). This
option is not implemented on many OSes, but the read sizes may still
indicate the MSS.</TD></TR>
<TR vAlign=top>
<TD><A name=port></A><TT>-p, --port <I>#</I></TT></TD>
<TD><TT>$IPERF_PORT</TT></TD>
<TD>The server port for the server to listen on and the client to connect
to. This should be the same in both client and server. Default is 5001,
the same as ttcp.</TD></TR>
<TR vAlign=top>
<TD><A name=udp></A><TT>-u, --udp</TT></TD>
<TD><TT>$IPERF_UDP</TT></TD>
<TD>Use UDP rather than TCP. See also the <A
href="#bandwidth">-b</A>
option.</TD></TR>
<TR vAlign=top>
<TD><A name=window></A><TT>-w, --window <I>#[KM]</I></TT></TD>
<TD><TT>$TCP_WINDOW_SIZE</TT></TD>
<TD>Sets the socket buffer sizes to the specified value. For TCP, this
sets the TCP window size. For UDP it is just the buffer which datagrams
are received in, and so limits the largest receivable datagram size.</TD></TR>
<TR vAlign=top>
<TD><A name=bind></A><TT>-B, --bind <I>host</I></TT></TD>
<TD><TT>$IPERF_BIND</TT></TD>
<TD>Bind to <I>host</I>, one of this machine's addresses. For the client
this sets the outbound interface. For a server this sets the incoming
interface. This is only useful on multihomed hosts, which have multiple
network interfaces.&nbsp;
<P>For Iperf in UDP server mode, this is also used to bind and join to a
multicast group. Use addresses in the range 224.0.0.0 to 239.255.255.255
for multicast. See also the <A
href="#ttl">-T</A>
option.</P></TD></TR>
<TR vAlign=top>
<TD><A name=compatibility></A><TT>-C, --compatibility </TT></TD>
<TD><TT>$IPERF_COMPAT</TT></TD>
<TD>Compatibility mode allows for use with older version of iperf. This mode
is not required for interoperability but it is highly recommended. In
some cases when using representative streaming you could cause a 1.7 server
to crash or cause undesired connection attempts.</P></TD></TR>
<TR vAlign=top>
<TD><A name=mss></A><TT>-M, --mss <I>#[KM}</I></TT></TD>
<TD><TT>$IPERF_MSS</TT></TD>
<TD>Attempt to set the TCP maximum segment size (MSS) via the TCP_MAXSEG
option. The MSS is usually the MTU - 40 bytes for the TCP/IP header. For
ethernet, the MSS is 1460 bytes (1500 byte MTU). This option is not
implemented on many OSes.</TD></TR>
<TR vAlign=top>
<TD><A name=nodelay></A><TT>-N, --nodelay</TT></TD>
<TD><TT>$IPERF_NODELAY</TT></TD>
<TD>Set the TCP no delay option, disabling Nagle's algorithm. Normally
this is only disabled for interactive applications like telnet.</TD></TR>
<TR>
<TD><TT>-V </TT>(from v1.6 or higher)</TD>
<TD>.</TD>
<TD>Bind to an IPv6 address <BR>Server side: <BR>$ iperf -s -V&nbsp;
<P>Client side: <BR>$ iperf -c &lt;Server IPv6 Address&gt; -V
<BR>&nbsp;</P>Note: On version 1.6.3 and later a specific IPv6 Address does
not need to be bound with the <A href="#bind">-B</A> option, previous 1.6
versions do. Also on most OSes using this option will also respond to IPv4
clients using IPv4 mapped addresses.</TD></TR>
<TR>
<TH bgColor=#cccccc colSpan=3>Server specific options</TH></TR>
<TR vAlign=top>
<TD><A name=server></A><TT>-s, --server</TT></TD>
<TD><TT>$IPERF_SERVER</TT></TD>
<TD>Run Iperf in server mode.</TD></TR>
<TR>
<TD><TT>-D </TT> (from v1.2 or higher)</TD>
<TD>.</TD>
<TD>Run the server as a daemon (Unix platforms) <BR>On Win32 platforms
where services are available, Iperf will start running as a service.</TD></TR>
<TR>
<TD><TT>-R </TT>(only for Windows, from v1.2 or higher)</TD>
<TD>.</TD>
<TD>Remove the Iperf service (if it's running).&nbsp;</TD></TR><TR>
<TD><TT>-o </TT>(only for Windows, from v1.2 or higher)</TD>
<TD>.</TD>
<TD>Redirect output to given file.&nbsp;</TD></TR>
<TR vAlign=top>
<TD><A name=sclient></A><TT>-c, --client <I>host</I></TT></TD>
<TD><TT>$IPERF_CLIENT</TT></TD>
<TD> If Iperf is in server mode, then specifying a host with -c
will limit the connections that Iperf will accept to the
<I>host</I> specified. Does not work well for UDP.</TD></TR>
<TR vAlign=top>
<TD><A name=sparallel></A><TT>-P, --parallel <I>#</I></TT></TD>
<TD><TT>$IPERF_PARALLEL</TT></TD>
<TD>The number of connections to handle by the server before
closing. Default is 0 (which means to accept connections forever).</TD></TR>
<TR>
<TH bgColor=#cccccc colSpan=3>Client specific options</TH></TR>
<TR vAlign=top>
<TD><A name=bandwidth></A><TT>-b, --bandwidth <I>#[KM]</I></TT></TD>
<TD><TT>$IPERF_BANDWIDTH</TT></TD>
<TD>The UDP bandwidth to send at, in bits/sec. This implies the -u option.
Default is 1 Mbit/sec.</TD></TR>
<TR vAlign=top>
<TD><A name=client></A><TT>-c, --client <I>host</I></TT></TD>
<TD><TT>$IPERF_CLIENT</TT></TD>
<TD>Run Iperf in client mode, connecting to an Iperf server running on
<I>host</I>.</TD></TR>
<TR vAlign=top>
<TD><A name=dualtest></A><TT>-d, --dualtest </TT></TD>
<TD><TT>$IPERF_DUALTEST</TT></TD>
<TD>Run Iperf in dual testing mode. This will cause the server to connect
back to the client on the port specified in the
<A href="#listenport">-L</A> option (or defaults
to the port the client connected to the server on). This is done immediately
therefore running the tests simultaneously. If you want an alternating
test try <A href="#tradeoff">-r.</A></TD></TR>
<TR vAlign=top>
<TD><A name=num></A><TT>-n, --num <I>#[KM]</I></TT></TD>
<TD><TT>$IPERF_NUM</TT></TD>
<TD>The number of buffers to transmit. Normally, Iperf sends for 10
seconds. The -n option overrides this and sends an array of <I>len</I>
bytes <I>num</I> times, no matter how long that takes. See also the <A
href="#len">-l</A>
and <A
href="#time">-t</A>
options.</TD></TR>
<TR vAlign=top>
<TD><A name=tradeoff></A><TT>-r, --tradeoff </TT></TD>
<TD><TT>$IPERF_TRADEOFF</TT></TD>
<TD>Run Iperf in tradeoff testing mode. This will cause the server to connect
back to the client on the port specified in the
<A href="#listenport">-L</A> option (or defaults
to the port the client connected to the server on). This is done following
the client connection termination, therefore running the tests
alternating. If you want an simultaneous test try
<A href="#dualtest">-d.</A></TD></TR>
<TR vAlign=top>
<TD><A name=time></A><TT>-t, --time <I>#</I></TT></TD>
<TD><TT>$IPERF_TIME</TT></TD>
<TD>The time in seconds to transmit for. Iperf normally works by
repeatedly sending an array of <I>len</I> bytes for <I>time</I> seconds.
Default is 10 seconds. See also the <A
href="#len">-l</A>
and <A
href="#num">-n</A>
options.</TD></TR>
<TR vAlign=top>
<TD><A name=listenport></A><TT>-L, --listenport <I>#</I></TT></TD>
<TD><TT>$IPERF_LISTENPORT</TT></TD>
<TD>This specifies the port that the server will connect back to the
client on. It defaults to the port used to connect to the server
from the client.</TD></TR>
<TR vAlign=top>
<TD><A name=parallel></A><TT>-P, --parallel <I>#</I></TT></TD>
<TD><TT>$IPERF_PARALLEL</TT></TD>
<TD>The number of simultaneous connections to make to the server. Default
is 1. Requires thread support on both the client and server.</TD></TR>
<TR vAlign=top>
<TD><A name=tos></A><TT>-S, --tos <I>#</I></TT></TD>
<TD><TT>$IPERF_TOS</TT></TD>
<TD>The type-of-service for outgoing packets. (Many routers ignore the TOS
field.) You may specify the value in hex with a '0x' prefix, in octal with
a '0' prefix, or in decimal. For example, '0x10' hex = '020' octal = '16'
decimal. The TOS numbers specified in RFC 1349 are:&nbsp;
<PRE>
&nbsp;&nbsp;&nbsp; IPTOS_LOWDELAY&nbsp;&nbsp;&nbsp;&nbsp; minimize delay&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x10
&nbsp;&nbsp;&nbsp; IPTOS_THROUGHPUT&nbsp;&nbsp; maximize throughput&nbsp;&nbsp; 0x08
&nbsp;&nbsp;&nbsp; IPTOS_RELIABILITY&nbsp; maximize reliability&nbsp; 0x04
&nbsp;&nbsp;&nbsp; IPTOS_LOWCOST&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; minimize cost&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x02
&nbsp;&nbsp;&nbsp;&nbsp;
</PRE>
</TD></TR>
<TR vAlign=top>
<TD><A name=ttl></A><TT>-T, --ttl <I>#</I></TT></TD>
<TD><TT>$IPERF_TTL</TT></TD>
<TD>The time-to-live for outgoing multicast packets. This is essentially
the number of router hops to go through, and is also used for scoping.
Default is 1, link-local.</TD></TR>
<TR>
<TD><TT>-F</TT> (from v1.2 or higher)</TD>
<TD>.</TD>
<TD>Use a representative stream to measure bandwidth, e.g. :-&nbsp; <BR>$
iperf -c &lt;server address&gt; -F &lt;file-name&gt;</TD></TR>
<TR>
<TD><TT>-I </TT>(from v1.2 or higher)</TD>
<TD>.</TD>
<TD>Same as -F, input from stdin.</TD></TR>
<!-- <TR>
<TD><TT>-W </TT>(from v1.2 or higher)</TD>
<TD>.</TD>
<TD>Adaptive Window Sizes.
<BR>Use Iperf to suggest the best Window size for a connection. Iperf will start from a default window size and try to perform a search for the optimal window size</TD></TR>
--> <TR>
<TH bgColor=#cccccc colSpan=3>Miscellaneous options</TH></TR>
<TR vAlign=top>
<TD><A name=help></A><TT>-h, --help</TT></TD>
<TD>&nbsp;</TD>
<TD>Print out a summary of commands and quit.</TD></TR>
<TR vAlign=top>
<TD><A name=version></A><TT>-v, --version</TT></TD>
<TD>&nbsp;</TD>
<TD>Print version information and quit. Prints 'pthreads' if compiled with
POSIX threads, 'win32 threads' if compiled with Microsoft Win32 threads,
or 'single threaded' if compiled without threads.</TD></TR></TBODY></TABLE>
<P>
<HR>
<!-- ----- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- -->
<H2><A name=tuningtcp></A>Tuning a TCP connection</H2>
The primary goal of Iperf
is to help in tuning TCP connections over a particular path. The most
fundamental tuning issue for TCP is the TCP window size, which controls how much
data can be in the network at any one point. If it is too small, the sender will
be idle at times and get poor performance. The theoretical value to use for the
TCP window size is the <I>bandwidth delay product</I>,
<BLOCKQUOTE>bottleneck bandwidth * round trip time</BLOCKQUOTE>In the below
modi4/cyclops example, the bottleneck link is a 45 Mbit/sec DS3 link and the
round trip time measured with ping is 42 ms. The bandwidth delay product is
<BLOCKQUOTE>45 Mbit/sec * 42 ms <BR>= (45e6) * (42e-3) <BR>= 1890000 bits
<BR>= 230 KByte</BLOCKQUOTE>That is a starting point for figuring the best
window size; setting it higher or lower may produce better results. In our
example, buffer sizes over 130K did not improve the performance, despite the
bandwidth delay product of 230K.
<P>Note that many OSes and hosts have upper limits on the TCP window size. These
may be as low as 64 KB, or as high as several MB. Iperf tries to detect when
these occur and give a warning that the actual and requested window sizes are
not equal (as below, though that is due to rounding in IRIX). PSC has a <A
href="http://www.psc.edu/networking/perf_tune.html">list detailing</A> how to
change the default and maximum window sizes for various OSes. For more
information on TCP window sizes, see the <A
href="http://dast.nlanr.net/Guides/GettingStarted/TCP_window_size.html">User's
Guide to TCP Windows.</A>
<P>Here is an example session, between node1 in Illinois and node2 in North
Carolina. These are connected via the vBNS backbone and a 45 Mbit/sec DS3 link.
Notice we improve bandwidth performance by a factor of 3 using proper TCP window
sizes. Use the adaptive window sizes feature on platforms which allow setting
window sizes in the granularity of bytes.
<BLOCKQUOTE>
<PRE>
<B>node2&gt;</B> iperf -s
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 60.0 KByte (default)
------------------------------------------------------------
[&nbsp; 4] local &lt;IP Addr node2&gt; port 5001 connected with &lt;IP Addr node1&gt; port 2357
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth
[&nbsp; 4]&nbsp; 0.0-10.1 sec&nbsp;&nbsp; 6.5 MBytes&nbsp;&nbsp; <B><FONT color=#ff0000>5.2 Mbits/sec
</FONT>node1&gt;</B> iperf -c node2
------------------------------------------------------------
Client connecting to node1, TCP port 5001
TCP window size: 59.9 KByte (default)
------------------------------------------------------------
[&nbsp; 3] local &lt;IP Addr node1&gt; port 2357 connected with &lt;IP Addr node2&gt; port 5001
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth
[&nbsp; 3]&nbsp; 0.0-10.0 sec&nbsp;&nbsp; 6.5 MBytes&nbsp;&nbsp; 5.2 Mbits/sec</PRE>
<HR>
<PRE><B>node2&gt;</B> iperf -s -w 130k
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size:&nbsp; 130 KByte
------------------------------------------------------------
[&nbsp; 4] local &lt;IP Addr node 2&gt; port 5001 connected with &lt;IP Addr node 1&gt; port 2530
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth
[&nbsp; 4]&nbsp; 0.0-10.1 sec&nbsp; 19.7 MBytes&nbsp; <B><FONT color=#ff0000>15.7 Mbits/sec
</FONT>node1&gt;</B> iperf -c node2 -w 130k
------------------------------------------------------------
Client connecting to node2, TCP port 5001
TCP window size:&nbsp; 129 KByte (WARNING: requested&nbsp; 130 KByte)
------------------------------------------------------------
[&nbsp; 3] local &lt;IP Addr node1&gt; port 2530 connected with &lt;IP Addr node2&gt; port 5001
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth
[&nbsp; 3]&nbsp; 0.0-10.0 sec&nbsp; 19.7 MBytes&nbsp; 15.8 Mbits/sec</PRE></BLOCKQUOTE>Another
test to do is run parallel TCP streams. If the total aggregate bandwidth is more
than what an individual stream gets, something is wrong. Either the TCP window
size is too small, or the OS's TCP implementation has bugs, or the network
itself has deficiencies. See above for TCP window sizes; otherwise diagnosing
which is somewhat difficult. If Iperf is compiled with pthreads, a single client
and server can test this, otherwise setup multiple clients and servers on
different ports. Here's an example where a single stream gets 16.5 Mbit/sec, but
two parallel streams together get 16.7 + 9.4 = 26.1 Mbit/sec, even when using
large TCP window sizes:
<BLOCKQUOTE><PRE><B>node2&gt;</B> iperf -s -w 300k
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size:&nbsp; 300 KByte
------------------------------------------------------------
[&nbsp; 4] local &lt;IP Addr node2&gt; port 5001 connected with &lt;IP Addr node1&gt; port 6902
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth
[&nbsp; 4]&nbsp; 0.0-10.2 sec&nbsp; 20.9 MBytes&nbsp; <B><FONT color=#ff0000>16.5 Mbits/sec
</FONT></B>[&nbsp; 4] local &lt;IP Addr node2&gt; port 5001 connected with &lt;IP Addr node1&gt; port 6911
[&nbsp; 5] local &lt;IP Addr node2&gt; port 5001 connected with &lt;IP Addr node2&gt; port 6912
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth
[&nbsp; 5]&nbsp; 0.0-10.1 sec&nbsp; 21.0 MBytes&nbsp; <B><FONT color=#ff0000>16.7 Mbits/sec
</FONT></B>[&nbsp; 4]&nbsp; 0.0-10.3 sec&nbsp; 12.0 MBytes&nbsp;&nbsp;<B><FONT color=#ff0000> 9.4 Mbits/sec
</FONT>node1&gt;</B> ./iperf -c node2 -w 300k
------------------------------------------------------------
Client connecting to node2, TCP port 5001
TCP window size:&nbsp; 299 KByte (WARNING: requested&nbsp; 300 KByte)
------------------------------------------------------------
[&nbsp; 3] local &lt;IP Addr node2&gt; port 6902 connected with &lt;IP Addr node1&gt; port 5001
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth
[&nbsp; 3]&nbsp; 0.0-10.2 sec&nbsp; 20.9 MBytes&nbsp; 16.4 Mbits/sec
<B>node1&gt;</B> iperf -c node2 -w 300k -P 2
------------------------------------------------------------
Client connecting to node2, TCP port 5001
TCP window size:&nbsp; 299 KByte (WARNING: requested&nbsp; 300 KByte)
------------------------------------------------------------
[&nbsp; 4] local &lt;IP Addr node2&gt; port 6912 connected with &lt;IP Addr node1&gt; port 5001
[&nbsp; 3] local &lt;IP Addr node2&gt; port 6911 connected with &lt;IP Addr node1&gt; port 5001
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth
[&nbsp; 4]&nbsp; 0.0-10.1 sec&nbsp; 21.0 MBytes&nbsp; 16.6 Mbits/sec
[&nbsp; 3]&nbsp; 0.0-10.2 sec&nbsp; 12.0 MBytes&nbsp;&nbsp; 9.4 Mbits/sec</PRE></BLOCKQUOTE>A
secondary tuning issue for TCP is the maximum transmission unit (MTU). To be
most effective, both hosts should support Path MTU Discovery. PSC has a <A
href="http://www.psc.edu/networking/perf_tune.html">list detailing</A> what OSes
support Path MTU Discovery. Hosts without Path MTU Discovery often use 536 as
the MSS, which wastes bandwidth and processing time. Use the -m option to
display what MSS is being used, and see if this matches what you expect. Often
it is around 1460 bytes for ethernet.
<BLOCKQUOTE><PRE><B>node3&gt;</B> iperf -s -m
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 60.0 KByte (default)
------------------------------------------------------------
[&nbsp; 4] local &lt;IP Addr node3&gt; port 5001 connected with &lt;IP Addr node4&gt; port 1096
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth
[&nbsp; 4]&nbsp; 0.0- 2.0 sec&nbsp;&nbsp; 1.8 MBytes&nbsp;&nbsp; 6.9 Mbits/sec
[&nbsp; 4] <B><FONT color=#ff0000>MSS size 1448 bytes (MTU 1500 bytes, ethernet)
</FONT></B>[&nbsp; 4] Read lengths occurring in more than 5% of reads:
[&nbsp; 4]&nbsp;&nbsp; 952 bytes read&nbsp;&nbsp; 219 times (16.2%)
[&nbsp; 4]&nbsp; 1448 bytes read&nbsp; 1128 times (83.6%)</PRE></BLOCKQUOTE>Here
is a host that doesn't support Path MTU Discovery. It will only send and receive
small 576 byte packets.
<BLOCKQUOTE><PRE><B>node4&gt;</B> iperf -s -m
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 32.0 KByte (default)
------------------------------------------------------------
[&nbsp; 4] local &lt;IP Addr node4&gt; port 5001 connected with &lt;IP Addr node3&gt; port 13914
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth
[&nbsp; 4]&nbsp; 0.0- 2.3 sec&nbsp;&nbsp; 632 KBytes&nbsp;&nbsp; 2.1 Mbits/sec
<B><FONT color=#ff0000>WARNING: Path MTU Discovery may not be enabled.
</FONT></B>[&nbsp; 4] <B><FONT color=#ff0000>MSS size 536 bytes (MTU 576 bytes, minimum)
</FONT></B>[&nbsp; 4] Read lengths occurring in more than 5% of reads:
[&nbsp; 4]&nbsp;&nbsp; 536 bytes read&nbsp;&nbsp; 308 times (58.4%)
[&nbsp; 4]&nbsp; 1072 bytes read&nbsp;&nbsp;&nbsp; 91 times (17.3%)
[&nbsp; 4]&nbsp; 1608 bytes read&nbsp;&nbsp;&nbsp; 29 times (5.5%)</PRE></BLOCKQUOTE>Iperf
supports other tuning options, which were added for exceptional network
situations like HIPPI-to-HIPPI over ATM. <BR>
<HR>
<!-- ----- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- -->
<H2><A name=tuningudp></A>Tuning a UDP connection</H2>
Iperf creates a constant bit rate UDP stream. This is a very artificial
stream, similar to voice communication but not much else.
<P>
You will want to adjust the datagram size (-l) to the size your application
uses.
<P>
The server detects UDP datagram loss by ID numbers in the datagrams. Usually
a UDP datagram becomes several IP packets. Losing a single IP packet will lose
the entire datagram. To measure packet loss instead of datagram loss, make the
datagrams small enough to fit into a single packet, using the -l option. The
default size of 1470 bytes works for ethernet. Out-of-order packets are also
detected. (Out-of-order packets cause some ambiguity in the lost packet count;
Iperf assumes they are not duplicate packets, so they are excluded from the lost
packet count.) Since TCP does not report loss to the user, I find UDP tests
helpful to see packet loss along a path.
<P>
Jitter calculations are continuously computed by the server, as specified by
RTP in RFC 1889. The client records a 64 bit second/microsecond timestamp in the
packet. The server computes the relative transit time as (server's receive time
- client's send time). The client's and server's clocks do not need to be
synchronized; any difference is subtracted out in the jitter calculation. Jitter
is the smoothed mean of differences between consecutive transit times.
<BLOCKQUOTE><PRE><B>node2&gt;</B> iperf -s -u -i 1
------------------------------------------------------------
Server listening on UDP port 5001
Receiving 1470 byte datagrams
UDP buffer size: 60.0 KByte (default)
------------------------------------------------------------
[&nbsp; 4] local &lt;IP Addr node2&gt; port 5001 connected with &lt;IP Addr node1&gt; port 9726
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Jitter&nbsp;&nbsp; Lost/Total Datagrams
[&nbsp; 4]&nbsp; 0.0- 1.0 sec&nbsp;&nbsp; 1.3 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.209 ms&nbsp;&nbsp;&nbsp; 1/&nbsp; 894 (0.11%)
[&nbsp; 4]&nbsp; 1.0- 2.0 sec&nbsp;&nbsp; 1.3 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.221 ms&nbsp;&nbsp;&nbsp; 0/&nbsp; 892 (0%)
[&nbsp; 4]&nbsp; 2.0- 3.0 sec&nbsp;&nbsp; 1.3 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.277 ms&nbsp;&nbsp;&nbsp; 0/&nbsp; 892 (0%)
[&nbsp; 4]&nbsp; 3.0- 4.0 sec&nbsp;&nbsp; 1.3 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.359 ms&nbsp;&nbsp;&nbsp; 0/&nbsp; 893 (0%)
[&nbsp; 4]&nbsp; 4.0- 5.0 sec&nbsp;&nbsp; 1.3 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.251 ms&nbsp;&nbsp;&nbsp; 0/&nbsp; 892 (0%)
[&nbsp; 4]&nbsp; 5.0- 6.0 sec&nbsp;&nbsp; 1.3 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.215 ms&nbsp;&nbsp;&nbsp; 0/&nbsp; 892 (0%)
[&nbsp; 4]&nbsp; 6.0- 7.0 sec&nbsp;&nbsp; 1.3 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.325 ms&nbsp;&nbsp;&nbsp; 0/&nbsp; 892 (0%)
[&nbsp; 4]&nbsp; 7.0- 8.0 sec&nbsp;&nbsp; 1.3 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.254 ms&nbsp;&nbsp;&nbsp; 0/&nbsp; 892 (0%)
[&nbsp; 4]&nbsp; 8.0- 9.0 sec&nbsp;&nbsp; 1.3 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.282 ms&nbsp;&nbsp;&nbsp; 0/&nbsp; 892 (0%)
[&nbsp; 4]&nbsp; 0.0-10.0 sec&nbsp; 12.5 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.243 ms&nbsp;&nbsp;&nbsp; 1/ 8922 (0.011%)
<B>node1&gt;</B> iperf -c node2 -u -b 10m
------------------------------------------------------------
Client connecting to node2, UDP port 5001
Sending 1470 byte datagrams
UDP buffer size: 60.0 KByte (default)
------------------------------------------------------------
[&nbsp; 3] local &lt;IP Addr node1&gt; port 9726 connected with &lt;IP Addr node2&gt; port 5001
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth
[&nbsp; 3]&nbsp; 0.0-10.0 sec&nbsp; 12.5 MBytes&nbsp; 10.0 Mbits/sec
[&nbsp; 3] Sent 8922 datagrams</PRE></BLOCKQUOTE>Notice the higher jitter due to
datagram reassembly when using larger 32 KB datagrams, each split into 23
packets of 1500 bytes. The higher datagram loss seen here may be due to the
burstiness of the traffic, which is 23 back-to-back packets and then a long
pause, rather than evenly spaced individual packets.
<BLOCKQUOTE><PRE><B>node2&gt;</B> iperf -s -u -l 32k -w 128k -i 1
------------------------------------------------------------
Server listening on UDP port 5001
Receiving 32768 byte datagrams
UDP buffer size:&nbsp; 128 KByte
------------------------------------------------------------
[&nbsp; 3] local &lt;IP Addr node2&gt; port 5001 connected with &lt;IP Addr node1&gt; port 11303
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Jitter&nbsp;&nbsp; Lost/Total Datagrams
[&nbsp; 3]&nbsp; 0.0- 1.0 sec&nbsp;&nbsp; 1.3 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.430 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 41 (0%)
[&nbsp; 3]&nbsp; 1.0- 2.0 sec&nbsp;&nbsp; 1.1 MBytes&nbsp;&nbsp; 8.5 Mbits/sec&nbsp; 5.996 ms&nbsp;&nbsp;&nbsp; 6/&nbsp;&nbsp; 40 (15%)
[&nbsp; 3]&nbsp; 2.0- 3.0 sec&nbsp;&nbsp; 1.2 MBytes&nbsp;&nbsp; 9.7 Mbits/sec&nbsp; 0.796 ms&nbsp;&nbsp;&nbsp; 1/&nbsp;&nbsp; 40 (2.5%)
[&nbsp; 3]&nbsp; 3.0- 4.0 sec&nbsp;&nbsp; 1.2 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.403 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 40 (0%)
[&nbsp; 3]&nbsp; 4.0- 5.0 sec&nbsp;&nbsp; 1.2 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.448 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 40 (0%)
[&nbsp; 3]&nbsp; 5.0- 6.0 sec&nbsp;&nbsp; 1.2 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.464 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 40 (0%)
[&nbsp; 3]&nbsp; 6.0- 7.0 sec&nbsp;&nbsp; 1.2 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.442 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 40 (0%)
[&nbsp; 3]&nbsp; 7.0- 8.0 sec&nbsp;&nbsp; 1.2 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.342 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 40 (0%)
[&nbsp; 3]&nbsp; 8.0- 9.0 sec&nbsp;&nbsp; 1.2 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.431 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 40 (0%)
[&nbsp; 3]&nbsp; 9.0-10.0 sec&nbsp;&nbsp; 1.2 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.407 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 40 (0%)
[&nbsp; 3]&nbsp; 0.0-10.0 sec&nbsp; 12.3 MBytes&nbsp;&nbsp; 9.8 Mbits/sec&nbsp; 0.407 ms&nbsp;&nbsp;&nbsp; 7/&nbsp; 401 (1.7%)
<B>node1&gt;</B> iperf -c node2 -b 10m -l 32k -w 128k
------------------------------------------------------------
Client connecting to node2, UDP port 5001
Sending 32768 byte datagrams
UDP buffer size:&nbsp; 128 KByte
------------------------------------------------------------
[&nbsp; 3] local &lt;IP Addr node2&gt; port 11303 connected with &lt;IP Addr node1&gt; port 5001
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth
[&nbsp; 3]&nbsp; 0.0-10.0 sec&nbsp; 12.5 MBytes&nbsp; 10.0 Mbits/sec
[&nbsp; 3] Sent 401 datagrams</PRE><PRE></PRE></BLOCKQUOTE>
<P><A name=multicast></A>
<B><FONT size=+1>Multicast</FONT></B>
<P>To test multicast, run several servers with the bind option (-B, --bind) set
to the multicast group address. Run the client, connecting to the multicast
group address and setting the TTL (-T, --ttl) as needed. Unlike normal TCP and
UDP tests, multicast servers may be started after the client. In that case,
datagrams sent before the server started show up as losses in the first periodic
report (61 datagrams on arno below).
<BLOCKQUOTE><PRE><B>node5&gt;</B> iperf -c 224.0.67.67 -u --ttl 5 -t 5
------------------------------------------------------------
Client connecting to 224.0.67.67, UDP port 5001
Sending 1470 byte datagrams
Setting multicast TTL to 5
UDP buffer size: 32.0 KByte (default)
------------------------------------------------------------
[&nbsp; 3] local &lt;IP Addr node5&gt; port 1025 connected with 224.0.67.67 port 5001
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth
[&nbsp; 3]&nbsp; 0.0- 5.0 sec&nbsp;&nbsp; 642 KBytes&nbsp;&nbsp; 1.0 Mbits/sec
[&nbsp; 3] Sent 447 datagrams
<B>node5&gt;</B> iperf -s -u -B 224.0.67.67 -i 1
------------------------------------------------------------
Server listening on UDP port 5001
Binding to local address 224.0.67.67
Joining multicast group&nbsp; 224.0.67.67
Receiving 1470 byte datagrams
UDP buffer size: 32.0 KByte (default)
------------------------------------------------------------
[&nbsp; 3] local 224.0.67.67 port 5001 connected with &lt;IP Addr node5&gt; port 1025
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Jitter&nbsp;&nbsp; Lost/Total Datagrams
[&nbsp; 3]&nbsp; 0.0- 1.0 sec&nbsp;&nbsp; 131 KBytes&nbsp;&nbsp; 1.0 Mbits/sec&nbsp; 0.007 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 91 (0%)
[&nbsp; 3]&nbsp; 1.0- 2.0 sec&nbsp;&nbsp; 128 KBytes&nbsp;&nbsp; 1.0 Mbits/sec&nbsp; 0.008 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 89 (0%)
[&nbsp; 3]&nbsp; 2.0- 3.0 sec&nbsp;&nbsp; 128 KBytes&nbsp;&nbsp; 1.0 Mbits/sec&nbsp; 0.010 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 89 (0%)
[&nbsp; 3]&nbsp; 3.0- 4.0 sec&nbsp;&nbsp; 128 KBytes&nbsp;&nbsp; 1.0 Mbits/sec&nbsp; 0.013 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 89 (0%)
[&nbsp; 3]&nbsp; 4.0- 5.0 sec&nbsp;&nbsp; 128 KBytes&nbsp;&nbsp; 1.0 Mbits/sec&nbsp; 0.008 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 89 (0%)
[&nbsp; 3]&nbsp; 0.0- 5.0 sec&nbsp;&nbsp; 642 KBytes&nbsp;&nbsp; 1.0 Mbits/sec&nbsp; 0.008 ms&nbsp;&nbsp;&nbsp; 0/&nbsp; 447 (0%)
<B>node6&gt;</B> iperf -s -u -B 224.0.67.67 -i 1
------------------------------------------------------------
Server listening on UDP port 5001
Binding to local address 224.0.67.67
Joining multicast group&nbsp; 224.0.67.67
Receiving 1470 byte datagrams
UDP buffer size: 60.0 KByte (default)
------------------------------------------------------------
[&nbsp; 3] local 224.0.67.67 port 5001 connected with &lt;IP Addr node5&gt; port 1025
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Jitter&nbsp;&nbsp; Lost/Total Datagrams
[&nbsp; 3]&nbsp; 0.0- 1.0 sec&nbsp;&nbsp; 129 KBytes&nbsp;&nbsp; 1.0 Mbits/sec&nbsp; 0.778 ms&nbsp;&nbsp; 61/&nbsp; 151 (40%)
[&nbsp; 3]&nbsp; 1.0- 2.0 sec&nbsp;&nbsp; 128 KBytes&nbsp;&nbsp; 1.0 Mbits/sec&nbsp; 0.236 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 89 (0%)
[&nbsp; 3]&nbsp; 2.0- 3.0 sec&nbsp;&nbsp; 128 KBytes&nbsp;&nbsp; 1.0 Mbits/sec&nbsp; 0.264 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 89 (0%)
[&nbsp; 3]&nbsp; 3.0- 4.0 sec&nbsp;&nbsp; 128 KBytes&nbsp;&nbsp; 1.0 Mbits/sec&nbsp; 0.248 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 89 (0%)
[&nbsp; 3]&nbsp; 0.0- 4.3 sec&nbsp;&nbsp; 554 KBytes&nbsp;&nbsp; 1.0 Mbits/sec&nbsp; 0.298 ms&nbsp;&nbsp; 61/&nbsp; 447 (14%)</PRE><PRE><HR width="100%"></PRE></BLOCKQUOTE>
<P><A name=ipv6></A>
<DL>
<DT><B><FONT size=+2>IPv6 Mode</FONT></B>
<DD>Download the IPv6 version of this release.<BR>Get the IPv6 address of the node using the 'ifconfig' command.<BR>Use the <FONT color=#000099>-V</FONT> option to indicate that you are using an IPv6 address Please note that we need to explicitly bind the server address also.
<P>Server side:<BR><FONT color=#000099> $ iperf -s -V</FONT>
<P>Client side:<BR><FONT color=#000099>$ iperf -c &lt;Server IPv6 Address&gt; -V </FONT>
<P>Note: Iperf version 1.6.2 and eariler require a IPv6 address to be explicitly bound
with the <A HREF="#bind">-B</A> option for the server.</P></DD></DL>
<HR>
<P><A name=repmode></A>
<DL>
<DT><B><FONT size=+2>Using Representative Streams to measure
bandwidth</FONT></B>
<DD>Use the -F or -I option. If you want to test how your network performs
with compressed / uncompressed streams, just create representative streams and
use the -F option to test it. This is usually due to the link layer
compressing data.
<P>The -F option is for file input.<BR>The -I option is for input from stdin.
<P>E.g. <BR>Client: $ <FONT color=#000099> iperf -c &lt;server address&gt; -F &lt;file-name&gt;<BR></FONT>
<BR>Client: $ <FONT color=#000099> iperf -c &lt;server address&gt; -I </FONT></P></DD></DL>
<P><A name=daemon></A>
<HR>
<DL>
<DT><B><FONT size=+2>Running the server as a daemon</FONT></B>
<DD>Use the -D command line option to run the server as a daemon. Redirect the
output to a file.<BR>E.g. <FONT color=#000099>iperf -s -D &gt;
iperfLog</FONT>. <FONT color=#000000>This will have the Iperf Server running
as a daemon and the server messages will be logged in the file iperfLog.
</DD></DL>
<HR>
<P><A name=service></A>
<DL>
<DT><B><FONT size=+2>Using Iperf as a Service under Win32</FONT></B>
<DD>There are three options for Win32:
<P>
<DL>
<DT>-o outputfilename
<DD>output the messages into the specified file
<DT>-s -D
<DD>install Iperf as a service and run it
<DT>-s -R
<DD>uninstall the Iperf service </DD></DL>
<P>Examples:
<DL>
<DT><FONT color=#3366ff>iperf -s -D -o iperflog.txt</FONT>
<DD>will install the Iperf service and run it. Messages will be reported
into "%windir%\system32\iperflog.txt"
<P></P>
<DT><FONT color=#3366ff>iperf -s -R</FONT>
<DD>will uninstall the Iperf service if it is installed.
<P>Note: If you stop want to restart the Iperf service after having killed
it with the Microsoft Management Console or the Windows Task Manager, make
sure to use the proper OPTION in the service properties dialog.
</P></DD></DL></DD></DL>
<HR>
<!--<P><A name=multicast></A>
<DL>
<DT><B><FONT size=+2>Running the multicast server and client</FONT></B>
<DD>Use the -B option while starting the server to bind it to a multicast
address.<BR>E.g. :-<FONT color=#3366ff>iperf -s -u -B 224.0.55.55</FONT>.
<P>This will have the Iperf server listening for datagrams (-u) for the
address 224.0.55.55(-B 224.0.55.55).
<P>Now, start a client sending packets to this multicast address.
<P>E.g. : <FONT color=#3366ff>iperf -c 224.0.55.55 -u</FONT>.
This will have a UDP client (-u) sending to the multicast address
224.0.55.55(-c 224.0.55.55).
<P><FONT color=#000000>Start multiple clients or servers as explained above,
sending data to the same multicast server. (If you have multiple servers
listening on the multicast address, each of the servers will be getting the data)
</P></DD></DL>
<HR>-->
<!--<A name=adaptive></A>
<DL>
<DT><B><FONT size=+2>Adaptive window sizes</FONT></B>
<DD>Use the -W option on the client to run the client with the adaptive window
size. Ensure that the server window size is fairly big for this
option.<BR>E.g.. If the server TCP window size is 8KB, it does not help having
a client TCP window size of 256KB.<BR>256KB Server TCP Window Size should
suffice for most high bandwidth networks.
<P>Client changes the TCP window size using a binary exponential
algorithm. This means that you may notice that TCP window size suggested may
vary according to the traffic in the network, Iperf will suggest the best
window size for the current network scenario.
</DL>
<HR width="100%">
--><P><!-- ----- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- -->
<CENTER>
<P>Copyright 1999,2000,2001,2002,2003,2004 <BR>The Board of Trustees of the University of
Illinois <BR>All rights reserved <BR>See <A
href="ui_license.html">UI License</A> for
complete details.</CENTER>
</BODY>
</HTML>

View File

@ -1,90 +0,0 @@
<HTML>
<HEAD>
<TITLE>Iperf Copyright</TITLE>
<!-- $Id: ui_license.html,v 1.1.1.1 2004/05/18 01:50:44 kgibbs Exp $ -->
</HEAD>
<BODY BGCOLOR="#FFFFFF" LINK="#006633" VLINK="#669900" ALINK="#669966">
<CENTER>
<P><IMG SRC="dast.gif"
ALT="Distributed Applications Support Team"></P>
</CENTER>
<H1 ALIGN=CENTER>Iperf Copyright</H1>
<HR><!-- ----- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- -->
<CENTER>
Copyright (c) 1999,2000,2001,2002,2003,2004,2005 The Board of Trustees of the University of Illinois<br>
All Rights Reserved.
<P>
<a href="http://dast.nlanr.net/Projects/Iperf">Iperf performance test</a><BR>
Mark Gates<BR>
Ajay Tirumala<br>
Jim Ferguson<br>
Jon Dugan<br>
Feng Qin<br>
Kevin Gibbs<br>
John Estabrook<BR>
National Laboratory for Applied Network Research <BR>
National Center for Supercomputing Applications <BR>
University of Illinois at Urbana-Champaign <BR>
<a href="http://www.ncsa.uiuc.edu">http://www.ncsa.uiuc.edu</a>
</center>
<P>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software (Iperf)
and associated documentation files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
<p>
<ul>
<li>Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimers.
<p>
<li>Redistributions in binary form must reproduce the above copyright notice, this list
of conditions and the following disclaimers in the documentation and/or other
materials provided with the distribution.
<p>
<li>Neither the names of the University of Illinois, NCSA, nor the names of its
contributors may be used to endorse or promote products derived from this
Software without specific prior written permission.
</ul>
<p>
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
</pre>
<HR><!-- ----- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- -->
<CENTER>
<P><FONT FACE="helvetica,arial" SIZE="2">
<A HREF="mailto:dast@nlanr.net">dast@nlanr.net</A>
Last modified: Jan 5, 2004<br>
<A HREF="http://www.nlanr.net">NLANR</a> ||
<A HREF="http://dast.nlanr.net">applications support</a> ||
<A HREF="http://ncne.nlanr.net">engineering support</a> ||
<A HREF="http://moat.nlanr.net">measurement and operations</a>
</FONT></P>
</CENTER>
</BODY>
</HTML>

View File

@ -1,93 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
* Client.hpp
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* A client thread initiates a connect to the server and handles
* sending and receiving data, then closes the socket.
* -------------------------------------------------------------------
*/
#ifndef CLIENT_H
#define CLIENT_H
#include "Settings.hpp"
#include "Timestamp.hpp"
/* ------------------------------------------------------------------- */
class Client {
public:
// stores server hostname, port, UDP/TCP mode, and UDP rate
Client( thread_Settings *inSettings );
// destroy the client object
~Client();
// connects and sends data
void Run( void );
// TCP specific version of above
void RunTCP( void );
void InitiateServer();
// UDP / TCP
void Send( void );
void write_UDP_FIN( );
// client connect
void Connect( );
protected:
thread_Settings *mSettings;
char* mBuf;
Timestamp mEndTime;
Timestamp lastPacketTime;
}; // end class Client
#endif // CLIENT_H

View File

@ -1,169 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Condition.h
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* An abstract class for waiting on a condition variable. If
* threads are not available, this does nothing.
* ------------------------------------------------------------------- */
#ifndef CONDITION_H
#define CONDITION_H
#include "headers.h"
#include "Mutex.h"
#include "util.h"
#if defined( HAVE_POSIX_THREAD )
typedef struct Condition {
pthread_cond_t mCondition;
pthread_mutex_t mMutex;
} Condition;
#elif defined( HAVE_WIN32_THREAD )
typedef struct Condition {
HANDLE mCondition;
HANDLE mMutex;
} Condition;
#else
typedef struct Condition {
int mCondition;
int mMutex;
} Condition;
#endif
#define Condition_Lock( Cond ) Mutex_Lock( &Cond.mMutex )
#define Condition_Unlock( Cond ) Mutex_Unlock( &Cond.mMutex )
// initialize condition
#if defined( HAVE_POSIX_THREAD )
#define Condition_Initialize( Cond ) do { \
Mutex_Initialize( &(Cond)->mMutex ); \
pthread_cond_init( &(Cond)->mCondition, NULL ); \
} while ( 0 )
#elif defined( HAVE_WIN32_THREAD )
// set all conditions to be broadcast
// unfortunately in Win32 you have to know at creation
// whether the signal is broadcast or not.
#define Condition_Initialize( Cond ) do { \
Mutex_Initialize( &(Cond)->mMutex ); \
(Cond)->mCondition = CreateEvent( NULL, true, false, NULL ); \
} while ( 0 )
#else
#define Condition_Initialize( Cond )
#endif
// destroy condition
#if defined( HAVE_POSIX_THREAD )
#define Condition_Destroy( Cond ) do { \
pthread_cond_destroy( &(Cond)->mCondition ); \
Mutex_Destroy( &(Cond)->mMutex ); \
} while ( 0 )
#elif defined( HAVE_WIN32_THREAD )
#define Condition_Destroy( Cond ) do { \
CloseHandle( (Cond)->mCondition ); \
Mutex_Destroy( &(Cond)->mMutex ); \
} while ( 0 )
#else
#define Condition_Destroy( Cond )
#endif
// sleep this thread, waiting for condition signal
#if defined( HAVE_POSIX_THREAD )
#define Condition_Wait( Cond ) pthread_cond_wait( &(Cond)->mCondition, &(Cond)->mMutex )
#elif defined( HAVE_WIN32_THREAD )
// atomically release mutex and wait on condition,
// then re-acquire the mutex
#define Condition_Wait( Cond ) do { \
SignalObjectAndWait( (Cond)->mMutex, (Cond)->mCondition, INFINITE, false ); \
Mutex_Lock( &(Cond)->mMutex ); \
} while ( 0 )
#else
#define Condition_Wait( Cond )
#endif
// sleep this thread, waiting for condition signal,
// but bound sleep time by the relative time inSeconds.
#if defined( HAVE_POSIX_THREAD )
#define Condition_TimedWait( Cond, inSeconds ) do { \
struct timespec absTimeout; \
absTimeout.tv_sec = time( NULL ) + inSeconds; \
absTimeout.tv_nsec = 0; \
pthread_cond_timedwait( &(Cond)->mCondition, &(Cond)->mMutex, &absTimeout ); \
} while ( 0 )
#elif defined( HAVE_WIN32_THREAD )
// atomically release mutex and wait on condition,
// then re-acquire the mutex
#define Condition_TimedWait( Cond, inSeconds ) do { \
SignalObjectAndWait( (Cond)->mMutex, (Cond)->mCondition, inSeconds*1000, false ); \
Mutex_Lock( &(Cond)->mMutex ); \
} while ( 0 )
#else
#define Condition_TimedWait( Cond, inSeconds )
#endif
// send a condition signal to wake one thread waiting on condition
// in Win32, this actually wakes up all threads, same as Broadcast
// use PulseEvent to auto-reset the signal after waking all threads
#if defined( HAVE_POSIX_THREAD )
#define Condition_Signal( Cond ) pthread_cond_signal( &(Cond)->mCondition )
#elif defined( HAVE_WIN32_THREAD )
#define Condition_Signal( Cond ) PulseEvent( (Cond)->mCondition )
#else
#define Condition_Signal( Cond )
#endif
// send a condition signal to wake all threads waiting on condition
#if defined( HAVE_POSIX_THREAD )
#define Condition_Broadcast( Cond ) pthread_cond_broadcast( &(Cond)->mCondition )
#elif defined( HAVE_WIN32_THREAD )
#define Condition_Broadcast( Cond ) PulseEvent( (Cond)->mCondition )
#else
#define Condition_Broadcast( Cond )
#endif
#endif // CONDITION_H

View File

@ -1,123 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Extractor.h
* by Ajay Tirumala (tirumala@ncsa.uiuc.edu)
* -------------------------------------------------------------------
* Extract data from a file, used to measure the transfer rates
* for various stream formats.
*
* E.g. Use a gzipped file to measure the transfer rates for
* compressed data
* Use an MPEG file to measure the transfer rates of
* Multimedia data formats
* Use a plain BMP file to measure the transfer rates of
* Uncompressed data
*
* This is beneficial especially in measuring bandwidth across WAN
* links where data compression takes place before data transmission
* ------------------------------------------------------------------- */
#ifndef _EXTRACTOR_H
#define _EXTRACTOR_H
#include <stdlib.h>
#include <stdio.h>
#include "Settings.hpp"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Constructor
* @arg fileName Name of the file
* @arg size Block size for reading
*/
void Extractor_Initialize( char *fileName, int size, thread_Settings *mSettings );
/**
* Constructor
* @arg fp File Pointer
* @arg size Block size for reading
*/
void Extractor_InitializeFile( FILE *fp, int size, thread_Settings *mSettings );
/*
* Fetches the next data block from
* the file
* @arg block Pointer to the data read
* @return Number of bytes read
*/
int Extractor_getNextDataBlock( char *block, thread_Settings *mSettings );
/**
* Function which determines whether
* the file stream is still readable
* @return true, if readable; false, if not
*/
int Extractor_canRead( thread_Settings *mSettings );
/**
* This is used to reduce the read size
* Used in UDP transfer to accomodate the
* the header (timestamp)
* @arg delta Size to reduce
*/
void Extractor_reduceReadSize( int delta, thread_Settings *mSettings );
/**
* Destructor
*/
void Extractor_Destroy( thread_Settings *mSettings );
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif

View File

@ -1,96 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* List.h
* by Kevin Gibbs <kgibbs@ncsa.uiuc.edu>
* -------------------------------------------------------------------
*/
#ifndef Iperf_LIST_H
#define Iperf_LIST_H
#include "headers.h"
#include "Settings.hpp"
#include "Reporter.h"
#include "Mutex.h"
/*
* List handling utilities to replace STD vector
*/
struct Iperf_ListEntry;
/*
* A List entry that consists of a sockaddr
* a pointer to the Audience that sockaddr is
* associated with and a pointer to the next
* entry
*/
struct Iperf_ListEntry {
iperf_sockaddr data;
MultiHeader *holder;
thread_Settings *server;
Iperf_ListEntry *next;
};
extern Mutex clients_mutex;
extern Iperf_ListEntry *clients;
/*
* Functions to modify or search the List
*/
void Iperf_pushback ( Iperf_ListEntry *add, Iperf_ListEntry **root );
void Iperf_delete ( iperf_sockaddr *del, Iperf_ListEntry **root );
void Iperf_destroy ( Iperf_ListEntry **root );
Iperf_ListEntry* Iperf_present ( iperf_sockaddr *find, Iperf_ListEntry *root );
Iperf_ListEntry* Iperf_hostpresent ( iperf_sockaddr *find, Iperf_ListEntry *root );
#endif

View File

@ -1,95 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Listener.hpp
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* Listener sets up a socket listening on the server host. For each
* connected socket that accept() returns, this creates a Server
* socket and spawns a thread for it.
* ------------------------------------------------------------------- */
#ifndef LISTENER_H
#define LISTENER_H
#include "Thread.h"
#include "Settings.hpp"
class Listener;
class Listener {
public:
// stores server port and TCP/UDP mode
Listener( thread_Settings *inSettings );
// destroy the server object
~Listener();
// accepts connections and starts Servers
void Run( void );
// Starts the Servers as a daemon
void runAsDaemon( const char *, int );
void Listen( );
void McastJoin( );
void McastSetTTL( int val );
void Accept( thread_Settings *server );
void UDPSingleServer ();
protected:
int mClients;
char* mBuf;
thread_Settings *mSettings;
thread_Settings *server;
}; // end class Listener
#endif // LISTENER_H

View File

@ -1,196 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Locale.h
* by Ajay Tirumala <tirumala@ncsa.uiuc.edu>
* & Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* Strings and other stuff that is locale specific.
* ------------------------------------------------------------------- */
#ifndef LOCALE_H
#define LOCALE_H
#ifdef __cplusplus
extern "C" {
#endif
/* -------------------------------------------------------------------
* usage
* ------------------------------------------------------------------- */
extern const char usage_short[];
extern const char usage_long1[];
extern const char usage_long2[];
extern const char version[];
/* -------------------------------------------------------------------
* settings
* ------------------------------------------------------------------- */
extern const char seperator_line[];
extern const char server_port[];
extern const char client_port[];
extern const char bind_address[];
extern const char multicast_ttl[];
extern const char join_multicast[];
extern const char client_datagram_size[];
extern const char server_datagram_size[];
extern const char tcp_window_size[];
extern const char udp_buffer_size[];
extern const char window_default[];
extern const char wait_server_threads[];
/* -------------------------------------------------------------------
* reports
* ------------------------------------------------------------------- */
extern const char report_read_lengths[];
extern const char report_read_length_times[];
extern const char report_bw_header[];
extern const char report_bw_format[];
extern const char report_sum_bw_format[];
extern const char report_bw_jitter_loss_header[];
extern const char report_bw_jitter_loss_format[];
extern const char report_sum_bw_jitter_loss_format[];
extern const char report_outoforder[];
extern const char report_sum_outoforder[];
extern const char report_peer[];
extern const char report_mss_unsupported[];
extern const char report_mss[];
extern const char report_datagrams[];
extern const char report_sum_datagrams[];
extern const char server_reporting[];
extern const char reportCSV_peer[];
extern const char reportCSV_bw_format[];
extern const char reportCSV_bw_jitter_loss_format[];
/* -------------------------------------------------------------------
* warnings
* ------------------------------------------------------------------- */
extern const char warn_window_requested[];
extern const char warn_window_small[];
extern const char warn_delay_large[];
extern const char warn_no_pathmtu[];
extern const char warn_no_ack[];
extern const char warn_ack_failed[];
extern const char warn_fileopen_failed[];
extern const char unable_to_change_win[];
extern const char opt_estimate[];
extern const char report_interval_small[];
extern const char warn_invalid_server_option[];
extern const char warn_invalid_client_option[];
extern const char warn_invalid_compatibility_option[];
extern const char warn_implied_udp[];
extern const char warn_implied_compatibility[];
extern const char warn_buffer_too_small[];
extern const char warn_invalid_single_threaded[];
extern const char warn_invalid_report_style[];
extern const char warn_invalid_report[];
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif // LOCALE_H

View File

@ -1,2 +0,0 @@
EXTRA_DIST = Client.hpp Condition.h Extractor.h List.h Listener.hpp Locale.h Makefile.am Mutex.h PerfSocket.hpp Reporter.h Server.hpp Settings.hpp SocketAddr.h Thread.h Timestamp.hpp config.win32.h delay.hpp gettimeofday.h gnu_getopt.h headers.h inet_aton.h report_CSV.h report_default.h service.h snprintf.h util.h version.h
DISTCLEANFILES = $(top_builddir)/include/iperf-int.h

View File

@ -1,310 +0,0 @@
# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = include
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \
$(top_srcdir)/m4/ax_create_stdint_h.m4 \
$(top_srcdir)/m4/dast.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
SOURCES =
DIST_SOURCES =
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GREP = @GREP@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
STRIP_BEGIN = @STRIP_BEGIN@
STRIP_DUMMY = @STRIP_DUMMY@
STRIP_END = @STRIP_END@
VERSION = @VERSION@
WEB100_CFLAGS = @WEB100_CFLAGS@
WEB100_CONFIG = @WEB100_CONFIG@
WEB100_LIBS = @WEB100_LIBS@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
acx_pthread_config = @acx_pthread_config@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
EXTRA_DIST = Client.hpp Condition.h Extractor.h List.h Listener.hpp Locale.h Makefile.am Mutex.h PerfSocket.hpp Reporter.h Server.hpp Settings.hpp SocketAddr.h Thread.h Timestamp.hpp config.win32.h delay.hpp gettimeofday.h gnu_getopt.h headers.h inet_aton.h report_CSV.h report_default.h service.h snprintf.h util.h version.h
DISTCLEANFILES = $(top_builddir)/include/iperf-int.h
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --foreign include/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
uninstall-info-am:
tags: TAGS
TAGS:
ctags: CTAGS
CTAGS:
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am:
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am
.PHONY: all all-am check check-am clean clean-generic distclean \
distclean-generic distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-exec \
install-exec-am install-info install-info-am install-man \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \
uninstall-info-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -1,112 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Mutex.h
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* An abstract class for locking a mutex (mutual exclusion). If
* threads are not available, this does nothing.
* ------------------------------------------------------------------- */
#ifndef MUTEX_H
#define MUTEX_H
#include "headers.h"
#if defined( HAVE_POSIX_THREAD )
typedef pthread_mutex_t Mutex;
#elif defined( HAVE_WIN32_THREAD )
typedef HANDLE Mutex;
#else
typedef int Mutex;
#endif
/* ------------------------------------------------------------------- *
class Mutex {
public:*/
// initialize mutex
#if defined( HAVE_POSIX_THREAD )
#define Mutex_Initialize( MutexPtr ) pthread_mutex_init( MutexPtr, NULL )
#elif defined( HAVE_WIN32_THREAD )
#define Mutex_Initialize( MutexPtr ) *MutexPtr = CreateMutex( NULL, false, NULL )
#else
#define Mutex_Initialize( MutexPtr )
#endif
// lock the mutex variable
#if defined( HAVE_POSIX_THREAD )
#define Mutex_Lock( MutexPtr ) pthread_mutex_lock( MutexPtr )
#elif defined( HAVE_WIN32_THREAD )
#define Mutex_Lock( MutexPtr ) WaitForSingleObject( *MutexPtr, INFINITE )
#else
#define Mutex_Lock( MutexPtr )
#endif
// unlock the mutex variable
#if defined( HAVE_POSIX_THREAD )
#define Mutex_Unlock( MutexPtr ) pthread_mutex_unlock( MutexPtr )
#elif defined( HAVE_WIN32_THREAD )
#define Mutex_Unlock( MutexPtr ) ReleaseMutex( *MutexPtr )
#else
#define Mutex_Unlock( MutexPtr )
#endif
// destroy, making sure mutex is unlocked
#if defined( HAVE_POSIX_THREAD )
#define Mutex_Destroy( MutexPtr ) do { \
int rc = pthread_mutex_destroy( MutexPtr ); \
if ( rc == EBUSY ) { \
Mutex_Unlock( MutexPtr ); \
pthread_mutex_destroy( MutexPtr ); \
} \
} while ( 0 )
#elif defined( HAVE_WIN32_THREAD )
#define Mutex_Destroy( MutexPtr ) CloseHandle( *MutexPtr )
#else
#define Mutex_Destroy( MutexPtr )
#endif
#endif // MUTEX_H

View File

@ -1,78 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* PerfSocket.hpp
* by Mark Gates <mgates@nlanr.net>
* & Ajay Tirumala <tirumala@ncsa.uiuc.edu>
* -------------------------------------------------------------------
* Changes in version 1.6
* Incorporates class declarations for fetching data from files
* ------------------------------------------------------------------- */
#ifndef PERFSOCKET_H
#define PERFSOCKET_H
#include "Mutex.h"
#include "Settings.hpp"
void SetSocketOptions( thread_Settings *inSettings );
// handle interupts
void Sig_Interupt( int inSigno );
#ifdef __cplusplus
extern "C" {
#endif
extern int sInterupted;
extern int groupID;
extern Mutex groupCond;
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif // PERFSOCKET_H

View File

@ -1,230 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Reporter.h
* by Kevin Gibbs <kgibbs@nlanr.net>
*
* Since version 2.0 this handles all reporting.
* ________________________________________________________________ */
#ifndef REPORTER_H
#define REPORTER_H
#include "headers.h"
#include "Mutex.h"
struct thread_Settings;
struct server_hdr;
#include "Settings.hpp"
#define NUM_REPORT_STRUCTS 700
#define NUM_MULTI_SLOTS 5
#ifdef __cplusplus
extern "C" {
#endif
/*
* This struct contains all important information from the sending or
* recieving thread.
*/
typedef struct ReportStruct {
int packetID;
max_size_t packetLen;
struct timeval packetTime;
struct timeval sentTime;
} ReportStruct;
/*
* The type field of ReporterData is a bitmask
* with one or more of the following
*/
#define TRANSFER_REPORT 0x00000001
#define SERVER_RELAY_REPORT 0x00000002
#define SETTINGS_REPORT 0x00000004
#define CONNECTION_REPORT 0x00000008
#define MULTIPLE_REPORT 0x00000010
typedef struct Transfer_Info {
void *reserved_delay;
int transferID;
int groupID;
int cntError;
int cntOutofOrder;
int cntDatagrams;
// Hopefully int64_t's
max_size_t TotalLen;
double jitter;
double startTime;
double endTime;
// chars
char mFormat; // -f
u_char mTTL; // -T
char mUDP;
char free;
} Transfer_Info;
typedef struct Connection_Info {
iperf_sockaddr peer;
Socklen_t size_peer;
iperf_sockaddr local;
Socklen_t size_local;
} Connection_Info;
typedef struct ReporterData {
char* mHost; // -c
char* mLocalhost; // -B
// int's
int type;
int cntError;
int lastError;
int cntOutofOrder;
int lastOutofOrder;
int cntDatagrams;
int lastDatagrams;
int PacketID;
int mBufLen; // -l
int mMSS; // -M
int mTCPWin; // -w
/* flags is a BitMask of old bools
bool mBufLenSet; // -l
bool mCompat; // -C
bool mDaemon; // -D
bool mDomain; // -V
bool mFileInput; // -F or -I
bool mNodelay; // -N
bool mPrintMSS; // -m
bool mRemoveService; // -R
bool mStdin; // -I
bool mStdout; // -o
bool mSuggestWin; // -W
bool mUDP;
bool mMode_time;*/
int flags;
// enums (which should be special int's)
ThreadMode mThreadMode; // -s or -c
ReportMode mode;
max_size_t TotalLen;
max_size_t lastTotal;
// doubles
double lastTransit;
// shorts
unsigned short mPort; // -p
// structs or miscellaneous
Transfer_Info info;
Connection_Info connection;
struct timeval startTime;
struct timeval packetTime;
struct timeval nextTime;
struct timeval intervalTime;
} ReporterData;
typedef struct MultiHeader {
int reporterindex;
int agentindex;
int groupID;
int threads;
ReporterData *report;
Transfer_Info *data;
Condition barrier;
struct timeval startTime;
} MultiHeader;
typedef struct ReportHeader {
int reporterindex;
int agentindex;
ReporterData report;
ReportStruct *data;
MultiHeader *multireport;
struct ReportHeader *next;
} ReportHeader;
typedef void* (* report_connection)( Connection_Info*, int );
typedef void (* report_settings)( ReporterData* );
typedef void (* report_statistics)( Transfer_Info* );
typedef void (* report_serverstatistics)( Connection_Info*, Transfer_Info* );
MultiHeader* InitMulti( struct thread_Settings *agent, int inID );
ReportHeader* InitReport( struct thread_Settings *agent );
void ReportPacket( ReportHeader *agent, ReportStruct *packet );
void CloseReport( ReportHeader *agent, ReportStruct *packet );
void EndReport( ReportHeader *agent );
Transfer_Info* GetReport( ReportHeader *agent );
void ReportServerUDP( struct thread_Settings *agent, struct server_hdr *server );
void ReportSettings( struct thread_Settings *agent );
void ReportConnections( struct thread_Settings *agent );
extern report_connection connection_reports[];
extern report_settings settings_reports[];
extern report_statistics statistics_reports[];
extern report_serverstatistics serverstatistics_reports[];
extern report_statistics multiple_reports[];
extern char buffer[64]; // Buffer for printing
#define rMillion 1000000
#define TimeDifference( left, right ) (left.tv_sec - right.tv_sec) + \
(left.tv_usec - right.tv_usec) / ((double) rMillion)
#define TimeAdd( left, right ) do { \
left.tv_usec += right.tv_usec; \
if ( left.tv_usec > rMillion ) { \
left.tv_usec -= rMillion; \
left.tv_sec++; \
} \
left.tv_sec += right.tv_sec; \
} while ( 0 )
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif // REPORTER_H

View File

@ -1,85 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Server.hpp
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* A server thread is initiated for each connection accept() returns.
* Handles sending and receiving data, and then closes socket.
* ------------------------------------------------------------------- */
#ifndef SERVER_H
#define SERVER_H
#include "Settings.hpp"
#include "util.h"
#include "Timestamp.hpp"
/* ------------------------------------------------------------------- */
class Server {
public:
// stores server socket, port and TCP/UDP mode
Server( thread_Settings *inSettings );
// destroy the server object
~Server();
// accepts connection and receives data
void Run( void );
void write_UDP_AckFIN( );
static void Sig_Int( int inSigno );
private:
thread_Settings *mSettings;
char* mBuf;
Timestamp mEndTime;
}; // end class Server
#endif // SERVER_H

View File

@ -1,425 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Settings.hpp
* by Mark Gates <mgates@nlanr.net>
* & Ajay Tirumala <tirumala@ncsa.uiuc.edu>
* -------------------------------------------------------------------
* Stores and parses the initial values for all the global variables.
* -------------------------------------------------------------------
* headers
* uses
* <stdlib.h>
* <assert.h>
* ------------------------------------------------------------------- */
#ifndef SETTINGS_H
#define SETTINGS_H
#include "headers.h"
#include "Thread.h"
/* -------------------------------------------------------------------
* constants
* ------------------------------------------------------------------- */
#ifdef __cplusplus
extern "C" {
#endif
// server/client mode
typedef enum ThreadMode {
kMode_Unknown = 0,
kMode_Server,
kMode_Client,
kMode_Reporter,
kMode_Listener
} ThreadMode;
// report mode
typedef enum ReportMode {
kReport_Default = 0,
kReport_CSV,
//kReport_XML,
kReport_MAXIMUM
} ReportMode;
// test mode
typedef enum TestMode {
kTest_Normal = 0,
kTest_DualTest,
kTest_TradeOff,
kTest_Unknown
} TestMode;
#include "Reporter.h"
/*
* The thread_Settings is a structure that holds all
* options for a given execution of either a client
* or server. By using this structure rather than
* a global structure or class we can have multiple
* clients or servers running with different settings.
* In version 2.0 and above this structure contains
* all the information needed for a thread to execute
* and contains only C elements so it can be manipulated
* by either C or C++.
*/
typedef struct thread_Settings {
// Pointers
char* mFileName; // -F
char* mHost; // -c
char* mLocalhost; // -B
char* mOutputFileName; // -o
FILE* Extractor_file;
ReportHeader* reporthdr;
MultiHeader* multihdr;
struct thread_Settings *runNow;
struct thread_Settings *runNext;
// int's
int mThreads; // -P
int mTOS; // -S
int mSock;
int Extractor_size;
int mBufLen; // -l
int mMSS; // -M
int mTCPWin; // -w
/* flags is a BitMask of old bools
bool mBufLenSet; // -l
bool mCompat; // -C
bool mDaemon; // -D
bool mDomain; // -V
bool mFileInput; // -F or -I
bool mNodelay; // -N
bool mPrintMSS; // -m
bool mRemoveService; // -R
bool mStdin; // -I
bool mStdout; // -o
bool mSuggestWin; // -W
bool mUDP; // -u
bool mMode_time;
bool mReportSettings;
bool mMulticast;
bool mNoSettingsReport; // -x s
bool mNoConnectionReport; // -x c
bool mNoDataReport; // -x d
bool mNoServerReport; // -x
bool mNoMultReport; // -x m
bool mSinlgeClient; // -1 */
int flags;
// enums (which should be special int's)
ThreadMode mThreadMode; // -s or -c
ReportMode mReportMode;
TestMode mMode; // -r or -d
// Hopefully int64_t's
max_size_t mUDPRate; // -b or -u
max_size_t mAmount; // -n or -t
// doubles
double mInterval; // -i
// shorts
unsigned short mListenPort; // -L
unsigned short mPort; // -p
// chars
char mFormat; // -f
int mTTL; // -T
char pad1[2];
// structs or miscellaneous
iperf_sockaddr peer;
Socklen_t size_peer;
iperf_sockaddr local;
Socklen_t size_local;
nthread_t mTID;
char* mCongestion;
#if defined( HAVE_WIN32_THREAD )
HANDLE mHandle;
#endif
} thread_Settings;
/*
* Due to the use of thread_Settings in C and C++
* we are unable to use bool values. To provide
* the functionality of bools we use the following
* bitmask over an assumed 32 bit int. This will
* work fine on 64bit machines we will just be ignoring
* the upper 32bits.
*
* To add a flag simply define it as the next bit then
* add the 3 support functions below.
*/
#define FLAG_BUFLENSET 0x00000001
#define FLAG_COMPAT 0x00000002
#define FLAG_DAEMON 0x00000004
#define FLAG_DOMAIN 0x00000008
#define FLAG_FILEINPUT 0x00000010
#define FLAG_NODELAY 0x00000020
#define FLAG_PRINTMSS 0x00000040
#define FLAG_REMOVESERVICE 0x00000080
#define FLAG_STDIN 0x00000100
#define FLAG_STDOUT 0x00000200
#define FLAG_SUGGESTWIN 0x00000400
#define FLAG_UDP 0x00000800
#define FLAG_MODETIME 0x00001000
#define FLAG_REPORTSETTINGS 0x00002000
#define FLAG_MULTICAST 0x00004000
#define FLAG_NOSETTREPORT 0x00008000
#define FLAG_NOCONNREPORT 0x00010000
#define FLAG_NODATAREPORT 0x00020000
#define FLAG_NOSERVREPORT 0x00040000
#define FLAG_NOMULTREPORT 0x00080000
#define FLAG_SINGLECLIENT 0x00100000
#define FLAG_SINGLEUDP 0x00200000
#define FLAG_CONGESTION 0x00400000
#define isBuflenSet(settings) ((settings->flags & FLAG_BUFLENSET) != 0)
#define isCompat(settings) ((settings->flags & FLAG_COMPAT) != 0)
#define isDaemon(settings) ((settings->flags & FLAG_DAEMON) != 0)
#define isIPV6(settings) ((settings->flags & FLAG_DOMAIN) != 0)
#define isFileInput(settings) ((settings->flags & FLAG_FILEINPUT) != 0)
#define isNoDelay(settings) ((settings->flags & FLAG_NODELAY) != 0)
#define isPrintMSS(settings) ((settings->flags & FLAG_PRINTMSS) != 0)
#define isRemoveService(settings) ((settings->flags & FLAG_REMOVESERVICE) != 0)
#define isSTDIN(settings) ((settings->flags & FLAG_STDIN) != 0)
#define isSTDOUT(settings) ((settings->flags & FLAG_STDOUT) != 0)
#define isSuggestWin(settings) ((settings->flags & FLAG_SUGGESTWIN) != 0)
#define isUDP(settings) ((settings->flags & FLAG_UDP) != 0)
#define isModeTime(settings) ((settings->flags & FLAG_MODETIME) != 0)
#define isReport(settings) ((settings->flags & FLAG_REPORTSETTINGS) != 0)
#define isMulticast(settings) ((settings->flags & FLAG_MULTICAST) != 0)
// Active Low for Reports
#define isSettingsReport(settings) ((settings->flags & FLAG_NOSETTREPORT) == 0)
#define isConnectionReport(settings) ((settings->flags & FLAG_NOCONNREPORT) == 0)
#define isDataReport(settings) ((settings->flags & FLAG_NODATAREPORT) == 0)
#define isServerReport(settings) ((settings->flags & FLAG_NOSERVREPORT) == 0)
#define isMultipleReport(settings) ((settings->flags & FLAG_NOMULTREPORT) == 0)
// end Active Low
#define isSingleClient(settings) ((settings->flags & FLAG_SINGLECLIENT) != 0)
#define isSingleUDP(settings) ((settings->flags & FLAG_SINGLEUDP) != 0)
#define isCongestionControl(settings) ((settings->flags & FLAG_CONGESTION) != 0)
#define setBuflenSet(settings) settings->flags |= FLAG_BUFLENSET
#define setCompat(settings) settings->flags |= FLAG_COMPAT
#define setDaemon(settings) settings->flags |= FLAG_DAEMON
#define setIPV6(settings) settings->flags |= FLAG_DOMAIN
#define setFileInput(settings) settings->flags |= FLAG_FILEINPUT
#define setNoDelay(settings) settings->flags |= FLAG_NODELAY
#define setPrintMSS(settings) settings->flags |= FLAG_PRINTMSS
#define setRemoveService(settings) settings->flags |= FLAG_REMOVESERVICE
#define setSTDIN(settings) settings->flags |= FLAG_STDIN
#define setSTDOUT(settings) settings->flags |= FLAG_STDOUT
#define setSuggestWin(settings) settings->flags |= FLAG_SUGGESTWIN
#define setUDP(settings) settings->flags |= FLAG_UDP
#define setModeTime(settings) settings->flags |= FLAG_MODETIME
#define setReport(settings) settings->flags |= FLAG_REPORTSETTINGS
#define setMulticast(settings) settings->flags |= FLAG_MULTICAST
#define setNoSettReport(settings) settings->flags |= FLAG_NOSETTREPORT
#define setNoConnReport(settings) settings->flags |= FLAG_NOCONNREPORT
#define setNoDataReport(settings) settings->flags |= FLAG_NODATAREPORT
#define setNoServReport(settings) settings->flags |= FLAG_NOSERVREPORT
#define setNoMultReport(settings) settings->flags |= FLAG_NOMULTREPORT
#define setSingleClient(settings) settings->flags |= FLAG_SINGLECLIENT
#define setSingleUDP(settings) settings->flags |= FLAG_SINGLEUDP
#define setCongestionControl(settings) settings->flags |= FLAG_CONGESTION
#define unsetBuflenSet(settings) settings->flags &= ~FLAG_BUFLENSET
#define unsetCompat(settings) settings->flags &= ~FLAG_COMPAT
#define unsetDaemon(settings) settings->flags &= ~FLAG_DAEMON
#define unsetIPV6(settings) settings->flags &= ~FLAG_DOMAIN
#define unsetFileInput(settings) settings->flags &= ~FLAG_FILEINPUT
#define unsetNoDelay(settings) settings->flags &= ~FLAG_NODELAY
#define unsetPrintMSS(settings) settings->flags &= ~FLAG_PRINTMSS
#define unsetRemoveService(settings) settings->flags &= ~FLAG_REMOVESERVICE
#define unsetSTDIN(settings) settings->flags &= ~FLAG_STDIN
#define unsetSTDOUT(settings) settings->flags &= ~FLAG_STDOUT
#define unsetSuggestWin(settings) settings->flags &= ~FLAG_SUGGESTWIN
#define unsetUDP(settings) settings->flags &= ~FLAG_UDP
#define unsetModeTime(settings) settings->flags &= ~FLAG_MODETIME
#define unsetReport(settings) settings->flags &= ~FLAG_REPORTSETTINGS
#define unsetMulticast(settings) settings->flags &= ~FLAG_MULTICAST
#define unsetNoSettReport(settings) settings->flags &= ~FLAG_NOSETTREPORT
#define unsetNoConnReport(settings) settings->flags &= ~FLAG_NOCONNREPORT
#define unsetNoDataReport(settings) settings->flags &= ~FLAG_NODATAREPORT
#define unsetNoServReport(settings) settings->flags &= ~FLAG_NOSERVREPORT
#define unsetNoMultReport(settings) settings->flags &= ~FLAG_NOMULTREPORT
#define unsetSingleClient(settings) settings->flags &= ~FLAG_SINGLECLIENT
#define unsetSingleUDP(settings) settings->flags &= ~FLAG_SINGLEUDP
#define unsetCongestionControl(settings) settings->flags &= ~FLAG_CONGESTION
#define HEADER_VERSION1 0x80000000
#define RUN_NOW 0x00000001
// used to reference the 4 byte ID number we place in UDP datagrams
// use int32_t if possible, otherwise a 32 bit bitfield (e.g. on J90)
typedef struct UDP_datagram {
#ifdef HAVE_INT32_T
int32_t id;
u_int32_t tv_sec;
u_int32_t tv_usec;
#else
signed int id : 32;
unsigned int tv_sec : 32;
unsigned int tv_usec : 32;
#endif
} UDP_datagram;
/*
* The client_hdr structure is sent from clients
* to servers to alert them of things that need
* to happen. Order must be perserved in all
* future releases for backward compatibility.
* 1.7 has flags, numThreads, mPort, and bufferlen
*/
typedef struct client_hdr {
#ifdef HAVE_INT32_T
/*
* flags is a bitmap for different options
* the most significant bits are for determining
* which information is available. So 1.7 uses
* 0x80000000 and the next time information is added
* the 1.7 bit will be set and 0x40000000 will be
* set signifying additional information. If no
* information bits are set then the header is ignored.
* The lowest order diferentiates between dualtest and
* tradeoff modes, wheither the speaker needs to start
* immediately or after the audience finishes.
*/
int32_t flags;
int32_t numThreads;
int32_t mPort;
int32_t bufferlen;
int32_t mWinBand;
int32_t mAmount;
#else
signed int flags : 32;
signed int numThreads : 32;
signed int mPort : 32;
signed int bufferlen : 32;
signed int mWinBand : 32;
signed int mAmount : 32;
#endif
} client_hdr;
/*
* The server_hdr structure facilitates the server
* report of jitter and loss on the client side.
* It piggy_backs on the existing clear to close
* packet.
*/
typedef struct server_hdr {
#ifdef HAVE_INT32_T
/*
* flags is a bitmap for different options
* the most significant bits are for determining
* which information is available. So 1.7 uses
* 0x80000000 and the next time information is added
* the 1.7 bit will be set and 0x40000000 will be
* set signifying additional information. If no
* information bits are set then the header is ignored.
*/
int32_t flags;
int32_t total_len1;
int32_t total_len2;
int32_t stop_sec;
int32_t stop_usec;
int32_t error_cnt;
int32_t outorder_cnt;
int32_t datagrams;
int32_t jitter1;
int32_t jitter2;
#else
signed int flags : 32;
signed int total_len1 : 32;
signed int total_len2 : 32;
signed int stop_sec : 32;
signed int stop_usec : 32;
signed int error_cnt : 32;
signed int outorder_cnt : 32;
signed int datagrams : 32;
signed int jitter1 : 32;
signed int jitter2 : 32;
#endif
} server_hdr;
// set to defaults
void Settings_Initialize( thread_Settings* main );
// copy structure
void Settings_Copy( thread_Settings* from, thread_Settings** into );
// free associated memory
void Settings_Destroy( thread_Settings *mSettings );
// parse settings from user's environment variables
void Settings_ParseEnvironment( thread_Settings *mSettings );
// parse settings from app's command line
void Settings_ParseCommandLine( int argc, char **argv, thread_Settings *mSettings );
// convert to lower case for [KMG]bits/sec
void Settings_GetLowerCaseArg(const char *,char *);
// convert to upper case for [KMG]bytes/sec
void Settings_GetUpperCaseArg(const char *,char *);
// generate settings for listener instance
void Settings_GenerateListenerSettings( thread_Settings *client, thread_Settings **listener);
// generate settings for speaker instance
void Settings_GenerateClientSettings( thread_Settings *server,
thread_Settings **client,
client_hdr *hdr );
// generate client header for server
void Settings_GenerateClientHdr( thread_Settings *client, client_hdr *hdr );
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif // SETTINGS_H

View File

@ -1,104 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Socket.cpp
* by Ajay Tirumala <tirumala@ncsa.uiuc.edu>
* and Mark Gates <mgates@nlanr.net>
* ------------------------------------------------------------------- */
#ifndef SOCKET_ADDR_H
#define SOCKET_ADDR_H
#include "headers.h"
#include "Settings.hpp"
#ifdef __cplusplus
extern "C" {
#endif
/* ------------------------------------------------------------------- */
void SockAddr_localAddr( thread_Settings *inSettings );
void SockAddr_remoteAddr( thread_Settings *inSettings );
void SockAddr_setHostname( const char* inHostname,
iperf_sockaddr *inSockAddr,
int isIPv6 ); // DNS lookup
void SockAddr_getHostname( iperf_sockaddr *inSockAddr,
char* outHostname,
size_t len ); // reverse DNS lookup
void SockAddr_getHostAddress( iperf_sockaddr *inSockAddr,
char* outAddress,
size_t len ); // dotted decimal
void SockAddr_setPort( iperf_sockaddr *inSockAddr, unsigned short inPort );
void SockAddr_setPortAny( iperf_sockaddr *inSockAddr );
unsigned short SockAddr_getPort( iperf_sockaddr *inSockAddr );
void SockAddr_setAddressAny( iperf_sockaddr *inSockAddr );
// return pointer to the struct in_addr
struct in_addr* SockAddr_get_in_addr( iperf_sockaddr *inSockAddr );
#ifdef HAVE_IPV6
// return pointer to the struct in_addr
struct in6_addr* SockAddr_get_in6_addr( iperf_sockaddr *inSockAddr );
#endif
// return the sizeof the addess structure (struct sockaddr_in)
Socklen_t SockAddr_get_sizeof_sockaddr( iperf_sockaddr *inSockAddr );
int SockAddr_isMulticast( iperf_sockaddr *inSockAddr );
int SockAddr_isIPv6( iperf_sockaddr *inSockAddr );
int SockAddr_are_Equal( struct sockaddr *first, struct sockaddr *second );
int SockAddr_Hostare_Equal( struct sockaddr *first, struct sockaddr *second );
void SockAddr_zeroAddress( iperf_sockaddr *inSockAddr );
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif /* SOCKET_ADDR_H */

View File

@ -1,159 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Thread.h
* by Kevin Gibbs <kgibbs@nlanr.net>
*
* Based on:
* Thread.hpp
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* The thread subsystem is responsible for all thread functions. It
* provides a thread implementation agnostic interface to Iperf. If
* threads are not available (HAVE_THREAD is undefined), thread_start
* does not start a new thread but just launches the specified object
* in the current thread. Everything that defines a thread of
* execution in Iperf is contained in an thread_Settings structure. To
* start a thread simply pass one such structure into thread_start.
* ------------------------------------------------------------------- */
#ifndef THREAD_H
#define THREAD_H
#ifdef __cplusplus
extern "C" {
#endif
#if defined( HAVE_POSIX_THREAD )
/* Definitions for Posix Threads (pthreads) */
#include <pthread.h>
typedef pthread_t nthread_t;
#define HAVE_THREAD 1
#elif defined( HAVE_WIN32_THREAD )
/* Definitions for Win32 NT Threads */
typedef DWORD nthread_t;
#define HAVE_THREAD 1
#else
/* Definitions for no threads */
typedef int nthread_t;
#undef HAVE_THREAD
#endif
// Forward declaration
struct thread_Settings;
#include "Condition.h"
#include "Settings.hpp"
// initialize or destroy the thread subsystem
void thread_init( );
void thread_destroy( );
// start or stop a thread executing
void thread_start( struct thread_Settings* thread );
void thread_stop( struct thread_Settings* thread );
/* wait for this or all threads to complete */
void thread_joinall( void );
int thread_numuserthreads( void );
// set a thread to be ignorable, so joinall won't wait on it
void thread_setignore( void );
void thread_unsetignore( void );
// Used for threads that may never terminate (ie Listener Thread)
void thread_register_nonterm( void );
void thread_unregister_nonterm( void );
int thread_release_nonterm( int force );
/* -------------------------------------------------------------------
* Return the current thread's ID.
* ------------------------------------------------------------------- */
#if defined( HAVE_POSIX_THREAD )
#define thread_getid() pthread_self()
#elif defined( HAVE_WIN32_THREAD )
#define thread_getid() GetCurrentThreadId()
#else
#define thread_getid() 0
#endif
int thread_equalid( nthread_t inLeft, nthread_t inRight );
nthread_t thread_zeroid( void );
#if defined( HAVE_WIN32_THREAD )
DWORD WINAPI thread_run_wrapper( void* paramPtr );
#else
void* thread_run_wrapper( void* paramPtr );
#endif
void thread_rest ( void );
// defined in launch.cpp
void server_spawn( struct thread_Settings* thread );
void client_spawn( struct thread_Settings* thread );
void client_init( struct thread_Settings* clients );
void listener_spawn( struct thread_Settings* thread );
// defined in reporter.c
void reporter_spawn( struct thread_Settings* thread );
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif // THREAD_H

View File

@ -1,255 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Timestamp.hpp
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* A generic interface to a timestamp.
* This implementation uses the unix gettimeofday().
* -------------------------------------------------------------------
* headers
* uses
* <sys/types.h>
* <sys/time.h>
* <unistd.h>
* ------------------------------------------------------------------- */
#ifndef TIMESTAMP_H
#define TIMESTAMP_H
#include "headers.h"
/* ------------------------------------------------------------------- */
class Timestamp {
public:
/* -------------------------------------------------------------------
* Create a timestamp, with the current time in it.
* ------------------------------------------------------------------- */
Timestamp( void ) {
setnow();
}
/* -------------------------------------------------------------------
* Create a timestamp, with the given seconds/microseconds
* ------------------------------------------------------------------- */
Timestamp( long sec, long usec ) {
set( sec, usec );
}
/* -------------------------------------------------------------------
* Create a timestamp, with the given seconds
* ------------------------------------------------------------------- */
Timestamp( double sec ) {
set( sec );
}
/* -------------------------------------------------------------------
* Set timestamp to current time.
* ------------------------------------------------------------------- */
void setnow( void ) {
gettimeofday( &mTime, NULL );
}
/* -------------------------------------------------------------------
* Set timestamp to the given seconds/microseconds
* ------------------------------------------------------------------- */
void set( long sec, long usec ) {
assert( sec >= 0 );
assert( usec >= 0 && usec < kMillion );
mTime.tv_sec = sec;
mTime.tv_usec = usec;
}
/* -------------------------------------------------------------------
* Set timestamp to the given seconds
* ------------------------------------------------------------------- */
void set( double sec ) {
mTime.tv_sec = (long) sec;
mTime.tv_usec = (long) ((sec - mTime.tv_sec) * kMillion);
}
/* -------------------------------------------------------------------
* return seconds portion of timestamp
* ------------------------------------------------------------------- */
long getSecs( void ) {
return mTime.tv_sec;
}
/* -------------------------------------------------------------------
* return microseconds portion of timestamp
* ------------------------------------------------------------------- */
long getUsecs( void ) {
return mTime.tv_usec;
}
/* -------------------------------------------------------------------
* return timestamp as a floating point seconds
* ------------------------------------------------------------------- */
double get( void ) {
return mTime.tv_sec + mTime.tv_usec / ((double) kMillion);
}
/* -------------------------------------------------------------------
* subtract the right timestamp from my timestamp.
* return the difference in microseconds.
* ------------------------------------------------------------------- */
long subUsec( Timestamp right ) {
return(mTime.tv_sec - right.mTime.tv_sec) * kMillion +
(mTime.tv_usec - right.mTime.tv_usec);
}
/* -------------------------------------------------------------------
* subtract the right timestamp from my timestamp.
* return the difference in microseconds.
* ------------------------------------------------------------------- */
long subUsec( timeval right ) {
return(mTime.tv_sec - right.tv_sec) * kMillion +
(mTime.tv_usec - right.tv_usec);
}
/* -------------------------------------------------------------------
* Return the number of microseconds from now to last time of setting.
* ------------------------------------------------------------------- */
long delta_usec(void) {
struct timeval previous = mTime;
setnow();
return subUsec(previous);
}
/* -------------------------------------------------------------------
* subtract the right timestamp from my timestamp.
* return the difference in seconds as a floating point.
* ------------------------------------------------------------------- */
double subSec( Timestamp right ) {
return(mTime.tv_sec - right.mTime.tv_sec) +
(mTime.tv_usec - right.mTime.tv_usec) / ((double) kMillion);
}
/* -------------------------------------------------------------------
* add the right timestamp to my timestamp.
* ------------------------------------------------------------------- */
void add( Timestamp right ) {
mTime.tv_sec += right.mTime.tv_sec;
mTime.tv_usec += right.mTime.tv_usec;
// watch for under- and overflow
if ( mTime.tv_usec < 0 ) {
mTime.tv_usec += kMillion;
mTime.tv_sec--;
}
if ( mTime.tv_usec >= kMillion ) {
mTime.tv_usec -= kMillion;
mTime.tv_sec++;
}
assert( mTime.tv_usec >= 0 &&
mTime.tv_usec < kMillion );
}
/* -------------------------------------------------------------------
* add the seconds to my timestamp.
* TODO optimize?
* ------------------------------------------------------------------- */
void add( double sec ) {
mTime.tv_sec += (long) sec;
mTime.tv_usec += (long) ((sec - ((long) sec )) * kMillion);
// watch for overflow
if ( mTime.tv_usec >= kMillion ) {
mTime.tv_usec -= kMillion;
mTime.tv_sec++;
}
assert( mTime.tv_usec >= 0 &&
mTime.tv_usec < kMillion );
}
/* -------------------------------------------------------------------
* return true if my timestamp is before the right timestamp.
* ------------------------------------------------------------------- */
bool before( timeval right ) {
return mTime.tv_sec < right.tv_sec ||
(mTime.tv_sec == right.tv_sec &&
mTime.tv_usec < right.tv_usec);
}
bool before( Timestamp right ) { return before(right.mTime); }
/* -------------------------------------------------------------------
* return true if my timestamp is after the right timestamp.
* ------------------------------------------------------------------- */
bool after( timeval right ) {
return mTime.tv_sec > right.tv_sec ||
(mTime.tv_sec == right.tv_sec &&
mTime.tv_usec > right.tv_usec);
}
bool after( Timestamp right ) { return after(right.mTime); }
/**
* This function returns the fraction of time elapsed after the beginning
* till the end
*/
double fraction(Timestamp currentTime, Timestamp endTime) {
if ( (currentTime.after(*this)) && (endTime.after(currentTime)) ) {
return(((double)currentTime.subUsec(*this)) /
((double)endTime.subUsec(*this)));
} else {
return -1.0;
}
}
protected:
enum {
kMillion = 1000000
};
struct timeval mTime;
}; // end class Timestamp
#endif // TIMESTAMP_H

View File

@ -1,82 +0,0 @@
/* config.h. Generated by hand for Windows. */
#ifndef CONFIG_H
#define CONFIG_H
/* ===================================================================
* config.h
*
* config.h is derived from config.h.in -- do not edit config.h
*
* This contains variables that the configure script checks and
* then defines or undefines. The source code checks for these
* variables to know if certain features are present.
*
* by Mark Gates <mgates@nlanr.net>
*
* Copyright 1999 The Board of Trustees of the University of Illinois
* All rights reserved. See doc/license.txt for complete text.
*
* $Id: config.win32.h,v 1.1.1.1 2004/05/18 01:50:44 kgibbs Exp $
* =================================================================== */
/* Define if threads exist (using pthreads or Win32 threads) */
/* #undef HAVE_POSIX_THREAD */
#define HAVE_WIN32_THREAD 1
/* #undef _REENTRANT */
/* Define if on OSF1 and need special extern "C" around some header files */
/* #undef SPECIAL_OSF1_EXTERN */
/* Define if the strings.h header file exists */
/* #undef HAVE_STRINGS_H */
/* Define the intXX_t, u_intXX_t, size_t, ssize_t, and socklen_t types */
/* On the Cray J90 there is no 4 byte integer, so we define int32_t
* but it is 8 bytes, and we leave HAVE_INT32_T undefined. */
#define SIZEOF_INT 4
#define HAVE_U_INT16_T 1
#define HAVE_INT32_T 1
#define HAVE_INT64_T 1
#define HAVE_U_INT32_T 1
#define int32_t LONG32
#define u_int16_t UINT16
#define u_int32_t ULONG32
/* #undef size_t */
#define ssize_t int
/* socklen_t usually defined in <sys/socket.h>. Unfortunately it doesn't
* work on some systems (like DEC OSF/1), so we'll use our own Socklen_t */
#define Socklen_t int
/* Define if you have these functions. */
#define HAVE_SNPRINTF 1
/* #undef HAVE_INET_PTON */
/* #undef HAVE_INET_NTOP */
/* #undef HAVE_GETTIMEOFDAY */
/* #undef HAVE_PTHREAD_CANCEL */
#define HAVE_USLEEP 1
/* #undef HAVE_QUAD_SUPPORT */
/* #undef HAVE_PRINTF_QD */
/* standard C++, which isn't always... */
/* #undef bool */
#define true 1
#define false 0
/* Define if the host is Big Endian (network byte order) */
/* #undef WORDS_BIGENDIAN */
/* Define if multicast support exists */
#define HAVE_MULTICAST 1
/* Define if all IPv6 headers/structures are present */
#define HAVE_IPV6 1
/* Define if IPv6 multicast support exists */
#define HAVE_IPV6_MULTICAST 1
/* Define if Debugging of sockets is desired */
/* #undef DBG_MJZ */
#endif /* CONFIG_H */

View File

@ -1,58 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* delay.hpp
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* accurate microsecond delay
* ------------------------------------------------------------------- */
#ifndef DELAY_H
#define DELAY_H
void delay_loop( unsigned long usecs );
#endif /* DELAY_H */

View File

@ -1,81 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* gettimeofday.h
*
* Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* An implementation of gettimeofday for Windows.
* ------------------------------------------------------------------- */
#ifndef GETTIMEOFDAY_H
#define GETTIMEOFDAY_H
#ifndef HAVE_GETTIMEOFDAY
#ifdef __cplusplus
extern "C" {
#endif
int gettimeofday( struct timeval* tv, void* timezone );
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif /* HAVE_GETTIMEOFDAY */
#endif /* GETTIMEOFDAY_H */

View File

@ -1,136 +0,0 @@
/* Declarations for gnu_getopt.
Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc.
This file is part of the GNU C Library. Its master source is NOT part of
the C library, however. The master source lives in /gd/gnu/lib.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/*
* modified July 9, 1999 by mark gates <mgates@nlanr.net>
* Dec 17, 1999
*
* renamed all functions and variables by prepending "gnu_"
* removed/redid a bunch of stuff under the assumption we're
* using a modern standard C compiler.
*
* $Id: gnu_getopt.h,v 1.1.1.1 2004/05/18 01:50:44 kgibbs Exp $
*/
#ifndef _GETOPT_H
#define _GETOPT_H 1
#ifdef __cplusplus
extern "C" {
#endif
/* For communication from `gnu_getopt' to the caller.
When `gnu_getopt' finds an option that takes an argument,
the argument value is returned here.
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
extern char *gnu_optarg;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
and for communication between successive calls to `gnu_getopt'.
On entry to `gnu_getopt', zero means this is the first call; initialize.
When `gnu_getopt' returns -1, this is the index of the first of the
non-option elements that the caller should itself scan.
Otherwise, `gnu_optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
extern int gnu_optind;
/* Callers store zero here to inhibit the error message `gnu_getopt' prints
for unrecognized options. */
extern int gnu_opterr;
/* Set to an option character which was unrecognized. */
extern int gnu_optopt;
/* Describe the long-named options requested by the application.
The LONG_OPTIONS argument to gnu_getopt_long or getopt_long_only is a vector
of `struct option' terminated by an element containing a name which is
zero.
The field `has_arg' is:
no_argument (or 0) if the option does not take an argument,
required_argument (or 1) if the option requires an argument,
optional_argument (or 2) if the option takes an optional argument.
If the field `flag' is not NULL, it points to a variable that is set
to the value given in the field `val' when the option is found, but
left unchanged if the option is not found.
To have a long-named option do something other than set an `int' to
a compiled-in constant, such as set a value from `gnu_optarg', set the
option's `flag' field to zero and its `val' field to a nonzero
value (the equivalent single-letter option character, if there is
one). For long options that have a zero `flag' field, `gnu_getopt'
returns the contents of the `val' field. */
/* has_arg can't be an enum because some compilers complain about
type mismatches in all the code that assumes it is an int. */
struct option {
const char *name;
int has_arg;
int *flag;
int val;
};
/* Names for the values of the `has_arg' field of `struct option'. */
#define no_argument 0
#define required_argument 1
#define optional_argument 2
int gnu_getopt( int argc,
char *const *argv,
const char *shortopts );
int gnu_getopt_long( int argc,
char *const *argv,
const char *shortopts,
const struct option *longopts,
int *longind );
int gnu_getopt_long_only( int argc,
char *const *argv,
const char *shortopts,
const struct option *longopts,
int *longind );
/* Internal only. Users should not call this directly. */
int _gnu_getopt_internal( int argc,
char *const *argv,
const char *shortopts,
const struct option *longopts,
int *longind,
int long_only );
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif /* _GETOPT_H */

View File

@ -1,202 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* headers.h
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* All system headers required by iperf.
* This could be processed to form a single precompiled header,
* to avoid overhead of compiling it multiple times.
* This also verifies a few things are defined, for portability.
* ------------------------------------------------------------------- */
#ifndef HEADERS_H
#define HEADERS_H
#ifdef HAVE_CONFIG_H
#include "config.h"
/* OSF1 (at least the system I use) needs extern C
* around the <netdb.h> and <arpa/inet.h> files. */
#if defined( SPECIAL_OSF1_EXTERN ) && defined( __cplusplus )
#define SPECIAL_OSF1_EXTERN_C_START extern "C" {
#define SPECIAL_OSF1_EXTERN_C_STOP }
#else
#define SPECIAL_OSF1_EXTERN_C_START
#define SPECIAL_OSF1_EXTERN_C_STOP
#endif
#endif /* HAVE_CONFIG_H */
/* turn off assert debugging */
#define NDEBUG
/* standard C headers */
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <math.h>
#ifdef WIN32
/* Windows config file */
#include "config.win32.h"
/* Windows headers */
#define _WIN32_WINNT 0x0400 /* use (at least) WinNT 4.0 API */
#define WIN32_LEAN_AND_MEAN /* exclude unnecesary headers */
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
/* define EINTR, just to help compile; it isn't useful */
#ifndef EINTR
#define EINTR WSAEINTR
#endif // EINTR
/* Visual C++ has INT64, but not 'long long'.
* Metrowerks has 'long long', but INT64 doesn't work. */
#ifdef __MWERKS__
#define int64_t long long
#else
#define int64_t INT64
#endif // __MWERKS__
/* Visual C++ has _snprintf instead of snprintf */
#ifndef __MWERKS__
#define snprintf _snprintf
#endif // __MWERKS__
/* close, read, and write only work on files in Windows.
* I get away with #defining them because I don't read files. */
#define close( s ) closesocket( s )
#define read( s, b, l ) recv( s, (char*) b, l, 0 )
#define write( s, b, l ) send( s, (char*) b, l, 0 )
#else /* not defined WIN32 */
/* required on AIX for FD_SET (requires bzero).
* often this is the same as <string.h> */
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif // HAVE_STRINGS_H
/* unix headers */
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <signal.h>
#include <unistd.h>
/** Added for daemonizing the process */
#include <syslog.h>
SPECIAL_OSF1_EXTERN_C_START
#include <netdb.h>
SPECIAL_OSF1_EXTERN_C_STOP
#include <netinet/in.h>
#include <netinet/tcp.h>
SPECIAL_OSF1_EXTERN_C_START
#include <arpa/inet.h> /* netinet/in.h must be before this on SunOS */
SPECIAL_OSF1_EXTERN_C_STOP
#ifdef HAVE_POSIX_THREAD
#include <pthread.h>
#endif // HAVE_POSIX_THREAD
/* used in Win32 for error checking,
* rather than checking rc < 0 as unix usually does */
#define SOCKET_ERROR -1
#define INVALID_SOCKET -1
#endif /* not defined WIN32 */
#ifndef INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN 40
#endif
#ifndef INET_ADDRSTRLEN
#define INET_ADDRSTRLEN 15
#endif
//#ifdef __cplusplus
#ifdef HAVE_IPV6
#define REPORT_ADDRLEN (INET6_ADDRSTRLEN + 1)
typedef struct sockaddr_storage iperf_sockaddr;
#else
#define REPORT_ADDRLEN (INET_ADDRSTRLEN + 1)
typedef struct sockaddr_in iperf_sockaddr;
#endif
//#endif
// Rationalize stdint definitions and sizeof, thanks to ac_create_stdint_h.m4
// from the gnu archive
#include <iperf-int.h>
typedef uint64_t max_size_t;
/* in case the OS doesn't have these, we provide our own implementations */
#include "gettimeofday.h"
#include "inet_aton.h"
#include "snprintf.h"
#ifndef SHUT_RD
#define SHUT_RD 0
#define SHUT_WR 1
#define SHUT_RDWR 2
#endif // SHUT_RD
#endif /* HEADERS_H */

View File

@ -1,105 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* inet_aton.h
*
* Mark Gates <mgates@nlanr.net>
* Kevin Gibbs <kgibbs@ncsa.uiuc.edu> Sept. 2002
* to use this prototype, make sure HAVE_INET_PTON is not defined
* to use this prototype, make sure HAVE_INET_NTOP is not defined
*
* =================================================================== */
#ifndef INET_ATON_H
#define INET_ATON_H
#include "headers.h"
/*
* inet_pton is the new, better version of inet_aton.
* inet_aton is not IP version agnostic.
* inet_aton is the new, better version of inet_addr.
* inet_addr is incorrect in that it returns -1 as an error value,
* while -1 (0xFFFFFFFF) is a valid IP address (255.255.255.255).
*/
#ifndef HAVE_INET_NTOP
#ifdef __cplusplus
extern "C" {
#endif
int inet_ntop(int af, const void *src, char *dst, size_t size);
int inet_ntop4(const unsigned char *src, char *dst,
size_t size);
#ifdef HAVE_IPV6
int inet_ntop6(const unsigned char *src, char *dst,
size_t size);
#endif
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif /* HAVE_INET_NTOP */
#ifndef HAVE_INET_PTON
#ifdef __cplusplus
extern "C" {
#endif
int inet_pton(int af, const char *src, void *dst);
int inet_pton4(const char *src, unsigned char *dst);
#ifdef HAVE_IPV6
int inet_pton6(const char *src, unsigned char *dst);
#endif
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif /* HAVE_INET_PTON */
#endif /* INET_ATON_H */

View File

@ -1,62 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* report_CSV.h
* by Kevin Gibbs <kgibbs@nlanr.net>
*
* ________________________________________________________________ */
#ifndef REPORT_CSV_H
#define REPORT_CSV_H
void CSV_stats( Transfer_Info *stats );
void *CSV_peer( Connection_Info *stats, int ID);
void CSV_serverstats( Connection_Info *conn, Transfer_Info *stats );
#endif // REPORT_CSV_H

View File

@ -1,64 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* report_default.h
* by Kevin Gibbs <kgibbs@nlanr.net>
*
* ________________________________________________________________ */
#ifndef REPORT_DEFAULT_H
#define REPORT_DEFAULT_H
void reporter_printstats( Transfer_Info *stats );
void reporter_multistats( Transfer_Info *stats );
void reporter_serverstats( Connection_Info *conn, Transfer_Info *stats );
void reporter_reportsettings( ReporterData *stats );
void *reporter_reportpeer( Connection_Info *stats, int ID);
#endif // REPORT_DEFAULT_H

View File

@ -1,159 +0,0 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (C) 1993-1997 Microsoft Corporation. All Rights Reserved.
//
// MODULE: service.h
//
// AUTHOR: Craig Link
//
//
// Comments: The use of this header file and the accompanying service.c
// file simplifies the process of writting a service. You as a developer
// simply need to follow the TODO's outlined in this header file, and
// implement the ServiceStart() and ServiceStop() functions.
//
// There is no need to modify the code in service.c. Just add service.c
// to your project and link with the following libraries...
//
// libcmt.lib kernel32.lib advapi.lib shell32.lib
//
// This code also supports unicode. Be sure to compile both service.c and
// and code #include "service.h" with the same Unicode setting.
//
// Upon completion, your code will have the following command line interface
//
// <service exe> -? to display this list
// <service exe> -install to install the service
// <service exe> -remove to remove the service
// <service exe> -debug <params> to run as a console app for debugging
//
// Note: This code also implements Ctrl+C and Ctrl+Break handlers
// when using the debug option. These console events cause
// your ServiceStop routine to be called
//
// Also, this code only handles the OWN_SERVICE service type
// running in the LOCAL_SYSTEM security context.
//
// To control your service ( start, stop, etc ) you may use the
// Services control panel applet or the NET.EXE program.
//
// To aid in writing/debugging service, the
// SDK contains a utility (MSTOOLS\BIN\SC.EXE) that
// can be used to control, configure, or obtain service status.
// SC displays complete status for any service/driver
// in the service database, and allows any of the configuration
// parameters to be easily changed at the command line.
// For more information on SC.EXE, type SC at the command line.
//
/*
* modified Mar.07, 2002 by Feng Qin <fqin@ncsa.uiuc.edu>
* Mar.15, 2002
*
* removed some functions we don't use at all
* add code to start the service immediately after service is installed
*
* $Id: service.h,v 1.1.1.1 2004/05/18 01:50:44 kgibbs Exp $
*/
#ifndef _SERVICE_H
#define _SERVICE_H
#ifdef __cplusplus
extern "C" {
#endif
//////////////////////////////////////////////////////////////////////////////
//// todo: change to desired strings
////
// name of the executable
#define SZAPPNAME "IPerf"
// internal name of the service
#define SZSERVICENAME "IPerfService"
// displayed name of the service
#define SZSERVICEDISPLAYNAME "IPerf Service"
// list of service dependencies - "dep1\0dep2\0\0"
#define SZDEPENDENCIES ""
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//// todo: ServiceStart()must be defined by in your code.
//// The service should use ReportStatusToSCMgr to indicate
//// progress. This routine must also be used by StartService()
//// to report to the SCM when the service is running.
////
//// If a ServiceStop procedure is going to take longer than
//// 3 seconds to execute, it should spawn a thread to
//// execute the stop code, and return. Otherwise, the
//// ServiceControlManager will believe that the service has
//// stopped responding
////
VOID ServiceStart(DWORD dwArgc, LPTSTR *lpszArgv);
VOID ServiceStop();
//////////////////////////////////////////////////////////////////////////////
VOID WINAPI service_ctrl(DWORD dwCtrlCode);
VOID WINAPI service_main(DWORD dwArgc, LPTSTR *lpszArgv);
VOID CmdInstallService(int argc, char **argv);
BOOL CmdRemoveService();
BOOL CmdStartService(int argc, char **argv);
LPTSTR GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize );
VOID ServiceStart (DWORD dwArgc, LPTSTR *lpszArgv);
VOID ServiceStop();
//////////////////////////////////////////////////////////////////////////////
//// The following are procedures which
//// may be useful to call within the above procedures,
//// but require no implementation by the user.
//// They are implemented in service.c
//
// FUNCTION: ReportStatusToSCMgr()
//
// PURPOSE: Sets the current status of the service and
// reports it to the Service Control Manager
//
// PARAMETERS:
// dwCurrentState - the state of the service
// dwWin32ExitCode - error code to report
// dwWaitHint - worst case estimate to next checkpoint
//
// RETURN VALUE:
// TRUE - success
// FALSE - failure
//
BOOL ReportStatusToSCMgr(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint);
//
// FUNCTION: AddToMessageLog(LPTSTR lpszMsg)
//
// PURPOSE: Allows any thread to log an error message
//
// PARAMETERS:
// lpszMsg - text for message
//
// RETURN VALUE:
// none
//
void AddToMessageLog(LPTSTR lpszMsg);
//////////////////////////////////////////////////////////////////////////////
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,40 +0,0 @@
#ifndef SNPRINTF_H
#define SNPRINTF_H
/* ===================================================================
* snprintf.h
*
* This is from
* W. Richard Stevens, 'UNIX Network Programming', Vol 1, 2nd Edition,
* Prentice Hall, 1998.
*
* Mark Gates <mgates@nlanr.net>
* July 1998
*
* to use this prototype, make sure HAVE_SNPRINTF is not defined
*
* =================================================================== */
/*
* Throughout the book I use snprintf() because it's safer than sprintf().
* But as of the time of this writing, not all systems provide this
* function. The function below should only be built on those systems
* that do not provide a real snprintf().
* The function below just acts like sprintf(); it is not safe, but it
* tries to detect overflow.
*/
#ifndef HAVE_SNPRINTF
#ifdef __cplusplus
extern "C" {
#endif
int snprintf(char *buf, size_t size, const char *fmt, ...);
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif /* HAVE_SNPRINTF */
#endif /* SNPRINTF_H */

View File

@ -1,199 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* util.h
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* various C utility functions.
* ------------------------------------------------------------------- */
#ifndef UTIL_H
#define UTIL_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* -------------------------------------------------------------------
* set/getsockopt wrappers for SO_RCVBUF and SO_SNDBUF; TCP_MAXSEG
* socket.c
* ------------------------------------------------------------------- */
int setsock_tcp_windowsize( int inSock, int inTCPWin, int inSend );
int getsock_tcp_windowsize( int inSock, int inSend );
void setsock_tcp_mss( int inSock, int inTCPWin );
int getsock_tcp_mss( int inSock );
/* -------------------------------------------------------------------
* signal handlers
* signal.c
* ------------------------------------------------------------------- */
typedef void Sigfunc(int);
void sig_exit( int inSigno );
typedef Sigfunc *SigfuncPtr;
SigfuncPtr my_signal( int inSigno, SigfuncPtr inFunc );
#ifdef WIN32
/* under windows, emulate unix signals */
enum {
SIGINT,
SIGTERM,
SIGPIPE,
_NSIG
};
BOOL WINAPI sig_dispatcher( DWORD type );
#endif
/* -------------------------------------------------------------------
* error handlers
* error.c
* ------------------------------------------------------------------- */
void warn ( const char *inMessage, const char *inFile, int inLine );
void warn_errno( const char *inMessage, const char *inFile, int inLine );
#if defined( HAVE_POSIX_THREAD ) || defined( HAVE_WIN32_THREAD)
#define FAIL( cond, msg, settings ) \
do { \
if ( cond ) { \
warn( msg, __FILE__, __LINE__ ); \
thread_stop(settings); \
} \
} while( 0 )
#else
#define FAIL( cond, msg, settings ) \
do { \
if ( cond ) { \
warn( msg, __FILE__, __LINE__ ); \
exit( 1 ); \
} \
} while( 0 )
#endif
#define WARN( cond, msg ) \
do { \
if ( cond ) { \
warn( msg, __FILE__, __LINE__ ); \
} \
} while( 0 )
#if defined( HAVE_POSIX_THREAD ) || defined( HAVE_WIN32_THREAD)
#define FAIL_errno( cond, msg, settings ) \
do { \
if ( cond ) { \
warn_errno( msg, __FILE__, __LINE__ ); \
thread_stop(settings); \
} \
} while( 0 )
#else
#define FAIL_errno( cond, msg, settings ) \
do { \
if ( cond ) { \
warn_errno( msg, __FILE__, __LINE__ ); \
exit( 1 ); \
} \
} while( 0 )
#endif
#define WARN_errno( cond, msg ) \
do { \
if ( cond ) { \
warn_errno( msg, __FILE__, __LINE__ ); \
} \
} while( 0 )
/* -------------------------------------------------------------------
* initialize buffer to a pattern
* ------------------------------------------------------------------- */
void pattern( char *outBuf, int inBytes );
/* -------------------------------------------------------------------
* input and output numbers, converting with kilo, mega, giga
* stdio.c
* ------------------------------------------------------------------- */
double byte_atof( const char *inString );
max_size_t byte_atoi( const char *inString );
void byte_snprintf( char* outString, int inLen, double inNum, char inFormat );
/* -------------------------------------------------------------------
* redirect the stdout to a specified file
* stdio.c
* ------------------------------------------------------------------- */
void redirect(const char *inOutputFileName);
/* -------------------------------------------------------------------
* delete macro
* ------------------------------------------------------------------- */
#define DELETE_PTR( ptr ) \
do { \
if ( ptr != NULL ) { \
delete ptr; \
ptr = NULL; \
} \
} while( false )
#define DELETE_ARRAY( ptr ) \
do { \
if ( ptr != NULL ) { \
delete [] ptr; \
ptr = NULL; \
} \
} while( false )
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif /* UTIL_H */

View File

@ -1,2 +0,0 @@
#define IPERF_VERSION "2.1-CURRENT"
#define IPERF_VERSION_DATE "7 Apr 2008"

View File

@ -1,470 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Client.cpp
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* A client thread initiates a connect to the server and handles
* sending and receiving data, then closes the socket.
* ------------------------------------------------------------------- */
#include "headers.h"
#include "Client.hpp"
#include "Thread.h"
#include "SocketAddr.h"
#include "PerfSocket.hpp"
#include "Extractor.h"
#include "delay.hpp"
#include "util.h"
#include "Locale.h"
/* -------------------------------------------------------------------
* Store server hostname, optionally local hostname, and socket info.
* ------------------------------------------------------------------- */
Client::Client( thread_Settings *inSettings ) {
mSettings = inSettings;
mBuf = NULL;
// initialize buffer
mBuf = new char[ mSettings->mBufLen ];
pattern( mBuf, mSettings->mBufLen );
if ( isFileInput( mSettings ) ) {
if ( !isSTDIN( mSettings ) )
Extractor_Initialize( mSettings->mFileName, mSettings->mBufLen, mSettings );
else
Extractor_InitializeFile( stdin, mSettings->mBufLen, mSettings );
if ( !Extractor_canRead( mSettings ) ) {
unsetFileInput( mSettings );
}
}
// connect
Connect( );
if ( isReport( inSettings ) ) {
ReportSettings( inSettings );
if ( mSettings->multihdr && isMultipleReport( inSettings ) ) {
mSettings->multihdr->report->connection.peer = mSettings->peer;
mSettings->multihdr->report->connection.size_peer = mSettings->size_peer;
mSettings->multihdr->report->connection.local = mSettings->local;
SockAddr_setPortAny( &mSettings->multihdr->report->connection.local );
mSettings->multihdr->report->connection.size_local = mSettings->size_local;
}
}
} // end Client
/* -------------------------------------------------------------------
* Delete memory (hostname strings).
* ------------------------------------------------------------------- */
Client::~Client() {
if ( mSettings->mSock != INVALID_SOCKET ) {
int rc = close( mSettings->mSock );
WARN_errno( rc == SOCKET_ERROR, "close" );
mSettings->mSock = INVALID_SOCKET;
}
DELETE_ARRAY( mBuf );
} // end ~Client
const double kSecs_to_usecs = 1e6;
const int kBytes_to_Bits = 8;
void Client::RunTCP( void ) {
unsigned long currLen = 0;
struct itimerval it;
max_size_t totLen = 0;
int err;
char* readAt = mBuf;
// Indicates if the stream is readable
bool canRead = true, mMode_Time = isModeTime( mSettings );
ReportStruct *reportstruct = NULL;
// InitReport handles Barrier for multiple Streams
mSettings->reporthdr = InitReport( mSettings );
reportstruct = new ReportStruct;
reportstruct->packetID = 0;
lastPacketTime.setnow();
if ( mMode_Time ) {
memset (&it, 0, sizeof (it));
it.it_value.tv_sec = (int) (mSettings->mAmount / 100.0);
it.it_value.tv_usec = (int) 10000 * (mSettings->mAmount -
it.it_value.tv_sec * 100.0);
err = setitimer( ITIMER_REAL, &it, NULL );
if ( err != 0 ) {
perror("setitimer");
exit(1);
}
}
do {
// Read the next data block from
// the file if it's file input
if ( isFileInput( mSettings ) ) {
Extractor_getNextDataBlock( readAt, mSettings );
canRead = Extractor_canRead( mSettings ) != 0;
} else
canRead = true;
// perform write
currLen = write( mSettings->mSock, mBuf, mSettings->mBufLen );
if ( currLen < 0 ) {
WARN_errno( currLen < 0, "write2" );
break;
}
totLen += currLen;
if(mSettings->mInterval > 0) {
gettimeofday( &(reportstruct->packetTime), NULL );
reportstruct->packetLen = currLen;
ReportPacket( mSettings->reporthdr, reportstruct );
}
if ( !mMode_Time ) {
/* mAmount may be unsigned, so don't let it underflow! */
if( mSettings->mAmount >= currLen ) {
mSettings->mAmount -= currLen;
} else {
mSettings->mAmount = 0;
}
}
} while ( ! (sInterupted ||
(!mMode_Time && 0 >= mSettings->mAmount)) && canRead );
// stop timing
gettimeofday( &(reportstruct->packetTime), NULL );
// if we're not doing interval reporting, report the entire transfer as one big packet
if(0.0 == mSettings->mInterval) {
reportstruct->packetLen = totLen;
ReportPacket( mSettings->reporthdr, reportstruct );
}
CloseReport( mSettings->reporthdr, reportstruct );
DELETE_PTR( reportstruct );
EndReport( mSettings->reporthdr );
}
/* -------------------------------------------------------------------
* Send data using the connected UDP/TCP socket,
* until a termination flag is reached.
* Does not close the socket.
* ------------------------------------------------------------------- */
void Client::Run( void ) {
struct UDP_datagram* mBuf_UDP = (struct UDP_datagram*) mBuf;
unsigned long currLen = 0;
int delay_target = 0;
int delay = 0;
int adjust = 0;
char* readAt = mBuf;
#if HAVE_THREAD
if ( !isUDP( mSettings ) ) {
RunTCP();
return;
}
#endif
// Indicates if the stream is readable
bool canRead = true, mMode_Time = isModeTime( mSettings );
// setup termination variables
if ( mMode_Time ) {
mEndTime.setnow();
mEndTime.add( mSettings->mAmount / 100.0 );
}
if ( isUDP( mSettings ) ) {
// Due to the UDP timestamps etc, included
// reduce the read size by an amount
// equal to the header size
// compute delay for bandwidth restriction, constrained to [0,1] seconds
delay_target = (int) ( mSettings->mBufLen * ((kSecs_to_usecs * kBytes_to_Bits)
/ mSettings->mUDPRate) );
if ( delay_target < 0 ||
delay_target > (int) 1 * kSecs_to_usecs ) {
fprintf( stderr, warn_delay_large, delay_target / kSecs_to_usecs );
delay_target = (int) kSecs_to_usecs * 1;
}
if ( isFileInput( mSettings ) ) {
if ( isCompat( mSettings ) ) {
Extractor_reduceReadSize( sizeof(struct UDP_datagram), mSettings );
readAt += sizeof(struct UDP_datagram);
} else {
Extractor_reduceReadSize( sizeof(struct UDP_datagram) +
sizeof(struct client_hdr), mSettings );
readAt += sizeof(struct UDP_datagram) +
sizeof(struct client_hdr);
}
}
}
ReportStruct *reportstruct = NULL;
// InitReport handles Barrier for multiple Streams
mSettings->reporthdr = InitReport( mSettings );
reportstruct = new ReportStruct;
reportstruct->packetID = 0;
lastPacketTime.setnow();
do {
// Test case: drop 17 packets and send 2 out-of-order:
// sequence 51, 52, 70, 53, 54, 71, 72
//switch( datagramID ) {
// case 53: datagramID = 70; break;
// case 71: datagramID = 53; break;
// case 55: datagramID = 71; break;
// default: break;
//}
gettimeofday( &(reportstruct->packetTime), NULL );
if ( isUDP( mSettings ) ) {
// store datagram ID into buffer
mBuf_UDP->id = htonl( (reportstruct->packetID)++ );
mBuf_UDP->tv_sec = htonl( reportstruct->packetTime.tv_sec );
mBuf_UDP->tv_usec = htonl( reportstruct->packetTime.tv_usec );
// delay between writes
// make an adjustment for how long the last loop iteration took
// TODO this doesn't work well in certain cases, like 2 parallel streams
adjust = delay_target + lastPacketTime.subUsec( reportstruct->packetTime );
lastPacketTime.set( reportstruct->packetTime.tv_sec,
reportstruct->packetTime.tv_usec );
if ( adjust > 0 || delay > 0 ) {
delay += adjust;
}
}
// Read the next data block from
// the file if it's file input
if ( isFileInput( mSettings ) ) {
Extractor_getNextDataBlock( readAt, mSettings );
canRead = Extractor_canRead( mSettings ) != 0;
} else
canRead = true;
// perform write
currLen = write( mSettings->mSock, mBuf, mSettings->mBufLen );
if ( currLen < 0 && errno != ENOBUFS ) {
WARN_errno( currLen < 0, "write2" );
break;
}
// report packets
reportstruct->packetLen = currLen;
ReportPacket( mSettings->reporthdr, reportstruct );
if ( delay > 0 ) {
delay_loop( delay );
}
if ( !mMode_Time ) {
/* mAmount may be unsigned, so don't let it underflow! */
if( mSettings->mAmount >= currLen ) {
mSettings->mAmount -= currLen;
} else {
mSettings->mAmount = 0;
}
}
} while ( ! (sInterupted ||
(mMode_Time && mEndTime.before( reportstruct->packetTime )) ||
(!mMode_Time && 0 >= mSettings->mAmount)) && canRead );
// stop timing
gettimeofday( &(reportstruct->packetTime), NULL );
CloseReport( mSettings->reporthdr, reportstruct );
if ( isUDP( mSettings ) ) {
// send a final terminating datagram
// Don't count in the mTotalLen. The server counts this one,
// but didn't count our first datagram, so we're even now.
// The negative datagram ID signifies termination to the server.
// store datagram ID into buffer
mBuf_UDP->id = htonl( -(reportstruct->packetID) );
mBuf_UDP->tv_sec = htonl( reportstruct->packetTime.tv_sec );
mBuf_UDP->tv_usec = htonl( reportstruct->packetTime.tv_usec );
if ( isMulticast( mSettings ) ) {
write( mSettings->mSock, mBuf, mSettings->mBufLen );
} else {
write_UDP_FIN( );
}
}
DELETE_PTR( reportstruct );
EndReport( mSettings->reporthdr );
}
// end Run
void Client::InitiateServer() {
if ( !isCompat( mSettings ) ) {
int currLen;
client_hdr* temp_hdr;
if ( isUDP( mSettings ) ) {
UDP_datagram *UDPhdr = (UDP_datagram *)mBuf;
temp_hdr = (client_hdr*)(UDPhdr + 1);
} else {
temp_hdr = (client_hdr*)mBuf;
}
Settings_GenerateClientHdr( mSettings, temp_hdr );
if ( !isUDP( mSettings ) ) {
currLen = send( mSettings->mSock, mBuf, sizeof(client_hdr), 0 );
if ( currLen < 0 ) {
WARN_errno( currLen < 0, "write1" );
}
}
}
}
/* -------------------------------------------------------------------
* Setup a socket connected to a server.
* If inLocalhost is not null, bind to that address, specifying
* which outgoing interface to use.
* ------------------------------------------------------------------- */
void Client::Connect( ) {
int rc;
SockAddr_remoteAddr( mSettings );
assert( mSettings->inHostname != NULL );
// create an internet socket
int type = ( isUDP( mSettings ) ? SOCK_DGRAM : SOCK_STREAM);
int domain = (SockAddr_isIPv6( &mSettings->peer ) ?
#ifdef HAVE_IPV6
AF_INET6
#else
AF_INET
#endif
: AF_INET);
mSettings->mSock = socket( domain, type, 0 );
WARN_errno( mSettings->mSock == INVALID_SOCKET, "socket" );
SetSocketOptions( mSettings );
SockAddr_localAddr( mSettings );
if ( mSettings->mLocalhost != NULL ) {
// bind socket to local address
rc = bind( mSettings->mSock, (sockaddr*) &mSettings->local,
SockAddr_get_sizeof_sockaddr( &mSettings->local ) );
WARN_errno( rc == SOCKET_ERROR, "bind" );
}
// connect socket
rc = connect( mSettings->mSock, (sockaddr*) &mSettings->peer,
SockAddr_get_sizeof_sockaddr( &mSettings->peer ));
WARN_errno( rc == SOCKET_ERROR, "connect" );
getsockname( mSettings->mSock, (sockaddr*) &mSettings->local,
&mSettings->size_local );
getpeername( mSettings->mSock, (sockaddr*) &mSettings->peer,
&mSettings->size_peer );
} // end Connect
/* -------------------------------------------------------------------
* Send a datagram on the socket. The datagram's contents should signify
* a FIN to the application. Keep re-transmitting until an
* acknowledgement datagram is received.
* ------------------------------------------------------------------- */
void Client::write_UDP_FIN( ) {
int rc;
fd_set readSet;
struct timeval timeout;
int count = 0;
while ( count < 10 ) {
count++;
// write data
write( mSettings->mSock, mBuf, mSettings->mBufLen );
// wait until the socket is readable, or our timeout expires
FD_ZERO( &readSet );
FD_SET( mSettings->mSock, &readSet );
timeout.tv_sec = 0;
timeout.tv_usec = 250000; // quarter second, 250 ms
rc = select( mSettings->mSock+1, &readSet, NULL, NULL, &timeout );
FAIL_errno( rc == SOCKET_ERROR, "select", mSettings );
if ( rc == 0 ) {
// select timed out
continue;
} else {
// socket ready to read
rc = read( mSettings->mSock, mBuf, mSettings->mBufLen );
WARN_errno( rc < 0, "read" );
if ( rc < 0 ) {
break;
} else if ( rc >= (int) (sizeof(UDP_datagram) + sizeof(server_hdr)) ) {
ReportServerUDP( mSettings, (server_hdr*) ((UDP_datagram*)mBuf + 1) );
}
return;
}
}
fprintf( stderr, warn_no_ack, mSettings->mSock, count );
}
// end write_UDP_FIN

View File

@ -1,188 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
* Extractor.cpp
* by Ajay Tirumala (tirumala@ncsa.uiuc.edu)
* -------------------------------------------------------------------
* Extract data from a file, used to measure the transfer rates
* for various stream formats.
*
* E.g. Use a gzipped file to measure the transfer rates for
* compressed data
* Use an MPEG file to measure the transfer rates of
* Multimedia data formats
* Use a plain BMP file to measure the transfer rates of
* Uncompressed data
*
* This is beneficial especially in measuring bandwidth across WAN
* links where data compression takes place before data transmission
* -------------------------------------------------------------------
*/
#include "Extractor.h"
/**
* Constructor
* @arg fileName Name of the file
* @arg size Block size for reading
* Open the file and set the block size
*/
void Extractor_Initialize ( char *fileName, int inSize, thread_Settings *mSettings ) {
if ( (mSettings->Extractor_file = fopen (fileName, "rb")) == NULL ) {
fprintf( stderr, "Unable to open the file stream\n");
fprintf( stderr, "Will use the default data stream\n");
return;
}
mSettings->Extractor_size = inSize;
}
/**
* Constructor
* @arg fp File Pointer
* @arg size Block size for reading
* Set the block size,file pointer
*/
void Extractor_InitializeFile ( FILE *fp, int inSize, thread_Settings *mSettings ) {
mSettings->Extractor_file = fp;
mSettings->Extractor_size = inSize;
}
/**
* Destructor - Close the file
*/
void Extractor_Destroy ( thread_Settings *mSettings ) {
if ( mSettings->Extractor_file != NULL )
fclose( mSettings->Extractor_file );
}
/*
* Fetches the next data block from
* the file
* @arg block Pointer to the data read
* @return Number of bytes read
*/
int Extractor_getNextDataBlock ( char *data, thread_Settings *mSettings ) {
if ( Extractor_canRead( mSettings ) ) {
return(fread( data, 1, mSettings->Extractor_size,
mSettings->Extractor_file ));
}
return 0;
}
/**
* Function which determines whether
* the file stream is still readable
* @return boolean true, if readable; false, if not
*/
int Extractor_canRead ( thread_Settings *mSettings ) {
return(( mSettings->Extractor_file != NULL )
&& !(feof( mSettings->Extractor_file )));
}
/**
* This is used to reduce the read size
* Used in UDP transfer to accomodate the
* the header (timestamp)
* @arg delta Size to reduce
*/
void Extractor_reduceReadSize ( int delta, thread_Settings *mSettings ) {
mSettings->Extractor_size -= delta;
}

View File

@ -1,171 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Launch.cpp
* by Kevin Gibbs <kgibbs@nlanr.net>
* -------------------------------------------------------------------
* Functions to launch new server and client threads from C while
* the server and client are in C++.
* The launch function for reporters is in Reporter.c since it is
* in C and does not need a special launching function.
* ------------------------------------------------------------------- */
#include "headers.h"
#include "Thread.h"
#include "Settings.hpp"
#include "Client.hpp"
#include "Listener.hpp"
#include "Server.hpp"
#include "PerfSocket.hpp"
/*
* listener_spawn is responsible for creating a Listener class
* and launching the listener. It is provided as a means for
* the C thread subsystem to launch the listener C++ object.
*/
void listener_spawn( thread_Settings *thread ) {
Listener *theListener = NULL;
// start up a listener
theListener = new Listener( thread );
#ifndef WIN32
// handling of daemon mode in non-win32 builds
if ( isDaemon( thread ) ) {
theListener->runAsDaemon("iperf",LOG_DAEMON);
}
#endif
// Start listening
theListener->Run();
DELETE_PTR( theListener );
}
/*
* server_spawn is responsible for creating a Server class
* and launching the server. It is provided as a means for
* the C thread subsystem to launch the server C++ object.
*/
void server_spawn( thread_Settings *thread) {
Server *theServer = NULL;
// Start up the server
theServer = new Server( thread );
// Run the test
theServer->Run();
DELETE_PTR( theServer);
}
/*
* client_spawn is responsible for creating a Client class
* and launching the client. It is provided as a means for
* the C thread subsystem to launch the client C++ object.
*/
void client_spawn( thread_Settings *thread ) {
Client *theClient = NULL;
//start up the client
theClient = new Client( thread );
// Let the server know about our settings
theClient->InitiateServer();
// Run the test
theClient->Run();
DELETE_PTR( theClient );
}
/*
* client_init handles multiple threaded connects. It creates
* a listener object if either the dual test or tradeoff were
* specified. It also creates settings structures for all the
* threads and arranges them so they can be managed and started
* via the one settings structure that was passed in.
*/
void client_init( thread_Settings *clients ) {
thread_Settings *itr = NULL;
thread_Settings *next = NULL;
// Set the first thread to report Settings
setReport( clients );
itr = clients;
// See if we need to start a listener as well
Settings_GenerateListenerSettings( clients, &next );
// Create a multiple report header to handle reporting the
// sum of multiple client threads
Mutex_Lock( &groupCond );
groupID--;
clients->multihdr = InitMulti( clients, groupID );
Mutex_Unlock( &groupCond );
#ifdef HAVE_THREAD
if ( next != NULL ) {
// We have threads and we need to start a listener so
// have it ran before the client is launched
itr->runNow = next;
itr = next;
}
#endif
// For each of the needed threads create a copy of the
// provided settings, unsetting the report flag and add
// to the list of threads to start
for (int i = 1; i < clients->mThreads; i++) {
Settings_Copy( clients, &next );
unsetReport( next );
itr->runNow = next;
itr = next;
}
#ifndef HAVE_THREAD
if ( next != NULL ) {
// We don't have threads and we need to start a listener so
// have it ran after the client is finished
itr->runNext = next;
}
#endif
}

View File

@ -1,134 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* List.cpp
* by Kevin Gibbs <kgibbs@ncsa.uiuc.edu>
* -------------------------------------------------------------------
*/
#include "List.h"
#include "Mutex.h"
#include "SocketAddr.h"
/*
* Global List and Mutex variables
*/
Iperf_ListEntry *clients = NULL;
Mutex clients_mutex;
/*
* Add Entry add to the List
*/
void Iperf_pushback ( Iperf_ListEntry *add, Iperf_ListEntry **root ) {
add->next = *root;
*root = add;
}
/*
* Delete Entry del from the List
*/
void Iperf_delete ( iperf_sockaddr *del, Iperf_ListEntry **root ) {
Iperf_ListEntry *temp = Iperf_present( del, *root );
if ( temp != NULL ) {
if ( temp == *root ) {
*root = (*root)->next;
} else {
Iperf_ListEntry *itr = *root;
while ( itr->next != NULL ) {
if ( itr->next == temp ) {
itr->next = itr->next->next;
break;
}
itr = itr->next;
}
}
delete temp;
}
}
/*
* Destroy the List (cleanup function)
*/
void Iperf_destroy ( Iperf_ListEntry **root ) {
Iperf_ListEntry *itr1 = *root, *itr2;
while ( itr1 != NULL ) {
itr2 = itr1->next;
delete itr1;
itr1 = itr2;
}
*root = NULL;
}
/*
* Check if the exact Entry find is present
*/
Iperf_ListEntry* Iperf_present ( iperf_sockaddr *find, Iperf_ListEntry *root ) {
Iperf_ListEntry *itr = root;
while ( itr != NULL ) {
if ( SockAddr_are_Equal( (sockaddr*)itr, (sockaddr*)find ) ) {
return itr;
}
itr = itr->next;
}
return NULL;
}
/*
* Check if a Entry find is in the List or if any
* Entry exists that has the same host as the
* Entry find
*/
Iperf_ListEntry* Iperf_hostpresent ( iperf_sockaddr *find, Iperf_ListEntry *root ) {
Iperf_ListEntry *itr = root;
while ( itr != NULL ) {
if ( SockAddr_Hostare_Equal( (sockaddr*)itr, (sockaddr*)find ) ) {
return itr;
}
itr = itr->next;
}
return NULL;
}

View File

@ -1,716 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Listener.cpp
* by Mark Gates <mgates@nlanr.net>
* & Ajay Tirumala <tirumala@ncsa.uiuc.edu>
* -------------------------------------------------------------------
* Listener sets up a socket listening on the server host. For each
* connected socket that accept() returns, this creates a Server
* socket and spawns a thread for it.
*
* Changes to the latest version. Listener will run as a daemon
* Multicast Server is now Multi-threaded
* -------------------------------------------------------------------
* headers
* uses
* <stdlib.h>
* <stdio.h>
* <string.h>
* <errno.h>
*
* <sys/types.h>
* <unistd.h>
*
* <netdb.h>
* <netinet/in.h>
* <sys/socket.h>
* ------------------------------------------------------------------- */
#define HEADERS()
#include "headers.h"
#include "Listener.hpp"
#include "SocketAddr.h"
#include "PerfSocket.hpp"
#include "List.h"
#include "util.h"
/* -------------------------------------------------------------------
* Stores local hostname and socket info.
* ------------------------------------------------------------------- */
Listener::Listener( thread_Settings *inSettings ) {
mClients = inSettings->mThreads;
mBuf = NULL;
mSettings = inSettings;
// initialize buffer
mBuf = new char[ mSettings->mBufLen ];
// open listening socket
Listen( );
ReportSettings( inSettings );
} // end Listener
/* -------------------------------------------------------------------
* Delete memory (buffer).
* ------------------------------------------------------------------- */
Listener::~Listener() {
if ( mSettings->mSock != INVALID_SOCKET ) {
int rc = close( mSettings->mSock );
WARN_errno( rc == SOCKET_ERROR, "close" );
mSettings->mSock = INVALID_SOCKET;
}
DELETE_ARRAY( mBuf );
} // end ~Listener
/* -------------------------------------------------------------------
* Listens for connections and starts Servers to handle data.
* For TCP, each accepted connection spawns a Server thread.
* For UDP, handle all data in this thread for Win32 Only, otherwise
* spawn a new Server thread.
* ------------------------------------------------------------------- */
void Listener::Run( void ) {
#ifdef WIN32
if ( isUDP( mSettings ) && !isSingleUDP( mSettings ) ) {
UDPSingleServer();
} else
#else
#ifdef sun
if ( ( isUDP( mSettings ) &&
isMulticast( mSettings ) &&
!isSingleUDP( mSettings ) ) ||
isSingleUDP( mSettings ) ) {
UDPSingleServer();
} else
#else
if ( isSingleUDP( mSettings ) ) {
UDPSingleServer();
} else
#endif
#endif
{
bool client = false, UDP = isUDP( mSettings ), mCount = (mSettings->mThreads != 0);
thread_Settings *tempSettings = NULL;
Iperf_ListEntry *exist, *listtemp;
client_hdr* hdr = ( UDP ? (client_hdr*) (((UDP_datagram*)mBuf) + 1) :
(client_hdr*) mBuf);
if ( mSettings->mHost != NULL ) {
client = true;
SockAddr_remoteAddr( mSettings );
}
Settings_Copy( mSettings, &server );
server->mThreadMode = kMode_Server;
// Accept each packet,
// If there is no existing client, then start
// a new thread to service the new client
// The listener runs in a single thread
// Thread per client model is followed
do {
// Get a new socket
Accept( server );
if ( server->mSock == INVALID_SOCKET ) {
break;
}
if ( sInterupted != 0 ) {
close( server->mSock );
break;
}
// Reset Single Client Stuff
if ( isSingleClient( mSettings ) && clients == NULL ) {
mSettings->peer = server->peer;
mClients--;
client = true;
// Once all the server threads exit then quit
// Must keep going in case this client sends
// more streams
if ( mClients == 0 ) {
thread_release_nonterm( 0 );
mClients = 1;
}
}
// Verify that it is allowed
if ( client ) {
if ( !SockAddr_Hostare_Equal( (sockaddr*) &mSettings->peer,
(sockaddr*) &server->peer ) ) {
// Not allowed try again
close( server->mSock );
if ( isUDP( mSettings ) ) {
mSettings->mSock = -1;
Listen();
}
continue;
}
}
// Create an entry for the connection list
listtemp = new Iperf_ListEntry;
memcpy(listtemp, &server->peer, sizeof(iperf_sockaddr));
listtemp->next = NULL;
// See if we need to do summing
Mutex_Lock( &clients_mutex );
exist = Iperf_hostpresent( &server->peer, clients);
if ( exist != NULL ) {
// Copy group ID
listtemp->holder = exist->holder;
server->multihdr = exist->holder;
} else {
server->mThreads = 0;
Mutex_Lock( &groupCond );
groupID--;
listtemp->holder = InitMulti( server, groupID );
server->multihdr = listtemp->holder;
Mutex_Unlock( &groupCond );
}
// Store entry in connection list
Iperf_pushback( listtemp, &clients );
Mutex_Unlock( &clients_mutex );
tempSettings = NULL;
if ( !isCompat( mSettings ) && !isMulticast( mSettings ) ) {
if ( !UDP ) {
// TCP does not have the info yet
if ( recv( server->mSock, (char*)hdr, sizeof(client_hdr), 0) > 0 ) {
Settings_GenerateClientSettings( server, &tempSettings,
hdr );
}
} else {
Settings_GenerateClientSettings( server, &tempSettings,
hdr );
}
}
if ( tempSettings != NULL ) {
client_init( tempSettings );
if ( tempSettings->mMode == kTest_DualTest ) {
#ifdef HAVE_THREAD
server->runNow = tempSettings;
#else
server->runNext = tempSettings;
#endif
} else {
server->runNext = tempSettings;
}
}
// Start the server
#if defined(WIN32) && defined(HAVE_THREAD)
if ( UDP ) {
// WIN32 does bad UDP handling so run single threaded
if ( server->runNow != NULL ) {
thread_start( server->runNow );
}
server_spawn( server );
if ( server->runNext != NULL ) {
thread_start( server->runNext );
}
} else
#endif
thread_start( server );
// create a new socket
if ( UDP ) {
mSettings->mSock = -1;
Listen( );
}
// Prep for next connection
if ( !isSingleClient( mSettings ) ) {
mClients--;
}
Settings_Copy( mSettings, &server );
server->mThreadMode = kMode_Server;
} while ( !sInterupted && (!mCount || ( mCount && mClients > 0 )) );
Settings_Destroy( server );
}
} // end Run
/* -------------------------------------------------------------------
* Setup a socket listening on a port.
* For TCP, this calls bind() and listen().
* For UDP, this just calls bind().
* If inLocalhost is not null, bind to that address rather than the
* wildcard server address, specifying what incoming interface to
* accept connections on.
* ------------------------------------------------------------------- */
void Listener::Listen( ) {
int rc;
SockAddr_localAddr( mSettings );
// create an internet TCP socket
int type = (isUDP( mSettings ) ? SOCK_DGRAM : SOCK_STREAM);
int domain = (SockAddr_isIPv6( &mSettings->local ) ?
#ifdef HAVE_IPV6
AF_INET6
#else
AF_INET
#endif
: AF_INET);
#ifdef WIN32
if ( SockAddr_isMulticast( &mSettings->local ) ) {
// Multicast on Win32 requires special handling
mSettings->mSock = WSASocket( domain, type, 0, 0, 0, WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF );
WARN_errno( mSettings->mSock == INVALID_SOCKET, "socket" );
} else
#endif
{
mSettings->mSock = socket( domain, type, 0 );
WARN_errno( mSettings->mSock == INVALID_SOCKET, "socket" );
}
SetSocketOptions( mSettings );
// reuse the address, so we can run if a former server was killed off
int boolean = 1;
Socklen_t len = sizeof(boolean);
setsockopt( mSettings->mSock, SOL_SOCKET, SO_REUSEADDR, (char*) &boolean, len );
// bind socket to server address
#ifdef WIN32
if ( SockAddr_isMulticast( &mSettings->local ) ) {
// Multicast on Win32 requires special handling
rc = WSAJoinLeaf( mSettings->mSock, (sockaddr*) &mSettings->local, mSettings->size_local,0,0,0,0,JL_BOTH);
WARN_errno( rc == SOCKET_ERROR, "WSAJoinLeaf (aka bind)" );
} else
#endif
{
rc = bind( mSettings->mSock, (sockaddr*) &mSettings->local, mSettings->size_local );
WARN_errno( rc == SOCKET_ERROR, "bind" );
}
// listen for connections (TCP only).
// default backlog traditionally 5
if ( !isUDP( mSettings ) ) {
rc = listen( mSettings->mSock, 5 );
WARN_errno( rc == SOCKET_ERROR, "listen" );
}
#ifndef WIN32
// if multicast, join the group
if ( SockAddr_isMulticast( &mSettings->local ) ) {
McastJoin( );
}
#endif
} // end Listen
/* -------------------------------------------------------------------
* Joins the multicast group, with the default interface.
* ------------------------------------------------------------------- */
void Listener::McastJoin( ) {
#ifdef HAVE_MULTICAST
if ( !SockAddr_isIPv6( &mSettings->local ) ) {
struct ip_mreq mreq;
memcpy( &mreq.imr_multiaddr, SockAddr_get_in_addr( &mSettings->local ),
sizeof(mreq.imr_multiaddr));
mreq.imr_interface.s_addr = htonl( INADDR_ANY );
int rc = setsockopt( mSettings->mSock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
(char*) &mreq, sizeof(mreq));
WARN_errno( rc == SOCKET_ERROR, "multicast join" );
}
#ifdef HAVE_IPV6_MULTICAST
else {
struct ipv6_mreq mreq;
memcpy( &mreq.ipv6mr_multiaddr, SockAddr_get_in6_addr( &mSettings->local ),
sizeof(mreq.ipv6mr_multiaddr));
mreq.ipv6mr_interface = 0;
int rc = setsockopt( mSettings->mSock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP,
(char*) &mreq, sizeof(mreq));
WARN_errno( rc == SOCKET_ERROR, "multicast join" );
}
#endif
#endif
}
// end McastJoin
/* -------------------------------------------------------------------
* Sets the Multicast TTL for outgoing packets.
* ------------------------------------------------------------------- */
void Listener::McastSetTTL( int val ) {
#ifdef HAVE_MULTICAST
if ( !SockAddr_isIPv6( &mSettings->local ) ) {
int rc = setsockopt( mSettings->mSock, IPPROTO_IP, IP_MULTICAST_TTL,
(char*) &val, sizeof(val));
WARN_errno( rc == SOCKET_ERROR, "multicast ttl" );
}
#ifdef HAVE_IPV6_MULTICAST
else {
int rc = setsockopt( mSettings->mSock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
(char*) &val, sizeof(val));
WARN_errno( rc == SOCKET_ERROR, "multicast ttl" );
}
#endif
#endif
}
// end McastSetTTL
/* -------------------------------------------------------------------
* After Listen() has setup mSock, this will block
* until a new connection arrives.
* ------------------------------------------------------------------- */
void Listener::Accept( thread_Settings *server ) {
server->size_peer = sizeof(iperf_sockaddr);
if ( isUDP( server ) ) {
/* -------------------------------------------------------------------
* Do the equivalent of an accept() call for UDP sockets. This waits
* on a listening UDP socket until we get a datagram.
* ------------------------------------------------------------------- */
int rc;
Iperf_ListEntry *exist;
int32_t datagramID;
server->mSock = INVALID_SOCKET;
while ( server->mSock == INVALID_SOCKET ) {
rc = recvfrom( mSettings->mSock, mBuf, mSettings->mBufLen, 0,
(struct sockaddr*) &server->peer, &server->size_peer );
FAIL_errno( rc == SOCKET_ERROR, "recvfrom", mSettings );
Mutex_Lock( &clients_mutex );
// Handle connection for UDP sockets.
exist = Iperf_present( &server->peer, clients);
datagramID = ntohl( ((UDP_datagram*) mBuf)->id );
if ( exist == NULL && datagramID >= 0 ) {
server->mSock = mSettings->mSock;
int rc = connect( server->mSock, (struct sockaddr*) &server->peer,
server->size_peer );
FAIL_errno( rc == SOCKET_ERROR, "connect UDP", mSettings );
} else {
server->mSock = INVALID_SOCKET;
}
Mutex_Unlock( &clients_mutex );
}
} else {
// Handles interupted accepts. Returns the newly connected socket.
server->mSock = INVALID_SOCKET;
while ( server->mSock == INVALID_SOCKET ) {
// accept a connection
server->mSock = accept( mSettings->mSock,
(sockaddr*) &server->peer, &server->size_peer );
if ( server->mSock == INVALID_SOCKET && errno == EINTR ) {
continue;
}
}
}
server->size_local = sizeof(iperf_sockaddr);
getsockname( server->mSock, (sockaddr*) &server->local,
&server->size_local );
} // end Accept
void Listener::UDPSingleServer( ) {
bool client = false, UDP = isUDP( mSettings ), mCount = (mSettings->mThreads != 0);
thread_Settings *tempSettings = NULL;
Iperf_ListEntry *exist, *listtemp;
int rc;
int32_t datagramID;
client_hdr* hdr = ( UDP ? (client_hdr*) (((UDP_datagram*)mBuf) + 1) :
(client_hdr*) mBuf);
ReportStruct *reportstruct = new ReportStruct;
if ( mSettings->mHost != NULL ) {
client = true;
SockAddr_remoteAddr( mSettings );
}
Settings_Copy( mSettings, &server );
server->mThreadMode = kMode_Server;
// Accept each packet,
// If there is no existing client, then start
// a new report to service the new client
// The listener runs in a single thread
Mutex_Lock( &clients_mutex );
do {
// Get next packet
while ( sInterupted == 0) {
server->size_peer = sizeof( iperf_sockaddr );
rc = recvfrom( mSettings->mSock, mBuf, mSettings->mBufLen, 0,
(struct sockaddr*) &server->peer, &server->size_peer );
WARN_errno( rc == SOCKET_ERROR, "recvfrom" );
if ( rc == SOCKET_ERROR ) {
return;
}
// Handle connection for UDP sockets.
exist = Iperf_present( &server->peer, clients);
datagramID = ntohl( ((UDP_datagram*) mBuf)->id );
if ( datagramID >= 0 ) {
if ( exist != NULL ) {
// read the datagram ID and sentTime out of the buffer
reportstruct->packetID = datagramID;
reportstruct->sentTime.tv_sec = ntohl( ((UDP_datagram*) mBuf)->tv_sec );
reportstruct->sentTime.tv_usec = ntohl( ((UDP_datagram*) mBuf)->tv_usec );
reportstruct->packetLen = rc;
gettimeofday( &(reportstruct->packetTime), NULL );
ReportPacket( exist->server->reporthdr, reportstruct );
} else {
Mutex_Lock( &groupCond );
groupID--;
server->mSock = -groupID;
Mutex_Unlock( &groupCond );
server->size_local = sizeof(iperf_sockaddr);
getsockname( mSettings->mSock, (sockaddr*) &server->local,
&server->size_local );
break;
}
} else {
if ( exist != NULL ) {
// read the datagram ID and sentTime out of the buffer
reportstruct->packetID = -datagramID;
reportstruct->sentTime.tv_sec = ntohl( ((UDP_datagram*) mBuf)->tv_sec );
reportstruct->sentTime.tv_usec = ntohl( ((UDP_datagram*) mBuf)->tv_usec );
reportstruct->packetLen = rc;
gettimeofday( &(reportstruct->packetTime), NULL );
ReportPacket( exist->server->reporthdr, reportstruct );
// stop timing
gettimeofday( &(reportstruct->packetTime), NULL );
CloseReport( exist->server->reporthdr, reportstruct );
if ( rc > (int) ( sizeof( UDP_datagram )
+ sizeof( server_hdr ) ) ) {
UDP_datagram *UDP_Hdr;
server_hdr *hdr;
UDP_Hdr = (UDP_datagram*) mBuf;
Transfer_Info *stats = GetReport( exist->server->reporthdr );
hdr = (server_hdr*) (UDP_Hdr+1);
hdr->flags = htonl( HEADER_VERSION1 );
hdr->total_len1 = htonl( (long) (stats->TotalLen >> 32) );
hdr->total_len2 = htonl( (long) (stats->TotalLen & 0xFFFFFFFF) );
hdr->stop_sec = htonl( (long) stats->endTime );
hdr->stop_usec = htonl( (long)((stats->endTime - (long)stats->endTime)
* rMillion));
hdr->error_cnt = htonl( stats->cntError );
hdr->outorder_cnt = htonl( stats->cntOutofOrder );
hdr->datagrams = htonl( stats->cntDatagrams );
hdr->jitter1 = htonl( (long) stats->jitter );
hdr->jitter2 = htonl( (long) ((stats->jitter - (long)stats->jitter)
* rMillion) );
}
EndReport( exist->server->reporthdr );
exist->server->reporthdr = NULL;
Iperf_delete( &(exist->server->peer), &clients );
} else if ( rc > (int) ( sizeof( UDP_datagram )
+ sizeof( server_hdr ) ) ) {
UDP_datagram *UDP_Hdr;
server_hdr *hdr;
UDP_Hdr = (UDP_datagram*) mBuf;
hdr = (server_hdr*) (UDP_Hdr+1);
hdr->flags = htonl( 0 );
}
sendto( mSettings->mSock, mBuf, mSettings->mBufLen, 0,
(struct sockaddr*) &server->peer, server->size_peer);
}
}
if ( server->mSock == INVALID_SOCKET ) {
break;
}
if ( sInterupted != 0 ) {
close( server->mSock );
break;
}
// Reset Single Client Stuff
if ( isSingleClient( mSettings ) && clients == NULL ) {
mSettings->peer = server->peer;
mClients--;
client = true;
// Once all the server threads exit then quit
// Must keep going in case this client sends
// more streams
if ( mClients == 0 ) {
thread_release_nonterm( 0 );
mClients = 1;
}
}
// Verify that it is allowed
if ( client ) {
if ( !SockAddr_Hostare_Equal( (sockaddr*) &mSettings->peer,
(sockaddr*) &server->peer ) ) {
// Not allowed try again
connect( mSettings->mSock,
(sockaddr*) &server->peer,
server->size_peer );
close( mSettings->mSock );
mSettings->mSock = -1;
Listen( );
continue;
}
}
// Create an entry for the connection list
listtemp = new Iperf_ListEntry;
memcpy(listtemp, &server->peer, sizeof(iperf_sockaddr));
listtemp->server = server;
listtemp->next = NULL;
// See if we need to do summing
exist = Iperf_hostpresent( &server->peer, clients);
if ( exist != NULL ) {
// Copy group ID
listtemp->holder = exist->holder;
server->multihdr = exist->holder;
} else {
server->mThreads = 0;
Mutex_Lock( &groupCond );
groupID--;
listtemp->holder = InitMulti( server, groupID );
server->multihdr = listtemp->holder;
Mutex_Unlock( &groupCond );
}
// Store entry in connection list
Iperf_pushback( listtemp, &clients );
tempSettings = NULL;
if ( !isCompat( mSettings ) && !isMulticast( mSettings ) ) {
Settings_GenerateClientSettings( server, &tempSettings,
hdr );
}
if ( tempSettings != NULL ) {
client_init( tempSettings );
if ( tempSettings->mMode == kTest_DualTest ) {
#ifdef HAVE_THREAD
thread_start( tempSettings );
#else
server->runNext = tempSettings;
#endif
} else {
server->runNext = tempSettings;
}
}
server->reporthdr = InitReport( server );
// Prep for next connection
if ( !isSingleClient( mSettings ) ) {
mClients--;
}
Settings_Copy( mSettings, &server );
server->mThreadMode = kMode_Server;
} while ( !sInterupted && (!mCount || ( mCount && mClients > 0 )) );
Mutex_Unlock( &clients_mutex );
Settings_Destroy( server );
}
/* --------------------------------------------------------------------
* Run the server as a daemon
* --------------------------------------------------------------------*/
void Listener::runAsDaemon(const char *pname, int facility) {
#ifndef WIN32
pid_t pid;
/* Create a child process & if successful, exit from the parent process */
if ( (pid = fork()) == -1 ) {
fprintf( stderr, "error in first child create\n");
exit(0);
} else if ( pid != 0 ) {
exit(0);
}
/* Try becoming the session leader, once the parent exits */
if ( setsid() == -1 ) { /* Become the session leader */
fprintf( stderr, "Cannot change the session group leader\n");
} else {
}
signal(SIGHUP,SIG_IGN);
/* Now fork() and get released from the terminal */
if ( (pid = fork()) == -1 ) {
fprintf( stderr, "error\n");
exit(0);
} else if ( pid != 0 ) {
exit(0);
}
chdir(".");
fprintf( stderr, "Running Iperf Server as a daemon\n");
fprintf( stderr, "The Iperf daemon process ID : %d\n",((int)getpid()));
fflush(stderr);
fclose(stdin);
#else
fprintf( stderr, "Use the precompiled windows version for service (daemon) option\n");
#endif
}

View File

@ -1,335 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Locale.c
* by Ajay Tirumala <tirumala@ncsa.uiuc.edu>
* & Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* Strings and other stuff that is locale specific.
* ------------------------------------------------------------------- */
#include "version.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
#else
#ifdef WIN32
#include "config.win32.h"
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* -------------------------------------------------------------------
* usage
* ------------------------------------------------------------------- */
const char usage_short[] = "\
Usage: %s [-s|-c host] [options]\n\
Try `%s --help' for more information.\n";
const char usage_long1[] = "\
Usage: iperf [-s|-c host] [options]\n\
iperf [-h|--help] [-v|--version]\n\
\n\
Client/Server:\n\
-f, --format [kmKM] format to report: Kbits, Mbits, KBytes, MBytes\n\
-i, --interval # seconds between periodic bandwidth reports\n\
-l, --len #[KM] length of buffer to read or write (default 8 KB)\n\
-m, --print_mss print TCP maximum segment size (MTU - TCP/IP header)\n\
-o, --output <filename> output the report or error message to this specified file\n\
-p, --port # server port to listen on/connect to\n\
-u, --udp use UDP rather than TCP\n\
-w, --window #[KM] TCP window size (socket buffer size)\n\
-B, --bind <host> bind to <host>, an interface or multicast address\n\
-C, --compatibility for use with older versions does not sent extra msgs\n\
-M, --mss # set TCP maximum segment size (MTU - 40 bytes)\n\
-N, --nodelay set TCP no delay, disabling Nagle's Algorithm\n\
-V, --IPv6Version Set the domain to IPv6\n\
\n\
Server specific:\n\
-s, --server run in server mode\n\
-U, --single_udp run in single threaded UDP mode\n\
-D, --daemon run the server as a daemon\n"
#ifdef WIN32
" -R, --remove remove service in win32\n"
#endif
;
const char usage_long2[] = "\
\n\
Client specific:\n\
-b, --bandwidth #[KM] for UDP, bandwidth to send at in bits/sec\n\
(default 1 Mbit/sec, implies -u)\n\
-c, --client <host> run in client mode, connecting to <host>\n\
-d, --dualtest Do a bidirectional test simultaneously\n\
-n, --num #[KM] number of bytes to transmit (instead of -t)\n\
-r, --tradeoff Do a bidirectional test individually\n\
-t, --time # time in seconds to transmit for (default 10 secs)\n\
-F, --fileinput <name> input the data to be transmitted from a file\n\
-I, --stdin input the data to be transmitted from stdin\n\
-L, --listenport # port to recieve bidirectional tests back on\n\
-P, --parallel # number of parallel client threads to run\n\
-T, --ttl # time-to-live, for multicast (default 1)\n\
-Z, --linux-congestion <algo> set TCP congestion control algorithm (Linux only)\n\
\n\
Miscellaneous:\n\
-x, --reportexclude [CDMSV] exclude C(connection) D(data) M(multicast) S(settings) V(server) reports\n\
-y, --reportstyle C report as a Comma-Separated Values\n\
-h, --help print this message and quit\n\
-v, --version print version information and quit\n\
\n\
[KM] Indicates options that support a K or M suffix for kilo- or mega-\n\
\n\
The TCP window size option can be set by the environment variable\n\
TCP_WINDOW_SIZE. Most other options can be set by an environment variable\n\
IPERF_<long option name>, such as IPERF_BANDWIDTH.\n\
\n\
Report bugs to <iperf-users@lists.sourceforge.net>\n";
// include a description of the threading in the version
#if defined( HAVE_POSIX_THREAD )
#define IPERF_THREADS "pthreads"
#elif defined( HAVE_WIN32_THREAD )
#define IPERF_THREADS "win32 threads"
#else
#define IPERF_THREADS "single threaded"
#endif
const char version[] =
"iperf version " IPERF_VERSION " (" IPERF_VERSION_DATE ") " IPERF_THREADS "\n";
/* -------------------------------------------------------------------
* settings
* ------------------------------------------------------------------- */
const char seperator_line[] =
"------------------------------------------------------------\n";
const char server_port[] =
"Server listening on %s port %d\n";
const char client_port[] =
"Client connecting to %s, %s port %d\n";
const char bind_address[] =
"Binding to local address %s\n";
const char multicast_ttl[] =
"Setting multicast TTL to %d\n";
const char join_multicast[] =
"Joining multicast group %s\n";
const char client_datagram_size[] =
"Sending %d byte datagrams\n";
const char server_datagram_size[] =
"Receiving %d byte datagrams\n";
const char tcp_window_size[] =
"TCP window size";
const char udp_buffer_size[] =
"UDP buffer size";
const char window_default[] =
"(default)";
const char wait_server_threads[] =
"Waiting for server threads to complete. Interrupt again to force quit.\n";
/* -------------------------------------------------------------------
* reports
* ------------------------------------------------------------------- */
const char report_read_lengths[] =
"[%3d] Read lengths occurring in more than 5%% of reads:\n";
const char report_read_length_times[] =
"[%3d] %5d bytes read %5d times (%.3g%%)\n";
const char report_bw_header[] =
"[ ID] Interval Transfer Bandwidth\n";
const char report_bw_format[] =
"[%3d] %4.1f-%4.1f sec %ss %ss/sec\n";
const char report_sum_bw_format[] =
"[SUM] %4.1f-%4.1f sec %ss %ss/sec\n";
const char report_bw_jitter_loss_header[] =
"[ ID] Interval Transfer Bandwidth Jitter Lost/Total \
Datagrams\n";
const char report_bw_jitter_loss_format[] =
"[%3d] %4.1f-%4.1f sec %ss %ss/sec %5.3f ms %4d/%5d (%.2g%%)\n";
const char report_sum_bw_jitter_loss_format[] =
"[SUM] %4.1f-%4.1f sec %ss %ss/sec %5.3f ms %4d/%5d (%.2g%%)\n";
const char report_outoforder[] =
"[%3d] %4.1f-%4.1f sec %d datagrams received out-of-order\n";
const char report_sum_outoforder[] =
"[SUM] %4.1f-%4.1f sec %d datagrams received out-of-order\n";
const char report_peer[] =
"[%3d] local %s port %u connected with %s port %u\n";
const char report_mss_unsupported[] =
"[%3d] MSS and MTU size unknown (TCP_MAXSEG not supported by OS?)\n";
const char report_mss[] =
"[%3d] MSS size %d bytes (MTU %d bytes, %s)\n";
const char report_datagrams[] =
"[%3d] Sent %d datagrams\n";
const char report_sum_datagrams[] =
"[SUM] Sent %d datagrams\n";
const char server_reporting[] =
"[%3d] Server Report:\n";
const char reportCSV_peer[] =
"%s,%u,%s,%u";
#ifdef HAVE_QUAD_SUPPORT
#ifdef HAVE_PRINTF_QD
const char reportCSV_bw_format[] =
"%s,%s,%d,%.1f-%.1f,%qd,%qd\n";
const char reportCSV_bw_jitter_loss_format[] =
"%s,%s,%d,%.1f-%.1f,%qd,%qd,%.3f,%d,%d,%.3f,%d\n";
#else // HAVE_PRINTF_QD
const char reportCSV_bw_format[] =
"%s,%s,%d,%.1f-%.1f,%lld,%lld\n";
const char reportCSV_bw_jitter_loss_format[] =
"%s,%s,%d,%.1f-%.1f,%lld,%lld,%.3f,%d,%d,%.3f,%d\n";
#endif // HAVE_PRINTF_QD
#else // HAVE_QUAD_SUPPORT
#ifdef WIN32
const char reportCSV_bw_format[] =
"%s,%s,%d,%.1f-%.1f,%I64d,%I64d\n";
const char reportCSV_bw_jitter_loss_format[] =
"%s,%s,%d,%.1f-%.1f,%I64d,%I64d,%.3f,%d,%d,%.3f,%d\n";
#else
const char reportCSV_bw_format[] =
"%s,%s,%d,%.1f-%.1f,%d,%d\n";
const char reportCSV_bw_jitter_loss_format[] =
"%s,%s,%d,%.1f-%.1f,%d,%d,%.3f,%d,%d,%.3f,%d\n";
#endif //WIN32
#endif //HAVE_QUAD_SUPPORT
/* -------------------------------------------------------------------
* warnings
* ------------------------------------------------------------------- */
const char warn_window_requested[] =
" (WARNING: requested %s)";
const char warn_window_small[] = "\
WARNING: TCP window size set to %d bytes. A small window size\n\
will give poor performance. See the Iperf documentation.\n";
const char warn_delay_large[] =
"WARNING: delay too large, reducing from %.1f to 1.0 seconds.\n";
const char warn_no_pathmtu[] =
"WARNING: Path MTU Discovery may not be enabled.\n";
const char warn_no_ack[]=
"[%3d] WARNING: did not receive ack of last datagram after %d tries.\n";
const char warn_ack_failed[]=
"[%3d] WARNING: ack of last datagram failed after %d tries.\n";
const char warn_fileopen_failed[]=
"WARNING: Unable to open file stream for transfer\n\
Using default data stream. \n";
const char unable_to_change_win[]=
"WARNING: Unable to change the window size\n";
const char opt_estimate[]=
"Optimal Estimate\n";
const char report_interval_small[] =
"WARNING: interval too small, increasing from %3.2f to 0.5 seconds.\n";
const char warn_invalid_server_option[] =
"WARNING: option -%c is not valid for server mode\n";
const char warn_invalid_client_option[] =
"WARNING: option -%c is not valid for client mode\n";
const char warn_invalid_compatibility_option[] =
"WARNING: option -%c is not valid in compatibility mode\n";
const char warn_implied_udp[] =
"WARNING: option -%c implies udp testing\n";
const char warn_implied_compatibility[] =
"WARNING: option -%c has implied compatibility mode\n";
const char warn_buffer_too_small[] =
"WARNING: the UDP buffer was increased to %d for proper operation\n";
const char warn_invalid_single_threaded[] =
"WARNING: option -%c is not valid in single threaded versions\n";
const char warn_invalid_report_style[] =
"WARNING: unknown reporting style \"%s\", switching to default\n";
const char warn_invalid_report[] =
"WARNING: unknown reporting type \"%c\", ignored\n valid options are:\n\t exclude: C(connection) D(data) M(multicast) S(settings) V(server) report\n\n";
#ifdef __cplusplus
} /* end extern "C" */
#endif

View File

@ -1,39 +0,0 @@
bin_PROGRAMS = iperf
LIBCOMPAT_LDADDS = @STRIP_BEGIN@ \
$(top_builddir)/compat/libcompat.a \
@STRIP_END@
AM_CPPFLAGS = @STRIP_BEGIN@ \
-I$(top_srcdir)/include \
-I$(top_builddir)/include \
@STRIP_END@
AM_CXXFLAGS = -Wall
AM_CFLAGS = -Wall
iperf_LDFLAGS = @CFLAGS@ @PTHREAD_CFLAGS@ @WEB100_CFLAGS@ @DEFS@
iperf_SOURCES = \
Client.cpp \
Extractor.c \
Launch.cpp \
List.cpp \
Listener.cpp \
Locale.c \
PerfSocket.cpp \
ReportCSV.c \
ReportDefault.c \
Reporter.c \
Server.cpp \
Settings.cpp \
SocketAddr.c \
gnu_getopt.c \
gnu_getopt_long.c \
main.cpp \
service.c \
sockets.c \
stdio.c \
tcp_window_size.c
iperf_LDADD = $(LIBCOMPAT_LDADDS)

View File

@ -1,503 +0,0 @@
# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
bin_PROGRAMS = iperf$(EXEEXT)
subdir = src
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \
$(top_srcdir)/m4/ax_create_stdint_h.m4 \
$(top_srcdir)/m4/dast.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
am__installdirs = "$(DESTDIR)$(bindir)"
binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(bin_PROGRAMS)
am_iperf_OBJECTS = Client.$(OBJEXT) Extractor.$(OBJEXT) \
Launch.$(OBJEXT) List.$(OBJEXT) Listener.$(OBJEXT) \
Locale.$(OBJEXT) PerfSocket.$(OBJEXT) ReportCSV.$(OBJEXT) \
ReportDefault.$(OBJEXT) Reporter.$(OBJEXT) Server.$(OBJEXT) \
Settings.$(OBJEXT) SocketAddr.$(OBJEXT) gnu_getopt.$(OBJEXT) \
gnu_getopt_long.$(OBJEXT) main.$(OBJEXT) service.$(OBJEXT) \
sockets.$(OBJEXT) stdio.$(OBJEXT) tcp_window_size.$(OBJEXT)
iperf_OBJECTS = $(am_iperf_OBJECTS)
am__DEPENDENCIES_1 = $(top_builddir)/compat/libcompat.a
iperf_DEPENDENCIES = $(am__DEPENDENCIES_1)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
-o $@
SOURCES = $(iperf_SOURCES)
DIST_SOURCES = $(iperf_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GREP = @GREP@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
STRIP_BEGIN = @STRIP_BEGIN@
STRIP_DUMMY = @STRIP_DUMMY@
STRIP_END = @STRIP_END@
VERSION = @VERSION@
WEB100_CFLAGS = @WEB100_CFLAGS@
WEB100_CONFIG = @WEB100_CONFIG@
WEB100_LIBS = @WEB100_LIBS@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
acx_pthread_config = @acx_pthread_config@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
LIBCOMPAT_LDADDS = @STRIP_BEGIN@ \
$(top_builddir)/compat/libcompat.a \
@STRIP_END@
AM_CPPFLAGS = @STRIP_BEGIN@ \
-I$(top_srcdir)/include \
-I$(top_builddir)/include \
@STRIP_END@
AM_CXXFLAGS = -Wall
AM_CFLAGS = -Wall
iperf_LDFLAGS = @CFLAGS@ @PTHREAD_CFLAGS@ @WEB100_CFLAGS@ @DEFS@
iperf_SOURCES = \
Client.cpp \
Extractor.c \
Launch.cpp \
List.cpp \
Listener.cpp \
Locale.c \
PerfSocket.cpp \
ReportCSV.c \
ReportDefault.c \
Reporter.c \
Server.cpp \
Settings.cpp \
SocketAddr.c \
gnu_getopt.c \
gnu_getopt_long.c \
main.cpp \
service.c \
sockets.c \
stdio.c \
tcp_window_size.c
iperf_LDADD = $(LIBCOMPAT_LDADDS)
all: all-am
.SUFFIXES:
.SUFFIXES: .c .cpp .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --foreign src/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
@list='$(bin_PROGRAMS)'; for p in $$list; do \
p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
if test -f $$p \
; then \
f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
$(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
else :; fi; \
done
uninstall-binPROGRAMS:
@$(NORMAL_UNINSTALL)
@list='$(bin_PROGRAMS)'; for p in $$list; do \
f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
rm -f "$(DESTDIR)$(bindir)/$$f"; \
done
clean-binPROGRAMS:
-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
iperf$(EXEEXT): $(iperf_OBJECTS) $(iperf_DEPENDENCIES)
@rm -f iperf$(EXEEXT)
$(CXXLINK) $(iperf_LDFLAGS) $(iperf_OBJECTS) $(iperf_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Client.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Extractor.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Launch.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/List.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Listener.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Locale.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PerfSocket.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ReportCSV.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ReportDefault.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Reporter.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Server.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Settings.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SocketAddr.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnu_getopt.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnu_getopt_long.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/service.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sockets.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stdio.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcp_window_size.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
.cpp.o:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
.cpp.obj:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
uninstall-info-am:
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(PROGRAMS)
installdirs:
for dir in "$(DESTDIR)$(bindir)"; do \
test -z "$$dir" || $(mkdir_p) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am:
install-exec-am: install-binPROGRAMS
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-binPROGRAMS uninstall-info-am
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
clean-generic ctags distclean distclean-compile \
distclean-generic distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-binPROGRAMS \
install-data install-data-am install-exec install-exec-am \
install-info install-info-am install-man install-strip \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
uninstall-am uninstall-binPROGRAMS uninstall-info-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -1,158 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* PerfSocket.cpp
* by Mark Gates <mgates@nlanr.net>
* Ajay Tirumala <tirumala@ncsa.uiuc.edu>
* -------------------------------------------------------------------
* Has routines the Client and Server classes use in common for
* performance testing the network.
* Changes in version 1.2.0
* for extracting data from files
* -------------------------------------------------------------------
* headers
* uses
* <stdlib.h>
* <stdio.h>
* <string.h>
*
* <sys/types.h>
* <sys/socket.h>
* <unistd.h>
*
* <arpa/inet.h>
* <netdb.h>
* <netinet/in.h>
* <sys/socket.h>
* ------------------------------------------------------------------- */
#define HEADERS()
#include "headers.h"
#include "PerfSocket.hpp"
#include "SocketAddr.h"
#include "util.h"
/* -------------------------------------------------------------------
* Set socket options before the listen() or connect() calls.
* These are optional performance tuning factors.
* ------------------------------------------------------------------- */
void SetSocketOptions( thread_Settings *inSettings ) {
// set the TCP window size (socket buffer sizes)
// also the UDP buffer size
// must occur before call to accept() for large window sizes
setsock_tcp_windowsize( inSettings->mSock, inSettings->mTCPWin,
(inSettings->mThreadMode == kMode_Client ? 1 : 0) );
if ( isCongestionControl( inSettings ) ) {
#ifdef TCP_CONGESTION
Socklen_t len = strlen( inSettings->mCongestion ) + 1;
int rc = setsockopt( inSettings->mSock, IPPROTO_TCP, TCP_CONGESTION,
inSettings->mCongestion, len);
if (rc == SOCKET_ERROR ) {
fprintf(stderr, "Attempt to set '%s' congestion control failed: %s\n",
inSettings->mCongestion, strerror(errno));
exit(1);
}
#else
fprintf( stderr, "The -Z option is not available on this operating system\n");
#endif
}
// check if we're sending multicast, and set TTL
if ( isMulticast( inSettings ) && ( inSettings->mTTL > 0 ) ) {
int val = inSettings->mTTL;
#ifdef HAVE_MULTICAST
if ( !SockAddr_isIPv6( &inSettings->local ) ) {
int rc = setsockopt( inSettings->mSock, IPPROTO_IP, IP_MULTICAST_TTL,
(const void*) &val, (Socklen_t) sizeof(val));
WARN_errno( rc == SOCKET_ERROR, "multicast ttl" );
}
#ifdef HAVE_IPV6_MULTICAST
else {
int rc = setsockopt( inSettings->mSock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
(const void*) &val, (Socklen_t) sizeof(val));
WARN_errno( rc == SOCKET_ERROR, "multicast ttl" );
}
#endif
#endif
}
#ifdef IP_TOS
// set IP TOS (type-of-service) field
if ( inSettings->mTOS > 0 ) {
int tos = inSettings->mTOS;
Socklen_t len = sizeof(tos);
int rc = setsockopt( inSettings->mSock, IPPROTO_IP, IP_TOS,
(char*) &tos, len );
WARN_errno( rc == SOCKET_ERROR, "setsockopt IP_TOS" );
}
#endif
if ( !isUDP( inSettings ) ) {
// set the TCP maximum segment size
setsock_tcp_mss( inSettings->mSock, inSettings->mMSS );
#ifdef TCP_NODELAY
// set TCP nodelay option
if ( isNoDelay( inSettings ) ) {
int nodelay = 1;
Socklen_t len = sizeof(nodelay);
int rc = setsockopt( inSettings->mSock, IPPROTO_TCP, TCP_NODELAY,
(char*) &nodelay, len );
WARN_errno( rc == SOCKET_ERROR, "setsockopt TCP_NODELAY" );
}
#endif
}
}
// end SetSocketOptions

View File

@ -1,157 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* ReportCSV.c
* by Kevin Gibbs <kgibbs@nlanr.net>
*
* ________________________________________________________________ */
#include "headers.h"
#include "Settings.hpp"
#include "util.h"
#include "Reporter.h"
#include "report_CSV.h"
#include "Locale.h"
void CSV_timestamp( char *timestamp, int length );
void CSV_stats( Transfer_Info *stats ) {
// $TIMESTAMP,$ID,$INTERVAL,$BYTE,$SPEED,$JITTER,$LOSS,$PACKET,$%LOSS
max_size_t speed = (max_size_t)(((double)stats->TotalLen * 8.0) / (stats->endTime - stats->startTime));
char timestamp[16];
CSV_timestamp( timestamp, sizeof(timestamp) );
if ( stats->mUDP != (char)kMode_Server ) {
// TCP Reporting
printf( reportCSV_bw_format,
timestamp,
(stats->reserved_delay == NULL ? ",,," : stats->reserved_delay),
stats->transferID,
stats->startTime,
stats->endTime,
stats->TotalLen,
speed);
} else {
// UDP Reporting
printf( reportCSV_bw_jitter_loss_format,
timestamp,
(stats->reserved_delay == NULL ? ",,," : stats->reserved_delay),
stats->transferID,
stats->startTime,
stats->endTime,
stats->TotalLen,
speed,
stats->jitter*1000.0,
stats->cntError,
stats->cntDatagrams,
(100.0 * stats->cntError) / stats->cntDatagrams, stats->cntOutofOrder );
}
if ( stats->free == 1 && stats->reserved_delay != NULL ) {
free( stats->reserved_delay );
}
}
void *CSV_peer( Connection_Info *stats, int ID ) {
// copy the inet_ntop into temp buffers, to avoid overwriting
char local_addr[ REPORT_ADDRLEN ];
char remote_addr[ REPORT_ADDRLEN ];
char *buf = malloc( REPORT_ADDRLEN*2 + 10 );
struct sockaddr *local = ((struct sockaddr*)&stats->local);
struct sockaddr *peer = ((struct sockaddr*)&stats->peer);
if ( local->sa_family == AF_INET ) {
inet_ntop( AF_INET, &((struct sockaddr_in*)local)->sin_addr,
local_addr, REPORT_ADDRLEN);
}
#ifdef HAVE_IPV6
else {
inet_ntop( AF_INET6, &((struct sockaddr_in6*)local)->sin6_addr,
local_addr, REPORT_ADDRLEN);
}
#endif
if ( peer->sa_family == AF_INET ) {
inet_ntop( AF_INET, &((struct sockaddr_in*)peer)->sin_addr,
remote_addr, REPORT_ADDRLEN);
}
#ifdef HAVE_IPV6
else {
inet_ntop( AF_INET6, &((struct sockaddr_in6*)peer)->sin6_addr,
remote_addr, REPORT_ADDRLEN);
}
#endif
snprintf(buf, REPORT_ADDRLEN*2+10, reportCSV_peer,
local_addr, ( local->sa_family == AF_INET ?
ntohs(((struct sockaddr_in*)local)->sin_port) :
#ifdef HAVE_IPV6
ntohs(((struct sockaddr_in6*)local)->sin6_port)),
#else
0),
#endif
remote_addr, ( peer->sa_family == AF_INET ?
ntohs(((struct sockaddr_in*)peer)->sin_port) :
#ifdef HAVE_IPV6
ntohs(((struct sockaddr_in6*)peer)->sin6_port)));
#else
0));
#endif
return buf;
}
void CSV_serverstats( Connection_Info *conn, Transfer_Info *stats ) {
stats->reserved_delay = CSV_peer( conn, stats->transferID );
stats->free = 1;
CSV_stats( stats );
}
void CSV_timestamp( char *timestamp, int length ) {
time_t times;
struct tm *timest;
times = time( NULL );
timest = localtime( &times );
strftime( timestamp, length,"%Y%m%d%H%M%S", timest );
}

View File

@ -1,303 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* ReportDefault.c
* by Kevin Gibbs <kgibbs@nlanr.net>
*
* ________________________________________________________________ */
#include "headers.h"
#include "Settings.hpp"
#include "util.h"
#include "Reporter.h"
#include "report_default.h"
#include "Thread.h"
#include "Locale.h"
#include "PerfSocket.hpp"
#include "SocketAddr.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Prints transfer reports in default style
*/
void reporter_printstats( Transfer_Info *stats ) {
static char header_printed = 0;
byte_snprintf( buffer, sizeof(buffer)/2, (double) stats->TotalLen,
toupper( stats->mFormat));
byte_snprintf( &buffer[sizeof(buffer)/2], sizeof(buffer)/2,
stats->TotalLen / (stats->endTime - stats->startTime),
stats->mFormat);
if ( stats->mUDP != (char)kMode_Server ) {
// TCP Reporting
if( !header_printed ) {
printf( report_bw_header);
header_printed = 1;
}
printf( report_bw_format, stats->transferID,
stats->startTime, stats->endTime,
buffer, &buffer[sizeof(buffer)/2] );
} else {
// UDP Reporting
if( !header_printed ) {
printf( report_bw_jitter_loss_header);
header_printed = 1;
}
printf( report_bw_jitter_loss_format, stats->transferID,
stats->startTime, stats->endTime,
buffer, &buffer[sizeof(buffer)/2],
stats->jitter*1000.0, stats->cntError, stats->cntDatagrams,
(100.0 * stats->cntError) / stats->cntDatagrams );
if ( stats->cntOutofOrder > 0 ) {
printf( report_outoforder,
stats->transferID, stats->startTime,
stats->endTime, stats->cntOutofOrder );
}
}
if ( stats->free == 1 && stats->mUDP == (char)kMode_Client ) {
printf( report_datagrams, stats->transferID, stats->cntDatagrams );
}
}
/*
* Prints multiple transfer reports in default style
*/
void reporter_multistats( Transfer_Info *stats ) {
byte_snprintf( buffer, sizeof(buffer)/2, (double) stats->TotalLen,
toupper( stats->mFormat));
byte_snprintf( &buffer[sizeof(buffer)/2], sizeof(buffer)/2,
stats->TotalLen / (stats->endTime - stats->startTime),
stats->mFormat);
if ( stats->mUDP != (char)kMode_Server ) {
// TCP Reporting
printf( report_sum_bw_format,
stats->startTime, stats->endTime,
buffer, &buffer[sizeof(buffer)/2] );
} else {
// UDP Reporting
printf( report_sum_bw_jitter_loss_format,
stats->startTime, stats->endTime,
buffer, &buffer[sizeof(buffer)/2],
stats->jitter*1000.0, stats->cntError, stats->cntDatagrams,
(100.0 * stats->cntError) / stats->cntDatagrams );
if ( stats->cntOutofOrder > 0 ) {
printf( report_sum_outoforder,
stats->startTime,
stats->endTime, stats->cntOutofOrder );
}
}
if ( stats->free == 1 && stats->mUDP == (char)kMode_Client ) {
printf( report_sum_datagrams, stats->cntDatagrams );
}
}
/*
* Prints server transfer reports in default style
*/
void reporter_serverstats( Connection_Info *nused, Transfer_Info *stats ) {
printf( server_reporting, stats->transferID );
reporter_printstats( stats );
}
/*
* Report the client or listener Settings in default style
*/
void reporter_reportsettings( ReporterData *data ) {
int win, win_requested;
win = getsock_tcp_windowsize( data->info.transferID,
(data->mThreadMode == kMode_Listener ? 0 : 1) );
win_requested = data->mTCPWin;
printf( seperator_line );
if ( data->mThreadMode == kMode_Listener ) {
printf( server_port,
(isUDP( data ) ? "UDP" : "TCP"),
data->mPort );
} else {
printf( client_port,
data->mHost,
(isUDP( data ) ? "UDP" : "TCP"),
data->mPort );
}
if ( data->mLocalhost != NULL ) {
printf( bind_address, data->mLocalhost );
if ( SockAddr_isMulticast( &data->connection.local ) ) {
printf( join_multicast, data->mLocalhost );
}
}
if ( isUDP( data ) ) {
printf( (data->mThreadMode == kMode_Listener ?
server_datagram_size : client_datagram_size),
data->mBufLen );
if ( SockAddr_isMulticast( &data->connection.peer ) ) {
printf( multicast_ttl, data->info.mTTL);
}
}
byte_snprintf( buffer, sizeof(buffer), win,
toupper( data->info.mFormat));
printf( "%s: %s", (isUDP( data ) ?
udp_buffer_size : tcp_window_size), buffer );
if ( win_requested == 0 ) {
printf( " %s", window_default );
} else if ( win != win_requested ) {
byte_snprintf( buffer, sizeof(buffer), win_requested,
toupper( data->info.mFormat));
printf( warn_window_requested, buffer );
}
printf( "\n" );
printf( seperator_line );
}
/*
* Report a socket's peer IP address in default style
*/
void *reporter_reportpeer( Connection_Info *stats, int ID ) {
if ( ID > 0 ) {
// copy the inet_ntop into temp buffers, to avoid overwriting
char local_addr[ REPORT_ADDRLEN ];
char remote_addr[ REPORT_ADDRLEN ];
struct sockaddr *local = ((struct sockaddr*)&stats->local);
struct sockaddr *peer = ((struct sockaddr*)&stats->peer);
if ( local->sa_family == AF_INET ) {
inet_ntop( AF_INET, &((struct sockaddr_in*)local)->sin_addr,
local_addr, REPORT_ADDRLEN);
}
#ifdef HAVE_IPV6
else {
inet_ntop( AF_INET6, &((struct sockaddr_in6*)local)->sin6_addr,
local_addr, REPORT_ADDRLEN);
}
#endif
if ( peer->sa_family == AF_INET ) {
inet_ntop( AF_INET, &((struct sockaddr_in*)peer)->sin_addr,
remote_addr, REPORT_ADDRLEN);
}
#ifdef HAVE_IPV6
else {
inet_ntop( AF_INET6, &((struct sockaddr_in6*)peer)->sin6_addr,
remote_addr, REPORT_ADDRLEN);
}
#endif
printf( report_peer,
ID,
local_addr, ( local->sa_family == AF_INET ?
ntohs(((struct sockaddr_in*)local)->sin_port) :
#ifdef HAVE_IPV6
ntohs(((struct sockaddr_in6*)local)->sin6_port)),
#else
0),
#endif
remote_addr, ( peer->sa_family == AF_INET ?
ntohs(((struct sockaddr_in*)peer)->sin_port) :
#ifdef HAVE_IPV6
ntohs(((struct sockaddr_in6*)peer)->sin6_port)));
#else
0));
#endif
}
return NULL;
}
// end ReportPeer
/* -------------------------------------------------------------------
* Report the MSS and MTU, given the MSS (or a guess thereof)
* ------------------------------------------------------------------- */
// compare the MSS against the (MTU - 40) to (MTU - 80) bytes.
// 40 byte IP header and somewhat arbitrarily, 40 more bytes of IP options.
#define checkMSS_MTU( inMSS, inMTU ) (inMTU-40) >= inMSS && inMSS >= (inMTU-80)
void reporter_reportMSS( int inMSS, thread_Settings *inSettings ) {
if ( inMSS <= 0 ) {
printf( report_mss_unsupported, inSettings->mSock );
} else {
char* net;
int mtu = 0;
if ( checkMSS_MTU( inMSS, 1500 ) ) {
net = "ethernet";
mtu = 1500;
} else if ( checkMSS_MTU( inMSS, 4352 ) ) {
net = "FDDI";
mtu = 4352;
} else if ( checkMSS_MTU( inMSS, 9180 ) ) {
net = "ATM";
mtu = 9180;
} else if ( checkMSS_MTU( inMSS, 65280 ) ) {
net = "HIPPI";
mtu = 65280;
} else if ( checkMSS_MTU( inMSS, 576 ) ) {
net = "minimum";
mtu = 576;
printf( warn_no_pathmtu );
} else {
mtu = inMSS + 40;
net = "unknown interface";
}
printf( report_mss,
inSettings->mSock, inMSS, mtu, net );
}
}
// end ReportMSS
#ifdef __cplusplus
} /* end extern "C" */
#endif

View File

@ -1,932 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Reporter.c
* by Kevin Gibbs <kgibbs@nlanr.net>
*
* ________________________________________________________________ */
#include "headers.h"
#include "Settings.hpp"
#include "util.h"
#include "Reporter.h"
#include "Thread.h"
#include "Locale.h"
#include "PerfSocket.hpp"
#include "SocketAddr.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
The following 4 functions are provided for Reporting
styles that do not have all the reporting formats. For
instance the provided CSV format does not have a settings
report so it uses settings_notimpl.
*/
void* connection_notimpl( Connection_Info * nused, int nuse ) {
return NULL;
}
void settings_notimpl( ReporterData * nused ) { }
void statistics_notimpl( Transfer_Info * nused ) { }
void serverstatistics_notimpl( Connection_Info *nused1, Transfer_Info *nused2 ) { }
// To add a reporting style include its header here.
#include "report_default.h"
#include "report_CSV.h"
// The following array of report structs contains the
// pointers required for reporting in different reporting
// styles. To add a reporting style add a report struct
// below.
report_connection connection_reports[kReport_MAXIMUM] = {
reporter_reportpeer,
CSV_peer
};
report_settings settings_reports[kReport_MAXIMUM] = {
reporter_reportsettings,
settings_notimpl
};
report_statistics statistics_reports[kReport_MAXIMUM] = {
reporter_printstats,
CSV_stats
};
report_serverstatistics serverstatistics_reports[kReport_MAXIMUM] = {
reporter_serverstats,
CSV_serverstats
};
report_statistics multiple_reports[kReport_MAXIMUM] = {
reporter_multistats,
CSV_stats
};
char buffer[64]; // Buffer for printing
ReportHeader *ReportRoot = NULL;
int threadWait = 0;
int threadSleeping = 0;
extern Condition ReportCond;
int reporter_process_report ( ReportHeader *report );
void process_report ( ReportHeader *report );
int reporter_handle_packet( ReportHeader *report );
int reporter_condprintstats( ReporterData *stats, MultiHeader *multireport, int force );
int reporter_print( ReporterData *stats, int type, int end );
void PrintMSS( ReporterData *stats );
MultiHeader* InitMulti( thread_Settings *agent, int inID ) {
MultiHeader *multihdr = NULL;
if ( agent->mThreads > 1 || agent->mThreadMode == kMode_Server ) {
if ( isMultipleReport( agent ) ) {
multihdr = malloc(sizeof(MultiHeader) + sizeof(ReporterData) +
NUM_MULTI_SLOTS * sizeof(Transfer_Info));
} else {
multihdr = malloc(sizeof(MultiHeader));
}
if ( multihdr != NULL ) {
memset( multihdr, 0, sizeof(MultiHeader) );
Condition_Initialize( &multihdr->barrier );
multihdr->groupID = inID;
multihdr->threads = agent->mThreads;
if ( isMultipleReport( agent ) ) {
int i;
ReporterData *data = NULL;
multihdr->report = (ReporterData*)(multihdr + 1);
memset(multihdr->report, 0, sizeof(ReporterData));
multihdr->data = (Transfer_Info*)(multihdr->report + 1);
data = multihdr->report;
for ( i = 0; i < NUM_MULTI_SLOTS; i++ ) {
multihdr->data[i].startTime = -1;
multihdr->data[i].transferID = inID;
multihdr->data[i].groupID = -2;
}
data->type = TRANSFER_REPORT;
if ( agent->mInterval != 0.0 ) {
struct timeval *interval = &data->intervalTime;
interval->tv_sec = (long) agent->mInterval;
interval->tv_usec = (long) ((agent->mInterval - interval->tv_sec)
* rMillion);
}
data->mHost = agent->mHost;
data->mLocalhost = agent->mLocalhost;
data->mBufLen = agent->mBufLen;
data->mMSS = agent->mMSS;
data->mTCPWin = agent->mTCPWin;
data->flags = agent->flags;
data->mThreadMode = agent->mThreadMode;
data->mode = agent->mReportMode;
data->info.mFormat = agent->mFormat;
data->info.mTTL = agent->mTTL;
if ( isUDP( agent ) ) {
multihdr->report->info.mUDP = (char)agent->mThreadMode;
}
if ( isConnectionReport( agent ) ) {
data->type |= CONNECTION_REPORT;
data->connection.peer = agent->peer;
data->connection.size_peer = agent->size_peer;
SockAddr_setPortAny( &data->connection.peer );
data->connection.local = agent->local;
data->connection.size_local = agent->size_local;
SockAddr_setPortAny( &data->connection.local );
}
}
} else {
FAIL(1, "Out of Memory!!\n", agent);
}
}
return multihdr;
}
/*
* BarrierClient allows for multiple stream clients to be syncronized
*/
void BarrierClient( ReportHeader *agent ) {
Condition_Lock(agent->multireport->barrier);
agent->multireport->threads--;
if ( agent->multireport->threads == 0 ) {
// last one set time and wake up everyone
gettimeofday( &(agent->multireport->startTime), NULL );
Condition_Broadcast( &agent->multireport->barrier );
} else {
Condition_Wait( &agent->multireport->barrier );
}
agent->multireport->threads++;
Condition_Unlock( agent->multireport->barrier );
agent->report.startTime = agent->multireport->startTime;
agent->report.nextTime = agent->report.startTime;
TimeAdd( agent->report.nextTime, agent->report.intervalTime );
}
/*
* InitReport is called by a transfer agent (client or
* server) to setup the needed structures to communicate
* traffic.
*/
ReportHeader* InitReport( thread_Settings *agent ) {
ReportHeader *reporthdr = NULL;
ReporterData *data = NULL;
if ( isDataReport( agent ) ) {
/*
* Create in one big chunk
*/
reporthdr = malloc( sizeof(ReportHeader) +
NUM_REPORT_STRUCTS * sizeof(ReportStruct) );
if ( reporthdr != NULL ) {
// Only need to make sure the headers are clean
memset( reporthdr, 0, sizeof(ReportHeader));
reporthdr->data = (ReportStruct*)(reporthdr+1);
reporthdr->multireport = agent->multihdr;
data = &reporthdr->report;
reporthdr->reporterindex = NUM_REPORT_STRUCTS - 1;
data->info.transferID = agent->mSock;
data->info.groupID = (agent->multihdr != NULL ? agent->multihdr->groupID
: -1);
data->type = TRANSFER_REPORT;
if ( agent->mInterval != 0.0 ) {
struct timeval *interval = &data->intervalTime;
interval->tv_sec = (long) agent->mInterval;
interval->tv_usec = (long) ((agent->mInterval - interval->tv_sec)
* rMillion);
}
data->mHost = agent->mHost;
data->mLocalhost = agent->mLocalhost;
data->mBufLen = agent->mBufLen;
data->mMSS = agent->mMSS;
data->mTCPWin = agent->mTCPWin;
data->flags = agent->flags;
data->mThreadMode = agent->mThreadMode;
data->mode = agent->mReportMode;
data->info.mFormat = agent->mFormat;
data->info.mTTL = agent->mTTL;
if ( isUDP( agent ) ) {
reporthdr->report.info.mUDP = (char)agent->mThreadMode;
}
} else {
FAIL(1, "Out of Memory!!\n", agent);
}
}
if ( isConnectionReport( agent ) ) {
if ( reporthdr == NULL ) {
/*
* Create in one big chunk
*/
reporthdr = malloc( sizeof(ReportHeader) );
if ( reporthdr != NULL ) {
// Only need to make sure the headers are clean
memset( reporthdr, 0, sizeof(ReportHeader));
data = &reporthdr->report;
data->info.transferID = agent->mSock;
data->info.groupID = -1;
} else {
FAIL(1, "Out of Memory!!\n", agent);
}
}
if ( reporthdr != NULL ) {
data->type |= CONNECTION_REPORT;
data->connection.peer = agent->peer;
data->connection.size_peer = agent->size_peer;
data->connection.local = agent->local;
data->connection.size_local = agent->size_local;
} else {
FAIL(1, "Out of Memory!!\n", agent);
}
}
if ( isConnectionReport( agent ) || isDataReport( agent ) ) {
#ifdef HAVE_THREAD
/*
* Update the ReportRoot to include this report.
*/
if ( reporthdr->report.mThreadMode == kMode_Client &&
reporthdr->multireport != NULL ) {
// syncronize watches on my mark......
BarrierClient( reporthdr );
} else {
if ( reporthdr->multireport != NULL && isMultipleReport( agent )) {
reporthdr->multireport->threads++;
if ( reporthdr->multireport->report->startTime.tv_sec == 0 ) {
gettimeofday( &(reporthdr->multireport->report->startTime), NULL );
}
reporthdr->report.startTime = reporthdr->multireport->report->startTime;
} else {
// set start time
gettimeofday( &(reporthdr->report.startTime), NULL );
}
reporthdr->report.nextTime = reporthdr->report.startTime;
TimeAdd( reporthdr->report.nextTime, reporthdr->report.intervalTime );
}
Condition_Lock( ReportCond );
reporthdr->next = ReportRoot;
ReportRoot = reporthdr;
Condition_Signal( &ReportCond );
Condition_Unlock( ReportCond );
#else
// set start time
gettimeofday( &(reporthdr->report.startTime), NULL );
/*
* Process the report in this thread
*/
reporthdr->next = NULL;
process_report ( reporthdr );
#endif
}
if ( !isDataReport( agent ) ) {
reporthdr = NULL;
}
return reporthdr;
}
/*
* ReportPacket is called by a transfer agent to record
* the arrival or departure of a "packet" (for TCP it
* will actually represent many packets). This needs to
* be as simple and fast as possible as it gets called for
* every "packet".
*/
void ReportPacket( ReportHeader* agent, ReportStruct *packet ) {
if ( agent != NULL ) {
int index = agent->reporterindex;
/*
* First find the appropriate place to put the information
*/
if ( agent->agentindex == NUM_REPORT_STRUCTS ) {
// Just need to make sure that reporter is not on the first
// item
while ( index == 0 ) {
Condition_Signal( &ReportCond );
thread_rest();
index = agent->reporterindex;
}
agent->agentindex = 0;
}
// Need to make sure that reporter is not about to be "lapped"
while ( index - 1 == agent->agentindex ) {
Condition_Signal( &ReportCond );
thread_rest();
index = agent->reporterindex;
}
if (threadSleeping)
Condition_Signal( &ReportCond );
// Put the information there
memcpy( agent->data + agent->agentindex, packet, sizeof(ReportStruct) );
// Updating agentindex MUST be the last thing done
agent->agentindex++;
#ifndef HAVE_THREAD
/*
* Process the report in this thread
*/
process_report ( agent );
#endif
}
}
/*
* CloseReport is called by a transfer agent to finalize
* the report and signal transfer is over.
*/
void CloseReport( ReportHeader *agent, ReportStruct *packet ) {
if ( agent != NULL) {
/*
* Using PacketID of -1 ends reporting
*/
packet->packetID = -1;
packet->packetLen = 0;
ReportPacket( agent, packet );
packet->packetID = agent->report.cntDatagrams;
if (threadSleeping)
Condition_Signal( &ReportCond );
}
}
/*
* EndReport signifies the agent no longer is interested
* in the report. Calls to GetReport will no longer be
* filled
*/
void EndReport( ReportHeader *agent ) {
if ( agent != NULL ) {
int index = agent->reporterindex;
if (threadSleeping)
Condition_Signal( &ReportCond );
while ( index != -1 ) {
thread_rest();
index = agent->reporterindex;
}
agent->agentindex = -1;
#ifndef HAVE_THREAD
/*
* Process the report in this thread
*/
process_report ( agent );
#endif
}
}
/*
* GetReport is called by the agent after a CloseReport
* but before an EndReport to get the stats generated
* by the reporter thread.
*/
Transfer_Info *GetReport( ReportHeader *agent ) {
int index = agent->reporterindex;
while ( index != -1 ) {
thread_rest();
index = agent->reporterindex;
}
return &agent->report.info;
}
/*
* ReportSettings will generate a summary report for
* settings being used with Listeners or Clients
*/
void ReportSettings( thread_Settings *agent ) {
if ( isSettingsReport( agent ) ) {
/*
* Create in one big chunk
*/
ReportHeader *reporthdr = malloc( sizeof(ReportHeader) );
if ( reporthdr != NULL ) {
ReporterData *data = &reporthdr->report;
data->info.transferID = agent->mSock;
data->info.groupID = -1;
reporthdr->agentindex = -1;
reporthdr->reporterindex = -1;
data->mHost = agent->mHost;
data->mLocalhost = agent->mLocalhost;
data->mode = agent->mReportMode;
data->type = SETTINGS_REPORT;
data->mBufLen = agent->mBufLen;
data->mMSS = agent->mMSS;
data->mTCPWin = agent->mTCPWin;
data->flags = agent->flags;
data->mThreadMode = agent->mThreadMode;
data->mPort = agent->mPort;
data->info.mFormat = agent->mFormat;
data->info.mTTL = agent->mTTL;
data->connection.peer = agent->peer;
data->connection.size_peer = agent->size_peer;
data->connection.local = agent->local;
data->connection.size_local = agent->size_local;
#ifdef HAVE_THREAD
/*
* Update the ReportRoot to include this report.
*/
Condition_Lock( ReportCond );
if ( isUDP(agent) )
threadWait = 0;
else
threadWait = 1;
reporthdr->next = ReportRoot;
ReportRoot = reporthdr;
Condition_Signal( &ReportCond );
Condition_Unlock( ReportCond );
#else
/*
* Process the report in this thread
*/
reporthdr->next = NULL;
process_report ( reporthdr );
#endif
} else {
FAIL(1, "Out of Memory!!\n", agent);
}
}
}
/*
* ReportServerUDP will generate a report of the UDP
* statistics as reported by the server on the client
* side.
*/
void ReportServerUDP( thread_Settings *agent, server_hdr *server ) {
if ( (ntohl(server->flags) & HEADER_VERSION1) != 0 &&
isServerReport( agent ) ) {
/*
* Create in one big chunk
*/
ReportHeader *reporthdr = malloc( sizeof(ReportHeader) );
Transfer_Info *stats = &reporthdr->report.info;
if ( reporthdr != NULL ) {
stats->transferID = agent->mSock;
stats->groupID = (agent->multihdr != NULL ? agent->multihdr->groupID
: -1);
reporthdr->agentindex = -1;
reporthdr->reporterindex = -1;
reporthdr->report.type = SERVER_RELAY_REPORT;
reporthdr->report.mode = agent->mReportMode;
stats->mFormat = agent->mFormat;
stats->jitter = ntohl( server->jitter1 );
stats->jitter += ntohl( server->jitter2 ) / (double)rMillion;
stats->TotalLen = (((max_size_t) ntohl( server->total_len1 )) << 32) +
ntohl( server->total_len2 );
stats->startTime = 0;
stats->endTime = ntohl( server->stop_sec );
stats->endTime += ntohl( server->stop_usec ) / (double)rMillion;
stats->cntError = ntohl( server->error_cnt );
stats->cntOutofOrder = ntohl( server->outorder_cnt );
stats->cntDatagrams = ntohl( server->datagrams );
stats->mUDP = (char)kMode_Server;
reporthdr->report.connection.peer = agent->local;
reporthdr->report.connection.size_peer = agent->size_local;
reporthdr->report.connection.local = agent->peer;
reporthdr->report.connection.size_local = agent->size_peer;
#ifdef HAVE_THREAD
/*
* Update the ReportRoot to include this report.
*/
Condition_Lock( ReportCond );
reporthdr->next = ReportRoot;
ReportRoot = reporthdr;
Condition_Signal( &ReportCond );
Condition_Unlock( ReportCond );
#else
/*
* Process the report in this thread
*/
reporthdr->next = NULL;
process_report ( reporthdr );
#endif
} else {
FAIL(1, "Out of Memory!!\n", agent);
}
}
}
/*
* This function is called only when the reporter thread
* This function is the loop that the reporter thread processes
*/
void reporter_spawn( thread_Settings *thread ) {
do {
// This section allows for safe exiting with Ctrl-C
Condition_Lock ( ReportCond );
if ( ReportRoot == NULL ) {
// Allow main thread to exit if Ctrl-C is received
thread_setignore();
Condition_Wait ( &ReportCond );
// Stop main thread from exiting until done with all reports
thread_unsetignore();
}
Condition_Unlock ( ReportCond );
if ( ReportRoot != NULL ) {
ReportHeader *temp = ReportRoot;
//Condition_Unlock ( ReportCond );
if ( reporter_process_report ( temp ) ) {
// This section allows for more reports to be added while
// the reporter is processing reports without needing to
// stop the reporter or immediately notify it
Condition_Lock ( ReportCond );
if ( temp == ReportRoot ) {
// no new reports
ReportRoot = temp->next;
} else {
// new reports added
ReportHeader *itr = ReportRoot;
while ( itr->next != temp ) {
itr = itr->next;
}
itr->next = temp->next;
}
// finished with report so free it
free( temp );
Condition_Unlock ( ReportCond );
}
// yield control of CPU is another thread is waiting
// sleep on a condition variable, as it is much cheaper
// on most platforms than issuing schedyield or usleep
// syscalls
Condition_Lock ( ReportCond );
if ( threadWait && ReportRoot != NULL) {
threadSleeping = 1;
Condition_TimedWait (& ReportCond, 1 );
threadSleeping = 0;
}
Condition_Unlock ( ReportCond );
} else {
//Condition_Unlock ( ReportCond );
}
} while ( 1 );
}
/*
* Used for single threaded reporting
*/
void process_report ( ReportHeader *report ) {
if ( report != NULL ) {
if ( reporter_process_report( report ) ) {
free( report );
}
}
}
/*
* Process reports starting with "reporthdr"
*/
int reporter_process_report ( ReportHeader *reporthdr ) {
int need_free = 0;
// Recursively process reports
if ( reporthdr->next != NULL ) {
if ( reporter_process_report( reporthdr->next ) ) {
// If we are done with this report then free it
ReportHeader *temp = reporthdr->next;
reporthdr->next = reporthdr->next->next;
free( temp );
}
}
if ( (reporthdr->report.type & SETTINGS_REPORT) != 0 ) {
reporthdr->report.type &= ~SETTINGS_REPORT;
return reporter_print( &reporthdr->report, SETTINGS_REPORT, 1 );
} else if ( (reporthdr->report.type & CONNECTION_REPORT) != 0 ) {
reporthdr->report.type &= ~CONNECTION_REPORT;
reporter_print( &reporthdr->report, CONNECTION_REPORT,
(reporthdr->report.type == 0 ? 1 : 0) );
if ( reporthdr->multireport != NULL && isMultipleReport( (&reporthdr->report) )) {
if ( (reporthdr->multireport->report->type & CONNECTION_REPORT) != 0 ) {
reporthdr->multireport->report->type &= ~CONNECTION_REPORT;
reporter_print( reporthdr->multireport->report, CONNECTION_REPORT,
(reporthdr->report.type == 0 ? 1 : 0) );
}
}
} else if ( (reporthdr->report.type & SERVER_RELAY_REPORT) != 0 ) {
reporthdr->report.type &= ~SERVER_RELAY_REPORT;
return reporter_print( &reporthdr->report, SERVER_RELAY_REPORT, 1 );
}
if ( (reporthdr->report.type & TRANSFER_REPORT) != 0 ) {
// If there are more packets to process then handle them
if ( reporthdr->reporterindex >= 0 ) {
// Need to make sure we do not pass the "agent"
while ( reporthdr->reporterindex != reporthdr->agentindex - 1 ) {
if ( reporthdr->reporterindex == NUM_REPORT_STRUCTS - 1 ) {
if ( reporthdr->agentindex == 0 ) {
break;
} else {
reporthdr->reporterindex = 0;
}
} else {
reporthdr->reporterindex++;
}
if ( reporter_handle_packet( reporthdr ) ) {
// No more packets to process
reporthdr->reporterindex = -1;
break;
}
}
}
// If the agent is done with the report then free it
if ( reporthdr->agentindex == -1 ) {
need_free = 1;
}
}
return need_free;
}
/*
* Updates connection stats
*/
int reporter_handle_packet( ReportHeader *reporthdr ) {
ReportStruct *packet = &reporthdr->data[reporthdr->reporterindex];
ReporterData *data = &reporthdr->report;
Transfer_Info *stats = &reporthdr->report.info;
int finished = 0;
data->cntDatagrams++;
// If this is the last packet set the endTime
if ( packet->packetID < 0 ) {
data->packetTime = packet->packetTime;
finished = 1;
if ( reporthdr->report.mThreadMode != kMode_Client ) {
data->TotalLen += packet->packetLen;
}
} else {
// update recieved amount and time
data->packetTime = packet->packetTime;
reporter_condprintstats( &reporthdr->report, reporthdr->multireport, finished );
data->TotalLen += packet->packetLen;
if ( packet->packetID != 0 ) {
// UDP packet
double transit;
double deltaTransit;
// from RFC 1889, Real Time Protocol (RTP)
// J = J + ( | D(i-1,i) | - J ) / 16
transit = TimeDifference( packet->packetTime, packet->sentTime );
if ( data->lastTransit != 0.0 ) {
deltaTransit = transit - data->lastTransit;
if ( deltaTransit < 0.0 ) {
deltaTransit = -deltaTransit;
}
stats->jitter += (deltaTransit - stats->jitter) / (16.0);
}
data->lastTransit = transit;
// packet loss occured if the datagram numbers aren't sequential
if ( packet->packetID != data->PacketID + 1 ) {
if ( packet->packetID < data->PacketID + 1 ) {
data->cntOutofOrder++;
} else {
data->cntError += packet->packetID - data->PacketID - 1;
}
}
// never decrease datagramID (e.g. if we get an out-of-order packet)
if ( packet->packetID > data->PacketID ) {
data->PacketID = packet->packetID;
}
}
}
// Print a report if appropriate
return reporter_condprintstats( &reporthdr->report, reporthdr->multireport, finished );
}
/*
* Handles summing of threads
*/
void reporter_handle_multiple_reports( MultiHeader *reporthdr, Transfer_Info *stats, int force ) {
if ( reporthdr != NULL ) {
if ( reporthdr->threads > 1 ) {
int i;
Transfer_Info *current = NULL;
// Search for start Time
for ( i = 0; i < NUM_MULTI_SLOTS; i++ ) {
current = &reporthdr->data[i];
if ( current->startTime == stats->startTime ) {
break;
}
}
if ( current->startTime != stats->startTime ) {
// Find first available
for ( i = 0; i < NUM_MULTI_SLOTS; i++ ) {
current = &reporthdr->data[i];
if ( current->startTime < 0 ) {
break;
}
}
current->cntDatagrams = stats->cntDatagrams;
current->cntError = stats->cntError;
current->cntOutofOrder = stats->cntOutofOrder;
current->TotalLen = stats->TotalLen;
current->mFormat = stats->mFormat;
current->endTime = stats->endTime;
current->jitter = stats->jitter;
current->startTime = stats->startTime;
current->free = 1;
} else {
current->cntDatagrams += stats->cntDatagrams;
current->cntError += stats->cntError;
current->cntOutofOrder += stats->cntOutofOrder;
current->TotalLen += stats->TotalLen;
current->mFormat = stats->mFormat;
if ( current->endTime < stats->endTime ) {
current->endTime = stats->endTime;
}
if ( current->jitter < stats->jitter ) {
current->jitter = stats->jitter;
}
current->free++;
if ( current->free == reporthdr->threads ) {
void *reserved = reporthdr->report->info.reserved_delay;
current->free = force;
memcpy( &reporthdr->report->info, current, sizeof(Transfer_Info) );
current->startTime = -1;
reporthdr->report->info.reserved_delay = reserved;
reporter_print( reporthdr->report, MULTIPLE_REPORT, force );
}
}
}
}
}
/*
* Prints reports conditionally
*/
int reporter_condprintstats( ReporterData *stats, MultiHeader *multireport, int force ) {
if ( force != 0 ) {
stats->info.cntOutofOrder = stats->cntOutofOrder;
// assume most of the time out-of-order packets are not
// duplicate packets, so conditionally subtract them from the lost packets.
stats->info.cntError = stats->cntError;
if ( stats->info.cntError > stats->info.cntOutofOrder ) {
stats->info.cntError -= stats->info.cntOutofOrder;
}
stats->info.cntDatagrams = (isUDP(stats) ? stats->PacketID : stats->cntDatagrams);
stats->info.TotalLen = stats->TotalLen;
stats->info.startTime = 0;
stats->info.endTime = TimeDifference( stats->packetTime, stats->startTime );
stats->info.free = 1;
reporter_print( stats, TRANSFER_REPORT, force );
if ( isMultipleReport(stats) ) {
reporter_handle_multiple_reports( multireport, &stats->info, force );
}
} else while ((stats->intervalTime.tv_sec != 0 ||
stats->intervalTime.tv_usec != 0) &&
TimeDifference( stats->nextTime,
stats->packetTime ) < 0 ) {
stats->info.cntOutofOrder = stats->cntOutofOrder - stats->lastOutofOrder;
stats->lastOutofOrder = stats->cntOutofOrder;
// assume most of the time out-of-order packets are not
// duplicate packets, so conditionally subtract them from the lost packets.
stats->info.cntError = stats->cntError - stats->lastError;
if ( stats->info.cntError > stats->info.cntOutofOrder ) {
stats->info.cntError -= stats->info.cntOutofOrder;
}
stats->lastError = stats->cntError;
stats->info.cntDatagrams = (isUDP( stats ) ? stats->PacketID - stats->lastDatagrams :
stats->cntDatagrams - stats->lastDatagrams);
stats->lastDatagrams = (isUDP( stats ) ? stats->PacketID : stats->cntDatagrams);
stats->info.TotalLen = stats->TotalLen - stats->lastTotal;
stats->lastTotal = stats->TotalLen;
stats->info.startTime = stats->info.endTime;
stats->info.endTime = TimeDifference( stats->nextTime, stats->startTime );
TimeAdd( stats->nextTime, stats->intervalTime );
stats->info.free = 0;
reporter_print( stats, TRANSFER_REPORT, force );
if ( isMultipleReport(stats) ) {
reporter_handle_multiple_reports( multireport, &stats->info, force );
}
}
return force;
}
/*
* This function handles multiple format printing by sending to the
* appropriate dispatch function
*/
int reporter_print( ReporterData *stats, int type, int end ) {
switch ( type ) {
case TRANSFER_REPORT:
statistics_reports[stats->mode]( &stats->info );
if ( end != 0 && isPrintMSS( stats ) && !isUDP( stats ) ) {
PrintMSS( stats );
}
break;
case SERVER_RELAY_REPORT:
serverstatistics_reports[stats->mode]( &stats->connection, &stats->info );
break;
case SETTINGS_REPORT:
settings_reports[stats->mode]( stats );
break;
case CONNECTION_REPORT:
stats->info.reserved_delay = connection_reports[stats->mode](
&stats->connection,
stats->info.transferID );
break;
case MULTIPLE_REPORT:
multiple_reports[stats->mode]( &stats->info );
break;
default:
fprintf( stderr, "Printing type not implemented! No Output\n" );
}
fflush( stdout );
return end;
}
/* -------------------------------------------------------------------
* Report the MSS and MTU, given the MSS (or a guess thereof)
* ------------------------------------------------------------------- */
// compare the MSS against the (MTU - 40) to (MTU - 80) bytes.
// 40 byte IP header and somewhat arbitrarily, 40 more bytes of IP options.
#define checkMSS_MTU( inMSS, inMTU ) (inMTU-40) >= inMSS && inMSS >= (inMTU-80)
void PrintMSS( ReporterData *stats ) {
int inMSS = getsock_tcp_mss( stats->info.transferID );
if ( inMSS <= 0 ) {
printf( report_mss_unsupported, stats->info.transferID );
} else {
char* net;
int mtu = 0;
if ( checkMSS_MTU( inMSS, 1500 ) ) {
net = "ethernet";
mtu = 1500;
} else if ( checkMSS_MTU( inMSS, 4352 ) ) {
net = "FDDI";
mtu = 4352;
} else if ( checkMSS_MTU( inMSS, 9180 ) ) {
net = "ATM";
mtu = 9180;
} else if ( checkMSS_MTU( inMSS, 65280 ) ) {
net = "HIPPI";
mtu = 65280;
} else if ( checkMSS_MTU( inMSS, 576 ) ) {
net = "minimum";
mtu = 576;
printf( warn_no_pathmtu );
} else {
mtu = inMSS + 40;
net = "unknown interface";
}
printf( report_mss,
stats->info.transferID, inMSS, mtu, net );
}
}
// end ReportMSS
#ifdef __cplusplus
} /* end extern "C" */
#endif

View File

@ -1,235 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Server.cpp
* by Mark Gates <mgates@nlanr.net>
* Ajay Tirumala (tirumala@ncsa.uiuc.edu>.
* -------------------------------------------------------------------
* A server thread is initiated for each connection accept() returns.
* Handles sending and receiving data, and then closes socket.
* Changes to this version : The server can be run as a daemon
* ------------------------------------------------------------------- */
#define HEADERS()
#include "headers.h"
#include "Server.hpp"
#include "List.h"
#include "Extractor.h"
#include "Reporter.h"
#include "Locale.h"
/* -------------------------------------------------------------------
* Stores connected socket and socket info.
* ------------------------------------------------------------------- */
Server::Server( thread_Settings *inSettings ) {
mSettings = inSettings;
mBuf = NULL;
// initialize buffer
mBuf = new char[ mSettings->mBufLen ];
FAIL_errno( mBuf == NULL, "No memory for buffer\n", mSettings );
}
/* -------------------------------------------------------------------
* Destructor close socket.
* ------------------------------------------------------------------- */
Server::~Server() {
if ( mSettings->mSock != INVALID_SOCKET ) {
int rc = close( mSettings->mSock );
WARN_errno( rc == SOCKET_ERROR, "close" );
mSettings->mSock = INVALID_SOCKET;
}
DELETE_ARRAY( mBuf );
}
void Server::Sig_Int( int inSigno ) {
}
/* -------------------------------------------------------------------
* Receieve data from the (connected) TCP/UDP socket.
* Sends termination flag several times at the end.
* Does not close the socket.
* ------------------------------------------------------------------- */
void Server::Run( void ) {
long currLen;
max_size_t totLen = 0;
struct UDP_datagram* mBuf_UDP = (struct UDP_datagram*) mBuf;
ReportStruct *reportstruct = NULL;
reportstruct = new ReportStruct;
if ( reportstruct != NULL ) {
reportstruct->packetID = 0;
mSettings->reporthdr = InitReport( mSettings );
do {
// perform read
currLen = recv( mSettings->mSock, mBuf, mSettings->mBufLen, 0 );
if ( isUDP( mSettings ) ) {
// read the datagram ID and sentTime out of the buffer
reportstruct->packetID = ntohl( mBuf_UDP->id );
reportstruct->sentTime.tv_sec = ntohl( mBuf_UDP->tv_sec );
reportstruct->sentTime.tv_usec = ntohl( mBuf_UDP->tv_usec );
reportstruct->packetLen = currLen;
gettimeofday( &(reportstruct->packetTime), NULL );
} else {
totLen += currLen;
}
// terminate when datagram begins with negative index
// the datagram ID should be correct, just negated
if ( reportstruct->packetID < 0 ) {
reportstruct->packetID = -reportstruct->packetID;
currLen = -1;
}
if ( isUDP (mSettings))
ReportPacket( mSettings->reporthdr, reportstruct );
} while ( currLen > 0 );
// stop timing
gettimeofday( &(reportstruct->packetTime), NULL );
if ( !isUDP (mSettings)) {
reportstruct->packetLen = totLen;
ReportPacket( mSettings->reporthdr, reportstruct );
}
CloseReport( mSettings->reporthdr, reportstruct );
// send a acknowledgement back only if we're NOT receiving multicast
if ( isUDP( mSettings ) && !isMulticast( mSettings ) ) {
// send back an acknowledgement of the terminating datagram
write_UDP_AckFIN( );
}
} else {
FAIL(1, "Out of memory! Closing server thread\n", mSettings);
}
Mutex_Lock( &clients_mutex );
Iperf_delete( &(mSettings->peer), &clients );
Mutex_Unlock( &clients_mutex );
DELETE_PTR( reportstruct );
EndReport( mSettings->reporthdr );
}
// end Recv
/* -------------------------------------------------------------------
* Send an AckFIN (a datagram acknowledging a FIN) on the socket,
* then select on the socket for some time. If additional datagrams
* come in, probably our AckFIN was lost and they are re-transmitted
* termination datagrams, so re-transmit our AckFIN.
* ------------------------------------------------------------------- */
void Server::write_UDP_AckFIN( ) {
int rc;
fd_set readSet;
FD_ZERO( &readSet );
struct timeval timeout;
int count = 0;
while ( count < 10 ) {
count++;
UDP_datagram *UDP_Hdr;
server_hdr *hdr;
UDP_Hdr = (UDP_datagram*) mBuf;
if ( mSettings->mBufLen > (int) ( sizeof( UDP_datagram )
+ sizeof( server_hdr ) ) ) {
Transfer_Info *stats = GetReport( mSettings->reporthdr );
hdr = (server_hdr*) (UDP_Hdr+1);
hdr->flags = htonl( HEADER_VERSION1 );
hdr->total_len1 = htonl( (long) (stats->TotalLen >> 32) );
hdr->total_len2 = htonl( (long) (stats->TotalLen & 0xFFFFFFFF) );
hdr->stop_sec = htonl( (long) stats->endTime );
hdr->stop_usec = htonl( (long)((stats->endTime - (long)stats->endTime)
* rMillion));
hdr->error_cnt = htonl( stats->cntError );
hdr->outorder_cnt = htonl( stats->cntOutofOrder );
hdr->datagrams = htonl( stats->cntDatagrams );
hdr->jitter1 = htonl( (long) stats->jitter );
hdr->jitter2 = htonl( (long) ((stats->jitter - (long)stats->jitter)
* rMillion) );
}
// write data
write( mSettings->mSock, mBuf, mSettings->mBufLen );
// wait until the socket is readable, or our timeout expires
FD_SET( mSettings->mSock, &readSet );
timeout.tv_sec = 1;
timeout.tv_usec = 0;
rc = select( mSettings->mSock+1, &readSet, NULL, NULL, &timeout );
FAIL_errno( rc == SOCKET_ERROR, "select", mSettings );
if ( rc == 0 ) {
// select timed out
return;
} else {
// socket ready to read
rc = read( mSettings->mSock, mBuf, mSettings->mBufLen );
WARN_errno( rc < 0, "read" );
if ( rc <= 0 ) {
// Connection closed or errored
// Stop using it.
return;
}
}
}
fprintf( stderr, warn_ack_failed, mSettings->mSock, count );
}
// end write_UDP_AckFIN

View File

@ -1,843 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Settings.cpp
* by Mark Gates <mgates@nlanr.net>
* & Ajay Tirumala <tirumala@ncsa.uiuc.edu>
* -------------------------------------------------------------------
* Stores and parses the initial values for all the global variables.
* -------------------------------------------------------------------
* headers
* uses
* <stdlib.h>
* <stdio.h>
* <string.h>
*
* <unistd.h>
* ------------------------------------------------------------------- */
#define HEADERS()
#include "headers.h"
#include "Settings.hpp"
#include "Locale.h"
#include "SocketAddr.h"
#include "util.h"
#include "gnu_getopt.h"
void Settings_Interpret( char option, const char *optarg, thread_Settings *mExtSettings );
/* -------------------------------------------------------------------
* command line options
*
* The option struct essentially maps a long option name (--foobar)
* or environment variable ($FOOBAR) to its short option char (f).
* ------------------------------------------------------------------- */
#define LONG_OPTIONS()
const struct option long_options[] =
{
{"singleclient", no_argument, NULL, '1'},
{"bandwidth", required_argument, NULL, 'b'},
{"client", required_argument, NULL, 'c'},
{"dualtest", no_argument, NULL, 'd'},
{"format", required_argument, NULL, 'f'},
{"help", no_argument, NULL, 'h'},
{"interval", required_argument, NULL, 'i'},
{"len", required_argument, NULL, 'l'},
{"print_mss", no_argument, NULL, 'm'},
{"num", required_argument, NULL, 'n'},
{"output", required_argument, NULL, 'o'},
{"port", required_argument, NULL, 'p'},
{"tradeoff", no_argument, NULL, 'r'},
{"server", no_argument, NULL, 's'},
{"time", required_argument, NULL, 't'},
{"udp", no_argument, NULL, 'u'},
{"version", no_argument, NULL, 'v'},
{"window", required_argument, NULL, 'w'},
{"reportexclude", required_argument, NULL, 'x'},
{"reportstyle",required_argument, NULL, 'y'},
// more esoteric options
{"bind", required_argument, NULL, 'B'},
{"compatibility", no_argument, NULL, 'C'},
{"daemon", no_argument, NULL, 'D'},
{"file_input", required_argument, NULL, 'F'},
{"stdin_input", no_argument, NULL, 'I'},
{"mss", required_argument, NULL, 'M'},
{"nodelay", no_argument, NULL, 'N'},
{"listenport", required_argument, NULL, 'L'},
{"parallel", required_argument, NULL, 'P'},
{"remove", no_argument, NULL, 'R'},
{"tos", required_argument, NULL, 'S'},
{"ttl", required_argument, NULL, 'T'},
{"single_udp", no_argument, NULL, 'U'},
{"ipv6_domain", no_argument, NULL, 'V'},
{"suggest_win_size", no_argument, NULL, 'W'},
{"linux-congestion", required_argument, NULL, 'Z'},
{0, 0, 0, 0}
};
#define ENV_OPTIONS()
const struct option env_options[] =
{
{"IPERF_SINGLECLIENT", no_argument, NULL, '1'},
{"IPERF_BANDWIDTH", required_argument, NULL, 'b'},
{"IPERF_CLIENT", required_argument, NULL, 'c'},
{"IPERF_DUALTEST", no_argument, NULL, 'd'},
{"IPERF_FORMAT", required_argument, NULL, 'f'},
// skip help
{"IPERF_INTERVAL", required_argument, NULL, 'i'},
{"IPERF_LEN", required_argument, NULL, 'l'},
{"IPERF_PRINT_MSS", no_argument, NULL, 'm'},
{"IPERF_NUM", required_argument, NULL, 'n'},
{"IPERF_PORT", required_argument, NULL, 'p'},
{"IPERF_TRADEOFF", no_argument, NULL, 'r'},
{"IPERF_SERVER", no_argument, NULL, 's'},
{"IPERF_TIME", required_argument, NULL, 't'},
{"IPERF_UDP", no_argument, NULL, 'u'},
// skip version
{"TCP_WINDOW_SIZE", required_argument, NULL, 'w'},
{"IPERF_REPORTEXCLUDE", required_argument, NULL, 'x'},
{"IPERF_REPORTSTYLE",required_argument, NULL, 'y'},
// more esoteric options
{"IPERF_BIND", required_argument, NULL, 'B'},
{"IPERF_COMPAT", no_argument, NULL, 'C'},
{"IPERF_DAEMON", no_argument, NULL, 'D'},
{"IPERF_FILE_INPUT", required_argument, NULL, 'F'},
{"IPERF_STDIN_INPUT", no_argument, NULL, 'I'},
{"IPERF_MSS", required_argument, NULL, 'M'},
{"IPERF_NODELAY", no_argument, NULL, 'N'},
{"IPERF_LISTENPORT", required_argument, NULL, 'L'},
{"IPERF_PARALLEL", required_argument, NULL, 'P'},
{"IPERF_TOS", required_argument, NULL, 'S'},
{"IPERF_TTL", required_argument, NULL, 'T'},
{"IPERF_SINGLE_UDP", no_argument, NULL, 'U'},
{"IPERF_IPV6_DOMAIN", no_argument, NULL, 'V'},
{"IPERF_SUGGEST_WIN_SIZE", required_argument, NULL, 'W'},
{"IPERF_CONGESTION_CONTROL", required_argument, NULL, 'Z'},
{0, 0, 0, 0}
};
#define SHORT_OPTIONS()
const char short_options[] = "1b:c:df:hi:l:mn:o:p:rst:uvw:x:y:B:CDF:IL:M:NP:RS:T:UVWZ:";
/* -------------------------------------------------------------------
* defaults
* ------------------------------------------------------------------- */
#define DEFAULTS()
const long kDefault_UDPRate = 1024 * 1024; // -u if set, 1 Mbit/sec
const int kDefault_UDPBufLen = 1470; // -u if set, read/write 1470 bytes
// 1470 bytes is small enough to be sending one packet per datagram on ethernet
// 1450 bytes is small enough to be sending one packet per datagram on ethernet
// **** with IPv6 ****
/* -------------------------------------------------------------------
* Initialize all settings to defaults.
* ------------------------------------------------------------------- */
void Settings_Initialize( thread_Settings *main ) {
// Everything defaults to zero or NULL with
// this memset. Only need to set non-zero values
// below.
memset( main, 0, sizeof(thread_Settings) );
main->mSock = INVALID_SOCKET;
main->mReportMode = kReport_Default;
// option, defaults
main->flags = FLAG_MODETIME | FLAG_STDOUT; // Default time and stdout
//main->mUDPRate = 0; // -b, ie. TCP mode
//main->mHost = NULL; // -c, none, required for client
main->mMode = kTest_Normal; // -d, mMode == kTest_DualTest
main->mFormat = 'a'; // -f, adaptive bits
// skip help // -h,
//main->mBufLenSet = false; // -l,
main->mBufLen = 8 * 1024; // -l, 8 Kbyte
//main->mInterval = 0; // -i, ie. no periodic bw reports
//main->mPrintMSS = false; // -m, don't print MSS
// mAmount is time also // -n, N/A
//main->mOutputFileName = NULL; // -o, filename
main->mPort = 5001; // -p, ttcp port
// mMode = kTest_Normal; // -r, mMode == kTest_TradeOff
main->mThreadMode = kMode_Unknown; // -s, or -c, none
main->mAmount = 1000; // -t, 10 seconds
// mUDPRate > 0 means UDP // -u, N/A, see kDefault_UDPRate
// skip version // -v,
//main->mTCPWin = 0; // -w, ie. don't set window
// more esoteric options
//main->mLocalhost = NULL; // -B, none
//main->mCompat = false; // -C, run in Compatibility mode
//main->mDaemon = false; // -D, run as a daemon
//main->mFileInput = false; // -F,
//main->mFileName = NULL; // -F, filename
//main->mStdin = false; // -I, default not stdin
//main->mListenPort = 0; // -L, listen port
//main->mMSS = 0; // -M, ie. don't set MSS
//main->mNodelay = false; // -N, don't set nodelay
//main->mThreads = 0; // -P,
//main->mRemoveService = false; // -R,
//main->mTOS = 0; // -S, ie. don't set type of service
main->mTTL = 1; // -T, link-local TTL
//main->mDomain = kMode_IPv4; // -V,
//main->mSuggestWin = false; // -W, Suggest the window size.
} // end Settings
void Settings_Copy( thread_Settings *from, thread_Settings **into ) {
*into = new thread_Settings;
memcpy( *into, from, sizeof(thread_Settings) );
if ( from->mHost != NULL ) {
(*into)->mHost = new char[ strlen(from->mHost) + 1];
strcpy( (*into)->mHost, from->mHost );
}
if ( from->mOutputFileName != NULL ) {
(*into)->mOutputFileName = new char[ strlen(from->mOutputFileName) + 1];
strcpy( (*into)->mOutputFileName, from->mOutputFileName );
}
if ( from->mLocalhost != NULL ) {
(*into)->mLocalhost = new char[ strlen(from->mLocalhost) + 1];
strcpy( (*into)->mLocalhost, from->mLocalhost );
}
if ( from->mFileName != NULL ) {
(*into)->mFileName = new char[ strlen(from->mFileName) + 1];
strcpy( (*into)->mFileName, from->mFileName );
}
// Zero out certain entries
(*into)->mTID = thread_zeroid();
(*into)->runNext = NULL;
(*into)->runNow = NULL;
}
/* -------------------------------------------------------------------
* Delete memory: Does not clean up open file pointers or ptr_parents
* ------------------------------------------------------------------- */
void Settings_Destroy( thread_Settings *mSettings) {
DELETE_ARRAY( mSettings->mHost );
DELETE_ARRAY( mSettings->mLocalhost );
DELETE_ARRAY( mSettings->mFileName );
DELETE_ARRAY( mSettings->mOutputFileName );
DELETE_PTR( mSettings );
} // end ~Settings
/* -------------------------------------------------------------------
* Parses settings from user's environment variables.
* ------------------------------------------------------------------- */
void Settings_ParseEnvironment( thread_Settings *mSettings ) {
char *theVariable;
int i = 0;
while ( env_options[i].name != NULL ) {
theVariable = getenv( env_options[i].name );
if ( theVariable != NULL ) {
Settings_Interpret( env_options[i].val, theVariable, mSettings );
}
i++;
}
} // end ParseEnvironment
/* -------------------------------------------------------------------
* Parse settings from app's command line.
* ------------------------------------------------------------------- */
void Settings_ParseCommandLine( int argc, char **argv, thread_Settings *mSettings ) {
int option;
while ( (option =
gnu_getopt_long( argc, argv, short_options,
long_options, NULL )) != EOF ) {
Settings_Interpret( option, gnu_optarg, mSettings );
}
for ( int i = gnu_optind; i < argc; i++ ) {
fprintf( stderr, "%s: ignoring extra argument -- %s\n", argv[0], argv[i] );
}
} // end ParseCommandLine
/* -------------------------------------------------------------------
* Interpret individual options, either from the command line
* or from environment variables.
* ------------------------------------------------------------------- */
void Settings_Interpret( char option, const char *optarg, thread_Settings *mExtSettings ) {
char outarg[100];
switch ( option ) {
case '1': // Single Client
setSingleClient( mExtSettings );
break;
case 'b': // UDP bandwidth
if ( !isUDP( mExtSettings ) ) {
fprintf( stderr, warn_implied_udp, option );
}
if ( mExtSettings->mThreadMode != kMode_Client ) {
fprintf( stderr, warn_invalid_server_option, option );
break;
}
Settings_GetLowerCaseArg(optarg,outarg);
mExtSettings->mUDPRate = byte_atoi(outarg);
setUDP( mExtSettings );
// if -l has already been processed, mBufLenSet is true
// so don't overwrite that value.
if ( !isBuflenSet( mExtSettings ) ) {
mExtSettings->mBufLen = kDefault_UDPBufLen;
}
break;
case 'c': // client mode w/ server host to connect to
mExtSettings->mHost = new char[ strlen( optarg ) + 1 ];
strcpy( mExtSettings->mHost, optarg );
if ( mExtSettings->mThreadMode == kMode_Unknown ) {
// Test for Multicast
iperf_sockaddr temp;
SockAddr_setHostname( mExtSettings->mHost, &temp,
(isIPV6( mExtSettings ) ? 1 : 0 ));
if ( SockAddr_isMulticast( &temp ) ) {
setMulticast( mExtSettings );
}
mExtSettings->mThreadMode = kMode_Client;
mExtSettings->mThreads = 1;
}
break;
case 'd': // Dual-test Mode
if ( mExtSettings->mThreadMode != kMode_Client ) {
fprintf( stderr, warn_invalid_server_option, option );
break;
}
if ( isCompat( mExtSettings ) ) {
fprintf( stderr, warn_invalid_compatibility_option, option );
}
#ifdef HAVE_THREAD
mExtSettings->mMode = kTest_DualTest;
#else
fprintf( stderr, warn_invalid_single_threaded, option );
mExtSettings->mMode = kTest_TradeOff;
#endif
break;
case 'f': // format to print in
mExtSettings->mFormat = (*optarg);
break;
case 'h': // print help and exit
fprintf(stderr, usage_long1);
fprintf(stderr, usage_long2);
exit(1);
break;
case 'i': // specify interval between periodic bw reports
mExtSettings->mInterval = atof( optarg );
if ( mExtSettings->mInterval < 0.5 ) {
fprintf (stderr, report_interval_small, mExtSettings->mInterval);
mExtSettings->mInterval = 0.5;
}
break;
case 'l': // length of each buffer
Settings_GetUpperCaseArg(optarg,outarg);
mExtSettings->mBufLen = byte_atoi( outarg );
setBuflenSet( mExtSettings );
if ( !isUDP( mExtSettings ) ) {
if ( mExtSettings->mBufLen < (int) sizeof( client_hdr ) &&
!isCompat( mExtSettings ) ) {
setCompat( mExtSettings );
fprintf( stderr, warn_implied_compatibility, option );
}
} else {
if ( mExtSettings->mBufLen < (int) sizeof( UDP_datagram ) ) {
mExtSettings->mBufLen = sizeof( UDP_datagram );
fprintf( stderr, warn_buffer_too_small, mExtSettings->mBufLen );
}
if ( !isCompat( mExtSettings ) &&
mExtSettings->mBufLen < (int) ( sizeof( UDP_datagram )
+ sizeof( client_hdr ) ) ) {
setCompat( mExtSettings );
fprintf( stderr, warn_implied_compatibility, option );
}
}
break;
case 'm': // print TCP MSS
setPrintMSS( mExtSettings );
break;
case 'n': // bytes of data
// amount mode (instead of time mode)
unsetModeTime( mExtSettings );
Settings_GetUpperCaseArg(optarg,outarg);
mExtSettings->mAmount = byte_atoi( outarg );
break;
case 'o' : // output the report and other messages into the file
unsetSTDOUT( mExtSettings );
mExtSettings->mOutputFileName = new char[strlen(optarg)+1];
strcpy( mExtSettings->mOutputFileName, optarg);
break;
case 'p': // server port
mExtSettings->mPort = atoi( optarg );
break;
case 'r': // test mode tradeoff
if ( mExtSettings->mThreadMode != kMode_Client ) {
fprintf( stderr, warn_invalid_server_option, option );
break;
}
if ( isCompat( mExtSettings ) ) {
fprintf( stderr, warn_invalid_compatibility_option, option );
}
mExtSettings->mMode = kTest_TradeOff;
break;
case 's': // server mode
if ( mExtSettings->mThreadMode != kMode_Unknown ) {
fprintf( stderr, warn_invalid_client_option, option );
break;
}
mExtSettings->mThreadMode = kMode_Listener;
break;
case 't': // seconds to write for
// time mode (instead of amount mode)
setModeTime( mExtSettings );
mExtSettings->mAmount = (int) (atof( optarg ) * 100.0);
break;
case 'u': // UDP instead of TCP
// if -b has already been processed, UDP rate will
// already be non-zero, so don't overwrite that value
if ( !isUDP( mExtSettings ) ) {
setUDP( mExtSettings );
mExtSettings->mUDPRate = kDefault_UDPRate;
}
// if -l has already been processed, mBufLenSet is true
// so don't overwrite that value.
if ( !isBuflenSet( mExtSettings ) ) {
mExtSettings->mBufLen = kDefault_UDPBufLen;
} else if ( mExtSettings->mBufLen < (int) ( sizeof( UDP_datagram )
+ sizeof( client_hdr ) ) &&
!isCompat( mExtSettings ) ) {
setCompat( mExtSettings );
fprintf( stderr, warn_implied_compatibility, option );
}
break;
case 'v': // print version and exit
fprintf( stderr, version );
exit(1);
break;
case 'w': // TCP window size (socket buffer size)
Settings_GetUpperCaseArg(optarg,outarg);
mExtSettings->mTCPWin = byte_atoi(outarg);
if ( mExtSettings->mTCPWin < 2048 ) {
fprintf( stderr, warn_window_small, mExtSettings->mTCPWin );
}
break;
case 'x': // Limit Reports
while ( *optarg != '\0' ) {
switch ( *optarg ) {
case 's':
case 'S':
setNoSettReport( mExtSettings );
break;
case 'c':
case 'C':
setNoConnReport( mExtSettings );
break;
case 'd':
case 'D':
setNoDataReport( mExtSettings );
break;
case 'v':
case 'V':
setNoServReport( mExtSettings );
break;
case 'm':
case 'M':
setNoMultReport( mExtSettings );
break;
default:
fprintf(stderr, warn_invalid_report, *optarg);
}
optarg++;
}
break;
case 'y': // Reporting Style
switch ( *optarg ) {
case 'c':
case 'C':
mExtSettings->mReportMode = kReport_CSV;
break;
default:
fprintf( stderr, warn_invalid_report_style, optarg );
}
break;
// more esoteric options
case 'B': // specify bind address
mExtSettings->mLocalhost = new char[ strlen( optarg ) + 1 ];
strcpy( mExtSettings->mLocalhost, optarg );
// Test for Multicast
iperf_sockaddr temp;
SockAddr_setHostname( mExtSettings->mLocalhost, &temp,
(isIPV6( mExtSettings ) ? 1 : 0 ));
if ( SockAddr_isMulticast( &temp ) ) {
setMulticast( mExtSettings );
}
break;
case 'C': // Run in Compatibility Mode
setCompat( mExtSettings );
if ( mExtSettings->mMode != kTest_Normal ) {
fprintf( stderr, warn_invalid_compatibility_option,
( mExtSettings->mMode == kTest_DualTest ?
'd' : 'r' ) );
mExtSettings->mMode = kTest_Normal;
}
break;
case 'D': // Run as a daemon
setDaemon( mExtSettings );
break;
case 'F' : // Get the input for the data stream from a file
if ( mExtSettings->mThreadMode != kMode_Client ) {
fprintf( stderr, warn_invalid_server_option, option );
break;
}
setFileInput( mExtSettings );
mExtSettings->mFileName = new char[strlen(optarg)+1];
strcpy( mExtSettings->mFileName, optarg);
break;
case 'I' : // Set the stdin as the input source
if ( mExtSettings->mThreadMode != kMode_Client ) {
fprintf( stderr, warn_invalid_server_option, option );
break;
}
setFileInput( mExtSettings );
setSTDIN( mExtSettings );
mExtSettings->mFileName = new char[strlen("<stdin>")+1];
strcpy( mExtSettings->mFileName,"<stdin>");
break;
case 'L': // Listen Port (bidirectional testing client-side)
if ( mExtSettings->mThreadMode != kMode_Client ) {
fprintf( stderr, warn_invalid_server_option, option );
break;
}
mExtSettings->mListenPort = atoi( optarg );
break;
case 'M': // specify TCP MSS (maximum segment size)
Settings_GetUpperCaseArg(optarg,outarg);
mExtSettings->mMSS = byte_atoi( outarg );
break;
case 'N': // specify TCP nodelay option (disable Jacobson's Algorithm)
setNoDelay( mExtSettings );
break;
case 'P': // number of client threads
#ifdef HAVE_THREAD
mExtSettings->mThreads = atoi( optarg );
#else
if ( mExtSettings->mThreadMode != kMode_Server ) {
fprintf( stderr, warn_invalid_single_threaded, option );
} else {
mExtSettings->mThreads = atoi( optarg );
}
#endif
break;
case 'R':
setRemoveService( mExtSettings );
break;
case 'S': // IP type-of-service
// TODO use a function that understands base-2
// the zero base here allows the user to specify
// "0x#" hex, "0#" octal, and "#" decimal numbers
mExtSettings->mTOS = strtol( optarg, NULL, 0 );
break;
case 'T': // time-to-live for multicast
mExtSettings->mTTL = atoi( optarg );
break;
case 'U': // single threaded UDP server
setSingleUDP( mExtSettings );
break;
case 'V': // IPv6 Domain
setIPV6( mExtSettings );
if ( mExtSettings->mThreadMode == kMode_Server
&& mExtSettings->mLocalhost != NULL ) {
// Test for Multicast
iperf_sockaddr temp;
SockAddr_setHostname( mExtSettings->mLocalhost, &temp, 1);
if ( SockAddr_isMulticast( &temp ) ) {
setMulticast( mExtSettings );
}
} else if ( mExtSettings->mThreadMode == kMode_Client ) {
// Test for Multicast
iperf_sockaddr temp;
SockAddr_setHostname( mExtSettings->mHost, &temp, 1 );
if ( SockAddr_isMulticast( &temp ) ) {
setMulticast( mExtSettings );
}
}
break;
case 'W' :
setSuggestWin( mExtSettings );
fprintf( stderr, "The -W option is not available in this release\n");
break;
case 'Z':
#ifdef TCP_CONGESTION
setCongestionControl( mExtSettings );
mExtSettings->mCongestion = new char[strlen(optarg)+1];
strcpy( mExtSettings->mCongestion, optarg);
#else
fprintf( stderr, "The -Z option is not available on this operating system\n");
#endif
break;
default: // ignore unknown
break;
}
} // end Interpret
void Settings_GetUpperCaseArg(const char *inarg, char *outarg) {
int len = strlen(inarg);
strcpy(outarg,inarg);
if ( (len > 0) && (inarg[len-1] >='a')
&& (inarg[len-1] <= 'z') )
outarg[len-1]= outarg[len-1]+'A'-'a';
}
void Settings_GetLowerCaseArg(const char *inarg, char *outarg) {
int len = strlen(inarg);
strcpy(outarg,inarg);
if ( (len > 0) && (inarg[len-1] >='A')
&& (inarg[len-1] <= 'Z') )
outarg[len-1]= outarg[len-1]-'A'+'a';
}
/*
* Settings_GenerateListenerSettings
* Called to generate the settings to be passed to the Listener
* instance that will handle dual testings from the client side
* this should only return an instance if it was called on
* the thread_Settings instance generated from the command line
* for client side execution
*/
void Settings_GenerateListenerSettings( thread_Settings *client, thread_Settings **listener ) {
if ( !isCompat( client ) &&
(client->mMode == kTest_DualTest || client->mMode == kTest_TradeOff) ) {
*listener = new thread_Settings;
memcpy(*listener, client, sizeof( thread_Settings ));
setCompat( (*listener) );
unsetDaemon( (*listener) );
if ( client->mListenPort != 0 ) {
(*listener)->mPort = client->mListenPort;
} else {
(*listener)->mPort = client->mPort;
}
(*listener)->mFileName = NULL;
(*listener)->mHost = NULL;
(*listener)->mLocalhost = NULL;
(*listener)->mOutputFileName = NULL;
(*listener)->mMode = kTest_Normal;
(*listener)->mThreadMode = kMode_Listener;
if ( client->mHost != NULL ) {
(*listener)->mHost = new char[strlen( client->mHost ) + 1];
strcpy( (*listener)->mHost, client->mHost );
}
if ( client->mLocalhost != NULL ) {
(*listener)->mLocalhost = new char[strlen( client->mLocalhost ) + 1];
strcpy( (*listener)->mLocalhost, client->mLocalhost );
}
} else {
*listener = NULL;
}
}
/*
* Settings_GenerateSpeakerSettings
* Called to generate the settings to be passed to the Speaker
* instance that will handle dual testings from the server side
* this should only return an instance if it was called on
* the thread_Settings instance generated from the command line
* for server side execution. This should be an inverse operation
* of GenerateClientHdr.
*/
void Settings_GenerateClientSettings( thread_Settings *server,
thread_Settings **client,
client_hdr *hdr ) {
int flags = ntohl(hdr->flags);
if ( (flags & HEADER_VERSION1) != 0 ) {
*client = new thread_Settings;
memcpy(*client, server, sizeof( thread_Settings ));
setCompat( (*client) );
(*client)->mTID = thread_zeroid();
(*client)->mPort = (unsigned short) ntohl(hdr->mPort);
(*client)->mThreads = ntohl(hdr->numThreads);
if ( hdr->bufferlen != 0 ) {
(*client)->mBufLen = ntohl(hdr->bufferlen);
}
if ( hdr->mWinBand != 0 ) {
if ( isUDP( server ) ) {
(*client)->mUDPRate = ntohl(hdr->mWinBand);
} else {
(*client)->mTCPWin = ntohl(hdr->mWinBand);
}
}
(*client)->mAmount = ntohl(hdr->mAmount);
if ( ((*client)->mAmount & 0x80000000) > 0 ) {
setModeTime( (*client) );
#ifndef WIN32
(*client)->mAmount |= 0xFFFFFFFF00000000LL;
#else
(*client)->mAmount |= 0xFFFFFFFF00000000;
#endif
(*client)->mAmount = -(*client)->mAmount;
}
(*client)->mFileName = NULL;
(*client)->mHost = NULL;
(*client)->mLocalhost = NULL;
(*client)->mOutputFileName = NULL;
(*client)->mMode = ((flags & RUN_NOW) == 0 ?
kTest_TradeOff : kTest_DualTest);
(*client)->mThreadMode = kMode_Client;
if ( server->mLocalhost != NULL ) {
(*client)->mLocalhost = new char[strlen( server->mLocalhost ) + 1];
strcpy( (*client)->mLocalhost, server->mLocalhost );
}
(*client)->mHost = new char[REPORT_ADDRLEN];
if ( ((sockaddr*)&server->peer)->sa_family == AF_INET ) {
inet_ntop( AF_INET, &((sockaddr_in*)&server->peer)->sin_addr,
(*client)->mHost, REPORT_ADDRLEN);
}
#ifdef HAVE_IPV6
else {
inet_ntop( AF_INET6, &((sockaddr_in6*)&server->peer)->sin6_addr,
(*client)->mHost, REPORT_ADDRLEN);
}
#endif
} else {
*client = NULL;
}
}
/*
* Settings_GenerateClientHdr
* Called to generate the client header to be passed to the
* server that will handle dual testings from the server side
* This should be an inverse operation of GenerateSpeakerSettings
*/
void Settings_GenerateClientHdr( thread_Settings *client, client_hdr *hdr ) {
if ( client->mMode != kTest_Normal ) {
hdr->flags = htonl(HEADER_VERSION1);
} else {
hdr->flags = 0;
}
if ( isBuflenSet( client ) ) {
hdr->bufferlen = htonl(client->mBufLen);
} else {
hdr->bufferlen = 0;
}
if ( isUDP( client ) ) {
hdr->mWinBand = htonl(client->mUDPRate);
} else {
hdr->mWinBand = htonl(client->mTCPWin);
}
if ( client->mListenPort != 0 ) {
hdr->mPort = htonl(client->mListenPort);
} else {
hdr->mPort = htonl(client->mPort);
}
hdr->numThreads = htonl(client->mThreads);
if ( isModeTime( client ) ) {
hdr->mAmount = htonl(-(long)client->mAmount);
} else {
hdr->mAmount = htonl((long)client->mAmount);
hdr->mAmount &= htonl( 0x7FFFFFFF );
}
if ( client->mMode == kTest_DualTest ) {
hdr->flags |= htonl(RUN_NOW);
}
}

View File

@ -1,422 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Socket.cpp
* by Ajay Tirumala <tirumala@ncsa.uiuc.edu>
* and Mark Gates <mgates@nlanr.net>
* ------------------------------------------------------------------- */
#define HEADERS()
#include "headers.h"
#include "SocketAddr.h"
#ifdef __cplusplus
extern "C" {
#endif
/* -------------------------------------------------------------------
* Create a socket address. If inHostname is not null, resolve that
* address and fill it in. Fill in the port number. Use IPv6 ADDR_ANY
* if that is what is desired.
* ------------------------------------------------------------------- */
void SockAddr_remoteAddr( thread_Settings *inSettings ) {
SockAddr_zeroAddress( &inSettings->peer );
if ( inSettings->mHost != NULL ) {
SockAddr_setHostname( inSettings->mHost, &inSettings->peer,
isIPV6( inSettings ) );
} else {
#ifdef HAVE_IPV6
if ( isIPV6( inSettings ) ) {
((struct sockaddr*)&inSettings->peer)->sa_family = AF_INET6;
} else {
((struct sockaddr*)&inSettings->peer)->sa_family = AF_INET;
}
}
if ( SockAddr_isIPv6( &inSettings->peer ) ) {
inSettings->size_peer = sizeof( struct sockaddr_in6 );
} else {
inSettings->size_peer = sizeof( struct sockaddr_in );
}
#else
((struct sockaddr*)&inSettings->peer)->sa_family = AF_INET;
}
inSettings->size_peer = sizeof( struct sockaddr_in );
#endif
SockAddr_setPort( &inSettings->peer, inSettings->mPort );
}
// end SocketAddr
void SockAddr_localAddr( thread_Settings *inSettings ) {
SockAddr_zeroAddress( &inSettings->local );
if ( inSettings->mLocalhost != NULL ) {
SockAddr_setHostname( inSettings->mLocalhost, &inSettings->local,
isIPV6( inSettings ) );
} else {
#ifdef HAVE_IPV6
if ( isIPV6( inSettings ) ) {
((struct sockaddr*)&inSettings->local)->sa_family = AF_INET6;
} else {
((struct sockaddr*)&inSettings->local)->sa_family = AF_INET;
}
}
if ( SockAddr_isIPv6( &inSettings->local ) ) {
inSettings->size_local = sizeof( struct sockaddr_in6 );
} else {
inSettings->size_local = sizeof( struct sockaddr_in );
}
#else
((struct sockaddr*)&inSettings->local)->sa_family = AF_INET;
}
inSettings->size_local = sizeof( struct sockaddr_in );
#endif
SockAddr_setPort( &inSettings->local, inSettings->mPort );
}
// end SocketAddr
/* -------------------------------------------------------------------
* Resolve the hostname address and fill it in.
* ------------------------------------------------------------------- */
void SockAddr_setHostname( const char* inHostname,
iperf_sockaddr *inSockAddr,
int isIPv6 ) {
// ..I think this works for both ipv6 & ipv4... we'll see
#if defined(HAVE_IPV6)
{
struct addrinfo *res, *itr;
int ret_ga;
ret_ga = getaddrinfo(inHostname, NULL, NULL, &res);
if ( ret_ga ) {
fprintf(stderr, "error: %s\n", gai_strerror(ret_ga));
exit(1);
}
if ( !res->ai_addr ) {
fprintf(stderr, "getaddrinfo failed to get an address... target was '%s'\n", inHostname);
exit(1);
}
// Check address type before filling in the address
// ai_family = PF_xxx; ai_protocol = IPPROTO_xxx, see netdb.h
// ...but AF_INET6 == PF_INET6
itr = res;
if ( isIPv6 ) {
// First check all results for a IPv6 Address
while ( itr != NULL ) {
if ( itr->ai_family == AF_INET6 ) {
memcpy(inSockAddr, (itr->ai_addr),
(itr->ai_addrlen));
freeaddrinfo(res);
return;
} else {
itr = itr->ai_next;
}
}
}
itr = res;
// Now find a IPv4 Address
while ( itr != NULL ) {
if ( itr->ai_family == AF_INET ) {
memcpy(inSockAddr, (itr->ai_addr),
(itr->ai_addrlen));
freeaddrinfo(res);
return;
} else {
itr = itr->ai_next;
}
}
}
#else
// first try just converting dotted decimal
// on Windows gethostbyname doesn't understand dotted decimal
int rc = inet_pton( AF_INET, inHostname,
(unsigned char*)&(((struct sockaddr_in*)inSockAddr)->sin_addr) );
inSockAddr->sin_family = AF_INET;
if ( rc == 0 ) {
struct hostent *hostP = gethostbyname( inHostname );
if ( hostP == NULL ) {
/* this is the same as herror() but works on more systems */
const char* format;
switch ( h_errno ) {
case HOST_NOT_FOUND:
format = "%s: Unknown host\n";
break;
case NO_ADDRESS:
format = "%s: No address associated with name\n";
break;
case NO_RECOVERY:
format = "%s: Unknown server error\n";
break;
case TRY_AGAIN:
format = "%s: Host name lookup failure\n";
break;
default:
format = "%s: Unknown resolver error\n";
break;
}
fprintf( stderr, format, inHostname );
exit(1);
return; // TODO throw
}
memcpy(&(((struct sockaddr_in*)inSockAddr)->sin_addr), *(hostP->h_addr_list),
(hostP->h_length));
}
#endif
}
// end setHostname
/* -------------------------------------------------------------------
* Copy the IP address into the string.
* ------------------------------------------------------------------- */
void SockAddr_getHostAddress( iperf_sockaddr *inSockAddr, char* outAddress,
size_t len ) {
if ( ((struct sockaddr*)inSockAddr)->sa_family == AF_INET ) {
inet_ntop( AF_INET, &(((struct sockaddr_in*) inSockAddr)->sin_addr),
outAddress, len);
}
#ifdef HAVE_IPV6
else {
inet_ntop( AF_INET6, &(((struct sockaddr_in6*) inSockAddr)->sin6_addr),
outAddress, len);
}
#endif
}
// end getHostAddress
/* -------------------------------------------------------------------
* Set the address to any (generally all zeros).
* ------------------------------------------------------------------- */
void SockAddr_setAddressAny( iperf_sockaddr *inSockAddr ) {
if ( ((struct sockaddr*)inSockAddr)->sa_family == AF_INET )
memset( &(((struct sockaddr_in*) inSockAddr)->sin_addr), 0,
sizeof( struct in_addr ));
#if defined(HAVE_IPV6)
else
memset( &(((struct sockaddr_in6*) inSockAddr)->sin6_addr), 0,
sizeof( struct in6_addr ));
#endif
}
// end setAddressAny
/* -------------------------------------------------------------------
* Set the port to the given port. Handles the byte swapping.
* ------------------------------------------------------------------- */
void SockAddr_setPort( iperf_sockaddr *inSockAddr, unsigned short inPort ) {
if ( ((struct sockaddr*)inSockAddr)->sa_family == AF_INET )
((struct sockaddr_in*) inSockAddr)->sin_port = htons( inPort );
#if defined(HAVE_IPV6)
else
((struct sockaddr_in6*) inSockAddr)->sin6_port = htons( inPort );
#endif
}
// end setPort
/* -------------------------------------------------------------------
* Set the port to zero, which lets the OS pick the port.
* ------------------------------------------------------------------- */
void SockAddr_setPortAny( iperf_sockaddr *inSockAddr ) {
SockAddr_setPort( inSockAddr, 0 );
}
// end setPortAny
/* -------------------------------------------------------------------
* Return the port. Handles the byte swapping.
* ------------------------------------------------------------------- */
unsigned short SockAddr_getPort( iperf_sockaddr *inSockAddr ) {
if ( ((struct sockaddr*)inSockAddr)->sa_family == AF_INET )
return ntohs( ((struct sockaddr_in*) inSockAddr)->sin_port );
#if defined(HAVE_IPV6)
else
return ntohs( ((struct sockaddr_in6*) inSockAddr)->sin6_port);
#endif
return 0;
}
// end getPort
/* -------------------------------------------------------------------
* Return the IPv4 Internet Address from the sockaddr_in structure
* ------------------------------------------------------------------- */
struct in_addr* SockAddr_get_in_addr( iperf_sockaddr *inSockAddr ) {
if ( ((struct sockaddr*)inSockAddr)->sa_family == AF_INET )
return &(((struct sockaddr_in*) inSockAddr)->sin_addr);
fprintf(stderr, "FATAL: get_in_addr called on IPv6 address\n");
return NULL;
}
/* -------------------------------------------------------------------
* Return the IPv6 Internet Address from the sockaddr_in6 structure
* ------------------------------------------------------------------- */
#ifdef HAVE_IPV6
struct in6_addr* SockAddr_get_in6_addr( iperf_sockaddr *inSockAddr ) {
if ( ((struct sockaddr*)inSockAddr)->sa_family == AF_INET6 )
return &(((struct sockaddr_in6*) inSockAddr)->sin6_addr);
fprintf(stderr, "FATAL: get_in6_addr called on IPv4 address\n");
return NULL;
}
#endif
/* -------------------------------------------------------------------
* Return the size of the appropriate address structure.
* ------------------------------------------------------------------- */
Socklen_t SockAddr_get_sizeof_sockaddr( iperf_sockaddr *inSockAddr ) {
#if defined(HAVE_IPV6)
if ( ((struct sockaddr*)inSockAddr)->sa_family == AF_INET6 ) {
return(sizeof(struct sockaddr_in6));
}
#endif
return(sizeof(struct sockaddr_in));
}
// end get_sizeof_sockaddr
/* -------------------------------------------------------------------
* Return if IPv6 socket
* ------------------------------------------------------------------- */
int SockAddr_isIPv6( iperf_sockaddr *inSockAddr ) {
#if defined(HAVE_IPV6)
if ( ((struct sockaddr*)inSockAddr)->sa_family == AF_INET6 ) {
return 1;
}
#endif
return 0;
}
// end get_sizeof_sockaddr
/* -------------------------------------------------------------------
* Return true if the address is a IPv4 multicast address.
* ------------------------------------------------------------------- */
int SockAddr_isMulticast( iperf_sockaddr *inSockAddr ) {
#if defined(HAVE_IPV6)
if ( ((struct sockaddr*)inSockAddr)->sa_family == AF_INET6 ) {
return( IN6_IS_ADDR_MULTICAST(&(((struct sockaddr_in6*) inSockAddr)->sin6_addr) ));
} else
#endif
{
// 224.0.0.0 to 239.255.255.255 (e0.00.00.00 to ef.ff.ff.ff)
const unsigned long kMulticast_Mask = 0xe0000000L;
return(kMulticast_Mask ==
(ntohl( ((struct sockaddr_in*) inSockAddr)->sin_addr.s_addr) & kMulticast_Mask));
}
}
// end isMulticast
/* -------------------------------------------------------------------
* Zero out the address structure.
* ------------------------------------------------------------------- */
void SockAddr_zeroAddress( iperf_sockaddr *inSockAddr ) {
memset( inSockAddr, 0, sizeof( iperf_sockaddr ));
}
// zeroAddress
/* -------------------------------------------------------------------
* Compare two sockaddrs and return true if they are equal
* ------------------------------------------------------------------- */
int SockAddr_are_Equal( struct sockaddr* first, struct sockaddr* second ) {
if ( first->sa_family == AF_INET && second->sa_family == AF_INET ) {
// compare IPv4 adresses
return( ((long) ((struct sockaddr_in*)first)->sin_addr.s_addr == (long) ((struct sockaddr_in*)second)->sin_addr.s_addr)
&& ( ((struct sockaddr_in*)first)->sin_port == ((struct sockaddr_in*)second)->sin_port) );
}
#if defined(HAVE_IPV6)
if ( first->sa_family == AF_INET6 && second->sa_family == AF_INET6 ) {
// compare IPv6 addresses
return( !memcmp(((struct sockaddr_in6*)first)->sin6_addr.s6_addr, ((struct sockaddr_in6*)second)->sin6_addr.s6_addr, sizeof(struct in6_addr))
&& (((struct sockaddr_in6*)first)->sin6_port == ((struct sockaddr_in6*)second)->sin6_port) );
}
#endif
return 0;
}
/* -------------------------------------------------------------------
* Compare two sockaddrs and return true if the hosts are equal
* ------------------------------------------------------------------- */
int SockAddr_Hostare_Equal( struct sockaddr* first, struct sockaddr* second ) {
if ( first->sa_family == AF_INET && second->sa_family == AF_INET ) {
// compare IPv4 adresses
return( (long) ((struct sockaddr_in*)first)->sin_addr.s_addr ==
(long) ((struct sockaddr_in*)second)->sin_addr.s_addr);
}
#if defined(HAVE_IPV6)
if ( first->sa_family == AF_INET6 && second->sa_family == AF_INET6 ) {
// compare IPv6 addresses
return( !memcmp(((struct sockaddr_in6*)first)->sin6_addr.s6_addr,
((struct sockaddr_in6*)second)->sin6_addr.s6_addr, sizeof(struct in6_addr)));
}
#endif
return 0;
}
#ifdef __cplusplus
} /* end extern "C" */
#endif

View File

@ -1,818 +0,0 @@
/* Getopt for GNU.
NOTE: gnu_getopt is now part of the C library, so if you don't know what
"Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
before changing it!
Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97
Free Software Foundation, Inc.
This file is part of the GNU C Library. Its master source is NOT part of
the C library, however. The master source lives in /gd/gnu/lib.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/*
* modified July 9, 1999 by mark gates <mgates@nlanr.net>
* Dec 17, 1999
*
* renamed all functions and variables by prepending "gnu_"
* removed/redid a bunch of stuff under the assumption we're
* using a modern standard C compiler.
* add #include <string.h> here for strncmp(). Originally
* it was included only under special conditions.
*
* $Id: gnu_getopt.c,v 1.1.1.1 2004/05/18 01:50:44 kgibbs Exp $
*/
#include <stdio.h>
#include <stdlib.h>
#ifndef _MSC_VER /* Visual C++ doesn't have unistd.h */
#include <unistd.h>
#endif
#include <string.h>
#ifndef _
/* This is for other GNU distributions with internationalized messages.
When compiling libc, the _ macro is predefined. */
#ifdef HAVE_LIBINTL_H
#include <libintl.h>
#define _(msgid) gettext (msgid)
#else
#define _(msgid) (msgid)
#endif
#endif
/* This version of `gnu_getopt' appears to the caller like standard
Unix `getopt' but it behaves differently for the user, since it
allows the user to intersperse the options with the other
arguments.
As `gnu_getopt' works, it permutes the elements of ARGV so that,
when it is done, all the options precede everything else. Thus
all application programs are extended to handle flexible argument order.
Setting the environment variable POSIXLY_CORRECT disables permutation.
Then the behavior is completely standard.
GNU application programs can use a third alternative mode in which
they can distinguish the relative order of options and other arguments. */
#include "gnu_getopt.h"
#ifdef __cplusplus
extern "C" {
#endif
/* For communication from `gnu_getopt' to the caller.
When `gnu_getopt' finds an option that takes an argument,
the argument value is returned here.
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
char *gnu_optarg = NULL;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
and for communication between successive calls to `gnu_getopt'.
On entry to `gnu_getopt', zero means this is the first call; initialize.
When `gnu_getopt' returns -1, this is the index of the first of the
non-option elements that the caller should itself scan.
Otherwise, `gnu_optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
/* 1003.2 says this must be 1 before any call. */
int gnu_optind = 1;
/* Formerly, initialization of gnu_getopt depended on gnu_optind==0, which
causes problems with re-calling gnu_getopt as programs generally don't
know that. */
int __gnu_getopt_initialized = 0;
/* The next char to be scanned in the option-element
in which the last option character we returned was found.
This allows us to pick up the scan where we left off.
If this is zero, or a null string, it means resume the scan
by advancing to the next ARGV-element. */
static char *nextchar;
/* Callers store zero here to inhibit the error message
for unrecognized options. */
int gnu_opterr = 1;
/* Set to an option character which was unrecognized.
This must be initialized on some systems to avoid linking in the
system's own gnu_getopt implementation. */
int gnu_optopt = '?';
/* Describe how to deal with options that follow non-option ARGV-elements.
If the caller did not specify anything,
the default is REQUIRE_ORDER if the environment variable
POSIXLY_CORRECT is defined, PERMUTE otherwise.
REQUIRE_ORDER means don't recognize them as options;
stop option processing when the first non-option is seen.
This is what Unix does.
This mode of operation is selected by either setting the environment
variable POSIXLY_CORRECT, or using `+' as the first character
of the list of option characters.
PERMUTE is the default. We permute the contents of ARGV as we scan,
so that eventually all the non-options are at the end. This allows options
to be given in any order, even with programs that were not written to
expect this.
RETURN_IN_ORDER is an option available to programs that were written
to expect options and other ARGV-elements in any order and that care about
the ordering of the two. We describe each non-option ARGV-element
as if it were the argument of an option with character code 1.
Using `-' as the first character of the list of option characters
selects this mode of operation.
The special argument `--' forces an end of option-scanning regardless
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
`--' can cause `gnu_getopt' to return -1 with `gnu_optind' != ARGC. */
static enum {
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
} ordering;
/* Value of POSIXLY_CORRECT environment variable. */
static char *posixly_correct;
/* Avoid depending on library functions or files
whose names are inconsistent. */
static char *
my_index( const char* str, int chr ) {
while ( *str ) {
if ( *str == chr )
return(char *) str;
str++;
}
return 0;
}
/* Handle permutation of arguments. */
/* Describe the part of ARGV that contains non-options that have
been skipped. `first_nonopt' is the index in ARGV of the first of them;
`last_nonopt' is the index after the last of them. */
static int first_nonopt;
static int last_nonopt;
/* Exchange two adjacent subsequences of ARGV.
One subsequence is elements [first_nonopt,last_nonopt)
which contains all the non-options that have been skipped so far.
The other is elements [last_nonopt,gnu_optind), which contains all
the options processed since those non-options were skipped.
`first_nonopt' and `last_nonopt' are relocated so that they describe
the new indices of the non-options in ARGV after they are moved. */
static void exchange( char **argv );
static void
exchange( char **argv ) {
int bottom = first_nonopt;
int middle = last_nonopt;
int top = gnu_optind;
char *tem;
/* Exchange the shorter segment with the far end of the longer segment.
That puts the shorter segment into the right place.
It leaves the longer segment in the right place overall,
but it consists of two parts that need to be swapped next. */
while ( top > middle && middle > bottom ) {
if ( top - middle > middle - bottom ) {
/* Bottom segment is the short one. */
int len = middle - bottom;
register int i;
/* Swap it with the top part of the top segment. */
for ( i = 0; i < len; i++ ) {
tem = argv[bottom + i];
argv[bottom + i] = argv[top - (middle - bottom) + i];
argv[top - (middle - bottom) + i] = tem;
}
/* Exclude the moved bottom segment from further swapping. */
top -= len;
} else {
/* Top segment is the short one. */
int len = top - middle;
register int i;
/* Swap it with the bottom part of the bottom segment. */
for ( i = 0; i < len; i++ ) {
tem = argv[bottom + i];
argv[bottom + i] = argv[middle + i];
argv[middle + i] = tem;
}
/* Exclude the moved top segment from further swapping. */
bottom += len;
}
}
/* Update records for the slots the non-options now occupy. */
first_nonopt += (gnu_optind - last_nonopt);
last_nonopt = gnu_optind;
}
/* Initialize the internal data when the first call is made. */
static const char *
_gnu_getopt_initialize( int argc,
char *const * argv,
const char *optstring );
static const char *
_gnu_getopt_initialize( int argc,
char *const * argv,
const char *optstring ) {
/* Start processing options with ARGV-element 1 (since ARGV-element 0
is the program name); the sequence of previously skipped
non-option ARGV-elements is empty. */
first_nonopt = last_nonopt = gnu_optind = 1;
nextchar = NULL;
posixly_correct = getenv ("POSIXLY_CORRECT");
/* Determine how to handle the ordering of options and nonoptions. */
if ( optstring[0] == '-' ) {
ordering = RETURN_IN_ORDER;
++optstring;
} else if ( optstring[0] == '+' ) {
ordering = REQUIRE_ORDER;
++optstring;
} else if ( posixly_correct != NULL )
ordering = REQUIRE_ORDER;
else
ordering = PERMUTE;
return optstring;
}
/* Scan elements of ARGV (whose length is ARGC) for option characters
given in OPTSTRING.
If an element of ARGV starts with '-', and is not exactly "-" or "--",
then it is an option element. The characters of this element
(aside from the initial '-') are option characters. If `gnu_getopt'
is called repeatedly, it returns successively each of the option characters
from each of the option elements.
If `gnu_getopt' finds another option character, it returns that character,
updating `gnu_optind' and `nextchar' so that the next call to `gnu_getopt' can
resume the scan with the following option character or ARGV-element.
If there are no more option characters, `gnu_getopt' returns -1.
Then `gnu_optind' is the index in ARGV of the first ARGV-element
that is not an option. (The ARGV-elements have been permuted
so that those that are not options now come last.)
OPTSTRING is a string containing the legitimate option characters.
If an option character is seen that is not listed in OPTSTRING,
return '?' after printing an error message. If you set `gnu_opterr' to
zero, the error message is suppressed but we still return '?'.
If a char in OPTSTRING is followed by a colon, that means it wants an arg,
so the following text in the same ARGV-element, or the text of the following
ARGV-element, is returned in `gnu_optarg'. Two colons mean an option that
wants an optional arg; if there is text in the current ARGV-element,
it is returned in `gnu_optarg', otherwise `gnu_optarg' is set to zero.
If OPTSTRING starts with `-' or `+', it requests different methods of
handling the non-option ARGV-elements.
See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
Long-named options begin with `--' instead of `-'.
Their names may be abbreviated as long as the abbreviation is unique
or is an exact match for some defined option. If they have an
argument, it follows the option name in the same ARGV-element, separated
from the option name by a `=', or else the in next ARGV-element.
When `gnu_getopt' finds a long-named option, it returns 0 if that option's
`flag' field is nonzero, the value of the option's `val' field
if the `flag' field is zero.
The elements of ARGV aren't really const, because we permute them.
But we pretend they're const in the prototype to be compatible
with other systems.
LONGOPTS is a vector of `struct option' terminated by an
element containing a name which is zero.
LONGIND returns the index in LONGOPT of the long-named option found.
It is only valid when a long-named option has been found by the most
recent call.
If LONG_ONLY is nonzero, '-' as well as '--' can introduce
long-named options. */
int
_gnu_getopt_internal( int argc,
char *const *argv,
const char *optstring,
const struct option *longopts,
int *longind,
int long_only ) {
gnu_optarg = NULL;
if ( !__gnu_getopt_initialized || gnu_optind == 0 ) {
optstring = _gnu_getopt_initialize (argc, argv, optstring);
gnu_optind = 1; /* Don't scan ARGV[0], the program name. */
__gnu_getopt_initialized = 1;
}
/* Test whether ARGV[gnu_optind] points to a non-option argument.
Either it does not have option syntax, or there is an environment flag
from the shell indicating it is not an option. The later information
is only used when the used in the GNU libc. */
#define NONOPTION_P (argv[gnu_optind][0] != '-' || argv[gnu_optind][1] == '\0')
if ( nextchar == NULL || *nextchar == '\0' ) {
/* Advance to the next ARGV-element. */
/* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
moved back by the user (who may also have changed the arguments). */
if ( last_nonopt > gnu_optind )
last_nonopt = gnu_optind;
if ( first_nonopt > gnu_optind )
first_nonopt = gnu_optind;
if ( ordering == PERMUTE ) {
/* If we have just processed some options following some non-options,
exchange them so that the options come first. */
if ( first_nonopt != last_nonopt && last_nonopt != gnu_optind )
exchange ((char **) argv);
else if ( last_nonopt != gnu_optind )
first_nonopt = gnu_optind;
/* Skip any additional non-options
and extend the range of non-options previously skipped. */
while ( gnu_optind < argc && NONOPTION_P )
gnu_optind++;
last_nonopt = gnu_optind;
}
/* The special ARGV-element `--' means premature end of options.
Skip it like a null option,
then exchange with previous non-options as if it were an option,
then skip everything else like a non-option. */
if ( gnu_optind != argc && !strcmp (argv[gnu_optind], "--") ) {
gnu_optind++;
if ( first_nonopt != last_nonopt && last_nonopt != gnu_optind )
exchange ((char **) argv);
else if ( first_nonopt == last_nonopt )
first_nonopt = gnu_optind;
last_nonopt = argc;
gnu_optind = argc;
}
/* If we have done all the ARGV-elements, stop the scan
and back over any non-options that we skipped and permuted. */
if ( gnu_optind == argc ) {
/* Set the next-arg-index to point at the non-options
that we previously skipped, so the caller will digest them. */
if ( first_nonopt != last_nonopt )
gnu_optind = first_nonopt;
return -1;
}
/* If we have come to a non-option and did not permute it,
either stop the scan or describe it to the caller and pass it by. */
if ( NONOPTION_P ) {
if ( ordering == REQUIRE_ORDER )
return -1;
gnu_optarg = argv[gnu_optind++];
return 1;
}
/* We have found another option-ARGV-element.
Skip the initial punctuation. */
nextchar = (argv[gnu_optind] + 1
+ (longopts != NULL && argv[gnu_optind][1] == '-'));
}
/* Decode the current option-ARGV-element. */
/* Check whether the ARGV-element is a long option.
If long_only and the ARGV-element has the form "-f", where f is
a valid short option, don't consider it an abbreviated form of
a long option that starts with f. Otherwise there would be no
way to give the -f short option.
On the other hand, if there's a long option "fubar" and
the ARGV-element is "-fu", do consider that an abbreviation of
the long option, just like "--fu", and not "-f" with arg "u".
This distinction seems to be the most useful approach. */
if ( longopts != NULL
&& (argv[gnu_optind][1] == '-'
|| (long_only && (argv[gnu_optind][2] || !my_index (optstring, argv[gnu_optind][1])))) ) {
char *nameend;
const struct option *p;
const struct option *pfound = NULL;
int exact = 0;
int ambig = 0;
int indfound = -1;
int option_index;
for ( nameend = nextchar; *nameend && *nameend != '='; nameend++ )
/* Do nothing. */ ;
/* Test all long options for either exact match
or abbreviated matches. */
for ( p = longopts, option_index = 0; p->name; p++, option_index++ )
if ( !strncmp (p->name, nextchar, nameend - nextchar) ) {
if ( (unsigned int) (nameend - nextchar)
== (unsigned int) strlen (p->name) ) {
/* Exact match found. */
pfound = p;
indfound = option_index;
exact = 1;
break;
} else if ( pfound == NULL ) {
/* First nonexact match found. */
pfound = p;
indfound = option_index;
} else
/* Second or later nonexact match found. */
ambig = 1;
}
if ( ambig && !exact ) {
if ( gnu_opterr )
fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
argv[0], argv[gnu_optind]);
nextchar += strlen (nextchar);
gnu_optind++;
gnu_optopt = 0;
return '?';
}
if ( pfound != NULL ) {
option_index = indfound;
gnu_optind++;
if ( *nameend ) {
/* Don't test has_arg with >, because some C compilers don't
allow it to be used on enums. */
if ( pfound->has_arg )
gnu_optarg = nameend + 1;
else {
if ( gnu_opterr ) {
if ( argv[gnu_optind - 1][1] == '-' ) {
/* --option */
fprintf (stderr,
_("%s: option `--%s' doesn't allow an argument\n"),
argv[0], pfound->name);
} else {
/* +option or -option */
fprintf (stderr,
_("%s: option `%c%s' doesn't allow an argument\n"),
argv[0], argv[gnu_optind - 1][0], pfound->name);
}
}
nextchar += strlen (nextchar);
gnu_optopt = pfound->val;
return '?';
}
} else if ( pfound->has_arg == 1 ) {
if ( gnu_optind < argc )
gnu_optarg = argv[gnu_optind++];
else {
if ( gnu_opterr )
fprintf (stderr,
_("%s: option `%s' requires an argument\n"),
argv[0], argv[gnu_optind - 1]);
nextchar += strlen (nextchar);
gnu_optopt = pfound->val;
return optstring[0] == ':' ? ':' : '?';
}
}
nextchar += strlen (nextchar);
if ( longind != NULL )
*longind = option_index;
if ( pfound->flag ) {
*(pfound->flag) = pfound->val;
return 0;
}
return pfound->val;
}
/* Can't find it as a long option. If this is not gnu_getopt_long_only,
or the option starts with '--' or is not a valid short
option, then it's an error.
Otherwise interpret it as a short option. */
if ( !long_only || argv[gnu_optind][1] == '-'
|| my_index (optstring, *nextchar) == NULL ) {
if ( gnu_opterr ) {
if ( argv[gnu_optind][1] == '-' )
/* --option */
fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
argv[0], nextchar);
else
/* +option or -option */
fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
argv[0], argv[gnu_optind][0], nextchar);
}
nextchar = (char *) "";
gnu_optind++;
gnu_optopt = 0;
return '?';
}
}
/* Look at and handle the next short option-character. */
{
char c = *nextchar++;
char *temp = my_index (optstring, c);
/* Increment `gnu_optind' when we start to process its last character. */
if ( *nextchar == '\0' )
++gnu_optind;
if ( temp == NULL || c == ':' ) {
if ( gnu_opterr ) {
if ( posixly_correct )
/* 1003.2 specifies the format of this message. */
fprintf (stderr, _("%s: illegal option -- %c\n"),
argv[0], c);
else
fprintf (stderr, _("%s: invalid option -- %c\n"),
argv[0], c);
}
gnu_optopt = c;
return '?';
}
/* Convenience. Treat POSIX -W foo same as long option --foo */
if ( temp[0] == 'W' && temp[1] == ';' ) {
char *nameend;
const struct option *p;
const struct option *pfound = NULL;
int exact = 0;
int ambig = 0;
int indfound = 0;
int option_index;
/* This is an option that requires an argument. */
if ( *nextchar != '\0' ) {
gnu_optarg = nextchar;
/* If we end this ARGV-element by taking the rest as an arg,
we must advance to the next element now. */
gnu_optind++;
} else if ( gnu_optind == argc ) {
if ( gnu_opterr ) {
/* 1003.2 specifies the format of this message. */
fprintf (stderr, _("%s: option requires an argument -- %c\n"),
argv[0], c);
}
gnu_optopt = c;
if ( optstring[0] == ':' )
c = ':';
else
c = '?';
return c;
} else
/* We already incremented `gnu_optind' once;
increment it again when taking next ARGV-elt as argument. */
gnu_optarg = argv[gnu_optind++];
/* gnu_optarg is now the argument, see if it's in the
table of longopts. */
for ( nextchar = nameend = gnu_optarg; *nameend && *nameend != '='; nameend++ )
/* Do nothing. */ ;
/* Test all long options for either exact match
or abbreviated matches. */
for ( p = longopts, option_index = 0; p->name; p++, option_index++ )
if ( !strncmp (p->name, nextchar, nameend - nextchar) ) {
if ( (unsigned int) (nameend - nextchar) == strlen (p->name) ) {
/* Exact match found. */
pfound = p;
indfound = option_index;
exact = 1;
break;
} else if ( pfound == NULL ) {
/* First nonexact match found. */
pfound = p;
indfound = option_index;
} else
/* Second or later nonexact match found. */
ambig = 1;
}
if ( ambig && !exact ) {
if ( gnu_opterr )
fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
argv[0], argv[gnu_optind]);
nextchar += strlen (nextchar);
gnu_optind++;
return '?';
}
if ( pfound != NULL ) {
option_index = indfound;
if ( *nameend ) {
/* Don't test has_arg with >, because some C compilers don't
allow it to be used on enums. */
if ( pfound->has_arg )
gnu_optarg = nameend + 1;
else {
if ( gnu_opterr )
fprintf (stderr, _("\
%s: option `-W %s' doesn't allow an argument\n"),
argv[0], pfound->name);
nextchar += strlen (nextchar);
return '?';
}
} else if ( pfound->has_arg == 1 ) {
if ( gnu_optind < argc )
gnu_optarg = argv[gnu_optind++];
else {
if ( gnu_opterr )
fprintf (stderr,
_("%s: option `%s' requires an argument\n"),
argv[0], argv[gnu_optind - 1]);
nextchar += strlen (nextchar);
return optstring[0] == ':' ? ':' : '?';
}
}
nextchar += strlen (nextchar);
if ( longind != NULL )
*longind = option_index;
if ( pfound->flag ) {
*(pfound->flag) = pfound->val;
return 0;
}
return pfound->val;
}
nextchar = NULL;
return 'W'; /* Let the application handle it. */
}
if ( temp[1] == ':' ) {
if ( temp[2] == ':' ) {
/* This is an option that accepts an argument optionally. */
if ( *nextchar != '\0' ) {
gnu_optarg = nextchar;
gnu_optind++;
} else
gnu_optarg = NULL;
nextchar = NULL;
} else {
/* This is an option that requires an argument. */
if ( *nextchar != '\0' ) {
gnu_optarg = nextchar;
/* If we end this ARGV-element by taking the rest as an arg,
we must advance to the next element now. */
gnu_optind++;
} else if ( gnu_optind == argc ) {
if ( gnu_opterr ) {
/* 1003.2 specifies the format of this message. */
fprintf (stderr,
_("%s: option requires an argument -- %c\n"),
argv[0], c);
}
gnu_optopt = c;
if ( optstring[0] == ':' )
c = ':';
else
c = '?';
} else
/* We already incremented `gnu_optind' once;
increment it again when taking next ARGV-elt as argument. */
gnu_optarg = argv[gnu_optind++];
nextchar = NULL;
}
}
return c;
}
}
int
gnu_getopt ( int argc,
char *const *argv,
const char *optstring ) {
return _gnu_getopt_internal (argc, argv, optstring,
(const struct option *) 0,
(int *) 0,
0);
}
#ifdef __cplusplus
} /* end extern "C" */
#endif
#ifdef TEST
/* Compile with -DTEST to make an executable for use in testing
the above definition of `gnu_getopt'. */
int
main (argc, argv)
int argc;
char **argv;
{
int c;
int digit_optind = 0;
while ( 1 ) {
int this_option_optind = gnu_optind ? gnu_optind : 1;
c = gnu_getopt (argc, argv, "abc:d:0123456789");
if ( c == -1 )
break;
switch ( c ) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if ( digit_optind != 0 && digit_optind != this_option_optind )
fprintf ( stderr, "digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
fprintf ( stderr, "option %c\n", c);
break;
case 'a':
fprintf ( stderr, "option a\n");
break;
case 'b':
fprintf ( stderr, "option b\n");
break;
case 'c':
fprintf ( stderr, "option c with value `%s'\n", gnu_optarg);
break;
case '?':
break;
default:
fprintf ( stderr, "?? gnu_getopt returned character code 0%o ??\n", c);
}
}
if ( gnu_optind < argc ) {
fprintf (stderr, "non-option ARGV-elements: ");
while ( gnu_optind < argc )
fprintf ( stderr, "%s ", argv[gnu_optind++]);
fprintf ( stderr, "\n");
}
exit (0);
}
#endif /* TEST */

View File

@ -1,162 +0,0 @@
/* gnu_getopt_long and getopt_long_only entry points for GNU getopt.
Copyright (C) 1987,88,89,90,91,92,93,94,96,97 Free Software Foundation, Inc.
This file is part of the GNU C Library. Its master source is NOT part of
the C library, however. The master source lives in /gd/gnu/lib.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/*
* modified July 9, 1999 by mark gates <mgates@nlanr.net>
* Dec 17, 1999
*
* renamed all functions and variables by prepending "gnu_"
* removed/redid a bunch of stuff under the assumption we're
* using a modern standard C compiler.
* renamed file to gnu_getopt_long.c (from gnu_getopt1.c)
*
* $Id: gnu_getopt_long.c,v 1.1.1.1 2004/05/18 01:50:44 kgibbs Exp $
*/
#include "gnu_getopt.h"
#include <stdio.h>
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
int
gnu_getopt_long( int argc,
char *const *argv,
const char *options,
const struct option *long_options,
int *opt_index ) {
return _gnu_getopt_internal (argc, argv, options, long_options, opt_index, 0);
}
/* Like gnu_getopt_long, but '-' as well as '--' can indicate a long option.
If an option that starts with '-' (not '--') doesn't match a long option,
but does match a short option, it is parsed as a short option
instead. */
int
gnu_getopt_long_only( int argc,
char *const *argv,
const char *options,
const struct option *long_options,
int *opt_index ) {
return _gnu_getopt_internal (argc, argv, options, long_options, opt_index, 1);
}
#ifdef __cplusplus
} /* end extern "C" */
#endif
#ifdef TEST
#include <stdio.h>
int
main (argc, argv)
int argc;
char **argv;
{
int c;
int digit_optind = 0;
while ( 1 ) {
int this_option_optind = gnu_optind ? gnu_optind : 1;
int option_index = 0;
static struct option long_options[] =
{
{"add", 1, 0, 0},
{"append", 0, 0, 0},
{"delete", 1, 0, 0},
{"verbose", 0, 0, 0},
{"create", 0, 0, 0},
{"file", 1, 0, 0},
{0, 0, 0, 0}
};
c = gnu_getopt_long (argc, argv, "abc:d:0123456789",
long_options, &option_index);
if ( c == -1 )
break;
switch ( c ) {
case 0:
fprintf ( stderr, "option %s", long_options[option_index].name);
if ( gnu_optarg )
fprintf ( stderr, " with arg %s", gnu_optarg);
fprintf ( stderr, "\n");
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if ( digit_optind != 0 && digit_optind != this_option_optind )
fprintf ( stderr, "digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
fprintf ( stderr, "option %c\n", c);
break;
case 'a':
fprintf ( stderr, "option a\n");
break;
case 'b':
fprintf ( stderr, "option b\n");
break;
case 'c':
fprintf ( stderr, "option c with value `%s'\n", gnu_optarg);
break;
case 'd':
fprintf ( stderr, "option d with value `%s'\n", gnu_optarg);
break;
case '?':
break;
default:
fprintf ( stderr, "?? gnu_getopt returned character code 0%o ??\n", c);
}
}
if ( gnu_optind < argc ) {
fprintf ( stderr, "non-option ARGV-elements: ");
while ( gnu_optind < argc )
fprintf ( stderr, "%s ", argv[gnu_optind++]);
fprintf ( stderr, "\n");
}
exit (0);
}
#endif /* TEST */

View File

@ -1,295 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
* main.cpp
* by Mark Gates <mgates@nlanr.net>
* & Ajay Tirumala <tirumala@ncsa.uiuc.edu>
* -------------------------------------------------------------------
* main does initialization and creates the various objects that will
* actually run the iperf program, then waits in the Joinall().
* -------------------------------------------------------------------
* headers
* uses
* <stdlib.h>
* <string.h>
*
* <signal.h>
* ------------------------------------------------------------------- */
#define HEADERS()
#include "headers.h"
#include "Settings.hpp"
#include "PerfSocket.hpp"
#include "Locale.h"
#include "Condition.h"
#include "Timestamp.hpp"
#include "Listener.hpp"
#include "List.h"
#include "util.h"
#ifdef WIN32
#include "service.h"
#endif
/* -------------------------------------------------------------------
* prototypes
* ------------------------------------------------------------------- */
// Function called at exit to clean up as much as possible
void cleanup( void );
/* -------------------------------------------------------------------
* global variables
* ------------------------------------------------------------------- */
extern "C" {
// Global flag to signal a user interrupt
int sInterupted = 0;
// Global ID that we increment to be used
// as identifier for SUM reports
int groupID = 0;
// Mutex to protect access to the above ID
Mutex groupCond;
// Condition used to signify advances of the current
// records being accessed in a report and also to
// serialize modification of the report list
Condition ReportCond;
}
// global variables only accessed within this file
// Thread that received the SIGTERM or SIGINT signal
// Used to ensure that if multiple threads receive the
// signal we do not prematurely exit
nthread_t sThread;
// The main thread uses this function to wait
// for all other threads to complete
void waitUntilQuit( void );
/* -------------------------------------------------------------------
* main()
* Entry point into Iperf
*
* sets up signal handlers
* initialize global locks and conditions
* parses settings from environment and command line
* starts up server or client thread
* waits for all threads to complete
* ------------------------------------------------------------------- */
int main( int argc, char **argv ) {
// Set SIGTERM and SIGINT to call our user interrupt function
my_signal( SIGTERM, Sig_Interupt );
my_signal( SIGINT, Sig_Interupt );
my_signal( SIGALRM, Sig_Interupt );
#ifndef WIN32
// Ignore broken pipes
signal(SIGPIPE,SIG_IGN);
#else
// Start winsock
WSADATA wsaData;
int rc = WSAStartup( 0x202, &wsaData );
WARN_errno( rc == SOCKET_ERROR, "WSAStartup" );
if (rc == SOCKET_ERROR)
return 0;
// Tell windows we want to handle our own signals
SetConsoleCtrlHandler( sig_dispatcher, true );
#endif
// Initialize global mutexes and conditions
Condition_Initialize ( &ReportCond );
Mutex_Initialize( &groupCond );
Mutex_Initialize( &clients_mutex );
// Initialize the thread subsystem
thread_init( );
// Initialize the interrupt handling thread to 0
sThread = thread_zeroid();
// perform any cleanup when quitting Iperf
atexit( cleanup );
// Allocate the "global" settings
thread_Settings* ext_gSettings = new thread_Settings;
// Initialize settings to defaults
Settings_Initialize( ext_gSettings );
// read settings from environment variables
Settings_ParseEnvironment( ext_gSettings );
// read settings from command-line parameters
Settings_ParseCommandLine( argc, argv, ext_gSettings );
// Check for either having specified client or server
if ( ext_gSettings->mThreadMode == kMode_Client
|| ext_gSettings->mThreadMode == kMode_Listener ) {
#ifdef WIN32
// Start the server as a daemon
// Daemon mode for non-windows in handled
// in the listener_spawn function
if ( isDaemon( ext_gSettings ) ) {
CmdInstallService(argc, argv);
return 0;
}
// Remove the Windows service if requested
if ( isRemoveService( ext_gSettings ) ) {
// remove the service
if ( CmdRemoveService() ) {
fprintf(stderr, "IPerf Service is removed.\n");
return 0;
}
}
#endif
// initialize client(s)
if ( ext_gSettings->mThreadMode == kMode_Client ) {
client_init( ext_gSettings );
}
#ifdef HAVE_THREAD
// start up the reporter and client(s) or listener
{
thread_Settings *into = NULL;
// Create the settings structure for the reporter thread
Settings_Copy( ext_gSettings, &into );
into->mThreadMode = kMode_Reporter;
// Have the reporter launch the client or listener
into->runNow = ext_gSettings;
// Start all the threads that are ready to go
thread_start( into );
}
#else
// No need to make a reporter thread because we don't have threads
thread_start( ext_gSettings );
#endif
} else {
// neither server nor client mode was specified
// print usage and exit
#ifdef WIN32
// In Win32 we also attempt to start a previously defined service
// Starting in 2.0 to restart a previously defined service
// you must call iperf with "iperf -D" or using the environment variable
SERVICE_TABLE_ENTRY dispatchTable[] =
{
{ TEXT(SZSERVICENAME), (LPSERVICE_MAIN_FUNCTION)service_main},
{ NULL, NULL}
};
// Only attempt to start the service if "-D" was specified
if ( !isDaemon(ext_gSettings) ||
// starting the service by SCM, there is no arguments will be passed in.
// the arguments will pass into Service_Main entry.
!StartServiceCtrlDispatcher(dispatchTable) )
// If the service failed to start then print usage
#endif
fprintf( stderr, usage_short, argv[0], argv[0] );
return 0;
}
// wait for other (client, server) threads to complete
thread_joinall();
// all done!
return 0;
} // end main
/* -------------------------------------------------------------------
* Signal handler sets the sInterupted flag, so the object can
* respond appropriately.. [static]
* ------------------------------------------------------------------- */
void Sig_Interupt( int inSigno ) {
#ifdef HAVE_THREAD
// We try to not allow a single interrupt handled by multiple threads
// to completely kill the app so we save off the first thread ID
// then that is the only thread that can supply the next interrupt
if ( thread_equalid( sThread, thread_zeroid() ) ) {
sThread = thread_getid();
} else if ( thread_equalid( sThread, thread_getid() ) ) {
sig_exit( inSigno );
}
// global variable used by threads to see if they were interrupted
sInterupted = 1;
// with threads, stop waiting for non-terminating threads
// (ie Listener Thread)
thread_release_nonterm( 1 );
#else
// without threads, just exit quietly, same as sig_exit()
sig_exit( inSigno );
#endif
}
/* -------------------------------------------------------------------
* Any necesary cleanup before Iperf quits. Called at program exit,
* either by exit() or terminating main().
* ------------------------------------------------------------------- */
void cleanup( void ) {
#ifdef WIN32
// Shutdown Winsock
WSACleanup();
#endif
// clean up the list of clients
Iperf_destroy ( &clients );
// shutdown the thread subsystem
thread_destroy( );
} // end cleanup

View File

@ -1,601 +0,0 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (C) 1993-1997 Microsoft Corporation. All Rights Reserved.
//
// MODULE: service.c
//
// PURPOSE: Implements functions required by all services
// windows.
//
// FUNCTIONS:
// main(int argc, char **argv);
// service_ctrl(DWORD dwCtrlCode);
// service_main(DWORD dwArgc, LPTSTR *lpszArgv);
// CmdInstallService();
// CmdRemoveService();
// ControlHandler ( DWORD dwCtrlType );
// GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize );
//
// COMMENTS:
//
// AUTHOR: Craig Link - Microsoft Developer Support
//
/*
* modified Mar.07, 2002 by Feng Qin <fqin@ncsa.uiuc.edu>
* Mar.15, 2002
*
* removed some functions we don't use at all
* add code to start the service immediately after service is installed
*
* $Id: service.c,v 1.1.1.1 2004/05/18 01:50:44 kgibbs Exp $
*/
#ifdef WIN32
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <process.h>
#include <tchar.h>
#include "service.h"
// internal variables
SERVICE_STATUS ssStatus; // current status of the service
SERVICE_STATUS_HANDLE sshStatusHandle;
DWORD dwErr = 0;
TCHAR szErr[256];
//
// FUNCTION: service_main
//
// PURPOSE: To perform actual initialization of the service
//
// PARAMETERS:
// dwArgc - number of command line arguments
// lpszArgv - array of command line arguments
//
// RETURN VALUE:
// none
//
// COMMENTS:
// This routine performs the service initialization and then calls
// the user defined ServiceStart() routine to perform majority
// of the work.
//
void WINAPI service_main(DWORD dwArgc, LPTSTR *lpszArgv) {
// register our service control handler:
//
sshStatusHandle = RegisterServiceCtrlHandler( TEXT(SZSERVICENAME), service_ctrl);
if ( !sshStatusHandle )
goto clean;
// SERVICE_STATUS members that don't change in example
//
ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ssStatus.dwServiceSpecificExitCode = 0;
// report the status to the service control manager.
//
if ( !ReportStatusToSCMgr(
SERVICE_START_PENDING, // service state
NO_ERROR, // exit code
3000) ) // wait hint
goto clean;
ServiceStart( dwArgc, lpszArgv );
clean:
// try to report the stopped status to the service control manager.
//
if ( sshStatusHandle )
(VOID)ReportStatusToSCMgr(
SERVICE_STOPPED,
dwErr,
0);
return;
}
//
// FUNCTION: service_ctrl
//
// PURPOSE: This function is called by the SCM whenever
// ControlService() is called on this service.
//
// PARAMETERS:
// dwCtrlCode - type of control requested
//
// RETURN VALUE:
// none
//
// COMMENTS:
//
VOID WINAPI service_ctrl(DWORD dwCtrlCode) {
// Handle the requested control code.
//
switch ( dwCtrlCode ) {
// Stop the service.
//
// SERVICE_STOP_PENDING should be reported before
// setting the Stop Event - hServerStopEvent - in
// ServiceStop(). This avoids a race condition
// which may result in a 1053 - The Service did not respond...
// error.
case SERVICE_CONTROL_STOP:
ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 0);
ServiceStop();
return;
// Update the service status.
//
case SERVICE_CONTROL_INTERROGATE:
break;
// invalid control code
//
default:
break;
}
ReportStatusToSCMgr(SERVICE_STOPPED, NO_ERROR, 0);
// ReportStatusToSCMgr(ssStatus.dwCurrentState, NO_ERROR, 0);
}
//
// FUNCTION: ReportStatusToSCMgr()
//
// PURPOSE: Sets the current status of the service and
// reports it to the Service Control Manager
//
// PARAMETERS:
// dwCurrentState - the state of the service
// dwWin32ExitCode - error code to report
// dwWaitHint - worst case estimate to next checkpoint
//
// RETURN VALUE:
// TRUE - success
// FALSE - failure
//
// COMMENTS:
//
BOOL ReportStatusToSCMgr(DWORD dwCurrentState,
DWORD dwWin32ExitCode,
DWORD dwWaitHint) {
static DWORD dwCheckPoint = 1;
BOOL fResult = TRUE;
if ( dwCurrentState == SERVICE_START_PENDING )
ssStatus.dwControlsAccepted = 0;
else
ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
ssStatus.dwCurrentState = dwCurrentState;
ssStatus.dwWin32ExitCode = dwWin32ExitCode;
ssStatus.dwWaitHint = dwWaitHint;
if ( ( dwCurrentState == SERVICE_RUNNING ) ||
( dwCurrentState == SERVICE_STOPPED ) )
ssStatus.dwCheckPoint = 0;
else
ssStatus.dwCheckPoint = dwCheckPoint++;
// Report the status of the service to the service control manager.
//
if ( !(fResult = SetServiceStatus( sshStatusHandle, &ssStatus)) ) {
AddToMessageLog(TEXT("SetServiceStatus"));
}
return fResult;
}
//
// FUNCTION: AddToMessageLog(LPTSTR lpszMsg)
//
// PURPOSE: Allows any thread to log an error message
//
// PARAMETERS:
// lpszMsg - text for message
//
// RETURN VALUE:
// none
//
// COMMENTS:
//
VOID AddToMessageLog(LPTSTR lpszMsg) {
TCHAR szMsg[256];
HANDLE hEventSource;
LPTSTR lpszStrings[2];
dwErr = GetLastError();
// Use event logging to log the error.
//
hEventSource = RegisterEventSource(NULL, TEXT(SZSERVICENAME));
printf(lpszMsg);
_stprintf(szMsg, TEXT("%s error: %d"), TEXT(SZSERVICENAME), dwErr);
lpszStrings[0] = szMsg;
lpszStrings[1] = lpszMsg;
if ( hEventSource != NULL ) {
ReportEvent(hEventSource, // handle of event source
EVENTLOG_ERROR_TYPE, // event type
0, // event category
0, // event ID
NULL, // current user's SID
2, // strings in lpszStrings
0, // no bytes of raw data
lpszStrings, // array of error strings
NULL); // no raw data
(VOID) DeregisterEventSource(hEventSource);
}
}
///////////////////////////////////////////////////////////////////
//
// The following code handles service installation and removal
//
//
// FUNCTION: CmdInstallService()
//
// PURPOSE: Installs the service and Starts it
//
// PARAMETERS:
// argc: number of arguments
// argv: all of the arguments including the program's name
//
// RETURN VALUE:
// none
//
// COMMENTS:
//
void CmdInstallService(int argc, char **argv) {
SC_HANDLE schService;
SC_HANDLE schSCManager;
TCHAR szPath[512];
if ( GetModuleFileName( NULL, szPath, 512 ) == 0 ) {
_tprintf(TEXT("Unable to install %s - %s\n"), TEXT(SZSERVICEDISPLAYNAME), GetLastErrorText(szErr, 256));
return;
}
schSCManager = OpenSCManager(
NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS // access required
);
if ( schSCManager ) {
schService = OpenService(schSCManager, TEXT(SZSERVICENAME), SERVICE_ALL_ACCESS);
if ( !schService ) {
schService = CreateService(
schSCManager, // SCManager database
TEXT(SZSERVICENAME), // name of service
TEXT(SZSERVICEDISPLAYNAME), // name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_WIN32_OWN_PROCESS, // service type
SERVICE_DEMAND_START, // start type
SERVICE_ERROR_NORMAL, // error control type
szPath, // service's binary
NULL, // no load ordering group
NULL, // no tag identifier
TEXT(SZDEPENDENCIES), // dependencies
NULL, // LocalSystem account
NULL); // no password
} else {
_tprintf(TEXT("%s already installed.\n"), TEXT(SZSERVICEDISPLAYNAME) );
}
if ( schService ) {
if ( QueryServiceStatus( schService, &ssStatus ) ) {
int rc;
if ( ssStatus.dwCurrentState == SERVICE_STOPPED ) {
rc = StartService(schService, argc-1, argv+1);
}
if ( rc != 0 )
_tprintf(TEXT("%s started.\n"), TEXT(SZSERVICEDISPLAYNAME) );
}
CloseServiceHandle(schService);
} else {
_tprintf(TEXT("CreateService failed - %s\n"), GetLastErrorText(szErr, 256));
}
CloseServiceHandle(schSCManager);
} else
_tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256));
}
//
// FUNCTION: CmdRemoveService()
//
// PURPOSE: Stops and removes the service
//
// PARAMETERS:
// none
//
// RETURN VALUE:
// TRUE: service exists and is removed
// FALSE: service doesn't exist
//
// COMMENTS:
//
BOOL CmdRemoveService() {
BOOL isExist = FALSE;
SC_HANDLE schService;
SC_HANDLE schSCManager;
schSCManager = OpenSCManager(
NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS // access required
);
if ( schSCManager ) {
schService = OpenService(schSCManager, TEXT(SZSERVICENAME), SERVICE_ALL_ACCESS);
if ( schService ) {
isExist = TRUE;
// try to stop the service
if ( ControlService( schService, SERVICE_CONTROL_STOP, &ssStatus ) ) {
_tprintf(TEXT("Stopping %s."), TEXT(SZSERVICEDISPLAYNAME));
Sleep( 1000 );
while ( QueryServiceStatus( schService, &ssStatus ) ) {
if ( ssStatus.dwCurrentState == SERVICE_STOP_PENDING ) {
_tprintf(TEXT("."));
Sleep( 1000 );
} else
break;
}
if ( ssStatus.dwCurrentState == SERVICE_STOPPED )
_tprintf(TEXT("\n%s stopped.\n"), TEXT(SZSERVICEDISPLAYNAME) );
else
_tprintf(TEXT("\n%s failed to stop.\n"), TEXT(SZSERVICEDISPLAYNAME) );
}
// now remove the service
if ( DeleteService(schService) )
_tprintf(TEXT("%s removed.\n"), TEXT(SZSERVICEDISPLAYNAME) );
else
_tprintf(TEXT("DeleteService failed - %s\n"), GetLastErrorText(szErr,256));
CloseServiceHandle(schService);
}
CloseServiceHandle(schSCManager);
} else
_tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256));
return isExist;
}
//
// FUNCTION: CmdStartService()
//
// PURPOSE: Start service if it exists
//
// PARAMETERS:
// argc: number of arguments
// argv: arguments including program's name
//
// RETURN VALUE:
// TRUE: service exists and is started
// FALSE: service doesn't exist
//
// COMMENTS:
//
BOOL CmdStartService(int argc, char **argv) {
BOOL isExist = FALSE;
SC_HANDLE schService;
SC_HANDLE schSCManager;
schSCManager = OpenSCManager(
NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS // access required
);
if ( schSCManager ) {
schService = OpenService(schSCManager, TEXT(SZSERVICENAME), SERVICE_ALL_ACCESS);
if ( schService ) {
isExist = TRUE;
if ( QueryServiceStatus( schService, &ssStatus ) ) {
int rc;
if ( ssStatus.dwCurrentState == SERVICE_STOPPED ) {
rc = StartService(schService, argc-1, argv+1);
}
if ( rc != 0 )
_tprintf(TEXT("%s started.\n"), TEXT(SZSERVICEDISPLAYNAME) );
}
CloseServiceHandle(schService);
}
CloseServiceHandle(schSCManager);
} else
_tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256));
return isExist;
}
//
// FUNCTION: GetLastErrorText
//
// PURPOSE: copies error message text to string
//
// PARAMETERS:
// lpszBuf - destination buffer
// dwSize - size of buffer
//
// RETURN VALUE:
// destination buffer
//
// COMMENTS:
//
LPTSTR GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize ) {
DWORD dwRet;
LPTSTR lpszTemp = NULL;
dwRet = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_ARGUMENT_ARRAY,
NULL,
GetLastError(),
LANG_NEUTRAL,
(LPTSTR)&lpszTemp,
0,
NULL );
// supplied buffer is not long enough
if ( !dwRet || ( (long)dwSize < (long)dwRet+14 ) )
lpszBuf[0] = TEXT('\0');
else {
lpszTemp[lstrlen(lpszTemp)-2] = TEXT('\0'); //remove cr and newline character
_stprintf( lpszBuf, TEXT("%s (0x%x)"), lpszTemp, GetLastError() );
}
if ( lpszTemp )
LocalFree((HLOCAL) lpszTemp );
return lpszBuf;
}
/*--------------------------------------------------------------------
* ServiceStart
*
* each time starting the service, this is the entry point of the service.
* Start the service, certainly it is on server-mode
*
*-------------------------------------------------------------------- */
VOID ServiceStart (DWORD dwArgc, LPTSTR *lpszArgv) {
// report the status to the service control manager.
//
if ( !ReportStatusToSCMgr(
SERVICE_START_PENDING, // service state
NO_ERROR, // exit code
3000) ) // wait hint
goto clean;
thread_Settings* ext_gSettings = new thread_Settings;
// Initialize settings to defaults
Settings_Initialize( ext_gSettings );
// read settings from environment variables
Settings_ParseEnvironment( ext_gSettings );
// read settings from command-line parameters
Settings_ParseCommandLine( dwArgc, lpszArgv, ext_gSettings );
// report the status to the service control manager.
//
if ( !ReportStatusToSCMgr(
SERVICE_START_PENDING, // service state
NO_ERROR, // exit code
3000) ) // wait hint
goto clean;
// if needed, redirect the output into a specified file
if ( !isSTDOUT( ext_gSettings ) ) {
redirect( ext_gSettings->mOutputFileName );
}
// report the status to the service control manager.
//
if ( !ReportStatusToSCMgr(
SERVICE_START_PENDING, // service state
NO_ERROR, // exit code
3000) ) // wait hint
goto clean;
// initialize client(s)
if ( ext_gSettings->mThreadMode == kMode_Client ) {
client_init( ext_gSettings );
}
// start up the reporter and client(s) or listener
{
thread_Settings *into = NULL;
#ifdef HAVE_THREAD
Settings_Copy( ext_gSettings, &into );
into->mThreadMode = kMode_Reporter;
into->runNow = ext_gSettings;
#else
into = ext_gSettings;
#endif
thread_start( into );
}
// report the status to the service control manager.
//
if ( !ReportStatusToSCMgr(
SERVICE_RUNNING, // service state
NO_ERROR, // exit code
0) ) // wait hint
goto clean;
clean:
// wait for other (client, server) threads to complete
thread_joinall();
}
//
// FUNCTION: ServiceStop
//
// PURPOSE: Stops the service
//
// PARAMETERS:
// none
//
// RETURN VALUE:
// none
//
// COMMENTS:
// If a ServiceStop procedure is going to
// take longer than 3 seconds to execute,
// it should spawn a thread to execute the
// stop code, and return. Otherwise, the
// ServiceControlManager will believe that
// the service has stopped responding.
//
VOID ServiceStop() {
#ifdef HAVE_THREAD
Sig_Interupt( 1 );
#else
sig_exit(1);
#endif
}
#endif

View File

@ -1,196 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* socket.c
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* set/getsockopt and read/write wrappers
* ------------------------------------------------------------------- */
#include "headers.h"
#include "util.h"
#ifdef __cplusplus
extern "C" {
#endif
/* -------------------------------------------------------------------
* If inMSS > 0, set the TCP maximum segment size for inSock.
* Otherwise leave it as the system default.
* ------------------------------------------------------------------- */
const char warn_mss_fail[] = "\
WARNING: attempt to set TCP maxmimum segment size to %d failed.\n\
Setting the MSS may not be implemented on this OS.\n";
const char warn_mss_notset[] =
"WARNING: attempt to set TCP maximum segment size to %d, but got %d\n";
void setsock_tcp_mss( int inSock, int inMSS ) {
#ifdef TCP_MAXSEG
int rc;
int newMSS;
Socklen_t len;
assert( inSock != INVALID_SOCKET );
if ( inMSS > 0 ) {
/* set */
newMSS = inMSS;
len = sizeof( newMSS );
rc = setsockopt( inSock, IPPROTO_TCP, TCP_MAXSEG, (char*) &newMSS, len );
if ( rc == SOCKET_ERROR ) {
fprintf( stderr, warn_mss_fail, newMSS );
return;
}
/* verify results */
rc = getsockopt( inSock, IPPROTO_TCP, TCP_MAXSEG, (char*) &newMSS, &len );
WARN_errno( rc == SOCKET_ERROR, "getsockopt TCP_MAXSEG" );
if ( newMSS != inMSS ) {
fprintf( stderr, warn_mss_notset, inMSS, newMSS );
}
}
#endif
} /* end setsock_tcp_mss */
/* -------------------------------------------------------------------
* returns the TCP maximum segment size
* ------------------------------------------------------------------- */
int getsock_tcp_mss( int inSock ) {
int theMSS = 0;
#ifdef TCP_MAXSEG
int rc;
Socklen_t len;
assert( inSock >= 0 );
/* query for MSS */
len = sizeof( theMSS );
rc = getsockopt( inSock, IPPROTO_TCP, TCP_MAXSEG, (char*) &theMSS, &len );
WARN_errno( rc == SOCKET_ERROR, "getsockopt TCP_MAXSEG" );
#endif
return theMSS;
} /* end getsock_tcp_mss */
/* -------------------------------------------------------------------
* Attempts to reads n bytes from a socket.
* Returns number actually read, or -1 on error.
* If number read < inLen then we reached EOF.
*
* from Stevens, 1998, section 3.9
* ------------------------------------------------------------------- */
ssize_t readn( int inSock, void *outBuf, size_t inLen ) {
size_t nleft;
ssize_t nread;
char *ptr;
assert( inSock >= 0 );
assert( outBuf != NULL );
assert( inLen > 0 );
ptr = (char*) outBuf;
nleft = inLen;
while ( nleft > 0 ) {
nread = read( inSock, ptr, nleft );
if ( nread < 0 ) {
if ( errno == EINTR )
nread = 0; /* interupted, call read again */
else
return -1; /* error */
} else if ( nread == 0 )
break; /* EOF */
nleft -= nread;
ptr += nread;
}
return(inLen - nleft);
} /* end readn */
/* -------------------------------------------------------------------
* Attempts to write n bytes to a socket.
* returns number actually written, or -1 on error.
* number written is always inLen if there is not an error.
*
* from Stevens, 1998, section 3.9
* ------------------------------------------------------------------- */
ssize_t writen( int inSock, const void *inBuf, size_t inLen ) {
size_t nleft;
ssize_t nwritten;
const char *ptr;
assert( inSock >= 0 );
assert( inBuf != NULL );
assert( inLen > 0 );
ptr = (char*) inBuf;
nleft = inLen;
while ( nleft > 0 ) {
nwritten = write( inSock, ptr, nleft );
if ( nwritten <= 0 ) {
if ( errno == EINTR )
nwritten = 0; /* interupted, call write again */
else
return -1; /* error */
}
nleft -= nwritten;
ptr += nwritten;
}
return inLen;
} /* end writen */
#ifdef __cplusplus
} /* end extern "C" */
#endif

View File

@ -1,177 +0,0 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* tcp_window_size.c
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* set/getsockopt
* ------------------------------------------------------------------- */
#include "headers.h"
#include "util.h"
#ifdef __cplusplus
extern "C" {
#endif
/* -------------------------------------------------------------------
* If inTCPWin > 0, set the TCP window size (via the socket buffer
* sizes) for inSock. Otherwise leave it as the system default.
*
* This must be called prior to calling listen() or connect() on
* the socket, for TCP window sizes > 64 KB to be effective.
*
* This now works on UNICOS also, by setting TCP_WINSHIFT.
* This now works on AIX, by enabling RFC1323.
* returns -1 on error, 0 on no error.
* ------------------------------------------------------------------- */
int setsock_tcp_windowsize( int inSock, int inTCPWin, int inSend ) {
#ifdef SO_SNDBUF
int rc;
int newTCPWin;
assert( inSock >= 0 );
if ( inTCPWin > 0 ) {
#ifdef TCP_WINSHIFT
/* UNICOS requires setting the winshift explicitly */
if ( inTCPWin > 65535 ) {
int winShift = 0;
int scaledWin = inTCPWin >> 16;
while ( scaledWin > 0 ) {
scaledWin >>= 1;
winShift++;
}
/* set TCP window shift */
rc = setsockopt( inSock, IPPROTO_TCP, TCP_WINSHIFT,
(char*) &winShift, sizeof( winShift ));
if ( rc < 0 ) {
return rc;
}
/* Note: you cannot verify TCP window shift, since it returns
* a structure and not the same integer we use to set it. (ugh) */
}
#endif /* TCP_WINSHIFT */
#ifdef TCP_RFC1323
/* On AIX, RFC 1323 extensions can be set system-wide,
* using the 'no' network options command. But we can also set them
* per-socket, so let's try just in case. */
if ( inTCPWin > 65535 ) {
/* enable RFC 1323 */
int on = 1;
rc = setsockopt( inSock, IPPROTO_TCP, TCP_RFC1323,
(char*) &on, sizeof( on ));
if ( rc < 0 ) {
return rc;
}
}
#endif /* TCP_RFC1323 */
if ( !inSend ) {
/* receive buffer -- set
* note: results are verified after connect() or listen(),
* since some OS's don't show the corrected value until then. */
newTCPWin = inTCPWin;
rc = setsockopt( inSock, SOL_SOCKET, SO_RCVBUF,
(char*) &newTCPWin, sizeof( newTCPWin ));
} else {
/* send buffer -- set
* note: results are verified after connect() or listen(),
* since some OS's don't show the corrected value until then. */
newTCPWin = inTCPWin;
rc = setsockopt( inSock, SOL_SOCKET, SO_SNDBUF,
(char*) &newTCPWin, sizeof( newTCPWin ));
}
if ( rc < 0 ) {
return rc;
}
}
#endif /* SO_SNDBUF */
return 0;
} /* end setsock_tcp_windowsize */
/* -------------------------------------------------------------------
* returns the TCP window size (on the sending buffer, SO_SNDBUF),
* or -1 on error.
* ------------------------------------------------------------------- */
int getsock_tcp_windowsize( int inSock, int inSend ) {
int theTCPWin = 0;
#ifdef SO_SNDBUF
int rc;
Socklen_t len;
/* send buffer -- query for buffer size */
len = sizeof( theTCPWin );
if ( inSend ) {
rc = getsockopt( inSock, SOL_SOCKET, SO_SNDBUF,
(char*) &theTCPWin, &len );
} else {
rc = getsockopt( inSock, SOL_SOCKET, SO_RCVBUF,
(char*) &theTCPWin, &len );
}
if ( rc < 0 ) {
return rc;
}
#endif
return theTCPWin;
} /* end getsock_tcp_windowsize */
#ifdef __cplusplus
} /* end extern "C" */
#endif