Merge "NetworkDiagnostics: ping default router from all global addreses." into mnc-dr-dev

This commit is contained in:
Lorenzo Colitti
2015-09-15 02:39:20 +00:00
committed by Android (Google) Code Review

View File

@@ -18,6 +18,7 @@ package com.android.server.connectivity;
import static android.system.OsConstants.*; import static android.system.OsConstants.*;
import android.net.LinkAddress;
import android.net.LinkProperties; import android.net.LinkProperties;
import android.net.Network; import android.net.Network;
import android.net.NetworkUtils; import android.net.NetworkUtils;
@@ -27,6 +28,7 @@ import android.system.ErrnoException;
import android.system.Os; import android.system.Os;
import android.system.StructTimeval; import android.system.StructTimeval;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Pair;
import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.IndentingPrintWriter;
@@ -149,6 +151,8 @@ public class NetworkDiagnostics {
} }
private final Map<InetAddress, Measurement> mIcmpChecks = new HashMap<>(); private final Map<InetAddress, Measurement> mIcmpChecks = new HashMap<>();
private final Map<Pair<InetAddress, InetAddress>, Measurement> mExplicitSourceIcmpChecks =
new HashMap<>();
private final Map<InetAddress, Measurement> mDnsUdpChecks = new HashMap<>(); private final Map<InetAddress, Measurement> mDnsUdpChecks = new HashMap<>();
private final String mDescription; private final String mDescription;
@@ -178,7 +182,11 @@ public class NetworkDiagnostics {
for (RouteInfo route : mLinkProperties.getRoutes()) { for (RouteInfo route : mLinkProperties.getRoutes()) {
if (route.hasGateway()) { if (route.hasGateway()) {
prepareIcmpMeasurement(route.getGateway()); InetAddress gateway = route.getGateway();
prepareIcmpMeasurement(gateway);
if (route.isIPv6Default()) {
prepareExplicitSourceIcmpMeasurements(gateway);
}
} }
} }
for (InetAddress nameserver : mLinkProperties.getDnsServers()) { for (InetAddress nameserver : mLinkProperties.getDnsServers()) {
@@ -213,6 +221,20 @@ public class NetworkDiagnostics {
} }
} }
private void prepareExplicitSourceIcmpMeasurements(InetAddress target) {
for (LinkAddress l : mLinkProperties.getLinkAddresses()) {
InetAddress source = l.getAddress();
if (source instanceof Inet6Address && l.isGlobalPreferred()) {
Pair<InetAddress, InetAddress> srcTarget = new Pair<>(source, target);
if (!mExplicitSourceIcmpChecks.containsKey(srcTarget)) {
Measurement measurement = new Measurement();
measurement.thread = new Thread(new IcmpCheck(source, target, measurement));
mExplicitSourceIcmpChecks.put(srcTarget, measurement);
}
}
}
}
private void prepareDnsMeasurement(InetAddress target) { private void prepareDnsMeasurement(InetAddress target) {
if (!mDnsUdpChecks.containsKey(target)) { if (!mDnsUdpChecks.containsKey(target)) {
Measurement measurement = new Measurement(); Measurement measurement = new Measurement();
@@ -222,13 +244,16 @@ public class NetworkDiagnostics {
} }
private int totalMeasurementCount() { private int totalMeasurementCount() {
return mIcmpChecks.size() + mDnsUdpChecks.size(); return mIcmpChecks.size() + mExplicitSourceIcmpChecks.size() + mDnsUdpChecks.size();
} }
private void startMeasurements() { private void startMeasurements() {
for (Measurement measurement : mIcmpChecks.values()) { for (Measurement measurement : mIcmpChecks.values()) {
measurement.thread.start(); measurement.thread.start();
} }
for (Measurement measurement : mExplicitSourceIcmpChecks.values()) {
measurement.thread.start();
}
for (Measurement measurement : mDnsUdpChecks.values()) { for (Measurement measurement : mDnsUdpChecks.values()) {
measurement.thread.start(); measurement.thread.start();
} }
@@ -261,6 +286,10 @@ public class NetworkDiagnostics {
pw.println(entry.getValue().toString()); pw.println(entry.getValue().toString());
} }
} }
for (Map.Entry<Pair<InetAddress, InetAddress>, Measurement> entry :
mExplicitSourceIcmpChecks.entrySet()) {
pw.println(entry.getValue().toString());
}
for (Map.Entry<InetAddress, Measurement> entry : mDnsUdpChecks.entrySet()) { for (Map.Entry<InetAddress, Measurement> entry : mDnsUdpChecks.entrySet()) {
if (entry.getKey() instanceof Inet4Address) { if (entry.getKey() instanceof Inet4Address) {
pw.println(entry.getValue().toString()); pw.println(entry.getValue().toString());
@@ -276,13 +305,15 @@ public class NetworkDiagnostics {
private class SimpleSocketCheck implements Closeable { private class SimpleSocketCheck implements Closeable {
protected final InetAddress mSource; // Usually null.
protected final InetAddress mTarget; protected final InetAddress mTarget;
protected final int mAddressFamily; protected final int mAddressFamily;
protected final Measurement mMeasurement; protected final Measurement mMeasurement;
protected FileDescriptor mFileDescriptor; protected FileDescriptor mFileDescriptor;
protected SocketAddress mSocketAddress; protected SocketAddress mSocketAddress;
protected SimpleSocketCheck(InetAddress target, Measurement measurement) { protected SimpleSocketCheck(
InetAddress source, InetAddress target, Measurement measurement) {
mMeasurement = measurement; mMeasurement = measurement;
if (target instanceof Inet6Address) { if (target instanceof Inet6Address) {
@@ -301,6 +332,14 @@ public class NetworkDiagnostics {
mTarget = target; mTarget = target;
mAddressFamily = AF_INET; mAddressFamily = AF_INET;
} }
// We don't need to check the scope ID here because we currently only do explicit-source
// measurements from global IPv6 addresses.
mSource = source;
}
protected SimpleSocketCheck(InetAddress target, Measurement measurement) {
this(null, target, measurement);
} }
protected void setupSocket( protected void setupSocket(
@@ -314,6 +353,9 @@ public class NetworkDiagnostics {
SOL_SOCKET, SO_RCVTIMEO, StructTimeval.fromMillis(readTimeout)); SOL_SOCKET, SO_RCVTIMEO, StructTimeval.fromMillis(readTimeout));
// TODO: Use IP_RECVERR/IPV6_RECVERR, pending OsContants availability. // TODO: Use IP_RECVERR/IPV6_RECVERR, pending OsContants availability.
mNetwork.bindSocket(mFileDescriptor); mNetwork.bindSocket(mFileDescriptor);
if (mSource != null) {
Os.bind(mFileDescriptor, mSource, 0);
}
Os.connect(mFileDescriptor, mTarget, dstPort); Os.connect(mFileDescriptor, mTarget, dstPort);
mSocketAddress = Os.getsockname(mFileDescriptor); mSocketAddress = Os.getsockname(mFileDescriptor);
} }
@@ -343,8 +385,8 @@ public class NetworkDiagnostics {
private final int mProtocol; private final int mProtocol;
private final int mIcmpType; private final int mIcmpType;
public IcmpCheck(InetAddress target, Measurement measurement) { public IcmpCheck(InetAddress source, InetAddress target, Measurement measurement) {
super(target, measurement); super(source, target, measurement);
if (mAddressFamily == AF_INET6) { if (mAddressFamily == AF_INET6) {
mProtocol = IPPROTO_ICMPV6; mProtocol = IPPROTO_ICMPV6;
@@ -359,6 +401,10 @@ public class NetworkDiagnostics {
mMeasurement.description += " dst{" + mTarget.getHostAddress() + "}"; mMeasurement.description += " dst{" + mTarget.getHostAddress() + "}";
} }
public IcmpCheck(InetAddress target, Measurement measurement) {
this(null, target, measurement);
}
@Override @Override
public void run() { public void run() {
// Check if this measurement has already failed during setup. // Check if this measurement has already failed during setup.