Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f3c5a342 authored by Erik Kline's avatar Erik Kline Committed by Android Git Automerger
Browse files

am 11b5ee05: am cd7ed16f: LinkProperties function to compare provisioning and remove DNS servers

* commit '11b5ee05':
  LinkProperties function to compare provisioning and remove DNS servers
parents 8bd4d77d 11b5ee05
Loading
Loading
Loading
Loading
+67 −3
Original line number Diff line number Diff line
@@ -85,6 +85,54 @@ public final class LinkProperties implements Parcelable {
        }
    }

    /**
     * @hide
     */
    public enum ProvisioningChange {
        STILL_NOT_PROVISIONED,
        LOST_PROVISIONING,
        GAINED_PROVISIONING,
        STILL_PROVISIONED,
    }

    /**
     * Compare the provisioning states of two LinkProperties instances.
     *
     * @hide
     */
    public static ProvisioningChange compareProvisioning(
            LinkProperties before, LinkProperties after) {
        if (before.isProvisioned() && after.isProvisioned()) {
            // On dualstack networks, DHCPv4 renewals can occasionally fail.
            // When this happens, IPv6-reachable services continue to function
            // normally but IPv4-only services (naturally) fail.
            //
            // When an application using an IPv4-only service reports a bad
            // network condition to the framework, attempts to re-validate
            // the network succeed (since we support IPv6-only networks) and
            // nothing is changed.
            //
            // For users, this is confusing and unexpected behaviour, and is
            // not necessarily easy to diagnose.  Therefore, we treat changing
            // from a dualstack network to an IPv6-only network equivalent to
            // a total loss of provisioning.
            //
            // For one such example of this, see b/18867306.
            //
            // TODO: Remove this special case altogether.
            if (before.isIPv4Provisioned() && !after.isIPv4Provisioned()) {
                return ProvisioningChange.LOST_PROVISIONING;
            }
            return ProvisioningChange.STILL_PROVISIONED;
        } else if (before.isProvisioned() && !after.isProvisioned()) {
            return ProvisioningChange.LOST_PROVISIONING;
        } else if (!before.isProvisioned() && after.isProvisioned()) {
            return ProvisioningChange.GAINED_PROVISIONING;
        } else {  // !before.isProvisioned() && !after.isProvisioned()
            return ProvisioningChange.STILL_NOT_PROVISIONED;
        }
    }

    /**
     * @hide
     */
