Merge "Added support for multiple DNS servers."

This commit is contained in:
Irfan Sheriff
2011-08-24 11:46:12 -07:00
committed by Android (Google) Code Review
2 changed files with 68 additions and 56 deletions

View File

@@ -67,7 +67,7 @@ public final class DnsPinger extends Handler {
private final Context mContext; private final Context mContext;
private final int mConnectionType; private final int mConnectionType;
private final Handler mTarget; private final Handler mTarget;
private final InetAddress mDefaultDns; private final ArrayList<InetAddress> mDefaultDns;
private String TAG; private String TAG;
private static final int BASE = Protocol.BASE_DNS_PINGER; private static final int BASE = Protocol.BASE_DNS_PINGER;
@@ -113,7 +113,8 @@ public final class DnsPinger extends Handler {
throw new IllegalArgumentException("Invalid connectionType in constructor: " throw new IllegalArgumentException("Invalid connectionType in constructor: "
+ connectionType); + connectionType);
} }
mDefaultDns = getDefaultDns(); mDefaultDns = new ArrayList<InetAddress>();
mDefaultDns.add(getDefaultDns());
mEventCounter = 0; mEventCounter = 0;
} }
@@ -213,17 +214,16 @@ public final class DnsPinger extends Handler {
for (ActivePing activePing : mActivePings) for (ActivePing activePing : mActivePings)
activePing.socket.close(); activePing.socket.close();
mActivePings.clear(); mActivePings.clear();
removeMessages(ACTION_PING_DNS);
break; break;
} }
} }
/** /**
* @return The first DNS in the link properties of the specified connection * Returns a list of DNS addresses, coming from either the link properties of the
* type or the default system DNS if the link properties has null * specified connection or the default system DNS if the link properties has no dnses.
* dns set. Should not be null. * @return a non-empty non-null list
*/ */
public InetAddress getDns() { public List<InetAddress> getDnsList() {
LinkProperties curLinkProps = getCurrentLinkProperties(); LinkProperties curLinkProps = getCurrentLinkProperties();
if (curLinkProps == null) { if (curLinkProps == null) {
Slog.e(TAG, "getCurLinkProperties:: LP for type" + mConnectionType + " is null!"); Slog.e(TAG, "getCurLinkProperties:: LP for type" + mConnectionType + " is null!");
@@ -236,7 +236,7 @@ public final class DnsPinger extends Handler {
return mDefaultDns; return mDefaultDns;
} }
return dnses.iterator().next(); return new ArrayList<InetAddress>(dnses);
} }
/** /**

View File

@@ -46,9 +46,9 @@ import java.io.PrintWriter;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.URL; import java.net.URL;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
/** /**
* {@link WifiWatchdogStateMachine} monitors the initial connection to a Wi-Fi * {@link WifiWatchdogStateMachine} monitors the initial connection to a Wi-Fi
@@ -79,7 +79,7 @@ public class WifiWatchdogStateMachine extends StateMachine {
private static final int LOW_SIGNAL_CUTOFF = 1; private static final int LOW_SIGNAL_CUTOFF = 1;
private static final long DEFAULT_DNS_CHECK_SHORT_INTERVAL_MS = 2 * 60 * 1000; private static final long DEFAULT_DNS_CHECK_SHORT_INTERVAL_MS = 2 * 60 * 1000;
private static final long DEFAULT_DNS_CHECK_LONG_INTERVAL_MS = 10 * 60 * 1000; private static final long DEFAULT_DNS_CHECK_LONG_INTERVAL_MS = 30 * 60 * 1000;
private static final long DEFAULT_WALLED_GARDEN_INTERVAL_MS = 30 * 60 * 1000; private static final long DEFAULT_WALLED_GARDEN_INTERVAL_MS = 30 * 60 * 1000;
private static final int DEFAULT_MAX_SSID_BLACKLISTS = 7; private static final int DEFAULT_MAX_SSID_BLACKLISTS = 7;
@@ -661,26 +661,34 @@ public class WifiWatchdogStateMachine extends StateMachine {
} }
class DnsCheckingState extends State { class DnsCheckingState extends State {
int dnsCheckSuccesses = 0; List<InetAddress> mDnsList;
int dnsCheckTries = 0; int[] dnsCheckSuccesses;
String dnsCheckLogStr = ""; String dnsCheckLogStr;
Set<Integer> ids = new HashSet<Integer>(); String[] dnsResponseStrs;
/** Keeps track of active dns pings. Map is from pingID to index in mDnsList */
HashMap<Integer, Integer> idDnsMap = new HashMap<Integer, Integer>();
@Override @Override
public void enter() { public void enter() {
dnsCheckSuccesses = 0; mDnsList = mDnsPinger.getDnsList();
dnsCheckTries = 0; int numDnses = mDnsList.size();
ids.clear(); dnsCheckSuccesses = new int[numDnses];
InetAddress dns = mDnsPinger.getDns(); dnsResponseStrs = new String[numDnses];
for (int i = 0; i < numDnses; i++)
dnsResponseStrs[i] = "";
if (DBG) { if (DBG) {
Slog.d(WWSM_TAG, "Starting DNS pings at " + SystemClock.elapsedRealtime());
dnsCheckLogStr = String.format("Pinging %s on ssid [%s]: ", dnsCheckLogStr = String.format("Pinging %s on ssid [%s]: ",
mDnsPinger.getDns(), mConnectionInfo.getSSID()); mDnsList, mConnectionInfo.getSSID());
Slog.d(WWSM_TAG, dnsCheckLogStr);
} }
idDnsMap.clear();
for (int i=0; i < mNumDnsPings; i++) { for (int i=0; i < mNumDnsPings; i++) {
ids.add(mDnsPinger.pingDnsAsync(dns, mDnsPingTimeoutMs, for (int j = 0; j < numDnses; j++) {
DNS_INTRATEST_PING_INTERVAL * i)); idDnsMap.put(mDnsPinger.pingDnsAsync(mDnsList.get(j), mDnsPingTimeoutMs,
DNS_INTRATEST_PING_INTERVAL * i), j);
}
} }
} }
@@ -693,27 +701,24 @@ public class WifiWatchdogStateMachine extends StateMachine {
int pingID = msg.arg1; int pingID = msg.arg1;
int pingResponseTime = msg.arg2; int pingResponseTime = msg.arg2;
if (!ids.contains(pingID)) { Integer dnsServerId = idDnsMap.get(pingID);
if (dnsServerId == null) {
Slog.w(WWSM_TAG, "Received a Dns response with unknown ID!"); Slog.w(WWSM_TAG, "Received a Dns response with unknown ID!");
return HANDLED; return HANDLED;
} }
ids.remove(pingID);
dnsCheckTries++; idDnsMap.remove(pingID);
if (pingResponseTime >= 0) if (pingResponseTime >= 0)
dnsCheckSuccesses++; dnsCheckSuccesses[dnsServerId]++;
if (DBG) { if (DBG) {
if (pingResponseTime >= 0) { if (pingResponseTime >= 0) {
dnsCheckLogStr += "|" + pingResponseTime; dnsResponseStrs[dnsServerId] += "|" + pingResponseTime;
} else { } else {
dnsCheckLogStr += "|x"; dnsResponseStrs[dnsServerId] += "|x";
} }
} }
if (VDBG) {
Slog.v(WWSM_TAG, dnsCheckLogStr);
}
/** /**
* After a full ping count, if we have more responses than this * After a full ping count, if we have more responses than this
* cutoff, the outcome is success; else it is 'failure'. * cutoff, the outcome is success; else it is 'failure'.
@@ -723,10 +728,10 @@ public class WifiWatchdogStateMachine extends StateMachine {
* Our final success count will be at least this big, so we're * Our final success count will be at least this big, so we're
* guaranteed to succeed. * guaranteed to succeed.
*/ */
if (dnsCheckSuccesses >= mMinDnsResponses) { if (dnsCheckSuccesses[dnsServerId] >= mMinDnsResponses) {
// DNS CHECKS OK, NOW WALLED GARDEN // DNS CHECKS OK, NOW WALLED GARDEN
if (DBG) { if (DBG) {
Slog.d(WWSM_TAG, dnsCheckLogStr + "| SUCCESS"); Slog.d(WWSM_TAG, makeLogString() + " SUCCESS");
} }
if (!shouldCheckWalledGarden()) { if (!shouldCheckWalledGarden()) {
@@ -748,14 +753,9 @@ public class WifiWatchdogStateMachine extends StateMachine {
return HANDLED; return HANDLED;
} }
/** if (idDnsMap.isEmpty()) {
* Our final count will be at most the current count plus the
* remaining pings - we're guaranteed to fail.
*/
int remainingChecks = mNumDnsPings - dnsCheckTries;
if (remainingChecks + dnsCheckSuccesses < mMinDnsResponses) {
if (DBG) { if (DBG) {
Slog.d(WWSM_TAG, dnsCheckLogStr + "| FAILURE"); Slog.d(WWSM_TAG, makeLogString() + " FAILURE");
} }
transitionTo(mDnsCheckFailureState); transitionTo(mDnsCheckFailureState);
return HANDLED; return HANDLED;
@@ -764,12 +764,18 @@ public class WifiWatchdogStateMachine extends StateMachine {
return HANDLED; return HANDLED;
} }
private String makeLogString() {
String logStr = dnsCheckLogStr;
for (String respStr : dnsResponseStrs)
logStr += " [" + respStr + "]";
return logStr;
}
@Override @Override
public void exit() { public void exit() {
mDnsPinger.cancelPings(); mDnsPinger.cancelPings();
} }
private boolean shouldCheckWalledGarden() { private boolean shouldCheckWalledGarden() {
if (!mWalledGardenTestEnabled) { if (!mWalledGardenTestEnabled) {
if (VDBG) if (VDBG)
@@ -809,7 +815,8 @@ public class WifiWatchdogStateMachine extends StateMachine {
int checkGuard = 0; int checkGuard = 0;
Long lastCheckTime = null; Long lastCheckTime = null;
int curPingID = 0; /** Keeps track of dns pings. Map is from pingID to InetAddress used for ping */
HashMap<Integer, InetAddress> pingInfoMap = new HashMap<Integer, InetAddress>();
@Override @Override
public void enter() { public void enter() {
@@ -817,7 +824,7 @@ public class WifiWatchdogStateMachine extends StateMachine {
signalUnstable = false; signalUnstable = false;
checkGuard++; checkGuard++;
unstableSignalChecks = false; unstableSignalChecks = false;
curPingID = 0; pingInfoMap.clear();
triggerSingleDnsCheck(); triggerSingleDnsCheck();
} }
@@ -853,32 +860,37 @@ public class WifiWatchdogStateMachine extends StateMachine {
return HANDLED; return HANDLED;
} }
lastCheckTime = SystemClock.elapsedRealtime(); lastCheckTime = SystemClock.elapsedRealtime();
curPingID = mDnsPinger.pingDnsAsync(mDnsPinger.getDns(), pingInfoMap.clear();
mDnsPingTimeoutMs, 0); for (InetAddress curDns: mDnsPinger.getDnsList()) {
pingInfoMap.put(mDnsPinger.pingDnsAsync(curDns, mDnsPingTimeoutMs, 0),
curDns);
}
return HANDLED; return HANDLED;
case DnsPinger.DNS_PING_RESULT: case DnsPinger.DNS_PING_RESULT:
if ((short) msg.arg1 != curPingID) { InetAddress curDnsServer = pingInfoMap.get(msg.arg1);
if (VDBG) { if (curDnsServer == null) {
Slog.v(WWSM_TAG, "Received non-matching DnsPing w/ id: " +
msg.arg1);
}
return HANDLED; return HANDLED;
} }
pingInfoMap.remove(msg.arg1);
int responseTime = msg.arg2; int responseTime = msg.arg2;
if (responseTime >= 0) { if (responseTime >= 0) {
if (VDBG) { if (VDBG) {
Slog.v(WWSM_TAG, "Ran a single DNS ping. Response time: " Slog.v(WWSM_TAG, "Single DNS ping OK. Response time: "
+ responseTime); + responseTime + " from DNS " + curDnsServer);
} }
pingInfoMap.clear();
checkGuard++; checkGuard++;
unstableSignalChecks = false; unstableSignalChecks = false;
triggerSingleDnsCheck(); triggerSingleDnsCheck();
} else { } else {
if (DBG) { if (pingInfoMap.isEmpty()) {
Slog.d(WWSM_TAG, "Single dns ping failure. Starting full checks."); if (DBG) {
Slog.d(WWSM_TAG, "Single dns ping failure. All dns servers failed, "
+ "starting full checks.");
}
transitionTo(mDnsCheckingState);
} }
transitionTo(mDnsCheckingState);
} }
return HANDLED; return HANDLED;
} }