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

Commit 92b21561 authored by Automerger Merge Worker's avatar Automerger Merge Worker Committed by Remi NGUYEN VAN
Browse files

Fix parceling of LinkProperties Inet6Addr

IPv6 addresses parceled for DNS servers, private DNS servers, PCSCF
servers were parceled without the scope. This causes issues with
link-local DNS servers.

Test: atest FrameworksNetTests
Bug: 145181158
(cherry picked from commit 091f1d79)
Merged-In: Ie5b7782d788717dd1cc440e502d6cdf2d1c18eaa

Change-Id: I51313f50de8220988c2c1d26981c27d07dfb55f9
parent c5dffc9a
Loading
Loading
Loading
Loading
+37 −16
Original line number Original line Diff line number Diff line
@@ -73,6 +73,8 @@ public final class LinkProperties implements Parcelable {
    private static final int MIN_MTU_V6 = 1280;
    private static final int MIN_MTU_V6 = 1280;
    private static final int MAX_MTU    = 10000;
    private static final int MAX_MTU    = 10000;


    private static final int INET6_ADDR_LENGTH = 16;

    // Stores the properties of links that are "stacked" above this link.
    // Stores the properties of links that are "stacked" above this link.
    // Indexed by interface name to allow modification and to prevent duplicates being added.
    // Indexed by interface name to allow modification and to prevent duplicates being added.
    private Hashtable<String, LinkProperties> mStackedLinks = new Hashtable<>();
    private Hashtable<String, LinkProperties> mStackedLinks = new Hashtable<>();
@@ -1590,20 +1592,11 @@ public final class LinkProperties implements Parcelable {
            dest.writeParcelable(linkAddress, flags);
            dest.writeParcelable(linkAddress, flags);
        }
        }


        dest.writeInt(mDnses.size());
        writeAddresses(dest, mDnses);
        for (InetAddress d : mDnses) {
        writeAddresses(dest, mValidatedPrivateDnses);
            dest.writeByteArray(d.getAddress());
        }
        dest.writeInt(mValidatedPrivateDnses.size());
        for (InetAddress d : mValidatedPrivateDnses) {
            dest.writeByteArray(d.getAddress());
        }
        dest.writeBoolean(mUsePrivateDns);
        dest.writeBoolean(mUsePrivateDns);
        dest.writeString(mPrivateDnsServerName);
        dest.writeString(mPrivateDnsServerName);
        dest.writeInt(mPcscfs.size());
        writeAddresses(dest, mPcscfs);
        for (InetAddress d : mPcscfs) {
            dest.writeByteArray(d.getAddress());
        }
        dest.writeString(mDomains);
        dest.writeString(mDomains);
        dest.writeInt(mMtu);
        dest.writeInt(mMtu);
        dest.writeString(mTcpBufferSizes);
        dest.writeString(mTcpBufferSizes);
@@ -1624,6 +1617,35 @@ public final class LinkProperties implements Parcelable {
        dest.writeList(stackedLinks);
        dest.writeList(stackedLinks);
    }
    }


    private static void writeAddresses(@NonNull Parcel dest, @NonNull List<InetAddress> list) {
        dest.writeInt(list.size());
        for (InetAddress d : list) {
            writeAddress(dest, d);
        }
    }

    private static void writeAddress(@NonNull Parcel dest, @NonNull InetAddress addr) {
        dest.writeByteArray(addr.getAddress());
        if (addr instanceof Inet6Address) {
            final Inet6Address v6Addr = (Inet6Address) addr;
            final boolean hasScopeId = v6Addr.getScopeId() != 0;
            dest.writeBoolean(hasScopeId);
            if (hasScopeId) dest.writeInt(v6Addr.getScopeId());
        }
    }

    @NonNull
    private static InetAddress readAddress(@NonNull Parcel p) throws UnknownHostException {
        final byte[] addr = p.createByteArray();
        if (addr.length == INET6_ADDR_LENGTH) {
            final boolean hasScopeId = p.readBoolean();
            final int scopeId = hasScopeId ? p.readInt() : 0;
            return Inet6Address.getByAddress(null /* host */, addr, scopeId);
        }

        return InetAddress.getByAddress(addr);
    }

    /**
    /**
     * Implement the Parcelable interface.
     * Implement the Parcelable interface.
     */
     */
