From 0b628a4ffb3d6d7e07aa5f983f426b9bc88b996e Mon Sep 17 00:00:00 2001 From: "hyuna0213.jo" Date: Thu, 21 Jul 2016 10:34:16 +0900 Subject: [PATCH] modified network interface monitoring logic in tizen To detect network interface changes in tizen, CAFindInterfaceChange() function was modified. Change-Id: I325c59205b090f9715d72f533faf27831e114792 Signed-off-by: hyuna0213.jo Reviewed-on: https://gerrit.iotivity.org/gerrit/9527 Tested-by: jenkins-iotivity Reviewed-by: Jon A. Cruz (cherry picked from commit c5ec8565783a5be30d8089bafa2ede7466641837) Reviewed-on: https://gerrit.iotivity.org/gerrit/9599 Reviewed-by: Ashok Babu Channa --- .../src/ip_adapter/tizen/caipnwmonitor.c | 120 ++++++++------------- 1 file changed, 45 insertions(+), 75 deletions(-) diff --git a/resource/csdk/connectivity/src/ip_adapter/tizen/caipnwmonitor.c b/resource/csdk/connectivity/src/ip_adapter/tizen/caipnwmonitor.c index aaa39d4..0d30c79 100644 --- a/resource/csdk/connectivity/src/ip_adapter/tizen/caipnwmonitor.c +++ b/resource/csdk/connectivity/src/ip_adapter/tizen/caipnwmonitor.c @@ -30,6 +30,10 @@ #include #include #include +#include +#include +#include +#include #include "caadapterutils.h" #include "logger.h" @@ -37,8 +41,11 @@ #include "oic_string.h" #define TAG "IP_MONITOR" + #define MAX_INTERFACE_INFO_LENGTH (1024) +#define NETLINK_MESSAGE_LENGTH (4096) + static CAIPConnectionStateChangeCallback g_networkChangeCallback; static CAInterface_t *CANewInterfaceItem(int index, char *name, int family, @@ -65,99 +72,62 @@ void CAIPSetNetworkMonitorCallback(CAIPConnectionStateChangeCallback callback) CAInterface_t *CAFindInterfaceChange() { - char buf[MAX_INTERFACE_INFO_LENGTH] = { 0 }; - struct ifconf ifc = { .ifc_len = MAX_INTERFACE_INFO_LENGTH, .ifc_buf = buf }; - - int s = caglobals.ip.u6.fd != -1 ? caglobals.ip.u6.fd : caglobals.ip.u4.fd; - if (ioctl(s, SIOCGIFCONF, &ifc) < 0) - { - OIC_LOG_V(ERROR, TAG, "SIOCGIFCONF failed: %s", strerror(errno)); - return NULL; - } - CAInterface_t *foundNewInterface = NULL; - - struct ifreq* ifr = ifc.ifc_req; - size_t interfaces = ifc.ifc_len / sizeof (ifc.ifc_req[0]); - size_t ifreqsize = ifc.ifc_len; - - CAIfItem_t *previous = (CAIfItem_t *)OICMalloc(ifreqsize); - if (!previous) + char buf[NETLINK_MESSAGE_LENGTH] = { 0 }; + struct sockaddr_nl sa = { 0 }; + struct iovec iov = { .iov_base = buf, + .iov_len = sizeof (buf) }; + struct msghdr msg = { .msg_name = (void *)&sa, + .msg_namelen = sizeof (sa), + .msg_iov = &iov, + .msg_iovlen = 1 }; + + size_t len = recvmsg(caglobals.ip.netlinkFd, &msg, 0); + + for (struct nlmsghdr *nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, len); nh = NLMSG_NEXT(nh, len)) { - OIC_LOG(ERROR, TAG, "OICMalloc failed"); - return NULL; - } - - memcpy(previous, caglobals.ip.nm.ifItems, ifreqsize); - size_t numprevious = caglobals.ip.nm.numIfItems; - - if (ifreqsize > caglobals.ip.nm.sizeIfItems) - { - - CAIfItem_t *items = (CAIfItem_t *)OICRealloc(caglobals.ip.nm.ifItems, ifreqsize); - if (!items) + if (nh != NULL && nh->nlmsg_type != RTM_NEWLINK) { - OIC_LOG(ERROR, TAG, "OICRealloc failed"); - OICFree(previous); - return NULL; + continue; } - caglobals.ip.nm.ifItems = items; - caglobals.ip.nm.sizeIfItems = ifreqsize; - } - caglobals.ip.nm.numIfItems = 0; - for (size_t i = 0; i < interfaces; i++) - { - struct ifreq* item = &ifr[i]; - char *name = item->ifr_name; - struct sockaddr_in *sa4 = (struct sockaddr_in *)&item->ifr_addr; - uint32_t ipv4addr = sa4->sin_addr.s_addr; + struct ifinfomsg *ifi = (struct ifinfomsg *)NLMSG_DATA(nh); - if (ioctl(s, SIOCGIFFLAGS, item) < 0) - { - OIC_LOG_V(ERROR, TAG, "SIOCGIFFLAGS failed: %s", strerror(errno)); - continue; - } - int16_t flags = item->ifr_flags; - if ((flags & IFF_LOOPBACK) || !(flags & IFF_RUNNING)) - { - continue; - } - if (ioctl(s, SIOCGIFINDEX, item) < 0) + int ifiIndex = ifi->ifi_index; + u_arraylist_t *iflist = CAIPGetInterfaceInformation(ifiIndex); + + if ((!ifi || (ifi->ifi_flags & IFF_LOOPBACK) || !(ifi->ifi_flags & IFF_RUNNING))) { - OIC_LOG_V(ERROR, TAG, "SIOCGIFINDEX failed: %s", strerror(errno)); continue; } - int ifIndex = item->ifr_ifindex; - caglobals.ip.nm.ifItems[i].ifIndex = ifIndex; // refill interface list - caglobals.ip.nm.numIfItems++; - - if (foundNewInterface) + if (!iflist) { - continue; // continue updating interface list + OIC_LOG_V(ERROR, TAG, "get interface info failed: %s", strerror(errno)); + return NULL; } - // see if this interface didn't previously exist - bool found = false; - for (size_t j = 0; j < numprevious; j++) + uint32_t listLength = u_arraylist_length(iflist); + for (uint32_t i = 0; i < listLength; i++) { - if (ifIndex == previous[j].ifIndex) + CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i); + if (!ifitem) { - found = true; - break; + continue; } - } - if (found) - { - OIC_LOG_V(INFO, TAG, "Interface found: %s", name); - continue; - } - foundNewInterface = CANewInterfaceItem(ifIndex, name, AF_INET, ipv4addr, flags); - } + if ((int)ifitem->index != ifiIndex) + { + continue; + } - OICFree(previous); + + foundNewInterface = CANewInterfaceItem(ifitem->index, ifitem->name, ifitem->family, + ifitem->ipv4addr, ifitem->flags); + break; // we found the one we were looking for + } + u_arraylist_destroy(iflist); + } return foundNewInterface; } -- 2.7.4