summaryrefslogtreecommitdiffstats
path: root/services/java/com/android/server/ConnectivityService.java
diff options
context:
space:
mode:
Diffstat (limited to 'services/java/com/android/server/ConnectivityService.java')
-rw-r--r--services/java/com/android/server/ConnectivityService.java244
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);
}
}
}