diff --git a/service-t/Android.bp b/service-t/Android.bp index 55a07124e4..7e588cd412 100644 --- a/service-t/Android.bp +++ b/service-t/Android.bp @@ -102,7 +102,12 @@ java_library { ], exclude_srcs: [ "src/com/android/server/connectivity/mdns/internal/SocketNetlinkMonitor.java", - "src/com/android/server/connectivity/mdns/SocketNetLinkMonitorFactory.java" + "src/com/android/server/connectivity/mdns/SocketNetLinkMonitorFactory.java", + "src/com/android/server/connectivity/mdns/MdnsAdvertiser.java", + "src/com/android/server/connectivity/mdns/MdnsAnnouncer.java", + "src/com/android/server/connectivity/mdns/MdnsInterfaceAdvertiser.java", + "src/com/android/server/connectivity/mdns/MdnsProber.java", + "src/com/android/server/connectivity/mdns/MdnsRecordRepository.java", ], static_libs: [ "net-utils-device-common-mdns-standalone-build-test", diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsAnnouncer.java b/service-t/src/com/android/server/connectivity/mdns/MdnsAnnouncer.java index d9bc64305f..5812797b71 100644 --- a/service-t/src/com/android/server/connectivity/mdns/MdnsAnnouncer.java +++ b/service-t/src/com/android/server/connectivity/mdns/MdnsAnnouncer.java @@ -110,7 +110,7 @@ public class MdnsAnnouncer extends MdnsPacketRepeater cb, @NonNull SharedLog sharedLog) { - super(looper, replySender, cb, sharedLog); + super(looper, replySender, cb, sharedLog, MdnsAdvertiser.DBG); } // TODO: Notify MdnsRecordRepository that the records were announced for that service ID, diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsConstants.java b/service-t/src/com/android/server/connectivity/mdns/MdnsConstants.java index 1251170d4a..b83a6a02e6 100644 --- a/service-t/src/com/android/server/connectivity/mdns/MdnsConstants.java +++ b/service-t/src/com/android/server/connectivity/mdns/MdnsConstants.java @@ -19,6 +19,7 @@ package com.android.server.connectivity.mdns; import static java.nio.charset.StandardCharsets.UTF_8; import java.net.InetAddress; +import java.net.InetSocketAddress; import java.net.UnknownHostException; import java.nio.charset.Charset; @@ -42,6 +43,10 @@ public final class MdnsConstants { public static final String SUBTYPE_PREFIX = "_"; private static final String MDNS_IPV4_HOST_ADDRESS = "224.0.0.251"; private static final String MDNS_IPV6_HOST_ADDRESS = "FF02::FB"; + public static final InetSocketAddress IPV6_SOCKET_ADDR = new InetSocketAddress( + getMdnsIPv6Address(), MDNS_PORT); + public static final InetSocketAddress IPV4_SOCKET_ADDR = new InetSocketAddress( + getMdnsIPv4Address(), MDNS_PORT); private static InetAddress mdnsAddress; private MdnsConstants() { } @@ -75,4 +80,4 @@ public final class MdnsConstants { public static Charset getUtf8Charset() { return UTF_8; } -} \ No newline at end of file +} diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsInterfaceAdvertiser.java b/service-t/src/com/android/server/connectivity/mdns/MdnsInterfaceAdvertiser.java index 40dfd571fa..37e9743f09 100644 --- a/service-t/src/com/android/server/connectivity/mdns/MdnsInterfaceAdvertiser.java +++ b/service-t/src/com/android/server/connectivity/mdns/MdnsInterfaceAdvertiser.java @@ -161,7 +161,7 @@ public class MdnsInterfaceAdvertiser implements MulticastPacketReader.PacketHand @NonNull SharedLog sharedLog) { return new MdnsReplySender(looper, socket, packetCreationBuffer, sharedLog.forSubComponent( - MdnsReplySender.class.getSimpleName() + "/" + interfaceTag)); + MdnsReplySender.class.getSimpleName() + "/" + interfaceTag), DBG); } /** @see MdnsAnnouncer */ @@ -370,7 +370,7 @@ public class MdnsInterfaceAdvertiser implements MulticastPacketReader.PacketHand // happen when the incoming packet has answer records (not a question), so there will be no // answer. One exception is simultaneous probe tiebreaking (rfc6762 8.2), in which case the // conflicting service is still probing and won't reply either. - final MdnsRecordRepository.ReplyInfo answers = mRecordRepository.getReply(packet, src); + final MdnsReplyInfo answers = mRecordRepository.getReply(packet, src); if (answers == null) return; mReplySender.queueReply(answers); diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsPacketRepeater.java b/service-t/src/com/android/server/connectivity/mdns/MdnsPacketRepeater.java index fd0f5c9eaf..e84ceadae6 100644 --- a/service-t/src/com/android/server/connectivity/mdns/MdnsPacketRepeater.java +++ b/service-t/src/com/android/server/connectivity/mdns/MdnsPacketRepeater.java @@ -16,8 +16,8 @@ package com.android.server.connectivity.mdns; -import static com.android.server.connectivity.mdns.MdnsRecordRepository.IPV4_ADDR; -import static com.android.server.connectivity.mdns.MdnsRecordRepository.IPV6_ADDR; +import static com.android.server.connectivity.mdns.MdnsConstants.IPV4_SOCKET_ADDR; +import static com.android.server.connectivity.mdns.MdnsConstants.IPV6_SOCKET_ADDR; import android.annotation.NonNull; import android.annotation.Nullable; @@ -38,9 +38,8 @@ import java.net.InetSocketAddress; */ @RequiresApi(Build.VERSION_CODES.TIRAMISU) public abstract class MdnsPacketRepeater { - private static final boolean DBG = MdnsAdvertiser.DBG; private static final InetSocketAddress[] ALL_ADDRS = new InetSocketAddress[] { - IPV4_ADDR, IPV6_ADDR + IPV4_SOCKET_ADDR, IPV6_SOCKET_ADDR }; @NonNull @@ -51,6 +50,7 @@ public abstract class MdnsPacketRepeater { private final PacketRepeaterCallback mCb; @NonNull private final SharedLog mSharedLog; + private final boolean mEnableDebugLog; /** * Status callback from {@link MdnsPacketRepeater}. @@ -111,7 +111,7 @@ public abstract class MdnsPacketRepeater { } final MdnsPacket packet = request.getPacket(index); - if (DBG) { + if (mEnableDebugLog) { mSharedLog.v("Sending packets for iteration " + index + " out of " + request.getNumSends() + " for ID " + msg.what); } @@ -134,7 +134,7 @@ public abstract class MdnsPacketRepeater { // likely not to be available since the device is in deep sleep anyway. final long delay = request.getDelayMs(nextIndex); sendMessageDelayed(obtainMessage(msg.what, nextIndex, 0, request), delay); - if (DBG) mSharedLog.v("Scheduled next packet in " + delay + "ms"); + if (mEnableDebugLog) mSharedLog.v("Scheduled next packet in " + delay + "ms"); } // Call onSent after scheduling the next run, to allow the callback to cancel it @@ -145,15 +145,17 @@ public abstract class MdnsPacketRepeater { } protected MdnsPacketRepeater(@NonNull Looper looper, @NonNull MdnsReplySender replySender, - @Nullable PacketRepeaterCallback cb, @NonNull SharedLog sharedLog) { + @Nullable PacketRepeaterCallback cb, @NonNull SharedLog sharedLog, + boolean enableDebugLog) { mHandler = new ProbeHandler(looper); mReplySender = replySender; mCb = cb; mSharedLog = sharedLog; + mEnableDebugLog = enableDebugLog; } protected void startSending(int id, @NonNull T request, long initialDelayMs) { - if (DBG) { + if (mEnableDebugLog) { mSharedLog.v("Starting send with id " + id + ", request " + request.getClass().getSimpleName() + ", delay " + initialDelayMs); } @@ -172,7 +174,7 @@ public abstract class MdnsPacketRepeater { // all in the handler queue; unless this method is called from a message, but the current // message cannot be cancelled. if (mHandler.hasMessages(id)) { - if (DBG) { + if (mEnableDebugLog) { mSharedLog.v("Stopping send on id " + id); } mHandler.removeMessages(id); diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsProber.java b/service-t/src/com/android/server/connectivity/mdns/MdnsProber.java index f2b562ace3..e88947ab53 100644 --- a/service-t/src/com/android/server/connectivity/mdns/MdnsProber.java +++ b/service-t/src/com/android/server/connectivity/mdns/MdnsProber.java @@ -40,9 +40,8 @@ public class MdnsProber extends MdnsPacketRepeater { private static final long CONFLICT_RETRY_DELAY_MS = 5_000L; public MdnsProber(@NonNull Looper looper, @NonNull MdnsReplySender replySender, - @NonNull PacketRepeaterCallback cb, - @NonNull SharedLog sharedLog) { - super(looper, replySender, cb, sharedLog); + @NonNull PacketRepeaterCallback cb, @NonNull SharedLog sharedLog) { + super(looper, replySender, cb, sharedLog, MdnsAdvertiser.DBG); } /** Probing request to send with {@link MdnsProber}. */ diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsRecordRepository.java b/service-t/src/com/android/server/connectivity/mdns/MdnsRecordRepository.java index f5323720c0..130ff485d1 100644 --- a/service-t/src/com/android/server/connectivity/mdns/MdnsRecordRepository.java +++ b/service-t/src/com/android/server/connectivity/mdns/MdnsRecordRepository.java @@ -16,6 +16,8 @@ package com.android.server.connectivity.mdns; +import static com.android.server.connectivity.mdns.MdnsConstants.IPV4_SOCKET_ADDR; +import static com.android.server.connectivity.mdns.MdnsConstants.IPV6_SOCKET_ADDR; import static com.android.server.connectivity.mdns.MdnsConstants.NO_PACKET; import android.annotation.NonNull; @@ -79,11 +81,6 @@ public class MdnsRecordRepository { private static final String[] DNS_SD_SERVICE_TYPE = new String[] { "_services", "_dns-sd", "_udp", LOCAL_TLD }; - public static final InetSocketAddress IPV6_ADDR = new InetSocketAddress( - MdnsConstants.getMdnsIPv6Address(), MdnsConstants.MDNS_PORT); - public static final InetSocketAddress IPV4_ADDR = new InetSocketAddress( - MdnsConstants.getMdnsIPv4Address(), MdnsConstants.MDNS_PORT); - @NonNull private final Random mDelayGenerator = new Random(); // Map of service unique ID -> records for service @@ -454,37 +451,6 @@ public class MdnsRecordRepository { return ret; } - /** - * Info about a reply to be sent. - */ - public static class ReplyInfo { - @NonNull - public final List answers; - @NonNull - public final List additionalAnswers; - public final long sendDelayMs; - @NonNull - public final InetSocketAddress destination; - - public ReplyInfo( - @NonNull List answers, - @NonNull List additionalAnswers, - long sendDelayMs, - @NonNull InetSocketAddress destination) { - this.answers = answers; - this.additionalAnswers = additionalAnswers; - this.sendDelayMs = sendDelayMs; - this.destination = destination; - } - - @Override - public String toString() { - return "{ReplyInfo to " + destination + ", answers: " + answers.size() - + ", additionalAnswers: " + additionalAnswers.size() - + ", sendDelayMs " + sendDelayMs + "}"; - } - } - /** * Get the reply to send to an incoming packet. * @@ -492,7 +458,7 @@ public class MdnsRecordRepository { * @param src The source address of the incoming packet. */ @Nullable - public ReplyInfo getReply(MdnsPacket packet, InetSocketAddress src) { + public MdnsReplyInfo getReply(MdnsPacket packet, InetSocketAddress src) { final long now = SystemClock.elapsedRealtime(); final boolean replyUnicast = (packet.flags & MdnsConstants.QCLASS_UNICAST) != 0; final ArrayList additionalAnswerRecords = new ArrayList<>(); @@ -543,9 +509,9 @@ public class MdnsRecordRepository { if (replyUnicast) { dest = src; } else if (src.getAddress() instanceof Inet4Address) { - dest = IPV4_ADDR; + dest = IPV4_SOCKET_ADDR; } else { - dest = IPV6_ADDR; + dest = IPV6_SOCKET_ADDR; } // Build the list of answer records from their RecordInfo @@ -559,7 +525,7 @@ public class MdnsRecordRepository { answerRecords.add(info.record); } - return new ReplyInfo(answerRecords, additionalAnswerRecords, delayMs, dest); + return new MdnsReplyInfo(answerRecords, additionalAnswerRecords, delayMs, dest); } /** diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsReplyInfo.java b/service-t/src/com/android/server/connectivity/mdns/MdnsReplyInfo.java new file mode 100644 index 0000000000..ce61b54493 --- /dev/null +++ b/service-t/src/com/android/server/connectivity/mdns/MdnsReplyInfo.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.connectivity.mdns; + +import android.annotation.NonNull; + +import java.net.InetSocketAddress; +import java.util.List; + +/** + * Info about a mDNS reply to be sent. + */ +public final class MdnsReplyInfo { + @NonNull + public final List answers; + @NonNull + public final List additionalAnswers; + public final long sendDelayMs; + @NonNull + public final InetSocketAddress destination; + + public MdnsReplyInfo( + @NonNull List answers, + @NonNull List additionalAnswers, + long sendDelayMs, + @NonNull InetSocketAddress destination) { + this.answers = answers; + this.additionalAnswers = additionalAnswers; + this.sendDelayMs = sendDelayMs; + this.destination = destination; + } + + @Override + public String toString() { + return "{MdnsReplyInfo to " + destination + ", answers: " + answers.size() + + ", additionalAnswers: " + additionalAnswers.size() + + ", sendDelayMs " + sendDelayMs + "}"; + } +} diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsReplySender.java b/service-t/src/com/android/server/connectivity/mdns/MdnsReplySender.java index 3d64b5ab04..abf5d99518 100644 --- a/service-t/src/com/android/server/connectivity/mdns/MdnsReplySender.java +++ b/service-t/src/com/android/server/connectivity/mdns/MdnsReplySender.java @@ -26,7 +26,6 @@ import android.os.Looper; import android.os.Message; import com.android.net.module.util.SharedLog; -import com.android.server.connectivity.mdns.MdnsRecordRepository.ReplyInfo; import com.android.server.connectivity.mdns.util.MdnsUtils; import java.io.IOException; @@ -45,7 +44,6 @@ import java.util.Collections; */ @RequiresApi(Build.VERSION_CODES.TIRAMISU) public class MdnsReplySender { - private static final boolean DBG = MdnsAdvertiser.DBG; private static final int MSG_SEND = 1; private static final int PACKET_NOT_SENT = 0; private static final int PACKET_SENT = 1; @@ -58,24 +56,27 @@ public class MdnsReplySender { private final byte[] mPacketCreationBuffer; @NonNull private final SharedLog mSharedLog; + private final boolean mEnableDebugLog; public MdnsReplySender(@NonNull Looper looper, @NonNull MdnsInterfaceSocket socket, - @NonNull byte[] packetCreationBuffer, @NonNull SharedLog sharedLog) { + @NonNull byte[] packetCreationBuffer, @NonNull SharedLog sharedLog, + boolean enableDebugLog) { mHandler = new SendHandler(looper); mSocket = socket; mPacketCreationBuffer = packetCreationBuffer; mSharedLog = sharedLog; + mEnableDebugLog = enableDebugLog; } /** * Queue a reply to be sent when its send delay expires. */ - public void queueReply(@NonNull ReplyInfo reply) { + public void queueReply(@NonNull MdnsReplyInfo reply) { ensureRunningOnHandlerThread(mHandler); // TODO: implement response aggregation (RFC 6762 6.4) mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SEND, reply), reply.sendDelayMs); - if (DBG) { + if (mEnableDebugLog) { mSharedLog.v("Scheduling " + reply); } } @@ -118,8 +119,8 @@ public class MdnsReplySender { @Override public void handleMessage(@NonNull Message msg) { - final ReplyInfo replyInfo = (ReplyInfo) msg.obj; - if (DBG) mSharedLog.v("Sending " + replyInfo); + final MdnsReplyInfo replyInfo = (MdnsReplyInfo) msg.obj; + if (mEnableDebugLog) mSharedLog.v("Sending " + replyInfo); final int flags = 0x8400; // Response, authoritative (rfc6762 18.4) final MdnsPacket packet = new MdnsPacket(flags, diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsAnnouncerTest.kt b/tests/unit/java/com/android/server/connectivity/mdns/MdnsAnnouncerTest.kt index c39ee1e1c7..27974620b3 100644 --- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsAnnouncerTest.kt +++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsAnnouncerTest.kt @@ -82,7 +82,8 @@ class MdnsAnnouncerTest { @Test fun testAnnounce() { - val replySender = MdnsReplySender( thread.looper, socket, buffer, sharedLog) + val replySender = MdnsReplySender( + thread.looper, socket, buffer, sharedLog, true /* enableDebugLog */) @Suppress("UNCHECKED_CAST") val cb = mock(MdnsPacketRepeater.PacketRepeaterCallback::class.java) as MdnsPacketRepeater.PacketRepeaterCallback diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsInterfaceAdvertiserTest.kt b/tests/unit/java/com/android/server/connectivity/mdns/MdnsInterfaceAdvertiserTest.kt index c19747e65e..a67dc5e9a9 100644 --- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsInterfaceAdvertiserTest.kt +++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsInterfaceAdvertiserTest.kt @@ -190,8 +190,8 @@ class MdnsInterfaceAdvertiserTest { fun testReplyToQuery() { addServiceAndFinishProbing(TEST_SERVICE_ID_1, TEST_SERVICE_1) - val mockReply = mock(MdnsRecordRepository.ReplyInfo::class.java) - doReturn(mockReply).`when`(repository).getReply(any(), any()) + val testReply = MdnsReplyInfo(emptyList(), emptyList(), 0, InetSocketAddress(0)) + doReturn(testReply).`when`(repository).getReply(any(), any()) // Query obtained with: // scapy.raw(scapy.DNS( @@ -216,7 +216,7 @@ class MdnsInterfaceAdvertiserTest { assertContentEquals(arrayOf("_testservice", "_tcp", "local"), it.questions[0].name) } - verify(replySender).queueReply(mockReply) + verify(replySender).queueReply(testReply) } @Test diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsProberTest.kt b/tests/unit/java/com/android/server/connectivity/mdns/MdnsProberTest.kt index f28481995e..5b7c0bacc0 100644 --- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsProberTest.kt +++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsProberTest.kt @@ -119,7 +119,8 @@ class MdnsProberTest { @Test fun testProbe() { - val replySender = MdnsReplySender(thread.looper, socket, buffer, sharedLog) + val replySender = MdnsReplySender( + thread.looper, socket, buffer, sharedLog, true /* enableDebugLog */) val prober = TestProber(thread.looper, replySender, cb, sharedLog) val probeInfo = TestProbeInfo( listOf(makeServiceRecord(TEST_SERVICE_NAME_1, 37890))) @@ -143,7 +144,8 @@ class MdnsProberTest { @Test fun testProbeMultipleRecords() { - val replySender = MdnsReplySender(thread.looper, socket, buffer, sharedLog) + val replySender = MdnsReplySender( + thread.looper, socket, buffer, sharedLog, true /* enableDebugLog */) val prober = TestProber(thread.looper, replySender, cb, sharedLog) val probeInfo = TestProbeInfo(listOf( makeServiceRecord(TEST_SERVICE_NAME_1, 37890), @@ -181,7 +183,8 @@ class MdnsProberTest { @Test fun testStopProbing() { - val replySender = MdnsReplySender(thread.looper, socket, buffer, sharedLog) + val replySender = MdnsReplySender( + thread.looper, socket, buffer, sharedLog, true /* enableDebugLog */) val prober = TestProber(thread.looper, replySender, cb, sharedLog) val probeInfo = TestProbeInfo( listOf(makeServiceRecord(TEST_SERVICE_NAME_1, 37890)),