Second pass tying into dns cache per interface

Set dns servers for secondary nets and attach the
processes (pids) that are using the secondary nets
to the secondary nets associated dns cache.

bug:5465296
Change-Id: I1eaf92d5c6b81d287e9fb2763b3d972d9de34395
This commit is contained in:
Mattias Falk
2011-08-23 14:15:13 +02:00
committed by Robert Greenwalt
parent c9083111d9
commit d697aa2e38

View File

@@ -183,7 +183,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
* A per Net list of the PID's that requested access to the net * A per Net list of the PID's that requested access to the net
* used both as a refcount and for per-PID DNS selection * used both as a refcount and for per-PID DNS selection
*/ */
private List mNetRequestersPids[]; private List<Integer> mNetRequestersPids[];
// priority order of the nettrackers // priority order of the nettrackers
// (excluding dynamically set mNetworkPreference) // (excluding dynamically set mNetworkPreference)
@@ -199,7 +199,6 @@ public class ConnectivityService extends IConnectivityManager.Stub {
private int mDefaultConnectionSequence = 0; private int mDefaultConnectionSequence = 0;
private Object mDnsLock = new Object(); private Object mDnsLock = new Object();
private int mNumDnsEntries;
private boolean mDnsOverridden = false; private boolean mDnsOverridden = false;
private boolean mTestMode; private boolean mTestMode;
@@ -507,15 +506,14 @@ public class ConnectivityService extends IConnectivityManager.Stub {
} }
} }
mNetRequestersPids = new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE+1]; mNetRequestersPids =
(List<Integer> [])new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE+1];
for (int i : mPriorityList) { for (int i : mPriorityList) {
mNetRequestersPids[i] = new ArrayList(); mNetRequestersPids[i] = new ArrayList<Integer>();
} }
mFeatureUsers = new ArrayList<FeatureUser>(); mFeatureUsers = new ArrayList<FeatureUser>();
mNumDnsEntries = 0;
mTestMode = SystemProperties.get("cm.test.mode").equals("true") mTestMode = SystemProperties.get("cm.test.mode").equals("true")
&& SystemProperties.get("ro.build.type").equals("eng"); && SystemProperties.get("ro.build.type").equals("eng");
@@ -1316,6 +1314,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
Integer currentPid = new Integer(pid); Integer currentPid = new Integer(pid);
mNetRequestersPids[usedNetworkType].remove(currentPid); mNetRequestersPids[usedNetworkType].remove(currentPid);
reassessPidDns(pid, true); reassessPidDns(pid, true);
flushVmDnsCache();
if (mNetRequestersPids[usedNetworkType].size() != 0) { if (mNetRequestersPids[usedNetworkType].size() != 0) {
if (VDBG) { if (VDBG) {
log("stopUsingNetworkFeature: net " + networkType + ": " + feature + log("stopUsingNetworkFeature: net " + networkType + ": " + feature +
@@ -1697,9 +1696,8 @@ public class ConnectivityService extends IConnectivityManager.Stub {
* in accordance with network preference policies. * in accordance with network preference policies.
*/ */
if (!mNetConfigs[prevNetType].isDefault()) { if (!mNetConfigs[prevNetType].isDefault()) {
List pids = mNetRequestersPids[prevNetType]; List<Integer> pids = mNetRequestersPids[prevNetType];
for (int i = 0; i<pids.size(); i++) { for (Integer pid : pids) {
Integer pid = (Integer)pids.get(i);
// will remove them because the net's no longer connected // will remove them because the net's no longer connected
// need to do this now as only now do we know the pids and // need to do this now as only now do we know the pids and
// can properly null things that are no longer referenced. // can properly null things that are no longer referenced.
@@ -2261,6 +2259,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
} }
} }
if (resetDns) { if (resetDns) {
flushVmDnsCache();
if (VDBG) log("resetting DNS cache for " + iface); if (VDBG) log("resetting DNS cache for " + iface);
try { try {
mNetd.flushInterfaceDnsCache(iface); mNetd.flushInterfaceDnsCache(iface);
@@ -2427,9 +2426,10 @@ public class ConnectivityService extends IConnectivityManager.Stub {
* on the highest priority active net which this process requested. * on the highest priority active net which this process requested.
* If there aren't any, clear it out * If there aren't any, clear it out
*/ */
private void reassessPidDns(int myPid, boolean doBump) private void reassessPidDns(int pid, boolean doBump)
{ {
if (VDBG) log("reassessPidDns for pid " + myPid); if (VDBG) log("reassessPidDns for pid " + pid);
Integer myPid = new Integer(pid);
for(int i : mPriorityList) { for(int i : mPriorityList) {
if (mNetConfigs[i].isDefault()) { if (mNetConfigs[i].isDefault()) {
continue; continue;
@@ -2439,61 +2439,25 @@ public class ConnectivityService extends IConnectivityManager.Stub {
!nt.isTeardownRequested()) { !nt.isTeardownRequested()) {
LinkProperties p = nt.getLinkProperties(); LinkProperties p = nt.getLinkProperties();
if (p == null) continue; if (p == null) continue;
List pids = mNetRequestersPids[i]; if (mNetRequestersPids[i].contains(myPid)) {
for (int j=0; j<pids.size(); j++) { try {
Integer pid = (Integer)pids.get(j); mNetd.setDnsInterfaceForPid(p.getInterfaceName(), pid);
if (pid.intValue() == myPid) { } catch (Exception e) {
Collection<InetAddress> dnses = p.getDnses(); Slog.e(TAG, "exception reasseses pid dns: " + e);
writePidDns(dnses, myPid);
if (doBump) {
bumpDns();
} }
return; return;
} }
} }
} }
}
// nothing found - delete // nothing found - delete
for (int i = 1; ; i++) {
String prop = "net.dns" + i + "." + myPid;
if (SystemProperties.get(prop).length() == 0) {
if (doBump) {
bumpDns();
}
return;
}
SystemProperties.set(prop, "");
}
}
// return true if results in a change
private boolean writePidDns(Collection <InetAddress> dnses, int pid) {
int j = 1;
boolean changed = false;
for (InetAddress dns : dnses) {
String dnsString = dns.getHostAddress();
if (changed || !dnsString.equals(SystemProperties.get("net.dns" + j + "." + pid))) {
changed = true;
SystemProperties.set("net.dns" + j + "." + pid, dns.getHostAddress());
}
j++;
}
return changed;
}
private void bumpDns() {
/*
* Bump the property that tells the name resolver library to reread
* the DNS server list from the properties.
*/
String propVal = SystemProperties.get("net.dnschange");
int n = 0;
if (propVal.length() != 0) {
try { try {
n = Integer.parseInt(propVal); mNetd.clearDnsInterfaceForPid(pid);
} catch (NumberFormatException e) {} } catch (Exception e) {
Slog.e(TAG, "exception clear interface from pid: " + e);
} }
SystemProperties.set("net.dnschange", "" + (n+1)); }
private void flushVmDnsCache() {
/* /*
* Tell the VMs to toss their DNS caches * Tell the VMs to toss their DNS caches
*/ */
@@ -2512,48 +2476,17 @@ public class ConnectivityService extends IConnectivityManager.Stub {
} }
// Caller must grab mDnsLock. // Caller must grab mDnsLock.
private boolean updateDns(String network, String iface, private void updateDnsLocked(String network, String iface,
Collection<InetAddress> dnses, String domains) { Collection<InetAddress> dnses, String domains) {
boolean changed = false;
int last = 0; int last = 0;
if (dnses.size() == 0 && mDefaultDns != null) { if (dnses.size() == 0 && mDefaultDns != null) {
++last; dnses = new ArrayList();
String value = mDefaultDns.getHostAddress(); dnses.add(mDefaultDns);
if (!value.equals(SystemProperties.get("net.dns1"))) {
if (DBG) { if (DBG) {
loge("no dns provided for " + network + " - using " + value); loge("no dns provided for " + network + " - using " + mDefaultDns.getHostAddress());
} }
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 (VDBG) {
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 (VDBG) log("erasing " + key);
changed = true;
SystemProperties.set(key, "");
}
mNumDnsEntries = last;
if (SystemProperties.get("net.dns.search").equals(domains) == false) {
SystemProperties.set("net.dns.search", domains);
changed = true;
} }
if (changed) {
try { try {
mNetd.setDnsServersForInterface(iface, NetworkUtils.makeStrings(dnses), domains); mNetd.setDnsServersForInterface(iface, NetworkUtils.makeStrings(dnses), domains);
mNetd.setDefaultInterfaceForDns(iface); mNetd.setDefaultInterfaceForDns(iface);
@@ -2561,8 +2494,6 @@ public class ConnectivityService extends IConnectivityManager.Stub {
if (DBG) loge("exception setting default dns interface: " + e); if (DBG) loge("exception setting default dns interface: " + e);
} }
} }
return changed;
}
private void handleDnsConfigurationChange(int netType) { private void handleDnsConfigurationChange(int netType) {
// add default net's dns entries // add default net's dns entries
@@ -2571,12 +2502,11 @@ public class ConnectivityService extends IConnectivityManager.Stub {
LinkProperties p = nt.getLinkProperties(); LinkProperties p = nt.getLinkProperties();
if (p == null) return; if (p == null) return;
Collection<InetAddress> dnses = p.getDnses(); Collection<InetAddress> dnses = p.getDnses();
boolean changed = false;
if (mNetConfigs[netType].isDefault()) { if (mNetConfigs[netType].isDefault()) {
String network = nt.getNetworkInfo().getTypeName(); String network = nt.getNetworkInfo().getTypeName();
synchronized (mDnsLock) { synchronized (mDnsLock) {
if (!mDnsOverridden) { if (!mDnsOverridden) {
changed = updateDns(network, p.getInterfaceName(), dnses, p.getDomains()); updateDnsLocked(network, p.getInterfaceName(), dnses, p.getDomains());
} }
} }
} else { } else {
@@ -2587,13 +2517,16 @@ public class ConnectivityService extends IConnectivityManager.Stub {
if (DBG) loge("exception setting dns servers: " + e); if (DBG) loge("exception setting dns servers: " + e);
} }
// set per-pid dns for attached secondary nets // set per-pid dns for attached secondary nets
List pids = mNetRequestersPids[netType]; List<Integer> pids = mNetRequestersPids[netType];
for (int y=0; y< pids.size(); y++) { for (Integer pid : pids) {
Integer pid = (Integer)pids.get(y); try {
changed = writePidDns(dnses, pid.intValue()); mNetd.setDnsInterfaceForPid(p.getInterfaceName(), pid);
} catch (Exception e) {
Slog.e(TAG, "exception setting interface for pid: " + e);
} }
} }
if (changed) bumpDns(); }
flushVmDnsCache();
} }
} }
@@ -2652,7 +2585,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
pw.increaseIndent(); pw.increaseIndent();
for (int net : mPriorityList) { for (int net : mPriorityList) {
String pidString = net + ": "; String pidString = net + ": ";
for (Object pid : mNetRequestersPids[net]) { for (Integer pid : mNetRequestersPids[net]) {
pidString = pidString + pid.toString() + ", "; pidString = pidString + pid.toString() + ", ";
} }
pw.println(pidString); pw.println(pidString);
@@ -3354,14 +3287,10 @@ public class ConnectivityService extends IConnectivityManager.Stub {
String domains = buffer.toString().trim(); String domains = buffer.toString().trim();
// Apply DNS changes. // Apply DNS changes.
boolean changed = false;
synchronized (mDnsLock) { synchronized (mDnsLock) {
changed = updateDns("VPN", "VPN", addresses, domains); updateDnsLocked("VPN", "VPN", addresses, domains);
mDnsOverridden = true; mDnsOverridden = true;
} }
if (changed) {
bumpDns();
}
// Temporarily disable the default proxy. // Temporarily disable the default proxy.
synchronized (mDefaultProxyLock) { synchronized (mDefaultProxyLock) {