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

Commit a34aa2ac authored by Mark Chien's avatar Mark Chien Committed by Gerrit Code Review
Browse files

Merge "Replace TcpSocketInfo with similar structure"

parents b9879d00 d42fca67
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -23,4 +23,6 @@ parcelable TcpKeepalivePacketDataParcelable {
    int dstPort;
    int dstPort;
    int seq;
    int seq;
    int ack;
    int ack;
    int rcvWnd;
    int rcvWndScale;
}
}
+18 −23
Original line number Original line Diff line number Diff line
@@ -31,7 +31,7 @@ import android.net.NetworkUtils;
import android.net.SocketKeepalive.InvalidPacketException;
import android.net.SocketKeepalive.InvalidPacketException;
import android.net.SocketKeepalive.InvalidSocketException;
import android.net.SocketKeepalive.InvalidSocketException;
import android.net.TcpKeepalivePacketData;
import android.net.TcpKeepalivePacketData;
import android.net.TcpKeepalivePacketData.TcpSocketInfo;
import android.net.TcpKeepalivePacketDataParcelable;
import android.net.TcpRepairWindow;
import android.net.TcpRepairWindow;
import android.os.Handler;
import android.os.Handler;
import android.os.MessageQueue;
import android.os.MessageQueue;
@@ -46,7 +46,6 @@ import com.android.internal.annotations.GuardedBy;
import com.android.server.connectivity.KeepaliveTracker.KeepaliveInfo;
import com.android.server.connectivity.KeepaliveTracker.KeepaliveInfo;