@@ -286,6 +334,20 @@ public final class LinkProperties implements Parcelable {
        return false;
    }

    /**
     * Removes the given {@link InetAddress} from the list of DNS servers.
     *
     * @param dnsServer The {@link InetAddress} to remove from the list of DNS servers.
     * @return true if the DNS server was removed, false if it did not exist.
     * @hide
     */
    public boolean removeDnsServer(InetAddress dnsServer) {
        if (dnsServer != null) {
            return mDnses.remove(dnsServer);
        }
        return false;
    }

    /**
     * Replaces the DNS servers in this {@code LinkProperties} with
     * the given {@link Collection} of {@link InetAddress} objects.
@@ -679,8 +741,9 @@ public final class LinkProperties implements Parcelable {
     * This requires an IP address, default route, and DNS server.
     *
     * @return {@code true} if the link is provisioned, {@code false} otherwise.
     * @hide
     */
    private boolean hasIPv4() {
    public boolean isIPv4Provisioned() {
        return (hasIPv4Address() &&
                hasIPv4DefaultRoute() &&
                hasIPv4DnsServer());
@@ -691,8 +754,9 @@ public final class LinkProperties implements Parcelable {
     * This requires an IP address, default route, and DNS server.
     *
     * @return {@code true} if the link is provisioned, {@code false} otherwise.
     * @hide
     */
    private boolean hasIPv6() {
    public boolean isIPv6Provisioned() {
        return (hasGlobalIPv6Address() &&
                hasIPv6DefaultRoute() &&
                hasIPv6DnsServer());
@@ -706,7 +770,7 @@ public final class LinkProperties implements Parcelable {
     * @hide
     */
    public boolean isProvisioned() {
        return (hasIPv4() || hasIPv6());
        return (isIPv4Provisioned() || isIPv6Provisioned());
    }

    /**
+73 −4
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.net;

import android.net.LinkProperties;
import android.net.LinkProperties.ProvisioningChange;
import android.net.RouteInfo;
import android.system.OsConstants;
import android.test.suitebuilder.annotation.SmallTest;
@@ -34,7 +35,8 @@ public class LinkPropertiesTest extends TestCase {
    private static InetAddress DNS6 = NetworkUtils.numericToInetAddress("2001:4860:4860::8888");
    private static InetAddress GATEWAY1 = NetworkUtils.numericToInetAddress("75.208.8.1");
    private static InetAddress GATEWAY2 = NetworkUtils.numericToInetAddress("69.78.8.1");
    private static InetAddress GATEWAY6 = NetworkUtils.numericToInetAddress("fe80::6:0000:613");
    private static InetAddress GATEWAY61 = NetworkUtils.numericToInetAddress("fe80::6:0000:613");
    private static InetAddress GATEWAY62 = NetworkUtils.numericToInetAddress("fe80::6:2222");
    private static String NAME = "qmi0";
    private static int MTU = 1500;

@@ -466,6 +468,8 @@ public class LinkPropertiesTest extends TestCase {
        assertFalse("v4only:addr+dns", lp4.isProvisioned());
        lp4.addRoute(new RouteInfo(GATEWAY1));
        assertTrue("v4only:addr+dns+route", lp4.isProvisioned());
        assertTrue("v4only:addr+dns+route", lp4.isIPv4Provisioned());
        assertFalse("v4only:addr+dns+route", lp4.isIPv6Provisioned());

        LinkProperties lp6 = new LinkProperties();
        assertFalse("v6only:empty", lp6.isProvisioned());
@@ -473,11 +477,14 @@ public class LinkPropertiesTest extends TestCase {
        assertFalse("v6only:fe80-only", lp6.isProvisioned());
        lp6.addDnsServer(DNS6);
        assertFalse("v6only:fe80+dns", lp6.isProvisioned());
        lp6.addRoute(new RouteInfo(GATEWAY6));
        lp6.addRoute(new RouteInfo(GATEWAY61));
        assertFalse("v6only:fe80+dns+route", lp6.isProvisioned());
        lp6.addLinkAddress(LINKADDRV6);
        assertTrue("v6only:fe80+global+dns+route", lp6.isIPv6Provisioned());
        assertTrue("v6only:fe80+global+dns+route", lp6.isProvisioned());
        lp6.removeLinkAddress(LINKADDRV6LINKLOCAL);
        assertFalse("v6only:global+dns+route", lp6.isIPv4Provisioned());
        assertTrue("v6only:global+dns+route", lp6.isIPv6Provisioned());
        assertTrue("v6only:global+dns+route", lp6.isProvisioned());

        LinkProperties lp46 = new LinkProperties();
@@ -487,15 +494,77 @@ public class LinkPropertiesTest extends TestCase {
        lp46.addDnsServer(DNS6);
        assertFalse("dualstack:missing-routes", lp46.isProvisioned());
        lp46.addRoute(new RouteInfo(GATEWAY1));
        assertTrue("dualstack:v4-provisioned", lp46.isIPv4Provisioned());
        assertFalse("dualstack:v4-provisioned", lp46.isIPv6Provisioned());
        assertTrue("dualstack:v4-provisioned", lp46.isProvisioned());
        lp6.addRoute(new RouteInfo(GATEWAY6));
        lp46.addRoute(new RouteInfo(GATEWAY61));
        assertTrue("dualstack:both-provisioned", lp46.isIPv4Provisioned());
        assertTrue("dualstack:both-provisioned", lp46.isIPv6Provisioned());
        assertTrue("dualstack:both-provisioned", lp46.isProvisioned());

        // A link with an IPv6 address and default route, but IPv4 DNS server.
        LinkProperties mixed = new LinkProperties();
        mixed.addLinkAddress(LINKADDRV6);
        mixed.addDnsServer(DNS1);
        mixed.addRoute(new RouteInfo(GATEWAY6));
        mixed.addRoute(new RouteInfo(GATEWAY61));
        assertFalse("mixed:addr6+route6+dns4", mixed.isIPv4Provisioned());
        assertFalse("mixed:addr6+route6+dns4", mixed.isIPv6Provisioned());
        assertFalse("mixed:addr6+route6+dns4", mixed.isProvisioned());
    }

    @SmallTest
    public void testCompareProvisioning() {
        LinkProperties v4lp = new LinkProperties();
        v4lp.addLinkAddress(LINKADDRV4);
        v4lp.addRoute(new RouteInfo(GATEWAY1));
        v4lp.addDnsServer(DNS1);
        assertTrue(v4lp.isProvisioned());

        LinkProperties v4r = new LinkProperties(v4lp);
        v4r.removeDnsServer(DNS1);
        assertFalse(v4r.isProvisioned());

        assertEquals(ProvisioningChange.STILL_NOT_PROVISIONED,
                LinkProperties.compareProvisioning(v4r, v4r));
        assertEquals(ProvisioningChange.LOST_PROVISIONING,
                LinkProperties.compareProvisioning(v4lp, v4r));
        assertEquals(ProvisioningChange.GAINED_PROVISIONING,
                LinkProperties.compareProvisioning(v4r, v4lp));
        assertEquals(ProvisioningChange.STILL_PROVISIONED,
                LinkProperties.compareProvisioning(v4lp, v4lp));

        // Check that losing IPv4 provisioning on a dualstack network is
        // seen as a total loss of provisioning.
        LinkProperties v6lp = new LinkProperties();
        v6lp.addLinkAddress(LINKADDRV6);
        v6lp.addRoute(new RouteInfo(GATEWAY61));
        v6lp.addDnsServer(DNS6);
        assertFalse(v6lp.isIPv4Provisioned());
        assertTrue(v6lp.isIPv6Provisioned());
        assertTrue(v6lp.isProvisioned());

        LinkProperties v46lp = new LinkProperties(v6lp);
        v46lp.addLinkAddress(LINKADDRV4);
        v46lp.addRoute(new RouteInfo(GATEWAY1));
        v46lp.addDnsServer(DNS1);
        assertTrue(v46lp.isIPv4Provisioned());
        assertTrue(v46lp.isIPv6Provisioned());
        assertTrue(v46lp.isProvisioned());

        assertEquals(ProvisioningChange.STILL_PROVISIONED,
                LinkProperties.compareProvisioning(v6lp, v46lp));
        assertEquals(ProvisioningChange.LOST_PROVISIONING,
                LinkProperties.compareProvisioning(v46lp, v6lp));

        // Check that losing and gaining a secondary router does not change
        // the provisioning status.
        LinkProperties v6lp2 = new LinkProperties(v6lp);
        v6lp2.addRoute(new RouteInfo(GATEWAY62));
        assertTrue(v6lp2.isProvisioned());

        assertEquals(ProvisioningChange.STILL_PROVISIONED,
                LinkProperties.compareProvisioning(v6lp2, v6lp));
        assertEquals(ProvisioningChange.STILL_PROVISIONED,
                LinkProperties.compareProvisioning(v6lp, v6lp2));
    }
}