1 package com.android.server.connectivity.mdns.internal 2 3 import android.net.LinkAddress 4 import android.os.Build 5 import android.os.Handler 6 import android.os.HandlerThread 7 import android.system.OsConstants 8 import com.android.net.module.util.SharedLog 9 import com.android.net.module.util.netlink.NetlinkConstants 10 import com.android.net.module.util.netlink.RtNetlinkAddressMessage 11 import com.android.net.module.util.netlink.StructIfaddrMsg 12 import com.android.net.module.util.netlink.StructNlMsgHdr 13 import com.android.server.connectivity.mdns.MdnsAdvertiserTest 14 import com.android.server.connectivity.mdns.MdnsSocketProvider 15 import com.android.testutils.DevSdkIgnoreRule 16 import com.android.testutils.DevSdkIgnoreRunner 17 import org.junit.After 18 import org.junit.Before 19 import org.junit.Test 20 import org.junit.runner.RunWith 21 import org.mockito.ArgumentMatchers.eq 22 import org.mockito.Mockito 23 import org.mockito.Mockito.argThat 24 import org.mockito.Mockito.never 25 import org.mockito.Mockito.verify 26 27 private val LINKADDRV4 = LinkAddress("192.0.2.0/24") 28 private val IFACE_IDX = 32 29 30 @DevSdkIgnoreRunner.MonitorThreadLeak 31 @RunWith(DevSdkIgnoreRunner::class) 32 @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.S_V2) 33 internal class SocketNetlinkMonitorTest { 34 private val thread = HandlerThread(MdnsAdvertiserTest::class.simpleName) 35 private val sharedlog = Mockito.mock(SharedLog::class.java) 36 private val netlinkMonitorCallBack = 37 Mockito.mock(MdnsSocketProvider.NetLinkMonitorCallBack::class.java) 38 39 @Before setUpnull40 fun setUp() { 41 thread.start() 42 } 43 44 @After tearDownnull45 fun tearDown() { 46 thread.quitSafely() 47 thread.join() 48 } 49 50 @Test testHandleDeprecatedNetlinkMessagenull51 fun testHandleDeprecatedNetlinkMessage() { 52 val socketNetlinkMonitor = SocketNetlinkMonitor(Handler(thread.looper), sharedlog, 53 netlinkMonitorCallBack) 54 val nlmsghdr = StructNlMsgHdr().apply { 55 nlmsg_type = NetlinkConstants.RTM_NEWADDR 56 nlmsg_flags = (StructNlMsgHdr.NLM_F_REQUEST.toInt() 57 or StructNlMsgHdr.NLM_F_ACK.toInt()).toShort() 58 nlmsg_seq = 1 59 } 60 val structIfaddrMsg = StructIfaddrMsg(OsConstants.AF_INET.toShort(), 61 LINKADDRV4.prefixLength.toShort(), 62 LINKADDRV4.flags.toShort(), 63 LINKADDRV4.scope.toShort(), IFACE_IDX) 64 // If the LinkAddress is not preferred, RTM_NEWADDR will not trigger 65 // addOrUpdateInterfaceAddress() callback. 66 val deprecatedAddNetLinkMessage = RtNetlinkAddressMessage(nlmsghdr, structIfaddrMsg, 67 LINKADDRV4.address, null /* structIfacacheInfo */, 68 LINKADDRV4.flags or OsConstants.IFA_F_DEPRECATED) 69 socketNetlinkMonitor.processNetlinkMessage(deprecatedAddNetLinkMessage, 0L /* whenMs */) 70 verify(netlinkMonitorCallBack, never()).addOrUpdateInterfaceAddress(eq(IFACE_IDX), 71 argThat { it.address == LINKADDRV4.address }) 72 73 // If the LinkAddress is preferred, RTM_NEWADDR will trigger addOrUpdateInterfaceAddress() 74 // callback. 75 val preferredAddNetLinkMessage = RtNetlinkAddressMessage(nlmsghdr, structIfaddrMsg, 76 LINKADDRV4.address, null /* structIfacacheInfo */, 77 LINKADDRV4.flags or OsConstants.IFA_F_OPTIMISTIC) 78 socketNetlinkMonitor.processNetlinkMessage(preferredAddNetLinkMessage, 0L /* whenMs */) 79 verify(netlinkMonitorCallBack).addOrUpdateInterfaceAddress(eq(IFACE_IDX), 80 argThat { it.address == LINKADDRV4.address }) 81 82 // Even if the LinkAddress is not preferred, RTM_DELADDR will trigger 83 // deleteInterfaceAddress() callback. 84 nlmsghdr.nlmsg_type = NetlinkConstants.RTM_DELADDR 85 val deprecatedDelNetLinkMessage = RtNetlinkAddressMessage(nlmsghdr, structIfaddrMsg, 86 LINKADDRV4.address, null /* structIfacacheInfo */, 87 LINKADDRV4.flags or OsConstants.IFA_F_DEPRECATED) 88 socketNetlinkMonitor.processNetlinkMessage(deprecatedDelNetLinkMessage, 0L /* whenMs */) 89 verify(netlinkMonitorCallBack).deleteInterfaceAddress(eq(IFACE_IDX), 90 argThat { it.address == LINKADDRV4.address }) 91 } 92 } 93