[IOT-1361]Change "CAFindInterfaceChange()" to support IPv4/6
authorbg.chun <bg.chun@samsung.com>
Tue, 4 Oct 2016 02:44:58 +0000 (11:44 +0900)
committerAshok Babu Channa <ashok.channa@samsung.com>
Wed, 26 Oct 2016 12:48:37 +0000 (12:48 +0000)
Change "CAFindInterfaceChange" return type to listen for multicast packets from
both of IPv4/IPv6 Address bind in one physical Network Interface.
As is: CAInterface_t *CAFindInterfaceChange();
To be: u_arraylist_t *CAFindInterfaceChange();

Change-Id: I8c30f46669ca5c22962c4f629c2e2e4649cb54b5
https://jira.iotivity.org/browse/IOT-1361
Signed-off-by: bg.chun <bg.chun@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/12737
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: jihwan seo <jihwan.seo@samsung.com>
Reviewed-by: David Antler <david.a.antler@intel.com>
Reviewed-by: Hyuna Jo <hyuna0213.jo@samsung.com>
Reviewed-by: Dave Thaler <dthaler@microsoft.com>
Reviewed-by: Ashok Babu Channa <ashok.channa@samsung.com>
resource/csdk/connectivity/inc/caipnwmonitor.h
resource/csdk/connectivity/src/ip_adapter/android/caipnwmonitor.c
resource/csdk/connectivity/src/ip_adapter/caipserver.c
resource/csdk/connectivity/src/ip_adapter/linux/caipnwmonitor.c
resource/csdk/connectivity/src/ip_adapter/tizen/caipnwmonitor.c
resource/csdk/connectivity/src/ip_adapter/windows/caipnwmonitor.c

index d76c6fe4c332b8d8db01ecba8fba7ff1c76d5a89..e2e7c70d404fc33d3a28b462ee767f8ada631a20 100644 (file)
@@ -95,11 +95,11 @@ CAResult_t CAIPUnSetNetworkMonitorCallback(CATransportAdapter_t adapter);
 u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex);
 
 /**
 u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex);
 
 /**
- * Find a new network interface.
+ * Find network interface changes.
  *
  *
- * @return  Description of interface (or NULL if no change)
+ * @return  List of CAInterface_t items.
  */
  */
