fixed acquire-delay bug by:
installing policies before states updating policies if protocol has changed
This commit is contained in:
@@ -5,9 +5,6 @@
|
|||||||
* Copyright (C) 2006 Daniel Roethlisberger
|
* Copyright (C) 2006 Daniel Roethlisberger
|
||||||
* Copyright (C) 2005 Jan Hutter
|
* Copyright (C) 2005 Jan Hutter
|
||||||
* Hochschule fuer Technik Rapperswil
|
* Hochschule fuer Technik Rapperswil
|
||||||
* Copyright (C) 2003 Herbert Xu.
|
|
||||||
*
|
|
||||||
* Based on xfrm code from pluto.
|
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* 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
|
* under the terms of the GNU General Public License as published by the
|
||||||
@@ -227,6 +224,9 @@ struct policy_entry_t {
|
|||||||
/** direction of this policy: in, out, forward */
|
/** direction of this policy: in, out, forward */
|
||||||
u_int8_t direction;
|
u_int8_t direction;
|
||||||
|
|
||||||
|
/** protocol ID: ESP/AH */
|
||||||
|
protocol_id_t proto;
|
||||||
|
|
||||||
/** reqid of the policy */
|
/** reqid of the policy */
|
||||||
u_int32_t reqid;
|
u_int32_t reqid;
|
||||||
|
|
||||||
@@ -2612,14 +2612,16 @@ static status_t add_policy(private_kernel_interface_t *this,
|
|||||||
memset(policy, 0, sizeof(policy_entry_t));
|
memset(policy, 0, sizeof(policy_entry_t));
|
||||||
policy->sel = ts2selector(src_ts, dst_ts);
|
policy->sel = ts2selector(src_ts, dst_ts);
|
||||||
policy->direction = direction;
|
policy->direction = direction;
|
||||||
|
policy->proto = protocol;
|
||||||
|
|
||||||
/* find the policy, which matches EXACTLY */
|
/* find the policy, which matches EXACTLY */
|
||||||
pthread_mutex_lock(&this->mutex);
|
pthread_mutex_lock(&this->mutex);
|
||||||
iterator = this->policies->create_iterator(this->policies, TRUE);
|
iterator = this->policies->create_iterator(this->policies, TRUE);
|
||||||
while (iterator->iterate(iterator, (void**)¤t))
|
while (iterator->iterate(iterator, (void**)¤t))
|
||||||
{
|
{
|
||||||
if (memcmp(¤t->sel, &policy->sel, sizeof(struct xfrm_selector)) == 0 &&
|
if (memeq(¤t->sel, &policy->sel, sizeof(struct xfrm_selector)) &&
|
||||||
policy->direction == current->direction)
|
policy->direction == current->direction &&
|
||||||
|
policy->proto == current->proto)
|
||||||
{
|
{
|
||||||
/* use existing policy */
|
/* use existing policy */
|
||||||
current->refcount++;
|
current->refcount++;
|
||||||
|
|||||||
@@ -662,14 +662,19 @@ static status_t update(private_child_sa_t *this, proposal_t *proposal,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static status_t add_policies(private_child_sa_t *this,
|
static status_t add_policies(private_child_sa_t *this,
|
||||||
linked_list_t *my_ts_list,
|
linked_list_t *my_ts_list, linked_list_t *other_ts_list,
|
||||||
linked_list_t *other_ts_list, mode_t mode)
|
mode_t mode, protocol_id_t proto)
|
||||||
{
|
{
|
||||||
iterator_t *my_iter, *other_iter;
|
iterator_t *my_iter, *other_iter;
|
||||||
traffic_selector_t *my_ts, *other_ts;
|
traffic_selector_t *my_ts, *other_ts;
|
||||||
/* use low prio for ROUTED policies */
|
/* use low prio for ROUTED policies */
|
||||||
bool high_prio = (this->state != CHILD_CREATED);
|
bool high_prio = (this->state != CHILD_CREATED);
|
||||||
|
|
||||||
|
if (this->protocol == PROTO_NONE)
|
||||||
|
{ /* update if not set yet */
|
||||||
|
this->protocol = proto;
|
||||||
|
}
|
||||||
|
|
||||||
/* iterate over both lists */
|
/* iterate over both lists */
|
||||||
my_iter = my_ts_list->create_iterator(my_ts_list, TRUE);
|
my_iter = my_ts_list->create_iterator(my_ts_list, TRUE);
|
||||||
other_iter = other_ts_list->create_iterator(other_ts_list, TRUE);
|
other_iter = other_ts_list->create_iterator(other_ts_list, TRUE);
|
||||||
@@ -1029,7 +1034,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
|
|||||||
this->public.add = (status_t(*)(child_sa_t*,proposal_t*,mode_t,prf_plus_t*))add;
|
this->public.add = (status_t(*)(child_sa_t*,proposal_t*,mode_t,prf_plus_t*))add;
|
||||||
this->public.update = (status_t(*)(child_sa_t*,proposal_t*,mode_t,prf_plus_t*))update;
|
this->public.update = (status_t(*)(child_sa_t*,proposal_t*,mode_t,prf_plus_t*))update;
|
||||||
this->public.update_hosts = (status_t (*)(child_sa_t*,host_t*,host_t*,bool))update_hosts;
|
this->public.update_hosts = (status_t (*)(child_sa_t*,host_t*,host_t*,bool))update_hosts;
|
||||||
this->public.add_policies = (status_t (*)(child_sa_t*, linked_list_t*,linked_list_t*,mode_t))add_policies;
|
this->public.add_policies = (status_t (*)(child_sa_t*, linked_list_t*,linked_list_t*,mode_t,protocol_id_t))add_policies;
|
||||||
this->public.get_traffic_selectors = (linked_list_t*(*)(child_sa_t*,bool))get_traffic_selectors;
|
this->public.get_traffic_selectors = (linked_list_t*(*)(child_sa_t*,bool))get_traffic_selectors;
|
||||||
this->public.get_use_time = (status_t (*)(child_sa_t*,bool,time_t*))get_use_time;
|
this->public.get_use_time = (status_t (*)(child_sa_t*,bool,time_t*))get_use_time;
|
||||||
this->public.set_state = (void(*)(child_sa_t*,child_sa_state_t))set_state;
|
this->public.set_state = (void(*)(child_sa_t*,child_sa_state_t))set_state;
|
||||||
|
|||||||
@@ -203,10 +203,12 @@ struct child_sa_t {
|
|||||||
* @param my_ts traffic selectors for local site
|
* @param my_ts traffic selectors for local site
|
||||||
* @param other_ts traffic selectors for remote site
|
* @param other_ts traffic selectors for remote site
|
||||||
* @param mode mode for the SA: tunnel/transport
|
* @param mode mode for the SA: tunnel/transport
|
||||||
|
* @param proto protocol for policy, ESP/AH
|
||||||
* @return SUCCESS or FAILED
|
* @return SUCCESS or FAILED
|
||||||
*/
|
*/
|
||||||
status_t (*add_policies)(child_sa_t *this, linked_list_t *my_ts_list,
|
status_t (*add_policies)(child_sa_t *this, linked_list_t *my_ts_list,
|
||||||
linked_list_t *other_ts_list, mode_t mode);
|
linked_list_t *other_ts_list, mode_t mode,
|
||||||
|
protocol_id_t proto);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the traffic selectors of added policies of local host.
|
* Get the traffic selectors of added policies of local host.
|
||||||
|
|||||||
@@ -1263,7 +1263,7 @@ static status_t route(private_ike_sa_t *this, child_cfg_t *child_cfg)
|
|||||||
my_ts = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, me);
|
my_ts = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, me);
|
||||||
other_ts = child_cfg->get_traffic_selectors(child_cfg, FALSE, NULL, other);
|
other_ts = child_cfg->get_traffic_selectors(child_cfg, FALSE, NULL, other);
|
||||||
status = child_sa->add_policies(child_sa, my_ts, other_ts,
|
status = child_sa->add_policies(child_sa, my_ts, other_ts,
|
||||||
child_cfg->get_mode(child_cfg));
|
child_cfg->get_mode(child_cfg), PROTO_NONE);
|
||||||
my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy));
|
my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy));
|
||||||
other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy));
|
other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy));
|
||||||
if (status == SUCCESS)
|
if (status == SUCCESS)
|
||||||
|
|||||||
@@ -341,7 +341,6 @@ static status_t select_and_install(private_child_create_t *this, bool no_dh)
|
|||||||
{
|
{
|
||||||
seed = chunk_cata("cc", nonce_i, nonce_r);
|
seed = chunk_cata("cc", nonce_i, nonce_r);
|
||||||
}
|
}
|
||||||
prf_plus = prf_plus_create(this->ike_sa->get_child_prf(this->ike_sa), seed);
|
|
||||||
|
|
||||||
if (this->ipcomp != IPCOMP_NONE)
|
if (this->ipcomp != IPCOMP_NONE)
|
||||||
{
|
{
|
||||||
@@ -349,6 +348,15 @@ static status_t select_and_install(private_child_create_t *this, bool no_dh)
|
|||||||
this->other_cpi);
|
this->other_cpi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status = this->child_sa->add_policies(this->child_sa, my_ts, other_ts,
|
||||||
|
this->mode, this->proposal->get_protocol(this->proposal));
|
||||||
|
if (status != SUCCESS)
|
||||||
|
{
|
||||||
|
SIG(CHILD_UP_FAILED, "unable to install IPsec policies (SPD) in kernel");
|
||||||
|
return NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
prf_plus = prf_plus_create(this->ike_sa->get_child_prf(this->ike_sa), seed);
|
||||||
if (this->initiator)
|
if (this->initiator)
|
||||||
{
|
{
|
||||||
status = this->child_sa->update(this->child_sa, this->proposal,
|
status = this->child_sa->update(this->child_sa, this->proposal,
|
||||||
@@ -366,15 +374,6 @@ static status_t select_and_install(private_child_create_t *this, bool no_dh)
|
|||||||
SIG(CHILD_UP_FAILED, "unable to install IPsec SA (SAD) in kernel");
|
SIG(CHILD_UP_FAILED, "unable to install IPsec SA (SAD) in kernel");
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = this->child_sa->add_policies(this->child_sa, my_ts, other_ts,
|
|
||||||
this->mode);
|
|
||||||
|
|
||||||
if (status != SUCCESS)
|
|
||||||
{
|
|
||||||
SIG(CHILD_UP_FAILED, "unable to install IPsec policies (SPD) in kernel");
|
|
||||||
return NOT_FOUND;
|
|
||||||
}
|
|
||||||
/* add to IKE_SA, and remove from task */
|
/* add to IKE_SA, and remove from task */
|
||||||
this->child_sa->set_state(this->child_sa, CHILD_INSTALLED);
|
this->child_sa->set_state(this->child_sa, CHILD_INSTALLED);
|
||||||
this->ike_sa->add_child_sa(this->ike_sa, this->child_sa);
|
this->ike_sa->add_child_sa(this->ike_sa, this->child_sa);
|
||||||
|
|||||||
Reference in New Issue
Block a user