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

Commit cddc4131 authored by Mark Chien's avatar Mark Chien Committed by android-build-merger
Browse files

Merge "[TCPKeepalive] Fill correct TOS and TTL value" am: 6aef2afd am: 37dd29a1

am: 71f6e5b7

Change-Id: I80c56a14a0be2e6b7996f2bcb9a1a320f0c2c058
parents 4d7990f4 71f6e5b7
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -23,7 +23,10 @@ import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_ERROR;
import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT;
import static android.system.OsConstants.ENOPROTOOPT;
import static android.system.OsConstants.FIONREAD;
import static android.system.OsConstants.IPPROTO_IP;
import static android.system.OsConstants.IPPROTO_TCP;
import static android.system.OsConstants.IP_TOS;
import static android.system.OsConstants.IP_TTL;
import static android.system.OsConstants.TIOCOUTQ;

import android.annotation.NonNull;
@@ -193,6 +196,12 @@ public class TcpKeepaliveController {
            trw = NetworkUtils.getTcpRepairWindow(fd);
            tcpDetails.rcvWnd = trw.rcvWnd;
            tcpDetails.rcvWndScale = trw.rcvWndScale;
            if (tcpDetails.srcAddress.length == 4 /* V4 address length */) {
                // Query TOS.
                tcpDetails.tos = Os.getsockoptInt(fd, IPPROTO_IP, IP_TOS);
                // Query TTL.
                tcpDetails.ttl = Os.getsockoptInt(fd, IPPROTO_IP, IP_TTL);
            }
        } catch (ErrnoException e) {
            Log.e(TAG, "Exception reading TCP state from socket", e);
            if (e.errno == ENOPROTOOPT) {
+29 −10
Original line number Diff line number Diff line
@@ -50,6 +50,12 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
    /** TCP RCV window scale. */
    public final int tcpWndScale;

    /** IP TOS. */
    public final int ipTos;

    /** IP TTL. */
    public final int ipTtl;

    private static final int IPV4_HEADER_LENGTH = 20;
    private static final int IPV6_HEADER_LENGTH = 40;
    private static final int TCP_HEADER_LENGTH = 20;
@@ -65,6 +71,8 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
        // In the packet, the window is shifted right by the window scale.
        tcpWnd = tcpDetails.rcvWnd;
        tcpWndScale = tcpDetails.rcvWndScale;
        ipTos = tcpDetails.tos;
        ipTtl = tcpDetails.ttl;
    }

    /**
@@ -98,12 +106,11 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
        final int length = IPV4_HEADER_LENGTH + TCP_HEADER_LENGTH;
        ByteBuffer buf = ByteBuffer.allocate(length);
        buf.order(ByteOrder.BIG_ENDIAN);
        // IP version and TOS. TODO : fetch this from getsockopt(SOL_IP, IP_TOS)
        buf.putShort((short) 0x4500);
        buf.put((byte) 0x45);                       // IP version and IHL
        buf.put((byte) tcpDetails.tos);             // TOS
        buf.putShort((short) length);
        buf.putInt(0x4000);                         // ID, flags=DF, offset
        // TODO : fetch TTL from getsockopt(SOL_IP, IP_TTL)
        buf.put((byte) 64);
        buf.putInt(0x00004000);                     // ID, flags=DF, offset
        buf.put((byte) tcpDetails.ttl);             // TTL
        buf.put((byte) OsConstants.IPPROTO_TCP);
        final int ipChecksumOffset = buf.position();
        buf.putShort((short) 0);                    // IP checksum
@@ -117,7 +124,9 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
        buf.putShort((short) (tcpDetails.rcvWnd >> tcpDetails.rcvWndScale));   // Window size
        final int tcpChecksumOffset = buf.position();
        buf.putShort((short) 0);                    // TCP checksum
        // URG is not set therefore the urgent pointer is not included
        // URG is not set therefore the urgent pointer is zero.
        buf.putShort((short) 0);                    // Urgent pointer

        buf.putShort(ipChecksumOffset, IpUtils.ipChecksum(buf, 0));
        buf.putShort(tcpChecksumOffset, IpUtils.tcpChecksum(
                buf, 0, IPV4_HEADER_LENGTH, TCP_HEADER_LENGTH));
@@ -138,13 +147,15 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
                && this.tcpAck == other.tcpAck
                && this.tcpSeq == other.tcpSeq
                && this.tcpWnd == other.tcpWnd
                && this.tcpWndScale == other.tcpWndScale;
                && this.tcpWndScale == other.tcpWndScale
                && this.ipTos == other.ipTos
                && this.ipTtl == other.ipTtl;
    }

    @Override
    public int hashCode() {
        return Objects.hash(srcAddress, dstAddress, srcPort, dstPort, tcpAck, tcpSeq, tcpWnd,
                tcpWndScale);
                tcpWndScale, ipTos, ipTtl);
    }

    /**
@@ -164,6 +175,8 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
        out.writeInt(tcpAck);
        out.writeInt(tcpWnd);
        out.writeInt(tcpWndScale);
        out.writeInt(ipTos);
        out.writeInt(ipTtl);
    }

    private TcpKeepalivePacketData(Parcel in) {
@@ -172,6 +185,8 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
        tcpAck = in.readInt();
        tcpWnd = in.readInt();
        tcpWndScale = in.readInt();
        ipTos = in.readInt();
        ipTtl = in.readInt();
    }

    /** Parcelable Creator. */
@@ -200,6 +215,8 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
        parcel.ack = tcpAck;
        parcel.rcvWnd = tcpWnd;
        parcel.rcvWndScale = tcpWndScale;
        parcel.tos = ipTos;
        parcel.ttl = ipTtl;
        return parcel;
    }

