diff options
Diffstat (limited to 'services/java/com/android/server/ConnectivityService.java')
-rw-r--r-- | services/java/com/android/server/ConnectivityService.java | 244 |
1 files changed, 178 insertions, 66 deletions
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index b78424b..79c0675 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -155,7 +155,9 @@ public class ConnectivityService extends IConnectivityManager.Stub { private boolean mInetConditionChangeInFlight = false; private int mDefaultConnectionSequence = 0; + private Object mDnsLock = new Object(); private int mNumDnsEntries; + private boolean mDnsOverridden = false; private boolean mTestMode; private static ConnectivityService sServiceInstance; @@ -244,6 +246,13 @@ public class ConnectivityService extends IConnectivityManager.Stub { private static final int EVENT_SET_DEPENDENCY_MET = MAX_NETWORK_STATE_TRACKER_EVENT + 10; + /** + * used internally to restore DNS properties back to the + * default network + */ + private static final int EVENT_RESTORE_DNS = + MAX_NETWORK_STATE_TRACKER_EVENT + 11; + private Handler mHandler; // list of DeathRecipients used to make sure features are turned off when @@ -1081,7 +1090,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { try { InetAddress addr = InetAddress.getByAddress(hostAddress); LinkProperties lp = tracker.getLinkProperties(); - return addRoute(lp, RouteInfo.makeHostRoute(addr)); + return addRouteToAddress(lp, addr); } catch (UnknownHostException e) {} return false; } @@ -1094,6 +1103,31 @@ public class ConnectivityService extends IConnectivityManager.Stub { 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, boolean doAdd) { if ((ifaceName == null) || (lp == null) || (r == null)) return false; @@ -1704,49 +1738,50 @@ public class ConnectivityService extends IConnectivityManager.Stub { */ private void updateRoutes(LinkProperties newLp, LinkProperties curLp, boolean isLinkDefault) { Collection<RouteInfo> routesToAdd = null; - CompareResult<InetAddress> dnsDiff = null; - + CompareResult<InetAddress> dnsDiff = new CompareResult<InetAddress>(); + CompareResult<RouteInfo> routeDiff = new CompareResult<RouteInfo>(); if (curLp != null) { // 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); - - for (RouteInfo r : routeDiff.removed) { - if (isLinkDefault || ! r.isDefaultRoute()) { - removeRoute(curLp, r); - } - } - routesToAdd = routeDiff.added; + } else if (newLp != null) { + routeDiff.added = newLp.getRoutes(); + dnsDiff.added = newLp.getDnses(); } - if (newLp != null) { - // if we didn't get a diff from cur -> new, then just use the new - if (routesToAdd == null) { - routesToAdd = newLp.getRoutes(); + for (RouteInfo r : routeDiff.removed) { + if (isLinkDefault || ! r.isDefaultRoute()) { + removeRoute(curLp, r); } + } - for (RouteInfo r : routesToAdd) { - if (isLinkDefault || ! r.isDefaultRoute()) { - addRoute(newLp, r); - } + for (RouteInfo r : routeDiff.added) { + if (isLinkDefault || ! r.isDefaultRoute()) { + addRoute(newLp, r); } } if (!isLinkDefault) { // handle DNS routes - Collection<InetAddress> dnsToAdd = null; - if (dnsDiff != null) { - dnsToAdd = dnsDiff.added; - for (InetAddress dnsAddress : dnsDiff.removed) { - removeRoute(curLp, RouteInfo.makeHostRoute(dnsAddress)); + if (routeDiff.removed.size() == 0 && routeDiff.added.size() == 0) { + // no change in routes, check for change in dns themselves + for (InetAddress oldDns : dnsDiff.removed) { + removeRouteToAddress(curLp, oldDns); } - } - if (newLp != null) { - if (dnsToAdd == null) { - dnsToAdd = newLp.getDnses(); + for (InetAddress newDns : dnsDiff.added) { + addRouteToAddress(newLp, newDns); } - for(InetAddress dnsAddress : dnsToAdd) { - addRoute(newLp, RouteInfo.makeHostRoute(dnsAddress)); + } else { + // 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); + } } } } @@ -1890,6 +1925,50 @@ public class ConnectivityService extends IConnectivityManager.Stub { mContext.sendBroadcast(intent); } + // Caller must grab mDnsLock. + private boolean updateDns(String network, Collection<InetAddress> dnses, String domains) { + boolean changed = false; + int last = 0; + if (dnses.size() == 0 && mDefaultDns != null) { + ++last; + String value = mDefaultDns.getHostAddress(); + if (!value.equals(SystemProperties.get("net.dns1"))) { + if (DBG) { + log("no dns provided for " + network + " - using " + value); + } + changed = true; + SystemProperties.set("net.dns1", value); + } + } else { + for (InetAddress dns : dnses) { + ++last; + String key = "net.dns" + last; + String value = dns.getHostAddress(); + if (!changed && value.equals(SystemProperties.get(key))) { + continue; + } + if (DBG) { + log("adding dns " + value + " for " + network); + } + changed = true; + SystemProperties.set(key, value); + } + } + for (int i = last + 1; i <= mNumDnsEntries; ++i) { + String key = "net.dns" + i; + if (DBG) log("erasing " + key); + changed = true; + SystemProperties.set(key, ""); + } + mNumDnsEntries = last; + + if (!domains.equals(SystemProperties.get("net.dns.search"))) { + SystemProperties.set("net.dns.search", domains); + changed = true; + } + return changed; + } + private void handleDnsConfigurationChange(int netType) { // add default net's dns entries NetworkStateTracker nt = mNetTrackers[netType]; @@ -1899,40 +1978,12 @@ public class ConnectivityService extends IConnectivityManager.Stub { Collection<InetAddress> dnses = p.getDnses(); boolean changed = false; if (mNetConfigs[netType].isDefault()) { - int j = 1; - if (dnses.size() == 0 && mDefaultDns != null) { - String dnsString = mDefaultDns.getHostAddress(); - if (!dnsString.equals(SystemProperties.get("net.dns1"))) { - if (DBG) { - log("no dns provided - using " + dnsString); - } - changed = true; - SystemProperties.set("net.dns1", dnsString); - } - j++; - } else { - for (InetAddress dns : dnses) { - String dnsString = dns.getHostAddress(); - if (!changed && dnsString.equals(SystemProperties.get("net.dns" + j))) { - j++; - continue; - } - if (DBG) { - log("adding dns " + dns + " for " + - nt.getNetworkInfo().getTypeName()); - } - changed = true; - SystemProperties.set("net.dns" + j++, dnsString); - } - } - for (int k=j ; k<mNumDnsEntries; k++) { - if (changed || !TextUtils.isEmpty(SystemProperties.get("net.dns" + k))) { - if (DBG) log("erasing net.dns" + k); - changed = true; - SystemProperties.set("net.dns" + k, ""); + String network = nt.getNetworkInfo().getTypeName(); + synchronized (mDnsLock) { + if (!mDnsOverridden) { + changed = updateDns(network, dnses, ""); } } - mNumDnsEntries = j; } else { // set per-pid dns for attached secondary nets List pids = mNetRequestersPids[netType]; @@ -2139,6 +2190,13 @@ public class ConnectivityService extends IConnectivityManager.Stub { handleSetDependencyMet(msg.arg2, met); break; } + case EVENT_RESTORE_DNS: + { + if (mActiveDefaultNetwork != -1) { + handleDnsConfigurationChange(mActiveDefaultNetwork); + } + break; + } } } } @@ -2204,6 +2262,15 @@ public class ConnectivityService extends IConnectivityManager.Stub { } } + public int setUsbTethering(boolean enable) { + enforceTetherAccessPermission(); + if (isTetheringSupported()) { + return mTethering.setUsbTethering(enable); + } else { + return ConnectivityManager.TETHER_ERROR_UNSUPPORTED; + } + } + // TODO - move iface listing, queries, etc to new module // javadoc from interface public String[] getTetherableIfaces() { @@ -2586,12 +2653,57 @@ public class ConnectivityService extends IConnectivityManager.Stub { private VpnCallback() { } - public synchronized void override(List<String> dnsServers, List<String> searchDomains) { - // TODO: override DNS servers and http proxy. + public void override(List<String> dnsServers, List<String> searchDomains) { + if (dnsServers == null) { + restore(); + return; + } + + // Convert DNS servers into addresses. + List<InetAddress> addresses = new ArrayList<InetAddress>(); + for (String address : dnsServers) { + // Double check the addresses and remove invalid ones. + try { + addresses.add(InetAddress.parseNumericAddress(address)); + } catch (Exception e) { + // ignore + } + } + if (addresses.isEmpty()) { + restore(); + return; + } + + // Concatenate search domains into a string. + StringBuilder buffer = new StringBuilder(); + if (searchDomains != null) { + for (String domain : searchDomains) { + buffer.append(domain).append(' '); + } + } + String domains = buffer.toString().trim(); + + // Apply DNS changes. + boolean changed = false; + synchronized (mDnsLock) { + changed = updateDns("VPN", addresses, domains); + mDnsOverridden = true; + } + if (changed) { + bumpDns(); + } + + // TODO: temporarily remove http proxy? } - public synchronized void restore() { - // TODO: restore VPN changes. + public void restore() { + synchronized (mDnsLock) { + if (!mDnsOverridden) { + return; + } + mDnsOverridden = false; + } + mHandler.sendEmptyMessage(EVENT_RESTORE_DNS); } } } |