ikev1: Unify child_updown calls when having duplicate QMs
If a Quick mode is initiated for a CHILD_SA that is already installed we can identify this situation and rekey the already installed CHILD_SA. Otherwise we end up with several CHILD_SAs in state INSTALLED which means multiple calls of child_updown are done. Unfortunately, the deduplication code later does not call child_updown() (so up and down were not even). Closes strongswan/strongswan#95.
This commit is contained in:
committed by
Tobias Brunner
parent
55cce124bf
commit
e873544080
@@ -1005,14 +1005,25 @@ static bool has_notify_errors(private_quick_mode_t *this, message_t *message)
|
|||||||
/**
|
/**
|
||||||
* Check if this is a rekey for an existing CHILD_SA, reuse reqid if so
|
* Check if this is a rekey for an existing CHILD_SA, reuse reqid if so
|
||||||
*/
|
*/
|
||||||
static void check_for_rekeyed_child(private_quick_mode_t *this)
|
static void check_for_rekeyed_child(private_quick_mode_t *this, bool responder)
|
||||||
{
|
{
|
||||||
enumerator_t *enumerator, *policies;
|
enumerator_t *enumerator, *policies;
|
||||||
traffic_selector_t *local, *remote;
|
traffic_selector_t *local, *remote, *my_ts, *other_ts;
|
||||||
child_sa_t *child_sa;
|
child_sa_t *child_sa;
|
||||||
proposal_t *proposal;
|
proposal_t *proposal;
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
|
if (responder)
|
||||||
|
{
|
||||||
|
my_ts = this->tsr;
|
||||||
|
other_ts = this->tsi;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
my_ts = this->tsi;
|
||||||
|
other_ts = this->tsr;
|
||||||
|
}
|
||||||
|
|
||||||
name = this->config->get_name(this->config);
|
name = this->config->get_name(this->config);
|
||||||
enumerator = this->ike_sa->create_child_sa_enumerator(this->ike_sa);
|
enumerator = this->ike_sa->create_child_sa_enumerator(this->ike_sa);
|
||||||
while (this->reqid == 0 && enumerator->enumerate(enumerator, &child_sa))
|
while (this->reqid == 0 && enumerator->enumerate(enumerator, &child_sa))
|
||||||
@@ -1026,8 +1037,8 @@ static void check_for_rekeyed_child(private_quick_mode_t *this)
|
|||||||
case CHILD_REKEYING:
|
case CHILD_REKEYING:
|
||||||
policies = child_sa->create_policy_enumerator(child_sa);
|
policies = child_sa->create_policy_enumerator(child_sa);
|
||||||
if (policies->enumerate(policies, &local, &remote) &&
|
if (policies->enumerate(policies, &local, &remote) &&
|
||||||
local->equals(local, this->tsr) &&
|
local->equals(local, my_ts) &&
|
||||||
remote->equals(remote, this->tsi) &&
|
remote->equals(remote, other_ts) &&
|
||||||
this->proposal->equals(this->proposal, proposal))
|
this->proposal->equals(this->proposal, proposal))
|
||||||
{
|
{
|
||||||
this->reqid = child_sa->get_reqid(child_sa);
|
this->reqid = child_sa->get_reqid(child_sa);
|
||||||
@@ -1165,7 +1176,7 @@ METHOD(task_t, process_r, status_t,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
check_for_rekeyed_child(this);
|
check_for_rekeyed_child(this, TRUE);
|
||||||
|
|
||||||
this->child_sa = child_sa_create(
|
this->child_sa = child_sa_create(
|
||||||
this->ike_sa->get_my_host(this->ike_sa),
|
this->ike_sa->get_my_host(this->ike_sa),
|
||||||
@@ -1366,6 +1377,7 @@ METHOD(task_t, process_i, status_t,
|
|||||||
{
|
{
|
||||||
return send_notify(this, INVALID_PAYLOAD_TYPE);
|
return send_notify(this, INVALID_PAYLOAD_TYPE);
|
||||||
}
|
}
|
||||||
|
check_for_rekeyed_child(this, FALSE);
|
||||||
if (!install(this))
|
if (!install(this))
|
||||||
{
|
{
|
||||||
return send_notify(this, NO_PROPOSAL_CHOSEN);
|
return send_notify(this, NO_PROPOSAL_CHOSEN);
|
||||||
|
|||||||
Reference in New Issue
Block a user