aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Willi <martin@strongswan.org>2008-10-16 11:48:18 +0000
committerMartin Willi <martin@strongswan.org>2008-10-16 11:48:18 +0000
commitad3af574a4b71f7d83e5b871d9dd998ec4068580 (patch)
tree2c490c5f7efc35cc1190786e634d2cddbc4fa19e
parente17353fc31fb83852b196edfb52f4e091acbc0e3 (diff)
downloadstrongswan-ad3af574a4b71f7d83e5b871d9dd998ec4068580.tar.bz2
strongswan-ad3af574a4b71f7d83e5b871d9dd998ec4068580.tar.xz
moved updown script invocation to an optional plugin
-rw-r--r--configure.in5
-rw-r--r--src/charon/Makefile.am5
-rw-r--r--src/charon/bus/bus.c3
-rw-r--r--src/charon/plugins/updown/Makefile.am10
-rw-r--r--src/charon/plugins/updown/updown_plugin.c241
-rw-r--r--src/charon/plugins/updown/updown_plugin.h49
-rw-r--r--src/charon/sa/child_sa.c229
-rw-r--r--src/charon/sa/child_sa.h23
-rw-r--r--src/charon/sa/ike_sa.c9
-rw-r--r--src/charon/sa/ike_sa_manager.c5
-rw-r--r--src/charon/sa/tasks/child_create.c19
-rw-r--r--src/charon/sa/tasks/ike_mobike.c1
12 files changed, 354 insertions, 245 deletions
diff --git a/configure.in b/configure.in
index 117dcf30a..edd422b52 100644
--- a/configure.in
+++ b/configure.in
@@ -569,7 +569,7 @@ AC_ARG_ENABLE(
AC_ARG_ENABLE(
[updown],
- AS_HELP_STRING([--disable-updown],[disable installation of firewall scripts. (default is NO).]),
+ AS_HELP_STRING([--disable-updown],[disable updown firewall script plugin. (default is NO).]),
[if test x$enableval = xyes; then
updown=true
else
@@ -874,6 +874,7 @@ AM_CONDITIONAL(USE_NM, test x$nm = xtrue)
AM_CONDITIONAL(USE_UCI, test x$uci = xtrue)
AM_CONDITIONAL(USE_SMP, test x$smp = xtrue)
AM_CONDITIONAL(USE_SQL, test x$sql = xtrue)
+AM_CONDITIONAL(USE_UPDOWN, test x$updown = xtrue)
AM_CONDITIONAL(USE_UNIT_TESTS, test x$unittest = xtrue)
AM_CONDITIONAL(USE_EAP_SIM, test x$eap_sim = xtrue)
AM_CONDITIONAL(USE_EAP_SIM_FILE, test x$eap_sim_file = xtrue)
@@ -902,7 +903,6 @@ AM_CONDITIONAL(USE_CAPABILITIES, test x$capabilities = xlibcap)
AM_CONDITIONAL(USE_PLUTO, test x$pluto = xtrue)
AM_CONDITIONAL(USE_CHARON, test x$charon = xtrue)
AM_CONDITIONAL(USE_TOOLS, test x$tools = xtrue)
-AM_CONDITIONAL(USE_UPDOWN, test x$updown = xtrue)
AM_CONDITIONAL(USE_LIBSTRONGSWAN, test x$charon = xtrue -o x$tools = xtrue)
AM_CONDITIONAL(USE_FILE_CONFIG, test x$pluto = xtrue -o x$stroke = xtrue)
@@ -966,6 +966,7 @@ AC_OUTPUT(
src/charon/plugins/nm/Makefile
src/charon/plugins/uci/Makefile
src/charon/plugins/stroke/Makefile
+ src/charon/plugins/updown/Makefile
src/charon/plugins/unit_tester/Makefile
src/stroke/Makefile
src/ipsec/Makefile
diff --git a/src/charon/Makefile.am b/src/charon/Makefile.am
index 85111afdd..54a7903da 100644
--- a/src/charon/Makefile.am
+++ b/src/charon/Makefile.am
@@ -169,6 +169,11 @@ if USE_SQL
PLUGINS += sql
endif
+if USE_UPDOWN
+ SUBDIRS += plugins/updown
+ PLUGINS += updown
+endif
+
if USE_EAP_IDENTITY
SUBDIRS += plugins/eap_identity
PLUGINS += eapidentity
diff --git a/src/charon/bus/bus.c b/src/charon/bus/bus.c
index eb8390856..371d431b2 100644
--- a/src/charon/bus/bus.c
+++ b/src/charon/bus/bus.c
@@ -321,6 +321,9 @@ static void log_(private_bus_t *this, debug_t group, level_t level,
va_end(args);
}
+/**
+ * unregister a listener
+ */
static void unregister_listener(private_bus_t *this, entry_t *entry,
enumerator_t *enumerator)
{
diff --git a/src/charon/plugins/updown/Makefile.am b/src/charon/plugins/updown/Makefile.am
new file mode 100644
index 000000000..9fc226b5e
--- /dev/null
+++ b/src/charon/plugins/updown/Makefile.am
@@ -0,0 +1,10 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-updown.la
+libstrongswan_updown_la_SOURCES = updown_plugin.h updown_plugin.c
+libstrongswan_updown_la_LDFLAGS = -module
+
+
diff --git a/src/charon/plugins/updown/updown_plugin.c b/src/charon/plugins/updown/updown_plugin.c
new file mode 100644
index 000000000..e8fea0273
--- /dev/null
+++ b/src/charon/plugins/updown/updown_plugin.c
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#include "updown_plugin.h"
+
+#include <daemon.h>
+#include <config/child_cfg.h>
+
+typedef struct private_updown_plugin_t private_updown_plugin_t;
+
+/**
+ * private data of updown plugin
+ */
+struct private_updown_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ updown_plugin_t public;
+
+ /**
+ * Listener interface, listens to CHILD_SA state changes
+ */
+ listener_t listener;
+};
+
+/**
+ * Run the up/down script
+ */
+static void updown(ike_sa_t *ike_sa, child_sa_t *child_sa, bool up)
+{
+ traffic_selector_t *my_ts, *other_ts;
+ enumerator_t *enumerator;
+ child_cfg_t *config;
+ host_t *vip, *me, *other;
+ char *script;
+
+ config = child_sa->get_config(child_sa);
+ vip = ike_sa->get_virtual_ip(ike_sa, TRUE);
+ script = config->get_updown(config);
+ me = ike_sa->get_my_host(ike_sa);
+ other = ike_sa->get_other_host(ike_sa);
+
+ if (script == NULL)
+ {
+ return;
+ }
+
+ enumerator = child_sa->create_policy_enumerator(child_sa);
+ while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
+ {
+ char command[1024];
+ char *my_client, *other_client, *my_client_mask, *other_client_mask;
+ char *pos, *virtual_ip, *iface;
+ FILE *shell;
+
+ /* get subnet/bits from string */
+ asprintf(&my_client, "%R", my_ts);
+ pos = strchr(my_client, '/');
+ *pos = '\0';
+ my_client_mask = pos + 1;
+ pos = strchr(my_client_mask, '[');
+ if (pos)
+ {
+ *pos = '\0';
+ }
+ asprintf(&other_client, "%R", other_ts);
+ pos = strchr(other_client, '/');
+ *pos = '\0';
+ other_client_mask = pos + 1;
+ pos = strchr(other_client_mask, '[');
+ if (pos)
+ {
+ *pos = '\0';
+ }
+
+ if (vip)
+ {
+ asprintf(&virtual_ip, "PLUTO_MY_SOURCEIP='%H' ", vip);
+ }
+ else
+ {
+ asprintf(&virtual_ip, "");
+ }
+
+ iface = charon->kernel_interface->get_interface(
+ charon->kernel_interface, me);
+
+ /* build the command with all env variables.
+ * TODO: PLUTO_PEER_CA and PLUTO_NEXT_HOP are currently missing
+ */
+ snprintf(command, sizeof(command),
+ "2>&1 "
+ "PLUTO_VERSION='1.1' "
+ "PLUTO_VERB='%s%s%s' "
+ "PLUTO_CONNECTION='%s' "
+ "PLUTO_INTERFACE='%s' "
+ "PLUTO_REQID='%u' "
+ "PLUTO_ME='%H' "
+ "PLUTO_MY_ID='%D' "
+ "PLUTO_MY_CLIENT='%s/%s' "
+ "PLUTO_MY_CLIENT_NET='%s' "
+ "PLUTO_MY_CLIENT_MASK='%s' "
+ "PLUTO_MY_PORT='%u' "
+ "PLUTO_MY_PROTOCOL='%u' "
+ "PLUTO_PEER='%H' "
+ "PLUTO_PEER_ID='%D' "
+ "PLUTO_PEER_CLIENT='%s/%s' "
+ "PLUTO_PEER_CLIENT_NET='%s' "
+ "PLUTO_PEER_CLIENT_MASK='%s' "
+ "PLUTO_PEER_PORT='%u' "
+ "PLUTO_PEER_PROTOCOL='%u' "
+ "%s"
+ "%s"
+ "%s",
+ up ? "up" : "down",
+ my_ts->is_host(my_ts, me) ? "-host" : "-client",
+ me->get_family(me) == AF_INET ? "" : "-v6",
+ config->get_name(config),
+ iface ? iface : "unknown",
+ child_sa->get_reqid(child_sa),
+ me, ike_sa->get_my_id(ike_sa),
+ my_client, my_client_mask,
+ my_client, my_client_mask,
+ my_ts->get_from_port(my_ts),
+ my_ts->get_protocol(my_ts),
+ other, ike_sa->get_other_id(ike_sa),
+ other_client, other_client_mask,
+ other_client, other_client_mask,
+ other_ts->get_from_port(other_ts),
+ other_ts->get_protocol(other_ts),
+ virtual_ip,
+ config->get_hostaccess(config) ? "PLUTO_HOST_ACCESS='1' " : "",
+ script);
+ free(my_client);
+ free(other_client);
+ free(virtual_ip);
+ free(iface);
+
+ DBG3(DBG_CHD, "running updown script: %s", command);
+ shell = popen(command, "r");
+
+ if (shell == NULL)
+ {
+ DBG1(DBG_CHD, "could not execute updown script '%s'", script);
+ return;
+ }
+
+ while (TRUE)
+ {
+ char resp[128];
+
+ if (fgets(resp, sizeof(resp), shell) == NULL)
+ {
+ if (ferror(shell))
+ {
+ DBG1(DBG_CHD, "error reading output from updown script");
+ return;
+ }
+ else
+ {
+ break;
+ }
+ }
+ else
+ {
+ char *e = resp + strlen(resp);
+ if (e > resp && e[-1] == '\n')
+ { /* trim trailing '\n' */
+ e[-1] = '\0';
+ }
+ DBG1(DBG_CHD, "updown: %s", resp);
+ }
+ }
+ pclose(shell);
+ }
+ enumerator->destroy(enumerator);
+}
+
+/**
+ * Listener implementation
+ */
+static bool child_state_change(listener_t *this, ike_sa_t *ike_sa,
+ child_sa_t *child_sa, child_sa_state_t state)
+{
+ child_sa_state_t old;
+
+ old = child_sa->get_state(child_sa);
+
+ if ((old == CHILD_INSTALLED && state != CHILD_REKEYING ) ||
+ (old == CHILD_DELETING && state == CHILD_DESTROYING))
+ {
+ updown(ike_sa, child_sa, FALSE);
+ }
+ else if (state == CHILD_INSTALLED)
+ {
+ updown(ike_sa, child_sa, TRUE);
+ }
+ return TRUE;
+}
+
+/**
+ * Implementation of plugin_t.destroy
+ */
+static void destroy(private_updown_plugin_t *this)
+{
+ charon->bus->remove_listener(charon->bus, &this->listener);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_updown_plugin_t *this = malloc_thing(private_updown_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ memset(&this->listener, 0, sizeof(listener_t));
+ this->listener.child_state_change = child_state_change;
+
+ charon->bus->add_listener(charon->bus, &this->listener);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/charon/plugins/updown/updown_plugin.h b/src/charon/plugins/updown/updown_plugin.h
new file mode 100644
index 000000000..4d0a930c2
--- /dev/null
+++ b/src/charon/plugins/updown/updown_plugin.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup updown updown
+ * @ingroup cplugins
+ *
+ * @defgroup updown_plugin updown_plugin
+ * @{ @ingroup updown
+ */
+
+#ifndef UPDOWN_PLUGIN_H_
+#define UPDOWN_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct updown_plugin_t updown_plugin_t;
+
+/**
+ * Updown firewall script invocation plugin, compatible to pluto ones.
+ */
+struct updown_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a updown_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* UPDOWN_PLUGIN_H_ @}*/
diff --git a/src/charon/sa/child_sa.c b/src/charon/sa/child_sa.c
index 932828d11..d0df5454b 100644
--- a/src/charon/sa/child_sa.c
+++ b/src/charon/sa/child_sa.c
@@ -30,6 +30,7 @@ ENUM(child_sa_state_names, CHILD_CREATED, CHILD_DESTROYING,
"CREATED",
"ROUTED",
"INSTALLED",
+ "UPDATING",
"REKEYING",
"DELETING",
"DESTROYING",
@@ -49,8 +50,6 @@ struct private_child_sa_t {
struct {
/** address of peer */
host_t *addr;
- /** id of peer */
- identification_t *id;
/** actual used SPI, 0 if unused */
u_int32_t spi;
/** Compression Parameter Index (CPI) used, 0 if unused */
@@ -143,19 +142,9 @@ struct private_child_sa_t {
ipsec_mode_t mode;
/**
- * virtual IP assigned to local host
- */
- host_t *virtual_ip;
-
- /**
* config used to create this child
*/
child_cfg_t *config;
-
- /**
- * cached interface name for iptables
- */
- char *iface;
};
typedef struct keylen_entry_t keylen_entry_t;
@@ -404,170 +393,10 @@ static void get_stats(private_child_sa_t *this, ipsec_mode_t *mode,
}
/**
- * Run the up/down script
- */
-static void updown(private_child_sa_t *this, bool up)
-{
- traffic_selector_t *my_ts, *other_ts;
- enumerator_t *enumerator;
- char *script;
-
- script = this->config->get_updown(this->config);
-
- if (script == NULL)
- {
- return;
- }
-
- enumerator = create_policy_enumerator(this);
- while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
- {
- char command[1024];
- char *my_client, *other_client, *my_client_mask, *other_client_mask;
- char *pos, *virtual_ip;
- FILE *shell;
-
- /* get subnet/bits from string */
- asprintf(&my_client, "%R", my_ts);
- pos = strchr(my_client, '/');
- *pos = '\0';
- my_client_mask = pos + 1;
- pos = strchr(my_client_mask, '[');
- if (pos)
- {
- *pos = '\0';
- }
- asprintf(&other_client, "%R", other_ts);
- pos = strchr(other_client, '/');
- *pos = '\0';
- other_client_mask = pos + 1;
- pos = strchr(other_client_mask, '[');
- if (pos)
- {
- *pos = '\0';
- }
-
- if (this->virtual_ip)
- {
- asprintf(&virtual_ip, "PLUTO_MY_SOURCEIP='%H' ",
- this->virtual_ip);
- }
- else
- {
- asprintf(&virtual_ip, "");
- }
-
- /* we cache the iface name, as it may not be available when
- * the SA gets deleted */
- if (up)
- {
- free(this->iface);
- this->iface = charon->kernel_interface->get_interface(
- charon->kernel_interface, this->me.addr);
- }
-
- /* build the command with all env variables.
- * TODO: PLUTO_PEER_CA and PLUTO_NEXT_HOP are currently missing
- */
- snprintf(command, sizeof(command),
- "2>&1 "
- "PLUTO_VERSION='1.1' "
- "PLUTO_VERB='%s%s%s' "
- "PLUTO_CONNECTION='%s' "
- "PLUTO_INTERFACE='%s' "
- "PLUTO_REQID='%u' "
- "PLUTO_ME='%H' "
- "PLUTO_MY_ID='%D' "
- "PLUTO_MY_CLIENT='%s/%s' "
- "PLUTO_MY_CLIENT_NET='%s' "
- "PLUTO_MY_CLIENT_MASK='%s' "
- "PLUTO_MY_PORT='%u' "
- "PLUTO_MY_PROTOCOL='%u' "
- "PLUTO_PEER='%H' "
- "PLUTO_PEER_ID='%D' "
- "PLUTO_PEER_CLIENT='%s/%s' "
- "PLUTO_PEER_CLIENT_NET='%s' "
- "PLUTO_PEER_CLIENT_MASK='%s' "
- "PLUTO_PEER_PORT='%u' "
- "PLUTO_PEER_PROTOCOL='%u' "
- "%s"
- "%s"
- "%s",
- up ? "up" : "down",
- my_ts->is_host(my_ts, this->me.addr) ? "-host" : "-client",
- this->me.addr->get_family(this->me.addr) == AF_INET ? "" : "-v6",
- this->config->get_name(this->config),
- this->iface ? this->iface : "unknown",
- this->reqid,
- this->me.addr,
- this->me.id,
- my_client, my_client_mask,
- my_client, my_client_mask,
- my_ts->get_from_port(my_ts),
- my_ts->get_protocol(my_ts),
- this->other.addr,
- this->other.id,
- other_client, other_client_mask,
- other_client, other_client_mask,
- other_ts->get_from_port(other_ts),
- other_ts->get_protocol(other_ts),
- virtual_ip,
- this->config->get_hostaccess(this->config) ?
- "PLUTO_HOST_ACCESS='1' " : "",
- script);
- free(my_client);
- free(other_client);
- free(virtual_ip);
-
- DBG3(DBG_CHD, "running updown script: %s", command);
- shell = popen(command, "r");
-
- if (shell == NULL)
- {
- DBG1(DBG_CHD, "could not execute updown script '%s'", script);
- return;
- }
-
- while (TRUE)
- {
- char resp[128];
-
- if (fgets(resp, sizeof(resp), shell) == NULL)
- {
- if (ferror(shell))
- {
- DBG1(DBG_CHD, "error reading output from updown script");
- return;
- }
- else
- {
- break;
- }
- }
- else
- {
- char *e = resp + strlen(resp);
- if (e > resp && e[-1] == '\n')
- { /* trim trailing '\n' */
- e[-1] = '\0';
- }
- DBG1(DBG_CHD, "updown: %s", resp);
- }
- }
- pclose(shell);
- }
- enumerator->destroy(enumerator);
-}
-
-/**
* Implements child_sa_t.set_state
*/
static void set_state(private_child_sa_t *this, child_sa_state_t state)
{
- if (state == CHILD_INSTALLED)
- {
- updown(this, TRUE);
- }
charon->bus->child_state_change(charon->bus, &this->public, state);
this->state = state;
}
@@ -955,27 +784,32 @@ static status_t get_use_time(private_child_sa_t *this,
* Implementation of child_sa_t.update_hosts.
*/
static status_t update_hosts(private_child_sa_t *this,
- host_t *me, host_t *other, bool encap)
+ host_t *me, host_t *other, host_t *vip, bool encap)
{
+ child_sa_state_t old;
+
/* anything changed at all? */
if (me->equals(me, this->me.addr) &&
other->equals(other, this->other.addr) && this->encap == encap)
{
return SUCCESS;
}
- /* run updown script to remove iptables rules */
- updown(this, FALSE);
+
+ old = this->state;
+ set_state(this, CHILD_UPDATING);
this->encap = encap;
if (this->ipcomp != IPCOMP_NONE)
{
/* update our (initator) IPComp SA */
- charon->kernel_interface->update_sa(charon->kernel_interface, htonl(ntohs(this->me.cpi)),
- IPPROTO_COMP, this->other.addr, this->me.addr, other, me, FALSE);
+ charon->kernel_interface->update_sa(charon->kernel_interface,
+ htonl(ntohs(this->me.cpi)), IPPROTO_COMP,
+ this->other.addr, this->me.addr, other, me, FALSE);
/* update his (responder) IPComp SA */
- charon->kernel_interface->update_sa(charon->kernel_interface, htonl(ntohs(this->other.cpi)),
- IPPROTO_COMP, this->me.addr, this->other.addr, me, other, FALSE);
+ charon->kernel_interface->update_sa(charon->kernel_interface,
+ htonl(ntohs(this->other.cpi)), IPPROTO_COMP,
+ this->me.addr, this->other.addr, me, other, FALSE);
}
/* update our (initator) SA */
@@ -1018,12 +852,10 @@ static status_t update_hosts(private_child_sa_t *this,
/* we reinstall the virtual IP to handle interface roaming
* correctly */
- if (this->virtual_ip)
+ if (vip)
{
- charon->kernel_interface->del_ip(charon->kernel_interface,
- this->virtual_ip);
- charon->kernel_interface->add_ip(charon->kernel_interface,
- this->virtual_ip, me);
+ charon->kernel_interface->del_ip(charon->kernel_interface, vip);
+ charon->kernel_interface->add_ip(charon->kernel_interface, vip, me);
}
/* reinstall updated policies */
@@ -1052,21 +884,12 @@ static status_t update_hosts(private_child_sa_t *this,
this->other.addr = other->clone(other);
}
- /* install new iptables rules */
- updown(this, TRUE);
+ set_state(this, old);
return SUCCESS;
}
/**
- * Implementation of child_sa_t.set_virtual_ip.
- */
-static void set_virtual_ip(private_child_sa_t *this, host_t *ip)
-{
- this->virtual_ip = ip->clone(ip);
-}
-
-/**
* Implementation of child_sa_t.activate_ipcomp.
*/
static void activate_ipcomp(private_child_sa_t *this, ipcomp_transform_t ipcomp,
@@ -1098,11 +921,6 @@ static void destroy(private_child_sa_t *this)
enumerator_t *enumerator;
traffic_selector_t *my_ts, *other_ts;
- if (this->state == CHILD_DELETING || this->state == CHILD_INSTALLED)
- {
- updown(this, FALSE);
- }
-
set_state(this, CHILD_DESTROYING);
/* delete SAs in the kernel, if they are set up */
@@ -1158,11 +976,7 @@ static void destroy(private_child_sa_t *this)
this->other_ts->destroy_offset(this->other_ts, offsetof(traffic_selector_t, destroy));
this->me.addr->destroy(this->me.addr);
this->other.addr->destroy(this->other.addr);
- this->me.id->destroy(this->me.id);
- this->other.id->destroy(this->other.id);
this->config->destroy(this->config);
- free(this->iface);
- DESTROY_IF(this->virtual_ip);
free(this);
}
@@ -1170,7 +984,6 @@ static void destroy(private_child_sa_t *this)
* Described in header.
*/
child_sa_t * child_sa_create(host_t *me, host_t* other,
- identification_t *my_id, identification_t *other_id,
child_cfg_t *config, u_int32_t rekey, bool encap)
{
static u_int32_t reqid = 0;
@@ -1186,7 +999,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
this->public.alloc = (status_t(*)(child_sa_t*,linked_list_t*))alloc;
this->public.add = (status_t(*)(child_sa_t*,proposal_t*,ipsec_mode_t,prf_plus_t*))add;
this->public.update = (status_t(*)(child_sa_t*,proposal_t*,ipsec_mode_t,prf_plus_t*))update;
- this->public.update_hosts = (status_t (*)(child_sa_t*,host_t*,host_t*,bool))update_hosts;
+ this->public.update_hosts = (status_t (*)(child_sa_t*,host_t*,host_t*,host_t*,bool))update_hosts;
this->public.add_policies = (status_t (*)(child_sa_t*, linked_list_t*,linked_list_t*,ipsec_mode_t,protocol_id_t))add_policies;
this->public.get_traffic_selectors = (linked_list_t*(*)(child_sa_t*,bool))get_traffic_selectors;
this->public.create_policy_enumerator = (enumerator_t*(*)(child_sa_t*))create_policy_enumerator;
@@ -1196,14 +1009,11 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
this->public.get_config = (child_cfg_t*(*)(child_sa_t*))get_config;
this->public.activate_ipcomp = (void(*)(child_sa_t*,ipcomp_transform_t,u_int16_t))activate_ipcomp;
this->public.allocate_cpi = (u_int16_t(*)(child_sa_t*))allocate_cpi;
- this->public.set_virtual_ip = (void(*)(child_sa_t*,host_t*))set_virtual_ip;
this->public.destroy = (void(*)(child_sa_t*))destroy;
/* private data */
this->me.addr = me->clone(me);
this->other.addr = other->clone(other);
- this->me.id = my_id->clone(my_id);
- this->other.id = other_id->clone(other_id);
this->me.spi = 0;
this->me.cpi = 0;
this->other.spi = 0;
@@ -1224,10 +1034,9 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
this->other_ts = linked_list_create();
this->protocol = PROTO_NONE;
this->mode = MODE_TUNNEL;
- this->virtual_ip = NULL;
- this->iface = NULL;
this->config = config;
config->get_ref(config);
return &this->public;
}
+
diff --git a/src/charon/sa/child_sa.h b/src/charon/sa/child_sa.h
index cda1dc70a..11c3a0af7 100644
--- a/src/charon/sa/child_sa.h
+++ b/src/charon/sa/child_sa.h
@@ -55,6 +55,11 @@ enum child_sa_state_t {
CHILD_INSTALLED,
/**
+ * While updating hosts, in update_hosts()
+ */
+ CHILD_UPDATING,
+
+ /**
* CHILD_SA which is rekeying
*/
CHILD_REKEYING,
@@ -207,11 +212,12 @@ struct child_sa_t {
*
* @param me the new local host
* @param other the new remote host
+ * @param vip virtual IP, if any
* @param TRUE to use UDP encapsulation for NAT traversal
* @return SUCCESS or FAILED
*/
status_t (*update_hosts)(child_sa_t *this, host_t *me, host_t *other,
- bool encap);
+ host_t *vip, bool encap);
/**
* Install the policies using some traffic selectors.
@@ -273,16 +279,6 @@ struct child_sa_t {
child_cfg_t* (*get_config) (child_sa_t *this);
/**
- * Set the virtual IP used received from IRAS.
- *
- * To allow proper setup of firewall rules, the virtual IP is required
- * for filtering.
- *
- * @param ip own virtual IP
- */
- void (*set_virtual_ip) (child_sa_t *this, host_t *ip);
-
- /**
* Activate IPComp by setting the transform ID and CPI values.
*
* @param ipcomp the IPComp transform to use
@@ -316,8 +312,7 @@ struct child_sa_t {
* @param encap TRUE to enable UDP encapsulation (NAT traversal)
* @return child_sa_t object
*/
-child_sa_t * child_sa_create(host_t *me, host_t *other,
- identification_t *my_id, identification_t* other_id,
- child_cfg_t *config, u_int32_t reqid, bool encap);
+child_sa_t * child_sa_create(host_t *me, host_t *other, child_cfg_t *config,
+ u_int32_t reqid, bool encap);
#endif /*CHILD_SA_H_ @} */
diff --git a/src/charon/sa/ike_sa.c b/src/charon/sa/ike_sa.c
index 28241cfb7..1d45acbba 100644
--- a/src/charon/sa/ike_sa.c
+++ b/src/charon/sa/ike_sa.c
@@ -927,7 +927,7 @@ static void update_hosts(private_ike_sa_t *this, host_t *me, host_t *other)
while (iterator->iterate(iterator, (void**)&child_sa))
{
child_sa->update_hosts(child_sa, this->my_host, this->other_host,
- has_condition(this, COND_NAT_ANY));
+ this->my_virtual_ip, has_condition(this, COND_NAT_ANY));
}
iterator->destroy(iterator);
}
@@ -1285,8 +1285,8 @@ static status_t route(private_ike_sa_t *this, child_cfg_t *child_cfg)
resolve_hosts(this);
/* install kernel policies */
- child_sa = child_sa_create(this->my_host, this->other_host, this->my_id,
- this->other_id, child_cfg, 0, FALSE);
+ child_sa = child_sa_create(this->my_host, this->other_host,
+ child_cfg, 0, FALSE);
me = this->my_host;
if (this->my_virtual_ip)
{
@@ -2481,6 +2481,9 @@ static void destroy(private_ike_sa_t *this)
this->child_sas->destroy_offset(this->child_sas, offsetof(child_sa_t, destroy));
+ /* unset SA after here to avoid usage by the listeners */
+ charon->bus->set_sa(charon->bus, NULL);
+
this->task_manager->destroy(this->task_manager);
DESTROY_IF(this->crypter_in);
diff --git a/src/charon/sa/ike_sa_manager.c b/src/charon/sa/ike_sa_manager.c
index 1eedddb22..4db9d00c3 100644
--- a/src/charon/sa/ike_sa_manager.c
+++ b/src/charon/sa/ike_sa_manager.c
@@ -880,7 +880,6 @@ static status_t checkin_and_destroy(private_ike_sa_manager_t *this, ike_sa_t *ik
ike_sa_id = ike_sa->get_id(ike_sa);
DBG2(DBG_MGR, "checkin and destroy IKE_SA");
- charon->bus->set_sa(charon->bus, NULL);
pthread_mutex_lock(&(this->mutex));
@@ -899,6 +898,7 @@ static status_t checkin_and_destroy(private_ike_sa_manager_t *this, ike_sa_t *ik
DBG2(DBG_MGR, "tried to check-in and delete nonexisting IKE_SA");
retval = NOT_FOUND;
}
+ charon->bus->set_sa(charon->bus, NULL);
pthread_mutex_unlock(&(this->mutex));
return retval;
@@ -981,6 +981,7 @@ static void flush(private_ike_sa_manager_t *this)
enumerator = this->ike_sa_list->create_enumerator(this->ike_sa_list);
while (enumerator->enumerate(enumerator, &entry))
{
+ charon->bus->set_sa(charon->bus, entry->ike_sa);
entry->ike_sa->delete(entry->ike_sa);
}
enumerator->destroy(enumerator);
@@ -990,8 +991,10 @@ static void flush(private_ike_sa_manager_t *this)
while (this->ike_sa_list->remove_last(this->ike_sa_list,
(void**)&entry) == SUCCESS)
{
+ charon->bus->set_sa(charon->bus, entry->ike_sa);
entry_destroy(entry);
}
+ charon->bus->set_sa(charon->bus, NULL);
pthread_mutex_unlock(&(this->mutex));
}
diff --git a/src/charon/sa/tasks/child_create.c b/src/charon/sa/tasks/child_create.c
index 6c673927c..78a06e330 100644
--- a/src/charon/sa/tasks/child_create.c
+++ b/src/charon/sa/tasks/child_create.c
@@ -260,11 +260,6 @@ static status_t select_and_install(private_child_create_t *this, bool no_dh)
{
my_vip = me;
}
- else if (this->initiator)
- {
- /* to setup firewall rules correctly, CHILD_SA needs the virtual IP */
- this->child_sa->set_virtual_ip(this->child_sa, my_vip);
- }
if (other_vip == NULL)
{
other_vip = other;
@@ -639,11 +634,8 @@ static status_t build_i(private_child_create_t *this, message_t *message)
this->dh_group == MODP_NONE);
this->mode = this->config->get_mode(this->config);
- this->child_sa = child_sa_create(
- this->ike_sa->get_my_host(this->ike_sa),
- this->ike_sa->get_other_host(this->ike_sa),
- this->ike_sa->get_my_id(this->ike_sa),
- this->ike_sa->get_other_id(this->ike_sa), this->config, this->reqid,
+ this->child_sa = child_sa_create(this->ike_sa->get_my_host(this->ike_sa),
+ this->ike_sa->get_other_host(this->ike_sa), this->config, this->reqid,
this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY));
if (this->child_sa->alloc(this->child_sa, this->proposals) != SUCCESS)
@@ -822,11 +814,8 @@ static status_t build_r(private_child_create_t *this, message_t *message)
}
iterator->destroy(iterator);
- this->child_sa = child_sa_create(
- this->ike_sa->get_my_host(this->ike_sa),
- this->ike_sa->get_other_host(this->ike_sa),
- this->ike_sa->get_my_id(this->ike_sa),
- this->ike_sa->get_other_id(this->ike_sa), this->config, this->reqid,
+ this->child_sa = child_sa_create(this->ike_sa->get_my_host(this->ike_sa),
+ this->ike_sa->get_other_host(this->ike_sa), this->config, this->reqid,
this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY));
if (this->config->use_ipcomp(this->config) &&
diff --git a/src/charon/sa/tasks/ike_mobike.c b/src/charon/sa/tasks/ike_mobike.c
index 54b7d0a7b..b3bffd670 100644
--- a/src/charon/sa/tasks/ike_mobike.c
+++ b/src/charon/sa/tasks/ike_mobike.c
@@ -254,6 +254,7 @@ static void update_children(private_ike_mobike_t *this)
child_sa->update_hosts(child_sa,
this->ike_sa->get_my_host(this->ike_sa),
this->ike_sa->get_other_host(this->ike_sa),
+ this->ike_sa->get_virtual_ip(this->ike_sa, TRUE),
this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY));
}
iterator->destroy(iterator);