bus: Change ike_update() signature and only call it once

This avoids multiple events when both addresses change (e.g. switching
address families).
This commit is contained in:
Tobias Brunner 2020-10-27 17:02:21 +01:00
parent 5ef10ec326
commit 08a3ee0cce
6 changed files with 43 additions and 50 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2011-2016 Tobias Brunner * Copyright (C) 2011-2020 Tobias Brunner
* Copyright (C) 2006 Martin Willi * Copyright (C) 2006 Martin Willi
* HSR Hochschule fuer Technik Rapperswil * HSR Hochschule fuer Technik Rapperswil
* *
@ -866,7 +866,7 @@ METHOD(bus_t, ike_rekey, void,
} }
METHOD(bus_t, ike_update, void, METHOD(bus_t, ike_update, void,
private_bus_t *this, ike_sa_t *ike_sa, bool local, host_t *new) private_bus_t *this, ike_sa_t *ike_sa, host_t *local, host_t *remote)
{ {
enumerator_t *enumerator; enumerator_t *enumerator;
entry_t *entry; entry_t *entry;
@ -881,7 +881,8 @@ METHOD(bus_t, ike_update, void,
continue; continue;
} }
entry->calling++; entry->calling++;
keep = entry->listener->ike_update(entry->listener, ike_sa, local, new); keep = entry->listener->ike_update(entry->listener, ike_sa, local,
remote);
entry->calling--; entry->calling--;
if (!keep) if (!keep)
{ {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2012-2016 Tobias Brunner * Copyright (C) 2012-2020 Tobias Brunner
* Copyright (C) 2006-2009 Martin Willi * Copyright (C) 2006-2009 Martin Willi
* HSR Hochschule fuer Technik Rapperswil * HSR Hochschule fuer Technik Rapperswil
* *
@ -417,10 +417,11 @@ struct bus_t {
* IKE_SA peer endpoint update hook. * IKE_SA peer endpoint update hook.
* *
* @param ike_sa updated IKE_SA, having old endpoints set * @param ike_sa updated IKE_SA, having old endpoints set
* @param local TRUE if local endpoint gets updated, FALSE for remote * @param local new/current local endpoint address and port
* @param new new endpoint address and port * @param remote new/current remote endpoint address and port
*/ */
void (*ike_update)(bus_t *this, ike_sa_t *ike_sa, bool local, host_t *new); void (*ike_update)(bus_t *this, ike_sa_t *ike_sa, host_t *local,
host_t *remote);
/** /**
* IKE_SA reestablishing hook (before resolving hosts). * IKE_SA reestablishing hook (before resolving hosts).

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2011-2016 Tobias Brunner * Copyright (C) 2011-2020 Tobias Brunner
* Copyright (C) 2009 Martin Willi * Copyright (C) 2009 Martin Willi
* HSR Hochschule fuer Technik Rapperswil * HSR Hochschule fuer Technik Rapperswil
* *
@ -160,13 +160,15 @@ struct listener_t {
/** /**
* Hook called for IKE_SA peer endpoint updates. * Hook called for IKE_SA peer endpoint updates.
* *
* At least one endpoint has changed when this is invoked.
*
* @param ike_sa updated IKE_SA, having old endpoints set * @param ike_sa updated IKE_SA, having old endpoints set
* @param local TRUE if local endpoint gets updated, FALSE for remote * @param local new/current local endpoint address and port
* @param new new endpoint address and port * @param remote new/current remote endpoint address and port
* @return TRUE to stay registered, FALSE to unregister * @return TRUE to stay registered, FALSE to unregister
*/ */
bool (*ike_update)(listener_t *this, ike_sa_t *ike_sa, bool (*ike_update)(listener_t *this, ike_sa_t *ike_sa,
bool local, host_t *new); host_t *local, host_t *remote);
/** /**
* Hook called when an initiator reestablishes an IKE_SA. * Hook called when an initiator reestablishes an IKE_SA.

View File

@ -494,24 +494,13 @@ METHOD(listener_t, child_rekey, bool,
METHOD(listener_t, ike_update, bool, METHOD(listener_t, ike_update, bool,
private_connmark_listener_t *this, ike_sa_t *ike_sa, private_connmark_listener_t *this, ike_sa_t *ike_sa,
bool local, host_t *new) host_t *local, host_t *remote)
{ {
struct iptc_handle *ipth; struct iptc_handle *ipth;
enumerator_t *enumerator; enumerator_t *enumerator;
child_sa_t *child_sa; child_sa_t *child_sa;
host_t *dst, *src;
bool oldencap, newencap; bool oldencap, newencap;
if (local)
{
dst = new;
src = ike_sa->get_other_host(ike_sa);
}
else
{
dst = ike_sa->get_my_host(ike_sa);
src = new;
}
/* during ike_update(), has_encap() on the CHILD_SA has not yet been /* during ike_update(), has_encap() on the CHILD_SA has not yet been
* updated, but shows the old state. */ * updated, but shows the old state. */
newencap = ike_sa->has_condition(ike_sa, COND_NAT_ANY); newencap = ike_sa->has_condition(ike_sa, COND_NAT_ANY);
@ -525,9 +514,9 @@ METHOD(listener_t, ike_update, bool,
ipth = init_handle(); ipth = init_handle();
if (ipth) if (ipth)
{ {
if (manage_policies(this, ipth, dst, src, oldencap, if (manage_policies(this, ipth, local, remote, oldencap,
child_sa, FALSE) && child_sa, FALSE) &&
manage_policies(this, ipth, dst, src, newencap, manage_policies(this, ipth, local, remote, newencap,
child_sa, TRUE)) child_sa, TRUE))
{ {
commit_handle(ipth); commit_handle(ipth);

View File

@ -569,24 +569,13 @@ METHOD(listener_t, child_rekey, bool,
METHOD(listener_t, ike_update, bool, METHOD(listener_t, ike_update, bool,
private_forecast_listener_t *this, ike_sa_t *ike_sa, private_forecast_listener_t *this, ike_sa_t *ike_sa,
bool local, host_t *new) host_t *local, host_t *remote)
{ {
struct iptc_handle *ipth; struct iptc_handle *ipth;
enumerator_t *enumerator; enumerator_t *enumerator;
child_sa_t *child_sa; child_sa_t *child_sa;
host_t *lhost, *rhost;
bool encap; bool encap;
if (local)
{
lhost = new;
rhost = ike_sa->get_other_host(ike_sa);
}
else
{
lhost = ike_sa->get_my_host(ike_sa);
rhost = new;
}
/* during ike_update(), has_encap() on the CHILD_SA has not yet been /* during ike_update(), has_encap() on the CHILD_SA has not yet been
* updated, but shows the old state. */ * updated, but shows the old state. */
encap = ike_sa->has_condition(ike_sa, COND_NAT_ANY); encap = ike_sa->has_condition(ike_sa, COND_NAT_ANY);
@ -600,7 +589,7 @@ METHOD(listener_t, ike_update, bool,
if (ipth) if (ipth)
{ {
if (remove_entry(this, ipth, child_sa) && if (remove_entry(this, ipth, child_sa) &&
add_entry(this, ipth, lhost, rhost, child_sa, encap)) add_entry(this, ipth, local, remote, child_sa, encap))
{ {
commit_handle(ipth); commit_handle(ipth);
} }

View File

@ -1116,7 +1116,8 @@ METHOD(ike_sa_t, float_ports, void,
METHOD(ike_sa_t, update_hosts, void, METHOD(ike_sa_t, update_hosts, void,
private_ike_sa_t *this, host_t *me, host_t *other, bool force) private_ike_sa_t *this, host_t *me, host_t *other, bool force)
{ {
bool update = FALSE; host_t *new_me = NULL, *new_other = NULL;
bool silent = FALSE;
if (me == NULL) if (me == NULL)
{ {
@ -1131,18 +1132,16 @@ METHOD(ike_sa_t, update_hosts, void,
if (this->my_host->is_anyaddr(this->my_host) || if (this->my_host->is_anyaddr(this->my_host) ||
this->other_host->is_anyaddr(this->other_host)) this->other_host->is_anyaddr(this->other_host))
{ {
set_my_host(this, me->clone(me)); new_me = me;
set_other_host(this, other->clone(other)); new_other = other;
update = TRUE; silent = TRUE;
} }
else else
{ {
/* update our address in any case */ /* update our address in any case */
if (force && !me->equals(me, this->my_host)) if (force && !me->equals(me, this->my_host))
{ {
charon->bus->ike_update(charon->bus, &this->public, TRUE, me); new_me = me;
set_my_host(this, me->clone(me));
update = TRUE;
} }
if (!other->equals(other, this->other_host) && if (!other->equals(other, this->other_host) &&
@ -1154,20 +1153,32 @@ METHOD(ike_sa_t, update_hosts, void,
(!has_condition(this, COND_NAT_HERE) || (!has_condition(this, COND_NAT_HERE) ||
!has_condition(this, COND_ORIGINAL_INITIATOR))) !has_condition(this, COND_ORIGINAL_INITIATOR)))
{ {
charon->bus->ike_update(charon->bus, &this->public, FALSE, other); new_other = other;
set_other_host(this, other->clone(other));
update = TRUE;
} }
} }
} }
/* update all associated CHILD_SAs, if required */ if (new_me || new_other)
if (update)
{ {
enumerator_t *enumerator; enumerator_t *enumerator;
child_sa_t *child_sa; child_sa_t *child_sa;
linked_list_t *vips; linked_list_t *vips;
if (!silent)
{
charon->bus->ike_update(charon->bus, &this->public,
new_me ?: this->my_host,
new_other ?: this->other_host);
}
if (new_me)
{
set_my_host(this, new_me->clone(new_me));
}
if (new_other)
{
set_other_host(this, new_other->clone(new_other));
}
vips = linked_list_create_from_enumerator( vips = linked_list_create_from_enumerator(
array_create_enumerator(this->my_vips)); array_create_enumerator(this->my_vips));