summaryrefslogtreecommitdiff
path: root/src/libcharon/plugins/updown
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/plugins/updown')
-rw-r--r--src/libcharon/plugins/updown/Makefile.am1
-rw-r--r--src/libcharon/plugins/updown/Makefile.in18
-rw-r--r--src/libcharon/plugins/updown/updown_handler.c243
-rw-r--r--src/libcharon/plugins/updown/updown_handler.h57
-rw-r--r--src/libcharon/plugins/updown/updown_listener.c117
-rw-r--r--src/libcharon/plugins/updown/updown_listener.h4
-rw-r--r--src/libcharon/plugins/updown/updown_plugin.c22
7 files changed, 434 insertions, 28 deletions
diff --git a/src/libcharon/plugins/updown/Makefile.am b/src/libcharon/plugins/updown/Makefile.am
index 312c8d7e8..30683d83e 100644
--- a/src/libcharon/plugins/updown/Makefile.am
+++ b/src/libcharon/plugins/updown/Makefile.am
@@ -12,6 +12,7 @@ endif
libstrongswan_updown_la_SOURCES = \
updown_plugin.h updown_plugin.c \
+ updown_handler.h updown_handler.c \
updown_listener.h updown_listener.c
libstrongswan_updown_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/updown/Makefile.in b/src/libcharon/plugins/updown/Makefile.in
index fb7b38f65..0f3463704 100644
--- a/src/libcharon/plugins/updown/Makefile.in
+++ b/src/libcharon/plugins/updown/Makefile.in
@@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
@@ -76,7 +77,7 @@ am__installdirs = "$(DESTDIR)$(plugindir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
libstrongswan_updown_la_LIBADD =
am_libstrongswan_updown_la_OBJECTS = updown_plugin.lo \
- updown_listener.lo
+ updown_handler.lo updown_listener.lo
libstrongswan_updown_la_OBJECTS = \
$(am_libstrongswan_updown_la_OBJECTS)
libstrongswan_updown_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
@@ -85,7 +86,7 @@ libstrongswan_updown_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
@MONOLITHIC_FALSE@am_libstrongswan_updown_la_rpath = -rpath \
@MONOLITHIC_FALSE@ $(plugindir)
@MONOLITHIC_TRUE@am_libstrongswan_updown_la_rpath =
-DEFAULT_INCLUDES = -I.@am__isrc@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
@@ -111,6 +112,7 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
+BFDLIB = @BFDLIB@
BTLIB = @BTLIB@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
@@ -205,11 +207,14 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+charon_natt_port = @charon_natt_port@
+charon_plugins = @charon_plugins@
+charon_udp_port = @charon_udp_port@
clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
-default_pkcs11 = @default_pkcs11@
+dev_headers = @dev_headers@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
@@ -226,11 +231,12 @@ imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
+ipsec_script = @ipsec_script@
+ipsec_script_upper = @ipsec_script_upper@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
-libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
linux_headers = @linux_headers@
@@ -246,6 +252,7 @@ mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
+nm_plugins = @nm_plugins@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
@@ -255,7 +262,6 @@ pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
plugindir = @plugindir@
-pluto_plugins = @pluto_plugins@
pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
@@ -291,6 +297,7 @@ AM_CFLAGS = -rdynamic
@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-updown.la
libstrongswan_updown_la_SOURCES = \
updown_plugin.h updown_plugin.c \
+ updown_handler.h updown_handler.c \
updown_listener.h updown_listener.c
libstrongswan_updown_la_LDFLAGS = -module -avoid-version
@@ -377,6 +384,7 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/updown_handler.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/updown_listener.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/updown_plugin.Plo@am__quote@
diff --git a/src/libcharon/plugins/updown/updown_handler.c b/src/libcharon/plugins/updown/updown_handler.c
new file mode 100644
index 000000000..b2ac02e85
--- /dev/null
+++ b/src/libcharon/plugins/updown/updown_handler.c
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2012 Martin Willi
+ * Copyright (C) 2012 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "updown_handler.h"
+
+#include <daemon.h>
+#include <utils/linked_list.h>
+#include <threading/rwlock.h>
+
+typedef struct private_updown_handler_t private_updown_handler_t;
+
+/**
+ * Private data of an updown_handler_t object.
+ */
+struct private_updown_handler_t {
+
+ /**
+ * Public updown_handler_t interface.
+ */
+ updown_handler_t public;
+
+ /**
+ * List of connection specific attributes, as attributes_t
+ */
+ linked_list_t *attrs;
+
+ /**
+ * rwlock to lock access to pools
+ */
+ rwlock_t *lock;
+};
+
+/**
+ * Attributes assigned to an IKE_SA
+ */
+typedef struct {
+ /** unique IKE_SA identifier */
+ u_int id;
+ /** list of DNS attributes, as host_t */
+ linked_list_t *dns;
+} attributes_t;
+
+/**
+ * Destroy an attributes_t entry
+ */
+static void attributes_destroy(attributes_t *this)
+{
+ this->dns->destroy_offset(this->dns, offsetof(host_t, destroy));
+ free(this);
+}
+
+METHOD(attribute_handler_t, handle, bool,
+ private_updown_handler_t *this, identification_t *server,
+ configuration_attribute_type_t type, chunk_t data)
+{
+ attributes_t *current, *attr = NULL;
+ enumerator_t *enumerator;
+ ike_sa_t *ike_sa;
+ host_t *host;
+
+ ike_sa = charon->bus->get_sa(charon->bus);
+ if (!ike_sa)
+ {
+ return FALSE;
+ }
+ switch (type)
+ {
+ case INTERNAL_IP4_DNS:
+ host = host_create_from_chunk(AF_INET, data, 0);
+ break;
+ case INTERNAL_IP6_DNS:
+ host = host_create_from_chunk(AF_INET6, data, 0);
+ break;
+ default:
+ return FALSE;
+ }
+ if (!host)
+ {
+ return FALSE;
+ }
+
+ this->lock->write_lock(this->lock);
+ enumerator = this->attrs->create_enumerator(this->attrs);
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ if (current->id == ike_sa->get_unique_id(ike_sa))
+ {
+ attr = current;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (!attr)
+ {
+ INIT(attr,
+ .id = ike_sa->get_unique_id(ike_sa),
+ .dns = linked_list_create(),
+ );
+ this->attrs->insert_last(this->attrs, attr);
+ }
+ attr->dns->insert_last(attr->dns, host);
+ this->lock->unlock(this->lock);
+
+ return TRUE;
+}
+
+METHOD(attribute_handler_t, release, void,
+ private_updown_handler_t *this, identification_t *server,
+ configuration_attribute_type_t type, chunk_t data)
+{
+ attributes_t *attr;
+ enumerator_t *enumerator, *servers;
+ ike_sa_t *ike_sa;
+ host_t *host;
+ bool found = FALSE;
+ int family;
+
+ switch (type)
+ {
+ case INTERNAL_IP4_DNS:
+ family = AF_INET;
+ break;
+ case INTERNAL_IP6_DNS:
+ family = AF_INET6;
+ break;
+ default:
+ return;
+ }
+
+ ike_sa = charon->bus->get_sa(charon->bus);
+ if (ike_sa)
+ {
+ this->lock->write_lock(this->lock);
+ enumerator = this->attrs->create_enumerator(this->attrs);
+ while (enumerator->enumerate(enumerator, &attr))
+ {
+ if (attr->id == ike_sa->get_unique_id(ike_sa))
+ {
+ servers = attr->dns->create_enumerator(attr->dns);
+ while (servers->enumerate(servers, &host))
+ {
+ if (host->get_family(host) == family &&
+ chunk_equals(data, host->get_address(host)))
+ {
+ attr->dns->remove_at(attr->dns, servers);
+ host->destroy(host);
+ found = TRUE;
+ break;
+ }
+ }
+ servers->destroy(servers);
+ if (attr->dns->get_count(attr->dns) == 0)
+ {
+ this->attrs->remove_at(this->attrs, enumerator);
+ attributes_destroy(attr);
+ break;
+ }
+ }
+ if (found)
+ {
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
+ }
+}
+
+METHOD(updown_handler_t, create_dns_enumerator, enumerator_t*,
+ private_updown_handler_t *this, u_int id)
+{
+ attributes_t *attr;
+ enumerator_t *enumerator;
+ ike_sa_t *ike_sa;
+
+ ike_sa = charon->bus->get_sa(charon->bus);
+ if (!ike_sa)
+ {
+ return FALSE;
+ }
+
+ this->lock->read_lock(this->lock);
+ enumerator = this->attrs->create_enumerator(this->attrs);
+ while (enumerator->enumerate(enumerator, &attr))
+ {
+ if (attr->id == ike_sa->get_unique_id(ike_sa))
+ {
+ enumerator->destroy(enumerator);
+ return enumerator_create_cleaner(
+ attr->dns->create_enumerator(attr->dns),
+ (void*)this->lock->unlock, this->lock);
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
+
+ return enumerator_create_empty();
+}
+
+
+METHOD(updown_handler_t, destroy, void,
+ private_updown_handler_t *this)
+{
+ this->lock->destroy(this->lock);
+ this->attrs->destroy_function(this->attrs, (void*)attributes_destroy);
+ free(this);
+}
+
+/**
+ * See header
+ */
+updown_handler_t *updown_handler_create()
+{
+ private_updown_handler_t *this;
+
+ INIT(this,
+ .public = {
+ .handler = {
+ .handle = _handle,
+ .release = _release,
+ .create_attribute_enumerator = enumerator_create_empty,
+ },
+ .create_dns_enumerator = _create_dns_enumerator,
+ .destroy = _destroy,
+ },
+ .attrs = linked_list_create(),
+ .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+ );
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/updown/updown_handler.h b/src/libcharon/plugins/updown/updown_handler.h
new file mode 100644
index 000000000..d4de880b8
--- /dev/null
+++ b/src/libcharon/plugins/updown/updown_handler.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2012 Martin Willi
+ * Copyright (C) 2012 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup updown_handler updown_handler
+ * @{ @ingroup updown
+ */
+
+#ifndef UPDOWN_HANDLER_H_
+#define UPDOWN_HANDLER_H_
+
+#include <attributes/attribute_handler.h>
+
+typedef struct updown_handler_t updown_handler_t;
+
+/**
+ * Handler storing configuration attributes to pass to updown script.
+ */
+struct updown_handler_t {
+
+ /**
+ * Implements the attribute_handler_t interface
+ */
+ attribute_handler_t handler;
+
+ /**
+ * Create an enumerator over received DNS servers.
+ *
+ * @param id unique IKE_SA identifier to get attributes for
+ * @return enumerator over host_t*
+ */
+ enumerator_t* (*create_dns_enumerator)(updown_handler_t *this, u_int id);
+
+ /**
+ * Destroy a updown_handler_t.
+ */
+ void (*destroy)(updown_handler_t *this);
+};
+
+/**
+ * Create a updown_handler instance.
+ */
+updown_handler_t *updown_handler_create();
+
+#endif /** UPDOWN_HANDLER_H_ @}*/
diff --git a/src/libcharon/plugins/updown/updown_listener.c b/src/libcharon/plugins/updown/updown_listener.c
index 2bd757ec7..8b2af05b6 100644
--- a/src/libcharon/plugins/updown/updown_listener.c
+++ b/src/libcharon/plugins/updown/updown_listener.c
@@ -38,6 +38,11 @@ struct private_updown_listener_t {
* List of cached interface names
*/
linked_list_t *iface_cache;
+
+ /**
+ * DNS attribute handler
+ */
+ updown_handler_t *handler;
};
typedef struct cache_entry_t cache_entry_t;
@@ -90,6 +95,85 @@ static char* uncache_iface(private_updown_listener_t *this, u_int32_t reqid)
return iface;
}
+/**
+ * Create variables for handled DNS attributes
+ */
+static char *make_dns_vars(private_updown_listener_t *this, ike_sa_t *ike_sa)
+{
+ enumerator_t *enumerator;
+ host_t *host;
+ int v4 = 0, v6 = 0;
+ char total[512] = "", current[64];
+
+ if (!this->handler)
+ {
+ return strdup("");
+ }
+
+ enumerator = this->handler->create_dns_enumerator(this->handler,
+ ike_sa->get_unique_id(ike_sa));
+ while (enumerator->enumerate(enumerator, &host))
+ {
+ switch (host->get_family(host))
+ {
+ case AF_INET:
+ snprintf(current, sizeof(current),
+ "PLUTO_DNS4_%d='%H' ", ++v4, host);
+ break;
+ case AF_INET6:
+ snprintf(current, sizeof(current),
+ "PLUTO_DNS6_%d='%H' ", ++v6, host);
+ break;
+ default:
+ continue;
+ }
+ strncat(total, current, sizeof(total) - strlen(total) - 1);
+ }
+ enumerator->destroy(enumerator);
+
+ return strdup(total);
+}
+
+/**
+ * Create variables for local virtual IPs
+ */
+static char *make_vip_vars(private_updown_listener_t *this, ike_sa_t *ike_sa)
+{
+ enumerator_t *enumerator;
+ host_t *host;
+ int v4 = 0, v6 = 0;
+ char total[512] = "", current[64];
+ bool first = TRUE;
+
+ enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, TRUE);
+ while (enumerator->enumerate(enumerator, &host))
+ {
+ if (first)
+ { /* legacy variable for first VIP */
+ snprintf(current, sizeof(current),
+ "PLUTO_MY_SOURCEIP='%H' ", host);
+ strncat(total, current, sizeof(total) - strlen(total) - 1);
+ }
+ switch (host->get_family(host))
+ {
+ case AF_INET:
+ snprintf(current, sizeof(current),
+ "PLUTO_MY_SOURCEIP4_%d='%H' ", ++v4, host);
+ break;
+ case AF_INET6:
+ snprintf(current, sizeof(current),
+ "PLUTO_MY_SOURCEIP6_%d='%H' ", ++v6, host);
+ break;
+ default:
+ continue;
+ }
+ strncat(total, current, sizeof(total) - strlen(total) - 1);
+ }
+ enumerator->destroy(enumerator);
+
+ return strdup(total);
+}
+
METHOD(listener_t, child_updown, bool,
private_updown_listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
bool up)
@@ -97,11 +181,10 @@ METHOD(listener_t, child_updown, bool,
traffic_selector_t *my_ts, *other_ts;
enumerator_t *enumerator;
child_cfg_t *config;
- host_t *vip, *me, *other;
+ host_t *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);
@@ -117,7 +200,7 @@ METHOD(listener_t, child_updown, bool,
char command[1024];
host_t *my_client, *other_client;
u_int8_t my_client_mask, other_client_mask;
- char *virtual_ip, *iface, *mark_in, *mark_out, *udp_enc;
+ char *virtual_ip, *iface, *mark_in, *mark_out, *udp_enc, *dns;
mark_t mark;
bool is_host, is_ipv6;
FILE *shell;
@@ -125,20 +208,7 @@ METHOD(listener_t, child_updown, bool,
my_ts->to_subnet(my_ts, &my_client, &my_client_mask);
other_ts->to_subnet(other_ts, &other_client, &other_client_mask);
- if (vip)
- {
- if (asprintf(&virtual_ip, "PLUTO_MY_SOURCEIP='%H' ", vip) < 0)
- {
- virtual_ip = NULL;
- }
- }
- else
- {
- if (asprintf(&virtual_ip, "") < 0)
- {
- virtual_ip = NULL;
- }
- }
+ virtual_ip = make_vip_vars(this, ike_sa);
/* check for the presence of an inbound mark */
mark = config->get_mark(config, TRUE);
@@ -197,9 +267,8 @@ METHOD(listener_t, child_updown, bool,
if (up)
{
- iface = hydra->kernel_interface->get_interface(
- hydra->kernel_interface, me);
- if (iface)
+ if (hydra->kernel_interface->get_interface(hydra->kernel_interface,
+ me, &iface))
{
cache_iface(this, child_sa->get_reqid(child_sa), iface);
}
@@ -209,6 +278,8 @@ METHOD(listener_t, child_updown, bool,
iface = uncache_iface(this, child_sa->get_reqid(child_sa));
}
+ dns = make_dns_vars(this, ike_sa);
+
/* determine IPv4/IPv6 and client/host situation */
is_host = my_ts->is_host(my_ts, me);
is_ipv6 = is_host ? (me->get_family(me) == AF_INET6) :
@@ -239,6 +310,7 @@ METHOD(listener_t, child_updown, bool,
"%s"
"%s"
"%s"
+ "%s"
"%s",
up ? "up" : "down",
is_host ? "-host" : "-client",
@@ -259,6 +331,7 @@ METHOD(listener_t, child_updown, bool,
mark_out,
udp_enc,
config->get_hostaccess(config) ? "PLUTO_HOST_ACCESS='1' " : "",
+ dns,
script);
my_client->destroy(my_client);
other_client->destroy(other_client);
@@ -266,6 +339,7 @@ METHOD(listener_t, child_updown, bool,
free(mark_in);
free(mark_out);
free(udp_enc);
+ free(dns);
free(iface);
DBG3(DBG_CHD, "running updown script: %s", command);
@@ -315,7 +389,7 @@ METHOD(updown_listener_t, destroy, void,
/**
* See header
*/
-updown_listener_t *updown_listener_create()
+updown_listener_t *updown_listener_create(updown_handler_t *handler)
{
private_updown_listener_t *this;
@@ -327,6 +401,7 @@ updown_listener_t *updown_listener_create()
.destroy = _destroy,
},
.iface_cache = linked_list_create(),
+ .handler = handler,
);
return &this->public;
diff --git a/src/libcharon/plugins/updown/updown_listener.h b/src/libcharon/plugins/updown/updown_listener.h
index 5b866c4e5..2d9b56ade 100644
--- a/src/libcharon/plugins/updown/updown_listener.h
+++ b/src/libcharon/plugins/updown/updown_listener.h
@@ -23,6 +23,8 @@
#include <bus/bus.h>
+#include "updown_handler.h"
+
typedef struct updown_listener_t updown_listener_t;
/**
@@ -44,6 +46,6 @@ struct updown_listener_t {
/**
* Create a updown_listener instance.
*/
-updown_listener_t *updown_listener_create();
+updown_listener_t *updown_listener_create(updown_handler_t *handler);
#endif /** UPDOWN_LISTENER_H_ @}*/
diff --git a/src/libcharon/plugins/updown/updown_plugin.c b/src/libcharon/plugins/updown/updown_plugin.c
index 2ce2d3257..e1f0d1380 100644
--- a/src/libcharon/plugins/updown/updown_plugin.c
+++ b/src/libcharon/plugins/updown/updown_plugin.c
@@ -15,8 +15,10 @@
#include "updown_plugin.h"
#include "updown_listener.h"
+#include "updown_handler.h"
#include <daemon.h>
+#include <hydra.h>
typedef struct private_updown_plugin_t private_updown_plugin_t;
@@ -34,6 +36,11 @@ struct private_updown_plugin_t {
* Listener interface, listens to CHILD_SA state changes
*/
updown_listener_t *listener;
+
+ /**
+ * Attribute handler, to pass DNS servers to updown
+ */
+ updown_handler_t *handler;
};
METHOD(plugin_t, get_name, char*,
@@ -47,6 +54,12 @@ METHOD(plugin_t, destroy, void,
{
charon->bus->remove_listener(charon->bus, &this->listener->listener);
this->listener->destroy(this->listener);
+ if (this->handler)
+ {
+ hydra->attributes->remove_handler(hydra->attributes,
+ &this->handler->handler);
+ this->handler->destroy(this->handler);
+ }
free(this);
}
@@ -65,9 +78,16 @@ plugin_t *updown_plugin_create()
.destroy = _destroy,
},
},
- .listener = updown_listener_create(),
);
+ if (lib->settings->get_bool(lib->settings,
+ "charon.plugins.updown.dns_handler", FALSE))
+ {
+ this->handler = updown_handler_create();
+ hydra->attributes->add_handler(hydra->attributes,
+ &this->handler->handler);
+ }
+ this->listener = updown_listener_create(this->handler);
charon->bus->add_listener(charon->bus, &this->listener->listener);
return &this->public.plugin;