diff options
Diffstat (limited to 'src/vpn')
-rw-r--r-- | src/vpn/Makefile.am | 77 | ||||
-rw-r--r-- | src/vpn/Makefile.in | 485 | ||||
-rw-r--r-- | src/vpn/gnunet-helper-vpn-windows.c | 1557 | ||||
-rw-r--r-- | src/vpn/gnunet-service-vpn.c | 124 | ||||
-rw-r--r-- | src/vpn/gnunet-vpn.c | 24 | ||||
-rw-r--r-- | src/vpn/test_gnunet_vpn.c | 599 | ||||
-rw-r--r-- | src/vpn/test_gnunet_vpn.conf | 43 | ||||
-rw-r--r-- | src/vpn/vpn.conf.in | 3 | ||||
-rw-r--r-- | src/vpn/vpn.h | 4 | ||||
-rw-r--r-- | src/vpn/vpn_api.c | 4 |
10 files changed, 1864 insertions, 1056 deletions
diff --git a/src/vpn/Makefile.am b/src/vpn/Makefile.am index 2af34f8..8b67a33 100644 --- a/src/vpn/Makefile.am +++ b/src/vpn/Makefile.am @@ -1,7 +1,8 @@ -INCLUDES = -I$(top_srcdir)/src/include +INCLUDES = -I$(top_srcdir)/src/include -I$(top_builddir)/src/include if MINGW - WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols + WINFLAGS = -Wl,--no-undefined,--export-all-symbols + VPNBIN = gnunet-helper-vpn endif if USE_COVERAGE @@ -10,6 +11,8 @@ endif pkgcfgdir= $(pkgdatadir)/config.d/ +libexecdir= $(pkglibdir)/libexec/ + plugindir = $(libdir)/gnunet pkgcfg_DATA = \ @@ -18,15 +21,7 @@ pkgcfg_DATA = \ if LINUX VPNBIN = gnunet-helper-vpn install-exec-hook: - $(SUDO_BINARY) chown root:root $(bindir)/gnunet-helper-vpn || true - $(SUDO_BINARY) chmod u+s $(bindir)/gnunet-helper-vpn || true -if HAVE_MHD - VPN_TEST = \ - test_gnunet_vpn-4_to_6 \ - test_gnunet_vpn-6_to_4 \ - test_gnunet_vpn-6_over \ - test_gnunet_vpn-4_over -endif + $(top_srcdir)/src/vpn/install-vpn-helper.sh $(libexecdir) $(SUDO_BINARY) || true else install-exec-hook: endif @@ -36,23 +31,27 @@ lib_LTLIBRARIES = \ libgnunetvpn.la -bin_PROGRAMS = \ - $(VPNBIN) gnunet-service-vpn gnunet-vpn - - +libexec_PROGRAMS = \ + $(VPNBIN) \ + gnunet-service-vpn -check_PROGRAMS = $(VPN_TEST) +bin_PROGRAMS = \ + gnunet-vpn -if ENABLE_TEST_RUN -TESTS = $(check_PROGRAMS) +if MINGW + gnunet_helper_vpn_LDFLAGS = \ + -no-undefined -Wl,--export-all-symbols + + gnunet_helper_vpn_LDADD = \ + -lsetupapi -lnewdev -lshell32 -liconv -lstdc++ \ + -lcomdlg32 -lgdi32 -liphlpapi + + gnunet_helper_vpn_SOURCES = \ + gnunet-helper-vpn-windows.c +else + gnunet_helper_vpn_SOURCES = \ + gnunet-helper-vpn.c endif - -EXTRA_DIST = \ - test_gnunet_vpn.conf - -gnunet_helper_vpn_SOURCES = \ - gnunet-helper-vpn.c - gnunet_service_vpn_SOURCES = \ gnunet-service-vpn.c gnunet_service_vpn_LDADD = \ @@ -60,6 +59,7 @@ gnunet_service_vpn_LDADD = \ $(top_builddir)/src/tun/libgnunettun.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/mesh/libgnunetmesh.la \ + $(top_builddir)/src/regex/libgnunetregex.la \ $(GN_LIBINTL) gnunet_service_vpn_CFLAGS = \ -I$(top_srcdir)/src/exit $(CFLAGS) @@ -81,30 +81,3 @@ libgnunetvpn_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) -test_gnunet_vpn_4_over_SOURCES = \ - test_gnunet_vpn.c -test_gnunet_vpn_4_over_LDADD = -lmicrohttpd @LIBCURL@ \ - $(top_builddir)/src/vpn/libgnunetvpn.la \ - $(top_builddir)/src/arm/libgnunetarm.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_gnunet_vpn_6_over_SOURCES = \ - test_gnunet_vpn.c -test_gnunet_vpn_6_over_LDADD = -lmicrohttpd @LIBCURL@ \ - $(top_builddir)/src/vpn/libgnunetvpn.la \ - $(top_builddir)/src/arm/libgnunetarm.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_gnunet_vpn_4_to_6_SOURCES = \ - test_gnunet_vpn.c -test_gnunet_vpn_4_to_6_LDADD = -lmicrohttpd @LIBCURL@ \ - $(top_builddir)/src/vpn/libgnunetvpn.la \ - $(top_builddir)/src/arm/libgnunetarm.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_gnunet_vpn_6_to_4_SOURCES = \ - test_gnunet_vpn.c -test_gnunet_vpn_6_to_4_LDADD = -lmicrohttpd @LIBCURL@ \ - $(top_builddir)/src/vpn/libgnunetvpn.la \ - $(top_builddir)/src/arm/libgnunetarm.la \ - $(top_builddir)/src/util/libgnunetutil.la diff --git a/src/vpn/Makefile.in b/src/vpn/Makefile.in index 54ca311..c753cfd 100644 --- a/src/vpn/Makefile.in +++ b/src/vpn/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. @@ -18,6 +18,23 @@ 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@ @@ -37,23 +54,23 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ -bin_PROGRAMS = $(am__EXEEXT_1) gnunet-service-vpn$(EXEEXT) \ - gnunet-vpn$(EXEEXT) -check_PROGRAMS = $(am__EXEEXT_2) +libexec_PROGRAMS = $(am__EXEEXT_1) gnunet-service-vpn$(EXEEXT) +bin_PROGRAMS = gnunet-vpn$(EXEEXT) subdir = src/vpn DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(srcdir)/vpn.conf.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/absolute-header.m4 \ $(top_srcdir)/m4/align.m4 $(top_srcdir)/m4/argz.m4 \ - $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \ - $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ - $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libcurl.m4 \ - $(top_srcdir)/m4/libgcrypt.m4 $(top_srcdir)/m4/libtool.m4 \ - $(top_srcdir)/m4/libunistring.m4 $(top_srcdir)/m4/ltdl.m4 \ - $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ - $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ - $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/glib-2.0.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/libcurl.m4 $(top_srcdir)/m4/libgcrypt.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/libunistring.m4 \ + $(top_srcdir)/m4/ltdl.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/m4/po.m4 \ $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ @@ -83,30 +100,41 @@ 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__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)$(libdir)" "$(DESTDIR)$(bindir)" \ - "$(DESTDIR)$(pkgcfgdir)" + "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(pkgcfgdir)" LTLIBRARIES = $(lib_LTLIBRARIES) libgnunetvpn_la_DEPENDENCIES = \ $(top_builddir)/src/util/libgnunetutil.la am_libgnunetvpn_la_OBJECTS = vpn_api.lo libgnunetvpn_la_OBJECTS = $(am_libgnunetvpn_la_OBJECTS) -AM_V_lt = $(am__v_lt_$(V)) -am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent libgnunetvpn_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgnunetvpn_la_LDFLAGS) $(LDFLAGS) \ -o $@ +@LINUX_FALSE@@MINGW_TRUE@am__EXEEXT_1 = gnunet-helper-vpn$(EXEEXT) @LINUX_TRUE@am__EXEEXT_1 = gnunet-helper-vpn$(EXEEXT) -@HAVE_MHD_TRUE@@LINUX_TRUE@am__EXEEXT_2 = \ -@HAVE_MHD_TRUE@@LINUX_TRUE@ test_gnunet_vpn-4_to_6$(EXEEXT) \ -@HAVE_MHD_TRUE@@LINUX_TRUE@ test_gnunet_vpn-6_to_4$(EXEEXT) \ -@HAVE_MHD_TRUE@@LINUX_TRUE@ test_gnunet_vpn-6_over$(EXEEXT) \ -@HAVE_MHD_TRUE@@LINUX_TRUE@ test_gnunet_vpn-4_over$(EXEEXT) -PROGRAMS = $(bin_PROGRAMS) -am_gnunet_helper_vpn_OBJECTS = gnunet-helper-vpn.$(OBJEXT) +PROGRAMS = $(bin_PROGRAMS) $(libexec_PROGRAMS) +am__gnunet_helper_vpn_SOURCES_DIST = gnunet-helper-vpn.c \ + gnunet-helper-vpn-windows.c +@MINGW_FALSE@am_gnunet_helper_vpn_OBJECTS = \ +@MINGW_FALSE@ gnunet-helper-vpn.$(OBJEXT) +@MINGW_TRUE@am_gnunet_helper_vpn_OBJECTS = \ +@MINGW_TRUE@ gnunet-helper-vpn-windows.$(OBJEXT) gnunet_helper_vpn_OBJECTS = $(am_gnunet_helper_vpn_OBJECTS) -gnunet_helper_vpn_LDADD = $(LDADD) +gnunet_helper_vpn_DEPENDENCIES = +gnunet_helper_vpn_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(gnunet_helper_vpn_LDFLAGS) $(LDFLAGS) \ + -o $@ am_gnunet_service_vpn_OBJECTS = \ gnunet_service_vpn-gnunet-service-vpn.$(OBJEXT) gnunet_service_vpn_OBJECTS = $(am_gnunet_service_vpn_OBJECTS) @@ -116,6 +144,7 @@ gnunet_service_vpn_DEPENDENCIES = \ $(top_builddir)/src/tun/libgnunettun.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/mesh/libgnunetmesh.la \ + $(top_builddir)/src/regex/libgnunetregex.la \ $(am__DEPENDENCIES_1) gnunet_service_vpn_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ @@ -123,30 +152,6 @@ gnunet_service_vpn_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(LDFLAGS) -o $@ am_gnunet_vpn_OBJECTS = gnunet-vpn.$(OBJEXT) gnunet_vpn_OBJECTS = $(am_gnunet_vpn_OBJECTS) -am_test_gnunet_vpn_4_over_OBJECTS = test_gnunet_vpn.$(OBJEXT) -test_gnunet_vpn_4_over_OBJECTS = $(am_test_gnunet_vpn_4_over_OBJECTS) -test_gnunet_vpn_4_over_DEPENDENCIES = \ - $(top_builddir)/src/vpn/libgnunetvpn.la \ - $(top_builddir)/src/arm/libgnunetarm.la \ - $(top_builddir)/src/util/libgnunetutil.la -am_test_gnunet_vpn_4_to_6_OBJECTS = test_gnunet_vpn.$(OBJEXT) -test_gnunet_vpn_4_to_6_OBJECTS = $(am_test_gnunet_vpn_4_to_6_OBJECTS) -test_gnunet_vpn_4_to_6_DEPENDENCIES = \ - $(top_builddir)/src/vpn/libgnunetvpn.la \ - $(top_builddir)/src/arm/libgnunetarm.la \ - $(top_builddir)/src/util/libgnunetutil.la -am_test_gnunet_vpn_6_over_OBJECTS = test_gnunet_vpn.$(OBJEXT) -test_gnunet_vpn_6_over_OBJECTS = $(am_test_gnunet_vpn_6_over_OBJECTS) -test_gnunet_vpn_6_over_DEPENDENCIES = \ - $(top_builddir)/src/vpn/libgnunetvpn.la \ - $(top_builddir)/src/arm/libgnunetarm.la \ - $(top_builddir)/src/util/libgnunetutil.la -am_test_gnunet_vpn_6_to_4_OBJECTS = test_gnunet_vpn.$(OBJEXT) -test_gnunet_vpn_6_to_4_OBJECTS = $(am_test_gnunet_vpn_6_to_4_OBJECTS) -test_gnunet_vpn_6_to_4_DEPENDENCIES = \ - $(top_builddir)/src/vpn/libgnunetvpn.la \ - $(top_builddir)/src/arm/libgnunetarm.la \ - $(top_builddir)/src/util/libgnunetutil.la DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @@ -157,39 +162,35 @@ 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_$(V)) -am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +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_$(V)) -am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +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) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_$(V)) -am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +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_$(V)) -am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(libgnunetvpn_la_SOURCES) $(gnunet_helper_vpn_SOURCES) \ - $(gnunet_service_vpn_SOURCES) $(gnunet_vpn_SOURCES) \ - $(test_gnunet_vpn_4_over_SOURCES) \ - $(test_gnunet_vpn_4_to_6_SOURCES) \ - $(test_gnunet_vpn_6_over_SOURCES) \ - $(test_gnunet_vpn_6_to_4_SOURCES) -DIST_SOURCES = $(libgnunetvpn_la_SOURCES) $(gnunet_helper_vpn_SOURCES) \ - $(gnunet_service_vpn_SOURCES) $(gnunet_vpn_SOURCES) \ - $(test_gnunet_vpn_4_over_SOURCES) \ - $(test_gnunet_vpn_4_to_6_SOURCES) \ - $(test_gnunet_vpn_6_over_SOURCES) \ - $(test_gnunet_vpn_6_to_4_SOURCES) + $(gnunet_service_vpn_SOURCES) $(gnunet_vpn_SOURCES) +DIST_SOURCES = $(libgnunetvpn_la_SOURCES) \ + $(am__gnunet_helper_vpn_SOURCES_DIST) \ + $(gnunet_service_vpn_SOURCES) $(gnunet_vpn_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac DATA = $(pkgcfg_DATA) ETAGS = etags CTAGS = ctags -am__tty_colors = \ -red=; grn=; lgn=; blu=; std= DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -226,6 +227,10 @@ EXEEXT = @EXEEXT@ EXT_LIBS = @EXT_LIBS@ EXT_LIB_PATH = @EXT_LIB_PATH@ FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMSGFMT = @GMSGFMT@ GMSGFMT_015 = @GMSGFMT_015@ GNUNETDNS_GROUP = @GNUNETDNS_GROUP@ @@ -236,6 +241,7 @@ GN_LIBINTL = @GN_LIBINTL@ GN_LIB_LDFLAGS = @GN_LIB_LDFLAGS@ GN_PLUGIN_LDFLAGS = @GN_PLUGIN_LDFLAGS@ GN_USER_HOME_DIR = @GN_USER_HOME_DIR@ +GOBJECT_QUERY = @GOBJECT_QUERY@ GREP = @GREP@ HAVE_LIBUNISTRING = @HAVE_LIBUNISTRING@ INCLTDL = @INCLTDL@ @@ -258,6 +264,8 @@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBGTOP_CFLAGS = @LIBGTOP_CFLAGS@ +LIBGTOP_LIBS = @LIBGTOP_LIBS@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBLTDL = @LIBLTDL@ @@ -279,6 +287,7 @@ LT_CONFIG_H = @LT_CONFIG_H@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ @@ -288,6 +297,7 @@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ NM = @NM@ NMEDIT = @NMEDIT@ +NSS_DIR = @NSS_DIR@ OBJC = @OBJC@ OBJCDEPMODE = @OBJCDEPMODE@ OBJCFLAGS = @OBJCFLAGS@ @@ -303,6 +313,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ POSTGRES_CPPFLAGS = @POSTGRES_CPPFLAGS@ POSTGRES_LDFLAGS = @POSTGRES_LDFLAGS@ POSUB = @POSUB@ @@ -334,6 +345,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_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ @@ -356,6 +368,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ +gitcommand = @gitcommand@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ @@ -366,10 +379,9 @@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ -libexecdir = @libexecdir@ +libexecdir = $(pkglibdir)/libexec/ localedir = @localedir@ localstatedir = @localstatedir@ -lt_ECHO = @lt_ECHO@ ltdl_LIBOBJS = @ltdl_LIBOBJS@ ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@ mandir = @mandir@ @@ -387,6 +399,7 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ +svnversioncommand = @svnversioncommand@ sys_symbol_underscore = @sys_symbol_underscore@ sysconfdir = @sysconfdir@ target = @target@ @@ -397,30 +410,31 @@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -INCLUDES = -I$(top_srcdir)/src/include -@MINGW_TRUE@WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols +INCLUDES = -I$(top_srcdir)/src/include -I$(top_builddir)/src/include +@MINGW_TRUE@WINFLAGS = -Wl,--no-undefined,--export-all-symbols +@LINUX_TRUE@VPNBIN = gnunet-helper-vpn +@MINGW_TRUE@VPNBIN = gnunet-helper-vpn @USE_COVERAGE_TRUE@AM_CFLAGS = --coverage -O0 pkgcfgdir = $(pkgdatadir)/config.d/ plugindir = $(libdir)/gnunet pkgcfg_DATA = \ vpn.conf -@LINUX_TRUE@VPNBIN = gnunet-helper-vpn -@HAVE_MHD_TRUE@@LINUX_TRUE@VPN_TEST = \ -@HAVE_MHD_TRUE@@LINUX_TRUE@ test_gnunet_vpn-4_to_6 \ -@HAVE_MHD_TRUE@@LINUX_TRUE@ test_gnunet_vpn-6_to_4 \ -@HAVE_MHD_TRUE@@LINUX_TRUE@ test_gnunet_vpn-6_over \ -@HAVE_MHD_TRUE@@LINUX_TRUE@ test_gnunet_vpn-4_over - lib_LTLIBRARIES = \ libgnunetvpn.la -@ENABLE_TEST_RUN_TRUE@TESTS = $(check_PROGRAMS) -EXTRA_DIST = \ - test_gnunet_vpn.conf +@MINGW_TRUE@gnunet_helper_vpn_LDFLAGS = \ +@MINGW_TRUE@ -no-undefined -Wl,--export-all-symbols + +@MINGW_TRUE@gnunet_helper_vpn_LDADD = \ +@MINGW_TRUE@ -lsetupapi -lnewdev -lshell32 -liconv -lstdc++ \ +@MINGW_TRUE@ -lcomdlg32 -lgdi32 -liphlpapi -gnunet_helper_vpn_SOURCES = \ - gnunet-helper-vpn.c +@MINGW_FALSE@gnunet_helper_vpn_SOURCES = \ +@MINGW_FALSE@ gnunet-helper-vpn.c + +@MINGW_TRUE@gnunet_helper_vpn_SOURCES = \ +@MINGW_TRUE@ gnunet-helper-vpn-windows.c gnunet_service_vpn_SOURCES = \ gnunet-service-vpn.c @@ -430,6 +444,7 @@ gnunet_service_vpn_LDADD = \ $(top_builddir)/src/tun/libgnunettun.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/mesh/libgnunetmesh.la \ + $(top_builddir)/src/regex/libgnunetregex.la \ $(GN_LIBINTL) gnunet_service_vpn_CFLAGS = \ @@ -455,38 +470,6 @@ libgnunetvpn_la_LIBADD = \ libgnunetvpn_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) -test_gnunet_vpn_4_over_SOURCES = \ - test_gnunet_vpn.c - -test_gnunet_vpn_4_over_LDADD = -lmicrohttpd @LIBCURL@ \ - $(top_builddir)/src/vpn/libgnunetvpn.la \ - $(top_builddir)/src/arm/libgnunetarm.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_gnunet_vpn_6_over_SOURCES = \ - test_gnunet_vpn.c - -test_gnunet_vpn_6_over_LDADD = -lmicrohttpd @LIBCURL@ \ - $(top_builddir)/src/vpn/libgnunetvpn.la \ - $(top_builddir)/src/arm/libgnunetarm.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_gnunet_vpn_4_to_6_SOURCES = \ - test_gnunet_vpn.c - -test_gnunet_vpn_4_to_6_LDADD = -lmicrohttpd @LIBCURL@ \ - $(top_builddir)/src/vpn/libgnunetvpn.la \ - $(top_builddir)/src/arm/libgnunetarm.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_gnunet_vpn_6_to_4_SOURCES = \ - test_gnunet_vpn.c - -test_gnunet_vpn_6_to_4_LDADD = -lmicrohttpd @LIBCURL@ \ - $(top_builddir)/src/vpn/libgnunetvpn.la \ - $(top_builddir)/src/arm/libgnunetarm.la \ - $(top_builddir)/src/util/libgnunetutil.la - all: all-am .SUFFIXES: @@ -525,7 +508,6 @@ vpn.conf: $(top_builddir)/config.status $(srcdir)/vpn.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) - test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ @@ -533,6 +515,8 @@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) else :; fi; \ done; \ test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } @@ -554,12 +538,15 @@ clean-libLTLIBRARIES: echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done -libgnunetvpn.la: $(libgnunetvpn_la_OBJECTS) $(libgnunetvpn_la_DEPENDENCIES) +libgnunetvpn.la: $(libgnunetvpn_la_OBJECTS) $(libgnunetvpn_la_DEPENDENCIES) $(EXTRA_libgnunetvpn_la_DEPENDENCIES) $(AM_V_CCLD)$(libgnunetvpn_la_LINK) -rpath $(libdir) $(libgnunetvpn_la_OBJECTS) $(libgnunetvpn_la_LIBADD) $(LIBS) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) - test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || 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; \ @@ -599,36 +586,61 @@ clean-binPROGRAMS: list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list +install-libexecPROGRAMS: $(libexec_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(libexecdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libexecdir)" || 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)$(libexecdir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(libexecdir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-libexecPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || 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)$(libexecdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(libexecdir)" && rm -f $$files -clean-checkPROGRAMS: - @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ +clean-libexecPROGRAMS: + @list='$(libexec_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 -gnunet-helper-vpn$(EXEEXT): $(gnunet_helper_vpn_OBJECTS) $(gnunet_helper_vpn_DEPENDENCIES) +gnunet-helper-vpn$(EXEEXT): $(gnunet_helper_vpn_OBJECTS) $(gnunet_helper_vpn_DEPENDENCIES) $(EXTRA_gnunet_helper_vpn_DEPENDENCIES) @rm -f gnunet-helper-vpn$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(gnunet_helper_vpn_OBJECTS) $(gnunet_helper_vpn_LDADD) $(LIBS) -gnunet-service-vpn$(EXEEXT): $(gnunet_service_vpn_OBJECTS) $(gnunet_service_vpn_DEPENDENCIES) + $(AM_V_CCLD)$(gnunet_helper_vpn_LINK) $(gnunet_helper_vpn_OBJECTS) $(gnunet_helper_vpn_LDADD) $(LIBS) +gnunet-service-vpn$(EXEEXT): $(gnunet_service_vpn_OBJECTS) $(gnunet_service_vpn_DEPENDENCIES) $(EXTRA_gnunet_service_vpn_DEPENDENCIES) @rm -f gnunet-service-vpn$(EXEEXT) $(AM_V_CCLD)$(gnunet_service_vpn_LINK) $(gnunet_service_vpn_OBJECTS) $(gnunet_service_vpn_LDADD) $(LIBS) -gnunet-vpn$(EXEEXT): $(gnunet_vpn_OBJECTS) $(gnunet_vpn_DEPENDENCIES) +gnunet-vpn$(EXEEXT): $(gnunet_vpn_OBJECTS) $(gnunet_vpn_DEPENDENCIES) $(EXTRA_gnunet_vpn_DEPENDENCIES) @rm -f gnunet-vpn$(EXEEXT) $(AM_V_CCLD)$(LINK) $(gnunet_vpn_OBJECTS) $(gnunet_vpn_LDADD) $(LIBS) -test_gnunet_vpn-4_over$(EXEEXT): $(test_gnunet_vpn_4_over_OBJECTS) $(test_gnunet_vpn_4_over_DEPENDENCIES) - @rm -f test_gnunet_vpn-4_over$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_gnunet_vpn_4_over_OBJECTS) $(test_gnunet_vpn_4_over_LDADD) $(LIBS) -test_gnunet_vpn-4_to_6$(EXEEXT): $(test_gnunet_vpn_4_to_6_OBJECTS) $(test_gnunet_vpn_4_to_6_DEPENDENCIES) - @rm -f test_gnunet_vpn-4_to_6$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_gnunet_vpn_4_to_6_OBJECTS) $(test_gnunet_vpn_4_to_6_LDADD) $(LIBS) -test_gnunet_vpn-6_over$(EXEEXT): $(test_gnunet_vpn_6_over_OBJECTS) $(test_gnunet_vpn_6_over_DEPENDENCIES) - @rm -f test_gnunet_vpn-6_over$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_gnunet_vpn_6_over_OBJECTS) $(test_gnunet_vpn_6_over_LDADD) $(LIBS) -test_gnunet_vpn-6_to_4$(EXEEXT): $(test_gnunet_vpn_6_to_4_OBJECTS) $(test_gnunet_vpn_6_to_4_DEPENDENCIES) - @rm -f test_gnunet_vpn-6_to_4$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_gnunet_vpn_6_to_4_OBJECTS) $(test_gnunet_vpn_6_to_4_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -636,51 +648,46 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-helper-vpn-windows.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-helper-vpn.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-vpn.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet_service_vpn-gnunet-service-vpn.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_gnunet_vpn.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vpn_api.Plo@am__quote@ .c.o: @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 -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@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@ $(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 -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@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@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@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 $@ $< gnunet_service_vpn-gnunet-service-vpn.o: gnunet-service-vpn.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_vpn_CFLAGS) $(CFLAGS) -MT gnunet_service_vpn-gnunet-service-vpn.o -MD -MP -MF $(DEPDIR)/gnunet_service_vpn-gnunet-service-vpn.Tpo -c -o gnunet_service_vpn-gnunet-service-vpn.o `test -f 'gnunet-service-vpn.c' || echo '$(srcdir)/'`gnunet-service-vpn.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnunet_service_vpn-gnunet-service-vpn.Tpo $(DEPDIR)/gnunet_service_vpn-gnunet-service-vpn.Po -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gnunet-service-vpn.c' object='gnunet_service_vpn-gnunet-service-vpn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gnunet-service-vpn.c' object='gnunet_service_vpn-gnunet-service-vpn.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_vpn_CFLAGS) $(CFLAGS) -c -o gnunet_service_vpn-gnunet-service-vpn.o `test -f 'gnunet-service-vpn.c' || echo '$(srcdir)/'`gnunet-service-vpn.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_vpn_CFLAGS) $(CFLAGS) -c -o gnunet_service_vpn-gnunet-service-vpn.o `test -f 'gnunet-service-vpn.c' || echo '$(srcdir)/'`gnunet-service-vpn.c gnunet_service_vpn-gnunet-service-vpn.obj: gnunet-service-vpn.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_vpn_CFLAGS) $(CFLAGS) -MT gnunet_service_vpn-gnunet-service-vpn.obj -MD -MP -MF $(DEPDIR)/gnunet_service_vpn-gnunet-service-vpn.Tpo -c -o gnunet_service_vpn-gnunet-service-vpn.obj `if test -f 'gnunet-service-vpn.c'; then $(CYGPATH_W) 'gnunet-service-vpn.c'; else $(CYGPATH_W) '$(srcdir)/gnunet-service-vpn.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnunet_service_vpn-gnunet-service-vpn.Tpo $(DEPDIR)/gnunet_service_vpn-gnunet-service-vpn.Po -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gnunet-service-vpn.c' object='gnunet_service_vpn-gnunet-service-vpn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gnunet-service-vpn.c' object='gnunet_service_vpn-gnunet-service-vpn.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_vpn_CFLAGS) $(CFLAGS) -c -o gnunet_service_vpn-gnunet-service-vpn.obj `if test -f 'gnunet-service-vpn.c'; then $(CYGPATH_W) 'gnunet-service-vpn.c'; else $(CYGPATH_W) '$(srcdir)/gnunet-service-vpn.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gnunet_service_vpn_CFLAGS) $(CFLAGS) -c -o gnunet_service_vpn-gnunet-service-vpn.obj `if test -f 'gnunet-service-vpn.c'; then $(CYGPATH_W) 'gnunet-service-vpn.c'; else $(CYGPATH_W) '$(srcdir)/gnunet-service-vpn.c'; fi` mostlyclean-libtool: -rm -f *.lo @@ -689,8 +696,11 @@ clean-libtool: -rm -rf .libs _libs install-pkgcfgDATA: $(pkgcfg_DATA) @$(NORMAL_INSTALL) - test -z "$(pkgcfgdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgcfgdir)" @list='$(pkgcfg_DATA)'; test -n "$(pkgcfgdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgcfgdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgcfgdir)" || exit 1; \ + fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ @@ -704,9 +714,7 @@ uninstall-pkgcfgDATA: @$(NORMAL_UNINSTALL) @list='$(pkgcfg_DATA)'; test -n "$(pkgcfgdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - test -n "$$files" || exit 0; \ - echo " ( cd '$(DESTDIR)$(pkgcfgdir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(pkgcfgdir)" && rm -f $$files + dir='$(DESTDIR)$(pkgcfgdir)'; $(am__uninstall_files_from_dir) ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ @@ -760,98 +768,6 @@ GTAGS: distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -check-TESTS: $(TESTS) - @failed=0; all=0; xfail=0; xpass=0; skip=0; \ - srcdir=$(srcdir); export srcdir; \ - list=' $(TESTS) '; \ - $(am__tty_colors); \ - if test -n "$$list"; then \ - for tst in $$list; do \ - if test -f ./$$tst; then dir=./; \ - elif test -f $$tst; then dir=; \ - else dir="$(srcdir)/"; fi; \ - if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ - all=`expr $$all + 1`; \ - case " $(XFAIL_TESTS) " in \ - *[\ \ ]$$tst[\ \ ]*) \ - xpass=`expr $$xpass + 1`; \ - failed=`expr $$failed + 1`; \ - col=$$red; res=XPASS; \ - ;; \ - *) \ - col=$$grn; res=PASS; \ - ;; \ - esac; \ - elif test $$? -ne 77; then \ - all=`expr $$all + 1`; \ - case " $(XFAIL_TESTS) " in \ - *[\ \ ]$$tst[\ \ ]*) \ - xfail=`expr $$xfail + 1`; \ - col=$$lgn; res=XFAIL; \ - ;; \ - *) \ - failed=`expr $$failed + 1`; \ - col=$$red; res=FAIL; \ - ;; \ - esac; \ - else \ - skip=`expr $$skip + 1`; \ - col=$$blu; res=SKIP; \ - fi; \ - echo "$${col}$$res$${std}: $$tst"; \ - done; \ - if test "$$all" -eq 1; then \ - tests="test"; \ - All=""; \ - else \ - tests="tests"; \ - All="All "; \ - fi; \ - if test "$$failed" -eq 0; then \ - if test "$$xfail" -eq 0; then \ - banner="$$All$$all $$tests passed"; \ - else \ - if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ - banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ - fi; \ - else \ - if test "$$xpass" -eq 0; then \ - banner="$$failed of $$all $$tests failed"; \ - else \ - if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ - banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ - fi; \ - fi; \ - dashes="$$banner"; \ - skipped=""; \ - if test "$$skip" -ne 0; then \ - if test "$$skip" -eq 1; then \ - skipped="($$skip test was not run)"; \ - else \ - skipped="($$skip tests were not run)"; \ - fi; \ - test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ - dashes="$$skipped"; \ - fi; \ - report=""; \ - if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ - report="Please report to $(PACKAGE_BUGREPORT)"; \ - test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ - dashes="$$report"; \ - fi; \ - dashes=`echo "$$dashes" | sed s/./=/g`; \ - if test "$$failed" -eq 0; then \ - echo "$$grn$$dashes"; \ - else \ - echo "$$red$$dashes"; \ - fi; \ - echo "$$banner"; \ - test -z "$$skipped" || echo "$$skipped"; \ - test -z "$$report" || echo "$$report"; \ - echo "$$dashes$$std"; \ - test "$$failed" -eq 0; \ - else :; fi - distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -883,14 +799,12 @@ distdir: $(DISTFILES) fi; \ done check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) - $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA) install-binPROGRAMS: install-libLTLIBRARIES installdirs: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgcfgdir)"; do \ + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(pkgcfgdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -903,10 +817,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: @@ -920,8 +839,8 @@ maintainer-clean-generic: @echo "it deletes files that may require special tools to rebuild." clean: clean-am -clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ - clean-libLTLIBRARIES clean-libtool mostlyclean-am +clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \ + clean-libexecPROGRAMS clean-libtool mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) @@ -947,7 +866,8 @@ install-dvi: install-dvi-am install-dvi-am: -install-exec-am: install-binPROGRAMS install-libLTLIBRARIES +install-exec-am: install-binPROGRAMS install-libLTLIBRARIES \ + install-libexecPROGRAMS @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook install-html: install-html-am @@ -989,30 +909,29 @@ ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-libLTLIBRARIES \ - uninstall-pkgcfgDATA - -.MAKE: check-am install-am install-exec-am install-strip - -.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ - clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ - clean-libLTLIBRARIES clean-libtool ctags distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-binPROGRAMS install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-exec-hook install-html install-html-am \ - install-info install-info-am install-libLTLIBRARIES \ - install-man install-pdf install-pdf-am install-pkgcfgDATA \ - 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-binPROGRAMS \ - uninstall-libLTLIBRARIES uninstall-pkgcfgDATA + uninstall-libexecPROGRAMS uninstall-pkgcfgDATA + +.MAKE: install-am install-exec-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ + clean-generic clean-libLTLIBRARIES clean-libexecPROGRAMS \ + clean-libtool ctags distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-binPROGRAMS install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-exec-hook \ + install-html install-html-am install-info install-info-am \ + install-libLTLIBRARIES install-libexecPROGRAMS install-man \ + install-pdf install-pdf-am install-pkgcfgDATA 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-binPROGRAMS uninstall-libLTLIBRARIES \ + uninstall-libexecPROGRAMS uninstall-pkgcfgDATA @LINUX_TRUE@install-exec-hook: -@LINUX_TRUE@ $(SUDO_BINARY) chown root:root $(bindir)/gnunet-helper-vpn || true -@LINUX_TRUE@ $(SUDO_BINARY) chmod u+s $(bindir)/gnunet-helper-vpn || true +@LINUX_TRUE@ $(top_srcdir)/src/vpn/install-vpn-helper.sh $(libexecdir) $(SUDO_BINARY) || true @LINUX_FALSE@install-exec-hook: # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/src/vpn/gnunet-helper-vpn-windows.c b/src/vpn/gnunet-helper-vpn-windows.c new file mode 100644 index 0000000..b810dc7 --- /dev/null +++ b/src/vpn/gnunet-helper-vpn-windows.c @@ -0,0 +1,1557 @@ +/* + This file is part of GNUnet. + (C) 2010, 2012 Christian Grothoff + + GNUnet 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 3, or (at your + option) any later version. + + GNUnet 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. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/** + * @file vpn/gnunet-helper-vpn-windows.c + * @brief the helper for the VPN service in win32 builds. + * Opens a virtual network-interface, sends data received on the if to stdout, + * sends data received on stdin to the interface + * @author Christian M. Fuchs + * + * The following list of people have reviewed this code and considered + * it safe since the last modification (if you reviewed it, please + * have your name added to the list): + * + */ + +#include <stdio.h> +#include <windows.h> +#include <setupapi.h> +#include <ddk/cfgmgr32.h> +#include <ddk/newdev.h> +#include <Winsock2.h> +#include <time.h> +#include "platform.h" +#include "tap-windows.h" +/** + * Need 'struct GNUNET_MessageHeader'. + */ +#include "gnunet_common.h" + +/** + * Need VPN message types. + */ +#include "gnunet_protocols.h" + +/** + * Should we print (interesting|debug) messages that can happen during + * normal operation? + */ +#define DEBUG GNUNET_NO + +#if DEBUG +/* FIXME: define with varargs... */ +#define LOG_DEBUG(msg) fprintf (stderr, "%s", msg); +#else +#define LOG_DEBUG(msg) do {} while (0) +#endif + + +/** + * Maximum size of a GNUnet message (GNUNET_SERVER_MAX_MESSAGE_SIZE) + */ +#define MAX_SIZE 65536 + +/** + * Name or Path+Name of our win32 driver. + * The .sys and .cat files HAVE to be in the same location as this file! + */ +#define INF_FILE "share/gnunet/tapw32/OemWin2k.inf" + +/** + * Name or Path+Name of our win64 driver. + * The .sys and .cat files HAVE to be in the same location as this file! + */ +#define INF_FILE64 "share/gnunet/tapw64/OemWin2k.inf" + +/** + * Hardware ID used in the inf-file. + * This might change over time, as openvpn advances their driver + */ +#define HARDWARE_ID "tap0901" + +/** + * Minimum major-id of the driver version we can work with + */ +#define TAP_WIN_MIN_MAJOR 9 + +/** + * Minimum minor-id of the driver version we can work with. + * v <= 7 has buggy IPv6. + * v == 8 is broken for small IPv4 Packets + */ +#define TAP_WIN_MIN_MINOR 9 + +/** + * Time in seconds to wait for our virtual device to go up after telling it to do so. + * + * openvpn doesn't specify a value, 4 seems sane for testing, even for openwrt + * (in fact, 4 was chosen by a fair dice roll...) + */ +#define TAP32_POSTUP_WAITTIME 4 + +/** + * Location of the network interface list resides in registry. + */ +#define INTERFACE_REGISTRY_LOCATION "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}" + +/** + * Our local process' PID. Used for creating a sufficiently unique additional + * hardware ID for our device. + */ +static char secondary_hwid[LINE_LEN / 2]; + +/** + * Device's visible Name, used to identify a network device in netsh. + * eg: "Local Area Connection 9" + */ +static char device_visible_name[256]; + +/** + * This is our own local instance of a virtual network interface + * It is (somewhat) equivalent to using tun/tap in unixoid systems + * + * Upon initialization, we create such an device node. + * Upon termination, we remove it again. + * + * If we crash this device might stay around. + */ +static HDEVINFO DeviceInfo = INVALID_HANDLE_VALUE; + +/** + * Registry Key we hand over to windows to spawn a new virtual interface + */ +static SP_DEVINFO_DATA DeviceNode; + +/** + * GUID of our virtual device in the form of + * {12345678-1234-1234-1234-123456789abc} - in hex + */ +static char device_guid[256]; + + +/** + * Possible states of an IO facility. + */ +enum IO_State +{ + + /** + * overlapped I/O is ready for work + */ + IOSTATE_READY = 0, + + /** + * overlapped I/O has been queued + */ + IOSTATE_QUEUED, + + /** + * overlapped I/O has finished, but is waiting for it's write-partner + */ + IOSTATE_WAITING, + + /** + * there is a full buffer waiting + */ + IOSTATE_RESUME, + + /** + * Operlapped IO states for facility objects + * overlapped I/O has failed, stop processing + */ + IOSTATE_FAILED + +}; + + +/** + * A IO Object + read/writebuffer + buffer-size for windows asynchronous IO handling + */ +struct io_facility +{ + /** + * The mode the state machine associated with this object is in. + */ + enum IO_State facility_state; + + /** + * If the path is open or blocked in general (used for quickly checking) + */ + BOOL path_open; // BOOL is winbool (int), NOT boolean (unsigned char)! + + /** + * Windows Object-Handle (used for accessing TAP and STDIN/STDOUT) + */ + HANDLE handle; + + /** + * Overlaped IO structure used for asynchronous IO in windows. + */ + OVERLAPPED overlapped; + + /** + * Buffer for reading things to and writing from... + */ + unsigned char buffer[MAX_SIZE]; + + /** + * How much of this buffer was used when reading or how much data can be written + */ + DWORD buffer_size; + + /** + * Amount of data actually written or read by readfile/writefile. + */ + DWORD buffer_size_processed; + + /** + * How much of this buffer we have writte in total + */ + DWORD buffer_size_written; +}; + +/** + * ReOpenFile is only available as of XP SP2 and 2003 SP1 + */ +WINBASEAPI HANDLE WINAPI ReOpenFile (HANDLE, DWORD, DWORD, DWORD); + +/** + * IsWow64Process definition for our is_win64, as this is a kernel function + */ +typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); + +/** + * Determines if the host OS is win32 or win64 + * + * @return true if + */ +BOOL +is_win64 () +{ +#if defined(_WIN64) + //this is a win64 binary, + return TRUE; +#elif defined(_WIN32) + //this is a 32bit binary, and we need to check if we are running in WOW64 + BOOL success = FALSE; + BOOL on_wow64 = FALSE; + LPFN_ISWOW64PROCESS IsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress (GetModuleHandle ("kernel32"), "IsWow64Process"); + + if (NULL != IsWow64Process) + success = IsWow64Process (GetCurrentProcess (), &on_wow64); + + return success && on_wow64; +#endif +} +/** + * Wrapper for executing a shellcommand in windows. + * + * @param command - the command + parameters to execute + * @return * exitcode of the program executed, + * * EINVAL (cmd/file not found) + * * EPIPE (could not read STDOUT) + */ +static int +execute_shellcommand (const char *command) +{ + FILE *pipe; + + if ( (NULL == command) || + (NULL == (pipe = _popen (command, "rt"))) ) + return EINVAL; + +#if DEBUG + fprintf (stderr, "DEBUG: Command output: \n"); + char output[LINE_LEN]; + while (NULL != fgets (output, sizeof (output), pipe)) + fprintf (stderr, "%s", output); +#endif + + return _pclose (pipe); +} + + +/** + * @brief Sets the IPv6-Address given in address on the interface dev + * + * @param address the IPv6-Address + * @param prefix_len the length of the network-prefix + */ +static int +set_address6 (const char *address, unsigned long prefix_len) +{ + int ret = EINVAL; + char command[LINE_LEN]; + struct sockaddr_in6 sa6; + + /* + * parse the new address + */ + memset (&sa6, 0, sizeof (struct sockaddr_in6)); + sa6.sin6_family = AF_INET6; + if (1 != inet_pton (AF_INET6, address, &sa6.sin6_addr.s6_addr)) + { + fprintf (stderr, "ERROR: Failed to parse address `%s': %s\n", address, + strerror (errno)); + return -1; + } + + /* + * prepare the command + */ + snprintf (command, LINE_LEN, + "netsh interface ipv6 add address \"%s\" %s/%d store=active", + device_visible_name, address, prefix_len); + /* + * Set the address + */ + ret = execute_shellcommand (command); + + /* Did it work?*/ + if (0 != ret) + fprintf (stderr, "FATAL: Setting IPv6 address failed: %s\n", strerror (ret)); + return ret; +} + + +/** + * @brief Removes the IPv6-Address given in address from the interface dev + * + * @param dev the interface to remove + * @param address the IPv4-Address + * @param mask the netmask + */ +static void +remove_address6 (const char *address) +{ + char command[LINE_LEN]; + int ret = EINVAL; + + // sanity checking was already done in set_address6 + /* + * prepare the command + */ + snprintf (command, LINE_LEN, + "netsh interface ipv6 delete address \"%s\" store=persistent", + device_visible_name, address); + /* + * Set the address + */ + ret = execute_shellcommand (command); + + /* Did it work?*/ + if (0 != ret) + fprintf (stderr, "FATAL: removing IPv6 address failed: %s\n", strerror (ret)); +} + + +/** + * @brief Sets the IPv4-Address given in address on the interface dev + * + * @param dev the interface to configure + * @param address the IPv4-Address + * @param mask the netmask + */ +static int +set_address4 (const char *address, const char *mask) +{ + int ret = EINVAL; + char command[LINE_LEN]; + + struct sockaddr_in addr; + addr.sin_family = AF_INET; + + /* + * Parse the address + */ + if (1 != inet_pton (AF_INET, address, &addr.sin_addr.s_addr)) + { + fprintf (stderr, "ERROR: Failed to parse address `%s': %s\n", address, + strerror (errno)); + return -1; + } + // Set Device to Subnet-Mode? + // do we really need tun.c:2925 ? + + /* + * prepare the command + */ + snprintf (command, LINE_LEN, + "netsh interface ipv4 add address \"%s\" %s %s store=active", + device_visible_name, address, mask); + /* + * Set the address + */ + ret = execute_shellcommand (command); + + /* Did it work?*/ + if (0 != ret) + fprintf (stderr, "FATAL: Setting IPv4 address failed: %s\n", strerror (ret)); + return ret; +} + + +/** + * @brief Removes the IPv4-Address given in address from the interface dev + * + * @param dev the interface to remove + * @param address the IPv4-Address + * @param mask the netmask + */ +static void +remove_address4 (const char *address) +{ + char command[LINE_LEN]; + int ret = EINVAL; + + // sanity checking was already done in set_address4 + + /* + * prepare the command + */ + snprintf (command, LINE_LEN, + "netsh interface ipv4 delete address \"%s\" gateway=all store=persistent", + device_visible_name, address); + /* + * Set the address + */ + ret = execute_shellcommand (command); + + /* Did it work?*/ + if (0 != ret) + fprintf (stderr, "FATAL: removing IPv4 address failed: %s\n", strerror (ret)); +} + + +/** + * Setup a new virtual interface to use for tunneling. + * + * @return: TRUE if setup was successful, else FALSE + */ +static BOOL +setup_interface () +{ + /* + * where to find our inf-file. (+ the "full" path, after windows found") + * + * We do not directly input all the props here, because openvpn will update + * these details over time. + */ + char inf_file_path[MAX_PATH]; + char * temp_inf_filename; + char hwidlist[LINE_LEN + 4]; + char class_name[128]; + GUID class_guid; + int str_length = 0; + + /** + * Set the device's hardware ID and add it to a list. + * This information will later on identify this device in registry. + */ + strncpy (hwidlist, HARDWARE_ID, LINE_LEN); + /** + * this is kind of over-complicated, but allows keeps things independent of + * how the openvpn-hwid is actually stored. + * + * A HWID list is double-\0 terminated and \0 separated + */ + str_length = strlen (hwidlist) + 1; + strncpy (&hwidlist[str_length], secondary_hwid, LINE_LEN); + str_length += strlen (&hwidlist[str_length]) + 1; + + /** + * Locate the inf-file, we need to store it somewhere where the system can + * find it. We need to pick the correct driver for win32/win64. + */ + if (is_win64()) + GetFullPathNameA (INF_FILE64, MAX_PATH, inf_file_path, &temp_inf_filename); + else + GetFullPathNameA (INF_FILE, MAX_PATH, inf_file_path, &temp_inf_filename); + + fprintf (stderr, "INFO: Located our driver's .inf file at %s\n", inf_file_path); + /** + * Bootstrap our device info using the drivers inf-file + */ + if ( ! SetupDiGetINFClassA (inf_file_path, + &class_guid, + class_name, sizeof (class_name) / sizeof (char), + NULL)) + return FALSE; + + /** + * Collect all the other needed information... + * let the system fill our this form + */ + DeviceInfo = SetupDiCreateDeviceInfoList (&class_guid, NULL); + if (DeviceInfo == INVALID_HANDLE_VALUE) + return FALSE; + + DeviceNode.cbSize = sizeof (SP_DEVINFO_DATA); + if ( ! SetupDiCreateDeviceInfoA (DeviceInfo, + class_name, + &class_guid, + NULL, + 0, + DICD_GENERATE_ID, + &DeviceNode)) + return FALSE; + + /* Deploy all the information collected into the registry */ + if ( ! SetupDiSetDeviceRegistryPropertyA (DeviceInfo, + &DeviceNode, + SPDRP_HARDWAREID, + (LPBYTE) hwidlist, + str_length * sizeof (char))) + return FALSE; + + /* Install our new class(=device) into the system */ + if ( ! SetupDiCallClassInstaller (DIF_REGISTERDEVICE, + DeviceInfo, + &DeviceNode)) + return FALSE; + + /* This system call tends to take a while (several seconds!) on + "modern" Windoze systems */ + if ( ! UpdateDriverForPlugAndPlayDevicesA (NULL, + secondary_hwid, + inf_file_path, + INSTALLFLAG_FORCE | INSTALLFLAG_NONINTERACTIVE, + NULL)) //reboot required? NEVER! + return FALSE; + + fprintf (stderr, "DEBUG: successfully created a network device\n"); + return TRUE; +} + + +/** + * Remove our new virtual interface to use for tunneling. + * This function must be called AFTER setup_interface! + * + * @return: TRUE if destruction was successful, else FALSE + */ +static BOOL +remove_interface () +{ + SP_REMOVEDEVICE_PARAMS remove; + + if (INVALID_HANDLE_VALUE == DeviceInfo) + return FALSE; + + remove.ClassInstallHeader.cbSize = sizeof (SP_CLASSINSTALL_HEADER); + remove.HwProfile = 0; + remove.Scope = DI_REMOVEDEVICE_GLOBAL; + remove.ClassInstallHeader.InstallFunction = DIF_REMOVE; + /* + * 1. Prepare our existing device information set, and place the + * uninstall related information into the structure + */ + if ( ! SetupDiSetClassInstallParamsA (DeviceInfo, + (PSP_DEVINFO_DATA) & DeviceNode, + &remove.ClassInstallHeader, + sizeof (remove))) + return FALSE; + /* + * 2. Uninstall the virtual interface using the class installer + */ + if ( ! SetupDiCallClassInstaller (DIF_REMOVE, + DeviceInfo, + (PSP_DEVINFO_DATA) & DeviceNode)) + return FALSE; + + SetupDiDestroyDeviceInfoList (DeviceInfo); + + fprintf (stderr, "DEBUG: removed interface successfully\n"); + + return TRUE; +} + + +/** + * Do all the lookup necessary to retrieve the inteface's actual name + * off the registry. + * + * @return: TRUE if we were able to lookup the interface's name, else FALSE + */ +static BOOL +resolve_interface_name () +{ + SP_DEVINFO_LIST_DETAIL_DATA device_details; + char pnp_instance_id [MAX_DEVICE_ID_LEN]; + HKEY adapter_key_handle; + LONG status; + DWORD len; + int i = 0; + int retrys; + BOOL retval = FALSE; + char adapter[] = INTERFACE_REGISTRY_LOCATION; + + /* We can obtain the PNP instance ID from our setupapi handle */ + device_details.cbSize = sizeof (device_details); + if (CR_SUCCESS != CM_Get_Device_ID_ExA (DeviceNode.DevInst, + (PCHAR) pnp_instance_id, + MAX_DEVICE_ID_LEN, + 0, //must be 0 + NULL)) //hMachine, we are local + return FALSE; + + fprintf (stderr, "DEBUG: Resolving interface name for network device %s\n",pnp_instance_id); + + /* Registry is incredibly slow, retry for up to 30 seconds to allow registry to refresh */ + for (retrys = 0; retrys < 120 && !retval; retrys++) + { + /* sleep for 250ms*/ + Sleep (250); + + /* Now we can use this ID to locate the correct networks interface in registry */ + if (ERROR_SUCCESS != RegOpenKeyExA ( + HKEY_LOCAL_MACHINE, + adapter, + 0, + KEY_READ, + &adapter_key_handle)) + return FALSE; + + /* Of course there is a multitude of entries here, with arbitrary names, + * thus we need to iterate through there. + */ + while (!retval) + { + char instance_key[256]; + char query_key [256]; + HKEY instance_key_handle; + char pnpinstanceid_name[] = "PnpInstanceID"; + char pnpinstanceid_value[256]; + char adaptername_name[] = "Name"; + DWORD data_type; + + len = 256 * sizeof (char); + /* optain a subkey of {4D36E972-E325-11CE-BFC1-08002BE10318} */ + status = RegEnumKeyExA ( + adapter_key_handle, + i, + instance_key, + &len, + NULL, + NULL, + NULL, + NULL); + + /* this may fail due to one of two reasons: + * we are at the end of the list*/ + if (ERROR_NO_MORE_ITEMS == status) + break; + // * we found a broken registry key, continue with the next key. + if (ERROR_SUCCESS != status) + goto cleanup; + + /* prepare our new query string: */ + snprintf (query_key, 256, "%s\\%s\\Connection", + adapter, + instance_key); + + /* look inside instance_key\\Connection */ + if (ERROR_SUCCESS != RegOpenKeyExA ( + HKEY_LOCAL_MACHINE, + query_key, + 0, + KEY_READ, + &instance_key_handle)) + goto cleanup; + + /* now, read our PnpInstanceID */ + len = sizeof (pnpinstanceid_value); + status = RegQueryValueExA (instance_key_handle, + pnpinstanceid_name, + NULL, //reserved, always NULL according to MSDN + &data_type, + (LPBYTE) pnpinstanceid_value, + &len); + + if (status != ERROR_SUCCESS || data_type != REG_SZ) + goto cleanup; + + /* compare the value we got to our devices PNPInstanceID*/ + if (0 != strncmp (pnpinstanceid_value, pnp_instance_id, + sizeof (pnpinstanceid_value) / sizeof (char))) + goto cleanup; + + len = sizeof (device_visible_name); + status = RegQueryValueExA ( + instance_key_handle, + adaptername_name, + NULL, //reserved, always NULL according to MSDN + &data_type, + (LPBYTE) device_visible_name, + &len); + + if (status != ERROR_SUCCESS || data_type != REG_SZ) + goto cleanup; + + /* + * we have successfully found OUR instance, + * save the device GUID before exiting + */ + + strncpy (device_guid, instance_key, 256); + retval = TRUE; + fprintf (stderr, "DEBUG: Interface Name lookup succeeded on retry %d, got \"%s\" %s\n", retrys, device_visible_name, device_guid); + +cleanup: + RegCloseKey (instance_key_handle); + + ++i; + } + + RegCloseKey (adapter_key_handle); + } + return retval; +} + + +/** + * Determines the version of the installed TAP32 driver and checks if it's sufficiently new for GNUNET + * + * @param handle the handle to our tap device + * @return TRUE if the version is sufficient, else FALSE + */ +static BOOL +check_tapw32_version (HANDLE handle) +{ + ULONG version[3]; + DWORD len; + memset (&(version), 0, sizeof (version)); + + if (DeviceIoControl (handle, TAP_WIN_IOCTL_GET_VERSION, + &version, sizeof (version), + &version, sizeof (version), &len, NULL)) + fprintf (stderr, "INFO: TAP-Windows Driver Version %d.%d %s\n", + (int) version[0], + (int) version[1], + (version[2] ? "(DEBUG)" : "")); + + if ((version[0] != TAP_WIN_MIN_MAJOR) || + (version[1] < TAP_WIN_MIN_MINOR )){ + fprintf (stderr, "FATAL: This version of gnunet requires a TAP-Windows driver that is at least version %d.%d\n", + TAP_WIN_MIN_MAJOR, + TAP_WIN_MIN_MINOR); + return FALSE; + } + + return TRUE; +} + + +/** + * Creates a tun-interface called dev; + * + * @return the fd to the tun or -1 on error + */ +static HANDLE +init_tun () +{ + char device_path[256]; + HANDLE handle; + + if (! setup_interface ()) + { + errno = ENODEV; + return INVALID_HANDLE_VALUE; + } + + if (! resolve_interface_name ()) + { + errno = ENODEV; + return INVALID_HANDLE_VALUE; + } + + /* Open Windows TAP-Windows adapter */ + snprintf (device_path, sizeof (device_path), "%s%s%s", + USERMODEDEVICEDIR, + device_guid, + TAP_WIN_SUFFIX); + + handle = CreateFile ( + device_path, + GENERIC_READ | GENERIC_WRITE, + 0, /* was: FILE_SHARE_READ */ + 0, + OPEN_EXISTING, + FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, + 0 + ); + + if (INVALID_HANDLE_VALUE == handle) + { + fprintf (stderr, "FATAL: CreateFile failed on TAP device: %s\n", device_path); + return handle; + } + + /* get driver version info */ + if (! check_tapw32_version (handle)) + { + CloseHandle (handle); + return INVALID_HANDLE_VALUE; + } + + /* TODO (opt?): get MTU-Size */ + + fprintf (stderr, "DEBUG: successfully opened TAP device\n"); + return handle; +} + + +/** + * Brings a TAP device up and sets it to connected state. + * + * @param handle the handle to our TAP device + * @return True if the operation succeeded, else false + */ +static BOOL +tun_up (HANDLE handle) +{ + ULONG status = TRUE; + DWORD len; + if (! DeviceIoControl (handle, TAP_WIN_IOCTL_SET_MEDIA_STATUS, + &status, sizeof (status), + &status, sizeof (status), &len, NULL)) + { + fprintf (stderr, "FATAL: TAP driver ignored request to UP interface (DeviceIoControl call)\n"); + return FALSE; + } + + /* Wait for the device to go UP, might take some time. */ + Sleep (TAP32_POSTUP_WAITTIME * 1000); + fprintf (stderr, "DEBUG: successfully set TAP device to UP\n"); + + return TRUE; +} + + +/** + * Attempts to read off an input facility (tap or named pipe) in overlapped mode. + * + * 1. + * If the input facility is in IOSTATE_READY, it will issue a new read operation to the + * input handle. Then it goes into IOSTATE_QUEUED state. + * In case the read succeeded instantly the input facility enters 3. + * + * 2. + * If the input facility is in IOSTATE_QUEUED state, it will check if the queued read has finished already. + * If it has finished, go to state 3. + * If it has failed, set IOSTATE_FAILED + * + * 3. + * If the output facility is in state IOSTATE_READY, the read-buffer is copied to the output buffer. + * The input facility enters state IOSTATE_READY + * The output facility enters state IOSTATE_READY + * If the output facility is in state IOSTATE_QUEUED, the input facility enters IOSTATE_WAITING + * + * IOSTATE_WAITING is reset by the output facility, once it has completed. + * + * @param input_facility input named pipe or file to work with. + * @param output_facility output pipe or file to hand over data to. + * @return false if an event reset was impossible (OS error), else true + */ +static BOOL +attempt_read_tap (struct io_facility * input_facility, + struct io_facility * output_facility) +{ + struct GNUNET_MessageHeader * hdr; + unsigned short size; + + switch (input_facility->facility_state) + { + case IOSTATE_READY: + { + if (! ResetEvent (input_facility->overlapped.hEvent)) + { + return FALSE; + } + + input_facility->buffer_size = 0; + + /* Check how the task is handled */ + if (ReadFile (input_facility->handle, + input_facility->buffer, + sizeof (input_facility->buffer) - sizeof (struct GNUNET_MessageHeader), + &input_facility->buffer_size, + &input_facility->overlapped)) + {/* async event processed immediately*/ + + /* reset event manually*/ + if (! SetEvent (input_facility->overlapped.hEvent)) + return FALSE; + + fprintf (stderr, "DEBUG: tap read succeeded immediately\n"); + + /* we successfully read something from the TAP and now need to + * send it our via STDOUT. Is that possible at the moment? */ + if ((IOSTATE_READY == output_facility->facility_state || + IOSTATE_WAITING == output_facility->facility_state) + && (0 < input_facility->buffer_size)) + { /* hand over this buffers content and apply message header for gnunet */ + hdr = (struct GNUNET_MessageHeader *) output_facility->buffer; + size = input_facility->buffer_size + sizeof (struct GNUNET_MessageHeader); + + memcpy (output_facility->buffer + sizeof (struct GNUNET_MessageHeader), + input_facility->buffer, + input_facility->buffer_size); + + output_facility->buffer_size = size; + hdr->size = htons (size); + hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); + output_facility->facility_state = IOSTATE_READY; + } + else if (0 < input_facility->buffer_size) + /* If we have have read our buffer, wait for our write-partner*/ + input_facility->facility_state = IOSTATE_WAITING; + } + else /* operation was either queued or failed*/ + { + int err = GetLastError (); + if (ERROR_IO_PENDING == err) + { /* operation queued */ + input_facility->facility_state = IOSTATE_QUEUED; + } + else + { /* error occurred, let the rest of the elements finish */ + input_facility->path_open = FALSE; + input_facility->facility_state = IOSTATE_FAILED; + if (IOSTATE_WAITING == output_facility->facility_state) + output_facility->path_open = FALSE; + + fprintf (stderr, "FATAL: Read from handle failed, allowing write to finish\n"); + } + } + } + return TRUE; + // We are queued and should check if the read has finished + case IOSTATE_QUEUED: + { + // there was an operation going on already, check if that has completed now. + + if (GetOverlappedResult (input_facility->handle, + &input_facility->overlapped, + &input_facility->buffer_size, + FALSE)) + {/* successful return for a queued operation */ + if (! ResetEvent (input_facility->overlapped.hEvent)) + return FALSE; + + fprintf (stderr, "DEBUG: tap read succeeded delayed\n"); + + /* we successfully read something from the TAP and now need to + * send it our via STDOUT. Is that possible at the moment? */ + if ((IOSTATE_READY == output_facility->facility_state || + IOSTATE_WAITING == output_facility->facility_state) + && 0 < input_facility->buffer_size) + { /* hand over this buffers content and apply message header for gnunet */ + hdr = (struct GNUNET_MessageHeader *) output_facility->buffer; + size = input_facility->buffer_size + sizeof (struct GNUNET_MessageHeader); + + memcpy (output_facility->buffer + sizeof (struct GNUNET_MessageHeader), + input_facility->buffer, + input_facility->buffer_size); + + output_facility->buffer_size = size; + hdr->size = htons(size); + hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); + output_facility->facility_state = IOSTATE_READY; + input_facility->facility_state = IOSTATE_READY; + } + else if (0 < input_facility->buffer_size) + { /* If we have have read our buffer, wait for our write-partner*/ + input_facility->facility_state = IOSTATE_WAITING; + // TODO: shall we attempt to fill our buffer or should we wait for our write-partner to finish? + } + } + else + { /* operation still pending/queued or failed? */ + int err = GetLastError (); + if ((ERROR_IO_INCOMPLETE != err) && (ERROR_IO_PENDING != err)) + { /* error occurred, let the rest of the elements finish */ + input_facility->path_open = FALSE; + input_facility->facility_state = IOSTATE_FAILED; + if (IOSTATE_WAITING == output_facility->facility_state) + output_facility->path_open = FALSE; + fprintf (stderr, "FATAL: Read from handle failed, allowing write to finish\n"); + } + } + } + return TRUE; + case IOSTATE_RESUME: + hdr = (struct GNUNET_MessageHeader *) output_facility->buffer; + size = input_facility->buffer_size + sizeof (struct GNUNET_MessageHeader); + + memcpy (output_facility->buffer + sizeof (struct GNUNET_MessageHeader), + input_facility->buffer, + input_facility->buffer_size); + + output_facility->buffer_size = size; + hdr->size = htons (size); + hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); + output_facility->facility_state = IOSTATE_READY; + input_facility->facility_state = IOSTATE_READY; + return TRUE; + default: + return TRUE; + } +} + + +/** + * Attempts to read off an input facility (tap or named pipe) in overlapped mode. + * + * 1. + * If the input facility is in IOSTATE_READY, it will issue a new read operation to the + * input handle. Then it goes into IOSTATE_QUEUED state. + * In case the read succeeded instantly the input facility enters 3. + * + * 2. + * If the input facility is in IOSTATE_QUEUED state, it will check if the queued read has finished already. + * If it has finished, go to state 3. + * If it has failed, set IOSTATE_FAILED + * + * 3. + * If the facility is finished with ready + * The read-buffer is copied to the output buffer, except for the GNUNET_MessageHeader. + * The input facility enters state IOSTATE_READY + * The output facility enters state IOSTATE_READY + * If the output facility is in state IOSTATE_QUEUED, the input facility enters IOSTATE_WAITING + * + * IOSTATE_WAITING is reset by the output facility, once it has completed. + * + * @param input_facility input named pipe or file to work with. + * @param output_facility output pipe or file to hand over data to. + * @return false if an event reset was impossible (OS error), else true + */ +static BOOL +attempt_read_stdin (struct io_facility * input_facility, + struct io_facility * output_facility) +{ + struct GNUNET_MessageHeader * hdr; + + switch (input_facility->facility_state) + { + case IOSTATE_READY: + { + input_facility->buffer_size = 0; + +partial_read_iostate_ready: + if (! ResetEvent (input_facility->overlapped.hEvent)) + return FALSE; + + /* Check how the task is handled */ + if (ReadFile (input_facility->handle, + input_facility->buffer + input_facility->buffer_size, + sizeof (input_facility->buffer) - input_facility->buffer_size, + &input_facility->buffer_size_processed, + &input_facility->overlapped)) + {/* async event processed immediately*/ + hdr = (struct GNUNET_MessageHeader *) input_facility->buffer; + + /* reset event manually*/ + if (!SetEvent (input_facility->overlapped.hEvent)) + return FALSE; + + fprintf (stderr, "DEBUG: stdin read succeeded immediately\n"); + input_facility->buffer_size += input_facility->buffer_size_processed; + + if (ntohs (hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER || + ntohs (hdr->size) > sizeof (input_facility->buffer)) + { + fprintf (stderr, "WARNING: Protocol violation, got GNUnet Message type %h, size %h\n", ntohs (hdr->type), ntohs (hdr->size)); + input_facility->facility_state = IOSTATE_READY; + return TRUE; + } + /* we got the a part of a packet */ + if (ntohs (hdr->size) > input_facility->buffer_size) + goto partial_read_iostate_ready; + + /* have we read more than 0 bytes of payload? (sizeread > header)*/ + if (input_facility->buffer_size > sizeof (struct GNUNET_MessageHeader) && + ((IOSTATE_READY == output_facility->facility_state) || + (IOSTATE_WAITING == output_facility->facility_state))) + {/* we successfully read something from the TAP and now need to + * send it our via STDOUT. Is that possible at the moment? */ + + /* hand over this buffers content and strip gnunet message header */ + memcpy (output_facility->buffer, + input_facility->buffer + sizeof (struct GNUNET_MessageHeader), + input_facility->buffer_size - sizeof (struct GNUNET_MessageHeader)); + output_facility->buffer_size = input_facility->buffer_size - sizeof (struct GNUNET_MessageHeader); + output_facility->facility_state = IOSTATE_READY; + input_facility->facility_state = IOSTATE_READY; + } + else if (input_facility->buffer_size > sizeof (struct GNUNET_MessageHeader)) + /* If we have have read our buffer, wait for our write-partner*/ + input_facility->facility_state = IOSTATE_WAITING; + else /* we read nothing */ + input_facility->facility_state = IOSTATE_READY; + } + else /* operation was either queued or failed*/ + { + int err = GetLastError (); + if (ERROR_IO_PENDING == err) /* operation queued */ + input_facility->facility_state = IOSTATE_QUEUED; + else + { /* error occurred, let the rest of the elements finish */ + input_facility->path_open = FALSE; + input_facility->facility_state = IOSTATE_FAILED; + if (IOSTATE_WAITING == output_facility->facility_state) + output_facility->path_open = FALSE; + + fprintf (stderr, "FATAL: Read from handle failed, allowing write to finish\n"); + } + } + } + return TRUE; + // We are queued and should check if the read has finished + case IOSTATE_QUEUED: + { + // there was an operation going on already, check if that has completed now. + if (GetOverlappedResult (input_facility->handle, + &input_facility->overlapped, + &input_facility->buffer_size_processed, + FALSE)) + {/* successful return for a queued operation */ + hdr = (struct GNUNET_MessageHeader *) input_facility->buffer; + + if (! ResetEvent (input_facility->overlapped.hEvent)) + return FALSE; + + fprintf (stderr, "DEBUG: stdin read succeeded delayed\n"); + input_facility->buffer_size += input_facility->buffer_size_processed; + + if ((ntohs (hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) || + (ntohs (hdr->size) > sizeof (input_facility->buffer))) + { + fprintf (stderr, "WARNING: Protocol violation, got GNUnet Message type %h, size %h\n", ntohs (hdr->type), ntohs (hdr->size)); + input_facility->facility_state = IOSTATE_READY; + return TRUE; + } + /* we got the a part of a packet */ + if (ntohs (hdr->size) > input_facility->buffer_size ); + goto partial_read_iostate_ready; + + /* we successfully read something from the TAP and now need to + * send it our via STDOUT. Is that possible at the moment? */ + if ((IOSTATE_READY == output_facility->facility_state || + IOSTATE_WAITING == output_facility->facility_state) + && input_facility->buffer_size > sizeof(struct GNUNET_MessageHeader)) + { /* hand over this buffers content and strip gnunet message header */ + memcpy (output_facility->buffer, + input_facility->buffer + sizeof(struct GNUNET_MessageHeader), + input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader)); + output_facility->buffer_size = input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader); + output_facility->facility_state = IOSTATE_READY; + input_facility->facility_state = IOSTATE_READY; + } + else if (input_facility->buffer_size > sizeof(struct GNUNET_MessageHeader)) + input_facility->facility_state = IOSTATE_WAITING; + else + input_facility->facility_state = IOSTATE_READY; + } + else + { /* operation still pending/queued or failed? */ + int err = GetLastError (); + if ((ERROR_IO_INCOMPLETE != err) && (ERROR_IO_PENDING != err)) + { /* error occurred, let the rest of the elements finish */ + input_facility->path_open = FALSE; + input_facility->facility_state = IOSTATE_FAILED; + if (IOSTATE_WAITING == output_facility->facility_state) + output_facility->path_open = FALSE; + fprintf (stderr, "FATAL: Read from handle failed, allowing write to finish\n"); + } + } + } + return TRUE; + case IOSTATE_RESUME: /* Our buffer was filled already but our write facility was busy. */ + memcpy (output_facility->buffer, + input_facility->buffer + sizeof (struct GNUNET_MessageHeader), + input_facility->buffer_size - sizeof (struct GNUNET_MessageHeader)); + output_facility->buffer_size = input_facility->buffer_size - sizeof (struct GNUNET_MessageHeader); + output_facility->facility_state = IOSTATE_READY; + input_facility->facility_state = IOSTATE_READY; + return TRUE; + default: + return TRUE; + } +} + + +/** + * Attempts to write to an output facility (tap or named pipe) in overlapped mode. + * + * TODO: high level description + * + * @param output_facility output pipe or file to hand over data to. + * @param input_facility input named pipe or file to work with. + * @return false if an event reset was impossible (OS error), else true + */ +static BOOL +attempt_write (struct io_facility * output_facility, + struct io_facility * input_facility) +{ + switch (output_facility->facility_state) + { + case IOSTATE_READY: + output_facility->buffer_size_written = 0; + +continue_partial_write: + if (! ResetEvent (output_facility->overlapped.hEvent)) + return FALSE; + + /* Check how the task was handled */ + if (WriteFile (output_facility->handle, + output_facility->buffer + output_facility->buffer_size_written, + output_facility->buffer_size - output_facility->buffer_size_written, + &output_facility->buffer_size_processed, + &output_facility->overlapped)) + {/* async event processed immediately*/ + + fprintf (stderr, "DEBUG: write succeeded immediately\n"); + output_facility->buffer_size_written += output_facility->buffer_size_processed; + + /* reset event manually*/ + if (! SetEvent (output_facility->overlapped.hEvent)) + return FALSE; + + /* partial write */ + if (output_facility->buffer_size_written < output_facility->buffer_size) + goto continue_partial_write; + + /* we are now waiting for our buffer to be filled*/ + output_facility->facility_state = IOSTATE_WAITING; + + /* we successfully wrote something and now need to reset our reader */ + if (IOSTATE_WAITING == input_facility->facility_state) + input_facility->facility_state = IOSTATE_RESUME; + else if (IOSTATE_FAILED == input_facility->facility_state) + output_facility->path_open = FALSE; + } + else /* operation was either queued or failed*/ + { + int err = GetLastError (); + if (ERROR_IO_PENDING == err) + { /* operation queued */ + output_facility->facility_state = IOSTATE_QUEUED; + } + else + { /* error occurred, close this path */ + output_facility->path_open = FALSE; + output_facility->facility_state = IOSTATE_FAILED; + fprintf (stderr, "FATAL: Write to handle failed, exiting\n"); + } + } + return TRUE; + case IOSTATE_QUEUED: + // there was an operation going on already, check if that has completed now. + + if (GetOverlappedResult (output_facility->handle, + &output_facility->overlapped, + &output_facility->buffer_size_processed, + FALSE)) + {/* successful return for a queued operation */ + if (! ResetEvent (output_facility->overlapped.hEvent)) + return FALSE; + + fprintf (stderr, "DEBUG: write succeeded delayed\n"); + output_facility->buffer_size_written += output_facility->buffer_size_processed; + + /* partial write */ + if (output_facility->buffer_size_written < output_facility->buffer_size) + goto continue_partial_write; + + /* we are now waiting for our buffer to be filled*/ + output_facility->facility_state = IOSTATE_WAITING; + + /* we successfully wrote something and now need to reset our reader */ + if (IOSTATE_WAITING == input_facility->facility_state) + input_facility->facility_state = IOSTATE_RESUME; + else if (IOSTATE_FAILED == input_facility->facility_state) + output_facility->path_open = FALSE; + } + else + { /* operation still pending/queued or failed? */ + int err = GetLastError (); + if ((ERROR_IO_INCOMPLETE != err) && (ERROR_IO_PENDING != err)) + { /* error occurred, close this path */ + output_facility->path_open = FALSE; + output_facility->facility_state = IOSTATE_FAILED; + fprintf (stderr, "FATAL: Write to handle failed, exiting\n"); + } + } + default: + return TRUE; + } +} + + +/** + * Initialize a overlapped structure + * + * @param elem the element to initilize + * @param initial_state the initial state for this instance + * @param signaled if the hEvent created should default to signaled or not + * @return true on success, else false + */ +static BOOL +initialize_io_facility (struct io_facility * elem, + int initial_state, + BOOL signaled) +{ + elem->path_open = TRUE; + elem->handle = INVALID_HANDLE_VALUE; + elem->facility_state = initial_state; + elem->buffer_size = 0; + elem->overlapped.hEvent = CreateEvent (NULL, TRUE, signaled, NULL); + if (NULL == elem->overlapped.hEvent) + return FALSE; + + return TRUE; +} + + +/** + * Start forwarding to and from the tunnel. + * + * @param fd_tun tunnel FD + */ +static void +run (HANDLE tap_handle) +{ + /* IO-Facility for reading from our virtual interface */ + struct io_facility tap_read; + /* IO-Facility for writing to our virtual interface */ + struct io_facility tap_write; + /* IO-Facility for reading from stdin */ + struct io_facility std_in; + /* IO-Facility for writing to stdout */ + struct io_facility std_out; + + HANDLE parent_std_in_handle = GetStdHandle (STD_INPUT_HANDLE); + HANDLE parent_std_out_handle = GetStdHandle (STD_OUTPUT_HANDLE); + + /* tun up: */ + /* we do this HERE and not beforehand (in init_tun()), in contrast to openvpn + * to remove the need to flush the arp cache, handle DHCP and wrong IPs. + * + * DHCP and such are all features we will never use in gnunet afaik. + * But for openvpn those are essential. + */ + if (! tun_up (tap_handle)) + return; + + /* Initialize our overlapped IO structures*/ + if (! (initialize_io_facility (&tap_read, IOSTATE_READY, FALSE) + && initialize_io_facility (&tap_write, IOSTATE_WAITING, TRUE) + && initialize_io_facility (&std_in, IOSTATE_READY, FALSE) + && initialize_io_facility (&std_out, IOSTATE_WAITING, TRUE))) + goto teardown_final; + + /* Handles for STDIN and STDOUT */ + tap_read.handle = tap_handle; + tap_write.handle = tap_handle; + +#ifdef DEBUG_TO_CONSOLE + /* Debug output to console STDIN/STDOUT*/ + std_in.handle = parent_std_in_handle; + std_out.handle = parent_std_out_handle; + +#else + fprintf (stderr, "DEBUG: reopening stdin/out for overlapped IO\n"); + /* + * Find out the types of our handles. + * This part is a problem, because in windows we need to handle files, + * pipes and the console differently. + */ + if ((FILE_TYPE_PIPE != GetFileType (parent_std_in_handle)) || + (FILE_TYPE_PIPE != GetFileType (parent_std_out_handle))) + { + fprintf (stderr, "ERROR: stdin/stdout must be named pipes\n"); + goto teardown; + } + + std_in.handle = ReOpenFile (parent_std_in_handle, + GENERIC_READ, + FILE_SHARE_WRITE | FILE_SHARE_READ, + FILE_FLAG_OVERLAPPED); + + if (INVALID_HANDLE_VALUE == std_in.handle) + { + fprintf (stderr, "FATAL: Could not reopen stdin for in overlapped mode, has to be a named pipe\n"); + goto teardown; + } + + std_out.handle = ReOpenFile (parent_std_out_handle, + GENERIC_WRITE, + FILE_SHARE_READ, + FILE_FLAG_OVERLAPPED); + + if (INVALID_HANDLE_VALUE == std_out.handle) + { + fprintf (stderr, "FATAL: Could not reopen stdout for in overlapped mode, has to be a named pipe\n"); + goto teardown; + } +#endif + + fprintf (stderr, "DEBUG: mainloop has begun\n"); + + while (std_out.path_open || tap_write.path_open) + { + /* perform READ from stdin if possible */ + if (std_in.path_open && (! attempt_read_stdin (&std_in, &tap_write))) + break; + + /* perform READ from tap if possible */ + if (tap_read.path_open && (! attempt_read_tap (&tap_read, &std_out))) + break; + + /* perform WRITE to tap if possible */ + if (tap_write.path_open && (! attempt_write (&tap_write, &std_in))) + break; + + /* perform WRITE to STDOUT if possible */ + if (std_out.path_open && (! attempt_write (&std_out, &tap_read))) + break; + } + +teardown: + + fprintf (stderr, "DEBUG: teardown initiated\n"); + + CancelIo (tap_handle); + CancelIo (std_in.handle); + CancelIo (std_out.handle); + +teardown_final: + + CloseHandle (tap_handle); +} + + +/** + * Open VPN tunnel interface. + * + * @param argc must be 6 + * @param argv 0: binary name (gnunet-helper-vpn) + * 1: tunnel interface prefix (gnunet-vpn) + * 2: IPv6 address (::1), "-" to disable + * 3: IPv6 netmask length in bits (64), ignored if #2 is "-" + * 4: IPv4 address (1.2.3.4), "-" to disable + * 5: IPv4 netmask (255.255.0.0), ignored if #4 is "-" + */ +int +main (int argc, char **argv) +{ + char hwid[LINE_LEN]; + HANDLE handle; + int global_ret = 0; + BOOL have_ip4 = FALSE; + BOOL have_ip6 = FALSE; + + if (6 != argc) + { + fprintf (stderr, "FATAL: must supply 5 arguments\nUsage:\ngnunet-helper-vpn <if name prefix> <address6 or \"-\"> <netbits6> <address4 or \"-\"> <netmask4>\n", argv[0]); + return 1; + } + + strncpy (hwid, argv[1], LINE_LEN); + hwid[LINE_LEN - 1] = '\0'; + + /* + * We use our PID for finding/resolving the control-panel name of our virtual + * device. PIDs are (of course) unique at runtime, thus we can safely use it + * as additional hardware-id for our device. + */ + snprintf (secondary_hwid, LINE_LEN / 2, "%s-%d", + hwid, + _getpid ()); + + if (INVALID_HANDLE_VALUE == (handle = init_tun ())) + { + fprintf (stderr, "FATAL: could not initialize virtual-interface %s with IPv6 %s/%s and IPv4 %s/%s\n", + hwid, + argv[2], + argv[3], + argv[4], + argv[5]); + global_ret = -1; + goto cleanup; + } + + fprintf (stderr, "DEBUG: Setting IPs, if needed\n"); + if (0 != strcmp (argv[2], "-")) + { + const char *address = argv[2]; + long prefix_len = atol (argv[3]); + + if ((prefix_len < 1) || (prefix_len > 127)) + { + fprintf (stderr, "FATAL: ipv6 prefix_len out of range\n"); + global_ret = -1; + goto cleanup; + } + + fprintf (stderr, "DEBUG: Setting IP6 address: %s/%d\n",address,prefix_len); + if (0 != (global_ret = set_address6 (address, prefix_len))) + goto cleanup; + + have_ip6 = TRUE; + } + + if (0 != strcmp (argv[4], "-")) + { + const char *address = argv[4]; + const char *mask = argv[5]; + + fprintf (stderr, "DEBUG: Setting IP4 address: %s/%s\n",address,mask); + if (0 != (global_ret = set_address4 (address, mask))) + goto cleanup; + + have_ip4 = TRUE; + } + + run (handle); + global_ret = 0; +cleanup: + + if (have_ip4) + { + const char *address = argv[4]; + fprintf (stderr, "DEBUG: Removing IP4 address\n"); + remove_address4 (address); + } + if (have_ip6) + { + const char *address = argv[2]; + fprintf (stderr, "DEBUG: Removing IP6 address\n"); + remove_address6 (address); + } + + fprintf (stderr, "DEBUG: removing interface\n"); + remove_interface (); + fprintf (stderr, "DEBUG: graceful exit completed\n"); + + return global_ret; +} diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c index b7756a3..1a46f0b 100644 --- a/src/vpn/gnunet-service-vpn.c +++ b/src/vpn/gnunet-service-vpn.c @@ -35,6 +35,7 @@ #include "gnunet_statistics_service.h" #include "gnunet_constants.h" #include "gnunet_tun_lib.h" +#include "gnunet_regex_lib.h" #include "vpn.h" #include "exit.h" @@ -62,7 +63,7 @@ struct DestinationEntry * Key under which this entry is in the 'destination_map' (only valid * if 'heap_node != NULL'). */ - GNUNET_HashCode key; + struct GNUNET_HashCode key; /** * Pre-allocated tunnel for this destination, or NULL for none. @@ -91,7 +92,7 @@ struct DestinationEntry /** * The description of the service (only used for service tunnels). */ - GNUNET_HashCode service_descriptor; + struct GNUNET_HashCode service_descriptor; /** * Peer offering the service. @@ -371,7 +372,7 @@ static unsigned long long max_tunnel_mappings; static void get_destination_key_from_ip (int af, const void *address, - GNUNET_HashCode *key) + struct GNUNET_HashCode *key) { switch (af) { @@ -411,11 +412,11 @@ get_tunnel_key_from_ips (int af, uint16_t source_port, const void *destination_ip, uint16_t destination_port, - GNUNET_HashCode *key) + struct GNUNET_HashCode *key) { char *off; - memset (key, 0, sizeof (GNUNET_HashCode)); + memset (key, 0, sizeof (struct GNUNET_HashCode)); /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash, so we put the ports in there (and hope for few collisions) */ off = (char*) key; @@ -501,7 +502,7 @@ send_client_reply (struct GNUNET_SERVER_Client *client, static void free_tunnel_state (struct TunnelState *ts) { - GNUNET_HashCode key; + struct GNUNET_HashCode key; struct TunnelMessageQueueEntry *tnq; struct GNUNET_MESH_Tunnel *tunnel; @@ -689,7 +690,6 @@ send_to_peer_notify_callback (void *cls, size_t size, void *buf) if (NULL != (tnq = ts->tmq_head)) ts->th = GNUNET_MESH_notify_transmit_ready (ts->tunnel, GNUNET_NO /* cork */, - 42 /* priority */, GNUNET_TIME_UNIT_FOREVER_REL, NULL, tnq->len, @@ -742,7 +742,6 @@ send_to_tunnel (struct TunnelMessageQueueEntry *tnq, if (NULL == ts->th) ts->th = GNUNET_MESH_notify_transmit_ready (ts->tunnel, GNUNET_NO /* cork */, - 42 /* priority */, GNUNET_TIME_UNIT_FOREVER_REL, NULL, tnq->len, @@ -809,27 +808,45 @@ create_tunnel_to_destination (struct DestinationEntry *de, } else { + char *policy; + switch (de->details.exit_destination.af) { case AF_INET: - GNUNET_MESH_peer_request_connect_by_type (ts->tunnel, - GNUNET_APPLICATION_TYPE_IPV4_GATEWAY); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Creating tunnel to exit peer for %s\n", - "IPv4"); - break; + { + char address[GNUNET_REGEX_IPV4_REGEXLEN]; + GNUNET_REGEX_ipv4toregex (&de->details.exit_destination.ip.v4, + "255.255.255.255", address); + GNUNET_asprintf (&policy, "%s%s%s", + GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX, + "4", + address); + break; + } case AF_INET6: - GNUNET_MESH_peer_request_connect_by_type (ts->tunnel, - GNUNET_APPLICATION_TYPE_IPV6_GATEWAY); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Creating tunnel to exit peer for %s\n", - "IPv6"); + { + char address[GNUNET_REGEX_IPV6_REGEXLEN]; + GNUNET_REGEX_ipv6toregex (&de->details.exit_destination.ip.v6, + 128, address); + GNUNET_asprintf (&policy, "%s%s%s", + GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX, + "6", + address); break; + } default: GNUNET_assert (0); break; } - } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Requesting connect by string: %s\n", policy); + + GNUNET_MESH_peer_request_connect_by_string (ts->tunnel, policy); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Creating tunnel to exit peer for policy `%s'\n", + policy); + GNUNET_free (policy); + } return ts; } @@ -872,7 +889,7 @@ route_packet (struct DestinationEntry *destination, const void *payload, size_t payload_length) { - GNUNET_HashCode key; + struct GNUNET_HashCode key; struct TunnelState *ts; struct TunnelMessageQueueEntry *tnq; size_t alen; @@ -1510,7 +1527,7 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, { const struct GNUNET_TUN_Layer2PacketHeader *tun; size_t mlen; - GNUNET_HashCode key; + struct GNUNET_HashCode key; struct DestinationEntry *de; GNUNET_STATISTICS_update (stats, @@ -2336,7 +2353,7 @@ allocate_v4_address (struct in_addr *v4) struct in_addr addr; struct in_addr mask; struct in_addr rnd; - GNUNET_HashCode key; + struct GNUNET_HashCode key; unsigned int tries; GNUNET_assert (1 == inet_pton (AF_INET, ipv4addr, &addr)); @@ -2387,7 +2404,7 @@ allocate_v6_address (struct in6_addr *v6) struct in6_addr mask; struct in6_addr rnd; int i; - GNUNET_HashCode key; + struct GNUNET_HashCode key; unsigned int tries; GNUNET_assert (1 == inet_pton (AF_INET6, ipv6addr, &addr)); @@ -2564,7 +2581,7 @@ service_redirect_to_ip (void *cls GNUNET_UNUSED, struct GNUNET_SERVER_Client *cl struct in6_addr v6; void *addr; struct DestinationEntry *de; - GNUNET_HashCode key; + struct GNUNET_HashCode key; struct TunnelState *ts; /* validate and parse request */ @@ -2703,7 +2720,7 @@ service_redirect_to_service (void *cls GNUNET_UNUSED, struct GNUNET_SERVER_Clien struct in6_addr v6; void *addr; struct DestinationEntry *de; - GNUNET_HashCode key; + struct GNUNET_HashCode key; struct TunnelState *ts; /* parse request */ @@ -2835,7 +2852,7 @@ tunnel_cleaner (void *cls, const struct GNUNET_MESH_Tunnel *tunnel, void *tunnel */ static int cleanup_destination (void *cls, - const GNUNET_HashCode *key, + const struct GNUNET_HashCode *key, void *value) { struct DestinationEntry *de = value; @@ -2855,7 +2872,7 @@ cleanup_destination (void *cls, */ static int cleanup_tunnel (void *cls, - const GNUNET_HashCode *key, + const struct GNUNET_HashCode *key, void *value) { struct TunnelState *ts = value; @@ -2940,7 +2957,7 @@ cleanup (void *cls GNUNET_UNUSED, */ static int cleanup_tunnel_client (void *cls, - const GNUNET_HashCode *key, + const struct GNUNET_HashCode *key, void *value) { struct GNUNET_SERVER_Client *client = cls; @@ -2965,7 +2982,7 @@ cleanup_tunnel_client (void *cls, */ static int cleanup_destination_client (void *cls, - const GNUNET_HashCode *key, + const struct GNUNET_HashCode *key, void *value) { struct GNUNET_SERVER_Client *client = cls; @@ -3005,31 +3022,6 @@ client_disconnect (void *cls, struct GNUNET_SERVER_Client *client) /** - * Test if the given AF is supported by this system. - * - * @param af to test - * @return GNUNET_OK if the AF is supported - */ -static int -test_af (int af) -{ - int s; - - s = socket (af, SOCK_STREAM, 0); - if (-1 == s) - { - if (EAFNOSUPPORT == errno) - return GNUNET_NO; - GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, - "socket"); - return GNUNET_SYSERR; - } - close (s); - return GNUNET_OK; -} - - -/** * Main function that will be run by the scheduler. * * @param cls closure @@ -3065,16 +3057,21 @@ run (void *cls, char *ipv4mask; struct in_addr v4; struct in6_addr v6; + char *binary; + + binary = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-vpn"); if (GNUNET_YES != - GNUNET_OS_check_helper_binary ("gnunet-helper-vpn")) + GNUNET_OS_check_helper_binary (binary)) { fprintf (stderr, "`%s' is not SUID, refusing to run.\n", "gnunet-helper-vpn"); + GNUNET_free (binary); global_ret = 1; return; } + GNUNET_free (binary); cfg = cfg_; stats = GNUNET_STATISTICS_create ("vpn", cfg); if (GNUNET_OK != @@ -3086,9 +3083,9 @@ run (void *cls, &max_tunnel_mappings)) max_tunnel_mappings = 200; - destination_map = GNUNET_CONTAINER_multihashmap_create (max_destination_mappings * 2); + destination_map = GNUNET_CONTAINER_multihashmap_create (max_destination_mappings * 2, GNUNET_NO); destination_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); - tunnel_map = GNUNET_CONTAINER_multihashmap_create (max_tunnel_mappings * 2); + tunnel_map = GNUNET_CONTAINER_multihashmap_create (max_tunnel_mappings * 2, GNUNET_NO); tunnel_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); @@ -3102,7 +3099,7 @@ run (void *cls, return; } vpn_argv[1] = ifname; - if (GNUNET_OK == test_af (AF_INET6)) + if (GNUNET_OK == GNUNET_NETWORK_test_pf (PF_INET6)) { if ( (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6ADDR", @@ -3142,7 +3139,7 @@ run (void *cls, vpn_argv[2] = GNUNET_strdup ("-"); vpn_argv[3] = GNUNET_strdup ("-"); } - if (GNUNET_OK == test_af (AF_INET)) + if (GNUNET_OK == GNUNET_NETWORK_test_pf (PF_INET)) { if ( (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4ADDR", @@ -3177,13 +3174,14 @@ run (void *cls, vpn_argv[6] = NULL; mesh_handle = - GNUNET_MESH_connect (cfg_, 42 /* queue length */, NULL, + GNUNET_MESH_connect (cfg_, NULL, &inbound_tunnel_cb, &tunnel_cleaner, mesh_handlers, types); - helper_handle = GNUNET_HELPER_start ("gnunet-helper-vpn", vpn_argv, - &message_token, NULL); + helper_handle = GNUNET_HELPER_start (GNUNET_NO, + "gnunet-helper-vpn", vpn_argv, + &message_token, NULL, NULL); nc = GNUNET_SERVER_notification_context_create (server, 1); GNUNET_SERVER_add_handlers (server, service_handlers); GNUNET_SERVER_disconnect_notify (server, &client_disconnect, NULL); diff --git a/src/vpn/gnunet-vpn.c b/src/vpn/gnunet-vpn.c index ecc0442..6402e10 100644 --- a/src/vpn/gnunet-vpn.c +++ b/src/vpn/gnunet-vpn.c @@ -92,7 +92,7 @@ static int ret; /** * Option '-d': duration of the mapping */ -static unsigned long long duration = 5 * 60; +static struct GNUNET_TIME_Relative duration = { 5 * 60 * 1000} ; /** @@ -173,15 +173,14 @@ run (void *cls, char *const *args, const char *cfgfile, int dst_af; int req_af; struct GNUNET_PeerIdentity peer; - GNUNET_HashCode sd; + struct GNUNET_HashCode sd; const void *addr; struct in_addr v4; struct in6_addr v6; uint8_t protocol; struct GNUNET_TIME_Absolute etime; - etime = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, - (unsigned int) duration)); + etime = GNUNET_TIME_relative_to_absolute (duration); GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &do_disconnect, NULL); handle = GNUNET_VPN_connect (cfg); @@ -301,9 +300,9 @@ main (int argc, char *const *argv) {'a', "after-connect", NULL, gettext_noop ("print IP address only after mesh tunnel has been created"), 0, &GNUNET_GETOPT_set_one, &ipv6}, - {'d', "duration", "SECONDS", + {'d', "duration", "TIME", gettext_noop ("how long should the mapping be valid for new tunnels?"), - 1, &GNUNET_GETOPT_set_ulong, &duration}, + 1, &GNUNET_GETOPT_set_relative_time, &duration}, {'i', "ip", "IP", gettext_noop ("destination IP for the tunnel"), 1, &GNUNET_GETOPT_set_string, &target_ip}, @@ -323,11 +322,16 @@ main (int argc, char *const *argv) GNUNET_GETOPT_OPTION_VERBOSE (&verbosity), GNUNET_GETOPT_OPTION_END }; - return (GNUNET_OK == - GNUNET_PROGRAM_run (argc, argv, "gnunet-vpn", - gettext_noop - ("Setup tunnels via VPN."), options, + if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) + return 2; + + ret = (GNUNET_OK == + GNUNET_PROGRAM_run (argc, argv, "gnunet-vpn", + gettext_noop + ("Setup tunnels via VPN."), options, &run, NULL)) ? ret : 1; + GNUNET_free ((void *) argv); + return ret; } diff --git a/src/vpn/test_gnunet_vpn.c b/src/vpn/test_gnunet_vpn.c deleted file mode 100644 index 4c941bd..0000000 --- a/src/vpn/test_gnunet_vpn.c +++ /dev/null @@ -1,599 +0,0 @@ -/* - This file is part of GNUnet - (C) 2007, 2009, 2011, 2012 Christian Grothoff - - GNUnet 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, or (at your - option) any later version. - - GNUnet 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. - - You should have received a copy of the GNU General Public License - along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. -*/ - -/** - * @file test_gnunet_vpn.c - * @brief testcase for tunneling HTTP over the GNUnet VPN - * @author Christian Grothoff - */ -#include "platform.h" -#include <curl/curl.h> -#include <microhttpd.h> -#include "gnunet_vpn_service.h" -#include "gnunet_arm_service.h" - -#define PORT 48080 - -#define START_ARM GNUNET_YES - -#define VERBOSE GNUNET_NO - -#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 300) - -struct PeerContext -{ - struct GNUNET_CONFIGURATION_Handle *cfg; - struct GNUNET_PeerIdentity id; -#if START_ARM - struct GNUNET_OS_Process *arm_proc; -#endif -}; - -static struct PeerContext p1; - -/** - * Return value for 'main'. - */ -static int global_ret; - -static struct GNUNET_VPN_Handle *vpn; - -static struct MHD_Daemon *mhd; - -static GNUNET_SCHEDULER_TaskIdentifier mhd_task_id; - -static GNUNET_SCHEDULER_TaskIdentifier curl_task_id; - -static GNUNET_SCHEDULER_TaskIdentifier ctrl_c_task_id; - -static struct GNUNET_VPN_RedirectionRequest *rr; - -static CURL *curl; - -static CURLM *multi; - -static char *url; - -/** - * IP address of the ultimate destination. - */ -static const char *dest_ip; - -/** - * Address family of the dest_ip. - */ -static int dest_af; - -/** - * Address family to use by the curl client. - */ -static int src_af; - - -struct CBC -{ - char buf[1024]; - size_t pos; -}; - -static struct CBC cbc; - - - -static size_t -copy_buffer (void *ptr, size_t size, size_t nmemb, void *ctx) -{ - struct CBC *cbc = ctx; - - if (cbc->pos + size * nmemb > sizeof(cbc->buf)) - return 0; /* overflow */ - memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb); - cbc->pos += size * nmemb; - return size * nmemb; -} - - -static int -mhd_ahc (void *cls, - struct MHD_Connection *connection, - const char *url, - const char *method, - const char *version, - const char *upload_data, size_t *upload_data_size, - void **unused) -{ - static int ptr; - struct MHD_Response *response; - int ret; - - if (0 != strcmp ("GET", method)) - return MHD_NO; /* unexpected method */ - if (&ptr != *unused) - { - *unused = &ptr; - return MHD_YES; - } - *unused = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MHD sends respose for request to URL `%s'\n", url); - response = MHD_create_response_from_buffer (strlen (url), - (void *) url, - MHD_RESPMEM_MUST_COPY); - ret = MHD_queue_response (connection, MHD_HTTP_OK, response); - MHD_destroy_response (response); - if (ret == MHD_NO) - abort (); - return ret; -} - - -static void -do_shutdown () -{ - if (mhd_task_id != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (mhd_task_id); - mhd_task_id = GNUNET_SCHEDULER_NO_TASK; - } - if (curl_task_id != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (curl_task_id); - curl_task_id = GNUNET_SCHEDULER_NO_TASK; - } - if (ctrl_c_task_id != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (ctrl_c_task_id); - ctrl_c_task_id = GNUNET_SCHEDULER_NO_TASK; - } - if (NULL != mhd) - { - MHD_stop_daemon (mhd); - mhd = NULL; - } - if (NULL != rr) - { - GNUNET_VPN_cancel_request (rr); - rr = NULL; - } - if (NULL != vpn) - { - GNUNET_VPN_disconnect (vpn); - vpn = NULL; - } - GNUNET_free_non_null (url); - url = NULL; -} - - -/** - * Function to run the HTTP client. - */ -static void -curl_main (void); - - -static void -curl_task (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - curl_task_id = GNUNET_SCHEDULER_NO_TASK; - curl_main (); -} - - -static void -curl_main () -{ - fd_set rs; - fd_set ws; - fd_set es; - int max; - struct GNUNET_NETWORK_FDSet nrs; - struct GNUNET_NETWORK_FDSet nws; - struct GNUNET_TIME_Relative delay; - long timeout; - int running; - struct CURLMsg *msg; - - max = 0; - FD_ZERO (&rs); - FD_ZERO (&ws); - FD_ZERO (&es); - curl_multi_perform (multi, &running); - if (running == 0) - { - GNUNET_assert (NULL != (msg = curl_multi_info_read (multi, &running))); - if (msg->msg == CURLMSG_DONE) - { - if (msg->data.result != CURLE_OK) - { - fprintf (stderr, - "%s failed at %s:%d: `%s'\n", - "curl_multi_perform", - __FILE__, - __LINE__, curl_easy_strerror (msg->data.result)); - global_ret = 1; - } - } - curl_multi_remove_handle (multi, curl); - curl_multi_cleanup (multi); - curl_easy_cleanup (curl); - curl = NULL; - multi = NULL; - if (cbc.pos != strlen ("/hello_world")) - { - GNUNET_break (0); - global_ret = 2; - } - if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world"))) - { - GNUNET_break (0); - global_ret = 3; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download complete, shutting down!\n"); - do_shutdown (); - return; - } - GNUNET_assert (CURLM_OK == curl_multi_fdset (multi, &rs, &ws, &es, &max)); - if ( (CURLM_OK != curl_multi_timeout (multi, &timeout)) || - (-1 == timeout) ) - delay = GNUNET_TIME_UNIT_SECONDS; - else - delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, (unsigned int) timeout); - GNUNET_NETWORK_fdset_copy_native (&nrs, - &rs, - max + 1); - GNUNET_NETWORK_fdset_copy_native (&nws, - &ws, - max + 1); - curl_task_id = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - delay, - &nrs, - &nws, - &curl_task, - NULL); -} - - -/** - * Callback invoked from the VPN service once a redirection is - * available. Provides the IP address that can now be used to - * reach the requested destination (in our case, the MHD server) - * - * @param cls closure - * @param af address family, AF_INET or AF_INET6; AF_UNSPEC on error; - * will match 'result_af' from the request - * @param address IP address (struct in_addr or struct in_addr6, depending on 'af') - * that the VPN allocated for the redirection; - * traffic to this IP will now be redirected to the - * specified target peer; NULL on error - */ -static void -allocation_cb (void *cls, - int af, - const void *address) -{ - char ips[INET6_ADDRSTRLEN]; - - rr = NULL; - if (src_af != af) - { - fprintf (stderr, - "VPN failed to allocate appropriate address\n"); - GNUNET_SCHEDULER_shutdown (); - return; - } - GNUNET_asprintf (&url, - "http://%s:%u/hello_world", - inet_ntop (af, address, ips, sizeof (ips)), - (unsigned int) PORT); - curl = curl_easy_init (); - curl_easy_setopt (curl, CURLOPT_URL, url); - curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, ©_buffer); - curl_easy_setopt (curl, CURLOPT_WRITEDATA, &cbc); - curl_easy_setopt (curl, CURLOPT_FAILONERROR, 1); - curl_easy_setopt (curl, CURLOPT_TIMEOUT, 150L); - curl_easy_setopt (curl, CURLOPT_CONNECTTIMEOUT, 15L); - curl_easy_setopt (curl, CURLOPT_NOSIGNAL, 1); - - multi = curl_multi_init (); - GNUNET_assert (multi != NULL); - GNUNET_assert (CURLM_OK == curl_multi_add_handle (multi, curl)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Beginning HTTP download from `%s'\n", url); - curl_main (); -} - - -/** - * Function to keep the HTTP server running. - */ -static void -mhd_main (void); - - -static void -mhd_task (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - mhd_task_id = GNUNET_SCHEDULER_NO_TASK; - MHD_run (mhd); - mhd_main (); -} - - -static void -ctrl_c_shutdown (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - ctrl_c_task_id = GNUNET_SCHEDULER_NO_TASK; - do_shutdown (); - GNUNET_break (0); - global_ret = 1; -} - - -static void -mhd_main () -{ - struct GNUNET_NETWORK_FDSet nrs; - struct GNUNET_NETWORK_FDSet nws; - fd_set rs; - fd_set ws; - fd_set es; - int max_fd; - unsigned MHD_LONG_LONG timeout; - struct GNUNET_TIME_Relative delay; - - GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == mhd_task_id); - FD_ZERO (&rs); - FD_ZERO (&ws); - FD_ZERO (&es); - max_fd = -1; - GNUNET_assert (MHD_YES == - MHD_get_fdset (mhd, &rs, &ws, &es, &max_fd)); - if (MHD_YES == MHD_get_timeout (mhd, &timeout)) - delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, - (unsigned int) timeout); - else - delay = GNUNET_TIME_UNIT_FOREVER_REL; - GNUNET_NETWORK_fdset_copy_native (&nrs, - &rs, - max_fd + 1); - GNUNET_NETWORK_fdset_copy_native (&nws, - &ws, - max_fd + 1); - mhd_task_id = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - delay, - &nrs, - &nws, - &mhd_task, - NULL); -} - - -static void -run (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - struct in_addr v4; - struct in6_addr v6; - void *addr; - enum MHD_FLAG flags; - - vpn = GNUNET_VPN_connect (cfg); - GNUNET_assert (NULL != vpn); - flags = MHD_USE_DEBUG; - if (AF_INET6 == dest_af) - flags |= MHD_USE_IPv6; - mhd = MHD_start_daemon (flags, - PORT, - NULL, NULL, - &mhd_ahc, NULL, - MHD_OPTION_END); - GNUNET_assert (NULL != mhd); - mhd_main (); - addr = NULL; - switch (dest_af) - { - case AF_INET: - GNUNET_assert (1 == inet_pton (dest_af, dest_ip, &v4)); - addr = &v4; - break; - case AF_INET6: - GNUNET_assert (1 == inet_pton (dest_af, dest_ip, &v6)); - addr = &v6; - break; - default: - GNUNET_assert (0); - } - rr = GNUNET_VPN_redirect_to_ip (vpn, - src_af, - dest_af, - addr, - GNUNET_YES, - GNUNET_TIME_UNIT_FOREVER_ABS, - &allocation_cb, NULL); - ctrl_c_task_id = GNUNET_SCHEDULER_add_delayed (TIMEOUT, - &ctrl_c_shutdown, - NULL); -} - - -static void -setup_peer (struct PeerContext *p, const char *cfgname) -{ - p->cfg = GNUNET_CONFIGURATION_create (); -#if START_ARM - p->arm_proc = - GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", - "gnunet-service-arm", - "-c", cfgname, NULL); -#endif - GNUNET_assert (NULL != p->arm_proc); - GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname)); -} - - -static void -stop_peer (struct PeerContext *p) -{ -#if START_ARM - if (NULL != p->arm_proc) - { - if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) - GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); - if (GNUNET_OS_process_wait (p->arm_proc) != GNUNET_OK) - GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n", - GNUNET_OS_process_get_pid (p->arm_proc)); - GNUNET_OS_process_destroy (p->arm_proc); - p->arm_proc = NULL; - } -#endif - GNUNET_CONFIGURATION_destroy (p->cfg); -} - - -/** - * Test if the given AF is supported by this system. - * - * @param af to test - * @return GNUNET_OK if the AF is supported - */ -static int -test_af (int af) -{ - int s; - - s = socket (af, SOCK_STREAM, 0); - if (-1 == s) - { - if (EAFNOSUPPORT == errno) - return GNUNET_NO; - fprintf (stderr, "Failed to create test socket: %s\n", STRERROR (errno)); - return GNUNET_SYSERR; - } - close (s); - return GNUNET_OK; -} - - - -int -main (int argc, char *const *argv) -{ - const char *type; - const char *bin; - char *const argvx[] = { - "test_gnunet_vpn", - "-c", - "test_gnunet_vpn.conf", - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - - if (0 != ACCESS ("/dev/net/tun", R_OK)) - { - GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, - "access", - "/dev/net/tun"); - fprintf (stderr, - "WARNING: System unable to run test, skipping.\n"); - return 0; - } - if ( (GNUNET_YES != - GNUNET_OS_check_helper_binary ("gnunet-helper-vpn")) || - (GNUNET_YES != - GNUNET_OS_check_helper_binary ("gnunet-helper-exit")) ) - { - fprintf (stderr, - "WARNING: gnunet-helper-{exit,vpn} binaries in $PATH are not SUID, refusing to run test (as it would have to fail).\n"); - fprintf (stderr, - "Change $PATH ('.' in $PATH before $GNUNET_PREFIX/bin is problematic) or permissions (run 'make install' as root) to fix this!\n"); - return 0; - } - GNUNET_CRYPTO_setup_hostkey ("test_gnunet_vpn.conf"); - bin = argv[0]; - if (NULL != strstr (bin, "lt-")) - bin = strstr (bin, "lt-") + 4; - type = strstr (bin, "-"); - if (NULL == type) - { - fprintf (stderr, "invalid binary name\n"); - return 1; - } - type++; - if (0 == strcmp (type, "4_to_6")) - { - dest_ip = "FC5A:04E1:C2BA::1"; - dest_af = AF_INET6; - src_af = AF_INET; - } - else if (0 == strcmp (type, "6_to_4")) - { - dest_ip = "169.254.86.1"; - dest_af = AF_INET; - src_af = AF_INET6; - } - else if (0 == strcmp (type, "4_over")) - { - dest_ip = "169.254.86.1"; - dest_af = AF_INET; - src_af = AF_INET; - } - else if (0 == strcmp (type, "6_over")) - { - dest_ip = "FC5A:04E1:C2BA::1"; - dest_af = AF_INET6; - src_af = AF_INET6; - } - else - { - fprintf (stderr, "invalid binary suffix `%s'\n", type); - return 1; - } - if ( (GNUNET_OK != test_af (src_af)) || - (GNUNET_OK != test_af (dest_af)) ) - { - fprintf (stderr, - "Required address families not supported by this system, skipping test.\n"); - return 0; - } - - - if (0 != curl_global_init (CURL_GLOBAL_WIN32)) - { - fprintf (stderr, "failed to initialize curl\n"); - return 2; - } - setup_peer (&p1, "test_gnunet_vpn.conf"); - GNUNET_log_setup ("test_gnunet_vpn", - "WARNING", - NULL); - GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx, - "test_gnunet_vpn", "nohelp", options, &run, NULL); - stop_peer (&p1); - GNUNET_DISK_directory_remove ("/tmp/gnunet-test-vpn"); - return global_ret; -} - -/* end of test_gnunet_vpn.c */ - diff --git a/src/vpn/test_gnunet_vpn.conf b/src/vpn/test_gnunet_vpn.conf deleted file mode 100644 index bdac1a5..0000000 --- a/src/vpn/test_gnunet_vpn.conf +++ /dev/null @@ -1,43 +0,0 @@ -[PATHS] -SERVICEHOME = /tmp/gnunet-test-vpn/ -DEFAULTCONFIG = test_gnunet_vpn.conf - -[transport] -PLUGINS = tcp - -[arm] -DEFAULTSERVICES = statistics exit vpn -PORT = 0 -ALLOW_SHUTDOWN = YES - -[exit] -EXIT_IPV4 = YES -EXIT_IPV6 = YES - -# FIXME: can we use 'lo'? -EXIT_IFNAME = eth1 - -[testing] -WEAKRANDOM = YES -HOSTKEYSFILE = ../../contrib/testing_hostkeys.dat - -[nse] -WORKBITS = 1 - -# repeating some values from the default configurations -# here as the respective network addresses are also -# hard-wired in the tests and the MUST match (!) -[vpn] -IPV6ADDR = FC2D:FDAA:6A26::1 -IPV6PREFIX = 64 -IPV4ADDR = 169.254.20.1 -IPV4MASK = 255.255.255.0 - -[exit] -IPV6ADDR = FC5A:04E1:C2BA::1 -IPV6PREFIX = 96 -IPV4ADDR = 169.254.86.1 -IPV4MASK = 255.255.255.0 - -[gns] -AUTOSTART = NO diff --git a/src/vpn/vpn.conf.in b/src/vpn/vpn.conf.in index f5eb224..57657b9 100644 --- a/src/vpn/vpn.conf.in +++ b/src/vpn/vpn.conf.in @@ -1,9 +1,8 @@ [vpn] AUTOSTART = YES -@UNIXONLY@ PORT = 0 +@UNIXONLY@ PORT = 2105 HOSTNAME = localhost HOME = $SERVICEHOME -CONFIG = $DEFAULTCONFIG BINARY = gnunet-service-vpn ACCEPT_FROM = 127.0.0.1; ACCEPT_FROM6 = ::1; diff --git a/src/vpn/vpn.h b/src/vpn/vpn.h index bec3a5b..e1ae130 100644 --- a/src/vpn/vpn.h +++ b/src/vpn/vpn.h @@ -82,7 +82,7 @@ struct RedirectToIpRequestMessage struct RedirectToServiceRequestMessage { /** - * Type is GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_IP + * Type is GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_SERVICE */ struct GNUNET_MessageHeader header; @@ -115,7 +115,7 @@ struct RedirectToServiceRequestMessage /** * Service descriptor identifying the service. */ - GNUNET_HashCode service_descriptor; + struct GNUNET_HashCode service_descriptor; /** * Unique ID to match a future response to this request. diff --git a/src/vpn/vpn_api.c b/src/vpn/vpn_api.c index 5b70d19..e4da5fa 100644 --- a/src/vpn/vpn_api.c +++ b/src/vpn/vpn_api.c @@ -120,7 +120,7 @@ struct GNUNET_VPN_RedirectionRequest /** * For service redirection, service descriptor. */ - GNUNET_HashCode serv; + struct GNUNET_HashCode serv; /** * At what time should the created service mapping expire? @@ -464,7 +464,7 @@ GNUNET_VPN_redirect_to_peer (struct GNUNET_VPN_Handle *vh, int result_af, uint8_t protocol, const struct GNUNET_PeerIdentity *peer, - const GNUNET_HashCode *serv, + const struct GNUNET_HashCode *serv, int nac, struct GNUNET_TIME_Absolute expiration_time, GNUNET_VPN_AllocationCallback cb, |