[APR-5800]check interface name during MOBIKE procedure
authorDenis Vinogradov <denis.vinogradov@samsung.com>
Mon, 28 Sep 2020 05:38:35 +0000 (14:38 +0900)
committerrobot <robot@samsung.com>
Wed, 4 Nov 2020 04:56:19 +0000 (13:56 +0900)
  [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 <denis.vinogradov@samsung.com>
src/libcharon/sa/ike_sa.c
src/libcharon/sa/ike_sa.h
src/libcharon/sa/ikev2/tasks/ike_mobike.c

index 9b19a8ded135f6f267a792a93088bd27f299a273..6eca87484dc659216d9d540c13d7f0cc4f4d76ac 100755 (executable)
@@ -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,
index fbaa639e21d9e6359e40a1806f15ff5448ab0703..d3b3bcc2e5a65468b2c831730f1a974f6fc05e5b 100755 (executable)
@@ -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
         */
index b2ad0a02afcd7ea7aae98aeeb019e80a90d223a6..1f823e60bcfbb54e703671670be23d0f6c68a797 100755 (executable)
@@ -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 ... */