From 3e5bde3e5bf304a6a84b79b47a4e5760b77eef50 Mon Sep 17 00:00:00 2001 From: "hyuna0213.jo" Date: Mon, 14 Nov 2016 15:50:36 +0900 Subject: [PATCH] Use RTM_NEWADDR, RTM_DELADDR to receive info about an IP address. We use RTM_NEWLINK multicast group mask to receive information about a created or removed network interface. and If a specific network interface is added, we call getifaddrs() to get an IP address associated with an interface. but it is more correct to use RTM_NEWADDR, RTM_DELADDR to detect IP address changes. Change-Id: I9389cac95473583a015dd4d40489943dc856e0fd Signed-off-by: hyuna0213.jo Reviewed-on: https://gerrit.iotivity.org/gerrit/14277 Tested-by: jenkins-iotivity Reviewed-by: Jaehong Jo Reviewed-by: Dan Mihai Reviewed-by: Phil Coval Reviewed-by: Ashok Babu Channa --- .../csdk/connectivity/src/ip_adapter/caipserver.c | 3 +- .../src/ip_adapter/linux/caipnwmonitor.c | 41 +++++++++++----------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/resource/csdk/connectivity/src/ip_adapter/caipserver.c b/resource/csdk/connectivity/src/ip_adapter/caipserver.c index 5c2b06e..c7f9727 100644 --- a/resource/csdk/connectivity/src/ip_adapter/caipserver.c +++ b/resource/csdk/connectivity/src/ip_adapter/caipserver.c @@ -836,7 +836,8 @@ static void CARegisterForAddressChanges() caglobals.ip.netlinkFd = OC_INVALID_SOCKET; #ifdef __linux__ // create NETLINK fd for interface change notifications - struct sockaddr_nl sa = { AF_NETLINK, 0, 0, RTMGRP_LINK }; + struct sockaddr_nl sa = { AF_NETLINK, 0, 0, + RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR }; caglobals.ip.netlinkFd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_ROUTE); if (caglobals.ip.netlinkFd == OC_INVALID_SOCKET) diff --git a/resource/csdk/connectivity/src/ip_adapter/linux/caipnwmonitor.c b/resource/csdk/connectivity/src/ip_adapter/linux/caipnwmonitor.c index c64b6a0..26fbef8 100644 --- a/resource/csdk/connectivity/src/ip_adapter/linux/caipnwmonitor.c +++ b/resource/csdk/connectivity/src/ip_adapter/linux/caipnwmonitor.c @@ -330,37 +330,38 @@ u_arraylist_t *CAFindInterfaceChange() for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, len); nh = NLMSG_NEXT(nh, len)) { - if (nh != NULL && nh->nlmsg_type != RTM_NEWLINK) + if (nh != NULL && (nh->nlmsg_type != RTM_DELADDR && nh->nlmsg_type != RTM_NEWADDR)) { continue; } - struct ifinfomsg *ifi = (struct ifinfomsg *)NLMSG_DATA(nh); - if (!ifi) + if (RTM_DELADDR == nh->nlmsg_type) { - OIC_LOG_V(ERROR, TAG, "ifi is NULL"); - return NULL; - } - - int ifiIndex = ifi->ifi_index; - - if ((ifi->ifi_flags & IFF_LOOPBACK) || !(ifi->ifi_flags & IFF_RUNNING)) - { - bool isFound = CACmpNetworkList(ifiIndex); - if (isFound) + struct ifaddrmsg *ifa = (struct ifaddrmsg *)NLMSG_DATA (nh); + if (ifa) { - CARemoveNetworkMonitorList(ifiIndex); - CAIPPassNetworkChangesToAdapter(CA_INTERFACE_DOWN); + int ifiIndex = ifa->ifa_index; + bool isFound = CACmpNetworkList(ifiIndex); + if (isFound) + { + CARemoveNetworkMonitorList(ifiIndex); + CAIPPassNetworkChangesToAdapter(CA_INTERFACE_DOWN); + } } continue; } - iflist = CAIPGetInterfaceInformation(ifiIndex); - - if (!iflist) + // Netlink message type is RTM_NEWADDR. + struct ifaddrmsg *ifa = (struct ifaddrmsg *)NLMSG_DATA (nh); + if (ifa) { - OIC_LOG_V(ERROR, TAG, "get interface info failed: %s", strerror(errno)); - return NULL; + int ifiIndex = ifa->ifa_index; + iflist = CAIPGetInterfaceInformation(ifiIndex); + if (!iflist) + { + OIC_LOG_V(ERROR, TAG, "get interface info failed: %s", strerror(errno)); + return NULL; + } } } #endif -- 2.7.4