Merge changes If92be663,I377f3409,I7bb22856,I98d484b3,I945f2c7c, ...
* changes:
gn2bp: Remove unused builtin_deps
gn2bp: Allow pclmul and ssse3 cflag
gn2bp: Use list for cflag_allowlist
gn2bp: Fix to bubble up proto static_lib deps
gn2bp: Use chromium protoc to generate .c/.h files
gn2bp: create modules for protoc
gn2bp: Remove third_party protobuf from local_include_dirs_denylist
gn2bp: Remove third_party protobuf from builtin_deps
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsAnyRecord.java b/service/mdns/com/android/server/connectivity/mdns/MdnsAnyRecord.java
new file mode 100644
index 0000000..fcfe9f7
--- /dev/null
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsAnyRecord.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 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.net.DnsResolver;
+
+import java.io.IOException;
+
+/**
+ * A mDNS "ANY" record, used in mDNS questions to query for any record type.
+ */
+public class MdnsAnyRecord extends MdnsRecord {
+
+ protected MdnsAnyRecord(String[] name, MdnsPacketReader reader) throws IOException {
+ super(name, TYPE_ANY, reader, true /* isQuestion */);
+ }
+
+ protected MdnsAnyRecord(String[] name, boolean unicast) {
+ super(name, TYPE_ANY, DnsResolver.CLASS_IN /* cls */,
+ 0L /* receiptTimeMillis */, unicast /* cacheFlush */, 0L /* ttlMillis */);
+ }
+
+ @Override
+ protected void readData(MdnsPacketReader reader) throws IOException {
+ // No data to read
+ }
+
+ @Override
+ protected void writeData(MdnsPacketWriter writer) throws IOException {
+ // No data to write
+ }
+}
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsInetAddressRecord.java b/service/mdns/com/android/server/connectivity/mdns/MdnsInetAddressRecord.java
index 47ac20e..dd8a526 100644
--- a/service/mdns/com/android/server/connectivity/mdns/MdnsInetAddressRecord.java
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsInetAddressRecord.java
@@ -43,7 +43,32 @@
*/
public MdnsInetAddressRecord(String[] name, int type, MdnsPacketReader reader)
throws IOException {
- super(name, type, reader);
+ this(name, type, reader, false);
+ }
+
+ /**
+ * Constructs the {@link MdnsRecord}
+ *
+ * @param name the service host name
+ * @param type the type of record (either Type 'AAAA' or Type 'A')
+ * @param reader the reader to read the record from.
+ * @param isQuestion whether the record is in the question section
+ */
+ public MdnsInetAddressRecord(String[] name, int type, MdnsPacketReader reader,
+ boolean isQuestion)
+ throws IOException {
+ super(name, type, reader, isQuestion);
+ }
+
+ public MdnsInetAddressRecord(String[] name, long receiptTimeMillis, boolean cacheFlush,
+ long ttlMillis, InetAddress address) {
+ super(name, address instanceof Inet4Address ? TYPE_A : TYPE_AAAA,
+ MdnsConstants.QCLASS_INTERNET, receiptTimeMillis, cacheFlush, ttlMillis);
+ if (address instanceof Inet4Address) {
+ inet4Address = (Inet4Address) address;
+ } else {
+ inet6Address = (Inet6Address) address;
+ }
}
/** Returns the IPv6 address. */
@@ -127,4 +152,4 @@
&& Objects.equals(inet4Address, ((MdnsInetAddressRecord) other).inet4Address)
&& Objects.equals(inet6Address, ((MdnsInetAddressRecord) other).inet6Address);
}
-}
\ No newline at end of file
+}
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsPointerRecord.java b/service/mdns/com/android/server/connectivity/mdns/MdnsPointerRecord.java
index 9641a40..2c7b26b 100644
--- a/service/mdns/com/android/server/connectivity/mdns/MdnsPointerRecord.java
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsPointerRecord.java
@@ -29,7 +29,19 @@
private String[] pointer;
public MdnsPointerRecord(String[] name, MdnsPacketReader reader) throws IOException {
- super(name, TYPE_PTR, reader);
+ this(name, reader, false);
+ }
+
+ public MdnsPointerRecord(String[] name, MdnsPacketReader reader, boolean isQuestion)
+ throws IOException {
+ super(name, TYPE_PTR, reader, isQuestion);
+ }
+
+ public MdnsPointerRecord(String[] name, long receiptTimeMillis, boolean cacheFlush,
+ long ttlMillis, String[] pointer) {
+ super(name, TYPE_PTR, MdnsConstants.QCLASS_INTERNET, receiptTimeMillis, cacheFlush,
+ ttlMillis);
+ this.pointer = pointer;
}
/** Returns the pointer as an array of labels. */
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsRecord.java b/service/mdns/com/android/server/connectivity/mdns/MdnsRecord.java
index 35f6da1..c0481a4 100644
--- a/service/mdns/com/android/server/connectivity/mdns/MdnsRecord.java
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsRecord.java
@@ -39,6 +39,11 @@
public static final int TYPE_PTR = 0x000C;
public static final int TYPE_SRV = 0x0021;
public static final int TYPE_TXT = 0x0010;
+ public static final int TYPE_ANY = 0x00ff;
+
+ private static final int FLAG_CACHE_FLUSH = 0x8000;
+
+ public static final long RECEIPT_TIME_NOT_SENT = 0L;
/** Status indicating that the record is current. */
public static final int STATUS_OK = 0;
@@ -58,23 +63,52 @@
* Constructs a new record with the given name and type.
*
* @param reader The reader to read the record from.
+ * @param isQuestion Whether the record was included in the questions part of the message.
+ * @throws IOException If an error occurs while reading the packet.
+ */
+ protected MdnsRecord(String[] name, int type, MdnsPacketReader reader, boolean isQuestion)
+ throws IOException {
+ this.name = name;
+ this.type = type;
+ cls = reader.readUInt16();
+ receiptTimeMillis = SystemClock.elapsedRealtime();
+
+ if (isQuestion) {
+ // Questions do not have TTL or data
+ ttlMillis = 0L;
+ } else {
+ ttlMillis = SECONDS.toMillis(reader.readUInt32());
+ int dataLength = reader.readUInt16();
+
+ reader.setLimit(dataLength);
+ readData(reader);
+ reader.clearLimit();
+ }
+ }
+
+ /**
+ * Constructs a new record with the given name and type.
+ *
+ * @param reader The reader to read the record from.
* @throws IOException If an error occurs while reading the packet.
*/
// call to readData(com.android.server.connectivity.mdns.MdnsPacketReader) not allowed on given
// receiver.
@SuppressWarnings("nullness:method.invocation.invalid")
protected MdnsRecord(String[] name, int type, MdnsPacketReader reader) throws IOException {
+ this(name, type, reader, false);
+ }
+
+ /**
+ * Constructs a new record with the given properties.
+ */
+ protected MdnsRecord(String[] name, int type, int cls, long receiptTimeMillis,
+ boolean cacheFlush, long ttlMillis) {
this.name = name;
this.type = type;
- cls = reader.readUInt16();
- ttlMillis = SECONDS.toMillis(reader.readUInt32());
- int dataLength = reader.readUInt16();
-
- receiptTimeMillis = SystemClock.elapsedRealtime();
-
- reader.setLimit(dataLength);
- readData(reader);
- reader.clearLimit();
+ this.cls = cls | (cacheFlush ? FLAG_CACHE_FLUSH : 0);
+ this.receiptTimeMillis = receiptTimeMillis;
+ this.ttlMillis = ttlMillis;
}
/**
@@ -126,13 +160,29 @@
return type;
}
+ /** Return the record's class. */
+ public final int getRecordClass() {
+ return cls & ~FLAG_CACHE_FLUSH;
+ }
+
+ /** Return whether the cache flush flag is set. */
+ public final boolean getCacheFlush() {
+ return (cls & FLAG_CACHE_FLUSH) != 0;
+ }
+
/**
* Returns the record's remaining TTL.
*
+ * If the record was not sent yet (receipt time {@link #RECEIPT_TIME_NOT_SENT}), this is the
+ * original TTL of the record.
* @param now The current system time.
* @return The remaning TTL, in milliseconds.
*/
public long getRemainingTTL(final long now) {
+ if (receiptTimeMillis == RECEIPT_TIME_NOT_SENT) {
+ return ttlMillis;
+ }
+
long age = now - receiptTimeMillis;
if (age > ttlMillis) {
return 0;
@@ -187,6 +237,9 @@
/** Gets the status of the record. */
public int getStatus(final long now) {
+ if (receiptTimeMillis == RECEIPT_TIME_NOT_SENT) {
+ return STATUS_OK;
+ }
final long age = now - receiptTimeMillis;
if (age > ttlMillis) {
return STATUS_EXPIRED;
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsServiceRecord.java b/service/mdns/com/android/server/connectivity/mdns/MdnsServiceRecord.java
index c52d25e..ebd8b77 100644
--- a/service/mdns/com/android/server/connectivity/mdns/MdnsServiceRecord.java
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsServiceRecord.java
@@ -39,7 +39,23 @@
private String[] serviceHost;
public MdnsServiceRecord(String[] name, MdnsPacketReader reader) throws IOException {
- super(name, TYPE_SRV, reader);
+ this(name, reader, false);
+ }
+
+ public MdnsServiceRecord(String[] name, MdnsPacketReader reader, boolean isQuestion)
+ throws IOException {
+ super(name, TYPE_SRV, reader, isQuestion);
+ }
+
+ public MdnsServiceRecord(String[] name, long receiptTimeMillis, boolean cacheFlush,
+ long ttlMillis, int servicePriority, int serviceWeight, int servicePort,
+ String[] serviceHost) {
+ super(name, TYPE_SRV, MdnsConstants.QCLASS_INTERNET, receiptTimeMillis, cacheFlush,
+ ttlMillis);
+ this.servicePriority = servicePriority;
+ this.serviceWeight = serviceWeight;
+ this.servicePort = servicePort;
+ this.serviceHost = serviceHost;
}
/** Returns the service's port number. */
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsTextRecord.java b/service/mdns/com/android/server/connectivity/mdns/MdnsTextRecord.java
index 1e66589..4149dbe 100644
--- a/service/mdns/com/android/server/connectivity/mdns/MdnsTextRecord.java
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsTextRecord.java
@@ -33,7 +33,19 @@
private List<TextEntry> entries;
public MdnsTextRecord(String[] name, MdnsPacketReader reader) throws IOException {
- super(name, TYPE_TXT, reader);
+ this(name, reader, false);
+ }
+
+ public MdnsTextRecord(String[] name, MdnsPacketReader reader, boolean isQuestion)
+ throws IOException {
+ super(name, TYPE_TXT, reader, isQuestion);
+ }
+
+ public MdnsTextRecord(String[] name, long receiptTimeMillis, boolean cacheFlush, long ttlMillis,
+ List<TextEntry> entries) {
+ super(name, TYPE_TXT, MdnsConstants.QCLASS_INTERNET, receiptTimeMillis, cacheFlush,
+ ttlMillis);
+ this.entries = entries;
}
/** Returns the list of strings. */
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsRecordTests.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsRecordTests.java
index 9fc4674..9746a35 100644
--- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsRecordTests.java
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsRecordTests.java
@@ -79,14 +79,7 @@
Inet4Address addr = record.getInet4Address();
assertEquals("/10.1.2.3", addr.toString());
- // Encode
- MdnsPacketWriter writer = new MdnsPacketWriter(MAX_PACKET_SIZE);
- record.write(writer, record.getReceiptTime());
-
- packet = writer.getPacket(MULTICAST_IPV4_ADDRESS);
- byte[] dataOut = packet.getData();
-
- String dataOutText = HexDump.dumpHexString(dataOut, 0, packet.getLength());
+ String dataOutText = toHex(record);
Log.d(TAG, dataOutText);
assertEquals(dataInText, dataOutText);
@@ -123,14 +116,7 @@
Inet6Address addr = record.getInet6Address();
assertEquals("/aabb:ccdd:1122:3344:a0b0:c0d0:1020:3040", addr.toString());
- // Encode
- MdnsPacketWriter writer = new MdnsPacketWriter(MAX_PACKET_SIZE);
- record.write(writer, record.getReceiptTime());
-
- packet = writer.getPacket(MULTICAST_IPV6_ADDRESS);
- byte[] dataOut = packet.getData();
-
- String dataOutText = HexDump.dumpHexString(dataOut, 0, packet.getLength());
+ String dataOutText = toHex(record);
Log.d(TAG, dataOutText);
assertEquals(dataInText, dataOutText);
@@ -167,14 +153,7 @@
Inet4Address addr = record.getInet4Address();
assertEquals("/16.32.48.64", addr.toString());
- // Encode
- MdnsPacketWriter writer = new MdnsPacketWriter(MAX_PACKET_SIZE);
- record.write(writer, record.getReceiptTime());
-
- packet = writer.getPacket(MULTICAST_IPV4_ADDRESS);
- byte[] dataOut = packet.getData();
-
- String dataOutText = HexDump.dumpHexString(dataOut, 0, packet.getLength());
+ String dataOutText = toHex(record);
Log.d(TAG, dataOutText);
final byte[] expectedDataIn =
@@ -215,14 +194,7 @@
assertFalse(record.hasSubtype());
assertNull(record.getSubtype());
- // Encode
- MdnsPacketWriter writer = new MdnsPacketWriter(MAX_PACKET_SIZE);
- record.write(writer, record.getReceiptTime());
-
- packet = writer.getPacket(MULTICAST_IPV4_ADDRESS);
- byte[] dataOut = packet.getData();
-
- String dataOutText = HexDump.dumpHexString(dataOut, 0, packet.getLength());
+ String dataOutText = toHex(record);
Log.d(TAG, dataOutText);
assertEquals(dataInText, dataOutText);
@@ -263,14 +235,35 @@
assertEquals(1, record.getServicePriority());
assertEquals(255, record.getServiceWeight());
- // Encode
- MdnsPacketWriter writer = new MdnsPacketWriter(MAX_PACKET_SIZE);
- record.write(writer, record.getReceiptTime());
+ String dataOutText = toHex(record);
+ Log.d(TAG, dataOutText);
- packet = writer.getPacket(MULTICAST_IPV4_ADDRESS);
- byte[] dataOut = packet.getData();
+ assertEquals(dataInText, dataOutText);
+ }
- String dataOutText = HexDump.dumpHexString(dataOut, 0, packet.getLength());
+ @Test
+ public void testAnyRecord() throws IOException {
+ final byte[] dataIn = HexDump.hexStringToByteArray(
+ "047465737407616E64726F696403636F6D0000FF0001000000000000");
+ assertNotNull(dataIn);
+ String dataInText = HexDump.dumpHexString(dataIn, 0, dataIn.length);
+
+ // Decode
+ DatagramPacket packet = new DatagramPacket(dataIn, dataIn.length);
+ MdnsPacketReader reader = new MdnsPacketReader(packet);
+
+ String[] name = reader.readLabels();
+ assertNotNull(name);
+ assertEquals(3, name.length);
+ String fqdn = MdnsRecord.labelsToString(name);
+ assertEquals("test.android.com", fqdn);
+
+ int type = reader.readUInt16();
+ assertEquals(MdnsRecord.TYPE_ANY, type);
+
+ MdnsAnyRecord record = new MdnsAnyRecord(name, reader);
+
+ String dataOutText = toHex(record);
Log.d(TAG, dataOutText);
assertEquals(dataInText, dataOutText);
@@ -320,19 +313,23 @@
assertEquals(new TextEntry("b", "1234567890"), entries.get(1));
assertEquals(new TextEntry("xyz", "!@#$"), entries.get(2));
- // Encode
- MdnsPacketWriter writer = new MdnsPacketWriter(MAX_PACKET_SIZE);
- record.write(writer, record.getReceiptTime());
-
- packet = writer.getPacket(MULTICAST_IPV4_ADDRESS);
- byte[] dataOut = packet.getData();
-
- String dataOutText = HexDump.dumpHexString(dataOut, 0, packet.getLength());
+ String dataOutText = toHex(record);
Log.d(TAG, dataOutText);
assertEquals(dataInText, dataOutText);
}
+ private static String toHex(MdnsRecord record) throws IOException {
+ MdnsPacketWriter writer = new MdnsPacketWriter(MAX_PACKET_SIZE);
+ record.write(writer, record.getReceiptTime());
+
+ // The address does not matter as only the data is used
+ final DatagramPacket packet = writer.getPacket(MULTICAST_IPV4_ADDRESS);
+ final byte[] dataOut = packet.getData();
+
+ return HexDump.dumpHexString(dataOut, 0, packet.getLength());
+ }
+
@Test
public void textRecord_recordDoesNotHaveDataOfGivenLength_throwsEOFException()
throws Exception {