summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRemi NGUYEN VAN <reminv@google.com>2020-11-10 13:11:06 +0900
committerRemi NGUYEN VAN <reminv@google.com>2020-12-14 18:43:53 +0900
commitdac4ac4fdc1b578d28f6482007ac35d7719ff163 (patch)
tree402dd7f050e7a58cbdd2a969eee2a84c7bf4dbc7
parent103ec4aa8d2c9c573840346e18ea9a20a5adc356 (diff)
Use API TcpKeepalivePacketData in ClientModeImpl
Instead of statically linking against and jarjaring TcpKeepalivePacketData, use the new android.net.TcpKeepalivePacketData API for S. On R, build the KeepalivePacketDataParcelable from the base KeepalivePacketData class. The current ClientModeImpl code that uses a statically linked TcpKeepalivePacketData is actually broken, as since R the system_server has been sending a @hide android.net.TcpKeepalivePacketData, and ClientModeImpl was testing it against com.android.wifi.x.android.net.*. To fix this on R, this change rebuilds a TcpKeepalivePacketDataParcelable class from the packet data included in the base KeepalivePacketData class. Bug: 172789687 Test: atest ConnectivityManagerTest#testCreateTcpKeepalive See associated test change Change-Id: Ia32b4444dbf90306b2cfd37ec13d4ba4e90cd1e8
-rw-r--r--services/net/java/android/net/util/KeepalivePacketDataUtil.java69
-rw-r--r--tests/net/java/android/net/KeepalivePacketDataUtilTest.java46
-rw-r--r--wifi/jarjar-rules.txt2
3 files changed, 116 insertions, 1 deletions
diff --git a/services/net/java/android/net/util/KeepalivePacketDataUtil.java b/services/net/java/android/net/util/KeepalivePacketDataUtil.java
index f06070b6870d..6e539bbaf9fe 100644
--- a/services/net/java/android/net/util/KeepalivePacketDataUtil.java
+++ b/services/net/java/android/net/util/KeepalivePacketDataUtil.java
@@ -19,12 +19,16 @@ package android.net.util;
import static android.net.SocketKeepalive.ERROR_INVALID_IP_ADDRESS;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.net.InvalidPacketException;
+import android.net.KeepalivePacketData;
import android.net.NattKeepalivePacketData;
import android.net.NattKeepalivePacketDataParcelable;
import android.net.TcpKeepalivePacketData;
import android.net.TcpKeepalivePacketDataParcelable;
+import android.os.Build;
import android.system.OsConstants;
+import android.util.Log;
import com.android.net.module.util.IpUtils;
@@ -45,6 +49,8 @@ public final class KeepalivePacketDataUtil {
private static final int IPV6_HEADER_LENGTH = 40;
private static final int TCP_HEADER_LENGTH = 20;
+ private static final String TAG = KeepalivePacketDataUtil.class.getSimpleName();
+
/**
* Convert a NattKeepalivePacketData to a NattKeepalivePacketDataParcelable.
*/
@@ -151,4 +157,67 @@ public final class KeepalivePacketDataUtil {
}
// TODO: add buildV6Packet.
+
+ /**
+ * Get a {@link TcpKeepalivePacketDataParcelable} from {@link KeepalivePacketData}, if the
+ * generic class actually contains TCP keepalive data.
+ *
+ * @deprecated This method is used on R platforms where android.net.TcpKeepalivePacketData was
+ * not yet system API. Newer platforms should use android.net.TcpKeepalivePacketData directly.
+ *
+ * @param data A {@link KeepalivePacketData} that may contain TCP keepalive data.
+ * @return A parcelable containing TCP keepalive data, or null if the input data does not
+ * contain TCP keepalive data.
+ */
+ @Deprecated
+ @SuppressWarnings("AndroidFrameworkCompatChange") // API version check used to Log.wtf
+ @Nullable
+ public static TcpKeepalivePacketDataParcelable parseTcpKeepalivePacketData(
+ @Nullable KeepalivePacketData data) {
+ if (data == null) return null;
+
+ if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) {
+ Log.wtf(TAG, "parseTcpKeepalivePacketData should not be used after R, use "
+ + "TcpKeepalivePacketData instead.");
+ }
+
+ // Reconstruct TcpKeepalivePacketData from the packet contained in KeepalivePacketData
+ final ByteBuffer buffer = ByteBuffer.wrap(data.getPacket());
+ buffer.order(ByteOrder.BIG_ENDIAN);
+
+ // Most of the fields are accessible from the KeepalivePacketData superclass: instead of
+ // using Struct to parse everything, just extract the extra fields necessary for
+ // TcpKeepalivePacketData.
+ final int tcpSeq;
+ final int tcpAck;
+ final int wndSize;
+ final int ipTos;
+ final int ttl;
+ try {
+ // This only support IPv4, because TcpKeepalivePacketData only supports IPv4 for R and
+ // below, and this method should not be used on newer platforms.
+ tcpSeq = buffer.getInt(IPV4_HEADER_LENGTH + 4);
+ tcpAck = buffer.getInt(IPV4_HEADER_LENGTH + 8);
+ wndSize = buffer.getShort(IPV4_HEADER_LENGTH + 14);
+ ipTos = buffer.get(1);
+ ttl = buffer.get(8);
+ } catch (IndexOutOfBoundsException e) {
+ return null;
+ }
+
+ final TcpKeepalivePacketDataParcelable p = new TcpKeepalivePacketDataParcelable();
+ p.srcAddress = data.getSrcAddress().getAddress();
+ p.srcPort = data.getSrcPort();
+ p.dstAddress = data.getDstAddress().getAddress();
+ p.dstPort = data.getDstPort();
+ p.seq = tcpSeq;
+ p.ack = tcpAck;
+ // TcpKeepalivePacketData could actually use non-zero wndScale, but this does not affect
+ // actual functionality as generated packets will be the same (no wndScale option added)
+ p.rcvWnd = wndSize;
+ p.rcvWndScale = 0;
+ p.tos = ipTos;
+ p.ttl = ttl;
+ return p;
+ }
}
diff --git a/tests/net/java/android/net/KeepalivePacketDataUtilTest.java b/tests/net/java/android/net/KeepalivePacketDataUtilTest.java
index 9ae3595adbdb..fc739fbfac61 100644
--- a/tests/net/java/android/net/KeepalivePacketDataUtilTest.java
+++ b/tests/net/java/android/net/KeepalivePacketDataUtilTest.java
@@ -20,6 +20,7 @@ import static com.android.testutils.ParcelUtils.assertParcelingIsLossless;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import android.net.util.KeepalivePacketDataUtil;
@@ -156,4 +157,49 @@ public final class KeepalivePacketDataUtilTest {
+ " ack: 572662306, rcvWnd: 48000, rcvWndScale: 2, tos: 4, ttl: 64}";
assertEquals(expected, resultData.toString());
}
+
+ @Test
+ public void testParseTcpKeepalivePacketData() throws Exception {
+ final int srcPort = 1234;
+ final int dstPort = 4321;
+ final int sequence = 0x11111111;
+ final int ack = 0x22222222;
+ final int wnd = 4800;
+ final int wndScale = 2;
+ final int tos = 4;
+ final int ttl = 64;
+ final TcpKeepalivePacketDataParcelable testParcel = new TcpKeepalivePacketDataParcelable();
+ testParcel.srcAddress = IPV4_KEEPALIVE_SRC_ADDR;
+ testParcel.srcPort = srcPort;
+ testParcel.dstAddress = IPV4_KEEPALIVE_DST_ADDR;
+ testParcel.dstPort = dstPort;
+ testParcel.seq = sequence;
+ testParcel.ack = ack;
+ testParcel.rcvWnd = wnd;
+ testParcel.rcvWndScale = wndScale;
+ testParcel.tos = tos;
+ testParcel.ttl = ttl;
+
+ final KeepalivePacketData testData =
+ KeepalivePacketDataUtil.fromStableParcelable(testParcel);
+ final TcpKeepalivePacketDataParcelable parsedParcelable =
+ KeepalivePacketDataUtil.parseTcpKeepalivePacketData(testData);
+ final TcpKeepalivePacketData roundTripData =
+ KeepalivePacketDataUtil.fromStableParcelable(parsedParcelable);
+
+ // Generated packet is the same, but rcvWnd / wndScale will differ if scale is non-zero
+ assertTrue(testData.getPacket().length > 0);
+ assertArrayEquals(testData.getPacket(), roundTripData.getPacket());
+
+ testParcel.rcvWndScale = 0;
+ final KeepalivePacketData noScaleTestData =
+ KeepalivePacketDataUtil.fromStableParcelable(testParcel);
+ final TcpKeepalivePacketDataParcelable noScaleParsedParcelable =
+ KeepalivePacketDataUtil.parseTcpKeepalivePacketData(noScaleTestData);
+ final TcpKeepalivePacketData noScaleRoundTripData =
+ KeepalivePacketDataUtil.fromStableParcelable(noScaleParsedParcelable);
+ assertEquals(noScaleTestData, noScaleRoundTripData);
+ assertTrue(noScaleTestData.getPacket().length > 0);
+ assertArrayEquals(noScaleTestData.getPacket(), noScaleRoundTripData.getPacket());
+ }
}
diff --git a/wifi/jarjar-rules.txt b/wifi/jarjar-rules.txt
index 75b5e728eb0d..4099c27a0fae 100644
--- a/wifi/jarjar-rules.txt
+++ b/wifi/jarjar-rules.txt
@@ -21,6 +21,7 @@ rule android.net.ProvisioningConfigurationParcelable* com.android.wifi.x.@0
rule android.net.ResolverParamsParcel* com.android.wifi.x.@0
rule android.net.RouteInfoParcel* com.android.wifi.x.@0
rule android.net.ScanResultInfoParcelable* com.android.wifi.x.@0
+rule android.net.TcpKeepalivePacketDataParcelable* com.android.wifi.x.@0
rule android.net.TetherConfigParcel* com.android.wifi.x.@0
rule android.net.TetherOffloadRuleParcel* com.android.wifi.x.@0
rule android.net.TetherStatsParcel* com.android.wifi.x.@0
@@ -43,7 +44,6 @@ rule android.net.DhcpResults* com.android.wifi.x.@0
rule android.net.InterfaceConfiguration* com.android.wifi.x.@0
rule android.net.IpMemoryStore* com.android.wifi.x.@0
rule android.net.NetworkMonitorManager* com.android.wifi.x.@0
-rule android.net.TcpKeepalivePacketData* com.android.wifi.x.@0
rule android.net.NetworkFactory* com.android.wifi.x.@0
rule android.net.ip.IpClientCallbacks* com.android.wifi.x.@0
rule android.net.ip.IpClientManager* com.android.wifi.x.@0