remove old, obsolete cruft
Этот коммит содержится в:
родитель
90f2aa7216
Коммит
536a0804dc
@ -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
|
@ -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:
|
423
compat/Thread.c
423
compat/Thread.c
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
210
compat/error.c
210
compat/error.c
@ -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
|
@ -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 */
|
@ -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 */
|
@ -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
|
||||
|
@ -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
|
180
compat/signal.c
180
compat/signal.c
@ -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
|
@ -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 */
|
@ -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
|
@ -1 +0,0 @@
|
||||
EXTRA_DIST = index.html ui_license.html dast.gif
|
308
doc/Makefile.in
308
doc/Makefile.in
@ -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:
|
Двоичные данные
doc/dast.gif
Двоичные данные
doc/dast.gif
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 4.5 KiB |
758
doc/index.html
758
doc/index.html
@ -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"><dast@nlanr.net></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> |
|
||||
<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-<version#>' 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-<version>.tar.gz | tar -xvf -
|
||||
cd iperf-<version>
|
||||
./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>
|
||||
|
||||
<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
|
||||
<PRE>
|
||||
'b' = bits/sec 'B' = Bytes/sec
|
||||
'k' = Kbits/sec 'K' = KBytes/sec
|
||||
'm' = Mbits/sec 'M' = MBytes/sec
|
||||
'g' = Gbits/sec 'G' = GBytes/sec
|
||||
'a' = adaptive bits/sec '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'. <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.
|
||||
<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
|
||||
<P>Client side: <BR>$ iperf -c <Server IPv6 Address> -V
|
||||
<BR> </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). </TD></TR><TR>
|
||||
<TD><TT>-o </TT>(only for Windows, from v1.2 or higher)</TD>
|
||||
<TD>.</TD>
|
||||
<TD>Redirect output to given file. </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:
|
||||
<PRE>
|
||||
IPTOS_LOWDELAY minimize delay 0x10
|
||||
IPTOS_THROUGHPUT maximize throughput 0x08
|
||||
IPTOS_RELIABILITY maximize reliability 0x04
|
||||
IPTOS_LOWCOST minimize cost 0x02
|
||||
|
||||
</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. :- <BR>$
|
||||
iperf -c <server address> -F <file-name></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> </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> </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></B> iperf -s
|
||||
------------------------------------------------------------
|
||||
Server listening on TCP port 5001
|
||||
TCP window size: 60.0 KByte (default)
|
||||
------------------------------------------------------------
|
||||
[ 4] local <IP Addr node2> port 5001 connected with <IP Addr node1> port 2357
|
||||
[ ID] Interval Transfer Bandwidth
|
||||
[ 4] 0.0-10.1 sec 6.5 MBytes <B><FONT color=#ff0000>5.2 Mbits/sec
|
||||
|
||||
</FONT>node1></B> iperf -c node2
|
||||
------------------------------------------------------------
|
||||
Client connecting to node1, TCP port 5001
|
||||
TCP window size: 59.9 KByte (default)
|
||||
------------------------------------------------------------
|
||||
[ 3] local <IP Addr node1> port 2357 connected with <IP Addr node2> port 5001
|
||||
[ ID] Interval Transfer Bandwidth
|
||||
[ 3] 0.0-10.0 sec 6.5 MBytes 5.2 Mbits/sec</PRE>
|
||||
<HR>
|
||||
<PRE><B>node2></B> iperf -s -w 130k
|
||||
------------------------------------------------------------
|
||||
Server listening on TCP port 5001
|
||||
TCP window size: 130 KByte
|
||||
------------------------------------------------------------
|
||||
[ 4] local <IP Addr node 2> port 5001 connected with <IP Addr node 1> port 2530
|
||||
[ ID] Interval Transfer Bandwidth
|
||||
[ 4] 0.0-10.1 sec 19.7 MBytes <B><FONT color=#ff0000>15.7 Mbits/sec
|
||||
|
||||
</FONT>node1></B> iperf -c node2 -w 130k
|
||||
------------------------------------------------------------
|
||||
Client connecting to node2, TCP port 5001
|
||||
TCP window size: 129 KByte (WARNING: requested 130 KByte)
|
||||
------------------------------------------------------------
|
||||
[ 3] local <IP Addr node1> port 2530 connected with <IP Addr node2> port 5001
|
||||
[ ID] Interval Transfer Bandwidth
|
||||
[ 3] 0.0-10.0 sec 19.7 MBytes 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></B> iperf -s -w 300k
|
||||
------------------------------------------------------------
|
||||
Server listening on TCP port 5001
|
||||
TCP window size: 300 KByte
|
||||
------------------------------------------------------------
|
||||
[ 4] local <IP Addr node2> port 5001 connected with <IP Addr node1> port 6902
|
||||
[ ID] Interval Transfer Bandwidth
|
||||
[ 4] 0.0-10.2 sec 20.9 MBytes <B><FONT color=#ff0000>16.5 Mbits/sec
|
||||
|
||||
</FONT></B>[ 4] local <IP Addr node2> port 5001 connected with <IP Addr node1> port 6911
|
||||
[ 5] local <IP Addr node2> port 5001 connected with <IP Addr node2> port 6912
|
||||
[ ID] Interval Transfer Bandwidth
|
||||
[ 5] 0.0-10.1 sec 21.0 MBytes <B><FONT color=#ff0000>16.7 Mbits/sec
|
||||
</FONT></B>[ 4] 0.0-10.3 sec 12.0 MBytes <B><FONT color=#ff0000> 9.4 Mbits/sec
|
||||
|
||||
</FONT>node1></B> ./iperf -c node2 -w 300k
|
||||
------------------------------------------------------------
|
||||
Client connecting to node2, TCP port 5001
|
||||
TCP window size: 299 KByte (WARNING: requested 300 KByte)
|
||||
------------------------------------------------------------
|
||||
[ 3] local <IP Addr node2> port 6902 connected with <IP Addr node1> port 5001
|
||||
[ ID] Interval Transfer Bandwidth
|
||||
[ 3] 0.0-10.2 sec 20.9 MBytes 16.4 Mbits/sec
|
||||
|
||||
<B>node1></B> iperf -c node2 -w 300k -P 2
|
||||
------------------------------------------------------------
|
||||
Client connecting to node2, TCP port 5001
|
||||
TCP window size: 299 KByte (WARNING: requested 300 KByte)
|
||||
------------------------------------------------------------
|
||||
[ 4] local <IP Addr node2> port 6912 connected with <IP Addr node1> port 5001
|
||||
[ 3] local <IP Addr node2> port 6911 connected with <IP Addr node1> port 5001
|
||||
[ ID] Interval Transfer Bandwidth
|
||||
[ 4] 0.0-10.1 sec 21.0 MBytes 16.6 Mbits/sec
|
||||
[ 3] 0.0-10.2 sec 12.0 MBytes 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></B> iperf -s -m
|
||||
------------------------------------------------------------
|
||||
Server listening on TCP port 5001
|
||||
TCP window size: 60.0 KByte (default)
|
||||
------------------------------------------------------------
|
||||
[ 4] local <IP Addr node3> port 5001 connected with <IP Addr node4> port 1096
|
||||
[ ID] Interval Transfer Bandwidth
|
||||
[ 4] 0.0- 2.0 sec 1.8 MBytes 6.9 Mbits/sec
|
||||
[ 4] <B><FONT color=#ff0000>MSS size 1448 bytes (MTU 1500 bytes, ethernet)
|
||||
</FONT></B>[ 4] Read lengths occurring in more than 5% of reads:
|
||||
[ 4] 952 bytes read 219 times (16.2%)
|
||||
[ 4] 1448 bytes read 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></B> iperf -s -m
|
||||
------------------------------------------------------------
|
||||
Server listening on TCP port 5001
|
||||
TCP window size: 32.0 KByte (default)
|
||||
------------------------------------------------------------
|
||||
[ 4] local <IP Addr node4> port 5001 connected with <IP Addr node3> port 13914
|
||||
[ ID] Interval Transfer Bandwidth
|
||||
[ 4] 0.0- 2.3 sec 632 KBytes 2.1 Mbits/sec
|
||||
<B><FONT color=#ff0000>WARNING: Path MTU Discovery may not be enabled.
|
||||
</FONT></B>[ 4] <B><FONT color=#ff0000>MSS size 536 bytes (MTU 576 bytes, minimum)
|
||||
</FONT></B>[ 4] Read lengths occurring in more than 5% of reads:
|
||||
[ 4] 536 bytes read 308 times (58.4%)
|
||||
[ 4] 1072 bytes read 91 times (17.3%)
|
||||
[ 4] 1608 bytes read 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></B> iperf -s -u -i 1
|
||||
------------------------------------------------------------
|
||||
Server listening on UDP port 5001
|
||||
Receiving 1470 byte datagrams
|
||||
UDP buffer size: 60.0 KByte (default)
|
||||
------------------------------------------------------------
|
||||
[ 4] local <IP Addr node2> port 5001 connected with <IP Addr node1> port 9726
|
||||
[ ID] Interval Transfer Bandwidth Jitter Lost/Total Datagrams
|
||||
[ 4] 0.0- 1.0 sec 1.3 MBytes 10.0 Mbits/sec 0.209 ms 1/ 894 (0.11%)
|
||||
[ 4] 1.0- 2.0 sec 1.3 MBytes 10.0 Mbits/sec 0.221 ms 0/ 892 (0%)
|
||||
[ 4] 2.0- 3.0 sec 1.3 MBytes 10.0 Mbits/sec 0.277 ms 0/ 892 (0%)
|
||||
[ 4] 3.0- 4.0 sec 1.3 MBytes 10.0 Mbits/sec 0.359 ms 0/ 893 (0%)
|
||||
[ 4] 4.0- 5.0 sec 1.3 MBytes 10.0 Mbits/sec 0.251 ms 0/ 892 (0%)
|
||||
[ 4] 5.0- 6.0 sec 1.3 MBytes 10.0 Mbits/sec 0.215 ms 0/ 892 (0%)
|
||||
[ 4] 6.0- 7.0 sec 1.3 MBytes 10.0 Mbits/sec 0.325 ms 0/ 892 (0%)
|
||||
[ 4] 7.0- 8.0 sec 1.3 MBytes 10.0 Mbits/sec 0.254 ms 0/ 892 (0%)
|
||||
[ 4] 8.0- 9.0 sec 1.3 MBytes 10.0 Mbits/sec 0.282 ms 0/ 892 (0%)
|
||||
[ 4] 0.0-10.0 sec 12.5 MBytes 10.0 Mbits/sec 0.243 ms 1/ 8922 (0.011%)
|
||||
|
||||
<B>node1></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)
|
||||
------------------------------------------------------------
|
||||
[ 3] local <IP Addr node1> port 9726 connected with <IP Addr node2> port 5001
|
||||
[ ID] Interval Transfer Bandwidth
|
||||
[ 3] 0.0-10.0 sec 12.5 MBytes 10.0 Mbits/sec
|
||||
[ 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></B> iperf -s -u -l 32k -w 128k -i 1
|
||||
------------------------------------------------------------
|
||||
Server listening on UDP port 5001
|
||||
Receiving 32768 byte datagrams
|
||||
UDP buffer size: 128 KByte
|
||||
------------------------------------------------------------
|
||||
[ 3] local <IP Addr node2> port 5001 connected with <IP Addr node1> port 11303
|
||||
[ ID] Interval Transfer Bandwidth Jitter Lost/Total Datagrams
|
||||
[ 3] 0.0- 1.0 sec 1.3 MBytes 10.0 Mbits/sec 0.430 ms 0/ 41 (0%)
|
||||
[ 3] 1.0- 2.0 sec 1.1 MBytes 8.5 Mbits/sec 5.996 ms 6/ 40 (15%)
|
||||
[ 3] 2.0- 3.0 sec 1.2 MBytes 9.7 Mbits/sec 0.796 ms 1/ 40 (2.5%)
|
||||
[ 3] 3.0- 4.0 sec 1.2 MBytes 10.0 Mbits/sec 0.403 ms 0/ 40 (0%)
|
||||
[ 3] 4.0- 5.0 sec 1.2 MBytes 10.0 Mbits/sec 0.448 ms 0/ 40 (0%)
|
||||
[ 3] 5.0- 6.0 sec 1.2 MBytes 10.0 Mbits/sec 0.464 ms 0/ 40 (0%)
|
||||
[ 3] 6.0- 7.0 sec 1.2 MBytes 10.0 Mbits/sec 0.442 ms 0/ 40 (0%)
|
||||
[ 3] 7.0- 8.0 sec 1.2 MBytes 10.0 Mbits/sec 0.342 ms 0/ 40 (0%)
|
||||
[ 3] 8.0- 9.0 sec 1.2 MBytes 10.0 Mbits/sec 0.431 ms 0/ 40 (0%)
|
||||
[ 3] 9.0-10.0 sec 1.2 MBytes 10.0 Mbits/sec 0.407 ms 0/ 40 (0%)
|
||||
[ 3] 0.0-10.0 sec 12.3 MBytes 9.8 Mbits/sec 0.407 ms 7/ 401 (1.7%)
|
||||
|
||||
<B>node1></B> iperf -c node2 -b 10m -l 32k -w 128k
|
||||
------------------------------------------------------------
|
||||
Client connecting to node2, UDP port 5001
|
||||
Sending 32768 byte datagrams
|
||||
UDP buffer size: 128 KByte
|
||||
------------------------------------------------------------
|
||||
[ 3] local <IP Addr node2> port 11303 connected with <IP Addr node1> port 5001
|
||||
[ ID] Interval Transfer Bandwidth
|
||||
[ 3] 0.0-10.0 sec 12.5 MBytes 10.0 Mbits/sec
|
||||
[ 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></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)
|
||||
------------------------------------------------------------
|
||||
[ 3] local <IP Addr node5> port 1025 connected with 224.0.67.67 port 5001
|
||||
[ ID] Interval Transfer Bandwidth
|
||||
[ 3] 0.0- 5.0 sec 642 KBytes 1.0 Mbits/sec
|
||||
[ 3] Sent 447 datagrams
|
||||
|
||||
<B>node5></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 224.0.67.67
|
||||
Receiving 1470 byte datagrams
|
||||
UDP buffer size: 32.0 KByte (default)
|
||||
------------------------------------------------------------
|
||||
[ 3] local 224.0.67.67 port 5001 connected with <IP Addr node5> port 1025
|
||||
[ ID] Interval Transfer Bandwidth Jitter Lost/Total Datagrams
|
||||
[ 3] 0.0- 1.0 sec 131 KBytes 1.0 Mbits/sec 0.007 ms 0/ 91 (0%)
|
||||
[ 3] 1.0- 2.0 sec 128 KBytes 1.0 Mbits/sec 0.008 ms 0/ 89 (0%)
|
||||
[ 3] 2.0- 3.0 sec 128 KBytes 1.0 Mbits/sec 0.010 ms 0/ 89 (0%)
|
||||
[ 3] 3.0- 4.0 sec 128 KBytes 1.0 Mbits/sec 0.013 ms 0/ 89 (0%)
|
||||
[ 3] 4.0- 5.0 sec 128 KBytes 1.0 Mbits/sec 0.008 ms 0/ 89 (0%)
|
||||
[ 3] 0.0- 5.0 sec 642 KBytes 1.0 Mbits/sec 0.008 ms 0/ 447 (0%)
|
||||
|
||||
<B>node6></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 224.0.67.67
|
||||
Receiving 1470 byte datagrams
|
||||
UDP buffer size: 60.0 KByte (default)
|
||||
------------------------------------------------------------
|
||||
[ 3] local 224.0.67.67 port 5001 connected with <IP Addr node5> port 1025
|
||||
[ ID] Interval Transfer Bandwidth Jitter Lost/Total Datagrams
|
||||
[ 3] 0.0- 1.0 sec 129 KBytes 1.0 Mbits/sec 0.778 ms 61/ 151 (40%)
|
||||
[ 3] 1.0- 2.0 sec 128 KBytes 1.0 Mbits/sec 0.236 ms 0/ 89 (0%)
|
||||
[ 3] 2.0- 3.0 sec 128 KBytes 1.0 Mbits/sec 0.264 ms 0/ 89 (0%)
|
||||
[ 3] 3.0- 4.0 sec 128 KBytes 1.0 Mbits/sec 0.248 ms 0/ 89 (0%)
|
||||
[ 3] 0.0- 4.3 sec 554 KBytes 1.0 Mbits/sec 0.298 ms 61/ 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 <Server IPv6 Address> -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 <server address> -F <file-name><BR></FONT>
|
||||
<BR>Client: $ <FONT color=#000099> iperf -c <server address> -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 >
|
||||
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>
|
||||
|
@ -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>
|
@ -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
|
@ -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
|
@ -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
|
||||
|
@ -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
|
@ -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
|
196
include/Locale.h
196
include/Locale.h
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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
|
@ -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:
|
112
include/Mutex.h
112
include/Mutex.h
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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 */
|
159
include/Thread.h
159
include/Thread.h
@ -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
|
@ -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
|
@ -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 */
|
@ -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 */
|
@ -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 */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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 */
|
@ -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 */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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 */
|
@ -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
|
@ -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
|
@ -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
|
||||
|
@ -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 */
|
199
include/util.h
199
include/util.h
@ -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 */
|
||||
|
@ -1,2 +0,0 @@
|
||||
#define IPERF_VERSION "2.1-CURRENT"
|
||||
#define IPERF_VERSION_DATE "7 Apr 2008"
|
@ -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
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
134
src.old/List.cpp
134
src.old/List.cpp
@ -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;
|
||||
}
|
@ -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
|
||||
|
||||
}
|
||||
|
335
src.old/Locale.c
335
src.old/Locale.c
@ -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
|
@ -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)
|
@ -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:
|
@ -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
|
@ -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( × );
|
||||
strftime( timestamp, length,"%Y%m%d%H%M%S", timest );
|
||||
}
|
@ -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
|
@ -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
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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
|
@ -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 */
|
@ -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 */
|
295
src.old/main.cpp
295
src.old/main.cpp
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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
|
@ -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
|
@ -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
|
||||
|
Загрузка…
Ссылка в новой задаче
Block a user