summaryrefslogtreecommitdiff
path: root/src/libcharon/sa/ikev1/tasks/quick_mode.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/sa/ikev1/tasks/quick_mode.c')
-rw-r--r--src/libcharon/sa/ikev1/tasks/quick_mode.c76
1 files changed, 60 insertions, 16 deletions
diff --git a/src/libcharon/sa/ikev1/tasks/quick_mode.c b/src/libcharon/sa/ikev1/tasks/quick_mode.c
index 1133aab65..96edfd8d8 100644
--- a/src/libcharon/sa/ikev1/tasks/quick_mode.c
+++ b/src/libcharon/sa/ikev1/tasks/quick_mode.c
@@ -156,6 +156,16 @@ struct private_quick_mode_t {
u_int32_t reqid;
/**
+ * Explicit inbound mark value to use, if any
+ */
+ u_int mark_in;
+
+ /**
+ * Explicit inbound mark value to use, if any
+ */
+ u_int mark_out;
+
+ /**
* SPI of SA we rekey
*/
u_int32_t rekey;
@@ -196,8 +206,8 @@ static void schedule_inactivity_timeout(private_quick_mode_t *this)
close_ike = lib->settings->get_bool(lib->settings,
"%s.inactivity_close_ike", FALSE, lib->ns);
lib->scheduler->schedule_job(lib->scheduler, (job_t*)
- inactivity_job_create(this->child_sa->get_reqid(this->child_sa),
- timeout, close_ike), timeout);
+ inactivity_job_create(this->child_sa->get_unique_id(this->child_sa),
+ timeout, close_ike), timeout);
}
}
@@ -375,7 +385,7 @@ static bool install(private_quick_mode_t *this)
DBG0(DBG_IKE, "CHILD_SA %s{%d} established "
"with SPIs %.8x_i %.8x_o and TS %#R=== %#R",
this->child_sa->get_name(this->child_sa),
- this->child_sa->get_reqid(this->child_sa),
+ this->child_sa->get_unique_id(this->child_sa),
ntohl(this->child_sa->get_spi(this->child_sa, TRUE)),
ntohl(this->child_sa->get_spi(this->child_sa, FALSE)), my_ts, other_ts);
@@ -391,15 +401,14 @@ static bool install(private_quick_mode_t *this)
if (old)
{
charon->bus->child_rekey(charon->bus, old, this->child_sa);
+ /* rekeyed CHILD_SAs stay installed until they expire */
+ old->set_state(old, CHILD_REKEYED);
}
else
{
charon->bus->child_updown(charon->bus, this->child_sa, TRUE);
}
- if (!this->rekey)
- {
- schedule_inactivity_timeout(this);
- }
+ schedule_inactivity_timeout(this);
this->child_sa = NULL;
return TRUE;
}
@@ -456,12 +465,19 @@ static bool get_nonce(private_quick_mode_t *this, chunk_t *nonce,
/**
* Add KE payload to message
*/
-static void add_ke(private_quick_mode_t *this, message_t *message)
+static bool add_ke(private_quick_mode_t *this, message_t *message)
{
ke_payload_t *ke_payload;
- ke_payload = ke_payload_create_from_diffie_hellman(PLV1_KEY_EXCHANGE, this->dh);
+ ke_payload = ke_payload_create_from_diffie_hellman(PLV1_KEY_EXCHANGE,
+ this->dh);
+ if (!ke_payload)
+ {
+ DBG1(DBG_IKE, "creating KE payload failed");
+ return FALSE;
+ }
message->add_payload(message, &ke_payload->payload_interface);
+ return TRUE;
}
/**
@@ -477,8 +493,12 @@ static bool get_ke(private_quick_mode_t *this, message_t *message)
DBG1(DBG_IKE, "KE payload missing");
return FALSE;
}
- this->dh->set_other_public_value(this->dh,
- ke_payload->get_key_exchange_data(ke_payload));
+ if (!this->dh->set_other_public_value(this->dh,
+ ke_payload->get_key_exchange_data(ke_payload)))
+ {
+ DBG1(DBG_IKE, "unable to apply received KE value");
+ return FALSE;
+ }
return TRUE;
}
@@ -788,7 +808,8 @@ METHOD(task_t, build_i, status_t,
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->udp);
+ this->config, this->reqid, this->udp,
+ this->mark_in, this->mark_out);
if (this->udp && this->mode == MODE_TRANSPORT)
{
@@ -870,7 +891,10 @@ METHOD(task_t, build_i, status_t,
}
if (group != MODP_NONE)
{
- add_ke(this, message);
+ if (!add_ke(this, message))
+ {
+ return FAILED;
+ }
}
if (!this->tsi)
{
@@ -964,6 +988,7 @@ static void check_for_rekeyed_child(private_quick_mode_t *this)
{
case CHILD_INSTALLED:
case CHILD_REKEYING:
+ case CHILD_REKEYED:
policies = child_sa->create_policy_enumerator(child_sa);
if (policies->enumerate(policies, &local, &remote) &&
local->equals(local, this->tsr) &&
@@ -972,9 +997,14 @@ static void check_for_rekeyed_child(private_quick_mode_t *this)
{
this->reqid = child_sa->get_reqid(child_sa);
this->rekey = child_sa->get_spi(child_sa, TRUE);
+ this->mark_in = child_sa->get_mark(child_sa,
+ TRUE).value;
+ this->mark_out = child_sa->get_mark(child_sa,
+ FALSE).value;
child_sa->set_state(child_sa, CHILD_REKEYING);
DBG1(DBG_IKE, "detected rekeying of CHILD_SA %s{%u}",
- child_sa->get_name(child_sa), this->reqid);
+ child_sa->get_name(child_sa),
+ child_sa->get_unique_id(child_sa));
}
policies->destroy(policies);
break;
@@ -1097,7 +1127,8 @@ METHOD(task_t, process_r, status_t,
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->udp);
+ this->config, this->reqid, this->udp,
+ this->mark_in, this->mark_out);
tsi = linked_list_create_with_items(this->tsi, NULL);
tsr = linked_list_create_with_items(this->tsr, NULL);
@@ -1202,7 +1233,10 @@ METHOD(task_t, build_r, status_t,
}
if (this->dh)
{
- add_ke(this, message);
+ if (!add_ke(this, message))
+ {
+ return FAILED;
+ }
}
add_ts(this, message);
@@ -1307,6 +1341,13 @@ METHOD(quick_mode_t, use_reqid, void,
this->reqid = reqid;
}
+METHOD(quick_mode_t, use_marks, void,
+ private_quick_mode_t *this, u_int in, u_int out)
+{
+ this->mark_in = in;
+ this->mark_out = out;
+}
+
METHOD(quick_mode_t, rekey, void,
private_quick_mode_t *this, u_int32_t spi)
{
@@ -1334,6 +1375,8 @@ METHOD(task_t, migrate, void,
this->dh = NULL;
this->spi_i = 0;
this->spi_r = 0;
+ this->mark_in = 0;
+ this->mark_out = 0;
if (!this->initiator)
{
@@ -1372,6 +1415,7 @@ quick_mode_t *quick_mode_create(ike_sa_t *ike_sa, child_cfg_t *config,
.destroy = _destroy,
},
.use_reqid = _use_reqid,
+ .use_marks = _use_marks,
.rekey = _rekey,
},
.ike_sa = ike_sa,