Support multiple IPv4 / IPv6 addresses in MdnsResponse
If the mDNS service has multiple IPv4 / IPv6 addresses, only the
last added address will be present on the response. Since the
NsdServiceInfo supports multiple host addresses in Android U, the
MdnsResponse should also support multiple IPv4 / IPv6 addresses
in favor of providing accurate service info to clients.
Check cache flush flag on the response when adding a new address
record. Per RFC6762 10.2, clear all address records if the
cache-flush bit set.
Bug: 268586836
Test: atest FrameworksNetTests
Change-Id: I04548a3f16837939f3131b84c1033377ff81d521
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsResponse.java b/service-t/src/com/android/server/connectivity/mdns/MdnsResponse.java
index a6e3762..be2555b 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsResponse.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsResponse.java
@@ -25,6 +25,7 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
@@ -36,8 +37,8 @@
private final List<MdnsPointerRecord> pointerRecords;
private MdnsServiceRecord serviceRecord;
private MdnsTextRecord textRecord;
- private MdnsInetAddressRecord inet4AddressRecord;
- private MdnsInetAddressRecord inet6AddressRecord;
+ @NonNull private List<MdnsInetAddressRecord> inet4AddressRecords;
+ @NonNull private List<MdnsInetAddressRecord> inet6AddressRecords;
private long lastUpdateTime;
private final int interfaceIndex;
@Nullable private final Network network;
@@ -49,6 +50,8 @@
lastUpdateTime = now;
records = new LinkedList<>();
pointerRecords = new LinkedList<>();
+ inet4AddressRecords = new ArrayList<>();
+ inet6AddressRecords = new ArrayList<>();
this.interfaceIndex = interfaceIndex;
this.network = network;
this.serviceName = serviceName;
@@ -59,8 +62,8 @@
pointerRecords = new ArrayList<>(base.pointerRecords);
serviceRecord = base.serviceRecord;
textRecord = base.textRecord;
- inet4AddressRecord = base.inet4AddressRecord;
- inet6AddressRecord = base.inet6AddressRecord;
+ inet4AddressRecords = new ArrayList<>(base.inet4AddressRecords);
+ inet6AddressRecords = new ArrayList<>(base.inet6AddressRecords);
lastUpdateTime = base.lastUpdateTime;
serviceName = base.serviceName;
interfaceIndex = base.interfaceIndex;
@@ -94,8 +97,8 @@
if (recordsAreSame(pointerRecord, pointerRecords.get(existing))) {
return false;
}
- pointerRecords.remove(existing);
- records.remove(existing);
+ final MdnsRecord record = pointerRecords.remove(existing);
+ records.remove(record);
}
pointerRecords.add(pointerRecord);
records.add(pointerRecord);
@@ -201,46 +204,60 @@
return textRecord != null;
}
- /** Sets the IPv4 address record. */
- public synchronized boolean setInet4AddressRecord(
- @Nullable MdnsInetAddressRecord newInet4AddressRecord) {
- if (recordsAreSame(this.inet4AddressRecord, newInet4AddressRecord)) {
- return false;
+ /** Add the IPv4 address record. */
+ public synchronized boolean addInet4AddressRecord(
+ @NonNull MdnsInetAddressRecord newInet4AddressRecord) {
+ final int existing = inet4AddressRecords.indexOf(newInet4AddressRecord);
+ if (existing >= 0) {
+ if (recordsAreSame(newInet4AddressRecord, inet4AddressRecords.get(existing))) {
+ return false;
+ }
+ final MdnsRecord record = inet4AddressRecords.remove(existing);
+ records.remove(record);
}
- if (this.inet4AddressRecord != null) {
- records.remove(this.inet4AddressRecord);
- this.inet4AddressRecord = null;
- }
- if (newInet4AddressRecord != null && newInet4AddressRecord.getInet4Address() != null) {
- this.inet4AddressRecord = newInet4AddressRecord;
- records.add(this.inet4AddressRecord);
- }
+ inet4AddressRecords.add(newInet4AddressRecord);
+ records.add(newInet4AddressRecord);
return true;
}
- /** Gets the IPv4 address record. */
+ /** Gets the IPv4 address records. */
+ @NonNull
+ public synchronized List<MdnsInetAddressRecord> getInet4AddressRecords() {
+ return Collections.unmodifiableList(inet4AddressRecords);
+ }
+
+ /** Return the first IPv4 address record or null if no record. */
+ @Nullable
public synchronized MdnsInetAddressRecord getInet4AddressRecord() {
- return inet4AddressRecord;
+ return inet4AddressRecords.isEmpty() ? null : inet4AddressRecords.get(0);
}
+ /** Check whether response has IPv4 address record */
public synchronized boolean hasInet4AddressRecord() {
- return inet4AddressRecord != null;
+ return !inet4AddressRecords.isEmpty();
}
- /** Sets the IPv6 address record. */
- public synchronized boolean setInet6AddressRecord(
- @Nullable MdnsInetAddressRecord newInet6AddressRecord) {
- if (recordsAreSame(this.inet6AddressRecord, newInet6AddressRecord)) {
- return false;
+ /** Clear all IPv4 address records */
+ synchronized void clearInet4AddressRecords() {
+ for (MdnsInetAddressRecord record : inet4AddressRecords) {
+ records.remove(record);
}
- if (this.inet6AddressRecord != null) {
- records.remove(this.inet6AddressRecord);
- this.inet6AddressRecord = null;
+ inet4AddressRecords.clear();
+ }
+
+ /** Sets the IPv6 address records. */
+ public synchronized boolean addInet6AddressRecord(
+ @NonNull MdnsInetAddressRecord newInet6AddressRecord) {
+ final int existing = inet6AddressRecords.indexOf(newInet6AddressRecord);
+ if (existing >= 0) {
+ if (recordsAreSame(newInet6AddressRecord, inet6AddressRecords.get(existing))) {
+ return false;
+ }
+ final MdnsRecord record = inet6AddressRecords.remove(existing);
+ records.remove(record);
}
- if (newInet6AddressRecord != null && newInet6AddressRecord.getInet6Address() != null) {
- this.inet6AddressRecord = newInet6AddressRecord;
- records.add(this.inet6AddressRecord);
- }
+ inet6AddressRecords.add(newInet6AddressRecord);
+ records.add(newInet6AddressRecord);
return true;
}
@@ -260,13 +277,28 @@
return network;
}
- /** Gets the IPv6 address record. */
- public synchronized MdnsInetAddressRecord getInet6AddressRecord() {
- return inet6AddressRecord;
+ /** Gets all IPv6 address records. */
+ public synchronized List<MdnsInetAddressRecord> getInet6AddressRecords() {
+ return Collections.unmodifiableList(inet6AddressRecords);
}
+ /** Return the first IPv6 address record or null if no record. */
+ @Nullable
+ public synchronized MdnsInetAddressRecord getInet6AddressRecord() {
+ return inet6AddressRecords.isEmpty() ? null : inet6AddressRecords.get(0);
+ }
+
+ /** Check whether response has IPv6 address record */
public synchronized boolean hasInet6AddressRecord() {
- return inet6AddressRecord != null;
+ return !inet6AddressRecords.isEmpty();
+ }
+
+ /** Clear all IPv6 address records */
+ synchronized void clearInet6AddressRecords() {
+ for (MdnsInetAddressRecord record : inet6AddressRecords) {
+ records.remove(record);
+ }
+ inet6AddressRecords.clear();
}
/** Gets all of the records. */
@@ -283,22 +315,22 @@
if (this.serviceRecord == null) return false;
boolean dropAddressRecords = false;
- if (this.inet4AddressRecord != null) {
+ for (MdnsInetAddressRecord inetAddressRecord : getInet4AddressRecords()) {
if (!Arrays.equals(
- this.serviceRecord.getServiceHost(), this.inet4AddressRecord.getName())) {
+ this.serviceRecord.getServiceHost(), inetAddressRecord.getName())) {
dropAddressRecords = true;
}
}
- if (this.inet6AddressRecord != null) {
+ for (MdnsInetAddressRecord inetAddressRecord : getInet6AddressRecords()) {
if (!Arrays.equals(
- this.serviceRecord.getServiceHost(), this.inet6AddressRecord.getName())) {
+ this.serviceRecord.getServiceHost(), inetAddressRecord.getName())) {
dropAddressRecords = true;
}
}
if (dropAddressRecords) {
- setInet4AddressRecord(null);
- setInet6AddressRecord(null);
+ clearInet4AddressRecords();
+ clearInet6AddressRecords();
return true;
}
return false;
@@ -312,7 +344,7 @@
public synchronized boolean isComplete() {
return (serviceRecord != null)
&& (textRecord != null)
- && (inet4AddressRecord != null || inet6AddressRecord != null);
+ && (!inet4AddressRecords.isEmpty() || !inet6AddressRecords.isEmpty());
}
/**
@@ -378,13 +410,13 @@
++count;
}
- if (inet4AddressRecord != null) {
- inet4AddressRecord.write(writer, now);
+ for (MdnsInetAddressRecord inetAddressRecord : inet4AddressRecords) {
+ inetAddressRecord.write(writer, now);
++count;
}
- if (inet6AddressRecord != null) {
- inet6AddressRecord.write(writer, now);
+ for (MdnsInetAddressRecord inetAddressRecord : inet6AddressRecords) {
+ inetAddressRecord.write(writer, now);
++count;
}
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsResponseDecoder.java b/service-t/src/com/android/server/connectivity/mdns/MdnsResponseDecoder.java
index 7878b0b..0151202 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsResponseDecoder.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsResponseDecoder.java
@@ -205,39 +205,79 @@
}
}
- // Loop 3: find A and AAAA records, which reference the host name in the SRV record.
+ // Loop 3-1: find A and AAAA records and clear addresses if the cache-flush bit set, which
+ // reference the host name in the SRV record.
+ final List<MdnsInetAddressRecord> inetRecords = new ArrayList<>();
for (MdnsRecord record : records) {
if (record instanceof MdnsInetAddressRecord) {
MdnsInetAddressRecord inetRecord = (MdnsInetAddressRecord) record;
+ inetRecords.add(inetRecord);
if (allowMultipleSrvRecordsPerHost) {
List<MdnsResponse> matchingResponses =
findResponsesWithHostName(responses, inetRecord.getName());
for (MdnsResponse response : matchingResponses) {
- if (assignInetRecord(response, inetRecord)) {
- modified.add(response);
+ // Per RFC6762 10.2, clear all address records if the cache-flush bit set.
+ // This bit, the cache-flush bit, tells neighboring hosts
+ // that this is not a shared record type. Instead of merging this new
+ // record additively into the cache in addition to any previous records with
+ // the same name, rrtype, and rrclass, all old records with that name,
+ // rrtype, and rrclass that were received more than one second ago are
+ // declared invalid, and marked to expire from the cache in one second.
+ if (inetRecord.getCacheFlush()) {
+ response.clearInet4AddressRecords();
+ response.clearInet6AddressRecords();
}
}
} else {
MdnsResponse response =
findResponseWithHostName(responses, inetRecord.getName());
if (response != null) {
- if (assignInetRecord(response, inetRecord)) {
- modified.add(response);
+ // Per RFC6762 10.2, clear all address records if the cache-flush bit set.
+ // This bit, the cache-flush bit, tells neighboring hosts
+ // that this is not a shared record type. Instead of merging this new
+ // record additively into the cache in addition to any previous records with
+ // the same name, rrtype, and rrclass, all old records with that name,
+ // rrtype, and rrclass that were received more than one second ago are
+ // declared invalid, and marked to expire from the cache in one second.
+ if (inetRecord.getCacheFlush()) {
+ response.clearInet4AddressRecords();
+ response.clearInet6AddressRecords();
}
}
}
}
}
+ // Loop 3-2: Assign addresses, which reference the host name in the SRV record.
+ for (MdnsInetAddressRecord inetRecord : inetRecords) {
+ if (allowMultipleSrvRecordsPerHost) {
+ List<MdnsResponse> matchingResponses =
+ findResponsesWithHostName(responses, inetRecord.getName());
+ for (MdnsResponse response : matchingResponses) {
+ if (assignInetRecord(response, inetRecord)) {
+ modified.add(response);
+ }
+ }
+ } else {
+ MdnsResponse response =
+ findResponseWithHostName(responses, inetRecord.getName());
+ if (response != null) {
+ if (assignInetRecord(response, inetRecord)) {
+ modified.add(response);
+ }
+ }
+ }
+ }
+
return modified;
}
private static boolean assignInetRecord(
MdnsResponse response, MdnsInetAddressRecord inetRecord) {
if (inetRecord.getInet4Address() != null) {
- return response.setInet4AddressRecord(inetRecord);
+ return response.addInet4AddressRecord(inetRecord);
} else if (inetRecord.getInet6Address() != null) {
- return response.setInet6AddressRecord(inetRecord);
+ return response.addInet6AddressRecord(inetRecord);
}
return false;
}
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsServiceInfo.java b/service-t/src/com/android/server/connectivity/mdns/MdnsServiceInfo.java
index 938fc3f..606d3f8 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsServiceInfo.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsServiceInfo.java
@@ -57,8 +57,8 @@
source.createStringArrayList(),
source.createStringArray(),
source.readInt(),
- source.readString(),
- source.readString(),
+ source.createStringArrayList(),
+ source.createStringArrayList(),
source.createStringArrayList(),
source.createTypedArrayList(TextEntry.CREATOR),
source.readInt(),
@@ -76,10 +76,10 @@
private final List<String> subtypes;
private final String[] hostName;
private final int port;
- @Nullable
- private final String ipv4Address;
- @Nullable
- private final String ipv6Address;
+ @NonNull
+ private final List<String> ipv4Addresses;
+ @NonNull
+ private final List<String> ipv6Addresses;
final List<String> textStrings;
@Nullable
final List<TextEntry> textEntries;
@@ -105,8 +105,8 @@
subtypes,
hostName,
port,
- ipv4Address,
- ipv6Address,
+ List.of(ipv4Address),
+ List.of(ipv6Address),
textStrings,
/* textEntries= */ null,
/* interfaceIndex= */ INTERFACE_INDEX_UNSPECIFIED,
@@ -130,8 +130,8 @@
subtypes,
hostName,
port,
- ipv4Address,
- ipv6Address,
+ List.of(ipv4Address),
+ List.of(ipv6Address),
textStrings,
textEntries,
/* interfaceIndex= */ INTERFACE_INDEX_UNSPECIFIED,
@@ -160,8 +160,8 @@
subtypes,
hostName,
port,
- ipv4Address,
- ipv6Address,
+ List.of(ipv4Address),
+ List.of(ipv6Address),
textStrings,
textEntries,
interfaceIndex,
@@ -179,8 +179,8 @@
@Nullable List<String> subtypes,
String[] hostName,
int port,
- @Nullable String ipv4Address,
- @Nullable String ipv6Address,
+ @NonNull List<String> ipv4Addresses,
+ @NonNull List<String> ipv6Addresses,
@Nullable List<String> textStrings,
@Nullable List<TextEntry> textEntries,
int interfaceIndex,
@@ -193,8 +193,8 @@
}
this.hostName = hostName;
this.port = port;
- this.ipv4Address = ipv4Address;
- this.ipv6Address = ipv6Address;
+ this.ipv4Addresses = new ArrayList<>(ipv4Addresses);
+ this.ipv6Addresses = new ArrayList<>(ipv6Addresses);
this.textStrings = new ArrayList<>();
if (textStrings != null) {
this.textStrings.addAll(textStrings);
@@ -263,16 +263,41 @@
return port;
}
- /** Returns the IPV4 address of this service instance. */
+ /** Returns the IPV4 addresses of this service instance. */
+ @NonNull
+ public List<String> getIpv4Addresses() {
+ return Collections.unmodifiableList(ipv4Addresses);
+ }
+
+ /**
+ * Returns the first IPV4 address of this service instance.
+ *
+ * @deprecated Use {@link #getIpv4Addresses()} to get the entire list of IPV4
+ * addresses for
+ * the host.
+ */
@Nullable
+ @Deprecated
public String getIpv4Address() {
- return ipv4Address;
+ return ipv4Addresses.isEmpty() ? null : ipv4Addresses.get(0);
}
/** Returns the IPV6 address of this service instance. */
+ @NonNull
+ public List<String> getIpv6Addresses() {
+ return Collections.unmodifiableList(ipv6Addresses);
+ }
+
+ /**
+ * Returns the first IPV6 address of this service instance.
+ *
+ * @deprecated Use {@link #getIpv6Addresses()} to get the entire list of IPV6 addresses for
+ * the host.
+ */
@Nullable
+ @Deprecated
public String getIpv6Address() {
- return ipv6Address;
+ return ipv6Addresses.isEmpty() ? null : ipv6Addresses.get(0);
}
/**
@@ -336,8 +361,8 @@
out.writeStringList(subtypes);
out.writeStringArray(hostName);
out.writeInt(port);
- out.writeString(ipv4Address);
- out.writeString(ipv6Address);
+ out.writeStringList(ipv4Addresses);
+ out.writeStringList(ipv6Addresses);
out.writeStringList(textStrings);
out.writeTypedList(textEntries);
out.writeInt(interfaceIndex);
@@ -346,13 +371,16 @@
@Override
public String toString() {
- return String.format(
- Locale.ROOT,
- "Name: %s, subtypes: %s, ip: %s, port: %d",
- serviceInstanceName,
- TextUtils.join(",", subtypes),
- ipv4Address,
- port);
+ return "Name: " + serviceInstanceName
+ + ", type: " + TextUtils.join(".", serviceType)
+ + ", subtypes: " + TextUtils.join(",", subtypes)
+ + ", ip: " + ipv4Addresses
+ + ", ipv6: " + ipv6Addresses
+ + ", port: " + port
+ + ", interfaceIndex: " + interfaceIndex
+ + ", network: " + network
+ + ", textStrings: " + textStrings
+ + ", textEntries: " + textEntries;
}
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsServiceTypeClient.java b/service-t/src/com/android/server/connectivity/mdns/MdnsServiceTypeClient.java
index f886948..df270bb 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsServiceTypeClient.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsServiceTypeClient.java
@@ -115,15 +115,19 @@
port = response.getServiceRecord().getServicePort();
}
- String ipv4Address = null;
- String ipv6Address = null;
+ final List<String> ipv4Addresses = new ArrayList<>();
+ final List<String> ipv6Addresses = new ArrayList<>();
if (response.hasInet4AddressRecord()) {
- Inet4Address inet4Address = response.getInet4AddressRecord().getInet4Address();
- ipv4Address = (inet4Address == null) ? null : inet4Address.getHostAddress();
+ for (MdnsInetAddressRecord inetAddressRecord : response.getInet4AddressRecords()) {
+ final Inet4Address inet4Address = inetAddressRecord.getInet4Address();
+ ipv4Addresses.add((inet4Address == null) ? null : inet4Address.getHostAddress());
+ }
}
if (response.hasInet6AddressRecord()) {
- Inet6Address inet6Address = response.getInet6AddressRecord().getInet6Address();
- ipv6Address = (inet6Address == null) ? null : inet6Address.getHostAddress();
+ for (MdnsInetAddressRecord inetAddressRecord : response.getInet6AddressRecords()) {
+ final Inet6Address inet6Address = inetAddressRecord.getInet6Address();
+ ipv6Addresses.add((inet6Address == null) ? null : inet6Address.getHostAddress());
+ }
}
String serviceInstanceName = response.getServiceInstanceName();
if (serviceInstanceName == null) {
@@ -143,8 +147,8 @@
response.getSubtypes(),
hostName,
port,
- ipv4Address,
- ipv6Address,
+ ipv4Addresses,
+ ipv6Addresses,
textStrings,
textEntries,
response.getInterfaceIndex(),
diff --git a/tests/unit/java/com/android/server/NsdServiceTest.java b/tests/unit/java/com/android/server/NsdServiceTest.java
index 053212b..1fd4439 100644
--- a/tests/unit/java/com/android/server/NsdServiceTest.java
+++ b/tests/unit/java/com/android/server/NsdServiceTest.java
@@ -895,8 +895,8 @@
List.of(), /* subtypes */
new String[] {"android", "local"}, /* hostName */
12345, /* port */
- IPV4_ADDRESS,
- IPV6_ADDRESS,
+ List.of(IPV4_ADDRESS),
+ List.of(IPV6_ADDRESS),
List.of(), /* textStrings */
List.of(), /* textEntries */
1234, /* interfaceIndex */
@@ -915,8 +915,8 @@
null, /* subtypes */
null, /* hostName */
0, /* port */
- null, /* ipv4Address */
- null, /* ipv6Address */
+ List.of(), /* ipv4Address */
+ List.of(), /* ipv6Address */
null, /* textStrings */
null, /* textEntries */
1234, /* interfaceIndex */
@@ -992,8 +992,8 @@
List.of(), /* subtypes */
new String[]{"android", "local"}, /* hostName */
PORT,
- IPV4_ADDRESS,
- IPV6_ADDRESS,
+ List.of(IPV4_ADDRESS),
+ List.of(IPV6_ADDRESS),
List.of() /* textStrings */,
List.of(MdnsServiceInfo.TextEntry.fromBytes(new byte[]{
'k', 'e', 'y', '=', (byte) 0xFF, (byte) 0xFE})) /* textEntries */,
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseDecoderTests.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseDecoderTests.java
index d83c0dd..a80c078 100644
--- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseDecoderTests.java
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseDecoderTests.java
@@ -158,16 +158,16 @@
// MDNS record for name "testhost1" with an IPv4 address of 10.1.2.3
private static final byte[] DATAIN_IPV4_1 = HexDump.hexStringToByteArray(
- "0974657374686f73743100000100010000007800040a010203");
+ "0974657374686f73743100000180010000007800040a010203");
// MDNS record for name "testhost1" with an IPv4 address of 10.1.2.4
private static final byte[] DATAIN_IPV4_2 = HexDump.hexStringToByteArray(
- "0974657374686f73743100000100010000007800040a010204");
+ "0974657374686f73743100000180010000007800040a010204");
// MDNS record w/name "testhost1" & IPv6 address of aabb:ccdd:1122:3344:a0b0:c0d0:1020:3040
private static final byte[] DATAIN_IPV6_1 = HexDump.hexStringToByteArray(
- "0974657374686f73743100001c0001000000780010aabbccdd11223344a0b0c0d010203040");
+ "0974657374686f73743100001c8001000000780010aabbccdd11223344a0b0c0d010203040");
// MDNS record w/name "testhost1" & IPv6 address of aabb:ccdd:1122:3344:a0b0:c0d0:1020:3030
private static final byte[] DATAIN_IPV6_2 = HexDump.hexStringToByteArray(
- "0974657374686f73743100001c0001000000780010aabbccdd11223344a0b0c0d010203030");
+ "0974657374686f73743100001c8001000000780010aabbccdd11223344a0b0c0d010203030");
// MDNS record w/name "test" & PTR to foo.bar.quxx
private static final byte[] DATAIN_PTR_1 = HexDump.hexStringToByteArray(
"047465737400000C000100001194000E03666F6F03626172047175787800");
@@ -295,15 +295,15 @@
assertTrue(response.isComplete());
response = new MdnsResponse(responses.valueAt(0));
- response.setInet4AddressRecord(null);
+ response.clearInet4AddressRecords();
assertFalse(response.isComplete());
- response.setInet6AddressRecord(new MdnsInetAddressRecord(new String[] { "testhostname" },
+ response.addInet6AddressRecord(new MdnsInetAddressRecord(new String[] { "testhostname" },
0L /* receiptTimeMillis */, false /* cacheFlush */, 1234L /* ttlMillis */,
parseNumericAddress("2008:db1::123")));
assertTrue(response.isComplete());
- response.setInet6AddressRecord(null);
+ response.clearInet6AddressRecords();
assertFalse(response.isComplete());
response = new MdnsResponse(responses.valueAt(0));
@@ -356,10 +356,12 @@
assertTrue(response2.isComplete());
// And should both have the same IPv6 address:
- assertEquals(parseNumericAddress("2605:a601:a846:5700:3e61:5ff:fe0c:89f8"),
- response1.getInet6AddressRecord().getInet6Address());
- assertEquals(parseNumericAddress("2605:a601:a846:5700:3e61:5ff:fe0c:89f8"),
- response2.getInet6AddressRecord().getInet6Address());
+ assertTrue(response1.getInet6AddressRecords().stream().anyMatch(
+ record -> record.getInet6Address().equals(
+ parseNumericAddress("2605:a601:a846:5700:3e61:5ff:fe0c:89f8"))));
+ assertTrue(response2.getInet6AddressRecords().stream().anyMatch(
+ record -> record.getInet6Address().equals(
+ parseNumericAddress("2605:a601:a846:5700:3e61:5ff:fe0c:89f8"))));
}
@Test
@@ -514,9 +516,9 @@
reader.skip(2); // skip record type indication.
// Apply the right kind of record to the response.
if (responseData.recordClass == MdnsInet4AddressRecord.class) {
- response.setInet4AddressRecord(new MdnsInet4AddressRecord(name, reader));
+ response.addInet4AddressRecord(new MdnsInet4AddressRecord(name, reader));
} else if (responseData.recordClass == MdnsInet6AddressRecord.class) {
- response.setInet6AddressRecord(new MdnsInet6AddressRecord(name, reader));
+ response.addInet6AddressRecord(new MdnsInet6AddressRecord(name, reader));
} else if (responseData.recordClass == MdnsPointerRecord.class) {
response.addPointerRecord(new MdnsPointerRecord(name, reader));
} else if (responseData.recordClass == MdnsServiceRecord.class) {
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseTests.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseTests.java
index 132a822..3f5e7a1 100644
--- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseTests.java
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseTests.java
@@ -108,10 +108,10 @@
0 /* serviceWeight */, 0 /* servicePort */, hostname));
response.setTextRecord(new MdnsTextRecord(serviceName, 0L /* receiptTimeMillis */,
true /* cacheFlush */, recordsTtlMillis, emptyList() /* entries */));
- response.setInet4AddressRecord(new MdnsInetAddressRecord(
+ response.addInet4AddressRecord(new MdnsInetAddressRecord(
hostname, 0L /* receiptTimeMillis */, true /* cacheFlush */,
recordsTtlMillis, parseNumericAddress("192.0.2.123")));
- response.setInet6AddressRecord(new MdnsInetAddressRecord(
+ response.addInet6AddressRecord(new MdnsInetAddressRecord(
hostname, 0L /* receiptTimeMillis */, true /* cacheFlush */,
recordsTtlMillis, parseNumericAddress("2001:db8::123")));
return response;
@@ -126,7 +126,7 @@
MdnsInetAddressRecord record = new MdnsInetAddressRecord(name, MdnsRecord.TYPE_A, reader);
MdnsResponse response = new MdnsResponse(0, TEST_SERVICE_NAME, INTERFACE_INDEX, mNetwork);
assertFalse(response.hasInet4AddressRecord());
- assertTrue(response.setInet4AddressRecord(record));
+ assertTrue(response.addInet4AddressRecord(record));
assertEquals(response.getInet4AddressRecord(), record);
}
@@ -140,7 +140,7 @@
new MdnsInetAddressRecord(name, MdnsRecord.TYPE_AAAA, reader);
MdnsResponse response = new MdnsResponse(0, TEST_SERVICE_NAME, INTERFACE_INDEX, mNetwork);
assertFalse(response.hasInet6AddressRecord());
- assertTrue(response.setInet6AddressRecord(record));
+ assertTrue(response.addInet6AddressRecord(record));
assertEquals(response.getInet6AddressRecord(), record);
}
@@ -228,8 +228,8 @@
final MdnsResponse response = makeCompleteResponse(TEST_TTL_MS);
assertFalse(response.addPointerRecord(response.getPointerRecords().get(0)));
- assertFalse(response.setInet6AddressRecord(response.getInet6AddressRecord()));
- assertFalse(response.setInet4AddressRecord(response.getInet4AddressRecord()));
+ assertFalse(response.addInet6AddressRecord(response.getInet6AddressRecord()));
+ assertFalse(response.addInet4AddressRecord(response.getInet4AddressRecord()));
assertFalse(response.setServiceRecord(response.getServiceRecord()));
assertFalse(response.setTextRecord(response.getTextRecord()));
}
@@ -245,12 +245,14 @@
assertTrue(response.getRecords().stream().anyMatch(r ->
r == response.getPointerRecords().get(0)));
- assertTrue(response.setInet6AddressRecord(ttlZeroResponse.getInet6AddressRecord()));
+ assertTrue(response.addInet6AddressRecord(ttlZeroResponse.getInet6AddressRecord()));
+ assertEquals(1, response.getInet6AddressRecords().size());
assertEquals(0, response.getInet6AddressRecord().getTtl());
assertTrue(response.getRecords().stream().anyMatch(r ->
r == response.getInet6AddressRecord()));
- assertTrue(response.setInet4AddressRecord(ttlZeroResponse.getInet4AddressRecord()));
+ assertTrue(response.addInet4AddressRecord(ttlZeroResponse.getInet4AddressRecord()));
+ assertEquals(1, response.getInet4AddressRecords().size());
assertEquals(0, response.getInet4AddressRecord().getTtl());
assertTrue(response.getRecords().stream().anyMatch(r ->
r == response.getInet4AddressRecord()));
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceInfoTest.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceInfoTest.java
index 76728cf..a4e03a8 100644
--- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceInfoTest.java
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceInfoTest.java
@@ -177,8 +177,8 @@
List.of(),
new String[] {"my-host", "local"},
12345,
- "192.168.1.1",
- "2001::1",
+ List.of("192.168.1.1"),
+ List.of("2001::1"),
List.of(),
/* textEntries= */ null,
/* interfaceIndex= */ 20,
@@ -197,8 +197,8 @@
List.of(),
new String[] {"my-host", "local"},
12345,
- "192.168.1.1",
- "2001::1",
+ List.of("192.168.1.1", "192.168.1.2"),
+ List.of("2001::1", "2001::2"),
List.of("vn=Alphabet Inc.", "mn=Google Nest Hub Max", "id=12345"),
List.of(
MdnsServiceInfo.TextEntry.fromString("vn=Google Inc."),
@@ -217,7 +217,9 @@
assertArrayEquals(beforeParcel.getHostName(), afterParcel.getHostName());
assertEquals(beforeParcel.getPort(), afterParcel.getPort());
assertEquals(beforeParcel.getIpv4Address(), afterParcel.getIpv4Address());
+ assertEquals(beforeParcel.getIpv4Addresses(), afterParcel.getIpv4Addresses());
assertEquals(beforeParcel.getIpv6Address(), afterParcel.getIpv6Address());
+ assertEquals(beforeParcel.getIpv6Addresses(), afterParcel.getIpv6Addresses());
assertEquals(beforeParcel.getAttributes(), afterParcel.getAttributes());
assertEquals(beforeParcel.getInterfaceIndex(), afterParcel.getInterfaceIndex());
assertEquals(beforeParcel.getNetwork(), afterParcel.getNetwork());
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java
index a5c6123..d9fa10f 100644
--- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java
@@ -420,13 +420,13 @@
}
private static void verifyServiceInfo(MdnsServiceInfo serviceInfo, String serviceName,
- String[] serviceType, String ipv4Address, String ipv6Address, int port,
+ String[] serviceType, List<String> ipv4Addresses, List<String> ipv6Addresses, int port,
List<String> subTypes, Map<String, String> attributes, int interfaceIndex,
Network network) {
assertEquals(serviceName, serviceInfo.getServiceInstanceName());
assertArrayEquals(serviceType, serviceInfo.getServiceType());
- assertEquals(ipv4Address, serviceInfo.getIpv4Address());
- assertEquals(ipv6Address, serviceInfo.getIpv6Address());
+ assertEquals(ipv4Addresses, serviceInfo.getIpv4Addresses());
+ assertEquals(ipv6Addresses, serviceInfo.getIpv6Addresses());
assertEquals(port, serviceInfo.getPort());
assertEquals(subTypes, serviceInfo.getSubtypes());
for (String key : attributes.keySet()) {
@@ -449,8 +449,8 @@
verifyServiceInfo(serviceInfoCaptor.getAllValues().get(0),
"service-instance-1",
SERVICE_TYPE_LABELS,
- /* ipv4Address= */ null,
- /* ipv6Address= */ null,
+ /* ipv4Address= */ List.of(),
+ /* ipv6Address= */ List.of(),
/* port= */ 0,
/* subTypes= */ List.of(),
Collections.emptyMap(),
@@ -484,8 +484,8 @@
verifyServiceInfo(serviceInfoCaptor.getAllValues().get(0),
"service-instance-1",
SERVICE_TYPE_LABELS,
- ipV4Address /* ipv4Address */,
- null /* ipv6Address */,
+ List.of(ipV4Address) /* ipv4Address */,
+ List.of() /* ipv6Address */,
5353 /* port */,
Collections.singletonList("ABCDE") /* subTypes */,
Collections.singletonMap("key", null) /* attributes */,
@@ -539,8 +539,8 @@
verifyServiceInfo(serviceInfoCaptor.getAllValues().get(0),
"service-instance-1",
SERVICE_TYPE_LABELS,
- null /* ipv4Address */,
- ipV6Address /* ipv6Address */,
+ List.of() /* ipv4Address */,
+ List.of(ipV6Address) /* ipv6Address */,
5353 /* port */,
Collections.singletonList("ABCDE") /* subTypes */,
Collections.singletonMap("key", null) /* attributes */,
@@ -638,8 +638,8 @@
verifyServiceInfo(serviceInfoCaptor.getAllValues().get(0),
"service-instance-1",
SERVICE_TYPE_LABELS,
- "192.168.1.1" /* ipv4Address */,
- null /* ipv6Address */,
+ List.of("192.168.1.1") /* ipv4Address */,
+ List.of() /* ipv6Address */,
5353 /* port */,
Collections.singletonList("ABCDE") /* subTypes */,
Collections.singletonMap("key", null) /* attributes */,
@@ -834,8 +834,8 @@
verifyServiceInfo(serviceInfoCaptor.getAllValues().get(0),
serviceName,
SERVICE_TYPE_LABELS,
- null /* ipv4Address */,
- null /* ipv6Address */,
+ List.of() /* ipv4Address */,
+ List.of() /* ipv6Address */,
5353 /* port */,
Collections.singletonList(subtype) /* subTypes */,
Collections.singletonMap("key", null) /* attributes */,
@@ -847,8 +847,8 @@
verifyServiceInfo(serviceInfoCaptor.getAllValues().get(1),
serviceName,
SERVICE_TYPE_LABELS,
- ipV4Address /* ipv4Address */,
- null /* ipv6Address */,
+ List.of(ipV4Address) /* ipv4Address */,
+ List.of() /* ipv6Address */,
5353 /* port */,
Collections.singletonList(subtype) /* subTypes */,
Collections.singletonMap("key", null) /* attributes */,
@@ -860,8 +860,8 @@
verifyServiceInfo(serviceInfoCaptor.getAllValues().get(2),
serviceName,
SERVICE_TYPE_LABELS,
- ipV4Address /* ipv4Address */,
- ipV6Address /* ipv6Address */,
+ List.of(ipV4Address) /* ipv4Address */,
+ List.of(ipV6Address) /* ipv6Address */,
5354 /* port */,
Collections.singletonList(subtype) /* subTypes */,
Collections.singletonMap("key", "value") /* attributes */,
@@ -873,8 +873,8 @@
verifyServiceInfo(serviceInfoCaptor.getAllValues().get(3),
serviceName,
SERVICE_TYPE_LABELS,
- ipV4Address /* ipv4Address */,
- ipV6Address /* ipv6Address */,
+ List.of(ipV4Address) /* ipv4Address */,
+ List.of(ipV6Address) /* ipv6Address */,
5354 /* port */,
Collections.singletonList("ABCDE") /* subTypes */,
Collections.singletonMap("key", "value") /* attributes */,
@@ -886,8 +886,8 @@
verifyServiceInfo(serviceInfoCaptor.getAllValues().get(4),
serviceName,
SERVICE_TYPE_LABELS,
- ipV4Address /* ipv4Address */,
- ipV6Address /* ipv6Address */,
+ List.of(ipV4Address) /* ipv4Address */,
+ List.of(ipV6Address) /* ipv6Address */,
5354 /* port */,
Collections.singletonList("ABCDE") /* subTypes */,
Collections.singletonMap("key", "value") /* attributes */,
@@ -982,8 +982,8 @@
verifyServiceInfo(serviceInfoCaptor.getValue(),
instanceName,
SERVICE_TYPE_LABELS,
- ipV4Address,
- ipV6Address,
+ List.of(ipV4Address),
+ List.of(ipV6Address),
1234 /* port */,
Collections.emptyList() /* subTypes */,
Collections.emptyMap() /* attributes */,