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