Merge "Extend QosFilter address matching function" into main
This commit is contained in:
commit
ceb29e6cdf
7 changed files with 169 additions and 32 deletions
|
|
@ -39,6 +39,11 @@ java_aconfig_library {
|
|||
],
|
||||
}
|
||||
|
||||
// This library MUST NOT be available to platform. This is because if the
|
||||
// platform depends on a flag, it will not be able to delete that flag until
|
||||
// that platform version is no longer supported by mainline. Additionally,
|
||||
// there is no any safety mechanism that prevents the module from
|
||||
// deleting the flag by mistake, regressing on previous platform versions.
|
||||
java_aconfig_library {
|
||||
name: "com.android.net.flags-aconfig-java-export",
|
||||
aconfig_declarations: "com.android.net.flags-aconfig",
|
||||
|
|
|
|||
|
|
@ -191,3 +191,11 @@ flag {
|
|||
bug: "397536853"
|
||||
is_fixed_read_only: true
|
||||
}
|
||||
|
||||
flag {
|
||||
name: "qos_filter_ip_range_matching"
|
||||
namespace: "android_core_networking"
|
||||
description: "Flag for API to provide IP address range based QoS socket matching."
|
||||
bug: "406146808"
|
||||
is_fixed_read_only: true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -433,8 +433,10 @@ package android.net {
|
|||
public abstract class QosFilter {
|
||||
method @NonNull public abstract android.net.Network getNetwork();
|
||||
method public abstract boolean matchesLocalAddress(@NonNull java.net.InetAddress, int, int);
|
||||
method @FlaggedApi("com.android.net.flags.qos_filter_ip_range_matching") public abstract boolean matchesLocalPrefix(@NonNull android.net.IpPrefix, int, int);
|
||||
method public boolean matchesProtocol(int);
|
||||
method public abstract boolean matchesRemoteAddress(@NonNull java.net.InetAddress, int, int);
|
||||
method @FlaggedApi("com.android.net.flags.qos_filter_ip_range_matching") public abstract boolean matchesRemotePrefix(@NonNull android.net.IpPrefix, int, int);
|
||||
}
|
||||
|
||||
public final class QosSession implements android.os.Parcelable {
|
||||
|
|
|
|||
|
|
@ -16,9 +16,12 @@
|
|||
|
||||
package android.net;
|
||||
|
||||
import android.annotation.FlaggedApi;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.SystemApi;
|
||||
|
||||
import com.android.net.flags.Flags;
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
/**
|
||||
|
|
@ -93,6 +96,38 @@ public abstract class QosFilter {
|
|||
public abstract boolean matchesRemoteAddress(@NonNull InetAddress address,
|
||||
int startPort, int endPort);
|
||||
|
||||
/**
|
||||
* Determines whether or not the parameters will be matched with prefix length, source address
|
||||
* and port.
|
||||
*
|
||||
* @param ipPrefix the UE side IP address and prefix length included in IP packet filter set of
|
||||
* a QoS flow assigned on {@link Network}.
|
||||
* @param startPort the start of UE side port range included in IP packet filter set of a QoS
|
||||
* flow assigned on {@link Network}.
|
||||
* @param endPort the end of UE side port range included in IP packet filter set of a QoS flow
|
||||
* assigned on {@link Network}.
|
||||
* @return whether the parameters match the UE side address and port of the filter
|
||||
*/
|
||||
@FlaggedApi(Flags.FLAG_QOS_FILTER_IP_RANGE_MATCHING)
|
||||
public abstract boolean matchesLocalPrefix(
|
||||
@NonNull IpPrefix ipPrefix, int startPort, int endPort);
|
||||
|
||||
/**
|
||||
* Determines whether or not the parameters will be matched with prefix length, remote address
|
||||
* and port.
|
||||
*
|
||||
* @param ipPrefix the remote IP address and prefix length included in IP packet filter set of a
|
||||
* QoS flow assigned on {@link Network}.
|
||||
* @param startPort the start of remote port range included in IP packet filter set of a QoS
|
||||
* flow assigned on {@link Network}.
|
||||
* @param endPort the end of the remote range included in IP packet filter set of a QoS flow
|
||||
* assigned on {@link Network}.
|
||||
* @return whether the parameters match the remote address and port of the filter
|
||||
*/
|
||||
@FlaggedApi(Flags.FLAG_QOS_FILTER_IP_RANGE_MATCHING)
|
||||
public abstract boolean matchesRemotePrefix(
|
||||
@NonNull IpPrefix ipPrefix, int startPort, int endPort);
|
||||
|
||||
/**
|
||||
* Determines whether or not the parameter will be matched with this filter.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ import android.util.Log;
|
|||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
|
|
@ -179,10 +180,11 @@ public class QosSocketFilter extends QosFilter {
|
|||
@Override
|
||||
public boolean matchesLocalAddress(@NonNull final InetAddress address, final int startPort,
|
||||
final int endPort) {
|
||||
if (mQosSocketInfo.getLocalSocketAddress() == null) {
|
||||
return false;
|
||||
}
|
||||
return matchesAddress(mQosSocketInfo.getLocalSocketAddress(), address, startPort,
|
||||
return matchesLocalPrefix(
|
||||
address instanceof Inet4Address
|
||||
? new IpPrefix(address, 32)
|
||||
: new IpPrefix(address, 128),
|
||||
startPort,
|
||||
endPort);
|
||||
}
|
||||
|
||||
|
|
@ -192,11 +194,33 @@ public class QosSocketFilter extends QosFilter {
|
|||
@Override
|
||||
public boolean matchesRemoteAddress(@NonNull final InetAddress address, final int startPort,
|
||||
final int endPort) {
|
||||
return matchesRemotePrefix(
|
||||
address instanceof Inet4Address
|
||||
? new IpPrefix(address, 32)
|
||||
: new IpPrefix(address, 128),
|
||||
startPort,
|
||||
endPort);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public boolean matchesLocalPrefix(
|
||||
@NonNull final IpPrefix ipPrefix, final int startPort, final int endPort) {
|
||||
if (mQosSocketInfo.getLocalSocketAddress() == null) {
|
||||
return false;
|
||||
}
|
||||
return matchesAddress(mQosSocketInfo.getLocalSocketAddress(), ipPrefix, startPort, endPort);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public boolean matchesRemotePrefix(
|
||||
@NonNull final IpPrefix ipPrefix, final int startPort, final int endPort) {
|
||||
if (mQosSocketInfo.getRemoteSocketAddress() == null) {
|
||||
return false;
|
||||
}
|
||||
return matchesAddress(mQosSocketInfo.getRemoteSocketAddress(), address, startPort,
|
||||
endPort);
|
||||
return matchesAddress(
|
||||
mQosSocketInfo.getRemoteSocketAddress(), ipPrefix, startPort, endPort);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -212,25 +236,27 @@ public class QosSocketFilter extends QosFilter {
|
|||
}
|
||||
|
||||
/**
|
||||
* Called from {@link QosSocketFilter#matchesLocalAddress(InetAddress, int, int)}
|
||||
* and {@link QosSocketFilter#matchesRemoteAddress(InetAddress, int, int)} with the
|
||||
* filterSocketAddress coming from {@link QosSocketInfo#getLocalSocketAddress()}.
|
||||
* <p>
|
||||
* This method exists for testing purposes since {@link QosSocketInfo} couldn't be mocked
|
||||
* due to being final.
|
||||
* Called from {@link QosSocketFilter#matchesLocalPrefix(IpPrefix, int, int)} and {@link
|
||||
* QosSocketFilter#matchesRemotePrefix(IpPrefix, int, int)} with the filterSocketAddress coming
|
||||
* from {@link QosSocketInfo#getLocalSocketAddress()}.
|
||||
*
|
||||
* <p>This method exists for testing purposes since {@link QosSocketInfo} couldn't be mocked due
|
||||
* to being final.
|
||||
*
|
||||
* @param filterSocketAddress the socket address of the filter
|
||||
* @param address the address to compare the filterSocketAddressWith
|
||||
* @param ipPrefix the IP address with prefix length to compare the filterSocketAddressWith
|
||||
* @param startPort the start of the port range to check
|
||||
* @param endPort the end of the port range to check
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public static boolean matchesAddress(@NonNull final InetSocketAddress filterSocketAddress,
|
||||
@NonNull final InetAddress address,
|
||||
final int startPort, final int endPort) {
|
||||
public static boolean matchesAddress(
|
||||
@NonNull final InetSocketAddress filterSocketAddress,
|
||||
@NonNull final IpPrefix ipPrefix,
|
||||
final int startPort,
|
||||
final int endPort) {
|
||||
return startPort <= filterSocketAddress.getPort()
|
||||
&& endPort >= filterSocketAddress.getPort()
|
||||
&& (address.isAnyLocalAddress()
|
||||
|| filterSocketAddress.getAddress().equals(address));
|
||||
&& (ipPrefix.getAddress().isAnyLocalAddress()
|
||||
|| ipPrefix.contains(filterSocketAddress.getAddress()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1392,6 +1392,22 @@ class NetworkAgentTest {
|
|||
agent.expectCallback<OnRegisterQosCallback>().let {
|
||||
callbackId = it.callbackId
|
||||
assertTrue(it.filter.matchesProtocol(proto))
|
||||
// This test is only validating QosFilter address match APIs can be called.
|
||||
// Detail functionality checks are executed on QosSocketFilterTest.
|
||||
// Verify the match of test socket's Local address, currently the test socket
|
||||
// binds to the loopback address.
|
||||
assertTrue(it.filter.matchesLocalPrefix(
|
||||
IpPrefix(InetAddress.getLoopbackAddress(), 128),
|
||||
0,
|
||||
65535
|
||||
))
|
||||
// Since the test socket doesn't connect to the remote address, we expect
|
||||
// unmatched result.
|
||||
assertFalse(it.filter.matchesRemotePrefix(
|
||||
IpPrefix(InetAddress.getLoopbackAddress(), 128),
|
||||
0,
|
||||
65535
|
||||
))
|
||||
}
|
||||
|
||||
assertFailsWith<QosCallbackRegistrationException>(
|
||||
|
|
|
|||
|
|
@ -52,50 +52,95 @@ public class QosSocketFilterTest {
|
|||
public void testPortExactMatch() {
|
||||
final InetAddress addressA = InetAddresses.parseNumericAddress("1.2.3.4");
|
||||
final InetAddress addressB = InetAddresses.parseNumericAddress("1.2.3.4");
|
||||
assertTrue(QosSocketFilter.matchesAddress(
|
||||
new InetSocketAddress(addressA, 10), addressB, 10, 10));
|
||||
assertTrue(
|
||||
QosSocketFilter.matchesAddress(
|
||||
new InetSocketAddress(addressA, 10), new IpPrefix(addressB, 32), 10, 10));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPortLessThanStart() {
|
||||
final InetAddress addressA = InetAddresses.parseNumericAddress("1.2.3.4");
|
||||
final InetAddress addressB = InetAddresses.parseNumericAddress("1.2.3.4");
|
||||
assertFalse(QosSocketFilter.matchesAddress(
|
||||
new InetSocketAddress(addressA, 8), addressB, 10, 10));
|
||||
assertFalse(
|
||||
QosSocketFilter.matchesAddress(
|
||||
new InetSocketAddress(addressA, 8), new IpPrefix(addressB, 32), 10, 10));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPortGreaterThanEnd() {
|
||||
final InetAddress addressA = InetAddresses.parseNumericAddress("1.2.3.4");
|
||||
final InetAddress addressB = InetAddresses.parseNumericAddress("1.2.3.4");
|
||||
assertFalse(QosSocketFilter.matchesAddress(
|
||||
new InetSocketAddress(addressA, 18), addressB, 10, 10));
|
||||
assertFalse(
|
||||
QosSocketFilter.matchesAddress(
|
||||
new InetSocketAddress(addressA, 18), new IpPrefix(addressB, 32), 10, 10));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPortBetweenStartAndEnd() {
|
||||
final InetAddress addressA = InetAddresses.parseNumericAddress("1.2.3.4");
|
||||
final InetAddress addressB = InetAddresses.parseNumericAddress("1.2.3.4");
|
||||
assertTrue(QosSocketFilter.matchesAddress(
|
||||
new InetSocketAddress(addressA, 10), addressB, 8, 18));
|
||||
assertTrue(
|
||||
QosSocketFilter.matchesAddress(
|
||||
new InetSocketAddress(addressA, 10), new IpPrefix(addressB, 32), 8, 18));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddressesDontMatch() {
|
||||
final InetAddress addressA = InetAddresses.parseNumericAddress("1.2.3.4");
|
||||
final InetAddress addressB = InetAddresses.parseNumericAddress("1.2.3.5");
|
||||
assertFalse(QosSocketFilter.matchesAddress(
|
||||
new InetSocketAddress(addressA, 10), addressB, 10, 10));
|
||||
assertFalse(
|
||||
QosSocketFilter.matchesAddress(
|
||||
new InetSocketAddress(addressA, 10), new IpPrefix(addressB, 32), 10, 10));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddressMatchWithAnyLocalAddresses() {
|
||||
final InetAddress addressA = InetAddresses.parseNumericAddress("1.2.3.4");
|
||||
final InetAddress addressB = InetAddresses.parseNumericAddress("0.0.0.0");
|
||||
assertTrue(QosSocketFilter.matchesAddress(
|
||||
new InetSocketAddress(addressA, 10), addressB, 10, 10));
|
||||
assertFalse(QosSocketFilter.matchesAddress(
|
||||
new InetSocketAddress(addressB, 10), addressA, 10, 10));
|
||||
assertTrue(
|
||||
QosSocketFilter.matchesAddress(
|
||||
new InetSocketAddress(addressA, 10), new IpPrefix(addressB, 32), 10, 10));
|
||||
assertFalse(
|
||||
QosSocketFilter.matchesAddress(
|
||||
new InetSocketAddress(addressB, 10), new IpPrefix(addressA, 32), 10, 10));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddressMatchWithPrefixLength() {
|
||||
final InetAddress addressA = InetAddresses.parseNumericAddress("1.2.3.100");
|
||||
final InetAddress addressB = InetAddresses.parseNumericAddress("1.2.3.132");
|
||||
final InetAddress addressC = InetAddresses.parseNumericAddress("1.2.3.96");
|
||||
final InetAddress addressD = InetAddresses.parseNumericAddress("2001:2:3:5::13:D17");
|
||||
final InetAddress addressE = InetAddresses.parseNumericAddress("2001:2:3:4::13:D17");
|
||||
final InetAddress addressF = InetAddresses.parseNumericAddress("2001:2:3:5::");
|
||||
final InetAddress addressG = InetAddresses.parseNumericAddress("135.23.185.35");
|
||||
final InetAddress addressH = InetAddresses.parseNumericAddress("135.23.186.127");
|
||||
final InetAddress addressI = InetAddresses.parseNumericAddress("135.23.183.127");
|
||||
|
||||
assertTrue(
|
||||
QosSocketFilter.matchesAddress(
|
||||
new InetSocketAddress(addressA, 10), new IpPrefix(addressC, 27), 10, 10));
|
||||
assertFalse(
|
||||
QosSocketFilter.matchesAddress(
|
||||
new InetSocketAddress(addressB, 10), new IpPrefix(addressC, 27), 10, 10));
|
||||
assertTrue(
|
||||
QosSocketFilter.matchesAddress(
|
||||
new InetSocketAddress(addressG, 10), new IpPrefix(addressH, 22), 10, 10));
|
||||
assertFalse(
|
||||
QosSocketFilter.matchesAddress(
|
||||
new InetSocketAddress(addressI, 10), new IpPrefix(addressH, 22), 10, 10));
|
||||
assertTrue(
|
||||
QosSocketFilter.matchesAddress(
|
||||
new InetSocketAddress(addressD, 10), new IpPrefix(addressF, 64), 10, 10));
|
||||
assertFalse(
|
||||
QosSocketFilter.matchesAddress(
|
||||
new InetSocketAddress(addressE, 10), new IpPrefix(addressF, 64), 10, 10));
|
||||
assertFalse(
|
||||
QosSocketFilter.matchesAddress(
|
||||
new InetSocketAddress(addressA, 10), new IpPrefix(addressF, 64), 10, 10));
|
||||
assertTrue(
|
||||
QosSocketFilter.matchesAddress(
|
||||
new InetSocketAddress(addressD, 10), new IpPrefix(addressD, 128), 10, 10));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
Loading…
Reference in a new issue