blob: b52b15e6dd51a2d14c0bbb4e1c1266d1caad5d92 [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
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -070019import android.annotation.NonNull;
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -070020import android.annotation.Nullable;
paulhu7610bc72018-12-12 17:52:57 +080021import android.annotation.SystemApi;
Remi NGUYEN VAN94a05572019-01-20 12:38:10 +090022import android.annotation.TestApi;
Mathew Inwoodfa3a7462018-08-08 14:52:47 +010023import android.annotation.UnsupportedAppUsage;
Mathew Inwood55418ea2018-12-20 15:30:45 +000024import android.os.Build;
Robert Greenwalt47f69fe2010-06-15 15:43:39 -070025import android.os.Parcel;
Rubin Xu1bb5c082017-09-05 18:40:49 +010026import android.os.Parcelable;
John Wang4e900092011-04-04 12:35:42 -070027import android.text.TextUtils;
Robert Greenwalt47f69fe2010-06-15 15:43:39 -070028
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -080029import java.net.Inet4Address;
Lorenzo Colitti4faa0272013-08-08 11:00:12 +090030import java.net.Inet6Address;
Rubin Xu1bb5c082017-09-05 18:40:49 +010031import java.net.InetAddress;
Robert Greenwalt47f69fe2010-06-15 15:43:39 -070032import java.net.UnknownHostException;
33import java.util.ArrayList;
34import java.util.Collection;
Robert Greenwalt37e65eb2010-08-30 10:56:47 -070035import java.util.Collections;
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -080036import java.util.Hashtable;
Robert Greenwaltdf2b8782014-06-06 10:30:11 -070037import java.util.List;
Lorenzo Colittic17a1b92014-06-12 23:10:17 +090038import java.util.Objects;
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +090039import java.util.StringJoiner;
Robert Greenwalt47f69fe2010-06-15 15:43:39 -070040
41/**
Robert Greenwalt37e65eb2010-08-30 10:56:47 -070042 * Describes the properties of a network link.
Robert Greenwalt992564e2011-02-09 13:56:06 -080043 *
44 * A link represents a connection to a network.
45 * It may have multiple addresses and multiple gateways,
Robert Greenwalt4f05d552014-05-18 22:01:38 -070046 * multiple dns servers but only one http proxy and one
47 * network interface.
Robert Greenwalt992564e2011-02-09 13:56:06 -080048 *
Robert Greenwalt4f05d552014-05-18 22:01:38 -070049 * Note that this is just a holder of data. Modifying it
50 * does not affect live networks.
Robert Greenwalt992564e2011-02-09 13:56:06 -080051 *
Robert Greenwalt47f69fe2010-06-15 15:43:39 -070052 */
Robert Greenwalte595b972014-06-12 16:24:38 -070053public final class LinkProperties implements Parcelable {
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -080054 // The interface described by the network link.
Mathew Inwood55418ea2018-12-20 15:30:45 +000055 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Robert Greenwalt4717c262012-10-31 14:32:53 -070056 private String mIfaceName;
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +090057 private ArrayList<LinkAddress> mLinkAddresses = new ArrayList<>();
58 private ArrayList<InetAddress> mDnses = new ArrayList<>();
Hongshikfa425012018-06-28 20:42:19 +090059 // PCSCF addresses are addresses of SIP proxies that only exist for the IMS core service.
60 private ArrayList<InetAddress> mPcscfs = new ArrayList<InetAddress>();
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +090061 private ArrayList<InetAddress> mValidatedPrivateDnses = new ArrayList<>();
dalykd9201342018-01-17 14:20:55 -050062 private boolean mUsePrivateDns;
63 private String mPrivateDnsServerName;
Robert Greenwalt8058f622012-11-09 10:52:27 -080064 private String mDomains;
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +090065 private ArrayList<RouteInfo> mRoutes = new ArrayList<>();
Jason Monk207900c2014-04-25 15:00:09 -040066 private ProxyInfo mHttpProxy;
sy.yun9d9b74a2013-09-02 05:24:09 +090067 private int mMtu;
Robert Greenwalt3f05bf42014-08-06 12:00:25 -070068 // in the format "rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max"
69 private String mTcpBufferSizes;
Lorenzo Colitti59b34472019-01-08 09:58:59 +090070 private IpPrefix mNat64Prefix;
Robert Greenwalt47f69fe2010-06-15 15:43:39 -070071
w1997615afd812014-08-05 15:18:11 -070072 private static final int MIN_MTU = 68;
73 private static final int MIN_MTU_V6 = 1280;
74 private static final int MAX_MTU = 10000;
75
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -080076 // Stores the properties of links that are "stacked" above this link.
77 // Indexed by interface name to allow modification and to prevent duplicates being added.
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +090078 private Hashtable<String, LinkProperties> mStackedLinks = new Hashtable<>();
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -080079
Robert Greenwaltdf2b8782014-06-06 10:30:11 -070080 /**
81 * @hide
82 */
Robert Greenwalt0a46db52011-07-14 14:28:05 -070083 public static class CompareResult<T> {
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +090084 public final List<T> removed = new ArrayList<>();
85 public final List<T> added = new ArrayList<>();
Rubin Xu2fc72f72017-08-22 16:35:52 +010086
87 public CompareResult() {}
88
89 public CompareResult(Collection<T> oldItems, Collection<T> newItems) {
90 if (oldItems != null) {
91 removed.addAll(oldItems);
92 }
93 if (newItems != null) {
94 for (T newItem : newItems) {
95 if (!removed.remove(newItem)) {
96 added.add(newItem);
97 }
98 }
99 }
100 }
Wink Savillee8222252011-07-13 13:44:13 -0700101
102 @Override
103 public String toString() {
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900104 return "removed=[" + TextUtils.join(",", removed)
105 + "] added=[" + TextUtils.join(",", added)
106 + "]";
Wink Savillee8222252011-07-13 13:44:13 -0700107 }
108 }
109
Sreeram Ramachandrancc91c7b2014-06-03 18:41:43 -0700110 /**
111 * @hide
112 */
Erik Klinecd7ed162015-05-21 16:15:02 +0900113 public enum ProvisioningChange {
Mathew Inwoodfa3a7462018-08-08 14:52:47 +0100114 @UnsupportedAppUsage
Erik Klinecd7ed162015-05-21 16:15:02 +0900115 STILL_NOT_PROVISIONED,
Mathew Inwoodfa3a7462018-08-08 14:52:47 +0100116 @UnsupportedAppUsage
Erik Klinecd7ed162015-05-21 16:15:02 +0900117 LOST_PROVISIONING,
Mathew Inwoodfa3a7462018-08-08 14:52:47 +0100118 @UnsupportedAppUsage
Erik Klinecd7ed162015-05-21 16:15:02 +0900119 GAINED_PROVISIONING,
Mathew Inwoodfa3a7462018-08-08 14:52:47 +0100120 @UnsupportedAppUsage
Erik Klinecd7ed162015-05-21 16:15:02 +0900121 STILL_PROVISIONED,
122 }
123
124 /**
125 * Compare the provisioning states of two LinkProperties instances.
126 *
127 * @hide
128 */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +0100129 @UnsupportedAppUsage
Erik Klinecd7ed162015-05-21 16:15:02 +0900130 public static ProvisioningChange compareProvisioning(
131 LinkProperties before, LinkProperties after) {
132 if (before.isProvisioned() && after.isProvisioned()) {
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900133 // On dual-stack networks, DHCPv4 renewals can occasionally fail.
Erik Klinecd7ed162015-05-21 16:15:02 +0900134 // When this happens, IPv6-reachable services continue to function
135 // normally but IPv4-only services (naturally) fail.
136 //
137 // When an application using an IPv4-only service reports a bad
138 // network condition to the framework, attempts to re-validate
139 // the network succeed (since we support IPv6-only networks) and
140 // nothing is changed.
141 //
142 // For users, this is confusing and unexpected behaviour, and is
143 // not necessarily easy to diagnose. Therefore, we treat changing
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900144 // from a dual-stack network to an IPv6-only network equivalent to
Erik Klinecd7ed162015-05-21 16:15:02 +0900145 // a total loss of provisioning.
146 //
147 // For one such example of this, see b/18867306.
148 //
Erik Kline1ad4e222015-08-14 12:16:55 +0900149 // Additionally, losing IPv6 provisioning can result in TCP
150 // connections getting stuck until timeouts fire and other
151 // baffling failures. Therefore, loss of either IPv4 or IPv6 on a
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900152 // previously dual-stack network is deemed a lost of provisioning.
Erik Kline1ad4e222015-08-14 12:16:55 +0900153 if ((before.isIPv4Provisioned() && !after.isIPv4Provisioned()) ||
154 (before.isIPv6Provisioned() && !after.isIPv6Provisioned())) {
Erik Klinecd7ed162015-05-21 16:15:02 +0900155 return ProvisioningChange.LOST_PROVISIONING;
156 }
157 return ProvisioningChange.STILL_PROVISIONED;
158 } else if (before.isProvisioned() && !after.isProvisioned()) {
159 return ProvisioningChange.LOST_PROVISIONING;
160 } else if (!before.isProvisioned() && after.isProvisioned()) {
161 return ProvisioningChange.GAINED_PROVISIONING;
162 } else { // !before.isProvisioned() && !after.isProvisioned()
163 return ProvisioningChange.STILL_NOT_PROVISIONED;
164 }
165 }
166
167 /**
168 * @hide
169 */
paulhu7610bc72018-12-12 17:52:57 +0800170 @SystemApi
Robert Greenwalt37e65eb2010-08-30 10:56:47 -0700171 public LinkProperties() {
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700172 }
173
Sreeram Ramachandrancc91c7b2014-06-03 18:41:43 -0700174 /**
175 * @hide
176 */
Remi NGUYEN VAN299a7cc2019-01-23 21:35:52 +0900177 @SystemApi
178 @TestApi
Robert Greenwalt37e65eb2010-08-30 10:56:47 -0700179 public LinkProperties(LinkProperties source) {
Irfan Sheriffef6c1432010-08-30 20:37:17 -0700180 if (source != null) {
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900181 mIfaceName = source.mIfaceName;
182 mLinkAddresses.addAll(source.mLinkAddresses);
183 mDnses.addAll(source.mDnses);
184 mValidatedPrivateDnses.addAll(source.mValidatedPrivateDnses);
dalykd9201342018-01-17 14:20:55 -0500185 mUsePrivateDns = source.mUsePrivateDns;
186 mPrivateDnsServerName = source.mPrivateDnsServerName;
Hongshikfa425012018-06-28 20:42:19 +0900187 mPcscfs.addAll(source.mPcscfs);
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900188 mDomains = source.mDomains;
189 mRoutes.addAll(source.mRoutes);
190 mHttpProxy = (source.mHttpProxy == null) ? null : new ProxyInfo(source.mHttpProxy);
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800191 for (LinkProperties l: source.mStackedLinks.values()) {
192 addStackedLink(l);
193 }
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900194 setMtu(source.mMtu);
Robert Greenwalt3f05bf42014-08-06 12:00:25 -0700195 mTcpBufferSizes = source.mTcpBufferSizes;
Remi NGUYEN VANb68c3492019-01-16 15:27:27 +0900196 mNat64Prefix = source.mNat64Prefix;
Irfan Sheriffef6c1432010-08-30 20:37:17 -0700197 }
Robert Greenwalt37e65eb2010-08-30 10:56:47 -0700198 }
199
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700200 /**
201 * Sets the interface name for this link. All {@link RouteInfo} already set for this
202 * will have their interface changed to match this new value.
203 *
204 * @param iface The name of the network interface used for this link.
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700205 * @hide
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700206 */
paulhu7610bc72018-12-12 17:52:57 +0800207 @SystemApi
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700208 public void setInterfaceName(String iface) {
209 mIfaceName = iface;
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900210 ArrayList<RouteInfo> newRoutes = new ArrayList<>(mRoutes.size());
Lorenzo Colitti45b9a5b2013-03-08 11:30:39 -0800211 for (RouteInfo route : mRoutes) {
212 newRoutes.add(routeWithInterface(route));
213 }
214 mRoutes = newRoutes;
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700215 }
216
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700217 /**
218 * Gets the interface name for this link. May be {@code null} if not set.
219 *
220 * @return The interface name set for this link or {@code null}.
221 */
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -0700222 public @Nullable String getInterfaceName() {
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700223 return mIfaceName;
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700224 }
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700225
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700226 /**
227 * @hide
228 */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +0100229 @UnsupportedAppUsage
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700230 public List<String> getAllInterfaceNames() {
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900231 List<String> interfaceNames = new ArrayList<>(mStackedLinks.size() + 1);
232 if (mIfaceName != null) interfaceNames.add(mIfaceName);
Lorenzo Colitti4aa9bcf2013-03-20 19:22:58 +0900233 for (LinkProperties stacked: mStackedLinks.values()) {
234 interfaceNames.addAll(stacked.getAllInterfaceNames());
235 }
236 return interfaceNames;
237 }
238
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +0900239 /**
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700240 * Returns all the addresses on this link. We often think of a link having a single address,
241 * however, particularly with Ipv6 several addresses are typical. Note that the
242 * {@code LinkProperties} actually contains {@link LinkAddress} objects which also include
243 * prefix lengths for each address. This is a simplified utility alternative to
244 * {@link LinkProperties#getLinkAddresses}.
245 *
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900246 * @return An unmodifiable {@link List} of {@link InetAddress} for this link.
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700247 * @hide
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +0900248 */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +0100249 @UnsupportedAppUsage
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700250 public List<InetAddress> getAddresses() {
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900251 List<InetAddress> addresses = new ArrayList<>();
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700252 for (LinkAddress linkAddress : mLinkAddresses) {
253 addresses.add(linkAddress.getAddress());
254 }
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700255 return Collections.unmodifiableList(addresses);
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700256 }
257
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +0900258 /**
259 * Returns all the addresses on this link and all the links stacked above it.
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700260 * @hide
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +0900261 */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +0100262 @UnsupportedAppUsage
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700263 public List<InetAddress> getAllAddresses() {
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900264 List<InetAddress> addresses = new ArrayList<>();
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +0900265 for (LinkAddress linkAddress : mLinkAddresses) {
266 addresses.add(linkAddress.getAddress());
267 }
268 for (LinkProperties stacked: mStackedLinks.values()) {
269 addresses.addAll(stacked.getAllAddresses());
270 }
271 return addresses;
272 }
273
Lorenzo Colitti64483942013-11-15 18:43:52 +0900274 private int findLinkAddressIndex(LinkAddress address) {
275 for (int i = 0; i < mLinkAddresses.size(); i++) {
276 if (mLinkAddresses.get(i).isSameAddressAs(address)) {
277 return i;
278 }
Lorenzo Colitti4faa0272013-08-08 11:00:12 +0900279 }
Lorenzo Colitti64483942013-11-15 18:43:52 +0900280 return -1;
Lorenzo Colitti4faa0272013-08-08 11:00:12 +0900281 }
282
283 /**
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700284 * Adds a {@link LinkAddress} to this {@code LinkProperties} if a {@link LinkAddress} of the
285 * same address/prefix does not already exist. If it does exist it is replaced.
Lorenzo Colitti64483942013-11-15 18:43:52 +0900286 * @param address The {@code LinkAddress} to add.
287 * @return true if {@code address} was added or updated, false otherwise.
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700288 * @hide
Lorenzo Colitti64483942013-11-15 18:43:52 +0900289 */
Remi NGUYEN VAN5c5f1ba2019-01-29 12:08:43 +0900290 @SystemApi
291 @TestApi
Lorenzo Colitti64483942013-11-15 18:43:52 +0900292 public boolean addLinkAddress(LinkAddress address) {
293 if (address == null) {
294 return false;
295 }
296 int i = findLinkAddressIndex(address);
297 if (i < 0) {
298 // Address was not present. Add it.
299 mLinkAddresses.add(address);
300 return true;
301 } else if (mLinkAddresses.get(i).equals(address)) {
302 // Address was present and has same properties. Do nothing.
303 return false;
304 } else {
305 // Address was present and has different properties. Update it.
306 mLinkAddresses.set(i, address);
307 return true;
308 }
309 }
310
311 /**
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700312 * Removes a {@link LinkAddress} from this {@code LinkProperties}. Specifically, matches
313 * and {@link LinkAddress} with the same address and prefix.
314 *
315 * @param toRemove A {@link LinkAddress} specifying the address to remove.
Lorenzo Colitti4faa0272013-08-08 11:00:12 +0900316 * @return true if the address was removed, false if it did not exist.
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700317 * @hide
Lorenzo Colitti4faa0272013-08-08 11:00:12 +0900318 */
Remi NGUYEN VAN5c5f1ba2019-01-29 12:08:43 +0900319 @SystemApi
320 @TestApi
Lorenzo Colitti4faa0272013-08-08 11:00:12 +0900321 public boolean removeLinkAddress(LinkAddress toRemove) {
Lorenzo Colitti64483942013-11-15 18:43:52 +0900322 int i = findLinkAddressIndex(toRemove);
323 if (i >= 0) {
324 mLinkAddresses.remove(i);
325 return true;
326 }
327 return false;
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700328 }
329
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +0900330 /**
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700331 * Returns all the {@link LinkAddress} on this link. Typically a link will have
332 * one IPv4 address and one or more IPv6 addresses.
333 *
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700334 * @return An unmodifiable {@link List} of {@link LinkAddress} for this link.
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +0900335 */
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700336 public List<LinkAddress> getLinkAddresses() {
337 return Collections.unmodifiableList(mLinkAddresses);
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700338 }
339
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +0900340 /**
341 * Returns all the addresses on this link and all the links stacked above it.
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700342 * @hide
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +0900343 */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +0100344 @UnsupportedAppUsage
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700345 public List<LinkAddress> getAllLinkAddresses() {
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900346 List<LinkAddress> addresses = new ArrayList<>(mLinkAddresses);
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +0900347 for (LinkProperties stacked: mStackedLinks.values()) {
348 addresses.addAll(stacked.getAllLinkAddresses());
349 }
350 return addresses;
351 }
352
Lorenzo Colitti22f407b2013-08-23 20:54:49 +0900353 /**
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700354 * Replaces the {@link LinkAddress} in this {@code LinkProperties} with
355 * the given {@link Collection} of {@link LinkAddress}.
356 *
357 * @param addresses The {@link Collection} of {@link LinkAddress} to set in this
358 * object.
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700359 * @hide
Lorenzo Colitti22f407b2013-08-23 20:54:49 +0900360 */
paulhu7610bc72018-12-12 17:52:57 +0800361 @SystemApi
Lorenzo Colitti22f407b2013-08-23 20:54:49 +0900362 public void setLinkAddresses(Collection<LinkAddress> addresses) {
363 mLinkAddresses.clear();
364 for (LinkAddress address: addresses) {
365 addLinkAddress(address);
366 }
367 }
368
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700369 /**
Lorenzo Colitti309a75d2014-06-24 00:34:39 +0900370 * Adds the given {@link InetAddress} to the list of DNS servers, if not present.
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700371 *
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700372 * @param dnsServer The {@link InetAddress} to add to the list of DNS servers.
Lorenzo Colitti309a75d2014-06-24 00:34:39 +0900373 * @return true if the DNS server was added, false if it was already present.
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700374 * @hide
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700375 */
Remi NGUYEN VAN94a05572019-01-20 12:38:10 +0900376 @TestApi
377 @SystemApi
Lorenzo Colitti309a75d2014-06-24 00:34:39 +0900378 public boolean addDnsServer(InetAddress dnsServer) {
379 if (dnsServer != null && !mDnses.contains(dnsServer)) {
380 mDnses.add(dnsServer);
381 return true;
382 }
383 return false;
384 }
385
386 /**
Erik Klinecd7ed162015-05-21 16:15:02 +0900387 * Removes the given {@link InetAddress} from the list of DNS servers.
388 *
389 * @param dnsServer The {@link InetAddress} to remove from the list of DNS servers.
390 * @return true if the DNS server was removed, false if it did not exist.
391 * @hide
392 */
Remi NGUYEN VAN94a05572019-01-20 12:38:10 +0900393 @TestApi
394 @SystemApi
Erik Klinecd7ed162015-05-21 16:15:02 +0900395 public boolean removeDnsServer(InetAddress dnsServer) {
396 if (dnsServer != null) {
397 return mDnses.remove(dnsServer);
398 }
399 return false;
400 }
401
402 /**
Lorenzo Colitti309a75d2014-06-24 00:34:39 +0900403 * Replaces the DNS servers in this {@code LinkProperties} with
404 * the given {@link Collection} of {@link InetAddress} objects.
405 *
Chalard Jean03dbf6b2018-04-11 16:36:41 +0900406 * @param dnsServers The {@link Collection} of DNS servers to set in this object.
Lorenzo Colitti309a75d2014-06-24 00:34:39 +0900407 * @hide
408 */
paulhu7610bc72018-12-12 17:52:57 +0800409 @SystemApi
Lorenzo Colitti309a75d2014-06-24 00:34:39 +0900410 public void setDnsServers(Collection<InetAddress> dnsServers) {
411 mDnses.clear();
412 for (InetAddress dnsServer: dnsServers) {
413 addDnsServer(dnsServer);
414 }
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700415 }
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700416
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700417 /**
Sreeram Ramachandrancc91c7b2014-06-03 18:41:43 -0700418 * Returns all the {@link InetAddress} for DNS servers on this link.
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700419 *
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900420 * @return An unmodifiable {@link List} of {@link InetAddress} for DNS servers on
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700421 * this link.
422 */
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700423 public List<InetAddress> getDnsServers() {
424 return Collections.unmodifiableList(mDnses);
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700425 }
426
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700427 /**
dalykd9201342018-01-17 14:20:55 -0500428 * Set whether private DNS is currently in use on this network.
429 *
430 * @param usePrivateDns The private DNS state.
431 * @hide
432 */
Remi NGUYEN VAN94a05572019-01-20 12:38:10 +0900433 @TestApi
434 @SystemApi
dalykd9201342018-01-17 14:20:55 -0500435 public void setUsePrivateDns(boolean usePrivateDns) {
436 mUsePrivateDns = usePrivateDns;
437 }
438
439 /**
440 * Returns whether private DNS is currently in use on this network. When
441 * private DNS is in use, applications must not send unencrypted DNS
442 * queries as doing so could reveal private user information. Furthermore,
443 * if private DNS is in use and {@link #getPrivateDnsServerName} is not
444 * {@code null}, DNS queries must be sent to the specified DNS server.
445 *
446 * @return {@code true} if private DNS is in use, {@code false} otherwise.
447 */
448 public boolean isPrivateDnsActive() {
449 return mUsePrivateDns;
450 }
451
452 /**
453 * Set the name of the private DNS server to which private DNS queries
454 * should be sent when in strict mode. This value should be {@code null}
455 * when private DNS is off or in opportunistic mode.
456 *
457 * @param privateDnsServerName The private DNS server name.
458 * @hide
459 */
Remi NGUYEN VAN94a05572019-01-20 12:38:10 +0900460 @TestApi
461 @SystemApi
dalykd9201342018-01-17 14:20:55 -0500462 public void setPrivateDnsServerName(@Nullable String privateDnsServerName) {
463 mPrivateDnsServerName = privateDnsServerName;
464 }
465
466 /**
467 * Returns the private DNS server name that is in use. If not {@code null},
468 * private DNS is in strict mode. In this mode, applications should ensure
469 * that all DNS queries are encrypted and sent to this hostname and that
470 * queries are only sent if the hostname's certificate is valid. If
471 * {@code null} and {@link #isPrivateDnsActive} is {@code true}, private
472 * DNS is in opportunistic mode, and applications should ensure that DNS
473 * queries are encrypted and sent to a DNS server returned by
474 * {@link #getDnsServers}. System DNS will handle each of these cases
475 * correctly, but applications implementing their own DNS lookups must make
476 * sure to follow these requirements.
477 *
478 * @return The private DNS server name.
479 */
480 public @Nullable String getPrivateDnsServerName() {
481 return mPrivateDnsServerName;
482 }
483
484 /**
Chalard Jean03dbf6b2018-04-11 16:36:41 +0900485 * Adds the given {@link InetAddress} to the list of validated private DNS servers,
486 * if not present. This is distinct from the server name in that these are actually
487 * resolved addresses.
488 *
489 * @param dnsServer The {@link InetAddress} to add to the list of validated private DNS servers.
490 * @return true if the DNS server was added, false if it was already present.
491 * @hide
492 */
493 public boolean addValidatedPrivateDnsServer(InetAddress dnsServer) {
494 if (dnsServer != null && !mValidatedPrivateDnses.contains(dnsServer)) {
495 mValidatedPrivateDnses.add(dnsServer);
496 return true;
497 }
498 return false;
499 }
500
501 /**
502 * Removes the given {@link InetAddress} from the list of validated private DNS servers.
503 *
504 * @param dnsServer The {@link InetAddress} to remove from the list of validated private DNS
505 * servers.
506 * @return true if the DNS server was removed, false if it did not exist.
507 * @hide
508 */
509 public boolean removeValidatedPrivateDnsServer(InetAddress dnsServer) {
510 if (dnsServer != null) {
511 return mValidatedPrivateDnses.remove(dnsServer);
512 }
513 return false;
514 }
515
516 /**
517 * Replaces the validated private DNS servers in this {@code LinkProperties} with
518 * the given {@link Collection} of {@link InetAddress} objects.
519 *
520 * @param dnsServers The {@link Collection} of validated private DNS servers to set in this
521 * object.
522 * @hide
523 */
Remi NGUYEN VAN94a05572019-01-20 12:38:10 +0900524 @TestApi
525 @SystemApi
Chalard Jean03dbf6b2018-04-11 16:36:41 +0900526 public void setValidatedPrivateDnsServers(Collection<InetAddress> dnsServers) {
527 mValidatedPrivateDnses.clear();
528 for (InetAddress dnsServer: dnsServers) {
529 addValidatedPrivateDnsServer(dnsServer);
530 }
531 }
532
533 /**
534 * Returns all the {@link InetAddress} for validated private DNS servers on this link.
535 * These are resolved from the private DNS server name.
536 *
537 * @return An umodifiable {@link List} of {@link InetAddress} for validated private
538 * DNS servers on this link.
539 * @hide
540 */
Remi NGUYEN VAN94a05572019-01-20 12:38:10 +0900541 @TestApi
542 @SystemApi
Chalard Jean03dbf6b2018-04-11 16:36:41 +0900543 public List<InetAddress> getValidatedPrivateDnsServers() {
544 return Collections.unmodifiableList(mValidatedPrivateDnses);
545 }
546
547 /**
Hongshikfa425012018-06-28 20:42:19 +0900548 * Adds the given {@link InetAddress} to the list of PCSCF servers, if not present.
549 *
550 * @param pcscfServer The {@link InetAddress} to add to the list of PCSCF servers.
551 * @return true if the PCSCF server was added, false otherwise.
552 * @hide
553 */
554 public boolean addPcscfServer(InetAddress pcscfServer) {
555 if (pcscfServer != null && !mPcscfs.contains(pcscfServer)) {
556 mPcscfs.add(pcscfServer);
557 return true;
558 }
559 return false;
560 }
561
562 /**
563 * Removes the given {@link InetAddress} from the list of PCSCF servers.
564 *
565 * @param pcscf Server The {@link InetAddress} to remove from the list of PCSCF servers.
566 * @return true if the PCSCF server was removed, false otherwise.
567 * @hide
568 */
569 public boolean removePcscfServer(InetAddress pcscfServer) {
570 if (pcscfServer != null) {
571 return mPcscfs.remove(pcscfServer);
572 }
573 return false;
574 }
575
576 /**
577 * Replaces the PCSCF servers in this {@code LinkProperties} with
578 * the given {@link Collection} of {@link InetAddress} objects.
579 *
580 * @param addresses The {@link Collection} of PCSCF servers to set in this object.
581 * @hide
582 */
Remi NGUYEN VAN299a7cc2019-01-23 21:35:52 +0900583 @SystemApi
584 @TestApi
Hongshikfa425012018-06-28 20:42:19 +0900585 public void setPcscfServers(Collection<InetAddress> pcscfServers) {
586 mPcscfs.clear();
587 for (InetAddress pcscfServer: pcscfServers) {
588 addPcscfServer(pcscfServer);
589 }
590 }
591
592 /**
593 * Returns all the {@link InetAddress} for PCSCF servers on this link.
594 *
595 * @return An unmodifiable {@link List} of {@link InetAddress} for PCSCF servers on
596 * this link.
597 * @hide
598 */
Remi NGUYEN VAN299a7cc2019-01-23 21:35:52 +0900599 @SystemApi
600 @TestApi
Hongshikfa425012018-06-28 20:42:19 +0900601 public List<InetAddress> getPcscfServers() {
602 return Collections.unmodifiableList(mPcscfs);
603 }
604
605 /**
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700606 * Sets the DNS domain search path used on this link.
607 *
608 * @param domains A {@link String} listing in priority order the comma separated
609 * domains to search when resolving host names on this link.
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700610 * @hide
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700611 */
paulhu7610bc72018-12-12 17:52:57 +0800612 @SystemApi
Robert Greenwalt8058f622012-11-09 10:52:27 -0800613 public void setDomains(String domains) {
614 mDomains = domains;
615 }
616
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700617 /**
618 * Get the DNS domains search path set for this link.
619 *
620 * @return A {@link String} containing the comma separated domains to search when resolving
621 * host names on this link.
622 */
623 public String getDomains() {
624 return mDomains;
625 }
626
627 /**
628 * Sets the Maximum Transmission Unit size to use on this link. This should not be used
629 * unless the system default (1500) is incorrect. Values less than 68 or greater than
630 * 10000 will be ignored.
631 *
632 * @param mtu The MTU to use for this link.
633 * @hide
634 */
paulhu7610bc72018-12-12 17:52:57 +0800635 @SystemApi
sy.yun9d9b74a2013-09-02 05:24:09 +0900636 public void setMtu(int mtu) {
637 mMtu = mtu;
638 }
639
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700640 /**
641 * Gets any non-default MTU size set for this link. Note that if the default is being used
642 * this will return 0.
643 *
644 * @return The mtu value set for this link.
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700645 */
sy.yun9d9b74a2013-09-02 05:24:09 +0900646 public int getMtu() {
647 return mMtu;
648 }
649
Robert Greenwalt3f05bf42014-08-06 12:00:25 -0700650 /**
651 * Sets the tcp buffers sizes to be used when this link is the system default.
652 * Should be of the form "rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max".
653 *
654 * @param tcpBufferSizes The tcp buffers sizes to use.
655 *
656 * @hide
657 */
Remi NGUYEN VAN94a05572019-01-20 12:38:10 +0900658 @TestApi
659 @SystemApi
Robert Greenwalt3f05bf42014-08-06 12:00:25 -0700660 public void setTcpBufferSizes(String tcpBufferSizes) {
661 mTcpBufferSizes = tcpBufferSizes;
662 }
663
664 /**
665 * Gets the tcp buffer sizes.
666 *
667 * @return the tcp buffer sizes to use when this link is the system default.
668 *
669 * @hide
670 */
Remi NGUYEN VAN94a05572019-01-20 12:38:10 +0900671 @TestApi
672 @SystemApi
Robert Greenwalt3f05bf42014-08-06 12:00:25 -0700673 public String getTcpBufferSizes() {
674 return mTcpBufferSizes;
675 }
676
Lorenzo Colitti45b9a5b2013-03-08 11:30:39 -0800677 private RouteInfo routeWithInterface(RouteInfo route) {
678 return new RouteInfo(
679 route.getDestination(),
680 route.getGateway(),
Lorenzo Colitti4b0f8e62014-09-19 01:49:05 +0900681 mIfaceName,
682 route.getType());
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700683 }
Lorenzo Colitti45b9a5b2013-03-08 11:30:39 -0800684
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700685 /**
Lorenzo Colittic17a1b92014-06-12 23:10:17 +0900686 * Adds a {@link RouteInfo} to this {@code LinkProperties}, if not present. If the
687 * {@link RouteInfo} had an interface name set and that differs from the interface set for this
688 * {@code LinkProperties} an {@link IllegalArgumentException} will be thrown. The proper
689 * course is to add either un-named or properly named {@link RouteInfo}.
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700690 *
691 * @param route A {@link RouteInfo} to add to this object.
Lorenzo Colittic17a1b92014-06-12 23:10:17 +0900692 * @return {@code false} if the route was already present, {@code true} if it was added.
693 *
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700694 * @hide
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700695 */
paulhu7610bc72018-12-12 17:52:57 +0800696 @SystemApi
Lorenzo Colittic17a1b92014-06-12 23:10:17 +0900697 public boolean addRoute(RouteInfo route) {
Lorenzo Colitti45b9a5b2013-03-08 11:30:39 -0800698 if (route != null) {
699 String routeIface = route.getInterface();
700 if (routeIface != null && !routeIface.equals(mIfaceName)) {
Lorenzo Colitti1994bc12013-03-08 19:11:40 -0800701 throw new IllegalArgumentException(
Lorenzo Colitti45b9a5b2013-03-08 11:30:39 -0800702 "Route added with non-matching interface: " + routeIface +
Lorenzo Colitti1994bc12013-03-08 19:11:40 -0800703 " vs. " + mIfaceName);
Lorenzo Colitti45b9a5b2013-03-08 11:30:39 -0800704 }
Lorenzo Colittic17a1b92014-06-12 23:10:17 +0900705 route = routeWithInterface(route);
706 if (!mRoutes.contains(route)) {
707 mRoutes.add(route);
708 return true;
709 }
Lorenzo Colitti45b9a5b2013-03-08 11:30:39 -0800710 }
Lorenzo Colittic17a1b92014-06-12 23:10:17 +0900711 return false;
712 }
713
714 /**
715 * Removes a {@link RouteInfo} from this {@code LinkProperties}, if present. The route must
716 * specify an interface and the interface must match the interface of this
717 * {@code LinkProperties}, or it will not be removed.
718 *
719 * @return {@code true} if the route was removed, {@code false} if it was not present.
720 *
721 * @hide
722 */
Remi NGUYEN VAN94a05572019-01-20 12:38:10 +0900723 @TestApi
724 @SystemApi
Lorenzo Colittic17a1b92014-06-12 23:10:17 +0900725 public boolean removeRoute(RouteInfo route) {
726 return route != null &&
727 Objects.equals(mIfaceName, route.getInterface()) &&
728 mRoutes.remove(route);
Lorenzo Colitti45b9a5b2013-03-08 11:30:39 -0800729 }
730
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800731 /**
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700732 * Returns all the {@link RouteInfo} set on this link.
733 *
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700734 * @return An unmodifiable {@link List} of {@link RouteInfo} for this link.
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800735 */
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700736 public List<RouteInfo> getRoutes() {
737 return Collections.unmodifiableList(mRoutes);
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700738 }
739
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800740 /**
Rubin Xu1bb5c082017-09-05 18:40:49 +0100741 * Make sure this LinkProperties instance contains routes that cover the local subnet
742 * of its link addresses. Add any route that is missing.
743 * @hide
744 */
745 public void ensureDirectlyConnectedRoutes() {
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900746 for (LinkAddress addr : mLinkAddresses) {
Rubin Xu1bb5c082017-09-05 18:40:49 +0100747 addRoute(new RouteInfo(addr, null, mIfaceName));
748 }
749 }
750
751 /**
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800752 * Returns all the routes on this link and all the links stacked above it.
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700753 * @hide
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800754 */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +0100755 @UnsupportedAppUsage
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700756 public List<RouteInfo> getAllRoutes() {
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900757 List<RouteInfo> routes = new ArrayList<>(mRoutes);
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800758 for (LinkProperties stacked: mStackedLinks.values()) {
759 routes.addAll(stacked.getAllRoutes());
760 }
Robert Greenwalt6629bcd2013-03-15 11:28:50 -0700761 return routes;
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800762 }
763
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700764 /**
765 * Sets the recommended {@link ProxyInfo} to use on this link, or {@code null} for none.
766 * Note that Http Proxies are only a hint - the system recommends their use, but it does
767 * not enforce it and applications may ignore them.
768 *
Erik Klineb36a3132015-06-26 19:21:34 +0900769 * @param proxy A {@link ProxyInfo} defining the HTTP Proxy to use on this link.
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700770 * @hide
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700771 */
paulhu7610bc72018-12-12 17:52:57 +0800772 @SystemApi
Jason Monk207900c2014-04-25 15:00:09 -0400773 public void setHttpProxy(ProxyInfo proxy) {
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700774 mHttpProxy = proxy;
775 }
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700776
777 /**
778 * Gets the recommended {@link ProxyInfo} (or {@code null}) set on this link.
779 *
780 * @return The {@link ProxyInfo} set on this link
781 */
Jason Monk207900c2014-04-25 15:00:09 -0400782 public ProxyInfo getHttpProxy() {
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700783 return mHttpProxy;
784 }
785
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800786 /**
Lorenzo Colitti59b34472019-01-08 09:58:59 +0900787 * Returns the NAT64 prefix in use on this link, if any.
788 *
789 * @return the NAT64 prefix.
790 * @hide
791 */
Remi NGUYEN VAN299a7cc2019-01-23 21:35:52 +0900792 @SystemApi
793 @TestApi
Lorenzo Colitti59b34472019-01-08 09:58:59 +0900794 public @Nullable IpPrefix getNat64Prefix() {
795 return mNat64Prefix;
796 }
797
798 /**
799 * Sets the NAT64 prefix in use on this link.
800 *
801 * Currently, only 96-bit prefixes (i.e., where the 32-bit IPv4 address is at the end of the
802 * 128-bit IPv6 address) are supported.
803 *
804 * @param prefix the NAT64 prefix.
805 * @hide
806 */
Remi NGUYEN VAN299a7cc2019-01-23 21:35:52 +0900807 @SystemApi
808 @TestApi
Lorenzo Colitti59b34472019-01-08 09:58:59 +0900809 public void setNat64Prefix(IpPrefix prefix) {
810 if (prefix != null && prefix.getPrefixLength() != 96) {
811 throw new IllegalArgumentException("Only 96-bit prefixes are supported: " + prefix);
812 }
813 mNat64Prefix = prefix; // IpPrefix objects are immutable.
814 }
815
816 /**
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800817 * Adds a stacked link.
818 *
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900819 * If there is already a stacked link with the same interface name as link,
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800820 * that link is replaced with link. Otherwise, link is added to the list
821 * of stacked links. If link is null, nothing changes.
822 *
823 * @param link The link to add.
Lorenzo Colitti4faa0272013-08-08 11:00:12 +0900824 * @return true if the link was stacked, false otherwise.
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700825 * @hide
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800826 */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +0100827 @UnsupportedAppUsage
Lorenzo Colitti4faa0272013-08-08 11:00:12 +0900828 public boolean addStackedLink(LinkProperties link) {
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800829 if (link != null && link.getInterfaceName() != null) {
830 mStackedLinks.put(link.getInterfaceName(), link);
Lorenzo Colitti4faa0272013-08-08 11:00:12 +0900831 return true;
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800832 }
Lorenzo Colitti4faa0272013-08-08 11:00:12 +0900833 return false;
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800834 }
835
836 /**
837 * Removes a stacked link.
838 *
Lorenzo Colittif3cab632014-10-20 11:08:03 +0900839 * If there is a stacked link with the given interface name, it is
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800840 * removed. Otherwise, nothing changes.
841 *
Lorenzo Colittif3cab632014-10-20 11:08:03 +0900842 * @param iface The interface name of the link to remove.
Lorenzo Colitti4faa0272013-08-08 11:00:12 +0900843 * @return true if the link was removed, false otherwise.
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700844 * @hide
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800845 */
Lorenzo Colittif3cab632014-10-20 11:08:03 +0900846 public boolean removeStackedLink(String iface) {
847 if (iface != null) {
848 LinkProperties removed = mStackedLinks.remove(iface);
Lorenzo Colitti4faa0272013-08-08 11:00:12 +0900849 return removed != null;
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800850 }
Lorenzo Colitti4faa0272013-08-08 11:00:12 +0900851 return false;
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800852 }
853
854 /**
855 * Returns all the links stacked on top of this link.
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700856 * @hide
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800857 */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +0100858 @UnsupportedAppUsage
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700859 public @NonNull List<LinkProperties> getStackedLinks() {
860 if (mStackedLinks.isEmpty()) {
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900861 return Collections.emptyList();
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700862 }
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900863 List<LinkProperties> stacked = new ArrayList<>();
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800864 for (LinkProperties link : mStackedLinks.values()) {
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700865 stacked.add(new LinkProperties(link));
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800866 }
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700867 return Collections.unmodifiableList(stacked);
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800868 }
869
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700870 /**
871 * Clears this object to its initial state.
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700872 * @hide
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700873 */
paulhu7610bc72018-12-12 17:52:57 +0800874 @SystemApi
Robert Greenwalt37e65eb2010-08-30 10:56:47 -0700875 public void clear() {
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700876 mIfaceName = null;
Wink Savillee8222252011-07-13 13:44:13 -0700877 mLinkAddresses.clear();
878 mDnses.clear();
dalykd9201342018-01-17 14:20:55 -0500879 mUsePrivateDns = false;
880 mPrivateDnsServerName = null;
Hongshikfa425012018-06-28 20:42:19 +0900881 mPcscfs.clear();
Robert Greenwalt8058f622012-11-09 10:52:27 -0800882 mDomains = null;
Wink Savillee8222252011-07-13 13:44:13 -0700883 mRoutes.clear();
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700884 mHttpProxy = null;
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800885 mStackedLinks.clear();
sy.yun9d9b74a2013-09-02 05:24:09 +0900886 mMtu = 0;
Robert Greenwalt3f05bf42014-08-06 12:00:25 -0700887 mTcpBufferSizes = null;
Lorenzo Colitti59b34472019-01-08 09:58:59 +0900888 mNat64Prefix = null;
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700889 }
890
891 /**
892 * Implement the Parcelable interface
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700893 */
894 public int describeContents() {
895 return 0;
896 }
897
Wink Saville1f6408a2010-08-27 11:15:18 -0700898 @Override
Robert Greenwalt37e65eb2010-08-30 10:56:47 -0700899 public String toString() {
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900900 // Space as a separator, so no need for spaces at start/end of the individual fragments.
901 final StringJoiner resultJoiner = new StringJoiner(" ", "{", "}");
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700902
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900903 if (mIfaceName != null) {
904 resultJoiner.add("InterfaceName:");
905 resultJoiner.add(mIfaceName);
906 }
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700907
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900908 resultJoiner.add("LinkAddresses: [");
909 if (!mLinkAddresses.isEmpty()) {
910 resultJoiner.add(TextUtils.join(",", mLinkAddresses));
911 }
912 resultJoiner.add("]");
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700913
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900914 resultJoiner.add("DnsAddresses: [");
915 if (!mDnses.isEmpty()) {
916 resultJoiner.add(TextUtils.join(",", mDnses));
917 }
918 resultJoiner.add("]");
dalykd9201342018-01-17 14:20:55 -0500919
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900920 if (mUsePrivateDns) {
921 resultJoiner.add("UsePrivateDns: true");
922 }
923
Chalard Jeanfaaf2fe2018-06-07 13:28:09 +0900924 if (mPrivateDnsServerName != null) {
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900925 resultJoiner.add("PrivateDnsServerName:");
926 resultJoiner.add(mPrivateDnsServerName);
dalykd9201342018-01-17 14:20:55 -0500927 }
928
Hongshikfa425012018-06-28 20:42:19 +0900929 if (!mPcscfs.isEmpty()) {
930 resultJoiner.add("PcscfAddresses: [");
931 resultJoiner.add(TextUtils.join(",", mPcscfs));
932 resultJoiner.add("]");
933 }
934
Chalard Jean03dbf6b2018-04-11 16:36:41 +0900935 if (!mValidatedPrivateDnses.isEmpty()) {
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900936 final StringJoiner validatedPrivateDnsesJoiner =
937 new StringJoiner(",", "ValidatedPrivateDnsAddresses: [", "]");
938 for (final InetAddress addr : mValidatedPrivateDnses) {
939 validatedPrivateDnsesJoiner.add(addr.getHostAddress());
Chalard Jean03dbf6b2018-04-11 16:36:41 +0900940 }
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900941 resultJoiner.add(validatedPrivateDnsesJoiner.toString());
Chalard Jean03dbf6b2018-04-11 16:36:41 +0900942 }
943
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900944 resultJoiner.add("Domains:");
945 resultJoiner.add(mDomains);
Robert Greenwalt8058f622012-11-09 10:52:27 -0800946
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900947 resultJoiner.add("MTU:");
948 resultJoiner.add(Integer.toString(mMtu));
sy.yun9d9b74a2013-09-02 05:24:09 +0900949
Robert Greenwalt3f05bf42014-08-06 12:00:25 -0700950 if (mTcpBufferSizes != null) {
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900951 resultJoiner.add("TcpBufferSizes:");
952 resultJoiner.add(mTcpBufferSizes);
Robert Greenwalt3f05bf42014-08-06 12:00:25 -0700953 }
954
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900955 resultJoiner.add("Routes: [");
956 if (!mRoutes.isEmpty()) {
957 resultJoiner.add(TextUtils.join(",", mRoutes));
958 }
959 resultJoiner.add("]");
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700960
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900961 if (mHttpProxy != null) {
962 resultJoiner.add("HttpProxy:");
963 resultJoiner.add(mHttpProxy.toString());
964 }
965
Lorenzo Colitti59b34472019-01-08 09:58:59 +0900966 if (mNat64Prefix != null) {
967 resultJoiner.add("Nat64Prefix:");
968 resultJoiner.add(mNat64Prefix.toString());
969 }
970
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900971 final Collection<LinkProperties> stackedLinksValues = mStackedLinks.values();
972 if (!stackedLinksValues.isEmpty()) {
973 final StringJoiner stackedLinksJoiner = new StringJoiner(",", "Stacked: [", "]");
974 for (final LinkProperties lp : stackedLinksValues) {
975 stackedLinksJoiner.add("[ " + lp + " ]");
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800976 }
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900977 resultJoiner.add(stackedLinksJoiner.toString());
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800978 }
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +0900979
980 return resultJoiner.toString();
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800981 }
982
983 /**
984 * Returns true if this link has an IPv4 address.
985 *
986 * @return {@code true} if there is an IPv4 address, {@code false} otherwise.
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700987 * @hide
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800988 */
Remi NGUYEN VAN94a05572019-01-20 12:38:10 +0900989 @TestApi
990 @SystemApi
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800991 public boolean hasIPv4Address() {
992 for (LinkAddress address : mLinkAddresses) {
Hugo Benichibd87a392017-10-10 16:29:06 +0900993 if (address.getAddress() instanceof Inet4Address) {
994 return true;
995 }
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800996 }
997 return false;
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700998 }
999
Wink Savillee8222252011-07-13 13:44:13 -07001000 /**
Lorenzo Colitti87cfc702015-07-27 16:35:33 +09001001 * Returns true if this link or any of its stacked interfaces has an IPv4 address.
1002 *
1003 * @return {@code true} if there is an IPv4 address, {@code false} otherwise.
1004 */
1005 private boolean hasIPv4AddressOnInterface(String iface) {
Lorenzo Colitti89b63922015-07-30 23:41:43 +09001006 // mIfaceName can be null.
1007 return (Objects.equals(iface, mIfaceName) && hasIPv4Address()) ||
Lorenzo Colitti87cfc702015-07-27 16:35:33 +09001008 (iface != null && mStackedLinks.containsKey(iface) &&
1009 mStackedLinks.get(iface).hasIPv4Address());
1010 }
1011
1012 /**
Lorenzo Colitti76ea6c62014-06-23 22:33:43 +09001013 * Returns true if this link has a global preferred IPv6 address.
Lorenzo Colitti4faa0272013-08-08 11:00:12 +09001014 *
Lorenzo Colitti76ea6c62014-06-23 22:33:43 +09001015 * @return {@code true} if there is a global preferred IPv6 address, {@code false} otherwise.
Robert Greenwaltdf2b8782014-06-06 10:30:11 -07001016 * @hide
Lorenzo Colitti4faa0272013-08-08 11:00:12 +09001017 */
Remi NGUYEN VAN94a05572019-01-20 12:38:10 +09001018 @TestApi
1019 @SystemApi
Lorenzo Colitti76ea6c62014-06-23 22:33:43 +09001020 public boolean hasGlobalIPv6Address() {
Lorenzo Colitti4faa0272013-08-08 11:00:12 +09001021 for (LinkAddress address : mLinkAddresses) {
Lorenzo Colitti76ea6c62014-06-23 22:33:43 +09001022 if (address.getAddress() instanceof Inet6Address && address.isGlobalPreferred()) {
Lorenzo Colitti4faa0272013-08-08 11:00:12 +09001023 return true;
1024 }
1025 }
1026 return false;
1027 }
1028
1029 /**
Lorenzo Colitti76ea6c62014-06-23 22:33:43 +09001030 * Returns true if this link has an IPv4 default route.
1031 *
1032 * @return {@code true} if there is an IPv4 default route, {@code false} otherwise.
1033 * @hide
1034 */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +01001035 @UnsupportedAppUsage
Lorenzo Colitti76ea6c62014-06-23 22:33:43 +09001036 public boolean hasIPv4DefaultRoute() {
1037 for (RouteInfo r : mRoutes) {
Hugo Benichibd87a392017-10-10 16:29:06 +09001038 if (r.isIPv4Default()) {
1039 return true;
1040 }
Lorenzo Colitti76ea6c62014-06-23 22:33:43 +09001041 }
1042 return false;
1043 }
1044
1045 /**
1046 * Returns true if this link has an IPv6 default route.
1047 *
1048 * @return {@code true} if there is an IPv6 default route, {@code false} otherwise.
1049 * @hide
1050 */
Remi NGUYEN VAN94a05572019-01-20 12:38:10 +09001051 @TestApi
1052 @SystemApi
Lorenzo Colitti76ea6c62014-06-23 22:33:43 +09001053 public boolean hasIPv6DefaultRoute() {
1054 for (RouteInfo r : mRoutes) {
Hugo Benichibd87a392017-10-10 16:29:06 +09001055 if (r.isIPv6Default()) {
1056 return true;
1057 }
Lorenzo Colitti76ea6c62014-06-23 22:33:43 +09001058 }
1059 return false;
1060 }
1061
1062 /**
1063 * Returns true if this link has an IPv4 DNS server.
1064 *
1065 * @return {@code true} if there is an IPv4 DNS server, {@code false} otherwise.
1066 * @hide
1067 */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +01001068 @UnsupportedAppUsage
Lorenzo Colitti76ea6c62014-06-23 22:33:43 +09001069 public boolean hasIPv4DnsServer() {
1070 for (InetAddress ia : mDnses) {
Hugo Benichibd87a392017-10-10 16:29:06 +09001071 if (ia instanceof Inet4Address) {
1072 return true;
1073 }
Lorenzo Colitti76ea6c62014-06-23 22:33:43 +09001074 }
1075 return false;
1076 }
1077
1078 /**
1079 * Returns true if this link has an IPv6 DNS server.
1080 *
1081 * @return {@code true} if there is an IPv6 DNS server, {@code false} otherwise.
1082 * @hide
1083 */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +01001084 @UnsupportedAppUsage
Lorenzo Colitti76ea6c62014-06-23 22:33:43 +09001085 public boolean hasIPv6DnsServer() {
1086 for (InetAddress ia : mDnses) {
Hugo Benichibd87a392017-10-10 16:29:06 +09001087 if (ia instanceof Inet6Address) {
1088 return true;
1089 }
Lorenzo Colitti76ea6c62014-06-23 22:33:43 +09001090 }
1091 return false;
1092 }
1093
1094 /**
Hongshikfa425012018-06-28 20:42:19 +09001095 * Returns true if this link has an IPv4 PCSCF server.
1096 *
1097 * @return {@code true} if there is an IPv4 PCSCF server, {@code false} otherwise.
1098 * @hide
1099 */
1100 public boolean hasIPv4PcscfServer() {
1101 for (InetAddress ia : mPcscfs) {
1102 if (ia instanceof Inet4Address) {
1103 return true;
1104 }
1105 }
1106 return false;
1107 }
1108
1109 /**
1110 * Returns true if this link has an IPv6 PCSCF server.
1111 *
1112 * @return {@code true} if there is an IPv6 PCSCF server, {@code false} otherwise.
1113 * @hide
1114 */
1115 public boolean hasIPv6PcscfServer() {
1116 for (InetAddress ia : mPcscfs) {
1117 if (ia instanceof Inet6Address) {
1118 return true;
1119 }
1120 }
1121 return false;
1122 }
1123
1124 /**
Erik Klined3b9fd32014-10-24 21:50:20 +09001125 * Returns true if this link is provisioned for global IPv4 connectivity.
1126 * This requires an IP address, default route, and DNS server.
1127 *
1128 * @return {@code true} if the link is provisioned, {@code false} otherwise.
Erik Klinecd7ed162015-05-21 16:15:02 +09001129 * @hide
Erik Klined3b9fd32014-10-24 21:50:20 +09001130 */
Remi NGUYEN VAN94a05572019-01-20 12:38:10 +09001131 @TestApi
1132 @SystemApi
Erik Klinecd7ed162015-05-21 16:15:02 +09001133 public boolean isIPv4Provisioned() {
Erik Klined3b9fd32014-10-24 21:50:20 +09001134 return (hasIPv4Address() &&
1135 hasIPv4DefaultRoute() &&
1136 hasIPv4DnsServer());
1137 }
1138
1139 /**
1140 * Returns true if this link is provisioned for global IPv6 connectivity.
1141 * This requires an IP address, default route, and DNS server.
1142 *
1143 * @return {@code true} if the link is provisioned, {@code false} otherwise.
Erik Klinecd7ed162015-05-21 16:15:02 +09001144 * @hide
Erik Klined3b9fd32014-10-24 21:50:20 +09001145 */
Remi NGUYEN VAN94a05572019-01-20 12:38:10 +09001146 @TestApi
1147 @SystemApi
Erik Klinecd7ed162015-05-21 16:15:02 +09001148 public boolean isIPv6Provisioned() {
Erik Klined3b9fd32014-10-24 21:50:20 +09001149 return (hasGlobalIPv6Address() &&
1150 hasIPv6DefaultRoute() &&
1151 hasIPv6DnsServer());
1152 }
1153
1154 /**
1155 * Returns true if this link is provisioned for global connectivity,
1156 * for at least one Internet Protocol family.
Lorenzo Colitti76ea6c62014-06-23 22:33:43 +09001157 *
1158 * @return {@code true} if the link is provisioned, {@code false} otherwise.
1159 * @hide
1160 */
Remi NGUYEN VAN94a05572019-01-20 12:38:10 +09001161 @TestApi
1162 @SystemApi
Lorenzo Colitti76ea6c62014-06-23 22:33:43 +09001163 public boolean isProvisioned() {
Erik Klinecd7ed162015-05-21 16:15:02 +09001164 return (isIPv4Provisioned() || isIPv6Provisioned());
Lorenzo Colitti76ea6c62014-06-23 22:33:43 +09001165 }
1166
1167 /**
Erik Klineb36a3132015-06-26 19:21:34 +09001168 * Evaluate whether the {@link InetAddress} is considered reachable.
1169 *
1170 * @return {@code true} if the given {@link InetAddress} is considered reachable,
1171 * {@code false} otherwise.
1172 * @hide
1173 */
Remi NGUYEN VAN94a05572019-01-20 12:38:10 +09001174 @TestApi
1175 @SystemApi
Erik Klineb36a3132015-06-26 19:21:34 +09001176 public boolean isReachable(InetAddress ip) {
1177 final List<RouteInfo> allRoutes = getAllRoutes();
1178 // If we don't have a route to this IP address, it's not reachable.
1179 final RouteInfo bestRoute = RouteInfo.selectBestRoute(allRoutes, ip);
1180 if (bestRoute == null) {
1181 return false;
1182 }
1183
1184 // TODO: better source address evaluation for destination addresses.
1185
1186 if (ip instanceof Inet4Address) {
1187 // For IPv4, it suffices for now to simply have any address.
Lorenzo Colitti87cfc702015-07-27 16:35:33 +09001188 return hasIPv4AddressOnInterface(bestRoute.getInterface());
Erik Klineb36a3132015-06-26 19:21:34 +09001189 } else if (ip instanceof Inet6Address) {
1190 if (ip.isLinkLocalAddress()) {
1191 // For now, just make sure link-local destinations have
1192 // scopedIds set, since transmits will generally fail otherwise.
1193 // TODO: verify it matches the ifindex of one of the interfaces.
1194 return (((Inet6Address)ip).getScopeId() != 0);
1195 } else {
1196 // For non-link-local destinations check that either the best route
1197 // is directly connected or that some global preferred address exists.
1198 // TODO: reconsider all cases (disconnected ULA networks, ...).
1199 return (!bestRoute.hasGateway() || hasGlobalIPv6Address());
1200 }
1201 }
1202
1203 return false;
1204 }
1205
1206 /**
Wink Savillee8222252011-07-13 13:44:13 -07001207 * Compares this {@code LinkProperties} interface name against the target
1208 *
1209 * @param target LinkProperties to compare.
1210 * @return {@code true} if both are identical, {@code false} otherwise.
Robert Greenwalt4f05d552014-05-18 22:01:38 -07001211 * @hide
Wink Savillee8222252011-07-13 13:44:13 -07001212 */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +01001213 @UnsupportedAppUsage
Wink Savillee8222252011-07-13 13:44:13 -07001214 public boolean isIdenticalInterfaceName(LinkProperties target) {
1215 return TextUtils.equals(getInterfaceName(), target.getInterfaceName());
1216 }
1217
1218 /**
Robert Greenwalt4717c262012-10-31 14:32:53 -07001219 * Compares this {@code LinkProperties} interface addresses against the target
Wink Savillee8222252011-07-13 13:44:13 -07001220 *
1221 * @param target LinkProperties to compare.
1222 * @return {@code true} if both are identical, {@code false} otherwise.
Robert Greenwalt4f05d552014-05-18 22:01:38 -07001223 * @hide
Wink Savillee8222252011-07-13 13:44:13 -07001224 */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +01001225 @UnsupportedAppUsage
Wink Savillee8222252011-07-13 13:44:13 -07001226 public boolean isIdenticalAddresses(LinkProperties target) {
1227 Collection<InetAddress> targetAddresses = target.getAddresses();
1228 Collection<InetAddress> sourceAddresses = getAddresses();
1229 return (sourceAddresses.size() == targetAddresses.size()) ?
1230 sourceAddresses.containsAll(targetAddresses) : false;
1231 }
1232
1233 /**
1234 * Compares this {@code LinkProperties} DNS addresses against the target
1235 *
1236 * @param target LinkProperties to compare.
1237 * @return {@code true} if both are identical, {@code false} otherwise.
Robert Greenwalt4f05d552014-05-18 22:01:38 -07001238 * @hide
Wink Savillee8222252011-07-13 13:44:13 -07001239 */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +01001240 @UnsupportedAppUsage
Wink Savillee8222252011-07-13 13:44:13 -07001241 public boolean isIdenticalDnses(LinkProperties target) {
Robert Greenwaltdf2b8782014-06-06 10:30:11 -07001242 Collection<InetAddress> targetDnses = target.getDnsServers();
Robert Greenwalt8058f622012-11-09 10:52:27 -08001243 String targetDomains = target.getDomains();
1244 if (mDomains == null) {
1245 if (targetDomains != null) return false;
1246 } else {
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +09001247 if (!mDomains.equals(targetDomains)) return false;
Robert Greenwalt8058f622012-11-09 10:52:27 -08001248 }
Wink Savillee8222252011-07-13 13:44:13 -07001249 return (mDnses.size() == targetDnses.size()) ?
Chalard Jean03dbf6b2018-04-11 16:36:41 +09001250 mDnses.containsAll(targetDnses) : false;
Wink Savillee8222252011-07-13 13:44:13 -07001251 }
1252
1253 /**
dalykd9201342018-01-17 14:20:55 -05001254 * Compares this {@code LinkProperties} private DNS settings against the
1255 * target.
1256 *
1257 * @param target LinkProperties to compare.
1258 * @return {@code true} if both are identical, {@code false} otherwise.
1259 * @hide
1260 */
1261 public boolean isIdenticalPrivateDns(LinkProperties target) {
1262 return (isPrivateDnsActive() == target.isPrivateDnsActive()
1263 && TextUtils.equals(getPrivateDnsServerName(),
1264 target.getPrivateDnsServerName()));
1265 }
1266
1267 /**
Chalard Jean03dbf6b2018-04-11 16:36:41 +09001268 * Compares this {@code LinkProperties} validated private DNS addresses against
1269 * the target
1270 *
1271 * @param target LinkProperties to compare.
1272 * @return {@code true} if both are identical, {@code false} otherwise.
1273 * @hide
1274 */
1275 public boolean isIdenticalValidatedPrivateDnses(LinkProperties target) {
1276 Collection<InetAddress> targetDnses = target.getValidatedPrivateDnsServers();
1277 return (mValidatedPrivateDnses.size() == targetDnses.size())
1278 ? mValidatedPrivateDnses.containsAll(targetDnses) : false;
1279 }
1280
1281 /**
Hongshikfa425012018-06-28 20:42:19 +09001282 * Compares this {@code LinkProperties} PCSCF addresses against the target
1283 *
1284 * @param target LinkProperties to compare.
1285 * @return {@code true} if both are identical, {@code false} otherwise.
1286 * @hide
1287 */
1288 public boolean isIdenticalPcscfs(LinkProperties target) {
1289 Collection<InetAddress> targetPcscfs = target.getPcscfServers();
1290 return (mPcscfs.size() == targetPcscfs.size()) ?
1291 mPcscfs.containsAll(targetPcscfs) : false;
1292 }
1293
1294 /**
Wink Savillee8222252011-07-13 13:44:13 -07001295 * Compares this {@code LinkProperties} Routes against the target
1296 *
1297 * @param target LinkProperties to compare.
1298 * @return {@code true} if both are identical, {@code false} otherwise.
Robert Greenwalt4f05d552014-05-18 22:01:38 -07001299 * @hide
Wink Savillee8222252011-07-13 13:44:13 -07001300 */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +01001301 @UnsupportedAppUsage
Wink Savillee8222252011-07-13 13:44:13 -07001302 public boolean isIdenticalRoutes(LinkProperties target) {
1303 Collection<RouteInfo> targetRoutes = target.getRoutes();
1304 return (mRoutes.size() == targetRoutes.size()) ?
Chalard Jean03dbf6b2018-04-11 16:36:41 +09001305 mRoutes.containsAll(targetRoutes) : false;
Wink Savillee8222252011-07-13 13:44:13 -07001306 }
1307
1308 /**
1309 * Compares this {@code LinkProperties} HttpProxy against the target
1310 *
1311 * @param target LinkProperties to compare.
1312 * @return {@code true} if both are identical, {@code false} otherwise.
Robert Greenwalt4f05d552014-05-18 22:01:38 -07001313 * @hide
Wink Savillee8222252011-07-13 13:44:13 -07001314 */
Mathew Inwood55418ea2018-12-20 15:30:45 +00001315 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Wink Savillee8222252011-07-13 13:44:13 -07001316 public boolean isIdenticalHttpProxy(LinkProperties target) {
1317 return getHttpProxy() == null ? target.getHttpProxy() == null :
Chalard Jean03dbf6b2018-04-11 16:36:41 +09001318 getHttpProxy().equals(target.getHttpProxy());
Wink Savillee8222252011-07-13 13:44:13 -07001319 }
John Wang4e900092011-04-04 12:35:42 -07001320
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -08001321 /**
1322 * Compares this {@code LinkProperties} stacked links against the target
1323 *
1324 * @param target LinkProperties to compare.
1325 * @return {@code true} if both are identical, {@code false} otherwise.
Robert Greenwalt4f05d552014-05-18 22:01:38 -07001326 * @hide
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -08001327 */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +01001328 @UnsupportedAppUsage
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -08001329 public boolean isIdenticalStackedLinks(LinkProperties target) {
Lorenzo Colitti213f98b2013-04-01 10:47:43 +09001330 if (!mStackedLinks.keySet().equals(target.mStackedLinks.keySet())) {
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -08001331 return false;
1332 }
1333 for (LinkProperties stacked : mStackedLinks.values()) {
1334 // Hashtable values can never be null.
1335 String iface = stacked.getInterfaceName();
1336 if (!stacked.equals(target.mStackedLinks.get(iface))) {
1337 return false;
1338 }
1339 }
1340 return true;
1341 }
1342
sy.yun9d9b74a2013-09-02 05:24:09 +09001343 /**
1344 * Compares this {@code LinkProperties} MTU against the target
1345 *
Ying Wangd57de6a2013-09-06 22:53:16 -07001346 * @param target LinkProperties to compare.
sy.yun9d9b74a2013-09-02 05:24:09 +09001347 * @return {@code true} if both are identical, {@code false} otherwise.
Robert Greenwalt4f05d552014-05-18 22:01:38 -07001348 * @hide
sy.yun9d9b74a2013-09-02 05:24:09 +09001349 */
1350 public boolean isIdenticalMtu(LinkProperties target) {
1351 return getMtu() == target.getMtu();
1352 }
1353
Robert Greenwalt3f05bf42014-08-06 12:00:25 -07001354 /**
1355 * Compares this {@code LinkProperties} Tcp buffer sizes against the target.
1356 *
1357 * @param target LinkProperties to compare.
1358 * @return {@code true} if both are identical, {@code false} otherwise.
1359 * @hide
1360 */
1361 public boolean isIdenticalTcpBufferSizes(LinkProperties target) {
1362 return Objects.equals(mTcpBufferSizes, target.mTcpBufferSizes);
1363 }
1364
John Wang4e900092011-04-04 12:35:42 -07001365 /**
Lorenzo Colitti59b34472019-01-08 09:58:59 +09001366 * Compares this {@code LinkProperties} NAT64 prefix against the target.
1367 *
1368 * @param target LinkProperties to compare.
1369 * @return {@code true} if both are identical, {@code false} otherwise.
1370 * @hide
1371 */
1372 public boolean isIdenticalNat64Prefix(LinkProperties target) {
1373 return Objects.equals(mNat64Prefix, target.mNat64Prefix);
1374 }
1375
1376 /**
John Wang4e900092011-04-04 12:35:42 -07001377 * Compares this {@code LinkProperties} instance against the target
1378 * LinkProperties in {@code obj}. Two LinkPropertieses are equal if
1379 * all their fields are equal in values.
1380 *
1381 * For collection fields, such as mDnses, containsAll() is used to check
1382 * if two collections contains the same elements, independent of order.
1383 * There are two thoughts regarding containsAll()
1384 * 1. Duplicated elements. eg, (A, B, B) and (A, A, B) are equal.
1385 * 2. Worst case performance is O(n^2).
1386 *
1387 * @param obj the object to be tested for equality.
1388 * @return {@code true} if both objects are equal, {@code false} otherwise.
1389 */
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +09001390 @Override
John Wang4e900092011-04-04 12:35:42 -07001391 public boolean equals(Object obj) {
1392 if (this == obj) return true;
1393
1394 if (!(obj instanceof LinkProperties)) return false;
1395
John Wang4e900092011-04-04 12:35:42 -07001396 LinkProperties target = (LinkProperties) obj;
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +09001397 /*
Robert Greenwalt4f05d552014-05-18 22:01:38 -07001398 * This method does not check that stacked interfaces are equal, because
1399 * stacked interfaces are not so much a property of the link as a
1400 * description of connections between links.
1401 */
dalykd9201342018-01-17 14:20:55 -05001402 return isIdenticalInterfaceName(target)
1403 && isIdenticalAddresses(target)
1404 && isIdenticalDnses(target)
1405 && isIdenticalPrivateDns(target)
Chalard Jean03dbf6b2018-04-11 16:36:41 +09001406 && isIdenticalValidatedPrivateDnses(target)
Hongshikfa425012018-06-28 20:42:19 +09001407 && isIdenticalPcscfs(target)
dalykd9201342018-01-17 14:20:55 -05001408 && isIdenticalRoutes(target)
1409 && isIdenticalHttpProxy(target)
1410 && isIdenticalStackedLinks(target)
1411 && isIdenticalMtu(target)
Lorenzo Colitti59b34472019-01-08 09:58:59 +09001412 && isIdenticalTcpBufferSizes(target)
1413 && isIdenticalNat64Prefix(target);
Wink Savillee8222252011-07-13 13:44:13 -07001414 }
John Wang4e900092011-04-04 12:35:42 -07001415
Wink Savillee8222252011-07-13 13:44:13 -07001416 /**
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +09001417 * Compares the addresses in this LinkProperties with another
1418 * LinkProperties, examining only addresses on the base link.
Wink Savillee8222252011-07-13 13:44:13 -07001419 *
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +09001420 * @param target a LinkProperties with the new list of addresses
1421 * @return the differences between the addresses.
Robert Greenwalt4f05d552014-05-18 22:01:38 -07001422 * @hide
Wink Savillee8222252011-07-13 13:44:13 -07001423 */
Robert Greenwalt0a46db52011-07-14 14:28:05 -07001424 public CompareResult<LinkAddress> compareAddresses(LinkProperties target) {
Wink Savillee8222252011-07-13 13:44:13 -07001425 /*
1426 * Duplicate the LinkAddresses into removed, we will be removing
1427 * address which are common between mLinkAddresses and target
1428 * leaving the addresses that are different. And address which
1429 * are in target but not in mLinkAddresses are placed in the
1430 * addedAddresses.
1431 */
Rubin Xu2fc72f72017-08-22 16:35:52 +01001432 return new CompareResult<>(mLinkAddresses,
1433 target != null ? target.getLinkAddresses() : null);
John Wang4e900092011-04-04 12:35:42 -07001434 }
1435
Robert Greenwalt0a46db52011-07-14 14:28:05 -07001436 /**
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +09001437 * Compares the DNS addresses in this LinkProperties with another
1438 * LinkProperties, examining only DNS addresses on the base link.
Robert Greenwalt0a46db52011-07-14 14:28:05 -07001439 *
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +09001440 * @param target a LinkProperties with the new list of dns addresses
1441 * @return the differences between the DNS addresses.
Robert Greenwalt4f05d552014-05-18 22:01:38 -07001442 * @hide
Robert Greenwalt0a46db52011-07-14 14:28:05 -07001443 */
1444 public CompareResult<InetAddress> compareDnses(LinkProperties target) {
1445 /*
1446 * Duplicate the InetAddresses into removed, we will be removing
1447 * dns address which are common between mDnses and target
1448 * leaving the addresses that are different. And dns address which
1449 * are in target but not in mDnses are placed in the
1450 * addedAddresses.
1451 */
Rubin Xu2fc72f72017-08-22 16:35:52 +01001452 return new CompareResult<>(mDnses, target != null ? target.getDnsServers() : null);
Robert Greenwalt0a46db52011-07-14 14:28:05 -07001453 }
1454
1455 /**
Chalard Jean03dbf6b2018-04-11 16:36:41 +09001456 * Compares the validated private DNS addresses in this LinkProperties with another
1457 * LinkProperties.
1458 *
1459 * @param target a LinkProperties with the new list of validated private dns addresses
1460 * @return the differences between the DNS addresses.
1461 * @hide
1462 */
1463 public CompareResult<InetAddress> compareValidatedPrivateDnses(LinkProperties target) {
1464 return new CompareResult<>(mValidatedPrivateDnses,
1465 target != null ? target.getValidatedPrivateDnsServers() : null);
1466 }
1467
1468 /**
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +09001469 * Compares all routes in this LinkProperties with another LinkProperties,
1470 * examining both the the base link and all stacked links.
Robert Greenwalt0a46db52011-07-14 14:28:05 -07001471 *
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +09001472 * @param target a LinkProperties with the new list of routes
1473 * @return the differences between the routes.
Robert Greenwalt4f05d552014-05-18 22:01:38 -07001474 * @hide
Robert Greenwalt0a46db52011-07-14 14:28:05 -07001475 */
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +09001476 public CompareResult<RouteInfo> compareAllRoutes(LinkProperties target) {
Robert Greenwalt0a46db52011-07-14 14:28:05 -07001477 /*
1478 * Duplicate the RouteInfos into removed, we will be removing
Lorenzo Colitti1994bc12013-03-08 19:11:40 -08001479 * routes which are common between mRoutes and target
Robert Greenwalt0a46db52011-07-14 14:28:05 -07001480 * leaving the routes that are different. And route address which
1481 * are in target but not in mRoutes are placed in added.
1482 */
Rubin Xu2fc72f72017-08-22 16:35:52 +01001483 return new CompareResult<>(getAllRoutes(), target != null ? target.getAllRoutes() : null);
Robert Greenwalt0a46db52011-07-14 14:28:05 -07001484 }
1485
Paul Jensen992f2522014-04-28 10:33:11 -04001486 /**
1487 * Compares all interface names in this LinkProperties with another
1488 * LinkProperties, examining both the the base link and all stacked links.
1489 *
1490 * @param target a LinkProperties with the new list of interface names
1491 * @return the differences between the interface names.
1492 * @hide
1493 */
1494 public CompareResult<String> compareAllInterfaceNames(LinkProperties target) {
1495 /*
1496 * Duplicate the interface names into removed, we will be removing
1497 * interface names which are common between this and target
1498 * leaving the interface names that are different. And interface names which
1499 * are in target but not in this are placed in added.
1500 */
Rubin Xu2fc72f72017-08-22 16:35:52 +01001501 return new CompareResult<>(getAllInterfaceNames(),
1502 target != null ? target.getAllInterfaceNames() : null);
Paul Jensen992f2522014-04-28 10:33:11 -04001503 }
1504
Robert Greenwalt0a46db52011-07-14 14:28:05 -07001505
John Wang4e900092011-04-04 12:35:42 -07001506 /**
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +09001507 * Generate hashcode based on significant fields
1508 *
John Wang4e900092011-04-04 12:35:42 -07001509 * Equal objects must produce the same hash code, while unequal objects
1510 * may have the same hash codes.
1511 */
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +09001512 @Override
John Wang4e900092011-04-04 12:35:42 -07001513 public int hashCode() {
1514 return ((null == mIfaceName) ? 0 : mIfaceName.hashCode()
1515 + mLinkAddresses.size() * 31
1516 + mDnses.size() * 37
Chalard Jean03dbf6b2018-04-11 16:36:41 +09001517 + mValidatedPrivateDnses.size() * 61
Robert Greenwalt8058f622012-11-09 10:52:27 -08001518 + ((null == mDomains) ? 0 : mDomains.hashCode())
Robert Greenwaltaa70f102011-04-28 14:28:50 -07001519 + mRoutes.size() * 41
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -08001520 + ((null == mHttpProxy) ? 0 : mHttpProxy.hashCode())
sy.yun9d9b74a2013-09-02 05:24:09 +09001521 + mStackedLinks.hashCode() * 47)
Robert Greenwalt3f05bf42014-08-06 12:00:25 -07001522 + mMtu * 51
dalykd9201342018-01-17 14:20:55 -05001523 + ((null == mTcpBufferSizes) ? 0 : mTcpBufferSizes.hashCode())
1524 + (mUsePrivateDns ? 57 : 0)
Hongshikfa425012018-06-28 20:42:19 +09001525 + mPcscfs.size() * 67
Lorenzo Colitti59b34472019-01-08 09:58:59 +09001526 + ((null == mPrivateDnsServerName) ? 0 : mPrivateDnsServerName.hashCode())
1527 + Objects.hash(mNat64Prefix);
John Wang4e900092011-04-04 12:35:42 -07001528 }
1529
Robert Greenwalt47f69fe2010-06-15 15:43:39 -07001530 /**
1531 * Implement the Parcelable interface.
Robert Greenwalt47f69fe2010-06-15 15:43:39 -07001532 */
Robert Greenwalt37e65eb2010-08-30 10:56:47 -07001533 public void writeToParcel(Parcel dest, int flags) {
Robert Greenwalt47f69fe2010-06-15 15:43:39 -07001534 dest.writeString(getInterfaceName());
Irfan Sheriffed5d7d12010-10-01 16:08:28 -07001535 dest.writeInt(mLinkAddresses.size());
Chalard Jean03dbf6b2018-04-11 16:36:41 +09001536 for (LinkAddress linkAddress : mLinkAddresses) {
Irfan Sheriffed5d7d12010-10-01 16:08:28 -07001537 dest.writeParcelable(linkAddress, flags);
Robert Greenwalt47f69fe2010-06-15 15:43:39 -07001538 }
Irfan Sheriffed5d7d12010-10-01 16:08:28 -07001539
Robert Greenwalt47f69fe2010-06-15 15:43:39 -07001540 dest.writeInt(mDnses.size());
Chalard Jean03dbf6b2018-04-11 16:36:41 +09001541 for (InetAddress d : mDnses) {
1542 dest.writeByteArray(d.getAddress());
1543 }
1544 dest.writeInt(mValidatedPrivateDnses.size());
1545 for (InetAddress d : mValidatedPrivateDnses) {
Robert Greenwalt47f69fe2010-06-15 15:43:39 -07001546 dest.writeByteArray(d.getAddress());
1547 }
dalykd9201342018-01-17 14:20:55 -05001548 dest.writeBoolean(mUsePrivateDns);
1549 dest.writeString(mPrivateDnsServerName);
Hongshikfa425012018-06-28 20:42:19 +09001550 dest.writeInt(mPcscfs.size());
1551 for (InetAddress d : mPcscfs) {
1552 dest.writeByteArray(d.getAddress());
1553 }
Robert Greenwalt8058f622012-11-09 10:52:27 -08001554 dest.writeString(mDomains);
sy.yun9d9b74a2013-09-02 05:24:09 +09001555 dest.writeInt(mMtu);
Robert Greenwalt3f05bf42014-08-06 12:00:25 -07001556 dest.writeString(mTcpBufferSizes);
Robert Greenwaltaa70f102011-04-28 14:28:50 -07001557 dest.writeInt(mRoutes.size());
Chalard Jean03dbf6b2018-04-11 16:36:41 +09001558 for (RouteInfo route : mRoutes) {
Robert Greenwaltaa70f102011-04-28 14:28:50 -07001559 dest.writeParcelable(route, flags);
Robert Greenwalt47f69fe2010-06-15 15:43:39 -07001560 }
Robert Greenwalt992564e2011-02-09 13:56:06 -08001561
Robert Greenwalt47f69fe2010-06-15 15:43:39 -07001562 if (mHttpProxy != null) {
1563 dest.writeByte((byte)1);
1564 dest.writeParcelable(mHttpProxy, flags);
1565 } else {
1566 dest.writeByte((byte)0);
1567 }
Lorenzo Colitti59b34472019-01-08 09:58:59 +09001568 dest.writeParcelable(mNat64Prefix, 0);
1569
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +09001570 ArrayList<LinkProperties> stackedLinks = new ArrayList<>(mStackedLinks.values());
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -08001571 dest.writeList(stackedLinks);
Robert Greenwalt47f69fe2010-06-15 15:43:39 -07001572 }
1573
1574 /**
1575 * Implement the Parcelable interface.
Robert Greenwalt47f69fe2010-06-15 15:43:39 -07001576 */
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07001577 public static final @android.annotation.NonNull Creator<LinkProperties> CREATOR =
Robert Greenwalt37e65eb2010-08-30 10:56:47 -07001578 new Creator<LinkProperties>() {
1579 public LinkProperties createFromParcel(Parcel in) {
1580 LinkProperties netProp = new LinkProperties();
Robert Greenwalt4717c262012-10-31 14:32:53 -07001581
Robert Greenwalt47f69fe2010-06-15 15:43:39 -07001582 String iface = in.readString();
1583 if (iface != null) {
Robert Greenwalt4717c262012-10-31 14:32:53 -07001584 netProp.setInterfaceName(iface);
Robert Greenwalt47f69fe2010-06-15 15:43:39 -07001585 }
1586 int addressCount = in.readInt();
Chalard Jean03dbf6b2018-04-11 16:36:41 +09001587 for (int i = 0; i < addressCount; i++) {
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +09001588 netProp.addLinkAddress(in.readParcelable(null));
Robert Greenwalt47f69fe2010-06-15 15:43:39 -07001589 }
1590 addressCount = in.readInt();
Chalard Jean03dbf6b2018-04-11 16:36:41 +09001591 for (int i = 0; i < addressCount; i++) {
Robert Greenwalt47f69fe2010-06-15 15:43:39 -07001592 try {
Robert Greenwaltdf2b8782014-06-06 10:30:11 -07001593 netProp.addDnsServer(InetAddress.getByAddress(in.createByteArray()));
Robert Greenwalt47f69fe2010-06-15 15:43:39 -07001594 } catch (UnknownHostException e) { }
1595 }
Chalard Jean03dbf6b2018-04-11 16:36:41 +09001596 addressCount = in.readInt();
1597 for (int i = 0; i < addressCount; i++) {
1598 try {
1599 netProp.addValidatedPrivateDnsServer(
1600 InetAddress.getByAddress(in.createByteArray()));
1601 } catch (UnknownHostException e) { }
1602 }
dalykd9201342018-01-17 14:20:55 -05001603 netProp.setUsePrivateDns(in.readBoolean());
1604 netProp.setPrivateDnsServerName(in.readString());
Hongshikfa425012018-06-28 20:42:19 +09001605 addressCount = in.readInt();
1606 for (int i = 0; i < addressCount; i++) {
1607 try {
1608 netProp.addPcscfServer(InetAddress.getByAddress(in.createByteArray()));
1609 } catch (UnknownHostException e) { }
1610 }
Robert Greenwalt8058f622012-11-09 10:52:27 -08001611 netProp.setDomains(in.readString());
sy.yun9d9b74a2013-09-02 05:24:09 +09001612 netProp.setMtu(in.readInt());
Robert Greenwalt3f05bf42014-08-06 12:00:25 -07001613 netProp.setTcpBufferSizes(in.readString());
Robert Greenwalt992564e2011-02-09 13:56:06 -08001614 addressCount = in.readInt();
Chalard Jean03dbf6b2018-04-11 16:36:41 +09001615 for (int i = 0; i < addressCount; i++) {
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +09001616 netProp.addRoute(in.readParcelable(null));
Robert Greenwalt47f69fe2010-06-15 15:43:39 -07001617 }
1618 if (in.readByte() == 1) {
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +09001619 netProp.setHttpProxy(in.readParcelable(null));
Robert Greenwalt47f69fe2010-06-15 15:43:39 -07001620 }
Lorenzo Colitti59b34472019-01-08 09:58:59 +09001621 netProp.setNat64Prefix(in.readParcelable(null));
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -08001622 ArrayList<LinkProperties> stackedLinks = new ArrayList<LinkProperties>();
1623 in.readList(stackedLinks, LinkProperties.class.getClassLoader());
1624 for (LinkProperties stackedLink: stackedLinks) {
1625 netProp.addStackedLink(stackedLink);
1626 }
Robert Greenwalt47f69fe2010-06-15 15:43:39 -07001627 return netProp;
1628 }
1629
Robert Greenwalt37e65eb2010-08-30 10:56:47 -07001630 public LinkProperties[] newArray(int size) {
1631 return new LinkProperties[size];
Robert Greenwalt47f69fe2010-06-15 15:43:39 -07001632 }
1633 };
w1997615afd812014-08-05 15:18:11 -07001634
Chalard Jean03dbf6b2018-04-11 16:36:41 +09001635 /**
1636 * Check the valid MTU range based on IPv4 or IPv6.
1637 * @hide
1638 */
1639 public static boolean isValidMtu(int mtu, boolean ipv6) {
1640 if (ipv6) {
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +09001641 return mtu >= MIN_MTU_V6 && mtu <= MAX_MTU;
Chalard Jean03dbf6b2018-04-11 16:36:41 +09001642 } else {
Chalard Jeanb8cfa1d2018-06-07 13:27:00 +09001643 return mtu >= MIN_MTU && mtu <= MAX_MTU;
w1997615afd812014-08-05 15:18:11 -07001644 }
Chalard Jean03dbf6b2018-04-11 16:36:41 +09001645 }
Robert Greenwalt47f69fe2010-06-15 15:43:39 -07001646}