summaryrefslogtreecommitdiff
path: root/src/libcharon/plugins/load_tester
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/plugins/load_tester')
-rw-r--r--src/libcharon/plugins/load_tester/Makefile.am15
-rw-r--r--src/libcharon/plugins/load_tester/Makefile.in260
-rw-r--r--src/libcharon/plugins/load_tester/load_tester.c104
-rw-r--r--src/libcharon/plugins/load_tester/load_tester_config.c512
-rw-r--r--src/libcharon/plugins/load_tester/load_tester_config.h7
-rw-r--r--src/libcharon/plugins/load_tester/load_tester_control.c317
-rw-r--r--src/libcharon/plugins/load_tester/load_tester_control.h47
-rw-r--r--src/libcharon/plugins/load_tester/load_tester_creds.c167
-rw-r--r--src/libcharon/plugins/load_tester/load_tester_ipsec.c15
-rw-r--r--src/libcharon/plugins/load_tester/load_tester_listener.c24
-rw-r--r--src/libcharon/plugins/load_tester/load_tester_listener.h6
-rw-r--r--src/libcharon/plugins/load_tester/load_tester_plugin.c129
12 files changed, 1425 insertions, 178 deletions
diff --git a/src/libcharon/plugins/load_tester/Makefile.am b/src/libcharon/plugins/load_tester/Makefile.am
index cdd0445a9..e7c08783f 100644
--- a/src/libcharon/plugins/load_tester/Makefile.am
+++ b/src/libcharon/plugins/load_tester/Makefile.am
@@ -1,8 +1,11 @@
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon \
+ -DIPSEC_PIDDIR=\"${piddir}\"
-INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
- -I$(top_srcdir)/src/libcharon
-
-AM_CFLAGS = -rdynamic
+AM_CFLAGS = \
+ -rdynamic
if MONOLITHIC
noinst_LTLIBRARIES = libstrongswan-load-tester.la
@@ -16,6 +19,10 @@ libstrongswan_load_tester_la_SOURCES = \
load_tester_creds.c load_tester_creds.h \
load_tester_ipsec.c load_tester_ipsec.h \
load_tester_listener.c load_tester_listener.h \
+ load_tester_control.c load_tester_control.h \
load_tester_diffie_hellman.c load_tester_diffie_hellman.h
libstrongswan_load_tester_la_LDFLAGS = -module -avoid-version
+
+ipsec_PROGRAMS = load-tester
+load_tester_SOURCES = load_tester.c
diff --git a/src/libcharon/plugins/load_tester/Makefile.in b/src/libcharon/plugins/load_tester/Makefile.in
index bbd20d4b9..2e1ebc800 100644
--- a/src/libcharon/plugins/load_tester/Makefile.in
+++ b/src/libcharon/plugins/load_tester/Makefile.in
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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.
@@ -15,7 +15,25 @@
@SET_MAKE@
+
VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -34,6 +52,7 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
+ipsec_PROGRAMS = load-tester$(EXEEXT)
subdir = src/libcharon/plugins/load_tester
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -45,10 +64,11 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
$(top_srcdir)/m4/macros/add-plugin.m4 \
- $(top_srcdir)/configure.in
+ $(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 =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
@@ -72,58 +92,98 @@ am__nobase_list = $(am__nobase_strip_setup); \
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
-am__installdirs = "$(DESTDIR)$(plugindir)"
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(ipsecdir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
libstrongswan_load_tester_la_LIBADD =
am_libstrongswan_load_tester_la_OBJECTS = load_tester_plugin.lo \
load_tester_config.lo load_tester_creds.lo \
load_tester_ipsec.lo load_tester_listener.lo \
- load_tester_diffie_hellman.lo
+ load_tester_control.lo load_tester_diffie_hellman.lo
libstrongswan_load_tester_la_OBJECTS = \
$(am_libstrongswan_load_tester_la_OBJECTS)
-libstrongswan_load_tester_la_LINK = $(LIBTOOL) --tag=CC \
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+libstrongswan_load_tester_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
$(AM_CFLAGS) $(CFLAGS) $(libstrongswan_load_tester_la_LDFLAGS) \
$(LDFLAGS) -o $@
@MONOLITHIC_FALSE@am_libstrongswan_load_tester_la_rpath = -rpath \
@MONOLITHIC_FALSE@ $(plugindir)
@MONOLITHIC_TRUE@am_libstrongswan_load_tester_la_rpath =
-DEFAULT_INCLUDES = -I.@am__isrc@
+PROGRAMS = $(ipsec_PROGRAMS)
+am_load_tester_OBJECTS = load_tester.$(OBJEXT)
+load_tester_OBJECTS = $(am_load_tester_OBJECTS)
+load_tester_LDADD = $(LDADD)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
CCLD = $(CC)
-LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
- $(LDFLAGS) -o $@
-SOURCES = $(libstrongswan_load_tester_la_SOURCES)
-DIST_SOURCES = $(libstrongswan_load_tester_la_SOURCES)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+SOURCES = $(libstrongswan_load_tester_la_SOURCES) \
+ $(load_tester_SOURCES)
+DIST_SOURCES = $(libstrongswan_load_tester_la_SOURCES) \
+ $(load_tester_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
+BFDLIB = @BFDLIB@
BTLIB = @BTLIB@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
+CHECK_CFLAGS = @CHECK_CFLAGS@
+CHECK_LIBS = @CHECK_LIBS@
+COVERAGE_CFLAGS = @COVERAGE_CFLAGS@
+COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLIB = @DLLIB@
+DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -132,13 +192,16 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+GENHTML = @GENHTML@
GPERF = @GPERF@
+GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LCOV = @LCOV@
LD = @LD@
LDFLAGS = @LDFLAGS@
LEX = @LEX@
@@ -151,6 +214,7 @@ LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
MYSQLCFLAG = @MYSQLCFLAG@
MYSQLCONFIG = @MYSQLCONFIG@
@@ -178,11 +242,13 @@ RANLIB = @RANLIB@
RTLIB = @RTLIB@
RUBY = @RUBY@
RUBYINCLUDE = @RUBYINCLUDE@
+RUBYLIB = @RUBYLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SOCKLIB = @SOCKLIB@
STRIP = @STRIP@
+UNWINDLIB = @UNWINDLIB@
VERSION = @VERSION@
YACC = @YACC@
YFLAGS = @YFLAGS@
@@ -190,6 +256,7 @@ abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
@@ -198,8 +265,6 @@ am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
attest_plugins = @attest_plugins@
-axis2c_CFLAGS = @axis2c_CFLAGS@
-axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -208,14 +273,19 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+charon_natt_port = @charon_natt_port@
+charon_plugins = @charon_plugins@
+charon_udp_port = @charon_udp_port@
clearsilver_LIBS = @clearsilver_LIBS@
+cmd_plugins = @cmd_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
-default_pkcs11 = @default_pkcs11@
+dev_headers = @dev_headers@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
+fips_mode = @fips_mode@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
h_plugins = @h_plugins@
@@ -229,17 +299,17 @@ imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
+ipsec_script = @ipsec_script@
+ipsec_script_upper = @ipsec_script_upper@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
-libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
maemo_CFLAGS = @maemo_CFLAGS@
maemo_LIBS = @maemo_LIBS@
manager_plugins = @manager_plugins@
@@ -249,16 +319,15 @@ mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
+nm_plugins = @nm_plugins@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
-p_plugins = @p_plugins@
pcsclite_CFLAGS = @pcsclite_CFLAGS@
pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
plugindir = @plugindir@
-pluto_plugins = @pluto_plugins@
pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
@@ -286,10 +355,15 @@ top_srcdir = @top_srcdir@
urandom_device = @urandom_device@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
-INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
- -I$(top_srcdir)/src/libcharon
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon \
+ -DIPSEC_PIDDIR=\"${piddir}\"
+
+AM_CFLAGS = \
+ -rdynamic
-AM_CFLAGS = -rdynamic
@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-load-tester.la
@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-load-tester.la
libstrongswan_load_tester_la_SOURCES = \
@@ -298,9 +372,11 @@ libstrongswan_load_tester_la_SOURCES = \
load_tester_creds.c load_tester_creds.h \
load_tester_ipsec.c load_tester_ipsec.h \
load_tester_listener.c load_tester_listener.h \
+ load_tester_control.c load_tester_control.h \
load_tester_diffie_hellman.c load_tester_diffie_hellman.h
libstrongswan_load_tester_la_LDFLAGS = -module -avoid-version
+load_tester_SOURCES = load_tester.c
all: all-am
.SUFFIXES:
@@ -346,7 +422,6 @@ clean-noinstLTLIBRARIES:
done
install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
@$(NORMAL_INSTALL)
- test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)"
@list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
list2=; for p in $$list; do \
if test -f $$p; then \
@@ -354,6 +429,8 @@ install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
else :; fi; \
done; \
test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \
}
@@ -375,8 +452,57 @@ clean-pluginLTLIBRARIES:
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
-libstrongswan-load-tester.la: $(libstrongswan_load_tester_la_OBJECTS) $(libstrongswan_load_tester_la_DEPENDENCIES)
- $(libstrongswan_load_tester_la_LINK) $(am_libstrongswan_load_tester_la_rpath) $(libstrongswan_load_tester_la_OBJECTS) $(libstrongswan_load_tester_la_LIBADD) $(LIBS)
+libstrongswan-load-tester.la: $(libstrongswan_load_tester_la_OBJECTS) $(libstrongswan_load_tester_la_DEPENDENCIES) $(EXTRA_libstrongswan_load_tester_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libstrongswan_load_tester_la_LINK) $(am_libstrongswan_load_tester_la_rpath) $(libstrongswan_load_tester_la_OBJECTS) $(libstrongswan_load_tester_la_LIBADD) $(LIBS)
+install-ipsecPROGRAMS: $(ipsec_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(ipsec_PROGRAMS)'; test -n "$(ipsecdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(ipsecdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(ipsecdir)" || exit 1; \
+ fi; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p || test -f $$p1; \
+ then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(ipsecdir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(ipsecdir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-ipsecPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(ipsec_PROGRAMS)'; test -n "$(ipsecdir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(ipsecdir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(ipsecdir)" && rm -f $$files
+
+clean-ipsecPROGRAMS:
+ @list='$(ipsec_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+load-tester$(EXEEXT): $(load_tester_OBJECTS) $(load_tester_DEPENDENCIES) $(EXTRA_load_tester_DEPENDENCIES)
+ @rm -f load-tester$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(load_tester_OBJECTS) $(load_tester_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -384,7 +510,9 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/load_tester.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/load_tester_config.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/load_tester_control.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/load_tester_creds.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/load_tester_diffie_hellman.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/load_tester_ipsec.Plo@am__quote@
@@ -392,25 +520,25 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/load_tester_plugin.Plo@am__quote@
.c.o:
-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
.c.obj:
-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
-@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
@@ -502,9 +630,9 @@ distdir: $(DISTFILES)
done
check-am: all-am
check: check-am
-all-am: Makefile $(LTLIBRARIES)
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS)
installdirs:
- for dir in "$(DESTDIR)$(plugindir)"; do \
+ for dir in "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(ipsecdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
@@ -517,10 +645,15 @@ install-am: all-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
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
mostlyclean-generic:
clean-generic:
@@ -534,8 +667,8 @@ maintainer-clean-generic:
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
-clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
- clean-pluginLTLIBRARIES mostlyclean-am
+clean-am: clean-generic clean-ipsecPROGRAMS clean-libtool \
+ clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
@@ -555,7 +688,7 @@ info: info-am
info-am:
-install-data-am: install-pluginLTLIBRARIES
+install-data-am: install-ipsecPROGRAMS install-pluginLTLIBRARIES
install-dvi: install-dvi-am
@@ -601,23 +734,24 @@ ps: ps-am
ps-am:
-uninstall-am: uninstall-pluginLTLIBRARIES
+uninstall-am: uninstall-ipsecPROGRAMS uninstall-pluginLTLIBRARIES
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
- clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \
- ctags distclean distclean-compile distclean-generic \
- distclean-libtool distclean-tags distdir dvi dvi-am html \
- html-am info info-am install install-am install-data \
- install-data-am install-dvi install-dvi-am install-exec \
- install-exec-am install-html install-html-am install-info \
- install-info-am install-man install-pdf install-pdf-am \
- install-pluginLTLIBRARIES install-ps install-ps-am \
- install-strip installcheck installcheck-am installdirs \
- maintainer-clean maintainer-clean-generic mostlyclean \
- mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
- pdf pdf-am ps ps-am tags uninstall uninstall-am \
+ clean-ipsecPROGRAMS clean-libtool clean-noinstLTLIBRARIES \
+ clean-pluginLTLIBRARIES ctags distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-ipsecPROGRAMS install-man \
+ install-pdf install-pdf-am install-pluginLTLIBRARIES \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-ipsecPROGRAMS \
uninstall-pluginLTLIBRARIES
diff --git a/src/libcharon/plugins/load_tester/load_tester.c b/src/libcharon/plugins/load_tester/load_tester.c
new file mode 100644
index 000000000..b7b971ee8
--- /dev/null
+++ b/src/libcharon/plugins/load_tester/load_tester.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2012 Martin Willi
+ * Copyright (C) 2012 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program 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 General Public License
+ * for more details.
+ */
+
+#include "load_tester_control.h"
+
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+/**
+ * Connect to the daemon, return stream
+ */
+static FILE* make_connection()
+{
+ struct sockaddr_un addr;
+ FILE *stream;
+ int fd;
+
+ addr.sun_family = AF_UNIX;
+ strcpy(addr.sun_path, LOAD_TESTER_SOCKET);
+
+ fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (fd < 0)
+ {
+ fprintf(stderr, "opening socket failed: %s\n", strerror(errno));
+ return NULL;
+ }
+ if (connect(fd, (struct sockaddr *)&addr,
+ offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path)) < 0)
+ {
+ fprintf(stderr, "connecting to %s failed: %s\n",
+ LOAD_TESTER_SOCKET, strerror(errno));
+ close(fd);
+ return NULL;
+ }
+ stream = fdopen(fd, "r+");
+ if (!stream)
+ {
+ close(fd);
+ return NULL;
+ }
+ return stream;
+}
+
+/**
+ * Initiate load-tests
+ */
+static int initiate(unsigned int count, unsigned int delay)
+{
+ FILE *stream;
+ char c;
+
+ stream = make_connection();
+ if (!stream)
+ {
+ return 1;
+ }
+
+ fprintf(stream, "%u %u\n", count, delay);
+
+ while (1)
+ {
+ fflush(stream);
+ c = fgetc(stream);
+ if (c == EOF)
+ {
+ break;
+ }
+ if (fputc(c, stdout) == EOF)
+ {
+ break;
+ }
+ fflush(stdout);
+ }
+ fclose(stream);
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ if (argc >= 3 && strcmp(argv[1], "initiate") == 0)
+ {
+ return initiate(atoi(argv[2]), argc > 3 ? atoi(argv[3]) : 0);
+ }
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, " %s initiate <count> [<delay in ms>]\n", argv[0]);
+ return 1;
+}
diff --git a/src/libcharon/plugins/load_tester/load_tester_config.c b/src/libcharon/plugins/load_tester/load_tester_config.c
index 6bc6f91e4..ebadf44ca 100644
--- a/src/libcharon/plugins/load_tester/load_tester_config.c
+++ b/src/libcharon/plugins/load_tester/load_tester_config.c
@@ -16,6 +16,10 @@
#include "load_tester_config.h"
#include <daemon.h>
+#include <hydra.h>
+#include <attributes/mem_pool.h>
+#include <collections/hashtable.h>
+#include <threading/mutex.h>
typedef struct private_load_tester_config_t private_load_tester_config_t;
@@ -40,9 +44,14 @@ struct private_load_tester_config_t {
host_t *vip;
/**
- * Remote address
+ * Initiator address
*/
- char *remote;
+ char *initiator;
+
+ /**
+ * Responder address
+ */
+ char *responder;
/**
* IP address pool
@@ -55,6 +64,11 @@ struct private_load_tester_config_t {
proposal_t *proposal;
/**
+ * ESP proposal
+ */
+ proposal_t *esp;
+
+ /**
* Authentication method(s) to use/expect from initiator
*/
char *initiator_auth;
@@ -70,11 +84,36 @@ struct private_load_tester_config_t {
char *initiator_id;
/**
+ * Initiator ID to to match against as responder
+ */
+ char *initiator_match;
+
+ /**
* Responder ID to enforce
*/
char *responder_id;
/**
+ * Traffic Selector on initiator side, as proposed from initiator
+ */
+ char *initiator_tsi;
+
+ /**
+ * Traffic Selector on responder side, as proposed from initiator
+ */
+ char *initiator_tsr;
+
+ /**
+ * Traffic Selector on initiator side, as narrowed by responder
+ */
+ char *responder_tsi;
+
+ /**
+ * Traffic Selector on responder side, as narrowed by responder
+ */
+ char *responder_tsr;
+
+ /**
* IKE_SA rekeying delay
*/
u_int ike_rekey;
@@ -90,6 +129,11 @@ struct private_load_tester_config_t {
u_int dpd_delay;
/**
+ * DPD timeout (IKEv1 only)
+ */
+ u_int dpd_timeout;
+
+ /**
* incremental numbering of generated configs
*/
u_int num;
@@ -98,9 +142,155 @@ struct private_load_tester_config_t {
* Dynamic source port, if used
*/
u_int16_t port;
+
+ /**
+ * IKE version to use for load testing
+ */
+ ike_version_t version;
+
+ /**
+ * List of pools to allocate external addresses dynamically, as mem_pool_t
+ */
+ linked_list_t *pools;
+
+ /**
+ * Address prefix to use when installing dynamic addresses
+ */
+ int prefix;
+
+ /**
+ * Keep addresses until shutdown?
+ */
+ bool keep;
+
+ /**
+ * Hashtable with leases in "pools", host_t => entry_t
+ */
+ hashtable_t *leases;
+
+ /**
+ * Mutex for leases hashtable
+ */
+ mutex_t *mutex;
};
/**
+ * Lease entry
+ */
+typedef struct {
+ /** host reference, equal to key */
+ host_t *host;
+ /** associated identity */
+ identification_t *id;
+} entry_t;
+
+/**
+ * Destroy an entry_t
+ */
+static void entry_destroy(entry_t *this)
+{
+ this->host->destroy(this->host);
+ this->id->destroy(this->id);
+ free(this);
+}
+
+/**
+ * Hashtable hash function
+ */
+static u_int hash(host_t *key)
+{
+ return chunk_hash(key->get_address(key));
+}
+
+/**
+ * Hashtable equals function
+ */
+static bool equals(host_t *a, host_t *b)
+{
+ return a->ip_equals(a, b);
+}
+
+/**
+ * Load external addresses to use, if any
+ */
+static void load_addrs(private_load_tester_config_t *this)
+{
+ enumerator_t *enumerator, *tokens;
+ host_t *from, *to;
+ int bits;
+ char *iface, *token, *pos;
+ mem_pool_t *pool;
+
+ this->keep = lib->settings->get_bool(lib->settings,
+ "%s.plugins.load-tester.addrs_keep", FALSE, charon->name);
+ this->prefix = lib->settings->get_int(lib->settings,
+ "%s.plugins.load-tester.addrs_prefix", 16, charon->name);
+ enumerator = lib->settings->create_key_value_enumerator(lib->settings,
+ "%s.plugins.load-tester.addrs", charon->name);
+ while (enumerator->enumerate(enumerator, &iface, &token))
+ {
+ tokens = enumerator_create_token(token, ",", " ");
+ while (tokens->enumerate(tokens, &token))
+ {
+ pos = strchr(token, '-');
+ if (pos)
+ { /* range */
+ *(pos++) = '\0';
+ /* trim whitespace */
+ while (*pos == ' ')
+ {
+ pos++;
+ }
+ while (token[strlen(token) - 1] == ' ')
+ {
+ token[strlen(token) - 1] = '\0';
+ }
+ from = host_create_from_string(token, 0);
+ to = host_create_from_string(pos, 0);
+ if (from && to)
+ {
+ pool = mem_pool_create_range(iface, from, to);
+ if (pool)
+ {
+ DBG1(DBG_CFG, "loaded load-tester address range "
+ "%H-%H on %s", from, to, iface);
+ this->pools->insert_last(this->pools, pool);
+ }
+ from->destroy(from);
+ to->destroy(to);
+ }
+ else
+ {
+ DBG1(DBG_CFG, "parsing load-tester address range %s-%s "
+ "failed, skipped", token, pos);
+ DESTROY_IF(from);
+ DESTROY_IF(to);
+ }
+ }
+ else
+ { /* subnet */
+ from = host_create_from_subnet(token, &bits);
+ if (from)
+ {
+ DBG1(DBG_CFG, "loaded load-tester address pool %H/%d on %s",
+ from, bits, iface);
+ pool = mem_pool_create(iface, from, bits);
+ from->destroy(from);
+ this->pools->insert_last(this->pools, pool);
+ }
+ else
+ {
+ DBG1(DBG_CFG, "parsing load-tester address %s failed, "
+ "skipped", token);
+ }
+ }
+ }
+ tokens->destroy(tokens);
+ }
+ enumerator->destroy(enumerator);
+}
+
+/**
* Generate auth config from string
*/
static void generate_auth_cfg(private_load_tester_config_t *this, char *str,
@@ -123,8 +313,14 @@ static void generate_auth_cfg(private_load_tester_config_t *this, char *str,
if (this->initiator_id)
{
- if ((local && num) || (!local && !num))
- {
+ if (this->initiator_match && (!local && !num))
+ { /* as responder, use the secified identity that matches
+ * all used initiator identities, if given. */
+ snprintf(buf, sizeof(buf), this->initiator_match, rnd);
+ id = identification_create_from_string(buf);
+ }
+ else if ((local && num) || (!local && !num))
+ { /* as initiator, create peer specific identities */
snprintf(buf, sizeof(buf), this->initiator_id, num, rnd);
id = identification_create_from_string(buf);
}
@@ -159,7 +355,7 @@ static void generate_auth_cfg(private_load_tester_config_t *this, char *str,
}
}
}
- else if (strneq(str, "eap", strlen("eap")))
+ else if (strpfx(str, "eap"))
{ /* EAP authentication, use a NAI */
class = AUTH_CLASS_EAP;
if (*(str + strlen("eap")) == '-')
@@ -221,6 +417,88 @@ static void generate_auth_cfg(private_load_tester_config_t *this, char *str,
}
/**
+ * Add a TS from a string to a child_cfg
+ */
+static void add_ts(char *string, child_cfg_t *cfg, bool local)
+{
+ traffic_selector_t *ts;
+
+ if (string)
+ {
+ ts = traffic_selector_create_from_cidr(string, 0, 0, 65535);
+ if (!ts)
+ {
+ DBG1(DBG_CFG, "parsing TS string '%s' failed", string);
+ }
+ }
+ else
+ {
+ ts = traffic_selector_create_dynamic(0, 0, 65535);
+ }
+ if (ts)
+ {
+ cfg->add_traffic_selector(cfg, local, ts);
+ }
+}
+
+/**
+ * Allocate and install a dynamic external address to use
+ */
+static host_t *allocate_addr(private_load_tester_config_t *this, uint num)
+{
+ enumerator_t *enumerator;
+ mem_pool_t *pool;
+ host_t *found = NULL, *requested;
+ identification_t *id;
+ char *iface = NULL, buf[32];
+ entry_t *entry;
+
+ requested = host_create_any(AF_INET);
+ snprintf(buf, sizeof(buf), "ext-%d", num);
+ id = identification_create_from_string(buf);
+ enumerator = this->pools->create_enumerator(this->pools);
+ while (enumerator->enumerate(enumerator, &pool))
+ {
+ found = pool->acquire_address(pool, id, requested, MEM_POOL_NEW);
+ if (found)
+ {
+ iface = (char*)pool->get_name(pool);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ requested->destroy(requested);
+
+ if (!found)
+ {
+ DBG1(DBG_CFG, "no address found to install as load-tester external IP");
+ id->destroy(id);
+ return NULL;
+ }
+ if (hydra->kernel_interface->add_ip(hydra->kernel_interface,
+ found, this->prefix, iface) != SUCCESS)
+ {
+ DBG1(DBG_CFG, "installing load-tester IP %H on %s failed", found, iface);
+ found->destroy(found);
+ id->destroy(id);
+ return NULL;
+ }
+ DBG1(DBG_CFG, "installed load-tester IP %H on %s", found, iface);
+ INIT(entry,
+ .host = found->clone(found),
+ .id = id,
+ );
+ this->mutex->lock(this->mutex);
+ entry = this->leases->put(this->leases, entry->host, entry);
+ this->mutex->unlock(this->mutex);
+ if (entry)
+ { /* shouldn't actually happen */
+ entry_destroy(entry);
+ }
+ return found;
+}
+
+/**
* Generate a new initiator config, num = 0 for responder config
*/
static peer_cfg_t* generate_config(private_load_tester_config_t *this, uint num)
@@ -228,8 +506,8 @@ static peer_cfg_t* generate_config(private_load_tester_config_t *this, uint num)
ike_cfg_t *ike_cfg;
child_cfg_t *child_cfg;
peer_cfg_t *peer_cfg;
- traffic_selector_t *ts;
- proposal_t *proposal;
+ char local[32], *remote;
+ host_t *addr;
lifetime_cfg_t lifetime = {
.time = {
.life = this->child_rekey * 2,
@@ -238,24 +516,63 @@ static peer_cfg_t* generate_config(private_load_tester_config_t *this, uint num)
}
};
+ if (num)
+ { /* initiator */
+ if (this->pools->get_count(this->pools))
+ { /* using dynamically installed external addresses */
+ addr = allocate_addr(this, num);
+ if (!addr)
+ {
+ DBG1(DBG_CFG, "allocating external address failed");
+ return NULL;
+ }
+ snprintf(local, sizeof(local), "%H", addr);
+ addr->destroy(addr);
+ }
+ else
+ {
+ snprintf(local, sizeof(local), "%s", this->initiator);
+ }
+ remote = this->responder;
+ }
+ else
+ {
+ snprintf(local, sizeof(local), "%s", this->responder);
+ remote = this->initiator;
+ }
+
if (this->port && num)
{
- ike_cfg = ike_cfg_create(FALSE, FALSE,
- "0.0.0.0", this->port + num - 1, this->remote, IKEV2_NATT_PORT);
+ ike_cfg = ike_cfg_create(this->version, TRUE, FALSE,
+ local, FALSE, this->port + num - 1,
+ remote, FALSE, IKEV2_NATT_PORT,
+ FRAGMENTATION_NO, 0);
}
else
{
- ike_cfg = ike_cfg_create(FALSE, FALSE,
- "0.0.0.0", IKEV2_UDP_PORT, this->remote, IKEV2_UDP_PORT);
+ ike_cfg = ike_cfg_create(this->version, TRUE, FALSE,
+ local, FALSE,
+ charon->socket->get_port(charon->socket, FALSE),
+ remote, FALSE, IKEV2_UDP_PORT,
+ FRAGMENTATION_NO, 0);
}
ike_cfg->add_proposal(ike_cfg, this->proposal->clone(this->proposal));
- peer_cfg = peer_cfg_create("load-test", 2, ike_cfg,
+ peer_cfg = peer_cfg_create("load-test", ike_cfg,
CERT_SEND_IF_ASKED, UNIQUE_NO, 1, /* keytries */
this->ike_rekey, 0, /* rekey, reauth */
0, this->ike_rekey, /* jitter, overtime */
- FALSE, this->dpd_delay, /* mobike, dpddelay */
- this->vip ? this->vip->clone(this->vip) : NULL,
- this->pool, FALSE, NULL, NULL);
+ FALSE, FALSE, /* mobike, aggressive mode */
+ this->dpd_delay, /* dpd_delay */
+ this->dpd_timeout, /* dpd_timeout */
+ FALSE, NULL, NULL);
+ if (this->vip)
+ {
+ peer_cfg->add_virtual_ip(peer_cfg, this->vip->clone(this->vip));
+ }
+ if (this->pool)
+ {
+ peer_cfg->add_pool(peer_cfg, this->pool);
+ }
if (num)
{ /* initiator */
generate_auth_cfg(this, this->initiator_auth, peer_cfg, TRUE, num);
@@ -270,12 +587,25 @@ static peer_cfg_t* generate_config(private_load_tester_config_t *this, uint num)
child_cfg = child_cfg_create("load-test", &lifetime, NULL, TRUE, MODE_TUNNEL,
ACTION_NONE, ACTION_NONE, ACTION_NONE, FALSE,
0, 0, NULL, NULL, 0);
- proposal = proposal_create_from_string(PROTO_ESP, "aes128-sha1");
- child_cfg->add_proposal(child_cfg, proposal);
- ts = traffic_selector_create_dynamic(0, 0, 65535);
- child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
- ts = traffic_selector_create_dynamic(0, 0, 65535);
- child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
+ child_cfg->add_proposal(child_cfg, this->esp->clone(this->esp));
+
+ if (num)
+ { /* initiator */
+ if (this->vip)
+ {
+ add_ts(NULL, child_cfg, TRUE);
+ }
+ else
+ {
+ add_ts(this->initiator_tsi, child_cfg, TRUE);
+ }
+ add_ts(this->initiator_tsr, child_cfg, FALSE);
+ }
+ else
+ { /* responder */
+ add_ts(this->responder_tsr, child_cfg, TRUE);
+ add_ts(this->responder_tsi, child_cfg, FALSE);
+ }
peer_cfg->add_child_cfg(peer_cfg, child_cfg);
return peer_cfg;
}
@@ -306,11 +636,86 @@ METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
return NULL;
}
+METHOD(load_tester_config_t, delete_ip, void,
+ private_load_tester_config_t *this, host_t *ip)
+{
+ enumerator_t *enumerator;
+ mem_pool_t *pool;
+ entry_t *entry;
+
+ if (this->keep)
+ {
+ return;
+ }
+
+ this->mutex->lock(this->mutex);
+ entry = this->leases->remove(this->leases, ip);
+ this->mutex->unlock(this->mutex);
+
+ if (entry)
+ {
+ enumerator = this->pools->create_enumerator(this->pools);
+ while (enumerator->enumerate(enumerator, &pool))
+ {
+ if (pool->release_address(pool, entry->host, entry->id))
+ {
+ hydra->kernel_interface->del_ip(hydra->kernel_interface,
+ entry->host, this->prefix, FALSE);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ entry_destroy(entry);
+ }
+}
+
+/**
+ * Clean up leases for allocated external addresses, if have been kept
+ */
+static void cleanup_leases(private_load_tester_config_t *this)
+{
+ enumerator_t *pools, *leases;
+ mem_pool_t *pool;
+ identification_t *id;
+ host_t *addr;
+ entry_t *entry;
+ bool online;
+
+ pools = this->pools->create_enumerator(this->pools);
+ while (pools->enumerate(pools, &pool))
+ {
+ leases = pool->create_lease_enumerator(pool);
+ while (leases->enumerate(leases, &id, &addr, &online))
+ {
+ if (online)
+ {
+ hydra->kernel_interface->del_ip(hydra->kernel_interface,
+ addr, this->prefix, FALSE);
+ entry = this->leases->remove(this->leases, addr);
+ if (entry)
+ {
+ entry_destroy(entry);
+ }
+ }
+ }
+ leases->destroy(leases);
+ }
+ pools->destroy(pools);
+}
+
METHOD(load_tester_config_t, destroy, void,
private_load_tester_config_t *this)
{
+ if (this->keep)
+ {
+ cleanup_leases(this);
+ }
+ this->mutex->destroy(this->mutex);
+ this->leases->destroy(this->leases);
+ this->pools->destroy_offset(this->pools, offsetof(mem_pool_t, destroy));
this->peer_cfg->destroy(this->peer_cfg);
DESTROY_IF(this->proposal);
+ DESTROY_IF(this->esp);
DESTROY_IF(this->vip);
free(this);
}
@@ -329,50 +734,85 @@ load_tester_config_t *load_tester_config_create()
.create_ike_cfg_enumerator = _create_ike_cfg_enumerator,
.get_peer_cfg_by_name = _get_peer_cfg_by_name,
},
+ .delete_ip = _delete_ip,
.destroy = _destroy,
},
+ .pools = linked_list_create(),
+ .leases = hashtable_create((hashtable_hash_t)hash,
+ (hashtable_equals_t)equals, 256),
+ .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
.num = 1,
);
if (lib->settings->get_bool(lib->settings,
- "charon.plugins.load-tester.request_virtual_ip", FALSE))
+ "%s.plugins.load-tester.request_virtual_ip", FALSE, charon->name))
{
this->vip = host_create_from_string("0.0.0.0", 0);
}
this->pool = lib->settings->get_str(lib->settings,
- "charon.plugins.load-tester.pool", NULL);
- this->remote = lib->settings->get_str(lib->settings,
- "charon.plugins.load-tester.remote", "127.0.0.1");
+ "%s.plugins.load-tester.pool", NULL, charon->name);
+ this->initiator = lib->settings->get_str(lib->settings,
+ "%s.plugins.load-tester.initiator", "0.0.0.0", charon->name);
+ this->responder = lib->settings->get_str(lib->settings,
+ "%s.plugins.load-tester.responder", "127.0.0.1", charon->name);
this->proposal = proposal_create_from_string(PROTO_IKE,
- lib->settings->get_str(lib->settings,
- "charon.plugins.load-tester.proposal", "aes128-sha1-modp768"));
+ lib->settings->get_str(lib->settings,
+ "%s.plugins.load-tester.proposal", "aes128-sha1-modp768",
+ charon->name));
if (!this->proposal)
{ /* fallback */
this->proposal = proposal_create_from_string(PROTO_IKE,
"aes128-sha1-modp768");
}
+ this->esp = proposal_create_from_string(PROTO_ESP,
+ lib->settings->get_str(lib->settings,
+ "%s.plugins.load-tester.esp", "aes128-sha1",
+ charon->name));
+ if (!this->esp)
+ { /* fallback */
+ this->esp = proposal_create_from_string(PROTO_ESP, "aes128-sha1");
+ }
+
this->ike_rekey = lib->settings->get_int(lib->settings,
- "charon.plugins.load-tester.ike_rekey", 0);
+ "%s.plugins.load-tester.ike_rekey", 0, charon->name);
this->child_rekey = lib->settings->get_int(lib->settings,
- "charon.plugins.load-tester.child_rekey", 600);
+ "%s.plugins.load-tester.child_rekey", 600, charon->name);
this->dpd_delay = lib->settings->get_int(lib->settings,
- "charon.plugins.load-tester.dpd_delay", 0);
+ "%s.plugins.load-tester.dpd_delay", 0, charon->name);
+ this->dpd_timeout = lib->settings->get_int(lib->settings,
+ "%s.plugins.load-tester.dpd_timeout", 0, charon->name);
this->initiator_auth = lib->settings->get_str(lib->settings,
- "charon.plugins.load-tester.initiator_auth", "pubkey");
+ "%s.plugins.load-tester.initiator_auth", "pubkey", charon->name);
this->responder_auth = lib->settings->get_str(lib->settings,
- "charon.plugins.load-tester.responder_auth", "pubkey");
+ "%s.plugins.load-tester.responder_auth", "pubkey", charon->name);
this->initiator_id = lib->settings->get_str(lib->settings,
- "charon.plugins.load-tester.initiator_id", NULL);
+ "%s.plugins.load-tester.initiator_id", NULL, charon->name);
+ this->initiator_match = lib->settings->get_str(lib->settings,
+ "%s.plugins.load-tester.initiator_match", NULL, charon->name);
this->responder_id = lib->settings->get_str(lib->settings,
- "charon.plugins.load-tester.responder_id", NULL);
+ "%s.plugins.load-tester.responder_id", NULL, charon->name);
+
+ this->initiator_tsi = lib->settings->get_str(lib->settings,
+ "%s.plugins.load-tester.initiator_tsi", NULL, charon->name);
+ this->responder_tsi =lib->settings->get_str(lib->settings,
+ "%s.plugins.load-tester.responder_tsi",
+ this->initiator_tsi, charon->name);
+ this->initiator_tsr = lib->settings->get_str(lib->settings,
+ "%s.plugins.load-tester.initiator_tsr", NULL, charon->name);
+ this->responder_tsr =lib->settings->get_str(lib->settings,
+ "%s.plugins.load-tester.responder_tsr",
+ this->initiator_tsr, charon->name);
this->port = lib->settings->get_int(lib->settings,
- "charon.plugins.load-tester.dynamic_port", 0);
+ "%s.plugins.load-tester.dynamic_port", 0, charon->name);
+ this->version = lib->settings->get_int(lib->settings,
+ "%s.plugins.load-tester.version", IKE_ANY, charon->name);
+
+ load_addrs(this);
this->peer_cfg = generate_config(this, 0);
return &this->public;
}
-
diff --git a/src/libcharon/plugins/load_tester/load_tester_config.h b/src/libcharon/plugins/load_tester/load_tester_config.h
index c22387743..cfa4b1edc 100644
--- a/src/libcharon/plugins/load_tester/load_tester_config.h
+++ b/src/libcharon/plugins/load_tester/load_tester_config.h
@@ -36,6 +36,13 @@ struct load_tester_config_t {
backend_t backend;
/**
+ * Delete external IP if it was dynamically installed.
+ *
+ * @param ip external IP
+ */
+ void (*delete_ip)(load_tester_config_t *this, host_t *ip);
+
+ /**
* Destroy the backend.
*/
void (*destroy)(load_tester_config_t *this);
diff --git a/src/libcharon/plugins/load_tester/load_tester_control.c b/src/libcharon/plugins/load_tester/load_tester_control.c
new file mode 100644
index 000000000..f9ec9142f
--- /dev/null
+++ b/src/libcharon/plugins/load_tester/load_tester_control.c
@@ -0,0 +1,317 @@
+/*
+ * Copyright (C) 2012 Martin Willi
+ * Copyright (C) 2012 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program 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 General Public License
+ * for more details.
+ */
+
+#include "load_tester_control.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <daemon.h>
+#include <collections/hashtable.h>
+#include <threading/thread.h>
+#include <threading/mutex.h>
+#include <threading/condvar.h>
+#include <processing/jobs/callback_job.h>
+
+typedef struct private_load_tester_control_t private_load_tester_control_t;
+typedef struct init_listener_t init_listener_t;
+
+/**
+ * Private data of an load_tester_control_t object.
+ */
+struct private_load_tester_control_t {
+
+ /**
+ * Public load_tester_control_t interface.
+ */
+ load_tester_control_t public;
+
+ /**
+ * Load tester control stream service
+ */
+ stream_service_t *service;
+};
+
+/**
+ * Listener to follow initiation progress
+ */
+struct init_listener_t {
+
+ /**
+ * implements listener_t
+ */
+ listener_t listener;
+
+ /**
+ * Output stream to log to
+ */
+ FILE *stream;
+
+ /**
+ * IKE_SAs we have started to initiate
+ */
+ hashtable_t *initiated;
+
+ /**
+ * IKE_SAs we have completed to initate (success or failure)
+ */
+ hashtable_t *completed;
+
+ /**
+ * Mutex to lock IKE_SA tables
+ */
+ mutex_t *mutex;
+
+ /**
+ * Condvar to wait for completion
+ */
+ condvar_t *condvar;
+};
+
+/**
+ * Hashtable hash function
+ */
+static u_int hash(uintptr_t id)
+{
+ return id;
+}
+
+/**
+ * Hashtable hash function
+ */
+static bool equals(uintptr_t a, uintptr_t b)
+{
+ return a == b;
+}
+
+METHOD(listener_t, alert, bool,
+ init_listener_t *this, ike_sa_t *ike_sa, alert_t alert, va_list args)
+{
+ if (alert == ALERT_RETRANSMIT_SEND)
+ {
+ uintptr_t id;
+ bool match = FALSE;
+
+ id = ike_sa->get_unique_id(ike_sa);
+ this->mutex->lock(this->mutex);
+ if (this->initiated->get(this->initiated, (void*)id))
+ {
+ match = TRUE;
+ }
+ this->mutex->unlock(this->mutex);
+
+ if (match)
+ {
+ fprintf(this->stream, "*");
+ fflush(this->stream);
+ }
+ }
+ return TRUE;
+}
+
+METHOD(listener_t, ike_state_change, bool,
+ init_listener_t *this, ike_sa_t *ike_sa, ike_sa_state_t state)
+{
+ if (state == IKE_ESTABLISHED || state == IKE_DESTROYING)
+ {
+ uintptr_t id;
+ bool match = FALSE;
+
+ id = ike_sa->get_unique_id(ike_sa);
+ this->mutex->lock(this->mutex);
+ if (this->initiated->get(this->initiated, (void*)id))
+ {
+ match = !this->completed->put(this->completed, (void*)id, (void*)id);
+ }
+ this->mutex->unlock(this->mutex);
+
+ if (match)
+ {
+ this->condvar->signal(this->condvar);
+ fprintf(this->stream, state == IKE_ESTABLISHED ? "+" : "-");
+ fflush(this->stream);
+ }
+ }
+ return TRUE;
+}
+
+/**
+ * Logging callback function used during initiate
+ */
+static bool initiate_cb(init_listener_t *this, debug_t group, level_t level,
+ ike_sa_t *ike_sa, const char *message)
+{
+ uintptr_t id;
+
+ if (ike_sa)
+ {
+ id = ike_sa->get_unique_id(ike_sa);
+ this->mutex->lock(this->mutex);
+ this->initiated->put(this->initiated, (void*)id, (void*)id);
+ this->mutex->unlock(this->mutex);
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ * Accept connections, initiate load-test, write progress to stream
+ */
+static bool on_accept(private_load_tester_control_t *this, stream_t *io)
+{
+ init_listener_t *listener;
+ enumerator_t *enumerator;
+ peer_cfg_t *peer_cfg;
+ child_cfg_t *child_cfg;
+ u_int i, count, failed = 0, delay = 0;
+ char buf[16] = "";
+ FILE *stream;
+
+ stream = io->get_file(io);
+ if (!stream)
+ {
+ return FALSE;
+ }
+ fflush(stream);
+ if (fgets(buf, sizeof(buf), stream) == NULL)
+ {
+ fclose(stream);
+ return FALSE;
+ }
+ if (sscanf(buf, "%u %u", &count, &delay) < 1)
+ {
+ fclose(stream);
+ return FALSE;
+ }
+
+ INIT(listener,
+ .listener = {
+ .ike_state_change = _ike_state_change,
+ .alert = _alert,
+ },
+ .stream = stream,
+ .initiated = hashtable_create((void*)hash, (void*)equals, count),
+ .completed = hashtable_create((void*)hash, (void*)equals, count),
+ .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+ .condvar = condvar_create(CONDVAR_TYPE_DEFAULT),
+ );
+
+ charon->bus->add_listener(charon->bus, &listener->listener);
+
+ for (i = 0; i < count; i++)
+ {
+ peer_cfg = charon->backends->get_peer_cfg_by_name(charon->backends,
+ "load-test");
+ if (!peer_cfg)
+ {
+ failed++;
+ fprintf(stream, "!");
+ continue;
+ }
+ enumerator = peer_cfg->create_child_cfg_enumerator(peer_cfg);
+ if (!enumerator->enumerate(enumerator, &child_cfg))
+ {
+ enumerator->destroy(enumerator);
+ peer_cfg->destroy(peer_cfg);
+ failed++;
+ fprintf(stream, "!");
+ continue;
+ }
+ enumerator->destroy(enumerator);
+
+ switch (charon->controller->initiate(charon->controller,
+ peer_cfg, child_cfg->get_ref(child_cfg),
+ (void*)initiate_cb, listener, 0))
+ {
+ case NEED_MORE:
+ /* Callback returns FALSE once it got track of this IKE_SA.
+ * FALL */
+ case SUCCESS:
+ fprintf(stream, ".");
+ break;
+ default:
+ fprintf(stream, "!");
+ break;
+ }
+ if (delay)
+ {
+ usleep(delay * 1000);
+ }
+ fflush(stream);
+ }
+
+ listener->mutex->lock(listener->mutex);
+ while (listener->completed->get_count(listener->completed) < count - failed)
+ {
+ listener->condvar->wait(listener->condvar, listener->mutex);
+ }
+ listener->mutex->unlock(listener->mutex);
+
+ charon->bus->remove_listener(charon->bus, &listener->listener);
+
+ listener->initiated->destroy(listener->initiated);
+ listener->completed->destroy(listener->completed);
+ listener->mutex->destroy(listener->mutex);
+ listener->condvar->destroy(listener->condvar);
+ free(listener);
+
+ fprintf(stream, "\n");
+ fclose(stream);
+
+ return FALSE;
+}
+
+METHOD(load_tester_control_t, destroy, void,
+ private_load_tester_control_t *this)
+{
+ DESTROY_IF(this->service);
+ free(this);
+}
+
+/**
+ * See header
+ */
+load_tester_control_t *load_tester_control_create()
+{
+ private_load_tester_control_t *this;
+ char *uri;
+
+ INIT(this,
+ .public = {
+ .destroy = _destroy,
+ },
+ );
+
+ uri = lib->settings->get_str(lib->settings,
+ "%s.plugins.load-tester.socket", "unix://" LOAD_TESTER_SOCKET,
+ charon->name);
+ this->service = lib->streams->create_service(lib->streams, uri, 10);
+ if (this->service)
+ {
+ this->service->on_accept(this->service, (stream_service_cb_t)on_accept,
+ this, JOB_PRIO_CRITICAL, 0);
+ }
+ else
+ {
+ DBG1(DBG_CFG, "creating load-tester control socket failed");
+ }
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/load_tester/load_tester_control.h b/src/libcharon/plugins/load_tester/load_tester_control.h
new file mode 100644
index 000000000..5d280f0a0
--- /dev/null
+++ b/src/libcharon/plugins/load_tester/load_tester_control.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2012 Martin Willi
+ * Copyright (C) 2012 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program 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 General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup load_tester_control load_tester_control
+ * @{ @ingroup load_tester
+ */
+
+#ifndef LOAD_TESTER_CONTROL_H_
+#define LOAD_TESTER_CONTROL_H_
+
+/**
+ * Socket to accept connections.
+ */
+#define LOAD_TESTER_SOCKET IPSEC_PIDDIR "/charon.ldt"
+
+typedef struct load_tester_control_t load_tester_control_t;
+
+/**
+ * Unix control socket to initiate batches of load-tests.
+ */
+struct load_tester_control_t {
+
+ /**
+ * Destroy a load_tester_control_t.
+ */
+ void (*destroy)(load_tester_control_t *this);
+};
+
+/**
+ * Create a load_tester_control instance.
+ */
+load_tester_control_t *load_tester_control_create();
+
+#endif /** LOAD_TESTER_CONTROL_H_ @}*/
diff --git a/src/libcharon/plugins/load_tester/load_tester_creds.c b/src/libcharon/plugins/load_tester/load_tester_creds.c
index c34ea73c5..946d62021 100644
--- a/src/libcharon/plugins/load_tester/load_tester_creds.c
+++ b/src/libcharon/plugins/load_tester/load_tester_creds.c
@@ -16,6 +16,7 @@
#include "load_tester_creds.h"
#include <time.h>
+#include <sys/stat.h>
#include <daemon.h>
#include <credentials/keys/shared_key.h>
@@ -44,6 +45,16 @@ struct private_load_tester_creds_t {
certificate_t *ca;
/**
+ * Trusted CA certificates, including issuer CA
+ */
+ linked_list_t *cas;
+
+ /**
+ * Digest algorithm to issue certificates
+ */
+ hash_algorithm_t digest;
+
+ /**
* serial number to issue certificates
*/
u_int32_t serial;
@@ -182,6 +193,84 @@ static char *default_psk = "default-psk";
*/
static char *default_pwd = "default-pwd";
+
+/**
+ * Load the private key, hard-coded or from a file
+ */
+static private_key_t *load_issuer_key()
+{
+ char *path;
+
+ path = lib->settings->get_str(lib->settings,
+ "%s.plugins.load-tester.issuer_key", NULL, charon->name);
+ if (!path)
+ {
+ return lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+ BUILD_BLOB_ASN1_DER, chunk_create(private, sizeof(private)),
+ BUILD_END);
+ }
+ DBG1(DBG_CFG, "loading load-tester private key from '%s'", path);
+ return lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+ BUILD_FROM_FILE, path, BUILD_END);
+}
+
+/**
+ * Load the issuing certificate, hard-coded or from a file
+ */
+static certificate_t *load_issuer_cert()
+{
+ char *path;
+
+ path = lib->settings->get_str(lib->settings,
+ "%s.plugins.load-tester.issuer_cert", NULL, charon->name);
+ if (!path)
+ {
+ return lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+ BUILD_BLOB_ASN1_DER, chunk_create(cert, sizeof(cert)),
+ BUILD_X509_FLAG, X509_CA,
+ BUILD_END);
+ }
+ DBG1(DBG_CFG, "loading load-tester issuer cert from '%s'", path);
+ return lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+ BUILD_FROM_FILE, path, BUILD_END);
+}
+
+/**
+ * Load (intermediate) CA certificates, hard-coded or from a file
+ */
+static void load_ca_certs(private_load_tester_creds_t *this)
+{
+ enumerator_t *enumerator;
+ certificate_t *cert;
+ struct stat st;
+ char *path;
+
+ path = lib->settings->get_str(lib->settings,
+ "%s.plugins.load-tester.ca_dir", NULL, charon->name);
+ if (path)
+ {
+ enumerator = enumerator_create_directory(path);
+ if (enumerator)
+ {
+ while (enumerator->enumerate(enumerator, NULL, &path, &st))
+ {
+ if (S_ISREG(st.st_mode))
+ {
+ DBG1(DBG_CFG, "loading load-tester CA cert from '%s'", path);
+ cert = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_X509,
+ BUILD_FROM_FILE, path, BUILD_END);
+ if (cert)
+ {
+ this->cas->insert_last(this->cas, cert);
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+ }
+}
+
METHOD(credential_set_t, create_private_enumerator, enumerator_t*,
private_load_tester_creds_t *this, key_type_t type, identification_t *id)
{
@@ -207,8 +296,12 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
private_load_tester_creds_t *this, certificate_type_t cert, key_type_t key,
identification_t *id, bool trusted)
{
- certificate_t *peer_cert;
+ enumerator_t *enumerator;
+ certificate_t *peer_cert, *ca_cert;
public_key_t *peer_key, *ca_key;
+ identification_t *dn = NULL;
+ linked_list_t *sans;
+ char buf[128];
u_int32_t serial;
time_t now;
@@ -226,7 +319,7 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
}
if (!id)
{
- return enumerator_create_single(this->ca, NULL);
+ return this->cas->create_enumerator(this->cas);
}
ca_key = this->ca->get_public_key(this->ca);
if (ca_key)
@@ -238,26 +331,56 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
}
ca_key->destroy(ca_key);
}
- if (this->ca->has_subject(this->ca, id))
+ enumerator = this->cas->create_enumerator(this->cas);
+ while (enumerator->enumerate(enumerator, &ca_cert))
{
- return enumerator_create_single(this->ca, NULL);
+ if (ca_cert->has_subject(ca_cert, id))
+ {
+ enumerator->destroy(enumerator);
+ return enumerator_create_single(ca_cert, NULL);
+ }
}
+ enumerator->destroy(enumerator);
+
if (!trusted)
{
/* peer certificate, generate on demand */
serial = htonl(++this->serial);
now = time(NULL);
+ sans = linked_list_create();
+
+ switch (id->get_type(id))
+ {
+ case ID_DER_ASN1_DN:
+ break;
+ case ID_FQDN:
+ case ID_RFC822_ADDR:
+ case ID_IPV4_ADDR:
+ case ID_IPV6_ADDR:
+ /* encode as subjectAltName, construct a sane DN */
+ sans->insert_last(sans, id);
+ snprintf(buf, sizeof(buf), "CN=%Y", id);
+ dn = identification_create_from_string(buf);
+ break;
+ default:
+ sans->destroy(sans);
+ return NULL;
+ }
peer_key = this->private->get_public_key(this->private);
peer_cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
BUILD_SIGNING_KEY, this->private,
BUILD_SIGNING_CERT, this->ca,
+ BUILD_DIGEST_ALG, this->digest,
BUILD_PUBLIC_KEY, peer_key,
- BUILD_SUBJECT, id,
+ BUILD_SUBJECT, dn ?: id,
+ BUILD_SUBJECT_ALTNAMES, sans,
BUILD_NOT_BEFORE_TIME, now - 60 * 60 * 24,
BUILD_NOT_AFTER_TIME, now + 60 * 60 * 24,
BUILD_SERIAL, chunk_from_thing(serial),
BUILD_END);
peer_key->destroy(peer_key);
+ sans->destroy(sans);
+ DESTROY_IF(dn);
if (peer_cert)
{
return enumerator_create_single(peer_cert, (void*)peer_cert->destroy);
@@ -308,6 +431,7 @@ METHOD(credential_set_t, create_shared_enumerator, enumerator_t*,
METHOD(load_tester_creds_t, destroy, void,
private_load_tester_creds_t *this)
{
+ this->cas->destroy_offset(this->cas, offsetof(certificate_t, destroy));
DESTROY_IF(this->private);
DESTROY_IF(this->ca);
this->psk->destroy(this->psk);
@@ -318,12 +442,14 @@ METHOD(load_tester_creds_t, destroy, void,
load_tester_creds_t *load_tester_creds_create()
{
private_load_tester_creds_t *this;
- char *pwd, *psk;
+ char *pwd, *psk, *digest;
psk = lib->settings->get_str(lib->settings,
- "charon.plugins.load-tester.preshared_key", default_psk);
+ "%s.plugins.load-tester.preshared_key", default_psk, charon->name);
pwd = lib->settings->get_str(lib->settings,
- "charon.plugins.load-tester.eap_password", default_pwd);
+ "%s.plugins.load-tester.eap_password", default_pwd, charon->name);
+ digest = lib->settings->get_str(lib->settings,
+ "%s.plugins.load-tester.digest", "sha1", charon->name);
INIT(this,
.public = {
@@ -336,18 +462,29 @@ load_tester_creds_t *load_tester_creds_create()
},
.destroy = _destroy,
},
- .private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
- BUILD_BLOB_ASN1_DER, chunk_create(private, sizeof(private)),
- BUILD_END),
- .ca = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
- BUILD_BLOB_ASN1_DER, chunk_create(cert, sizeof(cert)),
- BUILD_X509_FLAG, X509_CA,
- BUILD_END),
+ .private = load_issuer_key(),
+ .ca = load_issuer_cert(),
+ .cas = linked_list_create(),
+ .digest = enum_from_name(hash_algorithm_short_names, digest),
.psk = shared_key_create(SHARED_IKE,
chunk_clone(chunk_create(psk, strlen(psk)))),
.pwd = shared_key_create(SHARED_EAP,
chunk_clone(chunk_create(pwd, strlen(pwd)))),
);
+
+ if (this->ca)
+ {
+ this->cas->insert_last(this->cas, this->ca->get_ref(this->ca));
+ }
+
+ if (this->digest == -1)
+ {
+ DBG1(DBG_CFG, "invalid load-tester digest: '%s', using sha1", digest);
+ this->digest = HASH_SHA1;
+ }
+
+ load_ca_certs(this);
+
return &this->public;
}
diff --git a/src/libcharon/plugins/load_tester/load_tester_ipsec.c b/src/libcharon/plugins/load_tester/load_tester_ipsec.c
index 440197260..bf08d2c9c 100644
--- a/src/libcharon/plugins/load_tester/load_tester_ipsec.c
+++ b/src/libcharon/plugins/load_tester/load_tester_ipsec.c
@@ -54,7 +54,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
u_int32_t spi, u_int8_t protocol, u_int32_t reqid, mark_t mark,
u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp,
- u_int16_t cpi, bool encap, bool esn, bool inbound,
+ u_int16_t cpi, bool initiator, bool encap, bool esn, bool inbound,
traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
{
return SUCCESS;
@@ -70,7 +70,8 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
METHOD(kernel_ipsec_t, query_sa, status_t,
private_load_tester_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t spi, u_int8_t protocol, mark_t mark, u_int64_t *bytes)
+ u_int32_t spi, u_int8_t protocol, mark_t mark,
+ u_int64_t *bytes, u_int64_t *packets, u_int32_t *time)
{
return NOT_SUPPORTED;
}
@@ -108,12 +109,6 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
return SUCCESS;
}
-METHOD(kernel_ipsec_t, bypass_socket, bool,
- private_load_tester_ipsec_t *this, int fd, int family)
-{
- return TRUE;
-}
-
METHOD(kernel_ipsec_t, destroy, void,
private_load_tester_ipsec_t *this)
{
@@ -141,7 +136,8 @@ load_tester_ipsec_t *load_tester_ipsec_create()
.query_policy = _query_policy,
.del_policy = _del_policy,
.flush_policies = (void*)return_failed,
- .bypass_socket = _bypass_socket,
+ .bypass_socket = (void*)return_true,
+ .enable_udp_decap = (void*)return_true,
.destroy = _destroy,
},
},
@@ -150,4 +146,3 @@ load_tester_ipsec_t *load_tester_ipsec_create()
return &this->public;
}
-
diff --git a/src/libcharon/plugins/load_tester/load_tester_listener.c b/src/libcharon/plugins/load_tester/load_tester_listener.c
index 7c96f7d97..7e832ddc0 100644
--- a/src/libcharon/plugins/load_tester/load_tester_listener.c
+++ b/src/libcharon/plugins/load_tester/load_tester_listener.c
@@ -50,6 +50,11 @@ struct private_load_tester_listener_t {
* Shutdown the daemon if we have established this SA count
*/
u_int shutdown_on;
+
+ /**
+ * Configuration backend
+ */
+ load_tester_config_t *config;
};
METHOD(listener_t, ike_updown, bool,
@@ -83,6 +88,16 @@ METHOD(listener_t, ike_updown, bool,
return TRUE;
}
+METHOD(listener_t, ike_state_change, bool,
+ private_load_tester_listener_t *this, ike_sa_t *ike_sa, ike_sa_state_t state)
+{
+ if (state == IKE_DESTROYING)
+ {
+ this->config->delete_ip(this->config, ike_sa->get_my_host(ike_sa));
+ }
+ return TRUE;
+}
+
METHOD(load_tester_listener_t, get_established, u_int,
private_load_tester_listener_t *this)
{
@@ -95,7 +110,8 @@ METHOD(load_tester_listener_t, destroy, void,
free(this);
}
-load_tester_listener_t *load_tester_listener_create(u_int shutdown_on)
+load_tester_listener_t *load_tester_listener_create(u_int shutdown_on,
+ load_tester_config_t *config)
{
private_load_tester_listener_t *this;
@@ -103,15 +119,17 @@ load_tester_listener_t *load_tester_listener_create(u_int shutdown_on)
.public = {
.listener = {
.ike_updown = _ike_updown,
+ .ike_state_change = _ike_state_change,
},
.get_established = _get_established,
.destroy = _destroy,
},
.delete_after_established = lib->settings->get_bool(lib->settings,
- "charon.plugins.load-tester.delete_after_established", FALSE),
+ "%s.plugins.load-tester.delete_after_established", FALSE,
+ charon->name),
.shutdown_on = shutdown_on,
+ .config = config,
);
return &this->public;
}
-
diff --git a/src/libcharon/plugins/load_tester/load_tester_listener.h b/src/libcharon/plugins/load_tester/load_tester_listener.h
index 2621798c8..eba4afcf1 100644
--- a/src/libcharon/plugins/load_tester/load_tester_listener.h
+++ b/src/libcharon/plugins/load_tester/load_tester_listener.h
@@ -23,6 +23,8 @@
#include <bus/bus.h>
+#include "load_tester_config.h"
+
typedef struct load_tester_listener_t load_tester_listener_t;
/**
@@ -52,8 +54,10 @@ struct load_tester_listener_t {
* Create a listener to handle special events during load test
*
* @param shutdown_on shut down the daemon after this many SAs are established
+ * @param config configuration backend
* @return listener
*/
-load_tester_listener_t *load_tester_listener_create(u_int shutdown_on);
+load_tester_listener_t *load_tester_listener_create(u_int shutdown_on,
+ load_tester_config_t *config);
#endif /** LOAD_TESTER_LISTENER_H_ @}*/
diff --git a/src/libcharon/plugins/load_tester/load_tester_plugin.c b/src/libcharon/plugins/load_tester/load_tester_plugin.c
index b260a9741..03557a269 100644
--- a/src/libcharon/plugins/load_tester/load_tester_plugin.c
+++ b/src/libcharon/plugins/load_tester/load_tester_plugin.c
@@ -18,6 +18,7 @@
#include "load_tester_creds.h"
#include "load_tester_ipsec.h"
#include "load_tester_listener.h"
+#include "load_tester_control.h"
#include "load_tester_diffie_hellman.h"
#include <unistd.h>
@@ -28,8 +29,6 @@
#include <threading/condvar.h>
#include <threading/mutex.h>
-static const char *plugin_name = "load_tester";
-
typedef struct private_load_tester_plugin_t private_load_tester_plugin_t;
/**
@@ -53,6 +52,11 @@ struct private_load_tester_plugin_t {
load_tester_creds_t *creds;
/**
+ * Unix control socket to initiate load-tests
+ */
+ load_tester_control_t *control;
+
+ /**
* event handler, listens on bus
*/
load_tester_listener_t *listener;
@@ -171,26 +175,81 @@ METHOD(plugin_t, get_name, char*,
return "load-tester";
}
-METHOD(plugin_t, destroy, void,
- private_load_tester_plugin_t *this)
+/**
+ * Register load_tester plugin features
+ */
+static bool register_load_tester(private_load_tester_plugin_t *this,
+ plugin_feature_t *feature, bool reg, void *data)
{
- this->iterations = -1;
- this->mutex->lock(this->mutex);
- while (this->running)
+ if (reg)
{
- this->condvar->wait(this->condvar, this->mutex);
+ u_int i, shutdown_on = 0;
+
+ this->config = load_tester_config_create();
+ this->creds = load_tester_creds_create();
+ this->control = load_tester_control_create();
+
+ charon->backends->add_backend(charon->backends, &this->config->backend);
+ lib->credmgr->add_set(lib->credmgr, &this->creds->credential_set);
+
+ if (lib->settings->get_bool(lib->settings,
+ "%s.plugins.load-tester.shutdown_when_complete", 0, charon->name))
+ {
+ shutdown_on = this->iterations * this->initiators;
+ }
+ this->listener = load_tester_listener_create(shutdown_on, this->config);
+ charon->bus->add_listener(charon->bus, &this->listener->listener);
+
+ for (i = 0; i < this->initiators; i++)
+ {
+ lib->processor->queue_job(lib->processor, (job_t*)
+ callback_job_create_with_prio((callback_job_cb_t)do_load_test,
+ this, NULL, NULL, JOB_PRIO_CRITICAL));
+ }
}
- this->mutex->unlock(this->mutex);
+ else
+ {
+ this->iterations = -1;
+ this->mutex->lock(this->mutex);
+ while (this->running)
+ {
+ this->condvar->wait(this->condvar, this->mutex);
+ }
+ this->mutex->unlock(this->mutex);
+ charon->backends->remove_backend(charon->backends, &this->config->backend);
+ lib->credmgr->remove_set(lib->credmgr, &this->creds->credential_set);
+ charon->bus->remove_listener(charon->bus, &this->listener->listener);
+ this->config->destroy(this->config);
+ this->creds->destroy(this->creds);
+ this->listener->destroy(this->listener);
+ this->control->destroy(this->control);
+ }
+ return TRUE;
+}
+
+METHOD(plugin_t, get_features, int,
+ private_load_tester_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_REGISTER(DH, load_tester_diffie_hellman_create),
+ PLUGIN_PROVIDE(DH, MODP_NULL),
+ PLUGIN_DEPENDS(CUSTOM, "load-tester"),
+ PLUGIN_CALLBACK((plugin_feature_callback_t)register_load_tester, NULL),
+ PLUGIN_PROVIDE(CUSTOM, "load-tester"),
+ PLUGIN_DEPENDS(CUSTOM, "kernel-net"),
+ PLUGIN_SDEPEND(PRIVKEY, KEY_RSA),
+ PLUGIN_SDEPEND(CERT_DECODE, CERT_ANY),
+ PLUGIN_SDEPEND(CERT_DECODE, CERT_X509),
+ };
+ *features = f;
+ return countof(f);
+}
+
+METHOD(plugin_t, destroy, void,
+ private_load_tester_plugin_t *this)
+{
hydra->kernel_interface->remove_ipsec_interface(hydra->kernel_interface,
(kernel_ipsec_constructor_t)load_tester_ipsec_create);
- charon->backends->remove_backend(charon->backends, &this->config->backend);
- lib->credmgr->remove_set(lib->credmgr, &this->creds->credential_set);
- charon->bus->remove_listener(charon->bus, &this->listener->listener);
- this->config->destroy(this->config);
- this->creds->destroy(this->creds);
- this->listener->destroy(this->listener);
- lib->crypto->remove_dh(lib->crypto,
- (dh_constructor_t)load_tester_diffie_hellman_create);
this->mutex->destroy(this->mutex);
this->condvar->destroy(this->condvar);
free(this);
@@ -202,10 +261,9 @@ METHOD(plugin_t, destroy, void,
plugin_t *load_tester_plugin_create()
{
private_load_tester_plugin_t *this;
- u_int i, shutdown_on = 0;
if (!lib->settings->get_bool(lib->settings,
- "charon.plugins.load-tester.enable", FALSE))
+ "%s.plugins.load-tester.enable", FALSE, charon->name))
{
DBG1(DBG_CFG, "disabling load-tester plugin, not configured");
return NULL;
@@ -215,49 +273,28 @@ plugin_t *load_tester_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
+ .get_features = _get_features,
.reload = (void*)return_false,
.destroy = _destroy,
},
},
.delay = lib->settings->get_int(lib->settings,
- "charon.plugins.load-tester.delay", 0),
+ "%s.plugins.load-tester.delay", 0, charon->name),
.iterations = lib->settings->get_int(lib->settings,
- "charon.plugins.load-tester.iterations", 1),
+ "%s.plugins.load-tester.iterations", 1, charon->name),
.initiators = lib->settings->get_int(lib->settings,
- "charon.plugins.load-tester.initiators", 0),
+ "%s.plugins.load-tester.initiators", 0, charon->name),
.init_limit = lib->settings->get_int(lib->settings,
- "charon.plugins.load-tester.init_limit", 0),
+ "%s.plugins.load-tester.init_limit", 0, charon->name),
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
.condvar = condvar_create(CONDVAR_TYPE_DEFAULT),
- .config = load_tester_config_create(),
- .creds = load_tester_creds_create(),
);
- lib->crypto->add_dh(lib->crypto, MODP_NULL, plugin_name,
- (dh_constructor_t)load_tester_diffie_hellman_create);
- charon->backends->add_backend(charon->backends, &this->config->backend);
- lib->credmgr->add_set(lib->credmgr, &this->creds->credential_set);
-
- if (lib->settings->get_bool(lib->settings,
- "charon.plugins.load-tester.shutdown_when_complete", 0))
- {
- shutdown_on = this->iterations * this->initiators;
- }
- this->listener = load_tester_listener_create(shutdown_on);
- charon->bus->add_listener(charon->bus, &this->listener->listener);
-
if (lib->settings->get_bool(lib->settings,
- "charon.plugins.load-tester.fake_kernel", FALSE))
+ "%s.plugins.load-tester.fake_kernel", FALSE, charon->name))
{
hydra->kernel_interface->add_ipsec_interface(hydra->kernel_interface,
(kernel_ipsec_constructor_t)load_tester_ipsec_create);
}
- for (i = 0; i < this->initiators; i++)
- {
- lib->processor->queue_job(lib->processor, (job_t*)
- callback_job_create_with_prio((callback_job_cb_t)do_load_test,
- this, NULL, NULL, JOB_PRIO_CRITICAL));
- }
return &this->public.plugin;
}
-