Replace TcpSocketInfo with similar structure

Replace TcpSocketInfo with TcpKeepalivePacketDataParcelable
because their structures are very similar.

bug: 128882321
Test: -build, flash, boot
      -FrameworksNetTests

Change-Id: Iafb4031a64ba4775a495c156e2c997d890c6b261
This commit is contained in:
markchien
2019-03-19 21:25:33 +08:00
parent 7f2cd7d5e7
commit 458c95b9ff
2 changed files with 48 additions and 41 deletions

View File

@@ -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) {

View File

@@ -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);
} }
} }