From a7dfbd3a1d261eecb7c2ec3eceb5315d7f21c215 Mon Sep 17 00:00:00 2001 From: Robert Greenwalt Date: Tue, 15 Jun 2010 15:43:39 -0700 Subject: [PATCH] Pass network properties to ConnectivityService. Used as a bag to hold ipaddr, gateway, dns, proxy info. addr's are InetAddresses for v4/v6 use. Cleaning up some old v4-only code bug:2655015 Change-Id: I7ac886fe5c519e8bab42f49cd82a5189d9c9ab59 --- core/java/android/net/NetworkProperties.java | 196 ++++++++++++++++++ core/java/android/net/NetworkUtils.java | 73 +++++-- core/java/android/net/ProxyProperties.java | 108 ++++++++++ core/jni/android_net_NetUtils.cpp | 6 +- .../android/server/ConnectivityService.java | 130 ++++++------ 5 files changed, 419 insertions(+), 94 deletions(-) create mode 100644 core/java/android/net/NetworkProperties.java create mode 100644 core/java/android/net/ProxyProperties.java diff --git a/core/java/android/net/NetworkProperties.java b/core/java/android/net/NetworkProperties.java new file mode 100644 index 0000000000..56e1f1a485 --- /dev/null +++ b/core/java/android/net/NetworkProperties.java @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net; + +import android.os.Parcelable; +import android.os.Parcel; +import android.util.Log; + +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Collection; + +/** + * Describes the properties of a network interface or single address + * of an interface. + * TODO - consider adding optional fields like Apn and ApnType + * @hide + */ +public class NetworkProperties implements Parcelable { + + private NetworkInterface mIface; + private Collection mAddresses; + private Collection mDnses; + private InetAddress mGateway; + private ProxyProperties mHttpProxy; + + public NetworkProperties() { + clear(); + } + + public synchronized void setInterface(NetworkInterface iface) { + mIface = iface; + } + public synchronized NetworkInterface getInterface() { + return mIface; + } + public synchronized String getInterfaceName() { + return (mIface == null ? null : mIface.getName()); + } + + public synchronized void addAddress(InetAddress address) { + mAddresses.add(address); + } + public synchronized Collection getAddresses() { + return mAddresses; + } + + public synchronized void addDns(InetAddress dns) { + mDnses.add(dns); + } + public synchronized Collection getDnses() { + return mDnses; + } + + public synchronized void setGateway(InetAddress gateway) { + mGateway = gateway; + } + public synchronized InetAddress getGateway() { + return mGateway; + } + + public synchronized void setHttpProxy(ProxyProperties proxy) { + mHttpProxy = proxy; + } + public synchronized ProxyProperties getHttpProxy() { + return mHttpProxy; + } + + public synchronized void clear() { + mIface = null; + mAddresses = new ArrayList(); + mDnses = new ArrayList(); + mGateway = null; + mHttpProxy = null; + } + + /** + * Implement the Parcelable interface + * @hide + */ + public int describeContents() { + return 0; + } + + public synchronized String toString() { + String ifaceName = (mIface == null ? "" : "InterfaceName: " + mIface.getName() + " "); + + String ip = "IpAddresses: ["; + for (InetAddress addr : mAddresses) ip += addr.toString() + ","; + ip += "] "; + + String dns = "DnsAddresses: ["; + for (InetAddress addr : mDnses) dns += addr.toString() + ","; + dns += "] "; + + String proxy = (mHttpProxy == null ? "" : "HttpProxy: " + mHttpProxy.toString() + " "); + String gateway = (mGateway == null ? "" : "Gateway: " + mGateway.toString() + " "); + + return ifaceName + ip + gateway + dns + proxy; + } + + /** + * Implement the Parcelable interface. + * @hide + */ + public synchronized void writeToParcel(Parcel dest, int flags) { + dest.writeString(getInterfaceName()); + dest.writeInt(mAddresses.size()); + for(InetAddress a : mAddresses) { + dest.writeString(a.getHostName()); + dest.writeByteArray(a.getAddress()); + } + dest.writeInt(mDnses.size()); + for(InetAddress d : mDnses) { + dest.writeString(d.getHostName()); + dest.writeByteArray(d.getAddress()); + } + if (mGateway != null) { + dest.writeByte((byte)1); + dest.writeString(mGateway.getHostName()); + dest.writeByteArray(mGateway.getAddress()); + } else { + dest.writeByte((byte)0); + } + if (mHttpProxy != null) { + dest.writeByte((byte)1); + dest.writeParcelable(mHttpProxy, flags); + } else { + dest.writeByte((byte)0); + } + } + + /** + * Implement the Parcelable interface. + * @hide + */ + public static final Creator CREATOR = + new Creator() { + public NetworkProperties createFromParcel(Parcel in) { + NetworkProperties netProp = new NetworkProperties(); + String iface = in.readString(); + if (iface != null) { + try { + netProp.setInterface(NetworkInterface.getByName(iface)); + } catch (Exception e) { + return null; + } + } + int addressCount = in.readInt(); + for (int i=0; i> 8) & 0xff); + addrBytes[2] = (byte)((addr >> 16) & 0xff); + addrBytes[3] = (byte)((addr >> 24) & 0xff); + return addrBytes; + } + + public static int v4StringToInt(String str) { + int result = 0; + String[] array = str.split("\\."); + if (array.length != 4) return 0; try { - inetAddress = InetAddress.getByName(hostname); - } catch (UnknownHostException e) { - return -1; + result = Integer.parseInt(array[3]); + result = (result << 8) + Integer.parseInt(array[2]); + result = (result << 8) + Integer.parseInt(array[1]); + result = (result << 8) + Integer.parseInt(array[0]); + } catch (NumberFormatException e) { + return 0; } - byte[] addrBytes; - int addr; - addrBytes = inetAddress.getAddress(); - addr = ((addrBytes[3] & 0xff) << 24) - | ((addrBytes[2] & 0xff) << 16) - | ((addrBytes[1] & 0xff) << 8) - | (addrBytes[0] & 0xff); - return addr; + return result; } } diff --git a/core/java/android/net/ProxyProperties.java b/core/java/android/net/ProxyProperties.java new file mode 100644 index 0000000000..6828dd4fac --- /dev/null +++ b/core/java/android/net/ProxyProperties.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net; + + +import android.os.Parcel; +import android.os.Parcelable; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * A container class for the http proxy info + * @hide + */ +public class ProxyProperties implements Parcelable { + + private InetAddress mProxy; + private int mPort; + private String mExclusionList; + + public ProxyProperties() { + } + + public synchronized InetAddress getAddress() { + return mProxy; + } + public synchronized void setAddress(InetAddress proxy) { + mProxy = proxy; + } + + public synchronized int getPort() { + return mPort; + } + public synchronized void setPort(int port) { + mPort = port; + } + + public synchronized String getExclusionList() { + return mExclusionList; + } + public synchronized void setExclusionList(String exclusionList) { + mExclusionList = exclusionList; + } + + /** + * Implement the Parcelable interface + * @hide + */ + public int describeContents() { + return 0; + } + + /** + * Implement the Parcelable interface. + * @hide + */ + public synchronized void writeToParcel(Parcel dest, int flags) { + if (mProxy != null) { + dest.writeByte((byte)1); + dest.writeString(mProxy.getHostName()); + dest.writeByteArray(mProxy.getAddress()); + } else { + dest.writeByte((byte)0); + } + dest.writeInt(mPort); + dest.writeString(mExclusionList); + } + + /** + * Implement the Parcelable interface. + * @hide + */ + public static final Creator CREATOR = + new Creator() { + public ProxyProperties createFromParcel(Parcel in) { + ProxyProperties proxyProperties = new ProxyProperties(); + if (in.readByte() == 1) { + try { + proxyProperties.setAddress(InetAddress.getByAddress(in.readString(), + in.createByteArray())); + } catch (UnknownHostException e) {} + } + proxyProperties.setPort(in.readInt()); + proxyProperties.setExclusionList(in.readString()); + return proxyProperties; + } + + public ProxyProperties[] newArray(int size) { + return new ProxyProperties[size]; + } + }; + +}; diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp index feb0dadc15..3cde9d63ed 100644 --- a/core/jni/android_net_NetUtils.cpp +++ b/core/jni/android_net_NetUtils.cpp @@ -222,10 +222,10 @@ static JNINativeMethod gNetworkUtilMethods[] = { { "enableInterface", "(Ljava/lang/String;)I", (void *)android_net_utils_enableInterface }, { "disableInterface", "(Ljava/lang/String;)I", (void *)android_net_utils_disableInterface }, - { "addHostRoute", "(Ljava/lang/String;I)I", (void *)android_net_utils_addHostRoute }, + { "addHostRouteNative", "(Ljava/lang/String;I)I", (void *)android_net_utils_addHostRoute }, { "removeHostRoutes", "(Ljava/lang/String;)I", (void *)android_net_utils_removeHostRoutes }, - { "setDefaultRoute", "(Ljava/lang/String;I)I", (void *)android_net_utils_setDefaultRoute }, - { "getDefaultRoute", "(Ljava/lang/String;)I", (void *)android_net_utils_getDefaultRoute }, + { "setDefaultRouteNative", "(Ljava/lang/String;I)I", (void *)android_net_utils_setDefaultRoute }, + { "getDefaultRouteNative", "(Ljava/lang/String;)I", (void *)android_net_utils_getDefaultRoute }, { "removeDefaultRoute", "(Ljava/lang/String;)I", (void *)android_net_utils_removeDefaultRoute }, { "resetConnections", "(Ljava/lang/String;)I", (void *)android_net_utils_resetConnections }, { "runDhcp", "(Ljava/lang/String;Landroid/net/DhcpInfo;)Z", (void *)android_net_utils_runDhcp }, diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index 9ff7de6152..9c504feac9 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -26,6 +26,7 @@ import android.net.ConnectivityManager; import android.net.IConnectivityManager; import android.net.MobileDataStateTracker; import android.net.NetworkInfo; +import android.net.NetworkProperties; import android.net.NetworkStateTracker; import android.net.wifi.WifiStateTracker; import android.net.NetworkUtils; @@ -51,7 +52,10 @@ import java.io.FileDescriptor; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; +import java.net.InetAddress; +import java.net.UnknownHostException; import java.util.ArrayList; +import java.util.Collection; import java.util.List; /** @@ -741,6 +745,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { * specified host is to be routed * @param hostAddress the IP address of the host to which the route is * desired + * todo - deprecate (only v4!) * @return {@code true} on success, {@code false} on failure */ public boolean requestRouteToHost(int networkType, int hostAddress) { @@ -757,7 +762,11 @@ public class ConnectivityService extends IConnectivityManager.Stub { } return false; } - return addHostRoute(tracker, hostAddress); + try { + InetAddress addr = InetAddress.getByAddress(NetworkUtils.v4IntToArray(hostAddress)); + return addHostRoute(tracker, addr); + } catch (UnknownHostException e) {} + return false; } /** @@ -765,22 +774,25 @@ public class ConnectivityService extends IConnectivityManager.Stub { * host via the mobile data network. * @param hostAddress the IP address of the host to which the route is desired, * in network byte order. + * TODO - deprecate * @return {@code true} on success, {@code false} on failure */ - private boolean addHostRoute(NetworkStateTracker nt, int hostAddress) { + private boolean addHostRoute(NetworkStateTracker nt, InetAddress hostAddress) { if (nt.getNetworkInfo().getType() == ConnectivityManager.TYPE_WIFI) { return false; } - String interfaceName = nt.getInterfaceName(); + NetworkProperties p = nt.getNetworkProperties(); + if (p == null) return false; + String interfaceName = p.getInterfaceName(); if (DBG) { - Slog.d(TAG, "Requested host route to " + Integer.toHexString(hostAddress) + - "(" + interfaceName + ")"); + Slog.d(TAG, "Requested host route to " + hostAddress + "(" + interfaceName + ")"); } - if (interfaceName != null && hostAddress != -1) { + if (interfaceName != null) { return NetworkUtils.addHostRoute(interfaceName, hostAddress) == 0; } else { + if (DBG) Slog.e(TAG, "addHostRoute failed due to null interface name"); return false; } } @@ -1251,21 +1263,20 @@ public class ConnectivityService extends IConnectivityManager.Stub { } private void addPrivateDnsRoutes(NetworkStateTracker nt) { - String interfaceName = nt.getInterfaceName(); boolean privateDnsRouteSet = nt.isPrivateDnsRouteSet(); + NetworkProperties p = nt.getNetworkProperties(); + if (p == null) return; + String interfaceName = p.getInterfaceName(); if (DBG) { Slog.d(TAG, "addPrivateDnsRoutes for " + nt + "(" + interfaceName + ") - mPrivateDnsRouteSet = " + privateDnsRouteSet); } - String[] dnsList = getNameServerList(nt.getDnsPropNames()); if (interfaceName != null && !privateDnsRouteSet) { - for (String addrString : dnsList) { - int addr = NetworkUtils.lookupHost(addrString); - if (addr != -1 && addr != 0) { - if (DBG) Slog.d(TAG, " adding "+addrString+" ("+addr+")"); - NetworkUtils.addHostRoute(interfaceName, addr); - } + Collection dnsList = p.getDnses(); + for (InetAddress dns : dnsList) { + if (DBG) Slog.d(TAG, " adding " + dns); + NetworkUtils.addHostRoute(interfaceName, dns); } nt.privateDnsRouteSet(true); } @@ -1274,7 +1285,9 @@ public class ConnectivityService extends IConnectivityManager.Stub { private void removePrivateDnsRoutes(NetworkStateTracker nt) { // TODO - we should do this explicitly but the NetUtils api doesnt // support this yet - must remove all. No worse than before - String interfaceName = nt.getInterfaceName(); + NetworkProperties p = nt.getNetworkProperties(); + if (p == null) return; + String interfaceName = p.getInterfaceName(); boolean privateDnsRouteSet = nt.isPrivateDnsRouteSet(); if (interfaceName != null && privateDnsRouteSet) { if (DBG) { @@ -1286,61 +1299,42 @@ public class ConnectivityService extends IConnectivityManager.Stub { } } - /** - * Return the IP addresses of the DNS servers available for this - * network interface. - * @param propertyNames the names of the system properties whose values - * give the IP addresses. Properties with no values are skipped. - * @return an array of {@code String}s containing the IP addresses - * of the DNS servers, in dot-notation. This may have fewer - * non-null entries than the list of names passed in, since - * some of the passed-in names may have empty values. - */ - String[] getNameServerList(String[] propertyNames) { - String[] dnsAddresses = new String[propertyNames.length]; - int i, j; - - for (i = 0, j = 0; i < propertyNames.length; i++) { - String value = SystemProperties.get(propertyNames[i]); - // The GSM layer sometimes sets a bogus DNS server address of - // 0.0.0.0 - if (!TextUtils.isEmpty(value) && !TextUtils.equals(value, "0.0.0.0")) { - dnsAddresses[j++] = value; - } - } - return dnsAddresses; - } private void addDefaultRoute(NetworkStateTracker nt) { - String interfaceName = nt.getInterfaceName(); - int defaultGatewayAddr = nt.getDefaultGatewayAddr(); + NetworkProperties p = nt.getNetworkProperties(); + if (p == null) return; + String interfaceName = p.getInterfaceName(); + InetAddress defaultGatewayAddr = p.getGateway(); boolean defaultRouteSet = nt.isDefaultRouteSet(); - NetworkInfo networkInfo = nt.getNetworkInfo(); - if ((interfaceName != null) && (defaultGatewayAddr != 0) && - defaultRouteSet == false) { - if (DBG) { + if ((interfaceName != null) && (defaultGatewayAddr != null ) && + (defaultRouteSet == false)) { + boolean error = (NetworkUtils.setDefaultRoute(interfaceName, defaultGatewayAddr) < 0); + + if (DBG && !error) { + NetworkInfo networkInfo = nt.getNetworkInfo(); Slog.d(TAG, "addDefaultRoute for " + networkInfo.getTypeName() + " (" + interfaceName + "), GatewayAddr=" + defaultGatewayAddr); } - NetworkUtils.setDefaultRoute(interfaceName, defaultGatewayAddr); - nt.defaultRouteSet(true); + nt.defaultRouteSet(!error); } } public void removeDefaultRoute(NetworkStateTracker nt) { - String interfaceName = nt.getInterfaceName(); + NetworkProperties p = nt.getNetworkProperties(); + if (p == null) return; + String interfaceName = p.getInterfaceName(); boolean defaultRouteSet = nt.isDefaultRouteSet(); - NetworkInfo networkInfo = nt.getNetworkInfo(); if (interfaceName != null && defaultRouteSet == true) { - if (DBG) { + boolean error = (NetworkUtils.removeDefaultRoute(interfaceName) < 0); + if (DBG && !error) { + NetworkInfo networkInfo = nt.getNetworkInfo(); Slog.d(TAG, "removeDefaultRoute for " + networkInfo.getTypeName() + " (" + interfaceName + ")"); } - NetworkUtils.removeDefaultRoute(interfaceName); - nt.defaultRouteSet(false); + nt.defaultRouteSet(error); } } @@ -1430,12 +1424,14 @@ public class ConnectivityService extends IConnectivityManager.Stub { NetworkStateTracker nt = mNetTrackers[i]; if (nt.getNetworkInfo().isConnected() && !nt.isTeardownRequested()) { + NetworkProperties p = nt.getNetworkProperties(); + if (p == null) continue; List pids = mNetRequestersPids[i]; for (int j=0; j dnses = p.getDnses(); + writePidDns(dnses, myPid); if (doBump) { bumpDns(); } @@ -1457,12 +1453,10 @@ public class ConnectivityService extends IConnectivityManager.Stub { } } - private void writePidDns(String[] dnsList, int pid) { + private void writePidDns(Collection dnses, int pid) { int j = 1; - for (String dns : dnsList) { - if (dns != null && !TextUtils.equals(dns, "0.0.0.0")) { - SystemProperties.set("net.dns" + j++ + "." + pid, dns); - } + for (InetAddress dns : dnses) { + SystemProperties.set("net.dns" + j++ + "." + pid, dns.getHostAddress()); } } @@ -1488,17 +1482,17 @@ public class ConnectivityService extends IConnectivityManager.Stub { NetworkStateTracker nt = mNetTrackers[netType]; if (nt != null && nt.getNetworkInfo().isConnected() && !nt.isTeardownRequested()) { - String[] dnsList = getNameServerList(nt.getDnsPropNames()); + NetworkProperties p = nt.getNetworkProperties(); + if (p == null) continue; + Collection dnses = p.getDnses(); if (mNetAttributes[netType].isDefault()) { int j = 1; - for (String dns : dnsList) { - if (dns != null && !TextUtils.equals(dns, "0.0.0.0")) { - if (DBG) { - Slog.d(TAG, "adding dns " + dns + " for " + - nt.getNetworkInfo().getTypeName()); - } - SystemProperties.set("net.dns" + j++, dns); + for (InetAddress dns : dnses) { + if (DBG) { + Slog.d(TAG, "adding dns " + dns + " for " + + nt.getNetworkInfo().getTypeName()); } + SystemProperties.set("net.dns" + j++, dns.getHostAddress()); } for (int k=j ; k