diff options
| author | Rubin Xu <rubinxu@google.com> | 2018-06-27 16:27:26 +0000 |
|---|---|---|
| committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2018-06-27 16:27:26 +0000 |
| commit | 25006326b33f90bba4274947b4214fbe569e5b90 (patch) | |
| tree | 73bdaf750a203594815f57166b024a5ffff9b9ff /server/NetlinkHandler.cpp | |
| parent | f0c02e4595fe0a637b62eb53479642e17e856799 (diff) | |
| parent | 6c00b61656da32ce3223a2fc711f5649b6b7b5ac (diff) | |
| download | platform_system_netd-25006326b33f90bba4274947b4214fbe569e5b90.tar.gz platform_system_netd-25006326b33f90bba4274947b4214fbe569e5b90.tar.bz2 platform_system_netd-25006326b33f90bba4274947b4214fbe569e5b90.zip | |
Merge "Do not destroy socket when VPN interface address is still in use"
Diffstat (limited to 'server/NetlinkHandler.cpp')
| -rw-r--r-- | server/NetlinkHandler.cpp | 66 |
1 files changed, 42 insertions, 24 deletions
diff --git a/server/NetlinkHandler.cpp b/server/NetlinkHandler.cpp index 928e32948..0b84c8c04 100644 --- a/server/NetlinkHandler.cpp +++ b/server/NetlinkHandler.cpp @@ -55,6 +55,18 @@ int NetlinkHandler::stop() { return this->stopListener(); } +static long parseIfIndex(const char* ifIndex) { + if (ifIndex == nullptr) { + return 0; + } + long ifaceIndex = strtol(ifIndex, NULL, 10); + // strtol returns 0 on error, which is fine because 0 is not a valid ifindex. + if (errno == ERANGE && (ifaceIndex == LONG_MAX || ifaceIndex == LONG_MIN)) { + return 0; + } + return ifaceIndex; +} + void NetlinkHandler::onEvent(NetlinkEvent *evt) { const char *subsys = evt->getSubsystem(); if (!subsys) { @@ -69,15 +81,11 @@ void NetlinkHandler::onEvent(NetlinkEvent *evt) { (action == NetlinkEvent::Action::kLinkUp) || (action == NetlinkEvent::Action::kLinkDown)) { const char *ifIndex = evt->findParam("IFINDEX"); - if (ifIndex) { - // strtol returns 0 on error, which is fine because 0 is not a valid ifindex. - long ifaceIndex = strtol(ifIndex, NULL, 10); - if (ifaceIndex == 0 || - (errno == ERANGE && (ifaceIndex == LONG_MAX || ifaceIndex == LONG_MIN))) { - ALOGE("invalid interface index: %s(%s)", iface, ifIndex); - } else { - gCtls->trafficCtrl.addInterface(iface, ifaceIndex); - } + long ifaceIndex = parseIfIndex(ifIndex); + if (ifaceIndex) { + gCtls->trafficCtrl.addInterface(iface, ifaceIndex); + } else { + ALOGE("invalid interface index: %s(%s)", iface, ifIndex); } } @@ -97,25 +105,35 @@ void NetlinkHandler::onEvent(NetlinkEvent *evt) { const char *address = evt->findParam("ADDRESS"); const char *flags = evt->findParam("FLAGS"); const char *scope = evt->findParam("SCOPE"); - if (action == NetlinkEvent::Action::kAddressRemoved && iface && address) { - // Note: if this interface was deleted, iface is "" and we don't notify. - SockDiag sd; - if (sd.open()) { - char addrstr[INET6_ADDRSTRLEN]; - strncpy(addrstr, address, sizeof(addrstr)); - char *slash = strchr(addrstr, '/'); - if (slash) { - *slash = '\0'; - } + const char *ifIndex = evt->findParam("IFINDEX"); + char addrstr[INET6_ADDRSTRLEN + strlen("/128")]; + strlcpy(addrstr, address, sizeof(addrstr)); + char *slash = strchr(addrstr, '/'); + if (slash) { + *slash = '\0'; + } - int ret = sd.destroySockets(addrstr); - if (ret < 0) { - ALOGE("Error destroying sockets: %s", strerror(ret)); + long ifaceIndex = parseIfIndex(ifIndex); + if (!ifaceIndex) { + ALOGE("invalid interface index: %s(%s)", iface, ifIndex); + } + if (action == NetlinkEvent::Action::kAddressUpdated) { + gCtls->netCtrl.addInterfaceAddress(ifaceIndex, address); + } else { // action == NetlinkEvent::Action::kAddressRemoved + bool shouldDestroy = gCtls->netCtrl.removeInterfaceAddress(ifaceIndex, address); + if (shouldDestroy) { + SockDiag sd; + if (sd.open()) { + int ret = sd.destroySockets(addrstr); + if (ret < 0) { + ALOGE("Error destroying sockets: %s", strerror(-ret)); + } + } else { + ALOGE("Error opening NETLINK_SOCK_DIAG socket: %s", strerror(errno)); } - } else { - ALOGE("Error opening NETLINK_SOCK_DIAG socket: %s", strerror(errno)); } } + // Note: if this interface was deleted, iface is "" and we don't notify. if (iface && iface[0] && address && flags && scope) { notifyAddressChanged(action, address, iface, flags, scope); } |
