Add better routes for secondary DNS

We'd been doing no-gateway hostroutes for dns servers on secondary nets, but on
some devices (multi-homed stingray) this is a problem.  Add gateway-ed hostroutes
instead so the BP can do it's nonstandard "magical" demultiplexing.

bug:5011392
Change-Id: Ia48f69c8ddf2a37cfb8f014f078f96bf601d2ddb
This commit is contained in:
Robert Greenwalt
2011-07-22 11:55:33 -07:00
parent cae18f1a8e
commit 9810742cd8
2 changed files with 58 additions and 32 deletions

View File

@@ -58,8 +58,8 @@ public class LinkProperties implements Parcelable {
private ProxyProperties mHttpProxy; private ProxyProperties mHttpProxy;
public static class CompareResult<T> { public static class CompareResult<T> {
public ArrayList<T> removed = new ArrayList<T>(); public Collection<T> removed = new ArrayList<T>();
public ArrayList<T> added = new ArrayList<T>(); public Collection<T> added = new ArrayList<T>();
@Override @Override
public String toString() { public String toString() {

View File

@@ -963,7 +963,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
try { try {
InetAddress addr = InetAddress.getByAddress(hostAddress); InetAddress addr = InetAddress.getByAddress(hostAddress);
LinkProperties lp = tracker.getLinkProperties(); LinkProperties lp = tracker.getLinkProperties();
return addRoute(lp, RouteInfo.makeHostRoute(addr)); return addRouteToAddress(lp, addr);
} catch (UnknownHostException e) {} } catch (UnknownHostException e) {}
return false; return false;
} }
@@ -976,6 +976,31 @@ public class ConnectivityService extends IConnectivityManager.Stub {
return modifyRoute(p.getInterfaceName(), p, r, 0, false); return modifyRoute(p.getInterfaceName(), p, r, 0, false);
} }
private boolean addRouteToAddress(LinkProperties lp, InetAddress addr) {
return modifyRouteToAddress(lp, addr, true);
}
private boolean removeRouteToAddress(LinkProperties lp, InetAddress addr) {
return modifyRouteToAddress(lp, addr, false);
}
private boolean modifyRouteToAddress(LinkProperties lp, InetAddress addr, boolean doAdd) {
RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getRoutes(), addr);
if (bestRoute == null) {
bestRoute = RouteInfo.makeHostRoute(addr);
} else {
if (bestRoute.getGateway().equals(addr)) {
// if there is no better route, add the implied hostroute for our gateway
bestRoute = RouteInfo.makeHostRoute(addr);
} else {
// if we will connect to this through another route, add a direct route
// to it's gateway
bestRoute = RouteInfo.makeHostRoute(addr, bestRoute.getGateway());
}
}
return modifyRoute(lp.getInterfaceName(), lp, bestRoute, 0, doAdd);
}
private boolean modifyRoute(String ifaceName, LinkProperties lp, RouteInfo r, int cycleCount, private boolean modifyRoute(String ifaceName, LinkProperties lp, RouteInfo r, int cycleCount,
boolean doAdd) { boolean doAdd) {
if ((ifaceName == null) || (lp == null) || (r == null)) return false; if ((ifaceName == null) || (lp == null) || (r == null)) return false;
@@ -1547,49 +1572,50 @@ public class ConnectivityService extends IConnectivityManager.Stub {
*/ */
private void updateRoutes(LinkProperties newLp, LinkProperties curLp, boolean isLinkDefault) { private void updateRoutes(LinkProperties newLp, LinkProperties curLp, boolean isLinkDefault) {
Collection<RouteInfo> routesToAdd = null; Collection<RouteInfo> routesToAdd = null;
CompareResult<InetAddress> dnsDiff = null; CompareResult<InetAddress> dnsDiff = new CompareResult<InetAddress>();
CompareResult<RouteInfo> routeDiff = new CompareResult<RouteInfo>();
if (curLp != null) { if (curLp != null) {
// check for the delta between the current set and the new // check for the delta between the current set and the new
CompareResult<RouteInfo> routeDiff = curLp.compareRoutes(newLp); routeDiff = curLp.compareRoutes(newLp);
dnsDiff = curLp.compareDnses(newLp); dnsDiff = curLp.compareDnses(newLp);
} else if (newLp != null) {
for (RouteInfo r : routeDiff.removed) { routeDiff.added = newLp.getRoutes();
if (isLinkDefault || ! r.isDefaultRoute()) { dnsDiff.added = newLp.getDnses();
removeRoute(curLp, r);
}
}
routesToAdd = routeDiff.added;
} }
if (newLp != null) { for (RouteInfo r : routeDiff.removed) {
// if we didn't get a diff from cur -> new, then just use the new if (isLinkDefault || ! r.isDefaultRoute()) {
if (routesToAdd == null) { removeRoute(curLp, r);
routesToAdd = newLp.getRoutes();
} }
}
for (RouteInfo r : routesToAdd) { for (RouteInfo r : routeDiff.added) {
if (isLinkDefault || ! r.isDefaultRoute()) { if (isLinkDefault || ! r.isDefaultRoute()) {
addRoute(newLp, r); addRoute(newLp, r);
}
} }
} }
if (!isLinkDefault) { if (!isLinkDefault) {
// handle DNS routes // handle DNS routes
Collection<InetAddress> dnsToAdd = null; if (routeDiff.removed.size() == 0 && routeDiff.added.size() == 0) {
if (dnsDiff != null) { // no change in routes, check for change in dns themselves
dnsToAdd = dnsDiff.added; for (InetAddress oldDns : dnsDiff.removed) {
for (InetAddress dnsAddress : dnsDiff.removed) { removeRouteToAddress(curLp, oldDns);
removeRoute(curLp, RouteInfo.makeHostRoute(dnsAddress));
} }
} for (InetAddress newDns : dnsDiff.added) {
if (newLp != null) { addRouteToAddress(newLp, newDns);
if (dnsToAdd == null) {
dnsToAdd = newLp.getDnses();
} }
for(InetAddress dnsAddress : dnsToAdd) { } else {
addRoute(newLp, RouteInfo.makeHostRoute(dnsAddress)); // routes changed - remove all old dns entries and add new
if (curLp != null) {
for (InetAddress oldDns : curLp.getDnses()) {
removeRouteToAddress(curLp, oldDns);
}
}
if (newLp != null) {
for (InetAddress newDns : newLp.getDnses()) {
addRouteToAddress(newLp, newDns);
}
} }
} }
} }