-CAInterface_t *CAFindInterfaceChange();
+u_arraylist_t *CAFindInterfaceChange();
 
 /**
  * Start network monitor.
 
 /**
  * Start network monitor.
index b1f84ca0f1fd3e02878b2599bc5543b57d97dcab..03b729431a141a0ea80103f453ac027069deb24d 100644 (file)
@@ -178,7 +178,7 @@ CAResult_t CAIPUnSetNetworkMonitorCallback(CATransportAdapter_t adapter)
     return CA_STATUS_OK;
 }
 
     return CA_STATUS_OK;
 }
 
-CAInterface_t *CAFindInterfaceChange()
+u_arraylist_t *CAFindInterfaceChange()
 {
     // release netlink event
     char *bufPtr = (char *)OICCalloc(NETLINK_MESSAGE_LENGTH, sizeof (char));
 {
     // release netlink event
     char *bufPtr = (char *)OICCalloc(NETLINK_MESSAGE_LENGTH, sizeof (char));
@@ -201,6 +201,7 @@ CAInterface_t *CAFindInterfaceChange()
         return NULL;
     }
 
         return NULL;
     }
 
+    u_arraylist_t *iflist = NULL;
     CAInterface_t *foundNewInterface = NULL;
 
     struct ifreq* ifr = ifc.ifc_req;
     CAInterface_t *foundNewInterface = NULL;
 
     struct ifreq* ifr = ifc.ifc_req;
@@ -287,7 +288,39 @@ CAInterface_t *CAFindInterfaceChange()
     }
 
     OICFree(previous);
     }
 
     OICFree(previous);
-    return foundNewInterface;
+    // below code is temporary impl for consistency with caipserver.
+    // TODO: whole code which using ioctl will be removed and changed with internal getifaddrs impl.
+    if (foundNewInterface)
+    {
+        iflist = u_arraylist_create();
+
+        if (!iflist)
+        {
+            OIC_LOG_V(ERROR, TAG, "Failed to create iflist: %s", strerror(errno));
+            goto exit;
+        }
+
+        CAResult_t result = CAAddInterfaceItem(iflist,
+                                               foundNewInterface->index,
+                                               foundNewInterface->name,
+                                               foundNewInterface->family,
+                                               foundNewInterface->addr,
+                                               foundNewInterface->flags);
+        if (CA_STATUS_OK != result)
+        {
+            goto exit;
+        }
+
+        // release foundNewInterface
+        OICFree(foundNewInterface);
+        foundNewInterface = NULL;
+    }
+    return iflist;
+exit:
+    OICFree(foundNewInterface);
+    foundNewInterface = NULL;
+    u_arraylist_destroy(iflist);
+    return NULL;
 }
 
 u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex)
 }
 
 u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex)
index 4ed0679137abd63371622aa20d612b358491b665..31a9b2d9482a7c368985f5e1ba245a7d5b7a1282 100644 (file)
@@ -249,11 +249,19 @@ static void CASelectReturned(fd_set *readFds, int ret)
         else ISSET(m4s, readFds, CA_MULTICAST | CA_IPV4 | CA_SECURE)
         else if ((caglobals.ip.netlinkFd != OC_INVALID_SOCKET) && FD_ISSET(caglobals.ip.netlinkFd, readFds))
         {
         else ISSET(m4s, readFds, CA_MULTICAST | CA_IPV4 | CA_SECURE)
         else if ((caglobals.ip.netlinkFd != OC_INVALID_SOCKET) && FD_ISSET(caglobals.ip.netlinkFd, readFds))
         {
-            CAInterface_t *ifchanged = CAFindInterfaceChange();
-            if (ifchanged)
+            u_arraylist_t *iflist = CAFindInterfaceChange();
+            if (iflist)
             {
             {
-                CAProcessNewInterface(ifchanged);
-                OICFree(ifchanged);
+                uint32_t listLength = u_arraylist_length(iflist);
+                for (uint32_t i = 0; i < listLength; i++)
+                {
+                    CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i);
+                    if (ifitem)
+                    {
+                        CAProcessNewInterface(ifitem);
+                    }
+                }
+                u_arraylist_destroy(iflist);
             }
             break;
         }
             }
             break;
         }
@@ -411,11 +419,19 @@ static void CAFindReadyMessage()
                     if ((caglobals.ip.addressChangeEvent != WSA_INVALID_EVENT) &&
                         (caglobals.ip.addressChangeEvent == eventArray[eventIndex]))
                     {
                     if ((caglobals.ip.addressChangeEvent != WSA_INVALID_EVENT) &&
                         (caglobals.ip.addressChangeEvent == eventArray[eventIndex]))
                     {
-                        CAInterface_t *newAddress;
-                        while ((newAddress = CAFindInterfaceChange()) != NULL)
+                        u_arraylist_t *iflist = CAFindInterfaceChange();
+                        if (iflist)
                         {
                         {
-                            CAProcessNewInterface(newAddress);
-                            OICFree(newAddress);
+                            uint32_t listLength = u_arraylist_length(iflist);
+                            for (uint32_t i = 0; i < listLength; i++)
+                            {
+                                CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i);
+                                if (ifitem)
+                                {
+                                    CAProcessNewInterface(ifitem);
+                                }
+                            }
+                            u_arraylist_destroy(iflist);
                         }
                         break;
                     }
                         }
                         break;
                     }
index c1471b265d3b735dc1cf4533f54a30fc7d69063a..904fc6805447533e44e68028c40e993d1965f3b3 100644 (file)
@@ -311,9 +311,9 @@ static CAInterface_t *CANewInterfaceItem(int index, const char *name, int family
     return ifitem;
 }
 
     return ifitem;
 }
 
-CAInterface_t *CAFindInterfaceChange()
+u_arraylist_t *CAFindInterfaceChange()
 {
 {
-    CAInterface_t *foundNewInterface = NULL;
+    u_arraylist_t *iflist = NULL;
 #ifdef __linux__
     char buf[4096] = { 0 };
     struct nlmsghdr *nh = NULL;
 #ifdef __linux__
     char buf[4096] = { 0 };
     struct nlmsghdr *nh = NULL;
@@ -349,35 +349,16 @@ CAInterface_t *CAFindInterfaceChange()
             continue;
         }
 
             continue;
         }
 
-        u_arraylist_t *iflist = CAIPGetInterfaceInformation(ifiIndex);
+        iflist = CAIPGetInterfaceInformation(ifiIndex);
+
         if (!iflist)
         {
             OIC_LOG_V(ERROR, TAG, "get interface info failed: %s", strerror(errno));
             return NULL;
         }
         if (!iflist)
         {
             OIC_LOG_V(ERROR, TAG, "get interface info failed: %s", strerror(errno));
             return NULL;
         }
-
-        uint32_t listLength = u_arraylist_length(iflist);
-        for (uint32_t i = 0; i < listLength; i++)
-        {
-            CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i);
-            if (!ifitem)
-            {
-                continue;
-            }
-
-            if ((int)ifitem->index != ifiIndex)
-            {
-                continue;
-            }
-
-            foundNewInterface = CANewInterfaceItem(ifitem->index, ifitem->name, ifitem->family,
-                                                   ifitem->addr, ifitem->flags);
-            break;    // we found the one we were looking for
-        }
-        u_arraylist_destroy(iflist);
     }
 #endif
     }
 #endif
-    return foundNewInterface;
+    return iflist;
 }
 
 u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex)
 }
 
 u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex)
index a141c3bbae4719447757243ff553066d1359145d..0a729697551a34c4a02621dca0281a03b6806674 100644 (file)
@@ -154,9 +154,9 @@ CAResult_t CAIPUnSetNetworkMonitorCallback(CATransportAdapter_t adapter)
     return CA_STATUS_OK;
 }
 
     return CA_STATUS_OK;
 }
 
-CAInterface_t *CAFindInterfaceChange()
+u_arraylist_t *CAFindInterfaceChange()
 {
 {
-    CAInterface_t *foundNewInterface = NULL;
+    u_arraylist_t *iflist = NULL;
     char buf[NETLINK_MESSAGE_LENGTH] = { 0 };
     struct sockaddr_nl sa = { 0 };
     struct iovec iov = { .iov_base = buf,
     char buf[NETLINK_MESSAGE_LENGTH] = { 0 };
     struct sockaddr_nl sa = { 0 };
     struct iovec iov = { .iov_base = buf,
@@ -177,41 +177,21 @@ CAInterface_t *CAFindInterfaceChange()
 
         struct ifinfomsg *ifi = (struct ifinfomsg *)NLMSG_DATA(nh);
 
 
         struct ifinfomsg *ifi = (struct ifinfomsg *)NLMSG_DATA(nh);
 
-        int ifiIndex = ifi->ifi_index;
-        u_arraylist_t *iflist = CAIPGetInterfaceInformation(ifiIndex);
-
         if ((!ifi || (ifi->ifi_flags & IFF_LOOPBACK) || !(ifi->ifi_flags & IFF_RUNNING)))
         {
             continue;
         }
 
         if ((!ifi || (ifi->ifi_flags & IFF_LOOPBACK) || !(ifi->ifi_flags & IFF_RUNNING)))
         {
             continue;
         }
 
+        int ifiIndex = ifi->ifi_index;
+        iflist = CAIPGetInterfaceInformation(ifiIndex);
+
         if (!iflist)
         {
             OIC_LOG_V(ERROR, TAG, "get interface info failed: %s", strerror(errno));
             return NULL;
         }
         if (!iflist)
         {
             OIC_LOG_V(ERROR, TAG, "get interface info failed: %s", strerror(errno));
             return NULL;
         }
-
-        uint32_t listLength = u_arraylist_length(iflist);
-        for (uint32_t i = 0; i < listLength; i++)
-        {
-            CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i);
-            if (!ifitem)
-            {
-                continue;
-            }
-
-            if ((int)ifitem->index != ifiIndex)
-            {
-                continue;
-            }
-
-            foundNewInterface = CANewInterfaceItem(ifitem->index, ifitem->name, ifitem->family,
-                                                   ifitem->addr, ifitem->flags);
-            break;    // we found the one we were looking for
-        }
-        u_arraylist_destroy(iflist);
     }
     }
-    return foundNewInterface;
+    return iflist;
 }
 
 CAResult_t CAIPStartNetworkMonitor(CAIPAdapterStateChangeCallback callback,
 }
 
 CAResult_t CAIPStartNetworkMonitor(CAIPAdapterStateChangeCallback callback,
index 1e86d3f730c4f99bc8f687965c342a804db9db49..635002519e9dc99ca9035589742f56e4a1fcd068 100644 (file)
@@ -402,29 +402,44 @@ static CAInterface_t *AllocateCAInterface(int index, const char *name, int famil
 }
 
 /**
 }
 
 /**
- * Find a new IP address. Note that this can only return one, so the caller must
- * call multiple times to get the list, which is pretty inefficient. The caller is
- * responsible for freeing the pointer returned via OICFree().
- * @todo Change the API to allow returning a list or, even better, allow calling
- *       CAIPPassNetworkChangesToTransportAdapter() at any time from IpAddressChangeCallback.
+ * Find a new IP address.
+ * The caller is responsible for freeing the pointer returned via u_arraylist_destroy().
  *
  *
- * @return  Dynamically allocated IP address entry, or NULL if no change.
+ * @return  Dynamically allocated IP address list, or NULL if no change.
  */
  */
