Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dac4ac4f authored by Remi NGUYEN VAN's avatar Remi NGUYEN VAN
Browse files

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
parent 103ec4aa
Loading
Loading
Loading
Loading
+69 −0
Original line number Diff line number Diff line
@@ -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;
    }
}
+46 −0
Original line number Diff line number Diff line
@@ -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());
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -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