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 android.net.InvalidPacketException.ERROR_INVALID_IP_ADDRESS 20 import android.net.InvalidPacketException.ERROR_INVALID_PORT 21 import android.net.NattSocketKeepalive.NATT_PORT 22 import android.os.Build 23 import androidx.test.filters.SmallTest 24 import androidx.test.runner.AndroidJUnit4 25 import com.android.testutils.ConnectivityModuleTest 26 import com.android.testutils.DevSdkIgnoreRule 27 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo 28 import com.android.testutils.assertEqualBothWays 29 import com.android.testutils.assertParcelingIsLossless 30 import com.android.testutils.parcelingRoundTrip 31 import java.net.Inet6Address 32 import java.net.InetAddress 33 import kotlin.test.assertFailsWith 34 import org.junit.Assert.assertEquals 35 import org.junit.Assert.assertNotEquals 36 import org.junit.Rule 37 import org.junit.Test 38 import org.junit.runner.RunWith 39 40 @RunWith(AndroidJUnit4::class) 41 @SmallTest 42 class NattKeepalivePacketDataTest { 43 @Rule @JvmField 44 val ignoreRule: DevSdkIgnoreRule = DevSdkIgnoreRule() 45 46 private val TEST_PORT = 4243 47 private val TEST_PORT2 = 4244 48 // ::FFFF:1.2.3.4 49 private val SRC_V4_MAPPED_V6_ADDRESS_BYTES = byteArrayOf( 50 0x00.toByte(), 51 0x00.toByte(), 52 0x00.toByte(), 53 0x00.toByte(), 54 0x00.toByte(), 55 0x00.toByte(), 56 0x00.toByte(), 57 0x00.toByte(), 58 0x00.toByte(), 59 0x00.toByte(), 60 0xff.toByte(), 61 0xff.toByte(), 62 0x01.toByte(), 63 0x02.toByte(), 64 0x03.toByte(), 65 0x04.toByte() 66 ) 67 private val TEST_SRC_ADDRV4 = "198.168.0.2".address() 68 private val TEST_DST_ADDRV4 = "198.168.0.1".address() 69 private val TEST_ADDRV6 = "2001:db8::1".address() 70 // This constant requires to be an Inet6Address, but InetAddresses.parseNumericAddress() will 71 // convert v4 mapped v6 address into an Inet4Address. So use Inet6Address.getByAddress() to 72 // create the address. 73 private val TEST_ADDRV4MAPPEDV6 = Inet6Address.getByAddress(null /* host */, 74 SRC_V4_MAPPED_V6_ADDRESS_BYTES, -1 /* scope_id */) 75 private val TEST_ADDRV4 = "1.2.3.4".address() 76 addressnull77 private fun String.address() = InetAddresses.parseNumericAddress(this) 78 private fun nattKeepalivePacket( 79 srcAddress: InetAddress? = TEST_SRC_ADDRV4, 80 srcPort: Int = TEST_PORT, 81 dstAddress: InetAddress? = TEST_DST_ADDRV4, 82 dstPort: Int = NATT_PORT 83 ) = NattKeepalivePacketData.nattKeepalivePacket(srcAddress, srcPort, dstAddress, dstPort) 84 85 @Test 86 fun testConstructor() { 87 assertFailsWith<InvalidPacketException>( 88 "Dst port is not NATT port should cause exception") { 89 nattKeepalivePacket(dstPort = TEST_PORT) 90 }.let { 91 assertEquals(it.error, ERROR_INVALID_PORT) 92 } 93 94 assertFailsWith<InvalidPacketException>("A v6 srcAddress should cause exception") { 95 nattKeepalivePacket(srcAddress = TEST_ADDRV6) 96 }.let { 97 assertEquals(it.error, ERROR_INVALID_IP_ADDRESS) 98 } 99 100 assertFailsWith<InvalidPacketException>("A v6 dstAddress should cause exception") { 101 nattKeepalivePacket(dstAddress = TEST_ADDRV6) 102 }.let { 103 assertEquals(it.error, ERROR_INVALID_IP_ADDRESS) 104 } 105 106 assertFailsWith<IllegalArgumentException>("Invalid data should cause exception") { 107 parcelingRoundTrip( 108 NattKeepalivePacketData(TEST_SRC_ADDRV4, TEST_PORT, TEST_DST_ADDRV4, TEST_PORT, 109 byteArrayOf(12, 31, 22, 44))) 110 } 111 } 112 113 @Test @IgnoreUpTo(Build.VERSION_CODES.R) @ConnectivityModuleTest testConstructor_afterRnull114 fun testConstructor_afterR() { 115 // v4 mapped v6 will be translated to a v4 address. 116 assertFailsWith<InvalidPacketException> { 117 nattKeepalivePacket(srcAddress = TEST_ADDRV6, dstAddress = TEST_ADDRV4MAPPEDV6) 118 } 119 assertFailsWith<InvalidPacketException> { 120 nattKeepalivePacket(srcAddress = TEST_ADDRV4MAPPEDV6, dstAddress = TEST_ADDRV6) 121 } 122 123 // Both src and dst address will be v4 after translation, so it won't cause exception. 124 val packet1 = nattKeepalivePacket( 125 dstAddress = TEST_ADDRV4MAPPEDV6, srcAddress = TEST_ADDRV4MAPPEDV6) 126 assertEquals(TEST_ADDRV4, packet1.srcAddress) 127 assertEquals(TEST_ADDRV4, packet1.dstAddress) 128 129 // Packet with v6 src and v6 dst address is valid. 130 val packet2 = nattKeepalivePacket(srcAddress = TEST_ADDRV6, dstAddress = TEST_ADDRV6) 131 assertEquals(TEST_ADDRV6, packet2.srcAddress) 132 assertEquals(TEST_ADDRV6, packet2.dstAddress) 133 } 134 135 @Test testParcelnull136 fun testParcel() { 137 assertParcelingIsLossless(nattKeepalivePacket()) 138 } 139 140 @Test testEqualsnull141 fun testEquals() { 142 assertEqualBothWays(nattKeepalivePacket(), nattKeepalivePacket()) 143 assertNotEquals(nattKeepalivePacket(dstAddress = TEST_SRC_ADDRV4), nattKeepalivePacket()) 144 assertNotEquals(nattKeepalivePacket(srcAddress = TEST_DST_ADDRV4), nattKeepalivePacket()) 145 // Test src port only because dst port have to be NATT_PORT 146 assertNotEquals(nattKeepalivePacket(srcPort = TEST_PORT2), nattKeepalivePacket()) 147 } 148 149 @Test testHashCodenull150 fun testHashCode() { 151 assertEquals(nattKeepalivePacket().hashCode(), nattKeepalivePacket().hashCode()) 152 } 153 } 154