From 24db3f1e1df4d90c0df777a6f7f124b4039fc030 Mon Sep 17 00:00:00 2001 From: Paul Hu <paulhu@google.com> Date: Thu, 23 Nov 2023 04:00:26 +0000 Subject: [PATCH] Generate a query packet with MdnsPacket This is a no-op change, only refactoring the query packet generation code to use MdnsPacket. This refactoring enables the insertion of additional sections into the query packet and facilitates the determination of truncation requirements. Bug: 312657709 Test: atest FrameworksNetTests NsdManagerTest Change-Id: I3671842b6d433e1856a1efae643f3fe1f6c532d1 --- .../mdns/EnqueueMdnsQueryCallable.java | 75 +++++++------------ .../mdns/MdnsInetAddressRecord.java | 6 ++ .../connectivity/mdns/MdnsPointerRecord.java | 6 ++ .../connectivity/mdns/MdnsServiceRecord.java | 6 ++ .../connectivity/mdns/MdnsTextRecord.java | 6 ++ .../connectivity/mdns/util/MdnsUtils.java | 19 +++-- 6 files changed, 64 insertions(+), 54 deletions(-) diff --git a/service-t/src/com/android/server/connectivity/mdns/EnqueueMdnsQueryCallable.java b/service-t/src/com/android/server/connectivity/mdns/EnqueueMdnsQueryCallable.java index 1582fb66b4..c4d3338ed2 100644 --- a/service-t/src/com/android/server/connectivity/mdns/EnqueueMdnsQueryCallable.java +++ b/service-t/src/com/android/server/connectivity/mdns/EnqueueMdnsQueryCallable.java @@ -32,6 +32,7 @@ import java.net.DatagramPacket; import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.concurrent.Callable; @@ -122,17 +123,22 @@ public class EnqueueMdnsQueryCallable implements Callable<Pair<Integer, List<Str return Pair.create(INVALID_TRANSACTION_ID, new ArrayList<>()); } - int numQuestions = 0; + final List<MdnsRecord> questions = new ArrayList<>(); if (sendDiscoveryQueries) { - numQuestions++; // Base service type - if (!subtypes.isEmpty()) { - numQuestions += subtypes.size(); + // Base service type + questions.add(new MdnsPointerRecord(serviceTypeLabels, expectUnicastResponse)); + for (String subtype : subtypes) { + final String[] labels = new String[serviceTypeLabels.length + 2]; + labels[0] = MdnsConstants.SUBTYPE_PREFIX + subtype; + labels[1] = MdnsConstants.SUBTYPE_LABEL; + System.arraycopy(serviceTypeLabels, 0, labels, 2, serviceTypeLabels.length); + + questions.add(new MdnsPointerRecord(labels, expectUnicastResponse)); } } // List of (name, type) to query - final ArrayList<Pair<String[], Integer>> missingKnownAnswerRecords = new ArrayList<>(); final long now = clock.elapsedRealtime(); for (MdnsResponse response : servicesToResolve) { final String[] serviceName = response.getServiceName(); @@ -142,13 +148,13 @@ public class EnqueueMdnsQueryCallable implements Callable<Pair<Integer, List<Str boolean renewSrv = !response.hasServiceRecord() || MdnsUtils.isRecordRenewalNeeded( response.getServiceRecord(), now); if (renewSrv && renewTxt) { - missingKnownAnswerRecords.add(new Pair<>(serviceName, MdnsRecord.TYPE_ANY)); + questions.add(new MdnsAnyRecord(serviceName, expectUnicastResponse)); } else { if (renewTxt) { - missingKnownAnswerRecords.add(new Pair<>(serviceName, MdnsRecord.TYPE_TXT)); + questions.add(new MdnsTextRecord(serviceName, expectUnicastResponse)); } if (renewSrv) { - missingKnownAnswerRecords.add(new Pair<>(serviceName, MdnsRecord.TYPE_SRV)); + questions.add(new MdnsServiceRecord(serviceName, expectUnicastResponse)); // The hostname is not yet known, so queries for address records will be // sent the next time the EnqueueMdnsQueryCallable is enqueued if the reply // does not contain them. In practice, advertisers should include the @@ -157,46 +163,27 @@ public class EnqueueMdnsQueryCallable implements Callable<Pair<Integer, List<Str } else if (!response.hasInet4AddressRecord() && !response.hasInet6AddressRecord()) { final String[] host = response.getServiceRecord().getServiceHost(); - missingKnownAnswerRecords.add(new Pair<>(host, MdnsRecord.TYPE_A)); - missingKnownAnswerRecords.add(new Pair<>(host, MdnsRecord.TYPE_AAAA)); + questions.add(new MdnsInetAddressRecord( + host, MdnsRecord.TYPE_A, expectUnicastResponse)); + questions.add(new MdnsInetAddressRecord( + host, MdnsRecord.TYPE_AAAA, expectUnicastResponse)); } } } - numQuestions += missingKnownAnswerRecords.size(); - if (numQuestions == 0) { + if (questions.size() == 0) { // No query to send return Pair.create(INVALID_TRANSACTION_ID, new ArrayList<>()); } - // Header. - packetWriter.writeUInt16(transactionId); // transaction ID - packetWriter.writeUInt16(MdnsConstants.FLAGS_QUERY); // flags - packetWriter.writeUInt16(numQuestions); // number of questions - packetWriter.writeUInt16(0); // number of answers (not yet known; will be written later) - packetWriter.writeUInt16(0); // number of authority entries - packetWriter.writeUInt16(0); // number of additional records - - // Question(s) for missing records on known answers - for (Pair<String[], Integer> question : missingKnownAnswerRecords) { - writeQuestion(question.first, question.second); - } - - // Question(s) for discovering other services with the type. There will be one question - // for each (fqdn+subtype, recordType) combination, as well as one for each (fqdn, - // recordType) combination. - if (sendDiscoveryQueries) { - for (String subtype : subtypes) { - String[] labels = new String[serviceTypeLabels.length + 2]; - labels[0] = MdnsConstants.SUBTYPE_PREFIX + subtype; - labels[1] = MdnsConstants.SUBTYPE_LABEL; - System.arraycopy(serviceTypeLabels, 0, labels, 2, serviceTypeLabels.length); - - writeQuestion(labels, MdnsRecord.TYPE_PTR); - } - writeQuestion(serviceTypeLabels, MdnsRecord.TYPE_PTR); - } - + final MdnsPacket queryPacket = new MdnsPacket( + transactionId, + MdnsConstants.FLAGS_QUERY, + questions, + Collections.emptyList(), /* answers */ + Collections.emptyList(), /* authorityRecords */ + Collections.emptyList() /* additionalRecords */); + MdnsUtils.writeMdnsPacket(packetWriter, queryPacket); sendPacketToIpv4AndIpv6(requestSender, MdnsConstants.MDNS_PORT); for (Integer emulatorPort : castShellEmulatorMdnsPorts) { sendPacketToIpv4AndIpv6(requestSender, emulatorPort); @@ -209,14 +196,6 @@ public class EnqueueMdnsQueryCallable implements Callable<Pair<Integer, List<Str } } - private void writeQuestion(String[] labels, int type) throws IOException { - packetWriter.writeLabels(labels); - packetWriter.writeUInt16(type); - packetWriter.writeUInt16( - MdnsConstants.QCLASS_INTERNET - | (expectUnicastResponse ? MdnsConstants.QCLASS_UNICAST : 0)); - } - private void sendPacket(MdnsSocketClientBase requestSender, InetSocketAddress address) throws IOException { DatagramPacket packet = packetWriter.getPacket(address); diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsInetAddressRecord.java b/service-t/src/com/android/server/connectivity/mdns/MdnsInetAddressRecord.java index 973fd9602e..4399f2d6da 100644 --- a/service-t/src/com/android/server/connectivity/mdns/MdnsInetAddressRecord.java +++ b/service-t/src/com/android/server/connectivity/mdns/MdnsInetAddressRecord.java @@ -60,6 +60,12 @@ public class MdnsInetAddressRecord extends MdnsRecord { super(name, type, reader, isQuestion); } + public MdnsInetAddressRecord(String[] name, int type, boolean isUnicast) { + super(name, type, + MdnsConstants.QCLASS_INTERNET | (isUnicast ? MdnsConstants.QCLASS_UNICAST : 0), + 0L /* receiptTimeMillis */, false /* cacheFlush */, 0L /* ttlMillis */); + } + public MdnsInetAddressRecord(String[] name, long receiptTimeMillis, boolean cacheFlush, long ttlMillis, InetAddress address) { super(name, address instanceof Inet4Address ? TYPE_A : TYPE_AAAA, diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsPointerRecord.java b/service-t/src/com/android/server/connectivity/mdns/MdnsPointerRecord.java index 41cc380029..e5c90a46e8 100644 --- a/service-t/src/com/android/server/connectivity/mdns/MdnsPointerRecord.java +++ b/service-t/src/com/android/server/connectivity/mdns/MdnsPointerRecord.java @@ -39,6 +39,12 @@ public class MdnsPointerRecord extends MdnsRecord { super(name, TYPE_PTR, reader, isQuestion); } + public MdnsPointerRecord(String[] name, boolean isUnicast) { + super(name, TYPE_PTR, + MdnsConstants.QCLASS_INTERNET | (isUnicast ? MdnsConstants.QCLASS_UNICAST : 0), + 0L /* receiptTimeMillis */, false /* cacheFlush */, 0L /* ttlMillis */); + } + public MdnsPointerRecord(String[] name, long receiptTimeMillis, boolean cacheFlush, long ttlMillis, String[] pointer) { super(name, TYPE_PTR, MdnsConstants.QCLASS_INTERNET, receiptTimeMillis, cacheFlush, diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsServiceRecord.java b/service-t/src/com/android/server/connectivity/mdns/MdnsServiceRecord.java index 4d407be63f..0d6a9ec487 100644 --- a/service-t/src/com/android/server/connectivity/mdns/MdnsServiceRecord.java +++ b/service-t/src/com/android/server/connectivity/mdns/MdnsServiceRecord.java @@ -49,6 +49,12 @@ public class MdnsServiceRecord extends MdnsRecord { super(name, TYPE_SRV, reader, isQuestion); } + public MdnsServiceRecord(String[] name, boolean isUnicast) { + super(name, TYPE_SRV, + MdnsConstants.QCLASS_INTERNET | (isUnicast ? MdnsConstants.QCLASS_UNICAST : 0), + 0L /* receiptTimeMillis */, false /* cacheFlush */, 0L /* ttlMillis */); + } + public MdnsServiceRecord(String[] name, long receiptTimeMillis, boolean cacheFlush, long ttlMillis, int servicePriority, int serviceWeight, int servicePort, String[] serviceHost) { diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsTextRecord.java b/service-t/src/com/android/server/connectivity/mdns/MdnsTextRecord.java index cf6c8acf2f..92cf3243cc 100644 --- a/service-t/src/com/android/server/connectivity/mdns/MdnsTextRecord.java +++ b/service-t/src/com/android/server/connectivity/mdns/MdnsTextRecord.java @@ -42,6 +42,12 @@ public class MdnsTextRecord extends MdnsRecord { super(name, TYPE_TXT, reader, isQuestion); } + public MdnsTextRecord(String[] name, boolean isUnicast) { + super(name, TYPE_TXT, + MdnsConstants.QCLASS_INTERNET | (isUnicast ? MdnsConstants.QCLASS_UNICAST : 0), + 0L /* receiptTimeMillis */, false /* cacheFlush */, 0L /* ttlMillis */); + } + public MdnsTextRecord(String[] name, long receiptTimeMillis, boolean cacheFlush, long ttlMillis, List<TextEntry> entries) { super(name, TYPE_TXT, MdnsConstants.QCLASS_INTERNET, receiptTimeMillis, cacheFlush, diff --git a/service-t/src/com/android/server/connectivity/mdns/util/MdnsUtils.java b/service-t/src/com/android/server/connectivity/mdns/util/MdnsUtils.java index 4d79f9d8ea..1482ebb7a0 100644 --- a/service-t/src/com/android/server/connectivity/mdns/util/MdnsUtils.java +++ b/service-t/src/com/android/server/connectivity/mdns/util/MdnsUtils.java @@ -183,13 +183,10 @@ public class MdnsUtils { } /** - * Create a raw DNS packet. + * Write the mdns packet from given MdnsPacket. */ - public static byte[] createRawDnsPacket(@NonNull byte[] packetCreationBuffer, - @NonNull MdnsPacket packet) throws IOException { - // TODO: support packets over size (send in multiple packets with TC bit set) - final MdnsPacketWriter writer = new MdnsPacketWriter(packetCreationBuffer); - + public static void writeMdnsPacket(@NonNull MdnsPacketWriter writer, @NonNull MdnsPacket packet) + throws IOException { writer.writeUInt16(packet.transactionId); // Transaction ID (advertisement: 0) writer.writeUInt16(packet.flags); // Response, authoritative (rfc6762 18.4) writer.writeUInt16(packet.questions.size()); // questions count @@ -210,6 +207,16 @@ public class MdnsUtils { for (MdnsRecord record : packet.additionalRecords) { record.write(writer, 0L); } + } + + /** + * Create a raw DNS packet. + */ + public static byte[] createRawDnsPacket(@NonNull byte[] packetCreationBuffer, + @NonNull MdnsPacket packet) throws IOException { + // TODO: support packets over size (send in multiple packets with TC bit set) + final MdnsPacketWriter writer = new MdnsPacketWriter(packetCreationBuffer); + writeMdnsPacket(writer, packet); final int len = writer.getWritePosition(); return Arrays.copyOfRange(packetCreationBuffer, 0, len); -- GitLab