From 980f1cc86c4c5cd4944c366457e3a63a6d708268 Mon Sep 17 00:00:00 2001 From: Denis Vinogradov Date: Mon, 28 Sep 2020 14:38:35 +0900 Subject: [PATCH] [APR-5800]check interface name during MOBIKE procedure [JIRA]: SOC-97122 [Problem]: Call dropped after moving from VoMobile to VoWiFi [Issue]: MOBIKE address update not started because path check message received on old interface. Due to long delay call is dropped - RTP timeout [Solution]: Check infterface of received packet. If interface is not matched to expected start update procedure Change-Id: I789112b28776a8840cdabd376cf2f605dca53086 Signed-off-by: Denis Vinogradov --- src/libcharon/sa/ike_sa.c | 61 +++++++++++++++++++++++ src/libcharon/sa/ike_sa.h | 6 +++ src/libcharon/sa/ikev2/tasks/ike_mobike.c | 9 ++++ 3 files changed, 76 insertions(+) diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c index 9b19a8d..6eca874 100755 --- a/src/libcharon/sa/ike_sa.c +++ b/src/libcharon/sa/ike_sa.c @@ -3727,6 +3727,65 @@ METHOD(ike_sa_t, install_vip, void, } } +METHOD(ike_sa_t, interface_not_matched, bool, + private_ike_sa_t *this, host_t *address) +{ + return !is_address_on_interface(this, address); +} + +METHOD(ike_sa_t, set_my_host_from_interface, void, + private_ike_sa_t *this, host_t *old) +{ + if (this->local_host && is_address_on_interface(this, this->local_host)) + { + /* already found */ + DBG1(DBG_IKE, "get from local host %H", this->local_host); + DESTROY_IF(this->my_host); + this->my_host = this->local_host->clone(this->local_host); + this->my_host->set_port(this->my_host, old->get_port(old)); + } + else + { + /* find new */ + enumerator_t *enumerator; + host_t *src = NULL, *addr; + int family = AF_UNSPEC; + + switch (charon->socket->supported_families(charon->socket)) + { + case SOCKET_FAMILY_IPV4: + family = AF_INET; + break; + case SOCKET_FAMILY_IPV6: + family = AF_INET6; + break; + case SOCKET_FAMILY_BOTH: + case SOCKET_FAMILY_NONE: + break; + } + enumerator = create_peer_address_enumerator(this); + while (enumerator->enumerate(enumerator, &addr)) + { + if (family != AF_UNSPEC && addr->get_family(addr) != family) + { + continue; + } + src = charon->kernel->get_source_addr(charon->kernel, addr, NULL); + if (src && is_address_on_interface(this, src)) + { + DBG1(DBG_IKE, "found new souce %H", src); + + DESTROY_IF(this->my_host); + this->my_host = src->clone(src); + this->my_host->set_port(this->my_host, old->get_port(old)); + break; + } + src = NULL; + } + enumerator->destroy(enumerator); + } +} + METHOD(ike_sa_t, get_tun_name, char*, private_ike_sa_t *this) { @@ -3973,6 +4032,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator, .is_terminated_from_service = _get_terminate, .install_vip = _install_vip, .wait_for_installed_vip = _wait_for_installed_vip, + .interface_not_matched = _interface_not_matched, + .set_my_host_from_interface = _set_my_host_from_interface, .get_tun_name = _get_tun_name, .get_mtu = _get_mtu, .get_configuration_attributes = _get_configuration_attributes, diff --git a/src/libcharon/sa/ike_sa.h b/src/libcharon/sa/ike_sa.h index fbaa639..d3b3bcc 100755 --- a/src/libcharon/sa/ike_sa.h +++ b/src/libcharon/sa/ike_sa.h @@ -1240,6 +1240,12 @@ struct ike_sa_t { */ void (*wait_for_installed_vip)(ike_sa_t *this); + /** + * MOBIKE enhancements + */ + bool (*interface_not_matched)(ike_sa_t *this, host_t *address); + void (*set_my_host_from_interface)(ike_sa_t *this, host_t *address); + /** * Get virtual device name */ diff --git a/src/libcharon/sa/ikev2/tasks/ike_mobike.c b/src/libcharon/sa/ikev2/tasks/ike_mobike.c index b2ad0a0..1f823e6 100755 --- a/src/libcharon/sa/ikev2/tasks/ike_mobike.c +++ b/src/libcharon/sa/ikev2/tasks/ike_mobike.c @@ -606,6 +606,15 @@ METHOD(task_t, process_i, status_t, this->update = TRUE; this->ike_sa->set_other_host(this->ike_sa, other_new->clone(other_new)); } +#ifdef VOWIFI_CFG + if (!this->update && this->ike_sa->interface_not_matched(this->ike_sa, me_new)) + { + this->update = TRUE; + + DBG1(DBG_IKE, "update address by interface"); + this->ike_sa->set_my_host_from_interface(this->ike_sa, me_new); + } +#endif if (this->update) { /* use the same task to ... */ -- 2.20.1