Loading core/java/android/net/LinkAddress.java +25 −1 Original line number Diff line number Diff line Loading @@ -21,12 +21,14 @@ import android.os.Parcelable; import android.util.Pair; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; import java.net.InterfaceAddress; import java.net.UnknownHostException; import static android.system.OsConstants.IFA_F_DADFAILED; import static android.system.OsConstants.IFA_F_DEPRECATED; import static android.system.OsConstants.IFA_F_OPTIMISTIC; import static android.system.OsConstants.IFA_F_TENTATIVE; import static android.system.OsConstants.RT_SCOPE_HOST; import static android.system.OsConstants.RT_SCOPE_LINK; Loading Loading @@ -92,6 +94,20 @@ public class LinkAddress implements Parcelable { return RT_SCOPE_UNIVERSE; } /** * Utility function to check if |address| is a Unique Local IPv6 Unicast Address * (a.k.a. "ULA"; RFC 4193). * * Per RFC 4193 section 8, fc00::/7 identifies these addresses. */ private boolean isIPv6ULA() { if (address != null && address instanceof Inet6Address) { byte[] bytes = address.getAddress(); return ((bytes[0] & (byte)0xfc) == (byte)0xfc); } return false; } /** * Utility function for the constructors. */ Loading Loading @@ -268,8 +284,16 @@ public class LinkAddress implements Parcelable { * @hide */ public boolean isGlobalPreferred() { /** * Note that addresses flagged as IFA_F_OPTIMISTIC are * simultaneously flagged as IFA_F_TENTATIVE (when the tentative * state has cleared either DAD has succeeded or failed, and both * flags are cleared regardless). */ return (scope == RT_SCOPE_UNIVERSE && (flags & (IFA_F_DADFAILED | IFA_F_DEPRECATED | IFA_F_TENTATIVE)) == 0L); !isIPv6ULA() && (flags & (IFA_F_DADFAILED | IFA_F_DEPRECATED)) == 0L && ((flags & IFA_F_TENTATIVE) == 0L || (flags & IFA_F_OPTIMISTIC) != 0L)); } /** Loading core/tests/coretests/src/android/net/LinkAddressTest.java +72 −0 Original line number Diff line number Diff line Loading @@ -33,8 +33,11 @@ import android.test.AndroidTestCase; import static android.test.MoreAsserts.assertNotEqual; import android.test.suitebuilder.annotation.SmallTest; import static android.system.OsConstants.IFA_F_DADFAILED; import static android.system.OsConstants.IFA_F_DEPRECATED; import static android.system.OsConstants.IFA_F_OPTIMISTIC; import static android.system.OsConstants.IFA_F_PERMANENT; import static android.system.OsConstants.IFA_F_TEMPORARY; import static android.system.OsConstants.IFA_F_TENTATIVE; import static android.system.OsConstants.RT_SCOPE_HOST; import static android.system.OsConstants.RT_SCOPE_LINK; Loading Loading @@ -340,4 +343,73 @@ public class LinkAddressTest extends AndroidTestCase { l = new LinkAddress(V4 + "/28", IFA_F_PERMANENT, RT_SCOPE_LINK); assertParcelingIsLossless(l); } private void assertGlobalPreferred(LinkAddress l, String msg) { assertTrue(msg, l.isGlobalPreferred()); } private void assertNotGlobalPreferred(LinkAddress l, String msg) { assertFalse(msg, l.isGlobalPreferred()); } public void testIsGlobalPreferred() { LinkAddress l; l = new LinkAddress(V4_ADDRESS, 32, 0, RT_SCOPE_UNIVERSE); assertGlobalPreferred(l, "v4,global,noflags"); l = new LinkAddress("10.10.1.7/23", 0, RT_SCOPE_UNIVERSE); assertGlobalPreferred(l, "v4-rfc1918,global,noflags"); l = new LinkAddress("10.10.1.7/23", 0, RT_SCOPE_SITE); assertNotGlobalPreferred(l, "v4-rfc1918,site-local,noflags"); l = new LinkAddress("127.0.0.7/8", 0, RT_SCOPE_HOST); assertNotGlobalPreferred(l, "v4-localhost,node-local,noflags"); l = new LinkAddress(V6_ADDRESS, 64, 0, RT_SCOPE_UNIVERSE); assertGlobalPreferred(l, "v6,global,noflags"); l = new LinkAddress(V6_ADDRESS, 64, IFA_F_PERMANENT, RT_SCOPE_UNIVERSE); assertGlobalPreferred(l, "v6,global,permanent"); // IPv6 ULAs are not acceptable "global preferred" addresses. l = new LinkAddress("fc12::1/64", 0, RT_SCOPE_UNIVERSE); assertNotGlobalPreferred(l, "v6,ula1,noflags"); l = new LinkAddress("fd34::1/64", 0, RT_SCOPE_UNIVERSE); assertNotGlobalPreferred(l, "v6,ula2,noflags"); l = new LinkAddress(V6_ADDRESS, 64, IFA_F_TEMPORARY, RT_SCOPE_UNIVERSE); assertGlobalPreferred(l, "v6,global,tempaddr"); l = new LinkAddress(V6_ADDRESS, 64, (IFA_F_TEMPORARY|IFA_F_DADFAILED), RT_SCOPE_UNIVERSE); assertNotGlobalPreferred(l, "v6,global,tempaddr+dadfailed"); l = new LinkAddress(V6_ADDRESS, 64, (IFA_F_TEMPORARY|IFA_F_DEPRECATED), RT_SCOPE_UNIVERSE); assertNotGlobalPreferred(l, "v6,global,tempaddr+deprecated"); l = new LinkAddress(V6_ADDRESS, 64, IFA_F_TEMPORARY, RT_SCOPE_SITE); assertNotGlobalPreferred(l, "v6,site-local,tempaddr"); l = new LinkAddress(V6_ADDRESS, 64, IFA_F_TEMPORARY, RT_SCOPE_LINK); assertNotGlobalPreferred(l, "v6,link-local,tempaddr"); l = new LinkAddress(V6_ADDRESS, 64, IFA_F_TEMPORARY, RT_SCOPE_HOST); assertNotGlobalPreferred(l, "v6,node-local,tempaddr"); l = new LinkAddress("::1/128", IFA_F_PERMANENT, RT_SCOPE_HOST); assertNotGlobalPreferred(l, "v6-localhost,node-local,permanent"); l = new LinkAddress(V6_ADDRESS, 64, (IFA_F_TEMPORARY|IFA_F_TENTATIVE), RT_SCOPE_UNIVERSE); assertNotGlobalPreferred(l, "v6,global,tempaddr+tentative"); l = new LinkAddress(V6_ADDRESS, 64, (IFA_F_TEMPORARY|IFA_F_TENTATIVE|IFA_F_OPTIMISTIC), RT_SCOPE_UNIVERSE); assertGlobalPreferred(l, "v6,global,tempaddr+optimistic"); } } Loading
core/java/android/net/LinkAddress.java +25 −1 Original line number Diff line number Diff line Loading @@ -21,12 +21,14 @@ import android.os.Parcelable; import android.util.Pair; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; import java.net.InterfaceAddress; import java.net.UnknownHostException; import static android.system.OsConstants.IFA_F_DADFAILED; import static android.system.OsConstants.IFA_F_DEPRECATED; import static android.system.OsConstants.IFA_F_OPTIMISTIC; import static android.system.OsConstants.IFA_F_TENTATIVE; import static android.system.OsConstants.RT_SCOPE_HOST; import static android.system.OsConstants.RT_SCOPE_LINK; Loading Loading @@ -92,6 +94,20 @@ public class LinkAddress implements Parcelable { return RT_SCOPE_UNIVERSE; } /** * Utility function to check if |address| is a Unique Local IPv6 Unicast Address * (a.k.a. "ULA"; RFC 4193). * * Per RFC 4193 section 8, fc00::/7 identifies these addresses. */ private boolean isIPv6ULA() { if (address != null && address instanceof Inet6Address) { byte[] bytes = address.getAddress(); return ((bytes[0] & (byte)0xfc) == (byte)0xfc); } return false; } /** * Utility function for the constructors. */ Loading Loading @@ -268,8 +284,16 @@ public class LinkAddress implements Parcelable { * @hide */ public boolean isGlobalPreferred() { /** * Note that addresses flagged as IFA_F_OPTIMISTIC are * simultaneously flagged as IFA_F_TENTATIVE (when the tentative * state has cleared either DAD has succeeded or failed, and both * flags are cleared regardless). */ return (scope == RT_SCOPE_UNIVERSE && (flags & (IFA_F_DADFAILED | IFA_F_DEPRECATED | IFA_F_TENTATIVE)) == 0L); !isIPv6ULA() && (flags & (IFA_F_DADFAILED | IFA_F_DEPRECATED)) == 0L && ((flags & IFA_F_TENTATIVE) == 0L || (flags & IFA_F_OPTIMISTIC) != 0L)); } /** Loading
core/tests/coretests/src/android/net/LinkAddressTest.java +72 −0 Original line number Diff line number Diff line Loading @@ -33,8 +33,11 @@ import android.test.AndroidTestCase; import static android.test.MoreAsserts.assertNotEqual; import android.test.suitebuilder.annotation.SmallTest; import static android.system.OsConstants.IFA_F_DADFAILED; import static android.system.OsConstants.IFA_F_DEPRECATED; import static android.system.OsConstants.IFA_F_OPTIMISTIC; import static android.system.OsConstants.IFA_F_PERMANENT; import static android.system.OsConstants.IFA_F_TEMPORARY; import static android.system.OsConstants.IFA_F_TENTATIVE; import static android.system.OsConstants.RT_SCOPE_HOST; import static android.system.OsConstants.RT_SCOPE_LINK; Loading Loading @@ -340,4 +343,73 @@ public class LinkAddressTest extends AndroidTestCase { l = new LinkAddress(V4 + "/28", IFA_F_PERMANENT, RT_SCOPE_LINK); assertParcelingIsLossless(l); } private void assertGlobalPreferred(LinkAddress l, String msg) { assertTrue(msg, l.isGlobalPreferred()); } private void assertNotGlobalPreferred(LinkAddress l, String msg) { assertFalse(msg, l.isGlobalPreferred()); } public void testIsGlobalPreferred() { LinkAddress l; l = new LinkAddress(V4_ADDRESS, 32, 0, RT_SCOPE_UNIVERSE); assertGlobalPreferred(l, "v4,global,noflags"); l = new LinkAddress("10.10.1.7/23", 0, RT_SCOPE_UNIVERSE); assertGlobalPreferred(l, "v4-rfc1918,global,noflags"); l = new LinkAddress("10.10.1.7/23", 0, RT_SCOPE_SITE); assertNotGlobalPreferred(l, "v4-rfc1918,site-local,noflags"); l = new LinkAddress("127.0.0.7/8", 0, RT_SCOPE_HOST); assertNotGlobalPreferred(l, "v4-localhost,node-local,noflags"); l = new LinkAddress(V6_ADDRESS, 64, 0, RT_SCOPE_UNIVERSE); assertGlobalPreferred(l, "v6,global,noflags"); l = new LinkAddress(V6_ADDRESS, 64, IFA_F_PERMANENT, RT_SCOPE_UNIVERSE); assertGlobalPreferred(l, "v6,global,permanent"); // IPv6 ULAs are not acceptable "global preferred" addresses. l = new LinkAddress("fc12::1/64", 0, RT_SCOPE_UNIVERSE); assertNotGlobalPreferred(l, "v6,ula1,noflags"); l = new LinkAddress("fd34::1/64", 0, RT_SCOPE_UNIVERSE); assertNotGlobalPreferred(l, "v6,ula2,noflags"); l = new LinkAddress(V6_ADDRESS, 64, IFA_F_TEMPORARY, RT_SCOPE_UNIVERSE); assertGlobalPreferred(l, "v6,global,tempaddr"); l = new LinkAddress(V6_ADDRESS, 64, (IFA_F_TEMPORARY|IFA_F_DADFAILED), RT_SCOPE_UNIVERSE); assertNotGlobalPreferred(l, "v6,global,tempaddr+dadfailed"); l = new LinkAddress(V6_ADDRESS, 64, (IFA_F_TEMPORARY|IFA_F_DEPRECATED), RT_SCOPE_UNIVERSE); assertNotGlobalPreferred(l, "v6,global,tempaddr+deprecated"); l = new LinkAddress(V6_ADDRESS, 64, IFA_F_TEMPORARY, RT_SCOPE_SITE); assertNotGlobalPreferred(l, "v6,site-local,tempaddr"); l = new LinkAddress(V6_ADDRESS, 64, IFA_F_TEMPORARY, RT_SCOPE_LINK); assertNotGlobalPreferred(l, "v6,link-local,tempaddr"); l = new LinkAddress(V6_ADDRESS, 64, IFA_F_TEMPORARY, RT_SCOPE_HOST); assertNotGlobalPreferred(l, "v6,node-local,tempaddr"); l = new LinkAddress("::1/128", IFA_F_PERMANENT, RT_SCOPE_HOST); assertNotGlobalPreferred(l, "v6-localhost,node-local,permanent"); l = new LinkAddress(V6_ADDRESS, 64, (IFA_F_TEMPORARY|IFA_F_TENTATIVE), RT_SCOPE_UNIVERSE); assertNotGlobalPreferred(l, "v6,global,tempaddr+tentative"); l = new LinkAddress(V6_ADDRESS, 64, (IFA_F_TEMPORARY|IFA_F_TENTATIVE|IFA_F_OPTIMISTIC), RT_SCOPE_UNIVERSE); assertGlobalPreferred(l, "v6,global,tempaddr+optimistic"); } }