import java.io.FileDescriptor;
import java.io.FileDescriptor;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.SocketException;
@@ -109,8 +108,8 @@ public class TcpKeepaliveController {
    public static TcpKeepalivePacketData getTcpKeepalivePacket(@NonNull FileDescriptor fd)
    public static TcpKeepalivePacketData getTcpKeepalivePacket(@NonNull FileDescriptor fd)
            throws InvalidPacketException, InvalidSocketException {
            throws InvalidPacketException, InvalidSocketException {
        try {
        try {
            final TcpSocketInfo tsi = switchToRepairMode(fd);
            final TcpKeepalivePacketDataParcelable tcpDetails = switchToRepairMode(fd);
            return TcpKeepalivePacketData.tcpKeepalivePacket(tsi);
            return TcpKeepalivePacketData.tcpKeepalivePacket(tcpDetails);
        } catch (InvalidPacketException | InvalidSocketException e) {
        } catch (InvalidPacketException | InvalidSocketException e) {
            switchOutOfRepairMode(fd);
            switchOutOfRepairMode(fd);
            throw e;
            throw e;
@@ -120,20 +119,15 @@ public class TcpKeepaliveController {
     * Switch the tcp socket to repair mode and query detail tcp information.
     * Switch the tcp socket to repair mode and query detail tcp information.
     *
     *
     * @param fd the fd of socket on which to use keepalive offload.
     * @param fd the fd of socket on which to use keepalive offload.
     * @return a {@link TcpKeepalivePacketData#TcpSocketInfo} object for current
     * @return a {@link TcpKeepalivePacketData#TcpKeepalivePacketDataParcelable} object for current
     * tcp/ip information.
     * tcp/ip information.
     */
     */
    private static TcpSocketInfo switchToRepairMode(FileDescriptor fd)
    private static TcpKeepalivePacketDataParcelable switchToRepairMode(FileDescriptor fd)
            throws InvalidSocketException {
            throws InvalidSocketException {
        if (DBG) Log.i(TAG, "switchToRepairMode to start tcp keepalive : " + fd);
        if (DBG) Log.i(TAG, "switchToRepairMode to start tcp keepalive : " + fd);
        final TcpKeepalivePacketDataParcelable tcpDetails = new TcpKeepalivePacketDataParcelable();
        final SocketAddress srcSockAddr;
        final SocketAddress srcSockAddr;
        final SocketAddress dstSockAddr;
        final SocketAddress dstSockAddr;
        final InetAddress srcAddress;
        final InetAddress dstAddress;
        final int srcPort;
        final int dstPort;
        int seq;
        final int ack;
        final TcpRepairWindow trw;
        final TcpRepairWindow trw;


        // Query source address and port.
        // Query source address and port.
@@ -144,8 +138,8 @@ public class TcpKeepaliveController {
            throw new InvalidSocketException(ERROR_INVALID_SOCKET, e);
            throw new InvalidSocketException(ERROR_INVALID_SOCKET, e);
        }
        }
        if (srcSockAddr instanceof InetSocketAddress) {
        if (srcSockAddr instanceof InetSocketAddress) {
            srcAddress = getAddress((InetSocketAddress) srcSockAddr);
            tcpDetails.srcAddress = getAddress((InetSocketAddress) srcSockAddr);
            srcPort = getPort((InetSocketAddress) srcSockAddr);
            tcpDetails.srcPort = getPort((InetSocketAddress) srcSockAddr);
        } else {
        } else {
            Log.e(TAG, "Invalid or mismatched SocketAddress");
            Log.e(TAG, "Invalid or mismatched SocketAddress");
            throw new InvalidSocketException(ERROR_INVALID_SOCKET);
            throw new InvalidSocketException(ERROR_INVALID_SOCKET);
@@ -158,8 +152,8 @@ public class TcpKeepaliveController {
            throw new InvalidSocketException(ERROR_INVALID_SOCKET, e);
            throw new InvalidSocketException(ERROR_INVALID_SOCKET, e);
        }
        }
        if (dstSockAddr instanceof InetSocketAddress) {
        if (dstSockAddr instanceof InetSocketAddress) {
            dstAddress = getAddress((InetSocketAddress) dstSockAddr);
            tcpDetails.dstAddress = getAddress((InetSocketAddress) dstSockAddr);
            dstPort = getPort((InetSocketAddress) dstSockAddr);
            tcpDetails.dstPort = getPort((InetSocketAddress) dstSockAddr);
        } else {
        } else {
            Log.e(TAG, "Invalid or mismatched peer SocketAddress");
            Log.e(TAG, "Invalid or mismatched peer SocketAddress");
            throw new InvalidSocketException(ERROR_INVALID_SOCKET);
            throw new InvalidSocketException(ERROR_INVALID_SOCKET);
@@ -178,10 +172,10 @@ public class TcpKeepaliveController {
            }
            }
            // Query write sequence number from SEND_QUEUE.
            // Query write sequence number from SEND_QUEUE.
            Os.setsockoptInt(fd, IPPROTO_TCP, TCP_REPAIR_QUEUE, TCP_SEND_QUEUE);
            Os.setsockoptInt(fd, IPPROTO_TCP, TCP_REPAIR_QUEUE, TCP_SEND_QUEUE);
            seq = Os.getsockoptInt(fd, IPPROTO_TCP, TCP_QUEUE_SEQ);
            tcpDetails.seq = Os.getsockoptInt(fd, IPPROTO_TCP, TCP_QUEUE_SEQ);
            // Query read sequence number from RECV_QUEUE.
            // Query read sequence number from RECV_QUEUE.
            Os.setsockoptInt(fd, IPPROTO_TCP, TCP_REPAIR_QUEUE, TCP_RECV_QUEUE);
            Os.setsockoptInt(fd, IPPROTO_TCP, TCP_REPAIR_QUEUE, TCP_RECV_QUEUE);
            ack = Os.getsockoptInt(fd, IPPROTO_TCP, TCP_QUEUE_SEQ);
            tcpDetails.ack = Os.getsockoptInt(fd, IPPROTO_TCP, TCP_QUEUE_SEQ);
            // Switch to NO_QUEUE to prevent illegal socket read/write in repair mode.
            // Switch to NO_QUEUE to prevent illegal socket read/write in repair mode.
            Os.setsockoptInt(fd, IPPROTO_TCP, TCP_REPAIR_QUEUE, TCP_NO_QUEUE);
            Os.setsockoptInt(fd, IPPROTO_TCP, TCP_REPAIR_QUEUE, TCP_NO_QUEUE);
            // Finally, check if socket is still idle. TODO : this check needs to move to
            // Finally, check if socket is still idle. TODO : this check needs to move to
@@ -197,6 +191,8 @@ public class TcpKeepaliveController {


            // Query tcp window size.
            // Query tcp window size.
            trw = NetworkUtils.getTcpRepairWindow(fd);
            trw = NetworkUtils.getTcpRepairWindow(fd);
            tcpDetails.rcvWnd = trw.rcvWnd;
            tcpDetails.rcvWndScale = trw.rcvWndScale;
        } catch (ErrnoException e) {
        } catch (ErrnoException e) {
            Log.e(TAG, "Exception reading TCP state from socket", e);
            Log.e(TAG, "Exception reading TCP state from socket", e);
            if (e.errno == ENOPROTOOPT) {
            if (e.errno == ENOPROTOOPT) {
@@ -212,10 +208,9 @@ public class TcpKeepaliveController {


        // Keepalive sequence number is last sequence number - 1. If it couldn't be retrieved,
        // Keepalive sequence number is last sequence number - 1. If it couldn't be retrieved,
        // then it must be set to -1, so decrement in all cases.
        // then it must be set to -1, so decrement in all cases.
        seq = seq - 1;
        tcpDetails.seq = tcpDetails.seq - 1;


        return new TcpSocketInfo(srcAddress, srcPort, dstAddress, dstPort, seq, ack, trw.rcvWnd,
        return tcpDetails;
                trw.rcvWndScale);
    }
    }


    /**
    /**
@@ -287,8 +282,8 @@ public class TcpKeepaliveController {
        switchOutOfRepairMode(fd);
        switchOutOfRepairMode(fd);
    }
    }


    private static InetAddress getAddress(InetSocketAddress inetAddr) {
    private static byte [] getAddress(InetSocketAddress inetAddr) {
        return inetAddr.getAddress();
        return inetAddr.getAddress().getAddress();
    }
    }


    private static int getPort(InetSocketAddress inetAddr) {
    private static int getPort(InetSocketAddress inetAddr) {
+22 −40
Original line number Original line Diff line number Diff line
@@ -25,8 +25,8 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.os.Parcelable;
import android.system.OsConstants;
import android.system.OsConstants;


import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.ByteOrder;
import java.util.Objects;
import java.util.Objects;
@@ -56,10 +56,10 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce


    // This should only be constructed via static factory methods, such as
    // This should only be constructed via static factory methods, such as
    // tcpKeepalivePacket.
    // tcpKeepalivePacket.
    private TcpKeepalivePacketData(TcpSocketInfo tcpDetails, byte[] data)
    private TcpKeepalivePacketData(final TcpKeepalivePacketDataParcelable tcpDetails,
            throws InvalidPacketException {
            final byte[] data) throws InvalidPacketException, UnknownHostException {
        super(tcpDetails.srcAddress, tcpDetails.srcPort, tcpDetails.dstAddress,
        super(InetAddress.getByAddress(tcpDetails.srcAddress), tcpDetails.srcPort,
                tcpDetails.dstPort, data);
                InetAddress.getByAddress(tcpDetails.dstAddress), tcpDetails.dstPort, data);
        tcpSeq = tcpDetails.seq;
        tcpSeq = tcpDetails.seq;
        tcpAck = tcpDetails.ack;
        tcpAck = tcpDetails.ack;
        // In the packet, the window is shifted right by the window scale.
        // In the packet, the window is shifted right by the window scale.
@@ -71,17 +71,22 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
     * Factory method to create tcp keepalive packet structure.
     * Factory method to create tcp keepalive packet structure.
     */
     */
    public static TcpKeepalivePacketData tcpKeepalivePacket(
    public static TcpKeepalivePacketData tcpKeepalivePacket(
            TcpSocketInfo tcpDetails) throws InvalidPacketException {
            TcpKeepalivePacketDataParcelable tcpDetails) throws InvalidPacketException {
        final byte[] packet;
        final byte[] packet;
        if ((tcpDetails.srcAddress instanceof Inet4Address)
        try {
                && (tcpDetails.dstAddress instanceof Inet4Address)) {
            if ((tcpDetails.srcAddress != null) && (tcpDetails.dstAddress != null)
                    && (tcpDetails.srcAddress.length == 4 /* V4 IP length */)
                    && (tcpDetails.dstAddress.length == 4 /* V4 IP length */)) {
                packet = buildV4Packet(tcpDetails);
                packet = buildV4Packet(tcpDetails);
            } else {
            } else {
                // TODO: support ipv6
                // TODO: support ipv6
                throw new InvalidPacketException(ERROR_INVALID_IP_ADDRESS);
                throw new InvalidPacketException(ERROR_INVALID_IP_ADDRESS);
            }
            }

            return new TcpKeepalivePacketData(tcpDetails, packet);
            return new TcpKeepalivePacketData(tcpDetails, packet);
        } catch (UnknownHostException e) {
            throw new InvalidPacketException(ERROR_INVALID_IP_ADDRESS);
        }

    }
    }


    /**
    /**
@@ -89,7 +94,7 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
     */
     */
    // TODO : if this code is ever moved to the network stack, factorize constants with the ones
    // TODO : if this code is ever moved to the network stack, factorize constants with the ones
    // over there.
    // over there.
    private static byte[] buildV4Packet(TcpSocketInfo tcpDetails) {
    private static byte[] buildV4Packet(TcpKeepalivePacketDataParcelable tcpDetails) {
        final int length = IPV4_HEADER_LENGTH + TCP_HEADER_LENGTH;
        final int length = IPV4_HEADER_LENGTH + TCP_HEADER_LENGTH;
        ByteBuffer buf = ByteBuffer.allocate(length);
        ByteBuffer buf = ByteBuffer.allocate(length);
        buf.order(ByteOrder.BIG_ENDIAN);
        buf.order(ByteOrder.BIG_ENDIAN);
@@ -102,8 +107,8 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
        buf.put((byte) OsConstants.IPPROTO_TCP);
        buf.put((byte) OsConstants.IPPROTO_TCP);
        final int ipChecksumOffset = buf.position();
        final int ipChecksumOffset = buf.position();
        buf.putShort((short) 0);                    // IP checksum
        buf.putShort((short) 0);                    // IP checksum
        buf.put(tcpDetails.srcAddress.getAddress());
        buf.put(tcpDetails.srcAddress);
        buf.put(tcpDetails.dstAddress.getAddress());
        buf.put(tcpDetails.dstAddress);
        buf.putShort((short) tcpDetails.srcPort);
        buf.putShort((short) tcpDetails.srcPort);
        buf.putShort((short) tcpDetails.dstPort);
        buf.putShort((short) tcpDetails.dstPort);
        buf.putInt(tcpDetails.seq);                 // Sequence Number
        buf.putInt(tcpDetails.seq);                 // Sequence Number
@@ -122,31 +127,6 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce


    // TODO: add buildV6Packet.
    // TODO: add buildV6Packet.


    /** Represents tcp/ip information. */
    // TODO: Replace TcpSocketInfo with TcpKeepalivePacketDataParcelable.
    public static class TcpSocketInfo {
        public final InetAddress srcAddress;
        public final InetAddress dstAddress;
        public final int srcPort;
        public final int dstPort;
        public final int seq;
        public final int ack;
        public final int rcvWnd;
        public final int rcvWndScale;

        public TcpSocketInfo(InetAddress sAddr, int sPort, InetAddress dAddr,
                int dPort, int writeSeq, int readSeq, int rWnd, int rWndScale) {
            srcAddress = sAddr;
            dstAddress = dAddr;
            srcPort = sPort;
            dstPort = dPort;
            seq = writeSeq;
            ack = readSeq;
            rcvWnd = rWnd;
            rcvWndScale = rWndScale;
        }
    }

    @Override
    @Override
    public boolean equals(@Nullable final Object o) {
    public boolean equals(@Nullable final Object o) {
        if (!(o instanceof TcpKeepalivePacketData)) return false;
        if (!(o instanceof TcpKeepalivePacketData)) return false;
@@ -218,6 +198,8 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
        parcel.dstPort = dstPort;
        parcel.dstPort = dstPort;
        parcel.seq = tcpSeq;
        parcel.seq = tcpSeq;
        parcel.ack = tcpAck;
        parcel.ack = tcpAck;
        parcel.rcvWnd = tcpWnd;
        parcel.rcvWndScale = tcpWndScale;
        return parcel;
        return parcel;
    }
    }


+30 −18
Original line number Original line Diff line number Diff line
@@ -21,12 +21,9 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.junit.Assert.fail;


import android.net.SocketKeepalive.InvalidPacketException;
import android.net.SocketKeepalive.InvalidPacketException;
import android.net.TcpKeepalivePacketData.TcpSocketInfo;


import com.android.internal.util.TestUtils;
import com.android.internal.util.TestUtils;


import libcore.net.InetAddressUtils;

import org.junit.Before;
import org.junit.Before;
import org.junit.Test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runner.RunWith;
@@ -37,14 +34,14 @@ import java.nio.ByteBuffer;


@RunWith(JUnit4.class)
@RunWith(JUnit4.class)
public final class TcpKeepalivePacketDataTest {
public final class TcpKeepalivePacketDataTest {
    private static final byte[] IPV4_KEEPALIVE_SRC_ADDR = {10, 0, 0, 1};
    private static final byte[] IPV4_KEEPALIVE_DST_ADDR = {10, 0, 0, 5};


    @Before
    @Before
    public void setUp() {}
    public void setUp() {}


    @Test
    @Test
    public void testV4TcpKeepalivePacket() {
    public void testV4TcpKeepalivePacket() throws Exception {
        final InetAddress srcAddr = InetAddressUtils.parseNumericAddress("192.168.0.1");
        final InetAddress dstAddr = InetAddressUtils.parseNumericAddress("192.168.0.10");
        final int srcPort = 1234;
        final int srcPort = 1234;
        final int dstPort = 4321;
        final int dstPort = 4321;
        final int seq = 0x11111111;
        final int seq = 0x11111111;
@@ -52,20 +49,28 @@ public final class TcpKeepalivePacketDataTest {
        final int wnd = 8000;
        final int wnd = 8000;
        final int wndScale = 2;
        final int wndScale = 2;
        TcpKeepalivePacketData resultData = null;
        TcpKeepalivePacketData resultData = null;
        TcpSocketInfo testInfo = new TcpSocketInfo(
        final TcpKeepalivePacketDataParcelable testInfo = new TcpKeepalivePacketDataParcelable();
                srcAddr, srcPort, dstAddr, dstPort, seq, ack, wnd, wndScale);
        testInfo.srcAddress = IPV4_KEEPALIVE_SRC_ADDR;
        testInfo.srcPort = srcPort;
        testInfo.dstAddress = IPV4_KEEPALIVE_DST_ADDR;
        testInfo.dstPort = dstPort;
        testInfo.seq = seq;
        testInfo.ack = ack;
        testInfo.rcvWnd = wnd;
        testInfo.rcvWndScale = wndScale;
        try {
        try {
            resultData = TcpKeepalivePacketData.tcpKeepalivePacket(testInfo);
            resultData = TcpKeepalivePacketData.tcpKeepalivePacket(testInfo);
        } catch (InvalidPacketException e) {
        } catch (InvalidPacketException e) {
            fail("InvalidPacketException: " + e);
            fail("InvalidPacketException: " + e);
        }
        }


        assertEquals(testInfo.srcAddress, resultData.srcAddress);
        assertEquals(InetAddress.getByAddress(testInfo.srcAddress), resultData.srcAddress);
        assertEquals(testInfo.dstAddress, resultData.dstAddress);
        assertEquals(InetAddress.getByAddress(testInfo.dstAddress), resultData.dstAddress);
        assertEquals(testInfo.srcPort, resultData.srcPort);
        assertEquals(testInfo.srcPort, resultData.srcPort);
        assertEquals(testInfo.dstPort, resultData.dstPort);
        assertEquals(testInfo.dstPort, resultData.dstPort);
        assertEquals(testInfo.seq, resultData.tcpSeq);
        assertEquals(testInfo.seq, resultData.tcpSeq);
        assertEquals(testInfo.ack, resultData.tcpAck);
        assertEquals(testInfo.ack, resultData.tcpAck);
        assertEquals(testInfo.rcvWnd, resultData.tcpWnd);
        assertEquals(testInfo.rcvWndScale, resultData.tcpWndScale);
        assertEquals(testInfo.rcvWndScale, resultData.tcpWndScale);


        TestUtils.assertParcelingIsLossless(resultData, TcpKeepalivePacketData.CREATOR);
        TestUtils.assertParcelingIsLossless(resultData, TcpKeepalivePacketData.CREATOR);
@@ -78,11 +83,11 @@ public final class TcpKeepalivePacketDataTest {
        byte[] ip = new byte[4];
        byte[] ip = new byte[4];
        buf = ByteBuffer.wrap(packet, 12, 4);
        buf = ByteBuffer.wrap(packet, 12, 4);
        buf.get(ip);
        buf.get(ip);
        assertArrayEquals(ip, srcAddr.getAddress());
        assertArrayEquals(ip, IPV4_KEEPALIVE_SRC_ADDR);
        // Destination IP address.
        // Destination IP address.
        buf = ByteBuffer.wrap(packet, 16, 4);
        buf = ByteBuffer.wrap(packet, 16, 4);
        buf.get(ip);
        buf.get(ip);
        assertArrayEquals(ip, dstAddr.getAddress());
        assertArrayEquals(ip, IPV4_KEEPALIVE_DST_ADDR);


        buf = ByteBuffer.wrap(packet, 20, 12);
        buf = ByteBuffer.wrap(packet, 20, 12);
        // Source port.
        // Source port.
@@ -102,25 +107,32 @@ public final class TcpKeepalivePacketDataTest {


    @Test
    @Test
    public void testParcel() throws Exception {
    public void testParcel() throws Exception {
        final InetAddress srcAddr = InetAddresses.parseNumericAddress("192.168.0.1");
        final InetAddress dstAddr = InetAddresses.parseNumericAddress("192.168.0.10");
        final int srcPort = 1234;
        final int srcPort = 1234;
        final int dstPort = 4321;
        final int dstPort = 4321;
        final int sequence = 0x11111111;
        final int sequence = 0x11111111;
        final int ack = 0x22222222;
        final int ack = 0x22222222;
        final int wnd = 48_000;
        final int wnd = 48_000;
        final int wndScale = 2;
        final int wndScale = 2;
        final TcpKeepalivePacketDataParcelable testInfo = new TcpKeepalivePacketDataParcelable();
        testInfo.srcAddress = IPV4_KEEPALIVE_SRC_ADDR;
        testInfo.srcPort = srcPort;
        testInfo.dstAddress = IPV4_KEEPALIVE_DST_ADDR;
        testInfo.dstPort = dstPort;
        testInfo.seq = sequence;
        testInfo.ack = ack;
        testInfo.rcvWnd = wnd;
        testInfo.rcvWndScale = wndScale;
        TcpKeepalivePacketData testData = null;
        TcpKeepalivePacketData testData = null;
        TcpKeepalivePacketDataParcelable resultData = null;
        TcpKeepalivePacketDataParcelable resultData = null;
        TcpSocketInfo testInfo = new TcpSocketInfo(
                srcAddr, srcPort, dstAddr, dstPort, sequence, ack, wnd, wndScale);
        testData = TcpKeepalivePacketData.tcpKeepalivePacket(testInfo);
        testData = TcpKeepalivePacketData.tcpKeepalivePacket(testInfo);
        resultData = testData.toStableParcelable();
        resultData = testData.toStableParcelable();
        assertArrayEquals(resultData.srcAddress, srcAddr.getAddress());
        assertArrayEquals(resultData.srcAddress, IPV4_KEEPALIVE_SRC_ADDR);
        assertArrayEquals(resultData.dstAddress, dstAddr.getAddress());
        assertArrayEquals(resultData.dstAddress, IPV4_KEEPALIVE_DST_ADDR);
        assertEquals(resultData.srcPort, srcPort);
        assertEquals(resultData.srcPort, srcPort);
        assertEquals(resultData.dstPort, dstPort);
        assertEquals(resultData.dstPort, dstPort);
        assertEquals(resultData.seq, sequence);
        assertEquals(resultData.seq, sequence);
        assertEquals(resultData.ack, ack);
        assertEquals(resultData.ack, ack);
        assertEquals(resultData.rcvWnd, wnd);
        assertEquals(resultData.rcvWndScale, wndScale);
    }
    }
}
}