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.testutils.DevSdkIgnoreRule; 31 import com.android.testutils.DevSdkIgnoreRunner; 32 33 import org.junit.After; 34 import org.junit.Before; 35 import org.junit.Test; 36 import org.junit.runner.RunWith; 37 38 import java.net.InetAddress; 39 import java.nio.ByteBuffer; 40 41 @RunWith(DevSdkIgnoreRunner.class) 42 @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R) 43 public final class KeepalivePacketDataUtilTest { 44 private static final byte[] IPV4_KEEPALIVE_SRC_ADDR = {10, 0, 0, 1}; 45 private static final byte[] IPV4_KEEPALIVE_DST_ADDR = {10, 0, 0, 5}; 46 47 private Log.TerribleFailureHandler mOriginalHandler; 48 49 @Before setUp()50 public void setUp() { 51 // Terrible failures are logged when using deprecated methods on newer platforms 52 mOriginalHandler = Log.setWtfHandler((tag, what, sys) -> 53 Log.e(tag, "Terrible failure in test", what)); 54 } 55 56 @After tearDown()57 public void tearDown() { 58 Log.setWtfHandler(mOriginalHandler); 59 } 60 61 @Test testFromTcpKeepaliveStableParcelable()62 public void testFromTcpKeepaliveStableParcelable() throws Exception { 63 final int srcPort = 1234; 64 final int dstPort = 4321; 65 final int seq = 0x11111111; 66 final int ack = 0x22222222; 67 final int wnd = 8000; 68 final int wndScale = 2; 69 final int tos = 4; 70 final int ttl = 64; 71 TcpKeepalivePacketData resultData = null; 72 final TcpKeepalivePacketDataParcelable testInfo = new TcpKeepalivePacketDataParcelable(); 73 testInfo.srcAddress = IPV4_KEEPALIVE_SRC_ADDR; 74 testInfo.srcPort = srcPort; 75 testInfo.dstAddress = IPV4_KEEPALIVE_DST_ADDR; 76 testInfo.dstPort = dstPort; 77 testInfo.seq = seq; 78 testInfo.ack = ack; 79 testInfo.rcvWnd = wnd; 80 testInfo.rcvWndScale = wndScale; 81 testInfo.tos = tos; 82 testInfo.ttl = ttl; 83 try { 84 resultData = KeepalivePacketDataUtil.fromStableParcelable(testInfo); 85 } catch (InvalidPacketException e) { 86 fail("InvalidPacketException: " + e); 87 } 88 89 assertEquals(InetAddress.getByAddress(testInfo.srcAddress), resultData.getSrcAddress()); 90 assertEquals(InetAddress.getByAddress(testInfo.dstAddress), resultData.getDstAddress()); 91 assertEquals(testInfo.srcPort, resultData.getSrcPort()); 92 assertEquals(testInfo.dstPort, resultData.getDstPort()); 93 assertEquals(testInfo.seq, resultData.tcpSeq); 94 assertEquals(testInfo.ack, resultData.tcpAck); 95 assertEquals(testInfo.rcvWnd, resultData.tcpWindow); 96 assertEquals(testInfo.rcvWndScale, resultData.tcpWindowScale); 97 assertEquals(testInfo.tos, resultData.ipTos); 98 assertEquals(testInfo.ttl, resultData.ipTtl); 99 100 assertParcelingIsLossless(resultData); 101 102 final byte[] packet = resultData.getPacket(); 103 // IP version and IHL 104 assertEquals(packet[0], 0x45); 105 // TOS 106 assertEquals(packet[1], tos); 107 // TTL 108 assertEquals(packet[8], ttl); 109 // Source IP address. 110 byte[] ip = new byte[4]; 111 ByteBuffer buf = ByteBuffer.wrap(packet, 12, 4); 112 buf.get(ip); 113 assertArrayEquals(ip, IPV4_KEEPALIVE_SRC_ADDR); 114 // Destination IP address. 115 buf = ByteBuffer.wrap(packet, 16, 4); 116 buf.get(ip); 117 assertArrayEquals(ip, IPV4_KEEPALIVE_DST_ADDR); 118 119 buf = ByteBuffer.wrap(packet, 20, 12); 120 // Source port. 121 assertEquals(buf.getShort(), srcPort); 122 // Destination port. 123 assertEquals(buf.getShort(), dstPort); 124 // Sequence number. 125 assertEquals(buf.getInt(), seq); 126 // Ack. 127 assertEquals(buf.getInt(), ack); 128 // Window size. 129 buf = ByteBuffer.wrap(packet, 34, 2); 130 assertEquals(buf.getShort(), wnd >> wndScale); 131 } 132 133 //TODO: add ipv6 test when ipv6 supported 134 135 @Test testToTcpKeepaliveStableParcelable()136 public void testToTcpKeepaliveStableParcelable() throws Exception { 137 final int srcPort = 1234; 138 final int dstPort = 4321; 139 final int sequence = 0x11111111; 140 final int ack = 0x22222222; 141 final int wnd = 48_000; 142 final int wndScale = 2; 143 final int tos = 4; 144 final int ttl = 64; 145 final TcpKeepalivePacketDataParcelable testInfo = new TcpKeepalivePacketDataParcelable(); 146 testInfo.srcAddress = IPV4_KEEPALIVE_SRC_ADDR; 147 testInfo.srcPort = srcPort; 148 testInfo.dstAddress = IPV4_KEEPALIVE_DST_ADDR; 149 testInfo.dstPort = dstPort; 150 testInfo.seq = sequence; 151 testInfo.ack = ack; 152 testInfo.rcvWnd = wnd; 153 testInfo.rcvWndScale = wndScale; 154 testInfo.tos = tos; 155 testInfo.ttl = ttl; 156 TcpKeepalivePacketData testData = null; 157 TcpKeepalivePacketDataParcelable resultData = null; 158 testData = KeepalivePacketDataUtil.fromStableParcelable(testInfo); 159 resultData = KeepalivePacketDataUtil.toStableParcelable(testData); 160 assertArrayEquals(resultData.srcAddress, IPV4_KEEPALIVE_SRC_ADDR); 161 assertArrayEquals(resultData.dstAddress, IPV4_KEEPALIVE_DST_ADDR); 162 assertEquals(resultData.srcPort, srcPort); 163 assertEquals(resultData.dstPort, dstPort); 164 assertEquals(resultData.seq, sequence); 165 assertEquals(resultData.ack, ack); 166 assertEquals(resultData.rcvWnd, wnd); 167 assertEquals(resultData.rcvWndScale, wndScale); 168 assertEquals(resultData.tos, tos); 169 assertEquals(resultData.ttl, ttl); 170 171 final String expected = "" 172 + "android.net.TcpKeepalivePacketDataParcelable{srcAddress: [10, 0, 0, 1]," 173 + " srcPort: 1234, dstAddress: [10, 0, 0, 5], dstPort: 4321, seq: 286331153," 174 + " ack: 572662306, rcvWnd: 48000, rcvWndScale: 2, tos: 4, ttl: 64}"; 175 assertEquals(expected, resultData.toString()); 176 } 177 178 @Test testParseTcpKeepalivePacketData()179 public void testParseTcpKeepalivePacketData() throws Exception { 180 final int srcPort = 1234; 181 final int dstPort = 4321; 182 final int sequence = 0x11111111; 183 final int ack = 0x22222222; 184 final int wnd = 4800; 185 final int wndScale = 2; 186 final int tos = 4; 187 final int ttl = 64; 188 final TcpKeepalivePacketDataParcelable testParcel = new TcpKeepalivePacketDataParcelable(); 189 testParcel.srcAddress = IPV4_KEEPALIVE_SRC_ADDR; 190 testParcel.srcPort = srcPort; 191 testParcel.dstAddress = IPV4_KEEPALIVE_DST_ADDR; 192 testParcel.dstPort = dstPort; 193 testParcel.seq = sequence; 194 testParcel.ack = ack; 195 testParcel.rcvWnd = wnd; 196 testParcel.rcvWndScale = wndScale; 197 testParcel.tos = tos; 198 testParcel.ttl = ttl; 199 200 final KeepalivePacketData testData = 201 KeepalivePacketDataUtil.fromStableParcelable(testParcel); 202 final TcpKeepalivePacketDataParcelable parsedParcelable = 203 KeepalivePacketDataUtil.parseTcpKeepalivePacketData(testData); 204 final TcpKeepalivePacketData roundTripData = 205 KeepalivePacketDataUtil.fromStableParcelable(parsedParcelable); 206 207 // Generated packet is the same, but rcvWnd / wndScale will differ if scale is non-zero 208 assertTrue(testData.getPacket().length > 0); 209 assertArrayEquals(testData.getPacket(), roundTripData.getPacket()); 210 211 testParcel.rcvWndScale = 0; 212 final KeepalivePacketData noScaleTestData = 213 KeepalivePacketDataUtil.fromStableParcelable(testParcel); 214 final TcpKeepalivePacketDataParcelable noScaleParsedParcelable = 215 KeepalivePacketDataUtil.parseTcpKeepalivePacketData(noScaleTestData); 216 final TcpKeepalivePacketData noScaleRoundTripData = 217 KeepalivePacketDataUtil.fromStableParcelable(noScaleParsedParcelable); 218 assertEquals(noScaleTestData, noScaleRoundTripData); 219 assertTrue(noScaleTestData.getPacket().length > 0); 220 assertArrayEquals(noScaleTestData.getPacket(), noScaleRoundTripData.getPacket()); 221 } 222 } 223