blob: 61acf2b841dd862f94e63fd92fe68df5631e9c1f [file] [log] [blame]
Robert Greenwalt47f69fe2010-06-15 15:43:39 -07001/*
Wink Saville6e809972010-09-21 09:15:35 -07002 * Copyright (C) 2010 The Android Open Source Project
Robert Greenwalt47f69fe2010-06-15 15:43:39 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.net;
18
Robert Greenwalt37e65eb2010-08-30 10:56:47 -070019import android.net.ProxyProperties;
Robert Greenwalt47f69fe2010-06-15 15:43:39 -070020import android.os.Parcelable;
21import android.os.Parcel;
John Wang4e900092011-04-04 12:35:42 -070022import android.text.TextUtils;
Robert Greenwalt47f69fe2010-06-15 15:43:39 -070023
24import java.net.InetAddress;
Robert Greenwalt47f69fe2010-06-15 15:43:39 -070025import java.net.UnknownHostException;
26import java.util.ArrayList;
27import java.util.Collection;
Robert Greenwalt37e65eb2010-08-30 10:56:47 -070028import java.util.Collections;
Robert Greenwalt47f69fe2010-06-15 15:43:39 -070029
30/**
Robert Greenwalt37e65eb2010-08-30 10:56:47 -070031 * Describes the properties of a network link.
Robert Greenwalt992564e2011-02-09 13:56:06 -080032 *
33 * A link represents a connection to a network.
34 * It may have multiple addresses and multiple gateways,
35 * multiple dns servers but only one http proxy.
36 *
37 * Because it's a single network, the dns's
38 * are interchangeable and don't need associating with
39 * particular addresses. The gateways similarly don't
40 * need associating with particular addresses.
41 *
42 * A dual stack interface works fine in this model:
43 * each address has it's own prefix length to describe
44 * the local network. The dns servers all return
45 * both v4 addresses and v6 addresses regardless of the
46 * address family of the server itself (rfc4213) and we
47 * don't care which is used. The gateways will be
48 * selected based on the destination address and the
49 * source address has no relavence.
Robert Greenwalt47f69fe2010-06-15 15:43:39 -070050 * @hide
51 */
Robert Greenwalt37e65eb2010-08-30 10:56:47 -070052public class LinkProperties implements Parcelable {
Robert Greenwalt47f69fe2010-06-15 15:43:39 -070053
Irfan Sheriffed5d7d12010-10-01 16:08:28 -070054 String mIfaceName;
55 private Collection<LinkAddress> mLinkAddresses;
Robert Greenwalt47f69fe2010-06-15 15:43:39 -070056 private Collection<InetAddress> mDnses;
Robert Greenwaltaa70f102011-04-28 14:28:50 -070057 private Collection<RouteInfo> mRoutes;
Robert Greenwalt47f69fe2010-06-15 15:43:39 -070058 private ProxyProperties mHttpProxy;
59
Robert Greenwalt37e65eb2010-08-30 10:56:47 -070060 public LinkProperties() {
Robert Greenwalt47f69fe2010-06-15 15:43:39 -070061 clear();
62 }
63
Robert Greenwalt37e65eb2010-08-30 10:56:47 -070064 // copy constructor instead of clone
65 public LinkProperties(LinkProperties source) {
Irfan Sheriffef6c1432010-08-30 20:37:17 -070066 if (source != null) {
Irfan Sheriffed5d7d12010-10-01 16:08:28 -070067 mIfaceName = source.getInterfaceName();
68 mLinkAddresses = source.getLinkAddresses();
Irfan Sheriffef6c1432010-08-30 20:37:17 -070069 mDnses = source.getDnses();
Robert Greenwaltaa70f102011-04-28 14:28:50 -070070 mRoutes = source.getRoutes();
Irfan Sheriffef6c1432010-08-30 20:37:17 -070071 mHttpProxy = new ProxyProperties(source.getHttpProxy());
72 }
Robert Greenwalt37e65eb2010-08-30 10:56:47 -070073 }
74
Irfan Sheriffed5d7d12010-10-01 16:08:28 -070075 public void setInterfaceName(String iface) {
76 mIfaceName = iface;
Robert Greenwalt47f69fe2010-06-15 15:43:39 -070077 }
78
Irfan Sheriffed5d7d12010-10-01 16:08:28 -070079 public String getInterfaceName() {
80 return mIfaceName;
Robert Greenwalt47f69fe2010-06-15 15:43:39 -070081 }
Irfan Sheriffed5d7d12010-10-01 16:08:28 -070082
Robert Greenwalt37e65eb2010-08-30 10:56:47 -070083 public Collection<InetAddress> getAddresses() {
Irfan Sheriffed5d7d12010-10-01 16:08:28 -070084 Collection<InetAddress> addresses = new ArrayList<InetAddress>();
85 for (LinkAddress linkAddress : mLinkAddresses) {
86 addresses.add(linkAddress.getAddress());
87 }
88 return Collections.unmodifiableCollection(addresses);
89 }
90
91 public void addLinkAddress(LinkAddress address) {
Robert Greenwalt04cac402011-03-02 17:03:37 -080092 if (address != null) mLinkAddresses.add(address);
Irfan Sheriffed5d7d12010-10-01 16:08:28 -070093 }
94
95 public Collection<LinkAddress> getLinkAddresses() {
96 return Collections.unmodifiableCollection(mLinkAddresses);
Robert Greenwalt47f69fe2010-06-15 15:43:39 -070097 }
98
Robert Greenwalt37e65eb2010-08-30 10:56:47 -070099 public void addDns(InetAddress dns) {
Robert Greenwalt04cac402011-03-02 17:03:37 -0800100 if (dns != null) mDnses.add(dns);
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700101 }
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700102
Robert Greenwalt37e65eb2010-08-30 10:56:47 -0700103 public Collection<InetAddress> getDnses() {
104 return Collections.unmodifiableCollection(mDnses);
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700105 }
106
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700107 public void addRoute(RouteInfo route) {
108 if (route != null) mRoutes.add(route);
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700109 }
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700110 public Collection<RouteInfo> getRoutes() {
111 return Collections.unmodifiableCollection(mRoutes);
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700112 }
113
Robert Greenwalt37e65eb2010-08-30 10:56:47 -0700114 public void setHttpProxy(ProxyProperties proxy) {
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700115 mHttpProxy = proxy;
116 }
Robert Greenwalt37e65eb2010-08-30 10:56:47 -0700117 public ProxyProperties getHttpProxy() {
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700118 return mHttpProxy;
119 }
120
Robert Greenwalt37e65eb2010-08-30 10:56:47 -0700121 public void clear() {
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700122 mIfaceName = null;
123 mLinkAddresses = new ArrayList<LinkAddress>();
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700124 mDnses = new ArrayList<InetAddress>();
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700125 mRoutes = new ArrayList<RouteInfo>();
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700126 mHttpProxy = null;
127 }
128
129 /**
130 * Implement the Parcelable interface
131 * @hide
132 */
133 public int describeContents() {
134 return 0;
135 }
136
Wink Saville1f6408a2010-08-27 11:15:18 -0700137 @Override
Robert Greenwalt37e65eb2010-08-30 10:56:47 -0700138 public String toString() {
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700139 String ifaceName = (mIfaceName == null ? "" : "InterfaceName: " + mIfaceName + " ");
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700140
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700141 String linkAddresses = "LinkAddresses: [";
John Wang4e900092011-04-04 12:35:42 -0700142 for (LinkAddress addr : mLinkAddresses) linkAddresses += addr.toString() + ",";
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700143 linkAddresses += "] ";
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700144
145 String dns = "DnsAddresses: [";
Wink Saville1f6408a2010-08-27 11:15:18 -0700146 for (InetAddress addr : mDnses) dns += addr.getHostAddress() + ",";
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700147 dns += "] ";
148
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700149 String routes = "Routes: [";
150 for (RouteInfo route : mRoutes) routes += route.toString() + ",";
151 routes += "] ";
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700152 String proxy = (mHttpProxy == null ? "" : "HttpProxy: " + mHttpProxy.toString() + " ");
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700153
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700154 return ifaceName + linkAddresses + routes + dns + proxy;
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700155 }
156
John Wang4e900092011-04-04 12:35:42 -0700157
158 @Override
159 /**
160 * Compares this {@code LinkProperties} instance against the target
161 * LinkProperties in {@code obj}. Two LinkPropertieses are equal if
162 * all their fields are equal in values.
163 *
164 * For collection fields, such as mDnses, containsAll() is used to check
165 * if two collections contains the same elements, independent of order.
166 * There are two thoughts regarding containsAll()
167 * 1. Duplicated elements. eg, (A, B, B) and (A, A, B) are equal.
168 * 2. Worst case performance is O(n^2).
169 *
170 * @param obj the object to be tested for equality.
171 * @return {@code true} if both objects are equal, {@code false} otherwise.
172 */
173 public boolean equals(Object obj) {
174 if (this == obj) return true;
175
176 if (!(obj instanceof LinkProperties)) return false;
177
178 boolean sameAddresses;
179 boolean sameDnses;
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700180 boolean sameRoutes;
John Wang4e900092011-04-04 12:35:42 -0700181
182 LinkProperties target = (LinkProperties) obj;
183
184 Collection<InetAddress> targetAddresses = target.getAddresses();
185 Collection<InetAddress> sourceAddresses = getAddresses();
186 sameAddresses = (sourceAddresses.size() == targetAddresses.size()) ?
187 sourceAddresses.containsAll(targetAddresses) : false;
188
189 Collection<InetAddress> targetDnses = target.getDnses();
190 sameDnses = (mDnses.size() == targetDnses.size()) ?
191 mDnses.containsAll(targetDnses) : false;
192
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700193 Collection<RouteInfo> targetRoutes = target.getRoutes();
194 sameRoutes = (mRoutes.size() == targetRoutes.size()) ?
195 mRoutes.containsAll(targetRoutes) : false;
John Wang4e900092011-04-04 12:35:42 -0700196
197 return
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700198 sameAddresses && sameDnses && sameRoutes
John Wang4e900092011-04-04 12:35:42 -0700199 && TextUtils.equals(getInterfaceName(), target.getInterfaceName())
200 && (getHttpProxy() == null ? target.getHttpProxy() == null :
201 getHttpProxy().equals(target.getHttpProxy()));
202 }
203
204 @Override
205 /**
206 * generate hashcode based on significant fields
207 * Equal objects must produce the same hash code, while unequal objects
208 * may have the same hash codes.
209 */
210 public int hashCode() {
211 return ((null == mIfaceName) ? 0 : mIfaceName.hashCode()
212 + mLinkAddresses.size() * 31
213 + mDnses.size() * 37
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700214 + mRoutes.size() * 41
John Wang4e900092011-04-04 12:35:42 -0700215 + ((null == mHttpProxy) ? 0 : mHttpProxy.hashCode()));
216 }
217
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700218 /**
219 * Implement the Parcelable interface.
220 * @hide
221 */
Robert Greenwalt37e65eb2010-08-30 10:56:47 -0700222 public void writeToParcel(Parcel dest, int flags) {
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700223 dest.writeString(getInterfaceName());
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700224 dest.writeInt(mLinkAddresses.size());
225 for(LinkAddress linkAddress : mLinkAddresses) {
226 dest.writeParcelable(linkAddress, flags);
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700227 }
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700228
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700229 dest.writeInt(mDnses.size());
230 for(InetAddress d : mDnses) {
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700231 dest.writeByteArray(d.getAddress());
232 }
Robert Greenwalt992564e2011-02-09 13:56:06 -0800233
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700234 dest.writeInt(mRoutes.size());
235 for(RouteInfo route : mRoutes) {
236 dest.writeParcelable(route, flags);
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700237 }
Robert Greenwalt992564e2011-02-09 13:56:06 -0800238
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700239 if (mHttpProxy != null) {
240 dest.writeByte((byte)1);
241 dest.writeParcelable(mHttpProxy, flags);
242 } else {
243 dest.writeByte((byte)0);
244 }
245 }
246
247 /**
248 * Implement the Parcelable interface.
249 * @hide
250 */
Robert Greenwalt37e65eb2010-08-30 10:56:47 -0700251 public static final Creator<LinkProperties> CREATOR =
252 new Creator<LinkProperties>() {
253 public LinkProperties createFromParcel(Parcel in) {
254 LinkProperties netProp = new LinkProperties();
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700255 String iface = in.readString();
256 if (iface != null) {
257 try {
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700258 netProp.setInterfaceName(iface);
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700259 } catch (Exception e) {
260 return null;
261 }
262 }
263 int addressCount = in.readInt();
264 for (int i=0; i<addressCount; i++) {
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700265 netProp.addLinkAddress((LinkAddress)in.readParcelable(null));
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700266 }
267 addressCount = in.readInt();
268 for (int i=0; i<addressCount; i++) {
269 try {
Irfan Sheriff1cf56ab2010-08-04 15:15:49 -0700270 netProp.addDns(InetAddress.getByAddress(in.createByteArray()));
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700271 } catch (UnknownHostException e) { }
272 }
Robert Greenwalt992564e2011-02-09 13:56:06 -0800273 addressCount = in.readInt();
274 for (int i=0; i<addressCount; i++) {
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700275 netProp.addRoute((RouteInfo)in.readParcelable(null));
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700276 }
277 if (in.readByte() == 1) {
278 netProp.setHttpProxy((ProxyProperties)in.readParcelable(null));
279 }
280 return netProp;
281 }
282
Robert Greenwalt37e65eb2010-08-30 10:56:47 -0700283 public LinkProperties[] newArray(int size) {
284 return new LinkProperties[size];
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700285 }
286 };
287}