diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java index e88292f507..61acf2b841 100644 --- a/core/java/android/net/LinkProperties.java +++ b/core/java/android/net/LinkProperties.java @@ -54,7 +54,7 @@ public class LinkProperties implements Parcelable { String mIfaceName; private Collection mLinkAddresses; private Collection mDnses; - private Collection mGateways; + private Collection mRoutes; private ProxyProperties mHttpProxy; public LinkProperties() { @@ -67,7 +67,7 @@ public class LinkProperties implements Parcelable { mIfaceName = source.getInterfaceName(); mLinkAddresses = source.getLinkAddresses(); mDnses = source.getDnses(); - mGateways = source.getGateways(); + mRoutes = source.getRoutes(); mHttpProxy = new ProxyProperties(source.getHttpProxy()); } } @@ -104,11 +104,11 @@ public class LinkProperties implements Parcelable { return Collections.unmodifiableCollection(mDnses); } - public void addGateway(InetAddress gateway) { - if (gateway != null) mGateways.add(gateway); + public void addRoute(RouteInfo route) { + if (route != null) mRoutes.add(route); } - public Collection getGateways() { - return Collections.unmodifiableCollection(mGateways); + public Collection getRoutes() { + return Collections.unmodifiableCollection(mRoutes); } public void setHttpProxy(ProxyProperties proxy) { @@ -122,7 +122,7 @@ public class LinkProperties implements Parcelable { mIfaceName = null; mLinkAddresses = new ArrayList(); mDnses = new ArrayList(); - mGateways = new ArrayList(); + mRoutes = new ArrayList(); mHttpProxy = null; } @@ -146,12 +146,12 @@ public class LinkProperties implements Parcelable { for (InetAddress addr : mDnses) dns += addr.getHostAddress() + ","; dns += "] "; - String gateways = "Gateways: ["; - for (InetAddress gw : mGateways) gateways += gw.getHostAddress() + ","; - gateways += "] "; + String routes = "Routes: ["; + for (RouteInfo route : mRoutes) routes += route.toString() + ","; + routes += "] "; String proxy = (mHttpProxy == null ? "" : "HttpProxy: " + mHttpProxy.toString() + " "); - return ifaceName + linkAddresses + gateways + dns + proxy; + return ifaceName + linkAddresses + routes + dns + proxy; } @@ -177,7 +177,7 @@ public class LinkProperties implements Parcelable { boolean sameAddresses; boolean sameDnses; - boolean sameGateways; + boolean sameRoutes; LinkProperties target = (LinkProperties) obj; @@ -190,12 +190,12 @@ public class LinkProperties implements Parcelable { sameDnses = (mDnses.size() == targetDnses.size()) ? mDnses.containsAll(targetDnses) : false; - Collection targetGateways = target.getGateways(); - sameGateways = (mGateways.size() == targetGateways.size()) ? - mGateways.containsAll(targetGateways) : false; + Collection targetRoutes = target.getRoutes(); + sameRoutes = (mRoutes.size() == targetRoutes.size()) ? + mRoutes.containsAll(targetRoutes) : false; return - sameAddresses && sameDnses && sameGateways + sameAddresses && sameDnses && sameRoutes && TextUtils.equals(getInterfaceName(), target.getInterfaceName()) && (getHttpProxy() == null ? target.getHttpProxy() == null : getHttpProxy().equals(target.getHttpProxy())); @@ -211,7 +211,7 @@ public class LinkProperties implements Parcelable { return ((null == mIfaceName) ? 0 : mIfaceName.hashCode() + mLinkAddresses.size() * 31 + mDnses.size() * 37 - + mGateways.size() * 41 + + mRoutes.size() * 41 + ((null == mHttpProxy) ? 0 : mHttpProxy.hashCode())); } @@ -231,9 +231,9 @@ public class LinkProperties implements Parcelable { dest.writeByteArray(d.getAddress()); } - dest.writeInt(mGateways.size()); - for(InetAddress gw : mGateways) { - dest.writeByteArray(gw.getAddress()); + dest.writeInt(mRoutes.size()); + for(RouteInfo route : mRoutes) { + dest.writeParcelable(route, flags); } if (mHttpProxy != null) { @@ -272,9 +272,7 @@ public class LinkProperties implements Parcelable { } addressCount = in.readInt(); for (int i=0; i CREATOR = + new Creator() { + public RouteInfo createFromParcel(Parcel in) { + InetAddress destAddr = null; + int prefix = 0; + InetAddress gateway = null; + + if (in.readByte() == 1) { + byte[] addr = in.createByteArray(); + prefix = in.readInt(); + + try { + destAddr = InetAddress.getByAddress(addr); + } catch (UnknownHostException e) {} + } + + if (in.readByte() == 1) { + byte[] addr = in.createByteArray(); + + try { + gateway = InetAddress.getByAddress(addr); + } catch (UnknownHostException e) {} + } + + LinkAddress dest = null; + + if (destAddr != null) { + dest = new LinkAddress(destAddr, prefix); + } + + return new RouteInfo(dest, gateway); + } + + public RouteInfo[] newArray(int size) { + return new RouteInfo[size]; + } + }; +} diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp index 9f675a24df..548376df52 100644 --- a/core/jni/android_net_NetUtils.cpp +++ b/core/jni/android_net_NetUtils.cpp @@ -67,7 +67,6 @@ namespace android { static struct fieldIds { jmethodID constructorId; jfieldID ipaddress; - jfieldID gateway; jfieldID prefixLength; jfieldID dns1; jfieldID dns2; @@ -181,7 +180,30 @@ static jboolean android_net_utils_runDhcpCommon(JNIEnv* env, jobject clazz, jstr env->ReleaseStringUTFChars(ifname, nameStr); if (result == 0) { env->SetObjectField(info, dhcpInfoInternalFieldIds.ipaddress, env->NewStringUTF(ipaddr)); - env->SetObjectField(info, dhcpInfoInternalFieldIds.gateway, env->NewStringUTF(gateway)); + + // set the gateway + jclass cls = env->FindClass("java/net/InetAddress"); + jmethodID method = env->GetStaticMethodID(cls, "getByName", + "(Ljava/lang/String;)Ljava/net/InetAddress;"); + jvalue args[1]; + args[0].l = env->NewStringUTF(gateway); + jobject inetAddressObject = env->CallStaticObjectMethodA(cls, method, args); + + if (!env->ExceptionOccurred()) { + cls = env->FindClass("android/net/RouteInfo"); + method = env->GetMethodID(cls, "", "(Ljava/net/InetAddress;)V"); + args[0].l = inetAddressObject; + jobject routeInfoObject = env->NewObjectA(cls, method, args); + + cls = env->FindClass("android/net/DhcpInfoInternal"); + method = env->GetMethodID(cls, "addRoute", "(Landroid/net/RouteInfo;)V"); + args[0].l = routeInfoObject; + env->CallVoidMethodA(info, method, args); + } else { + // if we have an exception (host not found perhaps), just don't add the route + env->ExceptionClear(); + } + env->SetIntField(info, dhcpInfoInternalFieldIds.prefixLength, prefixLength); env->SetObjectField(info, dhcpInfoInternalFieldIds.dns1, env->NewStringUTF(dns1)); env->SetObjectField(info, dhcpInfoInternalFieldIds.dns2, env->NewStringUTF(dns2)); @@ -258,7 +280,6 @@ int register_android_net_NetworkUtils(JNIEnv* env) LOG_FATAL_IF(dhcpInfoInternalClass == NULL, "Unable to find class android/net/DhcpInfoInternal"); dhcpInfoInternalFieldIds.constructorId = env->GetMethodID(dhcpInfoInternalClass, "", "()V"); dhcpInfoInternalFieldIds.ipaddress = env->GetFieldID(dhcpInfoInternalClass, "ipAddress", "Ljava/lang/String;"); - dhcpInfoInternalFieldIds.gateway = env->GetFieldID(dhcpInfoInternalClass, "gateway", "Ljava/lang/String;"); dhcpInfoInternalFieldIds.prefixLength = env->GetFieldID(dhcpInfoInternalClass, "prefixLength", "I"); dhcpInfoInternalFieldIds.dns1 = env->GetFieldID(dhcpInfoInternalClass, "dns1", "Ljava/lang/String;"); dhcpInfoInternalFieldIds.dns2 = env->GetFieldID(dhcpInfoInternalClass, "dns2", "Ljava/lang/String;"); diff --git a/core/tests/coretests/src/android/net/LinkPropertiesTest.java b/core/tests/coretests/src/android/net/LinkPropertiesTest.java index 50666b4d0d..e3b6b5f950 100644 --- a/core/tests/coretests/src/android/net/LinkPropertiesTest.java +++ b/core/tests/coretests/src/android/net/LinkPropertiesTest.java @@ -17,6 +17,7 @@ package android.net; import android.net.LinkProperties; +import android.net.RouteInfo; import android.test.suitebuilder.annotation.SmallTest; import junit.framework.TestCase; @@ -55,8 +56,8 @@ public class LinkPropertiesTest extends TestCase { source.addDns(NetworkUtils.numericToInetAddress(DNS1)); source.addDns(NetworkUtils.numericToInetAddress(DNS2)); // set 2 gateways - source.addGateway(NetworkUtils.numericToInetAddress(GATEWAY1)); - source.addGateway(NetworkUtils.numericToInetAddress(GATEWAY2)); + source.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(GATEWAY1))); + source.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(GATEWAY2))); LinkProperties target = new LinkProperties(); @@ -68,8 +69,8 @@ public class LinkPropertiesTest extends TestCase { NetworkUtils.numericToInetAddress(ADDRV6), 128)); target.addDns(NetworkUtils.numericToInetAddress(DNS1)); target.addDns(NetworkUtils.numericToInetAddress(DNS2)); - target.addGateway(NetworkUtils.numericToInetAddress(GATEWAY1)); - target.addGateway(NetworkUtils.numericToInetAddress(GATEWAY2)); + target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(GATEWAY1))); + target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(GATEWAY2))); assertTrue(source.equals(target)); assertTrue(source.hashCode() == target.hashCode()); @@ -83,8 +84,8 @@ public class LinkPropertiesTest extends TestCase { NetworkUtils.numericToInetAddress(ADDRV6), 128)); target.addDns(NetworkUtils.numericToInetAddress(DNS1)); target.addDns(NetworkUtils.numericToInetAddress(DNS2)); - target.addGateway(NetworkUtils.numericToInetAddress(GATEWAY1)); - target.addGateway(NetworkUtils.numericToInetAddress(GATEWAY2)); + target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(GATEWAY1))); + target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(GATEWAY2))); assertFalse(source.equals(target)); target.clear(); @@ -96,8 +97,8 @@ public class LinkPropertiesTest extends TestCase { NetworkUtils.numericToInetAddress(ADDRV6), 128)); target.addDns(NetworkUtils.numericToInetAddress(DNS1)); target.addDns(NetworkUtils.numericToInetAddress(DNS2)); - target.addGateway(NetworkUtils.numericToInetAddress(GATEWAY1)); - target.addGateway(NetworkUtils.numericToInetAddress(GATEWAY2)); + target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(GATEWAY1))); + target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(GATEWAY2))); assertFalse(source.equals(target)); target.clear(); @@ -109,8 +110,8 @@ public class LinkPropertiesTest extends TestCase { // change dnses target.addDns(NetworkUtils.numericToInetAddress("75.208.7.2")); target.addDns(NetworkUtils.numericToInetAddress(DNS2)); - target.addGateway(NetworkUtils.numericToInetAddress(GATEWAY1)); - target.addGateway(NetworkUtils.numericToInetAddress(GATEWAY2)); + target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(GATEWAY1))); + target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(GATEWAY2))); assertFalse(source.equals(target)); target.clear(); @@ -122,8 +123,8 @@ public class LinkPropertiesTest extends TestCase { target.addDns(NetworkUtils.numericToInetAddress(DNS1)); target.addDns(NetworkUtils.numericToInetAddress(DNS2)); // change gateway - target.addGateway(NetworkUtils.numericToInetAddress("75.208.8.2")); - target.addGateway(NetworkUtils.numericToInetAddress(GATEWAY2)); + target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress("75.208.8.2"))); + target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(GATEWAY2))); assertFalse(source.equals(target)); } catch (Exception e) { @@ -146,8 +147,8 @@ public class LinkPropertiesTest extends TestCase { source.addDns(NetworkUtils.numericToInetAddress(DNS1)); source.addDns(NetworkUtils.numericToInetAddress(DNS2)); // set 2 gateways - source.addGateway(NetworkUtils.numericToInetAddress(GATEWAY1)); - source.addGateway(NetworkUtils.numericToInetAddress(GATEWAY2)); + source.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(GATEWAY1))); + source.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(GATEWAY2))); LinkProperties target = new LinkProperties(); // Exchange order @@ -158,8 +159,8 @@ public class LinkPropertiesTest extends TestCase { NetworkUtils.numericToInetAddress(ADDRV4), 32)); target.addDns(NetworkUtils.numericToInetAddress(DNS2)); target.addDns(NetworkUtils.numericToInetAddress(DNS1)); - target.addGateway(NetworkUtils.numericToInetAddress(GATEWAY2)); - target.addGateway(NetworkUtils.numericToInetAddress(GATEWAY1)); + target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(GATEWAY2))); + target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(GATEWAY1))); assertTrue(source.equals(target)); assertTrue(source.hashCode() == target.hashCode()); diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index 6c3b3d3867..c225e895cb 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -34,6 +34,7 @@ import android.net.NetworkStateTracker; import android.net.NetworkUtils; import android.net.Proxy; import android.net.ProxyProperties; +import android.net.RouteInfo; import android.net.vpn.VpnManager; import android.net.wifi.WifiStateTracker; import android.os.Binder; @@ -1417,14 +1418,19 @@ public class ConnectivityService extends IConnectivityManager.Stub { if (p == null) return; String interfaceName = p.getInterfaceName(); if (TextUtils.isEmpty(interfaceName)) return; - for (InetAddress gateway : p.getGateways()) { + for (RouteInfo route : p.getRoutes()) { - if (NetworkUtils.addHostRoute(interfaceName, gateway, null) && - NetworkUtils.addDefaultRoute(interfaceName, gateway)) { - if (DBG) { - NetworkInfo networkInfo = nt.getNetworkInfo(); - log("addDefaultRoute for " + networkInfo.getTypeName() + - " (" + interfaceName + "), GatewayAddr=" + gateway.getHostAddress()); + //TODO - handle non-default routes + if (route.isDefaultRoute()) { + InetAddress gateway = route.getGateway(); + if (NetworkUtils.addHostRoute(interfaceName, gateway, null) && + NetworkUtils.addDefaultRoute(interfaceName, gateway)) { + if (DBG) { + NetworkInfo networkInfo = nt.getNetworkInfo(); + log("addDefaultRoute for " + networkInfo.getTypeName() + + " (" + interfaceName + "), GatewayAddr=" + + gateway.getHostAddress()); + } } } }