@@ -212,6 +229,8 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
                + " seq: " + tcpSeq
                + " ack: " + tcpAck
                + " wnd: " + tcpWnd
                + " wndScale: " + tcpWndScale;
                + " wndScale: " + tcpWndScale
                + " tos: " + ipTos
                + " ttl: " + ipTtl;
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -25,4 +25,6 @@ parcelable TcpKeepalivePacketDataParcelable {
    int ack;
    int rcvWnd;
    int rcvWndScale;
    int tos;
    int ttl;
}
+19 −4
Original line number Diff line number Diff line
@@ -48,6 +48,8 @@ public final class TcpKeepalivePacketDataTest {
        final int ack = 0x22222222;
        final int wnd = 8000;
        final int wndScale = 2;
        final int tos = 4;
        final int ttl = 64;
        TcpKeepalivePacketData resultData = null;
        final TcpKeepalivePacketDataParcelable testInfo = new TcpKeepalivePacketDataParcelable();
        testInfo.srcAddress = IPV4_KEEPALIVE_SRC_ADDR;
@@ -58,6 +60,8 @@ public final class TcpKeepalivePacketDataTest {
        testInfo.ack = ack;
        testInfo.rcvWnd = wnd;
        testInfo.rcvWndScale = wndScale;
        testInfo.tos = tos;
        testInfo.ttl = ttl;
        try {
            resultData = TcpKeepalivePacketData.tcpKeepalivePacket(testInfo);
        } catch (InvalidPacketException e) {
@@ -72,16 +76,21 @@ public final class TcpKeepalivePacketDataTest {
        assertEquals(testInfo.ack, resultData.tcpAck);
        assertEquals(testInfo.rcvWnd, resultData.tcpWnd);
        assertEquals(testInfo.rcvWndScale, resultData.tcpWndScale);
        assertEquals(testInfo.tos, resultData.ipTos);
        assertEquals(testInfo.ttl, resultData.ipTtl);

        TestUtils.assertParcelingIsLossless(resultData, TcpKeepalivePacketData.CREATOR);

        final byte[] packet = resultData.getPacket();
        // IP version and TOS.
        ByteBuffer buf = ByteBuffer.wrap(packet);
        assertEquals(buf.getShort(), 0x4500);
        // IP version and IHL
        assertEquals(packet[0], 0x45);
        // TOS
        assertEquals(packet[1], tos);
        // TTL
        assertEquals(packet[8], ttl);
        // Source IP address.
        byte[] ip = new byte[4];
        buf = ByteBuffer.wrap(packet, 12, 4);
        ByteBuffer buf = ByteBuffer.wrap(packet, 12, 4);
        buf.get(ip);
        assertArrayEquals(ip, IPV4_KEEPALIVE_SRC_ADDR);
        // Destination IP address.
@@ -113,6 +122,8 @@ public final class TcpKeepalivePacketDataTest {
        final int ack = 0x22222222;
        final int wnd = 48_000;
        final int wndScale = 2;
        final int tos = 4;
        final int ttl = 64;
        final TcpKeepalivePacketDataParcelable testInfo = new TcpKeepalivePacketDataParcelable();
        testInfo.srcAddress = IPV4_KEEPALIVE_SRC_ADDR;
        testInfo.srcPort = srcPort;
@@ -122,6 +133,8 @@ public final class TcpKeepalivePacketDataTest {
        testInfo.ack = ack;
        testInfo.rcvWnd = wnd;
        testInfo.rcvWndScale = wndScale;
        testInfo.tos = tos;
        testInfo.ttl = ttl;
        TcpKeepalivePacketData testData = null;
        TcpKeepalivePacketDataParcelable resultData = null;
        testData = TcpKeepalivePacketData.tcpKeepalivePacket(testInfo);
@@ -134,5 +147,7 @@ public final class TcpKeepalivePacketDataTest {
        assertEquals(resultData.ack, ack);
        assertEquals(resultData.rcvWnd, wnd);
        assertEquals(resultData.rcvWndScale, wndScale);
        assertEquals(resultData.tos, tos);
        assertEquals(resultData.ttl, ttl);
    }
}