diff options
author | Yves-Alexis Perez <corsac@debian.org> | 2013-08-25 15:37:26 +0200 |
---|---|---|
committer | Yves-Alexis Perez <corsac@debian.org> | 2013-08-25 15:37:26 +0200 |
commit | 6b99c8d9cff7b3e8ae8f3204b99e7ea40f791349 (patch) | |
tree | 009fc492961e13860d2a4bc2de8caf2bbe2975e7 /src/libcharon/plugins/socket_dynamic | |
parent | c83921a2b566aa9d55d8ccc7258f04fca6292ee6 (diff) | |
download | vyos-strongswan-6b99c8d9cff7b3e8ae8f3204b99e7ea40f791349.tar.gz vyos-strongswan-6b99c8d9cff7b3e8ae8f3204b99e7ea40f791349.zip |
Imported Upstream version 5.1.0
Diffstat (limited to 'src/libcharon/plugins/socket_dynamic')
4 files changed, 171 insertions, 55 deletions
diff --git a/src/libcharon/plugins/socket_dynamic/Makefile.am b/src/libcharon/plugins/socket_dynamic/Makefile.am index 914945535..04973e5ba 100644 --- a/src/libcharon/plugins/socket_dynamic/Makefile.am +++ b/src/libcharon/plugins/socket_dynamic/Makefile.am @@ -1,8 +1,11 @@ +AM_CPPFLAGS = \ + -I${linux_headers} \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon -INCLUDES = -I${linux_headers} -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra -I$(top_srcdir)/src/libcharon - -AM_CFLAGS = -rdynamic +AM_CFLAGS = \ + -rdynamic if MONOLITHIC noinst_LTLIBRARIES = libstrongswan-socket-dynamic.la diff --git a/src/libcharon/plugins/socket_dynamic/Makefile.in b/src/libcharon/plugins/socket_dynamic/Makefile.in index a12e4a893..e976e9902 100644 --- a/src/libcharon/plugins/socket_dynamic/Makefile.in +++ b/src/libcharon/plugins/socket_dynamic/Makefile.in @@ -62,7 +62,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ $(top_srcdir)/m4/macros/with.m4 \ $(top_srcdir)/m4/macros/enable-disable.m4 \ $(top_srcdir)/m4/macros/add-plugin.m4 \ - $(top_srcdir)/configure.in + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -103,7 +103,10 @@ am_libstrongswan_socket_dynamic_la_OBJECTS = socket_dynamic_plugin.lo \ socket_dynamic_socket.lo libstrongswan_socket_dynamic_la_OBJECTS = \ $(am_libstrongswan_socket_dynamic_la_OBJECTS) -libstrongswan_socket_dynamic_la_LINK = $(LIBTOOL) --tag=CC \ +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +libstrongswan_socket_dynamic_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) \ $(libstrongswan_socket_dynamic_la_LDFLAGS) $(LDFLAGS) -o $@ @@ -116,13 +119,26 @@ am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(libstrongswan_socket_dynamic_la_SOURCES) DIST_SOURCES = $(libstrongswan_socket_dynamic_la_SOURCES) am__can_run_installinfo = \ @@ -136,6 +152,7 @@ DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ @@ -148,6 +165,8 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECK_CFLAGS = @CHECK_CFLAGS@ CHECK_LIBS = @CHECK_LIBS@ +COVERAGE_CFLAGS = @COVERAGE_CFLAGS@ +COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ @@ -163,6 +182,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ GREP = @GREP@ @@ -171,6 +191,7 @@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ @@ -217,6 +238,7 @@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOCKLIB = @SOCKLIB@ STRIP = @STRIP@ +UNWINDLIB = @UNWINDLIB@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ @@ -245,6 +267,7 @@ charon_natt_port = @charon_natt_port@ charon_plugins = @charon_plugins@ charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ +cmd_plugins = @cmd_plugins@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -322,10 +345,15 @@ top_srcdir = @top_srcdir@ urandom_device = @urandom_device@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ -INCLUDES = -I${linux_headers} -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra -I$(top_srcdir)/src/libcharon +AM_CPPFLAGS = \ + -I${linux_headers} \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon + +AM_CFLAGS = \ + -rdynamic -AM_CFLAGS = -rdynamic @MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-socket-dynamic.la @MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-socket-dynamic.la libstrongswan_socket_dynamic_la_SOURCES = \ @@ -409,7 +437,7 @@ clean-pluginLTLIBRARIES: rm -f "$${dir}/so_locations"; \ done libstrongswan-socket-dynamic.la: $(libstrongswan_socket_dynamic_la_OBJECTS) $(libstrongswan_socket_dynamic_la_DEPENDENCIES) $(EXTRA_libstrongswan_socket_dynamic_la_DEPENDENCIES) - $(libstrongswan_socket_dynamic_la_LINK) $(am_libstrongswan_socket_dynamic_la_rpath) $(libstrongswan_socket_dynamic_la_OBJECTS) $(libstrongswan_socket_dynamic_la_LIBADD) $(LIBS) + $(AM_V_CCLD)$(libstrongswan_socket_dynamic_la_LINK) $(am_libstrongswan_socket_dynamic_la_rpath) $(libstrongswan_socket_dynamic_la_OBJECTS) $(libstrongswan_socket_dynamic_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -421,25 +449,25 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socket_dynamic_socket.Plo@am__quote@ .c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo diff --git a/src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c b/src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c index c21d5240e..fdc9a7cf9 100644 --- a/src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c +++ b/src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c @@ -40,6 +40,7 @@ METHOD(plugin_t, get_features, int, static plugin_feature_t f[] = { PLUGIN_CALLBACK(socket_register, socket_dynamic_socket_create), PLUGIN_PROVIDE(CUSTOM, "socket"), + PLUGIN_SDEPEND(CUSTOM, "kernel-ipsec"), }; *features = f; return countof(f); diff --git a/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c b/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c index a5e919348..abbc8bad2 100644 --- a/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c +++ b/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2012 Tobias Brunner + * Copyright (C) 2006-2013 Tobias Brunner * Copyright (C) 2006 Daniel Roethlisberger * Copyright (C) 2005-2010 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -326,13 +326,60 @@ METHOD(socket_t, receiver, status_t, } /** + * Get the port allocated dynamically using bind() + */ +static bool get_dynamic_port(int fd, int family, u_int16_t *port) +{ + union { + struct sockaddr_storage ss; + struct sockaddr s; + struct sockaddr_in sin; + struct sockaddr_in6 sin6; + } addr; + socklen_t addrlen; + + addrlen = sizeof(addr); + if (getsockname(fd, &addr.s, &addrlen) != 0) + { + DBG1(DBG_NET, "unable to getsockname: %s", strerror(errno)); + return FALSE; + } + switch (family) + { + case AF_INET: + if (addrlen != sizeof(addr.sin) || addr.sin.sin_family != family) + { + break; + } + *port = ntohs(addr.sin.sin_port); + return TRUE; + case AF_INET6: + if (addrlen != sizeof(addr.sin6) || addr.sin6.sin6_family != family) + { + break; + } + *port = ntohs(addr.sin6.sin6_port); + return TRUE; + default: + return FALSE; + } + DBG1(DBG_NET, "received invalid getsockname() result"); + return FALSE; +} + +/** * open a socket to send and receive packets */ static int open_socket(private_socket_dynamic_socket_t *this, - int family, u_int16_t port) + int family, u_int16_t *port) { + union { + struct sockaddr_storage ss; + struct sockaddr s; + struct sockaddr_in sin; + struct sockaddr_in6 sin6; + } addr; int on = TRUE; - struct sockaddr_storage addr; socklen_t addrlen; u_int sol, pktinfo = 0; int fd; @@ -342,27 +389,21 @@ static int open_socket(private_socket_dynamic_socket_t *this, switch (family) { case AF_INET: - { - struct sockaddr_in *sin = (struct sockaddr_in *)&addr; - sin->sin_family = AF_INET; - sin->sin_addr.s_addr = INADDR_ANY; - sin->sin_port = htons(port); - addrlen = sizeof(struct sockaddr_in); + addr.sin.sin_family = AF_INET; + addr.sin.sin_addr.s_addr = INADDR_ANY; + addr.sin.sin_port = htons(*port); + addrlen = sizeof(addr.sin); sol = SOL_IP; pktinfo = IP_PKTINFO; break; - } case AF_INET6: - { - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&addr; - sin6->sin6_family = AF_INET6; - memset(&sin6->sin6_addr, 0, sizeof(sin6->sin6_addr)); - sin6->sin6_port = htons(port); - addrlen = sizeof(struct sockaddr_in6); + addr.sin6.sin6_family = AF_INET6; + memset(&addr.sin6.sin6_addr, 0, sizeof(addr.sin6.sin6_addr)); + addr.sin6.sin6_port = htons(*port); + addrlen = sizeof(addr.sin6); sol = SOL_IPV6; pktinfo = IPV6_RECVPKTINFO; break; - } default: return 0; } @@ -380,13 +421,17 @@ static int open_socket(private_socket_dynamic_socket_t *this, return 0; } - /* bind the socket */ - if (bind(fd, (struct sockaddr *)&addr, addrlen) < 0) + if (bind(fd, &addr.s, addrlen) < 0) { DBG1(DBG_NET, "unable to bind socket: %s", strerror(errno)); close(fd); return 0; } + if (*port == 0 && !get_dynamic_port(fd, family, port)) + { + close(fd); + return 0; + } /* get additional packet info on receive */ if (setsockopt(fd, sol, pktinfo, &on, sizeof(on)) < 0) @@ -404,16 +449,41 @@ static int open_socket(private_socket_dynamic_socket_t *this, /* enable UDP decapsulation on each socket */ if (!hydra->kernel_interface->enable_udp_decap(hydra->kernel_interface, - fd, family, port)) + fd, family, *port)) { DBG1(DBG_NET, "enabling UDP decapsulation for %s on port %d failed", - family == AF_INET ? "IPv4" : "IPv6", port); + family == AF_INET ? "IPv4" : "IPv6", *port); } return fd; } /** + * Get the first usable socket for an address family + */ +static dynsock_t *get_any_socket(private_socket_dynamic_socket_t *this, + int family) +{ + dynsock_t *key, *value, *found = NULL; + enumerator_t *enumerator; + + this->lock->read_lock(this->lock); + enumerator = this->sockets->create_enumerator(this->sockets); + while (enumerator->enumerate(enumerator, &key, &value)) + { + if (value->family == family) + { + found = value; + break; + } + } + enumerator->destroy(enumerator); + this->lock->unlock(this->lock); + + return found; +} + +/** * Find/Create a socket to send from host */ static dynsock_t *find_socket(private_socket_dynamic_socket_t *this, @@ -433,7 +503,15 @@ static dynsock_t *find_socket(private_socket_dynamic_socket_t *this, { return skt; } - fd = open_socket(this, family, port); + if (!port) + { + skt = get_any_socket(this, family); + if (skt) + { + return skt; + } + } + fd = open_socket(this, family, &port); if (!fd) { return NULL; @@ -457,7 +535,7 @@ METHOD(socket_t, sender, status_t, { dynsock_t *skt; host_t *src, *dst; - int port, family; + int family; ssize_t len; chunk_t data; struct msghdr msg; @@ -467,9 +545,7 @@ METHOD(socket_t, sender, status_t, src = packet->get_source(packet); dst = packet->get_destination(packet); family = src->get_family(src); - port = src->get_port(src); - port = port ?: CHARON_UDP_PORT; - skt = find_socket(this, family, port); + skt = find_socket(this, family, src->get_port(src)); if (!skt) { return FAILED; @@ -544,6 +620,14 @@ METHOD(socket_t, get_port, u_int16_t, return 0; } +METHOD(socket_t, supported_families, socket_family_t, + private_socket_dynamic_socket_t *this) +{ + /* we could return only the families of the opened sockets, but it could + * be that both families are supported even if no socket is yet open */ + return SOCKET_FAMILY_BOTH; +} + METHOD(socket_t, destroy, void, private_socket_dynamic_socket_t *this) { @@ -578,6 +662,7 @@ socket_dynamic_socket_t *socket_dynamic_socket_create() .send = _sender, .receive = _receiver, .get_port = _get_port, + .supported_families = _supported_families, .destroy = _destroy, }, }, @@ -597,4 +682,3 @@ socket_dynamic_socket_t *socket_dynamic_socket_create() return &this->public; } - |