-CAInterface_t *CAFindInterfaceChange()
+u_arraylist_t  *CAFindInterfaceChange()
 {
 {
+    u_arraylist_t *iflist = u_arraylist_create();
+    if (!iflist)
+    {
+        OIC_LOG_V(ERROR, TAG, "Failed to create iflist: %s", strerror(errno));
+        return NULL;
+    }
+
     oc_mutex_lock(g_CAIPNetworkMonitorMutex);
 
     bool someAddressWentAway = g_CAIPNetworkMonitorSomeAddressWentAway;
     g_CAIPNetworkMonitorSomeAddressWentAway = false;
 
     oc_mutex_lock(g_CAIPNetworkMonitorMutex);
 
     bool someAddressWentAway = g_CAIPNetworkMonitorSomeAddressWentAway;
     g_CAIPNetworkMonitorSomeAddressWentAway = false;
 
-    CAInterface_t *newAddress = NULL;
-    if (g_CAIPNetworkMonitorNewAddressQueue)
+    bool newAddress = false;
+
+    // Pop whole new address in list.
+    while (g_CAIPNetworkMonitorNewAddressQueue)
     {
     {
-        // Pop the first new address to return.
         CANewAddress_t *change = g_CAIPNetworkMonitorNewAddressQueue;
         CANewAddress_t *change = g_CAIPNetworkMonitorNewAddressQueue;
-        DL_DELETE(g_CAIPNetworkMonitorNewAddressQueue, change);
-        newAddress = change->ipAddressInfo;
-        OICFree(change);
+
+        bool result = u_arraylist_add(iflist, change->ipAddressInfo);
+        if (!result)
+        {
+            OIC_LOG(ERROR, TAG, "u_arraylist_add failed.");
+            break;
+        }
+        else
+        {
+            DL_DELETE(g_CAIPNetworkMonitorNewAddressQueue, change);
+            OICFree(change);
+            newAddress = true;
+        }
     }
 
     oc_mutex_unlock(g_CAIPNetworkMonitorMutex);
     }
 
     oc_mutex_unlock(g_CAIPNetworkMonitorMutex);
@@ -438,7 +453,7 @@ CAInterface_t *CAFindInterfaceChange()
         CAIPPassNetworkChangesToTransportAdapter(CA_INTERFACE_UP);
     }
 
         CAIPPassNetworkChangesToTransportAdapter(CA_INTERFACE_UP);
     }
 
-    return newAddress;
+    return iflist;
 }
 
 static bool IsValidNetworkAdapter(PIP_ADAPTER_ADDRESSES pAdapterAddr, int desiredIndex)
 }
 
 static bool IsValidNetworkAdapter(PIP_ADAPTER_ADDRESSES pAdapterAddr, int desiredIndex)