summaryrefslogtreecommitdiffstats
path: root/server/NetlinkHandler.cpp
diff options
context:
space:
mode:
authorRubin Xu <rubinxu@google.com>2018-06-27 16:27:26 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2018-06-27 16:27:26 +0000
commit25006326b33f90bba4274947b4214fbe569e5b90 (patch)
tree73bdaf750a203594815f57166b024a5ffff9b9ff /server/NetlinkHandler.cpp
parentf0c02e4595fe0a637b62eb53479642e17e856799 (diff)
parent6c00b61656da32ce3223a2fc711f5649b6b7b5ac (diff)
downloadplatform_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.cpp66
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);
}