summaryrefslogtreecommitdiff
path: root/src/libcharon/processing
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/processing')
-rw-r--r--src/libcharon/processing/jobs/acquire_job.c4
-rw-r--r--src/libcharon/processing/jobs/adopt_children_job.c177
-rw-r--r--src/libcharon/processing/jobs/adopt_children_job.h49
-rw-r--r--src/libcharon/processing/jobs/delete_child_sa_job.c15
-rw-r--r--src/libcharon/processing/jobs/delete_child_sa_job.h4
-rw-r--r--src/libcharon/processing/jobs/delete_ike_sa_job.c6
-rw-r--r--src/libcharon/processing/jobs/dpd_timeout_job.c118
-rw-r--r--src/libcharon/processing/jobs/dpd_timeout_job.h52
-rw-r--r--src/libcharon/processing/jobs/inactivity_job.c15
-rw-r--r--src/libcharon/processing/jobs/initiate_mediation_job.c25
-rw-r--r--src/libcharon/processing/jobs/mediation_job.c10
-rw-r--r--src/libcharon/processing/jobs/migrate_job.c21
-rw-r--r--src/libcharon/processing/jobs/process_message_job.c7
-rw-r--r--src/libcharon/processing/jobs/rekey_child_sa_job.c4
-rw-r--r--src/libcharon/processing/jobs/rekey_ike_sa_job.c4
-rw-r--r--src/libcharon/processing/jobs/retransmit_job.c4
-rw-r--r--src/libcharon/processing/jobs/retry_initiate_job.c95
-rw-r--r--src/libcharon/processing/jobs/retry_initiate_job.h48
-rw-r--r--src/libcharon/processing/jobs/roam_job.c5
-rw-r--r--src/libcharon/processing/jobs/send_dpd_job.c4
-rw-r--r--src/libcharon/processing/jobs/send_keepalive_job.c4
-rw-r--r--src/libcharon/processing/jobs/start_action_job.c11
-rw-r--r--src/libcharon/processing/jobs/update_sa_job.c4
23 files changed, 612 insertions, 74 deletions
diff --git a/src/libcharon/processing/jobs/acquire_job.c b/src/libcharon/processing/jobs/acquire_job.c
index 2d836b002..207f534ba 100644
--- a/src/libcharon/processing/jobs/acquire_job.c
+++ b/src/libcharon/processing/jobs/acquire_job.c
@@ -53,12 +53,12 @@ METHOD(job_t, destroy, void,
free(this);
}
-METHOD(job_t, execute, void,
+METHOD(job_t, execute, job_requeue_t,
private_acquire_job_t *this)
{
charon->traps->acquire(charon->traps, this->reqid,
this->src_ts, this->dst_ts);
- destroy(this);
+ return JOB_REQUEUE_NONE;
}
METHOD(job_t, get_priority, job_priority_t,
diff --git a/src/libcharon/processing/jobs/adopt_children_job.c b/src/libcharon/processing/jobs/adopt_children_job.c
new file mode 100644
index 000000000..df5b70c0f
--- /dev/null
+++ b/src/libcharon/processing/jobs/adopt_children_job.c
@@ -0,0 +1,177 @@
+/*
+ * 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 "adopt_children_job.h"
+
+#include <daemon.h>
+#include <hydra.h>
+
+typedef struct private_adopt_children_job_t private_adopt_children_job_t;
+
+/**
+ * Private data of an adopt_children_job_t object.
+ */
+struct private_adopt_children_job_t {
+
+ /**
+ * Public adopt_children_job_t interface.
+ */
+ adopt_children_job_t public;
+
+ /**
+ * IKE_SA id to adopt children from
+ */
+ ike_sa_id_t *id;
+};
+
+METHOD(job_t, destroy, void,
+ private_adopt_children_job_t *this)
+{
+ this->id->destroy(this->id);
+ free(this);
+}
+
+METHOD(job_t, execute, job_requeue_t,
+ private_adopt_children_job_t *this)
+{
+ identification_t *my_id, *other_id, *xauth;
+ host_t *me, *other;
+ peer_cfg_t *cfg;
+ linked_list_t *children;
+ enumerator_t *enumerator, *childenum;
+ ike_sa_id_t *id;
+ ike_sa_t *ike_sa;
+ child_sa_t *child_sa;
+
+ ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, this->id);
+ if (ike_sa)
+ {
+ /* get what we need from new SA */
+ me = ike_sa->get_my_host(ike_sa);
+ me = me->clone(me);
+ other = ike_sa->get_other_host(ike_sa);
+ other = other->clone(other);
+ my_id = ike_sa->get_my_id(ike_sa);
+ my_id = my_id->clone(my_id);
+ other_id = ike_sa->get_other_id(ike_sa);
+ other_id = other_id->clone(other_id);
+ xauth = ike_sa->get_other_eap_id(ike_sa);
+ xauth = xauth->clone(xauth);
+ cfg = ike_sa->get_peer_cfg(ike_sa);
+ cfg->get_ref(cfg);
+
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+
+ /* find old SA to adopt children from */
+ children = linked_list_create();
+ enumerator = charon->ike_sa_manager->create_id_enumerator(
+ charon->ike_sa_manager, my_id, xauth,
+ other->get_family(other));
+ while (enumerator->enumerate(enumerator, &id))
+ {
+ if (id->equals(id, this->id))
+ { /* not from self */
+ continue;
+ }
+ ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, id);
+ if (ike_sa)
+ {
+ if ((ike_sa->get_state(ike_sa) == IKE_ESTABLISHED ||
+ ike_sa->get_state(ike_sa) == IKE_PASSIVE) &&
+ me->equals(me, ike_sa->get_my_host(ike_sa)) &&
+ other->equals(other, ike_sa->get_other_host(ike_sa)) &&
+ other_id->equals(other_id, ike_sa->get_other_id(ike_sa)) &&
+ cfg->equals(cfg, ike_sa->get_peer_cfg(ike_sa)))
+ {
+ childenum = ike_sa->create_child_sa_enumerator(ike_sa);
+ while (childenum->enumerate(childenum, &child_sa))
+ {
+ ike_sa->remove_child_sa(ike_sa, childenum);
+ children->insert_last(children, child_sa);
+ }
+ childenum->destroy(childenum);
+ DBG1(DBG_IKE, "detected reauth of existing IKE_SA, "
+ "adopting %d children", children->get_count(children));
+ ike_sa->set_state(ike_sa, IKE_DELETING);
+ charon->bus->ike_updown(charon->bus, ike_sa, FALSE);
+ charon->ike_sa_manager->checkin_and_destroy(
+ charon->ike_sa_manager, ike_sa);
+ }
+ else
+ {
+ charon->ike_sa_manager->checkin(
+ charon->ike_sa_manager, ike_sa);
+ }
+ if (children->get_count(children))
+ {
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ me->destroy(me);
+ other->destroy(other);
+ my_id->destroy(my_id);
+ other_id->destroy(other_id);
+ xauth->destroy(xauth);
+ cfg->destroy(cfg);
+
+ if (children->get_count(children))
+ {
+ /* adopt children by new SA */
+ ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
+ this->id);
+ if (ike_sa)
+ {
+ while (children->remove_last(children,
+ (void**)&child_sa) == SUCCESS)
+ {
+ ike_sa->add_child_sa(ike_sa, child_sa);
+ }
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ }
+ }
+ children->destroy_offset(children, offsetof(child_sa_t, destroy));
+ }
+ return JOB_REQUEUE_NONE;
+}
+
+METHOD(job_t, get_priority, job_priority_t,
+ private_adopt_children_job_t *this)
+{
+ return JOB_PRIO_HIGH;
+}
+
+/**
+ * See header
+ */
+adopt_children_job_t *adopt_children_job_create(ike_sa_id_t *id)
+{
+ private_adopt_children_job_t *this;
+
+ INIT(this,
+ .public = {
+ .job_interface = {
+ .execute = _execute,
+ .get_priority = _get_priority,
+ .destroy = _destroy,
+ },
+ },
+ .id = id->clone(id),
+ );
+
+ return &this->public;
+}
diff --git a/src/libcharon/processing/jobs/adopt_children_job.h b/src/libcharon/processing/jobs/adopt_children_job.h
new file mode 100644
index 000000000..073504abd
--- /dev/null
+++ b/src/libcharon/processing/jobs/adopt_children_job.h
@@ -0,0 +1,49 @@
+/*
+ * 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 adopt_children_job adopt_children_job
+ * @{ @ingroup cjobs
+ */
+
+#ifndef ADOPT_CHILDREN_JOB_H_
+#define ADOPT_CHILDREN_JOB_H_
+
+#include <library.h>
+#include <processing/jobs/job.h>
+#include <sa/ike_sa_id.h>
+
+typedef struct adopt_children_job_t adopt_children_job_t;
+
+/**
+ * Job adopting children after IKEv1 reauthentication from old SA.
+ */
+struct adopt_children_job_t {
+
+ /**
+ * Implements job_t.
+ */
+ job_t job_interface;
+};
+
+/**
+ * Create a adopt_children_job instance.
+ *
+ * @param id ike_sa_id_t of old ISAKMP SA to adopt children from
+ * @return job
+ */
+adopt_children_job_t *adopt_children_job_create(ike_sa_id_t *id);
+
+#endif /** ADOPT_CHILDREN_JOB_H_ @}*/
diff --git a/src/libcharon/processing/jobs/delete_child_sa_job.c b/src/libcharon/processing/jobs/delete_child_sa_job.c
index bd8bb9562..9afbac02b 100644
--- a/src/libcharon/processing/jobs/delete_child_sa_job.c
+++ b/src/libcharon/processing/jobs/delete_child_sa_job.c
@@ -44,6 +44,11 @@ struct private_delete_child_sa_job_t {
* inbound SPI of the CHILD_SA
*/
u_int32_t spi;
+
+ /**
+ * Delete for an expired CHILD_SA
+ */
+ bool expired;
};
METHOD(job_t, destroy, void,
@@ -52,7 +57,7 @@ METHOD(job_t, destroy, void,
free(this);
}
-METHOD(job_t, execute, void,
+METHOD(job_t, execute, job_requeue_t,
private_delete_child_sa_job_t *this)
{
ike_sa_t *ike_sa;
@@ -66,11 +71,11 @@ METHOD(job_t, execute, void,
}
else
{
- ike_sa->delete_child_sa(ike_sa, this->protocol, this->spi);
+ ike_sa->delete_child_sa(ike_sa, this->protocol, this->spi, this->expired);
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
}
- destroy(this);
+ return JOB_REQUEUE_NONE;
}
METHOD(job_t, get_priority, job_priority_t,
@@ -83,8 +88,7 @@ METHOD(job_t, get_priority, job_priority_t,
* Described in header
*/
delete_child_sa_job_t *delete_child_sa_job_create(u_int32_t reqid,
- protocol_id_t protocol,
- u_int32_t spi)
+ protocol_id_t protocol, u_int32_t spi, bool expired)
{
private_delete_child_sa_job_t *this;
@@ -99,6 +103,7 @@ delete_child_sa_job_t *delete_child_sa_job_create(u_int32_t reqid,
.reqid = reqid,
.protocol = protocol,
.spi = spi,
+ .expired = expired,
);
return &this->public;
diff --git a/src/libcharon/processing/jobs/delete_child_sa_job.h b/src/libcharon/processing/jobs/delete_child_sa_job.h
index fc0e2b518..be6d578bc 100644
--- a/src/libcharon/processing/jobs/delete_child_sa_job.h
+++ b/src/libcharon/processing/jobs/delete_child_sa_job.h
@@ -50,10 +50,10 @@ struct delete_child_sa_job_t {
* @param reqid reqid of the CHILD_SA, as used in kernel
* @param protocol protocol of the CHILD_SA
* @param spi security parameter index of the CHILD_SA
+ * @param expired TRUE if CHILD_SA already expired
* @return delete_child_sa_job_t object
*/
delete_child_sa_job_t *delete_child_sa_job_create(u_int32_t reqid,
- protocol_id_t protocol,
- u_int32_t spi);
+ protocol_id_t protocol, u_int32_t spi, bool expired);
#endif /** DELETE_CHILD_SA_JOB_H_ @}*/
diff --git a/src/libcharon/processing/jobs/delete_ike_sa_job.c b/src/libcharon/processing/jobs/delete_ike_sa_job.c
index c29b72230..08b41af8c 100644
--- a/src/libcharon/processing/jobs/delete_ike_sa_job.c
+++ b/src/libcharon/processing/jobs/delete_ike_sa_job.c
@@ -48,7 +48,7 @@ METHOD(job_t, destroy, void,
free(this);
}
-METHOD(job_t, execute, void,
+METHOD(job_t, execute, job_requeue_t,
private_delete_ike_sa_job_t *this)
{
ike_sa_t *ike_sa;
@@ -60,7 +60,7 @@ METHOD(job_t, execute, void,
if (ike_sa->get_state(ike_sa) == IKE_PASSIVE)
{
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
- return destroy(this);
+ return JOB_REQUEUE_NONE;
}
if (this->delete_if_established)
{
@@ -89,7 +89,7 @@ METHOD(job_t, execute, void,
}
}
}
- destroy(this);
+ return JOB_REQUEUE_NONE;
}
METHOD(job_t, get_priority, job_priority_t,
diff --git a/src/libcharon/processing/jobs/dpd_timeout_job.c b/src/libcharon/processing/jobs/dpd_timeout_job.c
new file mode 100644
index 000000000..91a76bbaf
--- /dev/null
+++ b/src/libcharon/processing/jobs/dpd_timeout_job.c
@@ -0,0 +1,118 @@
+/*
+ * 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 <stdlib.h>
+
+#include "dpd_timeout_job.h"
+
+#include <sa/ike_sa.h>
+#include <daemon.h>
+
+
+typedef struct private_dpd_timeout_job_t private_dpd_timeout_job_t;
+
+/**
+ * Private data
+ */
+struct private_dpd_timeout_job_t {
+
+ /**
+ * public dpd_timeout_job_t interface
+ */
+ dpd_timeout_job_t public;
+
+ /**
+ * IKE_SA identifier
+ */
+ ike_sa_id_t *ike_sa_id;
+
+ /**
+ * Timestamp of first DPD check
+ */
+ time_t check;
+};
+
+METHOD(job_t, destroy, void,
+ private_dpd_timeout_job_t *this)
+{
+ this->ike_sa_id->destroy(this->ike_sa_id);
+ free(this);
+}
+
+METHOD(job_t, execute, job_requeue_t,
+ private_dpd_timeout_job_t *this)
+{
+ time_t use_time, current;
+ enumerator_t *enumerator;
+ child_sa_t *child_sa;
+ ike_sa_t *ike_sa;
+
+ ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
+ this->ike_sa_id);
+ if (ike_sa)
+ {
+ use_time = ike_sa->get_statistic(ike_sa, STAT_INBOUND);
+
+ enumerator = ike_sa->create_child_sa_enumerator(ike_sa);
+ while (enumerator->enumerate(enumerator, &child_sa))
+ {
+ child_sa->get_usestats(child_sa, TRUE, &current, NULL);
+ use_time = max(use_time, current);
+ }
+ enumerator->destroy(enumerator);
+
+ /* check if no incoming packet during timeout, reestablish SA */
+ if (use_time < this->check)
+ {
+ DBG1(DBG_JOB, "DPD check timed out, enforcing DPD action");
+ ike_sa->reestablish(ike_sa);
+ charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
+ ike_sa);
+ }
+ else
+ {
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ }
+ }
+ return JOB_REQUEUE_NONE;
+}
+
+METHOD(job_t, get_priority, job_priority_t,
+ private_dpd_timeout_job_t *this)
+{
+ return JOB_PRIO_HIGH;
+}
+
+/*
+ * Described in header
+ */
+dpd_timeout_job_t *dpd_timeout_job_create(ike_sa_id_t *ike_sa_id)
+{
+ private_dpd_timeout_job_t *this;
+
+ INIT(this,
+ .public = {
+ .job_interface = {
+ .execute = _execute,
+ .get_priority = _get_priority,
+ .destroy = _destroy,
+ },
+ },
+ .ike_sa_id = ike_sa_id->clone(ike_sa_id),
+ .check = time_monotonic(NULL),
+ );
+
+ return &this->public;
+}
diff --git a/src/libcharon/processing/jobs/dpd_timeout_job.h b/src/libcharon/processing/jobs/dpd_timeout_job.h
new file mode 100644
index 000000000..573eb192d
--- /dev/null
+++ b/src/libcharon/processing/jobs/dpd_timeout_job.h
@@ -0,0 +1,52 @@
+/*
+ * 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 dpd_timeout_job dpd_timeout_job
+ * @{ @ingroup cjobs
+ */
+
+#ifndef DPD_TIMEOUT_JOB_H_
+#define DPD_TIMEOUT_JOB_H_
+
+typedef struct dpd_timeout_job_t dpd_timeout_job_t;
+
+#include <library.h>
+#include <processing/jobs/job.h>
+#include <sa/ike_sa_id.h>
+
+/**
+ * Job enforcing DPD timeout.
+ *
+ * This job detects if a DPD response has been received during the DPD timeout
+ * interval, and if not, enforced the DPD action.
+ */
+struct dpd_timeout_job_t {
+
+ /**
+ * implements job_t interface
+ */
+ job_t job_interface;
+};
+
+/**
+ * Creates a DPD timeout job.
+ *
+ * @param ike_sa_id ike_sa_id_t, gets cloned
+ * @return initiate_ike_sa_job_t object
+ */
+dpd_timeout_job_t *dpd_timeout_job_create(ike_sa_id_t *ike_sa_id);
+
+#endif /** DPD_TIMEOUT_JOB_H_ @}*/
diff --git a/src/libcharon/processing/jobs/inactivity_job.c b/src/libcharon/processing/jobs/inactivity_job.c
index 251b9ab03..3c56b0cd7 100644
--- a/src/libcharon/processing/jobs/inactivity_job.c
+++ b/src/libcharon/processing/jobs/inactivity_job.c
@@ -51,11 +51,11 @@ METHOD(job_t, destroy, void,
free(this);
}
-METHOD(job_t, execute, void,
+METHOD(job_t, execute, job_requeue_t,
private_inactivity_job_t *this)
{
ike_sa_t *ike_sa;
- bool rescheduled = FALSE;
+ u_int32_t reschedule = 0;
ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
this->reqid, TRUE);
@@ -87,9 +87,7 @@ METHOD(job_t, execute, void,
}
else
{
- lib->scheduler->schedule_job(lib->scheduler,
- &this->public.job_interface, this->timeout - diff);
- rescheduled = TRUE;
+ reschedule = this->timeout - diff;
}
}
children++;
@@ -108,7 +106,7 @@ METHOD(job_t, execute, void,
{
DBG1(DBG_JOB, "deleting CHILD_SA after %d seconds "
"of inactivity", this->timeout);
- status = ike_sa->delete_child_sa(ike_sa, proto, delete);
+ status = ike_sa->delete_child_sa(ike_sa, proto, delete, FALSE);
}
}
if (status == DESTROY_ME)
@@ -121,10 +119,11 @@ METHOD(job_t, execute, void,
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
}
}
- if (!rescheduled)
+ if (reschedule)
{
- destroy(this);
+ return JOB_RESCHEDULE(reschedule);
}
+ return JOB_REQUEUE_NONE;
}
METHOD(job_t, get_priority, job_priority_t,
diff --git a/src/libcharon/processing/jobs/initiate_mediation_job.c b/src/libcharon/processing/jobs/initiate_mediation_job.c
index e52f3c6df..17ab83053 100644
--- a/src/libcharon/processing/jobs/initiate_mediation_job.c
+++ b/src/libcharon/processing/jobs/initiate_mediation_job.c
@@ -54,7 +54,7 @@ METHOD(job_t, destroy, void,
*/
static bool initiate_callback(private_initiate_mediation_job_t *this,
debug_t group, level_t level, ike_sa_t *ike_sa,
- char *format, va_list args)
+ char *message)
{
if (ike_sa && !this->mediation_sa_id)
{
@@ -64,7 +64,7 @@ static bool initiate_callback(private_initiate_mediation_job_t *this,
return TRUE;
}
-METHOD(job_t, initiate, void,
+METHOD(job_t, initiate, job_requeue_t,
private_initiate_mediation_job_t *this)
{
ike_sa_t *mediated_sa, *mediation_sa;
@@ -93,8 +93,7 @@ METHOD(job_t, initiate, void,
mediated_cfg->destroy(mediated_cfg);
mediation_cfg->destroy(mediation_cfg);
enumerator->destroy(enumerator);
- destroy(this);
- return;
+ return JOB_REQUEUE_NONE;
}
enumerator->destroy(enumerator);
@@ -115,8 +114,7 @@ METHOD(job_t, initiate, void,
charon->ike_sa_manager->checkin(
charon->ike_sa_manager, mediated_sa);
}
- destroy(this);
- return;
+ return JOB_REQUEUE_NONE;
}
/* we need an additional reference because initiate consumes one */
mediation_cfg->get_ref(mediation_cfg);
@@ -134,8 +132,7 @@ METHOD(job_t, initiate, void,
charon->ike_sa_manager->checkin_and_destroy(
charon->ike_sa_manager, mediated_sa);
}
- destroy(this);
- return;
+ return JOB_REQUEUE_NONE;
}
mediation_cfg->destroy(mediation_cfg);
@@ -157,18 +154,17 @@ METHOD(job_t, initiate, void,
charon->ike_sa_manager->checkin_and_destroy(
charon->ike_sa_manager, mediated_sa);
}
- destroy(this);
- return;
+ return JOB_REQUEUE_NONE;
}
charon->ike_sa_manager->checkin(charon->ike_sa_manager,
mediation_sa);
}
mediated_cfg->destroy(mediated_cfg);
}
- destroy(this);
+ return JOB_REQUEUE_NONE;
}
-METHOD(job_t, reinitiate, void,
+METHOD(job_t, reinitiate, job_requeue_t,
private_initiate_mediation_job_t *this)
{
ike_sa_t *mediated_sa, *mediation_sa;
@@ -205,8 +201,7 @@ METHOD(job_t, reinitiate, void,
charon->ike_sa_manager,
mediated_sa);
}
- destroy(this);
- return;
+ return JOB_REQUEUE_NONE;
}
charon->ike_sa_manager->checkin(charon->ike_sa_manager,
mediation_sa);
@@ -214,7 +209,7 @@ METHOD(job_t, reinitiate, void,
mediated_cfg->destroy(mediated_cfg);
}
- destroy(this);
+ return JOB_REQUEUE_NONE;
}
METHOD(job_t, get_priority, job_priority_t,
diff --git a/src/libcharon/processing/jobs/mediation_job.c b/src/libcharon/processing/jobs/mediation_job.c
index 6f02f2a0a..759aad003 100644
--- a/src/libcharon/processing/jobs/mediation_job.c
+++ b/src/libcharon/processing/jobs/mediation_job.c
@@ -77,7 +77,7 @@ METHOD(job_t, destroy, void,
free(this);
}
-METHOD(job_t, execute, void,
+METHOD(job_t, execute, job_requeue_t,
private_mediation_job_t *this)
{
ike_sa_id_t *target_sa_id;
@@ -98,8 +98,7 @@ METHOD(job_t, execute, void,
DBG1(DBG_JOB, "callback for '%Y' to '%Y' failed",
this->source, this->target);
charon->ike_sa_manager->checkin(charon->ike_sa_manager, target_sa);
- destroy(this);
- return;
+ return JOB_REQUEUE_NONE;
}
}
else
@@ -112,8 +111,7 @@ METHOD(job_t, execute, void,
this->source, this->target);
charon->ike_sa_manager->checkin(charon->ike_sa_manager, target_sa);
/* FIXME: notify the initiator */
- destroy(this);
- return;
+ return JOB_REQUEUE_NONE;
}
}
@@ -130,7 +128,7 @@ METHOD(job_t, execute, void,
DBG1(DBG_JOB, "mediation between '%Y' and '%Y' failed: "
"peer is not online anymore", this->source, this->target);
}
- destroy(this);
+ return JOB_REQUEUE_NONE;
}
METHOD(job_t, get_priority, job_priority_t,
diff --git a/src/libcharon/processing/jobs/migrate_job.c b/src/libcharon/processing/jobs/migrate_job.c
index eb10e2e46..2ebfc6714 100644
--- a/src/libcharon/processing/jobs/migrate_job.c
+++ b/src/libcharon/processing/jobs/migrate_job.c
@@ -67,7 +67,7 @@ METHOD(job_t, destroy, void,
free(this);
}
-METHOD(job_t, execute, void,
+METHOD(job_t, execute, job_requeue_t,
private_migrate_job_t *this)
{
ike_sa_t *ike_sa = NULL;
@@ -79,9 +79,10 @@ METHOD(job_t, execute, void,
}
if (ike_sa)
{
- enumerator_t *children;
+ enumerator_t *children, *enumerator;
child_sa_t *child_sa;
host_t *host;
+ linked_list_t *vips;
children = ike_sa->create_child_sa_enumerator(ike_sa);
while (children->enumerate(children, (void**)&child_sa))
@@ -97,27 +98,35 @@ METHOD(job_t, execute, void,
ike_sa->set_kmaddress(ike_sa, this->local, this->remote);
host = this->local->clone(this->local);
- host->set_port(host, IKEV2_UDP_PORT);
+ host->set_port(host, charon->socket->get_port(charon->socket, FALSE));
ike_sa->set_my_host(ike_sa, host);
host = this->remote->clone(this->remote);
host->set_port(host, IKEV2_UDP_PORT);
ike_sa->set_other_host(ike_sa, host);
- if (child_sa->update(child_sa, this->local, this->remote,
- ike_sa->get_virtual_ip(ike_sa, TRUE),
+ vips = linked_list_create();
+ enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, TRUE);
+ while (enumerator->enumerate(enumerator, &host))
+ {
+ vips->insert_last(vips, host);
+ }
+ enumerator->destroy(enumerator);
+
+ if (child_sa->update(child_sa, this->local, this->remote, vips,
ike_sa->has_condition(ike_sa, COND_NAT_ANY)) == NOT_SUPPORTED)
{
ike_sa->rekey_child_sa(ike_sa, child_sa->get_protocol(child_sa),
child_sa->get_spi(child_sa, TRUE));
}
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ vips->destroy(vips);
}
else
{
DBG1(DBG_JOB, "no CHILD_SA found with reqid {%d}", this->reqid);
}
- destroy(this);
+ return JOB_REQUEUE_NONE;
}
METHOD(job_t, get_priority, job_priority_t,
diff --git a/src/libcharon/processing/jobs/process_message_job.c b/src/libcharon/processing/jobs/process_message_job.c
index a4924d001..71a2cb45d 100644
--- a/src/libcharon/processing/jobs/process_message_job.c
+++ b/src/libcharon/processing/jobs/process_message_job.c
@@ -42,7 +42,7 @@ METHOD(job_t, destroy, void,
free(this);
}
-METHOD(job_t, execute, void,
+METHOD(job_t, execute, job_requeue_t,
private_process_message_job_t *this)
{
ike_sa_t *ike_sa;
@@ -59,8 +59,7 @@ METHOD(job_t, execute, void,
this->message->get_source(this->message),
this->message->get_destination(this->message));
charon->connect_manager->process_check(charon->connect_manager, this->message);
- destroy(this);
- return;
+ return JOB_REQUEUE_NONE;
}
#endif /* ME */
@@ -81,7 +80,7 @@ METHOD(job_t, execute, void,
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
}
}
- destroy(this);
+ return JOB_REQUEUE_NONE;
}
METHOD(job_t, get_priority, job_priority_t,
diff --git a/src/libcharon/processing/jobs/rekey_child_sa_job.c b/src/libcharon/processing/jobs/rekey_child_sa_job.c
index 5855f1bc9..1bf8dc0cb 100644
--- a/src/libcharon/processing/jobs/rekey_child_sa_job.c
+++ b/src/libcharon/processing/jobs/rekey_child_sa_job.c
@@ -51,7 +51,7 @@ METHOD(job_t, destroy, void,
free(this);
}
-METHOD(job_t, execute, void,
+METHOD(job_t, execute, job_requeue_t,
private_rekey_child_sa_job_t *this)
{
ike_sa_t *ike_sa;
@@ -68,7 +68,7 @@ METHOD(job_t, execute, void,
ike_sa->rekey_child_sa(ike_sa, this->protocol, this->spi);
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
}
- destroy(this);
+ return JOB_REQUEUE_NONE;
}
METHOD(job_t, get_priority, job_priority_t,
diff --git a/src/libcharon/processing/jobs/rekey_ike_sa_job.c b/src/libcharon/processing/jobs/rekey_ike_sa_job.c
index 5366195fd..712c7c2c1 100644
--- a/src/libcharon/processing/jobs/rekey_ike_sa_job.c
+++ b/src/libcharon/processing/jobs/rekey_ike_sa_job.c
@@ -46,7 +46,7 @@ METHOD(job_t, destroy, void,
free(this);
}
-METHOD(job_t, execute, void,
+METHOD(job_t, execute, job_requeue_t,
private_rekey_ike_sa_job_t *this)
{
ike_sa_t *ike_sa;
@@ -78,7 +78,7 @@ METHOD(job_t, execute, void,
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
}
}
- destroy(this);
+ return JOB_REQUEUE_NONE;
}
METHOD(job_t, get_priority, job_priority_t,
diff --git a/src/libcharon/processing/jobs/retransmit_job.c b/src/libcharon/processing/jobs/retransmit_job.c
index 050f7005a..48c326804 100644
--- a/src/libcharon/processing/jobs/retransmit_job.c
+++ b/src/libcharon/processing/jobs/retransmit_job.c
@@ -47,7 +47,7 @@ METHOD(job_t, destroy, void,
free(this);
}
-METHOD(job_t, execute, void,
+METHOD(job_t, execute, job_requeue_t,
private_retransmit_job_t *this)
{
ike_sa_t *ike_sa;
@@ -67,7 +67,7 @@ METHOD(job_t, execute, void,
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
}
}
- destroy(this);
+ return JOB_REQUEUE_NONE;
}
METHOD(job_t, get_priority, job_priority_t,
diff --git a/src/libcharon/processing/jobs/retry_initiate_job.c b/src/libcharon/processing/jobs/retry_initiate_job.c
new file mode 100644
index 000000000..1cdc3058a
--- /dev/null
+++ b/src/libcharon/processing/jobs/retry_initiate_job.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2012 Tobias Brunner
+ * 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.
+ */
+
+#include "retry_initiate_job.h"
+
+#include <daemon.h>
+
+typedef struct private_retry_initiate_job_t private_retry_initiate_job_t;
+
+/**
+ * Private data of an retry_initiate_job_t object.
+ */
+struct private_retry_initiate_job_t {
+ /**
+ * Public retry_initiate_job_t interface.
+ */
+ retry_initiate_job_t public;
+
+ /**
+ * ID of the IKE_SA to re-initiate
+ */
+ ike_sa_id_t *ike_sa_id;
+};
+
+METHOD(job_t, destroy, void,
+ private_retry_initiate_job_t *this)
+{
+ this->ike_sa_id->destroy(this->ike_sa_id);
+ free(this);
+}
+
+METHOD(job_t, execute, job_requeue_t,
+ private_retry_initiate_job_t *this)
+{
+ ike_sa_t *ike_sa;
+
+ ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
+ this->ike_sa_id);
+ if (ike_sa == NULL)
+ {
+ DBG2(DBG_JOB, "IKE_SA to initiate not found");
+ }
+ else
+ {
+ if (ike_sa->retry_initiate(ike_sa) == DESTROY_ME)
+ {
+ charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
+ ike_sa);
+ }
+ else
+ {
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ }
+ }
+ return JOB_REQUEUE_NONE;
+}
+
+METHOD(job_t, get_priority, job_priority_t,
+ private_retry_initiate_job_t *this)
+{
+ return JOB_PRIO_HIGH;
+}
+
+/*
+ * Described in header
+ */
+retry_initiate_job_t *retry_initiate_job_create(ike_sa_id_t *ike_sa_id)
+{
+ private_retry_initiate_job_t *this;
+
+ INIT(this,
+ .public = {
+ .job_interface = {
+ .execute = _execute,
+ .get_priority = _get_priority,
+ .destroy = _destroy,
+ },
+ },
+ .ike_sa_id = ike_sa_id->clone(ike_sa_id),
+ );
+
+ return &(this->public);
+}
diff --git a/src/libcharon/processing/jobs/retry_initiate_job.h b/src/libcharon/processing/jobs/retry_initiate_job.h
new file mode 100644
index 000000000..29f79f23b
--- /dev/null
+++ b/src/libcharon/processing/jobs/retry_initiate_job.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2012 Tobias Brunner
+ * 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.
+ */
+
+/**
+ * @defgroup retry_initiate_job retry_initiate_job
+ * @{ @ingroup cjobs
+ */
+
+#ifndef RETRY_INITIATE_JOB_H_
+#define RETRY_INITIATE_JOB_H_
+
+typedef struct retry_initiate_job_t retry_initiate_job_t;
+
+#include <library.h>
+#include <sa/ike_sa_id.h>
+#include <processing/jobs/job.h>
+
+/**
+ * This job retries initiating an IKE_SA in case of e.g. a failed DNS lookup.
+ */
+struct retry_initiate_job_t {
+ /**
+ * The job_t interface.
+ */
+ job_t job_interface;
+};
+
+/**
+ * Creates a retry_initiate_job_t object.
+ *
+ * @param ike_sa_id ID of the IKE_SA to initiate
+ * @return retry_initiate_job_t object
+ */
+retry_initiate_job_t *retry_initiate_job_create(ike_sa_id_t *ike_sa_id);
+
+#endif /** RETRY_INITIATE_JOB_H_ @}*/
diff --git a/src/libcharon/processing/jobs/roam_job.c b/src/libcharon/processing/jobs/roam_job.c
index 951ac5ad3..0af4c6c39 100644
--- a/src/libcharon/processing/jobs/roam_job.c
+++ b/src/libcharon/processing/jobs/roam_job.c
@@ -44,7 +44,7 @@ METHOD(job_t, destroy, void,
free(this);
}
-METHOD(job_t, execute, void,
+METHOD(job_t, execute, job_requeue_t,
private_roam_job_t *this)
{
ike_sa_t *ike_sa;
@@ -82,8 +82,7 @@ METHOD(job_t, execute, void,
id->destroy(id);
}
list->destroy(list);
-
- destroy(this);
+ return JOB_REQUEUE_NONE;
}
METHOD(job_t, get_priority, job_priority_t,
diff --git a/src/libcharon/processing/jobs/send_dpd_job.c b/src/libcharon/processing/jobs/send_dpd_job.c
index ab00d013d..d2f38b803 100644
--- a/src/libcharon/processing/jobs/send_dpd_job.c
+++ b/src/libcharon/processing/jobs/send_dpd_job.c
@@ -45,7 +45,7 @@ METHOD(job_t, destroy, void,
free(this);
}
-METHOD(job_t, execute, void,
+METHOD(job_t, execute, job_requeue_t,
private_send_dpd_job_t *this)
{
ike_sa_t *ike_sa;
@@ -63,7 +63,7 @@ METHOD(job_t, execute, void,
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
}
}
- destroy(this);
+ return JOB_REQUEUE_NONE;
}
METHOD(job_t, get_priority, job_priority_t,
diff --git a/src/libcharon/processing/jobs/send_keepalive_job.c b/src/libcharon/processing/jobs/send_keepalive_job.c
index 5e128d478..3e3477679 100644
--- a/src/libcharon/processing/jobs/send_keepalive_job.c
+++ b/src/libcharon/processing/jobs/send_keepalive_job.c
@@ -45,7 +45,7 @@ METHOD(job_t, destroy, void,
free(this);
}
-METHOD(job_t, execute, void,
+METHOD(job_t, execute, job_requeue_t,
private_send_keepalive_job_t *this)
{
ike_sa_t *ike_sa;
@@ -57,7 +57,7 @@ METHOD(job_t, execute, void,
ike_sa->send_keepalive(ike_sa);
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
}
- destroy(this);
+ return JOB_REQUEUE_NONE;
}
METHOD(job_t, get_priority, job_priority_t,
diff --git a/src/libcharon/processing/jobs/start_action_job.c b/src/libcharon/processing/jobs/start_action_job.c
index b65181ef8..bc4aaf6d6 100644
--- a/src/libcharon/processing/jobs/start_action_job.c
+++ b/src/libcharon/processing/jobs/start_action_job.c
@@ -36,7 +36,7 @@ METHOD(job_t, destroy, void,
free(this);
}
-METHOD(job_t, execute, void,
+METHOD(job_t, execute, job_requeue_t,
private_start_action_job_t *this)
{
enumerator_t *enumerator, *children;
@@ -46,14 +46,9 @@ METHOD(job_t, execute, void,
char *name;
enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL, IKE_ANY);
while (enumerator->enumerate(enumerator, &peer_cfg))
{
- if (peer_cfg->get_ike_version(peer_cfg) != 2)
- {
- continue;
- }
-
children = peer_cfg->create_child_cfg_enumerator(peer_cfg);
while (children->enumerate(children, &child_cfg))
{
@@ -88,7 +83,7 @@ METHOD(job_t, execute, void,
children->destroy(children);
}
enumerator->destroy(enumerator);
- destroy(this);
+ return JOB_REQUEUE_NONE;
}
METHOD(job_t, get_priority, job_priority_t,
diff --git a/src/libcharon/processing/jobs/update_sa_job.c b/src/libcharon/processing/jobs/update_sa_job.c
index c4f6e4782..694318522 100644
--- a/src/libcharon/processing/jobs/update_sa_job.c
+++ b/src/libcharon/processing/jobs/update_sa_job.c
@@ -50,7 +50,7 @@ METHOD(job_t, destroy, void,
free(this);
}
-METHOD(job_t, execute, void,
+METHOD(job_t, execute, job_requeue_t,
private_update_sa_job_t *this)
{
ike_sa_t *ike_sa;
@@ -71,7 +71,7 @@ METHOD(job_t, execute, void,
}
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
}
- destroy(this);
+ return JOB_REQUEUE_NONE;
}
METHOD(job_t, get_priority, job_priority_t,