Merge "Support ICMP tests with larger packet size" am: 32319e85a2 am: 5b4d1d1764
Original change: https://android-review.googlesource.com/c/platform/packages/modules/Connectivity/+/2567414 Change-Id: I508b29a2e7da2f18284f2d942f60cc19eb64eeba Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
commit
84ffd1c8d4
1 changed files with 59 additions and 12 deletions
|
|
@ -19,6 +19,9 @@ package com.android.server.connectivity;
|
|||
import static android.system.OsConstants.*;
|
||||
|
||||
import static com.android.net.module.util.NetworkStackConstants.ICMP_HEADER_LEN;
|
||||
import static com.android.net.module.util.NetworkStackConstants.IPV4_HEADER_MIN_LEN;
|
||||
import static com.android.net.module.util.NetworkStackConstants.IPV6_HEADER_LEN;
|
||||
import static com.android.net.module.util.NetworkStackConstants.IPV6_MIN_MTU;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
|
|
@ -35,6 +38,7 @@ import android.system.ErrnoException;
|
|||
import android.system.Os;
|
||||
import android.system.StructTimeval;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.android.internal.util.IndentingPrintWriter;
|
||||
|
|
@ -174,7 +178,7 @@ public class NetworkDiagnostics {
|
|||
}
|
||||
}
|
||||
|
||||
private final Map<InetAddress, Measurement> mIcmpChecks = new HashMap<>();
|
||||
private final Map<Pair<InetAddress, Integer>, Measurement> mIcmpChecks = new HashMap<>();
|
||||
private final Map<Pair<InetAddress, InetAddress>, Measurement> mExplicitSourceIcmpChecks =
|
||||
new HashMap<>();
|
||||
private final Map<InetAddress, Measurement> mDnsUdpChecks = new HashMap<>();
|
||||
|
|
@ -207,17 +211,21 @@ public class NetworkDiagnostics {
|
|||
mLinkProperties.addDnsServer(TEST_DNS6);
|
||||
}
|
||||
|
||||
final int mtu = mLinkProperties.getMtu();
|
||||
for (RouteInfo route : mLinkProperties.getRoutes()) {
|
||||
if (route.getType() == RouteInfo.RTN_UNICAST && route.hasGateway()) {
|
||||
InetAddress gateway = route.getGateway();
|
||||
prepareIcmpMeasurement(gateway);
|
||||
// Use mtu in the route if exists. Otherwise, use the one in the link property.
|
||||
final int routeMtu = route.getMtu();
|
||||
prepareIcmpMeasurements(gateway, (routeMtu > 0) ? routeMtu : mtu);
|
||||
if (route.isIPv6Default()) {
|
||||
prepareExplicitSourceIcmpMeasurements(gateway);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (InetAddress nameserver : mLinkProperties.getDnsServers()) {
|
||||
prepareIcmpMeasurement(nameserver);
|
||||
prepareIcmpMeasurements(nameserver, mtu);
|
||||
prepareDnsMeasurement(nameserver);
|
||||
|
||||
// Unlike the DnsResolver which doesn't do certificate validation in opportunistic mode,
|
||||
|
|
@ -263,11 +271,50 @@ public class NetworkDiagnostics {
|
|||
localAddr.getHostAddress(), inetSockAddr.getPort());
|
||||
}
|
||||
|
||||
private void prepareIcmpMeasurement(InetAddress target) {
|
||||
if (!mIcmpChecks.containsKey(target)) {
|
||||
Measurement measurement = new Measurement();
|
||||
measurement.thread = new Thread(new IcmpCheck(target, 0, measurement));
|
||||
mIcmpChecks.put(target, measurement);
|
||||
private static int getHeaderLen(@NonNull InetAddress target) {
|
||||
// Convert IPv4 mapped v6 address to v4 if any.
|
||||
try {
|
||||
final InetAddress addr = InetAddress.getByAddress(target.getAddress());
|
||||
// An ICMPv6 header is technically 4 bytes, but the implementation in IcmpCheck#run()
|
||||
// will always fill in another 4 bytes padding in the v6 diagnostic packets, so the size
|
||||
// before icmp data is always 8 bytes in the implementation of ICMP diagnostics for both
|
||||
// v4 and v6 packets. Thus, it's fine to use the v4 header size in the length
|
||||
// calculation.
|
||||
if (addr instanceof Inet6Address) {
|
||||
return IPV6_HEADER_LEN + ICMP_HEADER_LEN;
|
||||
}
|
||||
} catch (UnknownHostException e) {
|
||||
Log.e(TAG, "Create InetAddress fail(" + target + "): " + e);
|
||||
}
|
||||
|
||||
return IPV4_HEADER_MIN_LEN + ICMP_HEADER_LEN;
|
||||
}
|
||||
|
||||
private void prepareIcmpMeasurements(@NonNull InetAddress target, int targetNetworkMtu) {
|
||||
// Test with different size payload ICMP.
|
||||
// 1. Test with 0 payload.
|
||||
addPayloadIcmpMeasurement(target, 0);
|
||||
final int header = getHeaderLen(target);
|
||||
// 2. Test with full size MTU.
|
||||
addPayloadIcmpMeasurement(target, targetNetworkMtu - header);
|
||||
// 3. If v6, make another measurement with the full v6 min MTU, unless that's what
|
||||
// was done above.
|
||||
if ((target instanceof Inet6Address) && (targetNetworkMtu != IPV6_MIN_MTU)) {
|
||||
addPayloadIcmpMeasurement(target, IPV6_MIN_MTU - header);
|
||||
}
|
||||
}
|
||||
|
||||
private void addPayloadIcmpMeasurement(@NonNull InetAddress target, int payloadLen) {
|
||||
// This can happen if the there is no mtu filled(which is 0) in the link property.
|
||||
// The value becomes negative after minus header length.
|
||||
if (payloadLen < 0) return;
|
||||
|
||||
final Pair<InetAddress, Integer> lenTarget =
|
||||
new Pair<>(target, Integer.valueOf(payloadLen));
|
||||
if (!mIcmpChecks.containsKey(lenTarget)) {
|
||||
final Measurement measurement = new Measurement();
|
||||
measurement.thread = new Thread(new IcmpCheck(target, payloadLen, measurement));
|
||||
mIcmpChecks.put(lenTarget, measurement);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -336,8 +383,8 @@ public class NetworkDiagnostics {
|
|||
ArrayList<Measurement> measurements = new ArrayList(totalMeasurementCount());
|
||||
|
||||
// Sort measurements IPv4 first.
|
||||
for (Map.Entry<InetAddress, Measurement> entry : mIcmpChecks.entrySet()) {
|
||||
if (entry.getKey() instanceof Inet4Address) {
|
||||
for (Map.Entry<Pair<InetAddress, Integer>, Measurement> entry : mIcmpChecks.entrySet()) {
|
||||
if (entry.getKey().first instanceof Inet4Address) {
|
||||
measurements.add(entry.getValue());
|
||||
}
|
||||
}
|
||||
|
|
@ -359,8 +406,8 @@ public class NetworkDiagnostics {
|
|||
}
|
||||
|
||||
// IPv6 measurements second.
|
||||
for (Map.Entry<InetAddress, Measurement> entry : mIcmpChecks.entrySet()) {
|
||||
if (entry.getKey() instanceof Inet6Address) {
|
||||
for (Map.Entry<Pair<InetAddress, Integer>, Measurement> entry : mIcmpChecks.entrySet()) {
|
||||
if (entry.getKey().first instanceof Inet6Address) {
|
||||
measurements.add(entry.getValue());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue