diff options
Diffstat (limited to 'src/libcharon/sa/ikev1/tasks/quick_mode.c')
-rw-r--r-- | src/libcharon/sa/ikev1/tasks/quick_mode.c | 76 |
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, |