From 7261a3d1f3e7c1487e885847461965bc0c43be6c Mon Sep 17 00:00:00 2001 From: "bg.chun" Date: Tue, 4 Oct 2016 11:44:58 +0900 Subject: [PATCH] [IOT-1361]Change "CAFindInterfaceChange()" to support IPv4/6 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 Reviewed-on: https://gerrit.iotivity.org/gerrit/12737 Tested-by: jenkins-iotivity Reviewed-by: jihwan seo Reviewed-by: David Antler Reviewed-by: Hyuna Jo Reviewed-by: Dave Thaler Reviewed-by: Ashok Babu Channa --- resource/csdk/connectivity/inc/caipnwmonitor.h | 6 +-- .../src/ip_adapter/android/caipnwmonitor.c | 37 ++++++++++++++++++- .../csdk/connectivity/src/ip_adapter/caipserver.c | 32 ++++++++++++---- .../src/ip_adapter/linux/caipnwmonitor.c | 29 +++------------ .../src/ip_adapter/tizen/caipnwmonitor.c | 32 +++------------- .../src/ip_adapter/windows/caipnwmonitor.c | 43 +++++++++++++++------- 6 files changed, 102 insertions(+), 77 deletions(-) diff --git a/resource/csdk/connectivity/inc/caipnwmonitor.h b/resource/csdk/connectivity/inc/caipnwmonitor.h index d76c6fe..e2e7c70 100644 --- a/resource/csdk/connectivity/inc/caipnwmonitor.h +++ b/resource/csdk/connectivity/inc/caipnwmonitor.h @@ -95,11 +95,11 @@ CAResult_t CAIPUnSetNetworkMonitorCallback(CATransportAdapter_t adapter); 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. diff --git a/resource/csdk/connectivity/src/ip_adapter/android/caipnwmonitor.c b/resource/csdk/connectivity/src/ip_adapter/android/caipnwmonitor.c index b1f84ca..03b7294 100644 --- a/resource/csdk/connectivity/src/ip_adapter/android/caipnwmonitor.c +++ b/resource/csdk/connectivity/src/ip_adapter/android/caipnwmonitor.c @@ -178,7 +178,7 @@ CAResult_t CAIPUnSetNetworkMonitorCallback(CATransportAdapter_t adapter) return CA_STATUS_OK; } -CAInterface_t *CAFindInterfaceChange() +u_arraylist_t *CAFindInterfaceChange() { // release netlink event char *bufPtr = (char *)OICCalloc(NETLINK_MESSAGE_LENGTH, sizeof (char)); @@ -201,6 +201,7 @@ CAInterface_t *CAFindInterfaceChange() return NULL; } + u_arraylist_t *iflist = NULL; CAInterface_t *foundNewInterface = NULL; struct ifreq* ifr = ifc.ifc_req; @@ -287,7 +288,39 @@ CAInterface_t *CAFindInterfaceChange() } 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) diff --git a/resource/csdk/connectivity/src/ip_adapter/caipserver.c b/resource/csdk/connectivity/src/ip_adapter/caipserver.c index 4ed0679..31a9b2d 100644 --- a/resource/csdk/connectivity/src/ip_adapter/caipserver.c +++ b/resource/csdk/connectivity/src/ip_adapter/caipserver.c @@ -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)) { - 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; } @@ -411,11 +419,19 @@ static void CAFindReadyMessage() 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; } diff --git a/resource/csdk/connectivity/src/ip_adapter/linux/caipnwmonitor.c b/resource/csdk/connectivity/src/ip_adapter/linux/caipnwmonitor.c index c1471b2..904fc68 100644 --- a/resource/csdk/connectivity/src/ip_adapter/linux/caipnwmonitor.c +++ b/resource/csdk/connectivity/src/ip_adapter/linux/caipnwmonitor.c @@ -311,9 +311,9 @@ static CAInterface_t *CANewInterfaceItem(int index, const char *name, int family 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; @@ -349,35 +349,16 @@ CAInterface_t *CAFindInterfaceChange() 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; } - - 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 - return foundNewInterface; + return iflist; } u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex) diff --git a/resource/csdk/connectivity/src/ip_adapter/tizen/caipnwmonitor.c b/resource/csdk/connectivity/src/ip_adapter/tizen/caipnwmonitor.c index a141c3b..0a72969 100644 --- a/resource/csdk/connectivity/src/ip_adapter/tizen/caipnwmonitor.c +++ b/resource/csdk/connectivity/src/ip_adapter/tizen/caipnwmonitor.c @@ -154,9 +154,9 @@ CAResult_t CAIPUnSetNetworkMonitorCallback(CATransportAdapter_t adapter) 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, @@ -177,41 +177,21 @@ CAInterface_t *CAFindInterfaceChange() 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; } + int ifiIndex = ifi->ifi_index; + iflist = CAIPGetInterfaceInformation(ifiIndex); + 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, diff --git a/resource/csdk/connectivity/src/ip_adapter/windows/caipnwmonitor.c b/resource/csdk/connectivity/src/ip_adapter/windows/caipnwmonitor.c index 1e86d3f..6350025 100644 --- a/resource/csdk/connectivity/src/ip_adapter/windows/caipnwmonitor.c +++ b/resource/csdk/connectivity/src/ip_adapter/windows/caipnwmonitor.c @@ -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; - 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; - 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); @@ -438,7 +453,7 @@ CAInterface_t *CAFindInterfaceChange() CAIPPassNetworkChangesToTransportAdapter(CA_INTERFACE_UP); } - return newAddress; + return iflist; } static bool IsValidNetworkAdapter(PIP_ADAPTER_ADDRESSES pAdapterAddr, int desiredIndex) -- 2.7.4