From 0a82e80073e193725a9d4c84a93db8a04b2456b9 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Thu, 31 Jul 2014 00:48:01 +0900 Subject: [PATCH] Stop using LinkProperties for static configuration. LinkProperties can represent way more complicated configurations than what we can actually apply to interfaces. This makes it error-prone to use it to represent static configuration, both when trying to apply configuration coming from LinkProperties and when trying to save configuration from current LinkProperties. Instead, move static configuration (IPv4 only, since we don't support static IPv6 configuration) into a separate StaticIpConfiguration class. Bug: 16114392 Bug: 16893413 Change-Id: Ib33f35c004e30b6067bb20235ffa43c247d174df --- core/java/android/net/DhcpResults.java | 150 +++++--------- core/java/android/net/EthernetManager.java | 9 +- core/java/android/net/IpConfiguration.java | 99 ++++++--- core/java/android/net/NetworkUtils.java | 27 +++ .../android/net/StaticIpConfiguration.java | 194 ++++++++++++++++++ core/jni/android_net_NetUtils.cpp | 24 +-- .../AccessPointParserHelper.java | 20 +- .../com/android/server/net/IpConfigStore.java | 90 ++++---- .../android/net/wifi/WifiConfiguration.java | 22 +- 9 files changed, 437 insertions(+), 198 deletions(-) create mode 100644 core/java/android/net/StaticIpConfiguration.java diff --git a/core/java/android/net/DhcpResults.java b/core/java/android/net/DhcpResults.java index 49a307e36dfde..71df60ad88f0f 100644 --- a/core/java/android/net/DhcpResults.java +++ b/core/java/android/net/DhcpResults.java @@ -16,13 +16,15 @@ package android.net; +import android.net.NetworkUtils; import android.os.Parcelable; import android.os.Parcel; import android.text.TextUtils; import android.util.Log; import java.net.InetAddress; -import java.net.UnknownHostException; +import java.net.Inet4Address; +import java.util.Objects; /** * A simple object for retrieving the results of a DHCP request. @@ -30,38 +32,34 @@ import java.net.UnknownHostException; * TODO - remove when DhcpInfo is deprecated. Move the remaining api to LinkProperties. * @hide */ -public class DhcpResults implements Parcelable { +public class DhcpResults extends StaticIpConfiguration { private static final String TAG = "DhcpResults"; - public final LinkProperties linkProperties; - public InetAddress serverAddress; - /** - * Vendor specific information (from RFC 2132). - */ + /** Vendor specific information (from RFC 2132). */ public String vendorInfo; public int leaseDuration; public DhcpResults() { - linkProperties = new LinkProperties(); + super(); + } + + public DhcpResults(StaticIpConfiguration source) { + super(source); } /** copy constructor */ public DhcpResults(DhcpResults source) { - if (source != null) { - linkProperties = new LinkProperties(source.linkProperties); - serverAddress = source.serverAddress; - leaseDuration = source.leaseDuration; - vendorInfo = source.vendorInfo; - } else { - linkProperties = new LinkProperties(); - } - } + super(source); - public DhcpResults(LinkProperties lp) { - linkProperties = new LinkProperties(lp); + if (source != null) { + // All these are immutable, so no need to make copies. + serverAddress = source.serverAddress; + vendorInfo = source.vendorInfo; + leaseDuration = source.leaseDuration; + } } /** @@ -70,14 +68,10 @@ public class DhcpResults implements Parcelable { * being empty. */ public void updateFromDhcpRequest(DhcpResults orig) { - if (orig == null || orig.linkProperties == null) return; - if (linkProperties.getRoutes().size() == 0) { - for (RouteInfo r : orig.linkProperties.getRoutes()) linkProperties.addRoute(r); - } - if (linkProperties.getDnsServers().size() == 0) { - for (InetAddress d : orig.linkProperties.getDnsServers()) { - linkProperties.addDnsServer(d); - } + if (orig == null) return; + if (gateway == null) gateway = orig.gateway; + if (dnsServers.size() == 0) { + dnsServers.addAll(orig.dnsServers); } } @@ -94,15 +88,14 @@ public class DhcpResults implements Parcelable { } public void clear() { - linkProperties.clear(); - serverAddress = null; + super.clear(); vendorInfo = null; leaseDuration = 0; } @Override public String toString() { - StringBuffer str = new StringBuffer(linkProperties.toString()); + StringBuffer str = new StringBuffer(super.toString()); str.append(" DHCP server ").append(serverAddress); str.append(" Vendor info ").append(vendorInfo); @@ -119,58 +112,19 @@ public class DhcpResults implements Parcelable { DhcpResults target = (DhcpResults)obj; - if (linkProperties == null) { - if (target.linkProperties != null) return false; - } else if (!linkProperties.equals(target.linkProperties)) return false; - if (serverAddress == null) { - if (target.serverAddress != null) return false; - } else if (!serverAddress.equals(target.serverAddress)) return false; - if (vendorInfo == null) { - if (target.vendorInfo != null) return false; - } else if (!vendorInfo.equals(target.vendorInfo)) return false; - if (leaseDuration != target.leaseDuration) return false; - - return true; - } - - /** Implement the Parcelable interface */ - public int describeContents() { - return 0; - } - - /** Implement the Parcelable interface */ - public void writeToParcel(Parcel dest, int flags) { - linkProperties.writeToParcel(dest, flags); - - dest.writeInt(leaseDuration); - - if (serverAddress != null) { - dest.writeByte((byte)1); - dest.writeByteArray(serverAddress.getAddress()); - } else { - dest.writeByte((byte)0); - } - - dest.writeString(vendorInfo); + return super.equals((StaticIpConfiguration) obj) && + Objects.equals(serverAddress, target.serverAddress) && + Objects.equals(vendorInfo, target.vendorInfo) && + leaseDuration == target.leaseDuration; } /** Implement the Parcelable interface */ public static final Creator CREATOR = new Creator() { public DhcpResults createFromParcel(Parcel in) { - DhcpResults prop = new DhcpResults((LinkProperties)in.readParcelable(null)); - - prop.leaseDuration = in.readInt(); - - if (in.readByte() == 1) { - try { - prop.serverAddress = InetAddress.getByAddress(in.createByteArray()); - } catch (UnknownHostException e) {} - } - - prop.vendorInfo = in.readString(); - - return prop; + DhcpResults dhcpResults = new DhcpResults(); + readFromParcel(dhcpResults, in); + return dhcpResults; } public DhcpResults[] newArray(int size) { @@ -178,33 +132,39 @@ public class DhcpResults implements Parcelable { } }; - // Utils for jni population - false on success - public void setInterfaceName(String interfaceName) { - linkProperties.setInterfaceName(interfaceName); + /** Implement the Parcelable interface */ + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeInt(leaseDuration); + NetworkUtils.parcelInetAddress(dest, serverAddress, flags); + dest.writeString(vendorInfo); } - public boolean addLinkAddress(String addrString, int prefixLength) { - InetAddress addr; + private static void readFromParcel(DhcpResults dhcpResults, Parcel in) { + StaticIpConfiguration.readFromParcel(dhcpResults, in); + dhcpResults.leaseDuration = in.readInt(); + dhcpResults.serverAddress = NetworkUtils.unparcelInetAddress(in); + dhcpResults.vendorInfo = in.readString(); + } + + // Utils for jni population - false on success + // Not part of the superclass because they're only used by the JNI iterface to the DHCP daemon. + public boolean setIpAddress(String addrString, int prefixLength) { try { - addr = NetworkUtils.numericToInetAddress(addrString); - } catch (IllegalArgumentException e) { - Log.e(TAG, "addLinkAddress failed with addrString " + addrString); + Inet4Address addr = (Inet4Address) NetworkUtils.numericToInetAddress(addrString); + ipAddress = new LinkAddress(addr, prefixLength); + } catch (IllegalArgumentException|ClassCastException e) { + Log.e(TAG, "setIpAddress failed with addrString " + addrString + "/" + prefixLength); return true; } - - LinkAddress linkAddress = new LinkAddress(addr, prefixLength); - linkProperties.addLinkAddress(linkAddress); - - RouteInfo routeInfo = new RouteInfo(linkAddress); - linkProperties.addRoute(routeInfo); return false; } - public boolean addGateway(String addrString) { + public boolean setGateway(String addrString) { try { - linkProperties.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(addrString))); + gateway = NetworkUtils.numericToInetAddress(addrString); } catch (IllegalArgumentException e) { - Log.e(TAG, "addGateway failed with addrString " + addrString); + Log.e(TAG, "setGateway failed with addrString " + addrString); return true; } return false; @@ -213,7 +173,7 @@ public class DhcpResults implements Parcelable { public boolean addDns(String addrString) { if (TextUtils.isEmpty(addrString) == false) { try { - linkProperties.addDnsServer(NetworkUtils.numericToInetAddress(addrString)); + dnsServers.add(NetworkUtils.numericToInetAddress(addrString)); } catch (IllegalArgumentException e) { Log.e(TAG, "addDns failed with addrString " + addrString); return true; @@ -241,6 +201,6 @@ public class DhcpResults implements Parcelable { } public void setDomains(String domains) { - linkProperties.setDomains(domains); + domains = domains; } } diff --git a/core/java/android/net/EthernetManager.java b/core/java/android/net/EthernetManager.java index 608ca28d84e16..d965f27c8feab 100644 --- a/core/java/android/net/EthernetManager.java +++ b/core/java/android/net/EthernetManager.java @@ -21,7 +21,6 @@ import android.net.IEthernetManager; import android.net.IpConfiguration; import android.net.IpConfiguration.IpAssignment; import android.net.IpConfiguration.ProxySettings; -import android.net.LinkProperties; import android.os.RemoteException; /** @@ -52,16 +51,12 @@ public class EthernetManager { */ public IpConfiguration getConfiguration() { if (mService == null) { - return new IpConfiguration(IpAssignment.UNASSIGNED, - ProxySettings.UNASSIGNED, - new LinkProperties()); + return new IpConfiguration(); } try { return mService.getConfiguration(); } catch (RemoteException e) { - return new IpConfiguration(IpAssignment.UNASSIGNED, - ProxySettings.UNASSIGNED, - new LinkProperties()); + return new IpConfiguration(); } } diff --git a/core/java/android/net/IpConfiguration.java b/core/java/android/net/IpConfiguration.java index 4730bab38cef7..fe69f2966de6e 100644 --- a/core/java/android/net/IpConfiguration.java +++ b/core/java/android/net/IpConfiguration.java @@ -16,7 +16,7 @@ package android.net; -import android.net.LinkProperties; +import android.net.StaticIpConfiguration; import android.os.Parcel; import android.os.Parcelable; @@ -31,7 +31,7 @@ public class IpConfiguration implements Parcelable { public enum IpAssignment { /* Use statically configured IP settings. Configuration can be accessed - * with linkProperties */ + * with staticIpConfiguration */ STATIC, /* Use dynamically configured IP settigns */ DHCP, @@ -42,12 +42,14 @@ public class IpConfiguration implements Parcelable { public IpAssignment ipAssignment; + public StaticIpConfiguration staticIpConfiguration; + public enum ProxySettings { /* No proxy is to be used. Any existing proxy settings * should be cleared. */ NONE, /* Use statically configured proxy. Configuration can be accessed - * with linkProperties */ + * with httpProxy. */ STATIC, /* no proxy details are assigned, this is used to indicate * that any existing proxy settings should be retained */ @@ -59,30 +61,69 @@ public class IpConfiguration implements Parcelable { public ProxySettings proxySettings; - public LinkProperties linkProperties; + public ProxyInfo httpProxy; - public IpConfiguration(IpConfiguration source) { - if (source != null) { - ipAssignment = source.ipAssignment; - proxySettings = source.proxySettings; - linkProperties = new LinkProperties(source.linkProperties); - } else { - ipAssignment = IpAssignment.UNASSIGNED; - proxySettings = ProxySettings.UNASSIGNED; - linkProperties = new LinkProperties(); - } + private void init(IpAssignment ipAssignment, + ProxySettings proxySettings, + StaticIpConfiguration staticIpConfiguration, + ProxyInfo httpProxy) { + this.ipAssignment = ipAssignment; + this.proxySettings = proxySettings; + this.staticIpConfiguration = (staticIpConfiguration == null) ? + null : new StaticIpConfiguration(staticIpConfiguration); + this.httpProxy = (httpProxy == null) ? + null : new ProxyInfo(httpProxy); } public IpConfiguration() { - this(null); + init(IpAssignment.UNASSIGNED, ProxySettings.UNASSIGNED, null, null); } public IpConfiguration(IpAssignment ipAssignment, ProxySettings proxySettings, - LinkProperties linkProperties) { + StaticIpConfiguration staticIpConfiguration, + ProxyInfo httpProxy) { + init(ipAssignment, proxySettings, staticIpConfiguration, httpProxy); + } + + public IpConfiguration(IpConfiguration source) { + this(); + if (source != null) { + init(source.ipAssignment, source.proxySettings, + source.staticIpConfiguration, source.httpProxy); + } + } + + public IpAssignment getIpAssignment() { + return ipAssignment; + } + + public void setIpAssignment(IpAssignment ipAssignment) { this.ipAssignment = ipAssignment; + } + + public StaticIpConfiguration getStaticIpConfiguration() { + return staticIpConfiguration; + } + + public void setStaticIpConfiguration(StaticIpConfiguration staticIpConfiguration) { + this.staticIpConfiguration = staticIpConfiguration; + } + + public ProxySettings getProxySettings() { + return proxySettings; + } + + public void setProxySettings(ProxySettings proxySettings) { this.proxySettings = proxySettings; - this.linkProperties = new LinkProperties(linkProperties); + } + + public ProxyInfo getHttpProxy() { + return httpProxy; + } + + public void setHttpProxy(ProxyInfo httpProxy) { + this.httpProxy = httpProxy; } @Override @@ -90,10 +131,16 @@ public class IpConfiguration implements Parcelable { StringBuilder sbuf = new StringBuilder(); sbuf.append("IP assignment: " + ipAssignment.toString()); sbuf.append("\n"); + if (staticIpConfiguration != null) { + sbuf.append("Static configuration: " + staticIpConfiguration.toString()); + sbuf.append("\n"); + } sbuf.append("Proxy settings: " + proxySettings.toString()); sbuf.append("\n"); - sbuf.append(linkProperties.toString()); - sbuf.append("\n"); + if (httpProxy != null) { + sbuf.append("HTTP proxy: " + httpProxy.toString()); + sbuf.append("\n"); + } return sbuf.toString(); } @@ -111,14 +158,16 @@ public class IpConfiguration implements Parcelable { IpConfiguration other = (IpConfiguration) o; return this.ipAssignment == other.ipAssignment && this.proxySettings == other.proxySettings && - Objects.equals(this.linkProperties, other.linkProperties); + Objects.equals(this.staticIpConfiguration, other.staticIpConfiguration) && + Objects.equals(this.httpProxy, other.httpProxy); } @Override public int hashCode() { - return 13 + (linkProperties != null ? linkProperties.hashCode() : 0) + + return 13 + (staticIpConfiguration != null ? staticIpConfiguration.hashCode() : 0) + 17 * ipAssignment.ordinal() + - 47 * proxySettings.ordinal(); + 47 * proxySettings.ordinal() + + 83 * httpProxy.hashCode(); } /** Implement the Parcelable interface */ @@ -130,7 +179,8 @@ public class IpConfiguration implements Parcelable { public void writeToParcel(Parcel dest, int flags) { dest.writeString(ipAssignment.name()); dest.writeString(proxySettings.name()); - dest.writeParcelable(linkProperties, flags); + dest.writeParcelable(staticIpConfiguration, flags); + dest.writeParcelable(httpProxy, flags); } /** Implement the Parcelable interface */ @@ -140,7 +190,8 @@ public class IpConfiguration implements Parcelable { IpConfiguration config = new IpConfiguration(); config.ipAssignment = IpAssignment.valueOf(in.readString()); config.proxySettings = ProxySettings.valueOf(in.readString()); - config.linkProperties = in.readParcelable(null); + config.staticIpConfiguration = in.readParcelable(null); + config.httpProxy = in.readParcelable(null); return config; } diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java index 663aa150d9254..54d8676be5a18 100644 --- a/core/java/android/net/NetworkUtils.java +++ b/core/java/android/net/NetworkUtils.java @@ -23,6 +23,7 @@ import java.net.UnknownHostException; import java.util.Collection; import java.util.Locale; +import android.os.Parcel; import android.util.Log; import android.util.Pair; @@ -202,6 +203,32 @@ public class NetworkUtils { return InetAddress.parseNumericAddress(addrString); } + /** + * Writes an InetAddress to a parcel. The address may be null. This is likely faster than + * calling writeSerializable. + */ + protected static void parcelInetAddress(Parcel parcel, InetAddress address, int flags) { + byte[] addressArray = (address != null) ? address.getAddress() : null; + parcel.writeByteArray(addressArray); + } + + /** + * Reads an InetAddress from a parcel. Returns null if the address that was written was null + * or if the data is invalid. + */ + protected static InetAddress unparcelInetAddress(Parcel in) { + byte[] addressArray = in.createByteArray(); + if (addressArray == null) { + return null; + } + try { + return InetAddress.getByAddress(addressArray); + } catch (UnknownHostException e) { + return null; + } + } + + /** * Masks a raw IP address byte array with the specified prefix length. */ diff --git a/core/java/android/net/StaticIpConfiguration.java b/core/java/android/net/StaticIpConfiguration.java new file mode 100644 index 0000000000000..5a273cfaa65a4 --- /dev/null +++ b/core/java/android/net/StaticIpConfiguration.java @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2014 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.net.LinkAddress; +import android.os.Parcelable; +import android.os.Parcel; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * Class that describes static IP configuration. + * + * This class is different from LinkProperties because it represents + * configuration intent. The general contract is that if we can represent + * a configuration here, then we should be able to configure it on a network. + * The intent is that it closely match the UI we have for configuring networks. + * + * In contrast, LinkProperties represents current state. It is much more + * expressive. For example, it supports multiple IP addresses, multiple routes, + * stacked interfaces, and so on. Because LinkProperties is so expressive, + * using it to represent configuration intent as well as current state causes + * problems. For example, we could unknowingly save a configuration that we are + * not in fact capable of applying, or we could save a configuration that the + * UI cannot display, which has the potential for malicious code to hide + * hostile or unexpected configuration from the user: see, for example, + * http://b/12663469 and http://b/16893413 . + * + * @hide + */ +public class StaticIpConfiguration implements Parcelable { + public LinkAddress ipAddress; + public InetAddress gateway; + public final ArrayList dnsServers; + public String domains; + + public StaticIpConfiguration() { + dnsServers = new ArrayList(); + } + + public StaticIpConfiguration(StaticIpConfiguration source) { + this(); + if (source != null) { + // All of these except dnsServers are immutable, so no need to make copies. + ipAddress = source.ipAddress; + gateway = source.gateway; + dnsServers.addAll(source.dnsServers); + domains = source.domains; + } + } + + public void clear() { + ipAddress = null; + gateway = null; + dnsServers.clear(); + domains = null; + } + + /** + * Returns the network routes specified by this object. Will typically include a + * directly-connected route for the IP address's local subnet and a default route. + */ + public List getRoutes(String iface) { + List routes = new ArrayList(2); + if (ipAddress != null) { + routes.add(new RouteInfo(ipAddress, null, iface)); + } + if (gateway != null) { + routes.add(new RouteInfo((LinkAddress) null, gateway, iface)); + } + return routes; + } + + /** + * Returns a LinkProperties object expressing the data in this object. Note that the information + * contained in the LinkProperties will not be a complete picture of the link's configuration, + * because any configuration information that is obtained dynamically by the network (e.g., + * IPv6 configuration) will not be included. + */ + public LinkProperties toLinkProperties(String iface) { + LinkProperties lp = new LinkProperties(); + lp.setInterfaceName(iface); + if (ipAddress != null) { + lp.addLinkAddress(ipAddress); + } + for (RouteInfo route : getRoutes(iface)) { + lp.addRoute(route); + } + for (InetAddress dns : dnsServers) { + lp.addDnsServer(dns); + } + return lp; + } + + public String toString() { + StringBuffer str = new StringBuffer(); + + str.append("IP address "); + if (ipAddress != null ) str.append(ipAddress).append(" "); + + str.append("Gateway "); + if (gateway != null) str.append(gateway.getHostAddress()).append(" "); + + str.append(" DNS servers: ["); + for (InetAddress dnsServer : dnsServers) { + str.append(" ").append(dnsServer.getHostAddress()); + } + + str.append(" ] Domains"); + if (domains != null) str.append(domains); + return str.toString(); + } + + public int hashCode() { + int result = 13; + result = 47 * result + (ipAddress == null ? 0 : ipAddress.hashCode()); + result = 47 * result + (gateway == null ? 0 : gateway.hashCode()); + result = 47 * result + (domains == null ? 0 : domains.hashCode()); + result = 47 * result + dnsServers.hashCode(); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + + if (!(obj instanceof StaticIpConfiguration)) return false; + + StaticIpConfiguration other = (StaticIpConfiguration) obj; + + return other != null && + Objects.equals(ipAddress, other.ipAddress) && + Objects.equals(gateway, other.gateway) && + dnsServers.equals(other.dnsServers) && + Objects.equals(domains, other.domains); + } + + /** Implement the Parcelable interface */ + public static Creator CREATOR = + new Creator() { + public StaticIpConfiguration createFromParcel(Parcel in) { + StaticIpConfiguration s = new StaticIpConfiguration(); + readFromParcel(s, in); + return s; + } + + public StaticIpConfiguration[] newArray(int size) { + return new StaticIpConfiguration[size]; + } + }; + + /** Implement the Parcelable interface */ + public int describeContents() { + return 0; + } + + /** Implement the Parcelable interface */ + public void writeToParcel(Parcel dest, int flags) { + dest.writeParcelable(ipAddress, flags); + NetworkUtils.parcelInetAddress(dest, gateway, flags); + dest.writeInt(dnsServers.size()); + for (InetAddress dnsServer : dnsServers) { + NetworkUtils.parcelInetAddress(dest, dnsServer, flags); + } + } + + protected static void readFromParcel(StaticIpConfiguration s, Parcel in) { + s.ipAddress = in.readParcelable(null); + s.gateway = NetworkUtils.unparcelInetAddress(in); + s.dnsServers.clear(); + int size = in.readInt(); + for (int i = 0; i < size; i++) { + s.dnsServers.add(NetworkUtils.unparcelInetAddress(in)); + } + } +} diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp index 32cf286527ae0..5bd38f381ce09 100644 --- a/core/jni/android_net_NetUtils.cpp +++ b/core/jni/android_net_NetUtils.cpp @@ -69,9 +69,8 @@ namespace android { */ static struct fieldIds { jmethodID clear; - jmethodID setInterfaceName; - jmethodID addLinkAddress; - jmethodID addGateway; + jmethodID setIpAddress; + jmethodID setGateway; jmethodID addDns; jmethodID setDomains; jmethodID setServerAddress; @@ -130,21 +129,16 @@ static jboolean android_net_utils_runDhcpCommon(JNIEnv* env, jobject clazz, jstr if (result == 0) { env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.clear); - // set mIfaceName - // dhcpResults->setInterfaceName(ifname) - env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.setInterfaceName, ifname); - // set the linkAddress // dhcpResults->addLinkAddress(inetAddress, prefixLength) - result = env->CallBooleanMethod(dhcpResults, dhcpResultsFieldIds.addLinkAddress, + result = env->CallBooleanMethod(dhcpResults, dhcpResultsFieldIds.setIpAddress, env->NewStringUTF(ipaddr), prefixLength); } if (result == 0) { // set the gateway - // dhcpResults->addGateway(gateway) result = env->CallBooleanMethod(dhcpResults, - dhcpResultsFieldIds.addGateway, env->NewStringUTF(gateway)); + dhcpResultsFieldIds.setGateway, env->NewStringUTF(gateway)); } if (result == 0) { @@ -279,12 +273,10 @@ int register_android_net_NetworkUtils(JNIEnv* env) LOG_FATAL_IF(dhcpResultsClass == NULL, "Unable to find class android/net/DhcpResults"); dhcpResultsFieldIds.clear = env->GetMethodID(dhcpResultsClass, "clear", "()V"); - dhcpResultsFieldIds.setInterfaceName = - env->GetMethodID(dhcpResultsClass, "setInterfaceName", "(Ljava/lang/String;)V"); - dhcpResultsFieldIds.addLinkAddress = - env->GetMethodID(dhcpResultsClass, "addLinkAddress", "(Ljava/lang/String;I)Z"); - dhcpResultsFieldIds.addGateway = - env->GetMethodID(dhcpResultsClass, "addGateway", "(Ljava/lang/String;)Z"); + dhcpResultsFieldIds.setIpAddress = + env->GetMethodID(dhcpResultsClass, "setIpAddress", "(Ljava/lang/String;I)Z"); + dhcpResultsFieldIds.setGateway = + env->GetMethodID(dhcpResultsClass, "setGateway", "(Ljava/lang/String;)Z"); dhcpResultsFieldIds.addDns = env->GetMethodID(dhcpResultsClass, "addDns", "(Ljava/lang/String;)Z"); dhcpResultsFieldIds.setDomains = diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java index 116a31efa799a..93b16e7a84c90 100644 --- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java +++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java @@ -26,8 +26,8 @@ import org.xml.sax.helpers.DefaultHandler; import android.net.IpConfiguration.IpAssignment; import android.net.IpConfiguration.ProxySettings; import android.net.LinkAddress; -import android.net.LinkProperties; import android.net.RouteInfo; +import android.net.StaticIpConfiguration; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiConfiguration.AuthAlgorithm; import android.net.wifi.WifiConfiguration.KeyMgmt; @@ -116,7 +116,7 @@ public class AccessPointParserHelper { boolean usercert = false; WifiConfiguration config = null; int securityType = NONE; - LinkProperties mLinkProperties = null; + StaticIpConfiguration mStaticIpConfiguration = null; InetAddress mInetAddr = null; @Override @@ -153,7 +153,7 @@ public class AccessPointParserHelper { usercert = true; } if (tagName.equalsIgnoreCase("ip")) { - mLinkProperties = new LinkProperties(); + mStaticIpConfiguration = new StaticIpConfiguration(); ip = true; } if (tagName.equalsIgnoreCase("gateway")) { @@ -173,15 +173,15 @@ public class AccessPointParserHelper { @Override public void endElement(String uri, String localName, String tagName) throws SAXException { if (tagName.equalsIgnoreCase("accesspoint")) { - if (mLinkProperties != null) { + if (mStaticIpConfiguration != null) { config.setIpAssignment(IpAssignment.STATIC); - config.setLinkProperties(mLinkProperties); + config.setStaticIpConfiguration(mStaticIpConfiguration); } else { config.setIpAssignment(IpAssignment.DHCP); } config.setProxySettings(ProxySettings.NONE); networks.add(config); - mLinkProperties = null; + mStaticIpConfiguration = null; } } @@ -312,7 +312,7 @@ public class AccessPointParserHelper { if (!InetAddress.isNumeric(gwAddr)) { throw new SAXException(); } - mLinkProperties.addRoute(new RouteInfo(InetAddress.getByName(gwAddr))); + mStaticIpConfiguration.gateway = InetAddress.getByName(gwAddr); } catch (UnknownHostException e) { throw new SAXException(); } @@ -324,7 +324,7 @@ public class AccessPointParserHelper { if ((nwPrefixLength < 0) || (nwPrefixLength > 32)) { throw new SAXException(); } - mLinkProperties.addLinkAddress(new LinkAddress(mInetAddr, nwPrefixLength)); + mStaticIpConfiguration.ipAddress = new LinkAddress(mInetAddr, nwPrefixLength); } catch (NumberFormatException e) { throw new SAXException(); } @@ -336,7 +336,7 @@ public class AccessPointParserHelper { if (!InetAddress.isNumeric(dnsAddr)) { throw new SAXException(); } - mLinkProperties.addDnsServer(InetAddress.getByName(dnsAddr)); + mStaticIpConfiguration.dnsServers.add(InetAddress.getByName(dnsAddr)); } catch (UnknownHostException e) { throw new SAXException(); } @@ -348,7 +348,7 @@ public class AccessPointParserHelper { if (!InetAddress.isNumeric(dnsAddr)) { throw new SAXException(); } - mLinkProperties.addDnsServer(InetAddress.getByName(dnsAddr)); + mStaticIpConfiguration.dnsServers.add(InetAddress.getByName(dnsAddr)); } catch (UnknownHostException e) { throw new SAXException(); } diff --git a/services/core/java/com/android/server/net/IpConfigStore.java b/services/core/java/com/android/server/net/IpConfigStore.java index 907eeb24181e9..857b9e90a0a12 100644 --- a/services/core/java/com/android/server/net/IpConfigStore.java +++ b/services/core/java/com/android/server/net/IpConfigStore.java @@ -20,10 +20,10 @@ import android.net.IpConfiguration; import android.net.IpConfiguration.IpAssignment; import android.net.IpConfiguration.ProxySettings; import android.net.LinkAddress; -import android.net.LinkProperties; import android.net.NetworkUtils; import android.net.ProxyInfo; import android.net.RouteInfo; +import android.net.StaticIpConfiguration; import android.os.Handler; import android.os.HandlerThread; import android.text.TextUtils; @@ -41,6 +41,7 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.net.InetAddress; +import java.net.Inet4Address; import java.util.Map; public class IpConfigStore { @@ -69,40 +70,32 @@ public class IpConfigStore { } private boolean writeConfig(DataOutputStream out, int configKey, - IpConfiguration config) throws IOException { + IpConfiguration config) throws IOException { boolean written = false; try { - LinkProperties linkProperties = config.linkProperties; switch (config.ipAssignment) { case STATIC: out.writeUTF(IP_ASSIGNMENT_KEY); out.writeUTF(config.ipAssignment.toString()); - for (LinkAddress linkAddr : linkProperties.getLinkAddresses()) { - out.writeUTF(LINK_ADDRESS_KEY); - out.writeUTF(linkAddr.getAddress().getHostAddress()); - out.writeInt(linkAddr.getPrefixLength()); - } - for (RouteInfo route : linkProperties.getRoutes()) { - out.writeUTF(GATEWAY_KEY); - LinkAddress dest = route.getDestinationLinkAddress(); - if (dest != null) { - out.writeInt(1); - out.writeUTF(dest.getAddress().getHostAddress()); - out.writeInt(dest.getPrefixLength()); - } else { - out.writeInt(0); + StaticIpConfiguration staticIpConfiguration = config.staticIpConfiguration; + if (staticIpConfiguration != null) { + if (staticIpConfiguration.ipAddress != null) { + LinkAddress ipAddress = staticIpConfiguration.ipAddress; + out.writeUTF(LINK_ADDRESS_KEY); + out.writeUTF(ipAddress.getAddress().getHostAddress()); + out.writeInt(ipAddress.getPrefixLength()); } - if (route.getGateway() != null) { - out.writeInt(1); - out.writeUTF(route.getGateway().getHostAddress()); - } else { - out.writeInt(0); + if (staticIpConfiguration.gateway != null) { + out.writeUTF(GATEWAY_KEY); + out.writeInt(0); // Default route. + out.writeInt(1); // Have a gateway. + out.writeUTF(staticIpConfiguration.gateway.getHostAddress()); + } + for (InetAddress inetAddr : staticIpConfiguration.dnsServers) { + out.writeUTF(DNS_KEY); + out.writeUTF(inetAddr.getHostAddress()); } - } - for (InetAddress inetAddr : linkProperties.getDnsServers()) { - out.writeUTF(DNS_KEY); - out.writeUTF(inetAddr.getHostAddress()); } written = true; break; @@ -121,7 +114,7 @@ public class IpConfigStore { switch (config.proxySettings) { case STATIC: - ProxyInfo proxyProperties = linkProperties.getHttpProxy(); + ProxyInfo proxyProperties = config.httpProxy; String exclusionList = proxyProperties.getExclusionListAsString(); out.writeUTF(PROXY_SETTINGS_KEY); out.writeUTF(config.proxySettings.toString()); @@ -134,7 +127,7 @@ public class IpConfigStore { written = true; break; case PAC: - ProxyInfo proxyPacProperties = linkProperties.getHttpProxy(); + ProxyInfo proxyPacProperties = config.httpProxy; out.writeUTF(PROXY_SETTINGS_KEY); out.writeUTF(config.proxySettings.toString()); out.writeUTF(PROXY_PAC_FILE); @@ -159,7 +152,7 @@ public class IpConfigStore { out.writeInt(configKey); } } catch (NullPointerException e) { - loge("Failure in writing " + config.linkProperties + e); + loge("Failure in writing " + config + e); } out.writeUTF(EOS); @@ -196,7 +189,7 @@ public class IpConfigStore { // Default is DHCP with no proxy IpAssignment ipAssignment = IpAssignment.DHCP; ProxySettings proxySettings = ProxySettings.NONE; - LinkProperties linkProperties = new LinkProperties(); + StaticIpConfiguration staticIpConfiguration = new StaticIpConfiguration(); String proxyHost = null; String pacFileUrl = null; int proxyPort = -1; @@ -213,13 +206,23 @@ public class IpConfigStore { } else if (key.equals(LINK_ADDRESS_KEY)) { LinkAddress linkAddr = new LinkAddress( NetworkUtils.numericToInetAddress(in.readUTF()), in.readInt()); - linkProperties.addLinkAddress(linkAddr); + if (linkAddr.getAddress() instanceof Inet4Address && + staticIpConfiguration.ipAddress == null) { + staticIpConfiguration.ipAddress = linkAddr; + } else { + loge("Non-IPv4 or duplicate address: " + linkAddr); + } } else if (key.equals(GATEWAY_KEY)) { LinkAddress dest = null; InetAddress gateway = null; if (version == 1) { // only supported default gateways - leave the dest/prefix empty gateway = NetworkUtils.numericToInetAddress(in.readUTF()); + if (staticIpConfiguration.gateway == null) { + staticIpConfiguration.gateway = gateway; + } else { + loge("Duplicate gateway: " + gateway.getHostAddress()); + } } else { if (in.readInt() == 1) { dest = new LinkAddress( @@ -229,10 +232,16 @@ public class IpConfigStore { if (in.readInt() == 1) { gateway = NetworkUtils.numericToInetAddress(in.readUTF()); } + RouteInfo route = new RouteInfo(dest, gateway); + if (route.isIPv4Default() && + staticIpConfiguration.gateway == null) { + staticIpConfiguration.gateway = gateway; + } else { + loge("Non-IPv4 default or duplicate route: " + route); + } } - linkProperties.addRoute(new RouteInfo(dest, gateway)); } else if (key.equals(DNS_KEY)) { - linkProperties.addDnsServer( + staticIpConfiguration.dnsServers.add( NetworkUtils.numericToInetAddress(in.readUTF())); } else if (key.equals(PROXY_SETTINGS_KEY)) { proxySettings = ProxySettings.valueOf(in.readUTF()); @@ -258,9 +267,11 @@ public class IpConfigStore { IpConfiguration config = new IpConfiguration(); networks.put(id, config); - config.linkProperties = linkProperties; switch (ipAssignment) { case STATIC: + config.staticIpConfiguration = staticIpConfiguration; + config.ipAssignment = ipAssignment; + break; case DHCP: config.ipAssignment = ipAssignment; break; @@ -276,16 +287,15 @@ public class IpConfigStore { switch (proxySettings) { case STATIC: - config.proxySettings = proxySettings; - ProxyInfo ProxyInfo = + ProxyInfo proxyInfo = new ProxyInfo(proxyHost, proxyPort, exclusionList); - linkProperties.setHttpProxy(ProxyInfo); + config.proxySettings = proxySettings; + config.httpProxy = proxyInfo; break; case PAC: + ProxyInfo proxyPacProperties = new ProxyInfo(pacFileUrl); config.proxySettings = proxySettings; - ProxyInfo proxyPacProperties = - new ProxyInfo(pacFileUrl); - linkProperties.setHttpProxy(proxyPacProperties); + config.httpProxy = proxyPacProperties; break; case NONE: config.proxySettings = proxySettings; diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 3c37b94695ad8..ac2a176c43847 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -21,7 +21,7 @@ import android.net.IpConfiguration; import android.net.IpConfiguration.ProxySettings; import android.net.IpConfiguration.IpAssignment; import android.net.ProxyInfo; -import android.net.LinkProperties; +import android.net.StaticIpConfiguration; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; @@ -1096,13 +1096,13 @@ public class WifiConfiguration implements Parcelable { } /** @hide */ - public LinkProperties getLinkProperties() { - return mIpConfiguration.linkProperties; + public StaticIpConfiguration getStaticIpConfiguration() { + return mIpConfiguration.getStaticIpConfiguration(); } /** @hide */ - public void setLinkProperties(LinkProperties linkProperties) { - mIpConfiguration.linkProperties = linkProperties; + public void setStaticIpConfiguration(StaticIpConfiguration staticIpConfiguration) { + mIpConfiguration.setStaticIpConfiguration(staticIpConfiguration); } /** @hide */ @@ -1125,10 +1125,20 @@ public class WifiConfiguration implements Parcelable { mIpConfiguration.proxySettings = proxySettings; } + /** @hide */ + public ProxyInfo getHttpProxy() { + return mIpConfiguration.httpProxy; + } + + /** @hide */ + public void setHttpProxy(ProxyInfo httpProxy) { + mIpConfiguration.httpProxy = httpProxy; + } + /** @hide */ public void setProxy(ProxySettings settings, ProxyInfo proxy) { mIpConfiguration.proxySettings = settings; - mIpConfiguration.linkProperties.setHttpProxy(proxy); + mIpConfiguration.httpProxy = proxy; } /** Implement the Parcelable interface {@hide} */