Merge "Skip presubmit for flaky tests in NetworkStackIntegrationTests due to Out of SLO" into main
diff --git a/Android.bp b/Android.bp
index c3887ed..b8e60df 100644
--- a/Android.bp
+++ b/Android.bp
@@ -506,6 +506,9 @@
srcs: [
"jni/network_stack_utils_jni.cpp"
],
+ header_libs: [
+ "bpf_headers",
+ ],
sdk_version: "30",
min_sdk_version: "30",
shared_libs: [
diff --git a/OWNERS b/OWNERS
index 62c5737..c24680e 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,2 +1,2 @@
set noparent
-file:platform/packages/modules/Connectivity:master:/OWNERS_core_networking
+file:platform/packages/modules/Connectivity:main:/OWNERS_core_networking
diff --git a/jni/network_stack_utils_jni.cpp b/jni/network_stack_utils_jni.cpp
index 5d84f57..b5d97be 100644
--- a/jni/network_stack_utils_jni.cpp
+++ b/jni/network_stack_utils_jni.cpp
@@ -36,6 +36,7 @@
#include <netjniutils/netjniutils.h>
#include <android/log.h>
+#include <bpf/BpfClassic.h>
namespace android {
constexpr const char NETWORKSTACKUTILS_PKG_NAME[] =
@@ -102,25 +103,22 @@
static void network_stack_utils_attachDhcpFilter(JNIEnv *env, jclass clazz, jobject javaFd) {
static sock_filter filter_code[] = {
// Check the protocol is UDP.
- BPF_STMT(BPF_LD | BPF_B | BPF_ABS, kIPv4Protocol),
- BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, IPPROTO_UDP, 0, 6),
+ BPF_LOAD_IPV4_U8(protocol),
+ BPF2_REJECT_IF_NOT_EQUAL(IPPROTO_UDP),
// Check this is not a fragment.
- BPF_STMT(BPF_LD | BPF_H | BPF_ABS, kIPv4FlagsOffset),
- BPF_JUMP(BPF_JMP | BPF_JSET | BPF_K, IP_MF | IP_OFFMASK, 4, 0),
+ BPF_LOAD_IPV4_BE16(frag_off),
+ BPF_JUMP(BPF_JMP | BPF_JSET | BPF_K, IP_MF | IP_OFFMASK, 0, 1),
+ BPF_REJECT,
// Get the IP header length.
BPF_STMT(BPF_LDX | BPF_B | BPF_MSH, kEtherHeaderLen),
// Check the destination port.
BPF_STMT(BPF_LD | BPF_H | BPF_IND, kUDPDstPortIndirectOffset),
- BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, kDhcpClientPort, 0, 1),
+ BPF2_REJECT_IF_NOT_EQUAL(kDhcpClientPort),
- // Accept.
- BPF_STMT(BPF_RET | BPF_K, 0xffff),
-
- // Reject.
- BPF_STMT(BPF_RET | BPF_K, 0)
+ BPF_ACCEPT,
};
const sock_fprog filter = {
sizeof(filter_code) / sizeof(filter_code[0]),
@@ -133,28 +131,17 @@
}
}
-static void network_stack_utils_attachRaFilter(JNIEnv *env, jclass clazz, jobject javaFd,
- jint hardwareAddressType) {
- if (hardwareAddressType != ARPHRD_ETHER) {
- jniThrowExceptionFmt(env, "java/net/SocketException",
- "attachRaFilter only supports ARPHRD_ETHER");
- return;
- }
-
+static void network_stack_utils_attachRaFilter(JNIEnv *env, jclass clazz, jobject javaFd) {
static sock_filter filter_code[] = {
// Check IPv6 Next Header is ICMPv6.
- BPF_STMT(BPF_LD | BPF_B | BPF_ABS, kIPv6NextHeader),
- BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, IPPROTO_ICMPV6, 0, 3),
+ BPF_LOAD_IPV6_U8(nexthdr),
+ BPF2_REJECT_IF_NOT_EQUAL(IPPROTO_ICMPV6),
// Check ICMPv6 type is Router Advertisement.
- BPF_STMT(BPF_LD | BPF_B | BPF_ABS, kICMPv6TypeOffset),
- BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, ND_ROUTER_ADVERT, 0, 1),
+ BPF_LOAD_NET_RELATIVE_U8(sizeof(ipv6hdr) + offsetof(icmp6_hdr, icmp6_type)),
+ BPF2_REJECT_IF_NOT_EQUAL(ND_ROUTER_ADVERT),
- // Accept.
- BPF_STMT(BPF_RET | BPF_K, 0xffff),
-
- // Reject.
- BPF_STMT(BPF_RET | BPF_K, 0)
+ BPF_ACCEPT,
};
static const sock_fprog filter = {
sizeof(filter_code) / sizeof(filter_code[0]),
@@ -227,11 +214,9 @@
BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, ND_ROUTER_SOLICIT, 0, 2),
BPF_JUMP(BPF_JMP | BPF_JGT | BPF_K, ND_NEIGHBOR_ADVERT, 1, 0),
- // Accept.
- BPF_STMT(BPF_RET | BPF_K, 0xffff),
+ BPF_ACCEPT,
- // Reject.
- BPF_STMT(BPF_RET | BPF_K, 0)
+ BPF_REJECT,
};
static const sock_fprog filter = {
sizeof(filter_code) / sizeof(filter_code[0]),
@@ -252,7 +237,7 @@
/* name, signature, funcPtr */
{ "addArpEntry", "([B[BLjava/lang/String;Ljava/io/FileDescriptor;)V", (void*) network_stack_utils_addArpEntry },
{ "attachDhcpFilter", "(Ljava/io/FileDescriptor;)V", (void*) network_stack_utils_attachDhcpFilter },
- { "attachRaFilter", "(Ljava/io/FileDescriptor;I)V", (void*) network_stack_utils_attachRaFilter },
+ { "attachRaFilter", "(Ljava/io/FileDescriptor;)V", (void*) network_stack_utils_attachRaFilter },
{ "attachControlPacketFilter", "(Ljava/io/FileDescriptor;I)V", (void*) network_stack_utils_attachControlPacketFilter },
};
diff --git a/src/android/net/apf/ApfFilter.java b/src/android/net/apf/ApfFilter.java
index 3689cee..5c8ff49 100644
--- a/src/android/net/apf/ApfFilter.java
+++ b/src/android/net/apf/ApfFilter.java
@@ -322,6 +322,8 @@
private static final int ICMP6_TYPE_OFFSET = ETH_HEADER_LEN + IPV6_HEADER_LEN;
+ private static final int IPPROTO_HOPOPTS = 0;
+
// NOTE: this must be added to the IPv4 header length in IPV4_HEADER_SIZE_MEMORY_SLOT
private static final int UDP_DESTINATION_PORT_OFFSET = ETH_HEADER_LEN + 2;
private static final int UDP_HEADER_LEN = 8;
@@ -535,7 +537,7 @@
socket = Os.socket(AF_PACKET, SOCK_RAW, ETH_P_IPV6);
SocketAddress addr = makePacketSocketAddress(ETH_P_IPV6, mInterfaceParams.index);
Os.bind(socket, addr);
- NetworkStackUtils.attachRaFilter(socket, mApfCapabilities.apfPacketFormat);
+ NetworkStackUtils.attachRaFilter(socket);
} catch(SocketException|ErrnoException e) {
Log.e(TAG, "Error starting filter", e);
return;
@@ -1486,6 +1488,8 @@
private void generateIPv6FilterLocked(ApfGenerator gen) throws IllegalInstructionException {
// Here's a basic summary of what the IPv6 filter program does:
//
+ // if there is a hop-by-hop option present (e.g. MLD query)
+ // pass
// if we're dropping multicast
// if it's not IPCMv6 or it's ICMPv6 but we're in doze mode:
// if it's multicast:
@@ -1500,6 +1504,10 @@
gen.addLoad8(Register.R0, IPV6_NEXT_HEADER_OFFSET);
+ // MLD packets set the router-alert hop-by-hop option.
+ // TODO: be smarter about not blindly passing every packet with HBH options.
+ gen.addJumpIfR0Equals(IPPROTO_HOPOPTS, mCountAndPassLabel);
+
// Drop multicast if the multicast filter is enabled.
if (mMulticastFilter) {
final String skipIPv6MulticastFilterLabel = "skipIPv6MulticastFilter";
@@ -1594,7 +1602,9 @@
// Here's a basic summary of what the mDNS filter program does:
//
// if it is a multicast mDNS packet
- // if QDCOUNT > 1 and the first QNAME is in the allowlist
+ // if QDCOUNT != 1
+ // pass
+ // else if the QNAME is in the allowlist
// pass
// else:
// drop
@@ -1645,11 +1655,11 @@
gen.addLoad16Indexed(Register.R0, UDP_DESTINATION_PORT_OFFSET);
gen.addJumpIfR0NotEquals(MDNS_PORT, skipMdnsFilter);
- // Only do the QNAME check if the QDCOUNT is more than 0.
- // If there is more than one query (QDCOUNT > 1), we only matches the first QNAME.
gen.addLoad16Indexed(Register.R0, MDNS_QDCOUNT_OFFSET);
- gen.addJumpIfR0Equals(0, mDnsDropPacket);
+ // If QDCOUNT != 1, pass the packet
+ gen.addJumpIfR0NotEquals(1, mDnsAcceptPacket);
+ // If QDCOUNT == 1, matches the QNAME with allowlist.
// Load offset for the first QNAME.
gen.addLoadImmediate(Register.R0, MDNS_QNAME_OFFSET);
gen.addAddR1();
diff --git a/src/android/net/dhcp6/Dhcp6AdvertisePacket.java b/src/android/net/dhcp6/Dhcp6AdvertisePacket.java
index a9fac83..263ab5f 100644
--- a/src/android/net/dhcp6/Dhcp6AdvertisePacket.java
+++ b/src/android/net/dhcp6/Dhcp6AdvertisePacket.java
@@ -34,7 +34,7 @@
*/
Dhcp6AdvertisePacket(int transId, @NonNull final byte[] clientDuid,
@NonNull final byte[] serverDuid, final byte[] iapd) {
- super(transId, (short) 0 /* secs */, clientDuid, serverDuid, iapd);
+ super(transId, 0 /* elapsedTime */, clientDuid, serverDuid, iapd);
}
/**
diff --git a/src/android/net/dhcp6/Dhcp6Client.java b/src/android/net/dhcp6/Dhcp6Client.java
index 975c2c5..8bda0d3 100644
--- a/src/android/net/dhcp6/Dhcp6Client.java
+++ b/src/android/net/dhcp6/Dhcp6Client.java
@@ -292,37 +292,35 @@
mTransStartMillis = SystemClock.elapsedRealtime();
}
- private short getHundredthsOfSec() {
- return (short) ((SystemClock.elapsedRealtime() - mTransStartMillis) / 10);
+ private long getElapsedTimeMs() {
+ return SystemClock.elapsedRealtime() - mTransStartMillis;
}
@SuppressWarnings("ByteBufferBackingArray")
private boolean sendSolicitPacket(final ByteBuffer iapd) {
final ByteBuffer packet = Dhcp6Packet.buildSolicitPacket(mTransId,
- getHundredthsOfSec() /* elapsed time */, iapd.array(), mClientDuid,
- true /* rapidCommit */);
+ getElapsedTimeMs(), iapd.array(), mClientDuid, true /* rapidCommit */);
return transmitPacket(packet, "solicit");
}
@SuppressWarnings("ByteBufferBackingArray")
private boolean sendRequestPacket(final ByteBuffer iapd) {
- final ByteBuffer packet = Dhcp6Packet.buildRequestPacket(mTransId,
- getHundredthsOfSec() /* elapsed time */, iapd.array(), mClientDuid,
- mServerDuid);
+ final ByteBuffer packet = Dhcp6Packet.buildRequestPacket(mTransId, getElapsedTimeMs(),
+ iapd.array(), mClientDuid, mServerDuid);
return transmitPacket(packet, "request");
}
@SuppressWarnings("ByteBufferBackingArray")
private boolean sendRenewPacket(final ByteBuffer iapd) {
- final ByteBuffer packet = Dhcp6Packet.buildRenewPacket(mTransId,
- getHundredthsOfSec() /* elapsed time*/, iapd.array(), mClientDuid, mServerDuid);
+ final ByteBuffer packet = Dhcp6Packet.buildRenewPacket(mTransId, getElapsedTimeMs(),
+ iapd.array(), mClientDuid, mServerDuid);
return transmitPacket(packet, "renew");
}
@SuppressWarnings("ByteBufferBackingArray")
private boolean sendRebindPacket(final ByteBuffer iapd) {
- final ByteBuffer packet = Dhcp6Packet.buildRebindPacket(mTransId,
- getHundredthsOfSec() /* elapsed time */, iapd.array(), mClientDuid);
+ final ByteBuffer packet = Dhcp6Packet.buildRebindPacket(mTransId, getElapsedTimeMs(),
+ iapd.array(), mClientDuid);
return transmitPacket(packet, "rebind");
}
diff --git a/src/android/net/dhcp6/Dhcp6Packet.java b/src/android/net/dhcp6/Dhcp6Packet.java
index 9682556..c82b7ed 100644
--- a/src/android/net/dhcp6/Dhcp6Packet.java
+++ b/src/android/net/dhcp6/Dhcp6Packet.java
@@ -80,7 +80,7 @@
* This time is expressed in hundredths of a second.
*/
public static final byte DHCP6_ELAPSED_TIME = 8;
- protected final short mSecs;
+ protected final int mElapsedTime;
/**
* DHCPv6 Optional Type: Status Code.
@@ -123,10 +123,10 @@
*/
protected int mIaId;
- Dhcp6Packet(int transId, short secs, @NonNull final byte[] clientDuid, final byte[] serverDuid,
- @NonNull final byte[] iapd) {
+ Dhcp6Packet(int transId, int elapsedTime, @NonNull final byte[] clientDuid,
+ final byte[] serverDuid, @NonNull final byte[] iapd) {
mTransId = transId;
- mSecs = secs;
+ mElapsedTime = elapsedTime;
mClientDuid = clientDuid;
mServerDuid = serverDuid;
mIaPd = iapd;
@@ -250,7 +250,7 @@
*/
@VisibleForTesting
static Dhcp6Packet decodePacket(@NonNull final ByteBuffer packet) throws ParseException {
- short secs = 0;
+ int elapsedTime = 0;
byte[] iapd = null;
byte[] serverDuid = null;
byte[] clientDuid = null;
@@ -308,7 +308,7 @@
break;
case DHCP6_ELAPSED_TIME:
expectedLen = 2;
- secs = packet.getShort();
+ elapsedTime = (int) (packet.getShort() & 0xFFFF);
break;
case DHCP6_STATUS_CODE:
expectedLen = optionLen;
@@ -335,23 +335,26 @@
switch(messageType) {
case DHCP6_MESSAGE_TYPE_SOLICIT:
- newPacket = new Dhcp6SolicitPacket(transId, secs, clientDuid, iapd, rapidCommit);
+ newPacket = new Dhcp6SolicitPacket(transId, elapsedTime, clientDuid, iapd,
+ rapidCommit);
break;
case DHCP6_MESSAGE_TYPE_ADVERTISE:
newPacket = new Dhcp6AdvertisePacket(transId, clientDuid, serverDuid, iapd);
break;
case DHCP6_MESSAGE_TYPE_REQUEST:
- newPacket = new Dhcp6RequestPacket(transId, secs, clientDuid, serverDuid, iapd);
+ newPacket = new Dhcp6RequestPacket(transId, elapsedTime, clientDuid, serverDuid,
+ iapd);
break;
case DHCP6_MESSAGE_TYPE_REPLY:
newPacket = new Dhcp6ReplyPacket(transId, clientDuid, serverDuid, iapd,
rapidCommit);
break;
case DHCP6_MESSAGE_TYPE_RENEW:
- newPacket = new Dhcp6RenewPacket(transId, secs, clientDuid, serverDuid, iapd);
+ newPacket = new Dhcp6RenewPacket(transId, elapsedTime, clientDuid, serverDuid,
+ iapd);
break;
case DHCP6_MESSAGE_TYPE_REBIND:
- newPacket = new Dhcp6RebindPacket(transId, secs, clientDuid, iapd);
+ newPacket = new Dhcp6RebindPacket(transId, elapsedTime, clientDuid, iapd);
break;
default:
throw new ParseException("Unimplemented DHCP6 message type %d" + messageType);
@@ -524,10 +527,11 @@
/**
* Builds a DHCPv6 SOLICIT packet from the required specified parameters.
*/
- public static ByteBuffer buildSolicitPacket(int transId, short secs, @NonNull final byte[] iapd,
- @NonNull final byte[] clientDuid, boolean rapidCommit) {
+ public static ByteBuffer buildSolicitPacket(int transId, long millisecs,
+ @NonNull final byte[] iapd, @NonNull final byte[] clientDuid, boolean rapidCommit) {
final Dhcp6SolicitPacket pkt =
- new Dhcp6SolicitPacket(transId, secs, clientDuid, iapd, rapidCommit);
+ new Dhcp6SolicitPacket(transId, (int) (millisecs / 10) /* elapsed time */,
+ clientDuid, iapd, rapidCommit);
return pkt.buildPacket();
}
@@ -555,29 +559,34 @@
/**
* Builds a DHCPv6 REQUEST packet from the required specified parameters.
*/
- public static ByteBuffer buildRequestPacket(int transId, short secs, @NonNull final byte[] iapd,
- @NonNull final byte[] clientDuid, @NonNull final byte[] serverDuid) {
+ public static ByteBuffer buildRequestPacket(int transId, long millisecs,
+ @NonNull final byte[] iapd, @NonNull final byte[] clientDuid,
+ @NonNull final byte[] serverDuid) {
final Dhcp6RequestPacket pkt =
- new Dhcp6RequestPacket(transId, secs, clientDuid, serverDuid, iapd);
+ new Dhcp6RequestPacket(transId, (int) (millisecs / 10) /* elapsed time */,
+ clientDuid, serverDuid, iapd);
return pkt.buildPacket();
}
/**
* Builds a DHCPv6 RENEW packet from the required specified parameters.
*/
- public static ByteBuffer buildRenewPacket(int transId, short secs, @NonNull final byte[] iapd,
- @NonNull final byte[] clientDuid, @NonNull final byte[] serverDuid) {
+ public static ByteBuffer buildRenewPacket(int transId, long millisecs,
+ @NonNull final byte[] iapd, @NonNull final byte[] clientDuid,
+ @NonNull final byte[] serverDuid) {
final Dhcp6RenewPacket pkt =
- new Dhcp6RenewPacket(transId, secs, clientDuid, serverDuid, iapd);
+ new Dhcp6RenewPacket(transId, (int) (millisecs / 10) /* elapsed time */, clientDuid,
+ serverDuid, iapd);
return pkt.buildPacket();
}
/**
* Builds a DHCPv6 REBIND packet from the required specified parameters.
*/
- public static ByteBuffer buildRebindPacket(int transId, short secs, @NonNull final byte[] iapd,
- @NonNull final byte[] clientDuid) {
- final Dhcp6RebindPacket pkt = new Dhcp6RebindPacket(transId, secs, clientDuid, iapd);
+ public static ByteBuffer buildRebindPacket(int transId, long millisecs,
+ @NonNull final byte[] iapd, @NonNull final byte[] clientDuid) {
+ final Dhcp6RebindPacket pkt = new Dhcp6RebindPacket(transId,
+ (int) (millisecs / 10) /* elapsed time */, clientDuid, iapd);
return pkt.buildPacket();
}
}
diff --git a/src/android/net/dhcp6/Dhcp6RebindPacket.java b/src/android/net/dhcp6/Dhcp6RebindPacket.java
index 33a9fc1..87f2f45 100644
--- a/src/android/net/dhcp6/Dhcp6RebindPacket.java
+++ b/src/android/net/dhcp6/Dhcp6RebindPacket.java
@@ -33,9 +33,9 @@
/**
* Generates a rebind packet with the specified parameters.
*/
- Dhcp6RebindPacket(int transId, short secs, @NonNull final byte[] clientDuid,
+ Dhcp6RebindPacket(int transId, int elapsedTime, @NonNull final byte[] clientDuid,
@NonNull final byte[] iapd) {
- super(transId, secs, clientDuid, null /* serverDuid */, iapd);
+ super(transId, elapsedTime, clientDuid, null /* serverDuid */, iapd);
}
/**
@@ -47,7 +47,7 @@
packet.putInt(msgTypeAndTransId);
addTlv(packet, DHCP6_CLIENT_IDENTIFIER, getClientDuid());
- addTlv(packet, DHCP6_ELAPSED_TIME, mSecs);
+ addTlv(packet, DHCP6_ELAPSED_TIME, (short) (mElapsedTime & 0xFFFF));
addTlv(packet, DHCP6_IA_PD, mIaPd);
packet.flip();
diff --git a/src/android/net/dhcp6/Dhcp6RenewPacket.java b/src/android/net/dhcp6/Dhcp6RenewPacket.java
index 3de73df..8c6686c 100644
--- a/src/android/net/dhcp6/Dhcp6RenewPacket.java
+++ b/src/android/net/dhcp6/Dhcp6RenewPacket.java
@@ -33,9 +33,9 @@
/**
* Generates a renew packet with the specified parameters.
*/
- Dhcp6RenewPacket(int transId, short secs, @NonNull final byte[] clientDuid,
+ Dhcp6RenewPacket(int transId, int elapsedTime, @NonNull final byte[] clientDuid,
@NonNull final byte[] serverDuid, final byte[] iapd) {
- super(transId, secs, clientDuid, serverDuid, iapd);
+ super(transId, elapsedTime, clientDuid, serverDuid, iapd);
}
/**
@@ -48,7 +48,7 @@
addTlv(packet, DHCP6_SERVER_IDENTIFIER, mServerDuid);
addTlv(packet, DHCP6_CLIENT_IDENTIFIER, mClientDuid);
- addTlv(packet, DHCP6_ELAPSED_TIME, mSecs);
+ addTlv(packet, DHCP6_ELAPSED_TIME, (short) (mElapsedTime & 0xFFFF));
addTlv(packet, DHCP6_IA_PD, mIaPd);
packet.flip();
diff --git a/src/android/net/dhcp6/Dhcp6ReplyPacket.java b/src/android/net/dhcp6/Dhcp6ReplyPacket.java
index 15f748b..d68fbdb 100644
--- a/src/android/net/dhcp6/Dhcp6ReplyPacket.java
+++ b/src/android/net/dhcp6/Dhcp6ReplyPacket.java
@@ -35,7 +35,7 @@
*/
Dhcp6ReplyPacket(int transId, @NonNull final byte[] clientDuid,
@NonNull final byte[] serverDuid, final byte[] iapd, boolean rapidCommit) {
- super(transId, (short) 0 /* secs */, clientDuid, serverDuid, iapd);
+ super(transId, 0 /* elapsedTime */, clientDuid, serverDuid, iapd);
mRapidCommit = rapidCommit;
}
diff --git a/src/android/net/dhcp6/Dhcp6RequestPacket.java b/src/android/net/dhcp6/Dhcp6RequestPacket.java
index 5671502..0c65f17 100644
--- a/src/android/net/dhcp6/Dhcp6RequestPacket.java
+++ b/src/android/net/dhcp6/Dhcp6RequestPacket.java
@@ -32,9 +32,9 @@
/**
* Generates a request packet with the specified parameters.
*/
- Dhcp6RequestPacket(int transId, short secs, @NonNull final byte[] clientDuid,
+ Dhcp6RequestPacket(int transId, int elapsedTime, @NonNull final byte[] clientDuid,
@NonNull final byte[] serverDuid, final byte[] iapd) {
- super(transId, secs, clientDuid, serverDuid, iapd);
+ super(transId, elapsedTime, clientDuid, serverDuid, iapd);
}
/**
@@ -47,7 +47,7 @@
addTlv(packet, DHCP6_SERVER_IDENTIFIER, mServerDuid);
addTlv(packet, DHCP6_CLIENT_IDENTIFIER, mClientDuid);
- addTlv(packet, DHCP6_ELAPSED_TIME, mSecs);
+ addTlv(packet, DHCP6_ELAPSED_TIME, (short) (mElapsedTime & 0xFFFF));
addTlv(packet, DHCP6_IA_PD, mIaPd);
packet.flip();
diff --git a/src/android/net/dhcp6/Dhcp6SolicitPacket.java b/src/android/net/dhcp6/Dhcp6SolicitPacket.java
index 69dc81e..4916c1e 100644
--- a/src/android/net/dhcp6/Dhcp6SolicitPacket.java
+++ b/src/android/net/dhcp6/Dhcp6SolicitPacket.java
@@ -31,9 +31,9 @@
/**
* Generates a solicit packet with the specified parameters.
*/
- Dhcp6SolicitPacket(int transId, short secs, @NonNull final byte[] clientDuid,
+ Dhcp6SolicitPacket(int transId, int elapsedTime, @NonNull final byte[] clientDuid,
final byte[] iapd, boolean rapidCommit) {
- super(transId, secs, clientDuid, null /* serverDuid */, iapd);
+ super(transId, elapsedTime, clientDuid, null /* serverDuid */, iapd);
mRapidCommit = rapidCommit;
}
@@ -45,7 +45,7 @@
final int msgTypeAndTransId = (DHCP6_MESSAGE_TYPE_SOLICIT << 24) | mTransId;
packet.putInt(msgTypeAndTransId);
- addTlv(packet, DHCP6_ELAPSED_TIME, mSecs);
+ addTlv(packet, DHCP6_ELAPSED_TIME, (short) (mElapsedTime & 0xFFFF));
addTlv(packet, DHCP6_CLIENT_IDENTIFIER, mClientDuid);
addTlv(packet, DHCP6_IA_PD, mIaPd);
if (mRapidCommit) {
diff --git a/src/android/net/ip/IpClient.java b/src/android/net/ip/IpClient.java
index b3a0652..c169ad5 100644
--- a/src/android/net/ip/IpClient.java
+++ b/src/android/net/ip/IpClient.java
@@ -2814,11 +2814,10 @@
// Delete the global IPv6 address based on delegated prefix from interface.
for (LinkAddress la : mLinkProperties.getLinkAddresses()) {
- if (!la.isIpv6()) continue;
- final Inet6Address address = (Inet6Address) la.getAddress();
- if (la.isIpv6() && prefix.contains(address)) {
- NetlinkUtils.sendRtmDelAddressRequest(mInterfaceParams.index, address,
- (short) la.getPrefixLength());
+ final InetAddress address = la.getAddress();
+ if (prefix.contains(address)) {
+ NetlinkUtils.sendRtmDelAddressRequest(mInterfaceParams.index,
+ (Inet6Address) address, (short) la.getPrefixLength());
}
}
}
diff --git a/src/com/android/networkstack/util/NetworkStackUtils.java b/src/com/android/networkstack/util/NetworkStackUtils.java
index 8559a26..8fb157c 100755
--- a/src/com/android/networkstack/util/NetworkStackUtils.java
+++ b/src/com/android/networkstack/util/NetworkStackUtils.java
@@ -385,9 +385,8 @@
/**
* Attaches a socket filter that accepts ICMPv6 router advertisements to the given socket.
* @param fd the socket's {@link FileDescriptor}.
- * @param packetType the hardware address type, one of ARPHRD_*.
*/
- public static native void attachRaFilter(FileDescriptor fd, int packetType)
+ public static native void attachRaFilter(FileDescriptor fd)
throws SocketException;
/**
diff --git a/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java b/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java
index d6b6c96..246d0d4 100644
--- a/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java
+++ b/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java
@@ -4852,6 +4852,8 @@
x -> x.isIpv6Provisioned()
&& hasIpv6AddressPrefixedWith(x, prefix)
&& hasRouteTo(x, "2001:db8:1::/64", RTN_UNREACHABLE)
+ // IPv4 address, IPv6 link-local, two global delegated IPv6 addresses
+ && x.getLinkAddresses().size() == 4
));
}
diff --git a/tests/integration/signature/android/net/util/NetworkStackUtilsIntegrationTest.kt b/tests/integration/signature/android/net/util/NetworkStackUtilsIntegrationTest.kt
index cf514e9..2377ffa 100644
--- a/tests/integration/signature/android/net/util/NetworkStackUtilsIntegrationTest.kt
+++ b/tests/integration/signature/android/net/util/NetworkStackUtilsIntegrationTest.kt
@@ -176,7 +176,7 @@
echo.rewind()
assertNextPacketEquals(socket, echo.readAsArray(), "ICMPv6 echo")
- NetworkStackUtils.attachRaFilter(socket, ARPHRD_ETHER)
+ NetworkStackUtils.attachRaFilter(socket)
// Send another echo, then an RA. After setting the filter expect only the RA.
echo.rewind()
reader.sendResponse(echo)
diff --git a/tests/unit/res/raw/apfPcap.pcap b/tests/unit/res/raw/apfPcap.pcap
index 6f69c4a..0206d25 100644
--- a/tests/unit/res/raw/apfPcap.pcap
+++ b/tests/unit/res/raw/apfPcap.pcap
Binary files differ
diff --git a/tests/unit/src/android/net/apf/ApfTest.java b/tests/unit/src/android/net/apf/ApfTest.java
index 285fcb4..f1719c3 100644
--- a/tests/unit/src/android/net/apf/ApfTest.java
+++ b/tests/unit/src/android/net/apf/ApfTest.java
@@ -1552,6 +1552,16 @@
program = ipClientCallback.getApfProgram();
assertPass(program, mdnsv4packet);
assertPass(program, mdnsv6packet);
+ // If packet contains more than one qname, pass the packet
+ mdnsv4packet = makeMdnsV4Packet("cccc.local", "dddd.local");
+ mdnsv6packet = makeMdnsV6Packet("cccc.local", "dddd.local");
+ assertPass(program, mdnsv4packet);
+ assertPass(program, mdnsv6packet);
+ // If packet doesn't contain any qname, pass the packet
+ mdnsv4packet = makeMdnsV4Packet();
+ mdnsv6packet = makeMdnsV6Packet();
+ assertPass(program, mdnsv4packet);
+ assertPass(program, mdnsv6packet);
mdnsv4packet = makeMdnsV4Packet("abcd.local");
mdnsv6packet = makeMdnsV6Packet("abcd.local");
diff --git a/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java b/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
index 19c9e5e..4cf6f34 100644
--- a/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
+++ b/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
@@ -90,7 +90,6 @@
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.times;
@@ -578,7 +577,7 @@
return null;
}).when(mContext).unregisterReceiver(any());
- resetCallbacks();
+ initCallbacks(11 /* interfaceVersion */);
setMinDataStallEvaluateInterval(TEST_MIN_STALL_EVALUATE_INTERVAL_MS);
setDataStallEvaluationType(DATA_STALL_EVALUATION_TYPE_DNS);
@@ -609,12 +608,7 @@
}
}
- private void resetCallbacks() throws Exception {
- resetCallbacks(11);
- }
-
- private void resetCallbacks(int interfaceVersion) throws Exception {
- reset(mCallbacks);
+ private void initCallbacks(int interfaceVersion) throws Exception {
try {
doReturn(interfaceVersion).when(mCallbacks).getInterfaceVersion();
} catch (RemoteException e) {
@@ -1025,7 +1019,6 @@
verify(mContext, times(1)).registerReceiver(receiverCaptor.capture(),
argThat(receiver -> ACTION_CONFIGURATION_CHANGED.equals(receiver.getAction(0))));
- resetCallbacks();
// New URLs with partial connectivity
doReturn(TEST_HTTPS_OTHER_URL1).when(mResources).getString(
R.string.config_captive_portal_https_url);
@@ -1039,7 +1032,8 @@
HandlerUtils.waitForIdle(nm.getHandler(), HANDLER_TIMEOUT_MS);
verifyNetworkTested(NETWORK_VALIDATION_RESULT_PARTIAL,
- NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP);
+ NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP,
+ 1 /* interactions */);
verify(mOtherHttpsConnection1, times(1)).getResponseCode();
verify(mOtherHttpConnection1, times(1)).getResponseCode();
}
@@ -1311,7 +1305,7 @@
assertTrue(INITIAL_REEVALUATE_DELAY_MS < 2000);
verify(mOtherFallbackConnection, timeout(INITIAL_REEVALUATE_DELAY_MS + HANDLER_TIMEOUT_MS))
.getResponseCode();
- verifyNetworkTested(VALIDATION_RESULT_PORTAL, 0 /* probesSucceeded */, TEST_LOGIN_URL);
+ verifyNetworkTestedPortal(TEST_LOGIN_URL, 1 /* interactions */);
}
@Test
@@ -1403,8 +1397,7 @@
+ "'user-portal-url': '" + TEST_LOGIN_URL + "'}");
nm.notifyLinkPropertiesChanged(makeCapportLPs());
- verifyNetworkTested(VALIDATION_RESULT_PORTAL, 0 /* probesSucceeded */,
- TEST_LOGIN_URL);
+ verifyNetworkTestedPortal(TEST_LOGIN_URL, 1 /* interactions */);
final ArgumentCaptor<CaptivePortalData> capportCaptor = ArgumentCaptor.forClass(
CaptivePortalData.class);
verify(mCallbacks).notifyCaptivePortalDataChanged(capportCaptor.capture());
@@ -1435,7 +1428,7 @@
// After notifyNetworkConnected, validation uses the capport API contents
notifyNetworkConnected(nm, lp, CELL_METERED_CAPABILITIES);
- verifyNetworkTested(VALIDATION_RESULT_PORTAL, 0 /* probesSucceeded */, TEST_LOGIN_URL);
+ verifyNetworkTestedPortal(TEST_LOGIN_URL, 1 /* interactions */);
verify(mHttpConnection, never()).getResponseCode();
verify(mCapportApiConnection).getResponseCode();
@@ -1555,25 +1548,19 @@
NETWORK_VALIDATION_RESULT_VALID,
NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS, null);
- resetCallbacks();
// Underlying network changed.
notifyUnderlyingNetworkChange(nm, nc , List.of(new Network(TEST_NETID)));
// The underlying network change should cause a re-validation
- verifyNetworkTested(NETWORK_VALIDATION_RESULT_VALID,
- NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS);
+ verifyNetworkTestedValidFromHttps(1 /* interactions */);
- resetCallbacks();
notifyUnderlyingNetworkChange(nm, nc , List.of(new Network(TEST_NETID)));
- // Identical networks should not cause revalidation.
- verify(mCallbacks, never()).notifyNetworkTestedWithExtras(matchNetworkTestResultParcelable(
- NETWORK_VALIDATION_RESULT_VALID,
- NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS));
+ // Identical networks should not cause revalidation. The interaction stays in 1 time which
+ // is verified in runNetworkTest.
+ verifyNetworkTestedValidFromHttps(1 /* interactions */);
- resetCallbacks();
// Change to another network
notifyUnderlyingNetworkChange(nm, nc , List.of(new Network(TEST_NETID2)));
- verifyNetworkTested(NETWORK_VALIDATION_RESULT_VALID,
- NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS);
+ verifyNetworkTestedValidFromHttps(2 /* interactions */);
}
private void notifyUnderlyingNetworkChange(NetworkMonitor nm, NetworkCapabilities nc,
@@ -1974,7 +1961,7 @@
@Test
public void testNoInternetCapabilityValidated_OlderPlatform() throws Exception {
// Before callbacks version 11, NETWORK_VALIDATION_RESULT_SKIPPED is not sent
- resetCallbacks(10);
+ initCallbacks(10);
doValidationSkippedTest(CELL_NO_INTERNET_CAPABILITIES, NETWORK_VALIDATION_RESULT_VALID);
}
@@ -2127,8 +2114,6 @@
// Portal URL should be detection URL.
final String redirectUrl = bundle.getString(ConnectivityManager.EXTRA_CAPTIVE_PORTAL_URL);
assertEquals(expectedUrl, redirectUrl);
-
- resetCallbacks();
}
@@ -2206,29 +2191,25 @@
wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns6.google",
new InetAddress[0]));
notifyNetworkConnected(wnm, CELL_NOT_METERED_CAPABILITIES);
- verifyNetworkTested(NETWORK_VALIDATION_RESULT_VALID, PROBES_PRIVDNS_VALID);
- verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyProbeStatusChanged(
- eq(PROBES_PRIVDNS_VALID), eq(PROBES_PRIVDNS_VALID));
+ verifyNetworkTestedValidFromPrivateDns(1 /* interactions */);
+ verifyProbeStatusChangedPrivateDnsCompleteAndSucceeded(1 /* interaction */);
// Verify dns query only get v4 address.
- resetCallbacks();
mFakeDns.setAnswer("dns4.google", new String[]{"192.0.2.1"}, TYPE_A);
wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns4.google",
new InetAddress[0]));
- verifyNetworkTested(NETWORK_VALIDATION_RESULT_VALID, PROBES_PRIVDNS_VALID);
+ verifyNetworkTestedValidFromPrivateDns(2 /* interactions */);
// NetworkMonitor will check if the probes has changed or not, if the probes has not
- // changed, the callback won't be fired.
- verify(mCallbacks, never()).notifyProbeStatusChanged(
- eq(PROBES_PRIVDNS_VALID), eq(PROBES_PRIVDNS_VALID));
+ // changed, the callback won't be fired. The interaction stays in 1 time.
+ verifyProbeStatusChangedPrivateDnsCompleteAndSucceeded(1 /* interaction */);
// Verify dns query get both v4 and v6 address.
- resetCallbacks();
mFakeDns.setAnswer("dns.google", new String[]{"2001:db8::54"}, TYPE_AAAA);
mFakeDns.setAnswer("dns.google", new String[]{"192.0.2.3"}, TYPE_A);
wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.google", new InetAddress[0]));
- verifyNetworkTested(NETWORK_VALIDATION_RESULT_VALID, PROBES_PRIVDNS_VALID);
- verify(mCallbacks, never()).notifyProbeStatusChanged(
- eq(PROBES_PRIVDNS_VALID), eq(PROBES_PRIVDNS_VALID));
+ verifyNetworkTestedValidFromPrivateDns(3 /* interactions */);
+ // Verify no further interaction.
+ verifyProbeStatusChangedPrivateDnsCompleteAndSucceeded(1 /* interaction */);
}
@Test
@@ -2240,22 +2221,18 @@
WrappedNetworkMonitor wnm = makeCellNotMeteredNetworkMonitor();
wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.google", new InetAddress[0]));
notifyNetworkConnected(wnm, CELL_NOT_METERED_CAPABILITIES);
- verifyNetworkTested(VALIDATION_RESULT_INVALID,
- NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS);
- verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS)).notifyProbeStatusChanged(
- eq(PROBES_PRIVDNS_VALID), eq(NETWORK_VALIDATION_PROBE_DNS
- | NETWORK_VALIDATION_PROBE_HTTPS));
+ verifyNetworkTestedInvalidFromHttps(1 /* interactions */);
+ verifyProbeStatusChangedPrivateDnsCompleteAndHttpsSucceeded(1 /* interaction */);
+
// Fix DNS and retry, expect validation to succeed.
- resetCallbacks();
mFakeDns.setAnswer("dns.google", new String[]{"2001:db8::1"}, TYPE_AAAA);
wnm.forceReevaluation(Process.myUid());
// ProbeCompleted should be reset to 0
HandlerUtils.waitForIdle(wnm.getHandler(), HANDLER_TIMEOUT_MS);
assertEquals(wnm.getEvaluationState().getProbeCompletedResult(), 0);
- verifyNetworkTested(NETWORK_VALIDATION_RESULT_VALID, PROBES_PRIVDNS_VALID);
- verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS)).notifyProbeStatusChanged(
- eq(PROBES_PRIVDNS_VALID), eq(PROBES_PRIVDNS_VALID));
+ verifyNetworkTestedValidFromPrivateDns(1 /* interactions */);
+ verifyProbeStatusChangedPrivateDnsCompleteAndSucceeded(1 /* interaction */);
}
@Test
@@ -2267,57 +2244,40 @@
WrappedNetworkMonitor wnm = makeCellNotMeteredNetworkMonitor();
wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.google", new InetAddress[0]));
notifyNetworkConnected(wnm, CELL_NOT_METERED_CAPABILITIES);
- verifyNetworkTested(VALIDATION_RESULT_INVALID,
- NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS);
- verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyProbeStatusChanged(
- eq(PROBES_PRIVDNS_VALID), eq(NETWORK_VALIDATION_PROBE_DNS
- | NETWORK_VALIDATION_PROBE_HTTPS));
+ verifyNetworkTestedInvalidFromHttps(1 /* interactions */);
+ verifyProbeStatusChangedPrivateDnsCompleteAndHttpsSucceeded(1 /* interactions */);
// Fix DNS and retry, expect validation to succeed.
- resetCallbacks();
mFakeDns.setAnswer("dns.google", new String[]{"2001:db8::1"}, TYPE_AAAA);
wnm.forceReevaluation(Process.myUid());
- verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).atLeastOnce())
- .notifyNetworkTestedWithExtras(matchNetworkTestResultParcelable(
- NETWORK_VALIDATION_RESULT_VALID, PROBES_PRIVDNS_VALID));
- verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyProbeStatusChanged(
- eq(PROBES_PRIVDNS_VALID), eq(PROBES_PRIVDNS_VALID));
+ verifyNetworkTestedValidFromPrivateDns(1 /* interactions */);
+ verifyProbeStatusChangedPrivateDnsCompleteAndSucceeded(1 /* interaction */);
// Change configuration to an invalid DNS name, expect validation to fail.
- resetCallbacks();
mFakeDns.setAnswer("dns.bad", new String[0], TYPE_A);
mFakeDns.setAnswer("dns.bad", new String[0], TYPE_AAAA);
wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.bad", new InetAddress[0]));
// Strict mode hostname resolve fail. Expect only notification for evaluation fail. No probe
// notification.
- verifyNetworkTested(VALIDATION_RESULT_INVALID,
- NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS);
- verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyProbeStatusChanged(
- eq(PROBES_PRIVDNS_VALID), eq(NETWORK_VALIDATION_PROBE_DNS
- | NETWORK_VALIDATION_PROBE_HTTPS));
+ verifyNetworkTestedInvalidFromHttps(2 /* interactions */);
+ verifyProbeStatusChangedPrivateDnsCompleteAndHttpsSucceeded(2 /* interaction */);
// Change configuration back to working again, but make private DNS not work.
// Expect validation to fail.
- resetCallbacks();
mFakeDns.setNonBypassPrivateDnsWorking(false);
wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.google",
new InetAddress[0]));
- verifyNetworkTested(VALIDATION_RESULT_INVALID,
- NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS);
+ verifyNetworkTestedInvalidFromHttps(3 /* interactions */);
// NetworkMonitor will check if the probes has changed or not, if the probes has not
- // changed, the callback won't be fired.
- verify(mCallbacks, never()).notifyProbeStatusChanged(
- eq(PROBES_PRIVDNS_VALID), eq(NETWORK_VALIDATION_PROBE_DNS
- | NETWORK_VALIDATION_PROBE_HTTPS));
+ // changed, the callback won't be fired. No further interaction.
+ verifyProbeStatusChangedPrivateDnsCompleteAndHttpsSucceeded(2 /* interaction */);
// Make private DNS work again. Expect validation to succeed.
- resetCallbacks();
mFakeDns.setNonBypassPrivateDnsWorking(true);
wnm.forceReevaluation(Process.myUid());
- verifyNetworkTested(NETWORK_VALIDATION_RESULT_VALID, PROBES_PRIVDNS_VALID);
- verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyProbeStatusChanged(
- eq(PROBES_PRIVDNS_VALID), eq(PROBES_PRIVDNS_VALID));
+ verifyNetworkTestedValidFromPrivateDns(1 /* interactions */);
+ verifyProbeStatusChangedPrivateDnsCompleteAndSucceeded(1 /* interaction */);
}
@Test
@@ -2423,8 +2383,7 @@
fail("Undefined transport type");
}
notifyNetworkConnected(nm, nc);
- verifyNetworkTested(NETWORK_VALIDATION_RESULT_VALID,
- NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS);
+ verifyNetworkTestedValidFromHttps(1 /* interactions */);
nm.setLastProbeTime(SystemClock.elapsedRealtime() - STALL_EXPECTED_LAST_PROBE_TIME_MS);
return nm;
}
@@ -2633,11 +2592,11 @@
NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP,
null /* redirectUrl */);
- resetCallbacks();
nm.setAcceptPartialConnectivity();
// Expect to update evaluation result notifications to CS.
verifyNetworkTested(NETWORK_VALIDATION_RESULT_PARTIAL | NETWORK_VALIDATION_RESULT_VALID,
- NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP);
+ NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP,
+ 1 /* interactions */);
}
@Test
@@ -2710,7 +2669,6 @@
final NetworkMonitor nm = runValidatedNetworkTest();
// Verify forceReevaluation will not reset the validation result but only probe result until
// getting the validation result.
- resetCallbacks();
setSslException(mHttpsConnection);
setStatus(mHttpConnection, 500);
setStatus(mFallbackConnection, 204);
@@ -2718,7 +2676,7 @@
// Expect to send HTTP, HTTPs, FALLBACK and evaluation results.
verifyNetworkTested(VALIDATION_RESULT_INVALID,
NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_FALLBACK,
- null /* redirectUrl */);
+ 1 /* interactions */);
HandlerUtils.waitForIdle(nm.getHandler(), HANDLER_TIMEOUT_MS);
}
@@ -2726,7 +2684,7 @@
public void testNotifyNetwork_NotifyNetworkTestedOldInterfaceVersion() throws Exception {
// Use old interface version so notifyNetworkTested is used over
// notifyNetworkTestedWithExtras
- resetCallbacks(4);
+ initCallbacks(4);
// Trigger Network validation
setStatus(mHttpsConnection, 204);
@@ -2813,8 +2771,6 @@
setValidProbes();
final NetworkMonitor nm = runValidatedNetworkTest();
- resetCallbacks();
-
nm.reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP,
CaptivePortalProbeResult.success(1 << PROBE_HTTP));
// Verify result should be appended and notifyNetworkTestedWithExtras callback is triggered
@@ -2842,20 +2798,22 @@
nm.getEvaluationState().reportEvaluationResult(NETWORK_VALIDATION_RESULT_VALID,
null /* redirectUrl */);
verifyNetworkTested(NETWORK_VALIDATION_RESULT_VALID,
- NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP);
+ NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP,
+ 1 /* interactions */);
nm.getEvaluationState().reportEvaluationResult(
NETWORK_VALIDATION_RESULT_VALID | NETWORK_VALIDATION_RESULT_PARTIAL,
null /* redirectUrl */);
verifyNetworkTested(
NETWORK_VALIDATION_RESULT_VALID | NETWORK_VALIDATION_RESULT_PARTIAL,
- NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP);
+ NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP,
+ 1 /* interactions */);
nm.getEvaluationState().reportEvaluationResult(VALIDATION_RESULT_INVALID,
TEST_REDIRECT_URL);
verifyNetworkTested(VALIDATION_RESULT_INVALID,
NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP,
- TEST_REDIRECT_URL);
+ TEST_REDIRECT_URL, 1 /* interactions */);
}
@Test
@@ -2997,14 +2955,13 @@
verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
.showProvisioningNotification(any(), any());
assertCaptivePortalAppReceiverRegistered(true /* isPortal */);
- verifyNetworkTested(VALIDATION_RESULT_PORTAL, 0 /* probesSucceeded */, TEST_LOGIN_URL);
+ verifyNetworkTestedPortal(TEST_LOGIN_URL, 1 /* interactions */);
// Force reevaluation and confirm that the network is still captive
HandlerUtils.waitForIdle(monitor.getHandler(), HANDLER_TIMEOUT_MS);
- resetCallbacks();
monitor.forceReevaluation(Process.myUid());
assertEquals(monitor.getEvaluationState().getProbeCompletedResult(), 0);
- verifyNetworkTested(VALIDATION_RESULT_PORTAL, 0 /* probesSucceeded */, TEST_LOGIN_URL);
+ verifyNetworkTestedPortal(TEST_LOGIN_URL, 2 /* interactions */);
// Check that startCaptivePortalApp sends the expected intent.
monitor.launchCaptivePortalApp();
@@ -3197,21 +3154,59 @@
int testResult, int probesSucceeded, String redirectUrl) throws Exception {
final NetworkMonitor monitor = makeMonitor(nc);
notifyNetworkConnected(monitor, config, lp, nc);
- verifyNetworkTested(testResult, probesSucceeded, redirectUrl);
+ verifyNetworkTested(testResult, probesSucceeded, redirectUrl, 1 /* interactions */);
HandlerUtils.waitForIdle(monitor.getHandler(), HANDLER_TIMEOUT_MS);
return monitor;
}
- private void verifyNetworkTested(int testResult, int probesSucceeded) throws Exception {
- verifyNetworkTested(testResult, probesSucceeded, null /* redirectUrl */);
+ private void verifyProbeStatusChangedPrivateDnsCompleteAndSucceeded(int interactions)
+ throws Exception {
+ verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(interactions))
+ .notifyProbeStatusChanged(eq(PROBES_PRIVDNS_VALID), eq(PROBES_PRIVDNS_VALID));
}
- private void verifyNetworkTested(int testResult, int probesSucceeded, String redirectUrl)
- throws RemoteException {
+ private void verifyProbeStatusChangedPrivateDnsCompleteAndHttpsSucceeded(int interactions)
+ throws Exception {
+ verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(interactions))
+ .notifyProbeStatusChanged(
+ eq(PROBES_PRIVDNS_VALID),
+ eq(NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS));
+ }
+
+ private void verifyNetworkTestedInvalidFromHttps(int interactions) throws Exception {
+ verifyNetworkTested(VALIDATION_RESULT_INVALID,
+ NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS,
+ interactions);
+ }
+
+ private void verifyNetworkTestedPortal(String redirectUrl, int interactions) throws Exception {
+ verifyNetworkTested(VALIDATION_RESULT_PORTAL, 0 /* probesSucceeded */, redirectUrl,
+ interactions);
+ }
+
+ private void verifyNetworkTestedValidFromHttps(int interactions) throws Exception {
+ verifyNetworkTested(NETWORK_VALIDATION_RESULT_VALID,
+ NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS,
+ interactions);
+ }
+
+ private void verifyNetworkTestedValidFromPrivateDns(int interactions) throws Exception {
+ verifyNetworkTested(NETWORK_VALIDATION_RESULT_VALID, PROBES_PRIVDNS_VALID, interactions);
+ }
+
+ private void verifyNetworkTested(int testResult, int probesSucceeded, int interactions)
+ throws Exception {
+ verifyNetworkTested(testResult, probesSucceeded, null /* redirectUrl */, interactions);
+ }
+
+ private void verifyNetworkTested(int testResult, int probesSucceeded, String redirectUrl,
+ int interactions) throws RemoteException {
try {
- verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS)).notifyNetworkTestedWithExtras(
- matchNetworkTestResultParcelable(testResult, probesSucceeded, redirectUrl));
+ verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(interactions))
+ .notifyNetworkTestedWithExtras(
+ matchNetworkTestResultParcelable(
+ testResult, probesSucceeded, redirectUrl));
} catch (AssertionFailedError e) {
// Capture the callbacks up to now to give a better error message
final ArgumentCaptor<NetworkTestResultParcelable> captor =
@@ -3221,14 +3216,15 @@
// call which failed, but this time use a captor to log the exact parcel sent by
// NetworkMonitor.
// This assertion will fail if notifyNetworkTested was not called at all.
- verify(mCallbacks).notifyNetworkTestedWithExtras(captor.capture());
+ verify(mCallbacks, times(interactions)).notifyNetworkTestedWithExtras(captor.capture());
- final NetworkTestResultParcelable lastResult = captor.getValue();
- fail(String.format("notifyNetworkTestedWithExtras was not called with the "
+ final List<NetworkTestResultParcelable> results = captor.getAllValues();
+ final NetworkTestResultParcelable lastResult = results.get(results.size() - 1);
+ fail(String.format("notifyNetworkTestedWithExtras was not called %d times with the "
+ "expected result within timeout. "
+ "Expected result %d, probes succeeded %d, redirect URL %s, "
+ "last result was (%d, %d, %s).",
- testResult, probesSucceeded, redirectUrl,
+ interactions, testResult, probesSucceeded, redirectUrl,
lastResult.result, lastResult.probesSucceeded, lastResult.redirectUrl));
}
}