@@ -1643,14 +1665,13 @@ public final class LinkProperties implements Parcelable {
                addressCount = in.readInt();
                addressCount = in.readInt();
                for (int i = 0; i < addressCount; i++) {
                for (int i = 0; i < addressCount; i++) {
                    try {
                    try {
                        netProp.addDnsServer(InetAddress.getByAddress(in.createByteArray()));
                        netProp.addDnsServer(readAddress(in));
                    } catch (UnknownHostException e) { }
                    } catch (UnknownHostException e) { }
                }
                }
                addressCount = in.readInt();
                addressCount = in.readInt();
                for (int i = 0; i < addressCount; i++) {
                for (int i = 0; i < addressCount; i++) {
                    try {
                    try {
                        netProp.addValidatedPrivateDnsServer(
                        netProp.addValidatedPrivateDnsServer(readAddress(in));
                                InetAddress.getByAddress(in.createByteArray()));
                    } catch (UnknownHostException e) { }
                    } catch (UnknownHostException e) { }
                }
                }
                netProp.setUsePrivateDns(in.readBoolean());
                netProp.setUsePrivateDns(in.readBoolean());
@@ -1658,7 +1679,7 @@ public final class LinkProperties implements Parcelable {
                addressCount = in.readInt();
                addressCount = in.readInt();
                for (int i = 0; i < addressCount; i++) {
                for (int i = 0; i < addressCount; i++) {
                    try {
                    try {
                        netProp.addPcscfServer(InetAddress.getByAddress(in.createByteArray()));
                        netProp.addPcscfServer(readAddress(in));
                    } catch (UnknownHostException e) { }
                    } catch (UnknownHostException e) { }
                }
                }
                netProp.setDomains(in.readString());
                netProp.setDomains(in.readString());
+67 −42
Original line number Original line Diff line number Diff line
@@ -31,6 +31,7 @@ import android.util.ArraySet;
import androidx.test.filters.SmallTest;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import androidx.test.runner.AndroidJUnit4;


import com.android.internal.util.ParcelableTestUtil;
import com.android.internal.util.TestUtils;
import com.android.internal.util.TestUtils;


import org.junit.Test;
import org.junit.Test;
@@ -47,25 +48,22 @@ import java.util.Set;
@RunWith(AndroidJUnit4.class)
@RunWith(AndroidJUnit4.class)
@SmallTest
@SmallTest
public class LinkPropertiesTest {
public class LinkPropertiesTest {
    private static final InetAddress ADDRV4 = InetAddresses.parseNumericAddress("75.208.6.1");
    private static final InetAddress ADDRV4 = address("75.208.6.1");
    private static final InetAddress ADDRV6 = InetAddresses.parseNumericAddress(
    private static final InetAddress ADDRV6 = address("2001:0db8:85a3:0000:0000:8a2e:0370:7334");
            "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
    private static final InetAddress DNS1 = address("75.208.7.1");
    private static final InetAddress DNS1 = InetAddresses.parseNumericAddress("75.208.7.1");
    private static final InetAddress DNS2 = address("69.78.7.1");
    private static final InetAddress DNS2 = InetAddresses.parseNumericAddress("69.78.7.1");
    private static final InetAddress DNS6 = address("2001:4860:4860::8888");
    private static final InetAddress DNS6 = InetAddresses.parseNumericAddress(
    private static final InetAddress PRIVDNS1 = address("1.1.1.1");
            "2001:4860:4860::8888");
    private static final InetAddress PRIVDNS2 = address("1.0.0.1");
    private static final InetAddress PRIVDNS1 = InetAddresses.parseNumericAddress("1.1.1.1");
    private static final InetAddress PRIVDNS6 = address("2606:4700:4700::1111");
    private static final InetAddress PRIVDNS2 = InetAddresses.parseNumericAddress("1.0.0.1");
    private static final InetAddress PCSCFV4 = address("10.77.25.37");
    private static final InetAddress PRIVDNS6 = InetAddresses.parseNumericAddress(
    private static final InetAddress PCSCFV6 = address("2001:0db8:85a3:0000:0000:8a2e:0370:1");
            "2606:4700:4700::1111");
    private static final InetAddress GATEWAY1 = address("75.208.8.1");
    private static final InetAddress PCSCFV4 = InetAddresses.parseNumericAddress("10.77.25.37");
    private static final InetAddress GATEWAY2 = address("69.78.8.1");
    private static final InetAddress PCSCFV6 = InetAddresses.parseNumericAddress(
    private static final InetAddress GATEWAY61 = address("fe80::6:0000:613");
            "2001:0db8:85a3:0000:0000:8a2e:0370:1");
    private static final InetAddress GATEWAY62 = address("fe80::6:22%lo");
    private static final InetAddress GATEWAY1 = InetAddresses.parseNumericAddress("75.208.8.1");
    private static final InetAddress TESTIPV4ADDR = address("192.168.47.42");
    private static final InetAddress GATEWAY2 = InetAddresses.parseNumericAddress("69.78.8.1");
    private static final InetAddress TESTIPV6ADDR = address("fe80::7:33%43");
    private static final InetAddress GATEWAY61 = InetAddresses.parseNumericAddress(
            "fe80::6:0000:613");
    private static final InetAddress GATEWAY62 = InetAddresses.parseNumericAddress("fe80::6:2222");
    private static final String NAME = "qmi0";
    private static final String NAME = "qmi0";
    private static final String DOMAINS = "google.com";
    private static final String DOMAINS = "google.com";
    private static final String PRIV_DNS_SERVER_NAME = "private.dns.com";
    private static final String PRIV_DNS_SERVER_NAME = "private.dns.com";
@@ -75,8 +73,7 @@ public class LinkPropertiesTest {
    private static final LinkAddress LINKADDRV6 = new LinkAddress(ADDRV6, 128);
    private static final LinkAddress LINKADDRV6 = new LinkAddress(ADDRV6, 128);
    private static final LinkAddress LINKADDRV6LINKLOCAL = new LinkAddress("fe80::1/64");
    private static final LinkAddress LINKADDRV6LINKLOCAL = new LinkAddress("fe80::1/64");


    // TODO: replace all calls to NetworkUtils.numericToInetAddress with calls to this method.
    private static InetAddress address(String addrString) {
    private InetAddress Address(String addrString) {
        return InetAddresses.parseNumericAddress(addrString);
        return InetAddresses.parseNumericAddress(addrString);
    }
    }


@@ -223,7 +220,7 @@ public class LinkPropertiesTest {
        target.clear();
        target.clear();
        target.setInterfaceName(NAME);
        target.setInterfaceName(NAME);
        // change link addresses
        // change link addresses
        target.addLinkAddress(new LinkAddress(Address("75.208.6.2"), 32));
        target.addLinkAddress(new LinkAddress(address("75.208.6.2"), 32));
        target.addLinkAddress(LINKADDRV6);
        target.addLinkAddress(LINKADDRV6);
        target.addDnsServer(DNS1);
        target.addDnsServer(DNS1);
        target.addDnsServer(DNS2);
        target.addDnsServer(DNS2);
@@ -238,7 +235,7 @@ public class LinkPropertiesTest {
        target.addLinkAddress(LINKADDRV4);
        target.addLinkAddress(LINKADDRV4);
        target.addLinkAddress(LINKADDRV6);
        target.addLinkAddress(LINKADDRV6);
        // change dnses
        // change dnses
        target.addDnsServer(Address("75.208.7.2"));
        target.addDnsServer(address("75.208.7.2"));
        target.addDnsServer(DNS2);
        target.addDnsServer(DNS2);
        target.addPcscfServer(PCSCFV6);
        target.addPcscfServer(PCSCFV6);
        target.addRoute(new RouteInfo(GATEWAY1));
        target.addRoute(new RouteInfo(GATEWAY1));
@@ -250,10 +247,10 @@ public class LinkPropertiesTest {
        target.setInterfaceName(NAME);
        target.setInterfaceName(NAME);
        target.addLinkAddress(LINKADDRV4);
        target.addLinkAddress(LINKADDRV4);
        target.addLinkAddress(LINKADDRV6);
        target.addLinkAddress(LINKADDRV6);
        target.addDnsServer(Address("75.208.7.2"));
        target.addDnsServer(address("75.208.7.2"));
        target.addDnsServer(DNS2);
        target.addDnsServer(DNS2);
        // change pcscf
        // change pcscf
        target.addPcscfServer(Address("2001::1"));
        target.addPcscfServer(address("2001::1"));
        target.addRoute(new RouteInfo(GATEWAY1));
        target.addRoute(new RouteInfo(GATEWAY1));
        target.addRoute(new RouteInfo(GATEWAY2));
        target.addRoute(new RouteInfo(GATEWAY2));
        target.setMtu(MTU);
        target.setMtu(MTU);
@@ -266,9 +263,9 @@ public class LinkPropertiesTest {
        target.addDnsServer(DNS1);
        target.addDnsServer(DNS1);
        target.addDnsServer(DNS2);
        target.addDnsServer(DNS2);
        // change gateway
        // change gateway
        target.addRoute(new RouteInfo(Address("75.208.8.2")));
        target.addRoute(new RouteInfo(address("75.208.8.2")));
        target.addRoute(new RouteInfo(GATEWAY2));
        target.setMtu(MTU);
        target.setMtu(MTU);
        target.addRoute(new RouteInfo(GATEWAY2));
        assertFalse(source.equals(target));
        assertFalse(source.equals(target));


        target.clear();
        target.clear();
@@ -344,7 +341,7 @@ public class LinkPropertiesTest {


    @Test
    @Test
    public void testRouteInterfaces() {
    public void testRouteInterfaces() {
        LinkAddress prefix = new LinkAddress(Address("2001:db8::"), 32);
        LinkAddress prefix = new LinkAddress(address("2001:db8::"), 32);
        InetAddress address = ADDRV6;
        InetAddress address = ADDRV6;


        // Add a route with no interface to a LinkProperties with no interface. No errors.
        // Add a route with no interface to a LinkProperties with no interface. No errors.
@@ -734,8 +731,7 @@ public class LinkPropertiesTest {


        // Add an on-link route, making the on-link DNS server reachable,
        // Add an on-link route, making the on-link DNS server reachable,
        // but there is still no IPv4 address.
        // but there is still no IPv4 address.
        assertTrue(v4lp.addRoute(new RouteInfo(
        assertTrue(v4lp.addRoute(new RouteInfo(new IpPrefix(address("75.208.0.0"), 16))));
                new IpPrefix(NetworkUtils.numericToInetAddress("75.208.0.0"), 16))));
        assertFalse(v4lp.isReachable(DNS1));
        assertFalse(v4lp.isReachable(DNS1));
        assertFalse(v4lp.isReachable(DNS2));
        assertFalse(v4lp.isReachable(DNS2));


@@ -751,9 +747,9 @@ public class LinkPropertiesTest {
        assertTrue(v4lp.isReachable(DNS2));
        assertTrue(v4lp.isReachable(DNS2));


        final LinkProperties v6lp = new LinkProperties();
        final LinkProperties v6lp = new LinkProperties();
        final InetAddress kLinkLocalDns = Address("fe80::6:1");
        final InetAddress kLinkLocalDns = address("fe80::6:1");
        final InetAddress kLinkLocalDnsWithScope = Address("fe80::6:2%43");
        final InetAddress kLinkLocalDnsWithScope = address("fe80::6:2%43");
        final InetAddress kOnLinkDns = Address("2001:db8:85a3::53");
        final InetAddress kOnLinkDns = address("2001:db8:85a3::53");
        assertFalse(v6lp.isReachable(kLinkLocalDns));
        assertFalse(v6lp.isReachable(kLinkLocalDns));
        assertFalse(v6lp.isReachable(kLinkLocalDnsWithScope));
        assertFalse(v6lp.isReachable(kLinkLocalDnsWithScope));
        assertFalse(v6lp.isReachable(kOnLinkDns));
        assertFalse(v6lp.isReachable(kOnLinkDns));
@@ -762,7 +758,7 @@ public class LinkPropertiesTest {
        // Add a link-local route, making the link-local DNS servers reachable. Because
        // Add a link-local route, making the link-local DNS servers reachable. Because
        // we assume the presence of an IPv6 link-local address, link-local DNS servers
        // we assume the presence of an IPv6 link-local address, link-local DNS servers
        // are considered reachable, but only those with a non-zero scope identifier.
        // are considered reachable, but only those with a non-zero scope identifier.
        assertTrue(v6lp.addRoute(new RouteInfo(new IpPrefix(Address("fe80::"), 64))));
        assertTrue(v6lp.addRoute(new RouteInfo(new IpPrefix(address("fe80::"), 64))));
        assertFalse(v6lp.isReachable(kLinkLocalDns));
        assertFalse(v6lp.isReachable(kLinkLocalDns));
        assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
        assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
        assertFalse(v6lp.isReachable(kOnLinkDns));
        assertFalse(v6lp.isReachable(kOnLinkDns));
@@ -778,7 +774,7 @@ public class LinkPropertiesTest {
        // Add a global route on link, but no global address yet. DNS servers reachable
        // Add a global route on link, but no global address yet. DNS servers reachable
        // via a route that doesn't require a gateway: give them the benefit of the
        // via a route that doesn't require a gateway: give them the benefit of the
        // doubt and hope the link-local source address suffices for communication.
        // doubt and hope the link-local source address suffices for communication.
        assertTrue(v6lp.addRoute(new RouteInfo(new IpPrefix(Address("2001:db8:85a3::"), 64))));
        assertTrue(v6lp.addRoute(new RouteInfo(new IpPrefix(address("2001:db8:85a3::"), 64))));
        assertFalse(v6lp.isReachable(kLinkLocalDns));
        assertFalse(v6lp.isReachable(kLinkLocalDns));
        assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
        assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
        assertTrue(v6lp.isReachable(kOnLinkDns));
        assertTrue(v6lp.isReachable(kOnLinkDns));
@@ -807,7 +803,7 @@ public class LinkPropertiesTest {
        stacked.setInterfaceName("v4-test0");
        stacked.setInterfaceName("v4-test0");
        v6lp.addStackedLink(stacked);
        v6lp.addStackedLink(stacked);


        InetAddress stackedAddress = Address("192.0.0.4");
        InetAddress stackedAddress = address("192.0.0.4");
        LinkAddress stackedLinkAddress = new LinkAddress(stackedAddress, 32);
        LinkAddress stackedLinkAddress = new LinkAddress(stackedAddress, 32);
        assertFalse(v6lp.isReachable(stackedAddress));
        assertFalse(v6lp.isReachable(stackedAddress));
        stacked.addLinkAddress(stackedLinkAddress);
        stacked.addLinkAddress(stackedLinkAddress);
@@ -840,7 +836,7 @@ public class LinkPropertiesTest {
        LinkProperties rmnet1 = new LinkProperties();
        LinkProperties rmnet1 = new LinkProperties();
        rmnet1.setInterfaceName("rmnet1");
        rmnet1.setInterfaceName("rmnet1");
        rmnet1.addLinkAddress(new LinkAddress("10.0.0.3/8"));
        rmnet1.addLinkAddress(new LinkAddress("10.0.0.3/8"));
        RouteInfo defaultRoute1 = new RouteInfo((IpPrefix) null, Address("10.0.0.1"),
        RouteInfo defaultRoute1 = new RouteInfo((IpPrefix) null, address("10.0.0.1"),
                rmnet1.getInterfaceName());
                rmnet1.getInterfaceName());
        RouteInfo directRoute1 = new RouteInfo(new IpPrefix("10.0.0.0/8"), null,
        RouteInfo directRoute1 = new RouteInfo(new IpPrefix("10.0.0.0/8"), null,
                rmnet1.getInterfaceName());
                rmnet1.getInterfaceName());
@@ -859,7 +855,7 @@ public class LinkPropertiesTest {
        rmnet2.setInterfaceName("rmnet2");
        rmnet2.setInterfaceName("rmnet2");
        rmnet2.addLinkAddress(new LinkAddress("fe80::cafe/64"));
        rmnet2.addLinkAddress(new LinkAddress("fe80::cafe/64"));
        rmnet2.addLinkAddress(new LinkAddress("2001:db8::2/64"));
        rmnet2.addLinkAddress(new LinkAddress("2001:db8::2/64"));
        RouteInfo defaultRoute2 = new RouteInfo((IpPrefix) null, Address("2001:db8::1"),
        RouteInfo defaultRoute2 = new RouteInfo((IpPrefix) null, address("2001:db8::1"),
                rmnet2.getInterfaceName());
                rmnet2.getInterfaceName());
        RouteInfo directRoute2 = new RouteInfo(new IpPrefix("2001:db8::/64"), null,
        RouteInfo directRoute2 = new RouteInfo(new IpPrefix("2001:db8::/64"), null,
                rmnet2.getInterfaceName());
                rmnet2.getInterfaceName());
@@ -925,24 +921,53 @@ public class LinkPropertiesTest {
    public void testLinkPropertiesParcelable() throws Exception {
    public void testLinkPropertiesParcelable() throws Exception {
        LinkProperties source = new LinkProperties();
        LinkProperties source = new LinkProperties();
        source.setInterfaceName(NAME);
        source.setInterfaceName(NAME);
        // set 2 link addresses

        source.addLinkAddress(LINKADDRV4);
        source.addLinkAddress(LINKADDRV4);
        source.addLinkAddress(LINKADDRV6);
        source.addLinkAddress(LINKADDRV6);
        // set 2 dnses

        source.addDnsServer(DNS1);
        source.addDnsServer(DNS1);
        source.addDnsServer(DNS2);
        source.addDnsServer(DNS2);
        // set 2 gateways
        source.addDnsServer(GATEWAY62);

        source.addPcscfServer(TESTIPV4ADDR);
        source.addPcscfServer(TESTIPV6ADDR);

        source.setUsePrivateDns(true);
        source.setPrivateDnsServerName(PRIV_DNS_SERVER_NAME);

        source.setDomains(DOMAINS);

        source.addRoute(new RouteInfo(GATEWAY1));
        source.addRoute(new RouteInfo(GATEWAY1));
        source.addRoute(new RouteInfo(GATEWAY2));
        source.addRoute(new RouteInfo(GATEWAY2));
        // set 2 validated private dnses

        source.addValidatedPrivateDnsServer(DNS6);
        source.addValidatedPrivateDnsServer(DNS6);
        source.addValidatedPrivateDnsServer(GATEWAY61);
        source.addValidatedPrivateDnsServer(GATEWAY61);
        source.addValidatedPrivateDnsServer(TESTIPV6ADDR);

        source.setHttpProxy(ProxyInfo.buildDirectProxy("test", 8888));


        source.setMtu(MTU);
        source.setMtu(MTU);


        source.setTcpBufferSizes(TCP_BUFFER_SIZES);

        source.setNat64Prefix(new IpPrefix("2001:db8:1:2:64:64::/96"));
        source.setNat64Prefix(new IpPrefix("2001:db8:1:2:64:64::/96"));


        final LinkProperties stacked = new LinkProperties();
        stacked.setInterfaceName("test-stacked");
        source.addStackedLink(stacked);

        TestUtils.assertParcelingIsLossless(source);
        TestUtils.assertParcelingIsLossless(source);
        ParcelableTestUtil.assertFieldCountEquals(14, LinkProperties.class);
    }

    @Test
    public void testLinkLocalDnsServerParceling() throws Exception {
        final String strAddress = "fe80::1%lo";
        final LinkProperties lp = new LinkProperties();
        lp.addDnsServer(address(strAddress));
        final LinkProperties unparceled = TestUtils.parcelingRoundTrip(lp);
        // Inet6Address#equals does not test for the scope id
        assertEquals(strAddress, unparceled.getDnsServers().get(0).getHostAddress());
    }
    }


    @Test
    @Test