summaryrefslogtreecommitdiff
path: root/src/libcharon/plugins/socket_dynamic
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/plugins/socket_dynamic')
-rw-r--r--src/libcharon/plugins/socket_dynamic/Makefile.am11
-rw-r--r--src/libcharon/plugins/socket_dynamic/Makefile.in76
-rw-r--r--src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c1
-rw-r--r--src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c138
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;
}
-