Merge "Generate a query packet with MdnsPacket" into main am: 9a966eab9e am: 755aa1fd9a
Original change: https://android-review.googlesource.com/c/platform/packages/modules/Connectivity/+/2845495 Change-Id: I77bc44a7b63e080dbe5acf157bb415d12c75cf27 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
commit
dd26ea0860
6 changed files with 64 additions and 54 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue