1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.net; 18 19 import static com.android.testutils.ParcelUtils.assertParcelingIsLossless; 20 21 import static org.junit.Assert.assertArrayEquals; 22 import static org.junit.Assert.assertEquals; 23 import static org.junit.Assert.assertTrue; 24 import static org.junit.Assert.fail; 25 26 import android.net.util.KeepalivePacketDataUtil; 27 import android.os.Build; 28 import android.util.Log; 29 30 import com.android.server.connectivity.TcpKeepaliveController; 31 import com.android.testutils.DevSdkIgnoreRule; 32 import com.android.testutils.DevSdkIgnoreRunner; 33 34 import org.junit.After; 35 import org.junit.Before; 36 import org.junit.Test; 37 import org.junit.runner.RunWith; 38 39 import java.net.InetAddress; 40 import java.nio.ByteBuffer; 41 42 @RunWith(DevSdkIgnoreRunner.class) 43 @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R) 44 public final class KeepalivePacketDataUtilTest { 45 private static final byte[] IPV4_KEEPALIVE_SRC_ADDR = {10, 0, 0, 1}; 46 private static final byte[] IPV4_KEEPALIVE_DST_ADDR = {10, 0, 0, 5}; 47 48 private Log.TerribleFailureHandler mOriginalHandler; 49 50 @Before setUp()51 public void setUp() { 52 // Terrible failures are logged when using deprecated methods on newer platforms 53 mOriginalHandler = Log.setWtfHandler((tag, what, sys) -> 54 Log.e(tag, "Terrible failure in test", what)); 55 } 56 57 @After tearDown()58 public void tearDown() { 59 Log.setWtfHandler(mOriginalHandler); 60 } 61 62 @Test testFromTcpKeepaliveStableParcelable()63 public void testFromTcpKeepaliveStableParcelable() throws Exception { 64 final int srcPort = 1234; 65 final int dstPort = 4321; 66 final int seq = 0x11111111; 67 final int ack = 0x22222222; 68 final int wnd = 8000; 69 final int wndScale = 2; 70 final int tos = 4; 71 final int ttl = 64; 72 TcpKeepalivePacketData resultData = null; 73 final TcpKeepalivePacketDataParcelable testInfo = new TcpKeepalivePacketDataParcelable(); 74 testInfo.srcAddress = IPV4_KEEPALIVE_SRC_ADDR; 75 testInfo.srcPort = srcPort; 76 testInfo.dstAddress = IPV4_KEEPALIVE_DST_ADDR; 77 testInfo.dstPort = dstPort; 78 testInfo.seq = seq; 79 testInfo.ack = ack; 80 testInfo.rcvWnd = wnd; 81 testInfo.rcvWndScale = wndScale; 82 testInfo.tos = tos; 83 testInfo.ttl = ttl; 84 try { 85 resultData = TcpKeepaliveController.fromStableParcelable(testInfo); 86 } catch (InvalidPacketException e) { 87 fail("InvalidPacketException: " + e); 88 } 89 90 assertEquals(InetAddress.getByAddress(testInfo.srcAddress), resultData.getSrcAddress()); 91 assertEquals(InetAddress.getByAddress(testInfo.dstAddress), resultData.getDstAddress()); 92 assertEquals(testInfo.srcPort, resultData.getSrcPort()); 93 assertEquals(testInfo.dstPort, resultData.getDstPort()); 94 assertEquals(testInfo.seq, resultData.tcpSeq); 95 assertEquals(testInfo.ack, resultData.tcpAck); 96 assertEquals(testInfo.rcvWnd, resultData.tcpWindow); 97 assertEquals(testInfo.rcvWndScale, resultData.tcpWindowScale); 98 assertEquals(testInfo.tos, resultData.ipTos); 99 assertEquals(testInfo.ttl, resultData.ipTtl); 100 101 assertParcelingIsLossless(resultData); 102 103 final byte[] packet = resultData.getPacket(); 104 // IP version and IHL 105 assertEquals(packet[0], 0x45); 106 // TOS 107 assertEquals(packet[1], tos); 108 // TTL 109 assertEquals(packet[8], ttl); 110 // Source IP address. 111 byte[] ip = new byte[4]; 112 ByteBuffer buf = ByteBuffer.wrap(packet, 12, 4); 113 buf.get(ip); 114 assertArrayEquals(ip, IPV4_KEEPALIVE_SRC_ADDR); 115 // Destination IP address. 116 buf = ByteBuffer.wrap(packet, 16, 4); 117 buf.get(ip); 118 assertArrayEquals(ip, IPV4_KEEPALIVE_DST_ADDR); 119 120 buf = ByteBuffer.wrap(packet, 20, 12); 121 // Source port. 122 assertEquals(buf.getShort(), srcPort); 123 // Destination port. 124 assertEquals(buf.getShort(), dstPort); 125 // Sequence number. 126 assertEquals(buf.getInt(), seq); 127 // Ack. 128 assertEquals(buf.getInt(), ack); 129 // Window size. 130 buf = ByteBuffer.wrap(packet, 34, 2); 131 assertEquals(buf.getShort(), wnd >> wndScale); 132 } 133 134 //TODO: add ipv6 test when ipv6 supported 135 136 @Test testToTcpKeepaliveStableParcelable()137 public void testToTcpKeepaliveStableParcelable() throws Exception { 138 final int srcPort = 1234; 139 final int dstPort = 4321; 140 final int sequence = 0x11111111; 141 final int ack = 0x22222222; 142 final int wnd = 48_000; 143 final int wndScale = 2; 144 final int tos = 4; 145 final int ttl = 64; 146 final TcpKeepalivePacketDataParcelable testInfo = new TcpKeepalivePacketDataParcelable(); 147 testInfo.srcAddress = IPV4_KEEPALIVE_SRC_ADDR; 148 testInfo.srcPort = srcPort; 149 testInfo.dstAddress = IPV4_KEEPALIVE_DST_ADDR; 150 testInfo.dstPort = dstPort; 151 testInfo.seq = sequence; 152 testInfo.ack = ack; 153 testInfo.rcvWnd = wnd; 154 testInfo.rcvWndScale = wndScale; 155 testInfo.tos = tos; 156 testInfo.ttl = ttl; 157 TcpKeepalivePacketData testData = null; 158 TcpKeepalivePacketDataParcelable resultData = null; 159 testData = TcpKeepaliveController.fromStableParcelable(testInfo); 160 resultData = KeepalivePacketDataUtil.toStableParcelable(testData); 161 assertArrayEquals(resultData.srcAddress, IPV4_KEEPALIVE_SRC_ADDR); 162 assertArrayEquals(resultData.dstAddress, IPV4_KEEPALIVE_DST_ADDR); 163 assertEquals(resultData.srcPort, srcPort); 164 assertEquals(resultData.dstPort, dstPort); 165 assertEquals(resultData.seq, sequence); 166 assertEquals(resultData.ack, ack); 167 assertEquals(resultData.rcvWnd, wnd); 168 assertEquals(resultData.rcvWndScale, wndScale); 169 assertEquals(resultData.tos, tos); 170 assertEquals(resultData.ttl, ttl); 171 172 final String expected = TcpKeepalivePacketDataParcelable.class.getName() 173 + "{srcAddress: [10, 0, 0, 1]," 174 + " srcPort: 1234, dstAddress: [10, 0, 0, 5], dstPort: 4321, seq: 286331153," 175 + " ack: 572662306, rcvWnd: 48000, rcvWndScale: 2, tos: 4, ttl: 64}"; 176 assertEquals(expected, resultData.toString()); 177 } 178 179 @Test testParseTcpKeepalivePacketData()180 public void testParseTcpKeepalivePacketData() throws Exception { 181 final int srcPort = 1234; 182 final int dstPort = 4321; 183 final int sequence = 0x11111111; 184 final int ack = 0x22222222; 185 final int wnd = 4800; 186 final int wndScale = 2; 187 final int tos = 4; 188 final int ttl = 64; 189 final TcpKeepalivePacketDataParcelable testParcel = new TcpKeepalivePacketDataParcelable(); 190 testParcel.srcAddress = IPV4_KEEPALIVE_SRC_ADDR; 191 testParcel.srcPort = srcPort; 192 testParcel.dstAddress = IPV4_KEEPALIVE_DST_ADDR; 193 testParcel.dstPort = dstPort; 194 testParcel.seq = sequence; 195 testParcel.ack = ack; 196 testParcel.rcvWnd = wnd; 197 testParcel.rcvWndScale = wndScale; 198 testParcel.tos = tos; 199 testParcel.ttl = ttl; 200 201 final KeepalivePacketData testData = 202 TcpKeepaliveController.fromStableParcelable(testParcel); 203 final TcpKeepalivePacketDataParcelable parsedParcelable = 204 KeepalivePacketDataUtil.parseTcpKeepalivePacketData(testData); 205 final TcpKeepalivePacketData roundTripData = 206 TcpKeepaliveController.fromStableParcelable(parsedParcelable); 207 208 // Generated packet is the same, but rcvWnd / wndScale will differ if scale is non-zero 209 assertTrue(testData.getPacket().length > 0); 210 assertArrayEquals(testData.getPacket(), roundTripData.getPacket()); 211 212 testParcel.rcvWndScale = 0; 213 final KeepalivePacketData noScaleTestData = 214 TcpKeepaliveController.fromStableParcelable(testParcel); 215 final TcpKeepalivePacketDataParcelable noScaleParsedParcelable = 216 KeepalivePacketDataUtil.parseTcpKeepalivePacketData(noScaleTestData); 217 final TcpKeepalivePacketData noScaleRoundTripData = 218 TcpKeepaliveController.fromStableParcelable(noScaleParsedParcelable); 219 assertEquals(noScaleTestData, noScaleRoundTripData); 220 assertTrue(noScaleTestData.getPacket().length > 0); 221 assertArrayEquals(noScaleTestData.getPacket(), noScaleRoundTripData.getPacket()); 222 } 223 } 224