blob: 194cffd164c4cba0fb1785aaf39b7c23b3bda728 [file] [log] [blame]
Lorenzo Colittief734f82014-07-31 00:48:01 +09001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
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
paulhu38068532019-03-15 17:17:02 +080019import android.annotation.NonNull;
20import android.annotation.Nullable;
Remi NGUYEN VAN8bd18cf2019-01-28 13:28:35 +090021import android.annotation.SystemApi;
Artur Satayev9c2add62019-12-10 17:47:52 +000022import android.compat.annotation.UnsupportedAppUsage;
Mathew Inwoode1a17ba2020-11-04 09:29:36 +000023import android.os.Build;
Lorenzo Colittief734f82014-07-31 00:48:01 +090024import android.os.Parcel;
Remi NGUYEN VAN8bd18cf2019-01-28 13:28:35 +090025import android.os.Parcelable;
Lorenzo Colittief734f82014-07-31 00:48:01 +090026
Chalard Jean059356d2020-07-31 20:00:30 +090027import com.android.net.module.util.InetAddressUtils;
Roshan Pius32b898b2019-11-14 12:20:41 -080028
Etan Cohen1e86b3a2021-12-12 02:14:06 +000029import java.net.Inet4Address;
Lorenzo Colittief734f82014-07-31 00:48:01 +090030import java.net.InetAddress;
Lorenzo Colittief734f82014-07-31 00:48:01 +090031import java.util.ArrayList;
32import java.util.List;
33import java.util.Objects;
34
35/**
36 * Class that describes static IP configuration.
Lorenzo Colittief734f82014-07-31 00:48:01 +090037 */
Remi NGUYEN VAN8bd18cf2019-01-28 13:28:35 +090038public final class StaticIpConfiguration implements Parcelable {
39 /** @hide */
Mathew Inwoode1a17ba2020-11-04 09:29:36 +000040 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
paulhu38068532019-03-15 17:17:02 +080041 @Nullable
Lorenzo Colittief734f82014-07-31 00:48:01 +090042 public LinkAddress ipAddress;
Remi NGUYEN VAN8bd18cf2019-01-28 13:28:35 +090043 /** @hide */
Mathew Inwoode1a17ba2020-11-04 09:29:36 +000044 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
paulhu38068532019-03-15 17:17:02 +080045 @Nullable
Lorenzo Colittief734f82014-07-31 00:48:01 +090046 public InetAddress gateway;
Remi NGUYEN VAN8bd18cf2019-01-28 13:28:35 +090047 /** @hide */
Mathew Inwoode1a17ba2020-11-04 09:29:36 +000048 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
paulhu38068532019-03-15 17:17:02 +080049 @NonNull
Lorenzo Colittief734f82014-07-31 00:48:01 +090050 public final ArrayList<InetAddress> dnsServers;
Remi NGUYEN VAN8bd18cf2019-01-28 13:28:35 +090051 /** @hide */
Mathew Inwoode1a17ba2020-11-04 09:29:36 +000052 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
paulhu38068532019-03-15 17:17:02 +080053 @Nullable
Lorenzo Colittief734f82014-07-31 00:48:01 +090054 public String domains;
55
Etan Cohen1e86b3a2021-12-12 02:14:06 +000056 /** @hide */
57 @SystemApi
Lorenzo Colittief734f82014-07-31 00:48:01 +090058 public StaticIpConfiguration() {
Remi NGUYEN VAN04c58fe2019-04-01 17:09:05 +090059 dnsServers = new ArrayList<>();
Lorenzo Colittief734f82014-07-31 00:48:01 +090060 }
61
Etan Cohen1e86b3a2021-12-12 02:14:06 +000062 /** @hide */
63 @SystemApi
paulhu38068532019-03-15 17:17:02 +080064 public StaticIpConfiguration(@Nullable StaticIpConfiguration source) {
Lorenzo Colittief734f82014-07-31 00:48:01 +090065 this();
66 if (source != null) {
67 // All of these except dnsServers are immutable, so no need to make copies.
68 ipAddress = source.ipAddress;
69 gateway = source.gateway;
70 dnsServers.addAll(source.dnsServers);
71 domains = source.domains;
72 }
73 }
74
Etan Cohen1e86b3a2021-12-12 02:14:06 +000075 /** @hide */
76 @SystemApi
Lorenzo Colittief734f82014-07-31 00:48:01 +090077 public void clear() {
78 ipAddress = null;
79 gateway = null;
80 dnsServers.clear();
81 domains = null;
82 }
83
Remi NGUYEN VAN04c58fe2019-04-01 17:09:05 +090084 /**
85 * Get the static IP address included in the configuration.
86 */
Etan Cohen1e86b3a2021-12-12 02:14:06 +000087 public @NonNull LinkAddress getIpAddress() {
Remi NGUYEN VAN8bd18cf2019-01-28 13:28:35 +090088 return ipAddress;
89 }
90
Remi NGUYEN VAN04c58fe2019-04-01 17:09:05 +090091 /**
92 * Get the gateway included in the configuration.
93 */
paulhu38068532019-03-15 17:17:02 +080094 public @Nullable InetAddress getGateway() {
Remi NGUYEN VAN8bd18cf2019-01-28 13:28:35 +090095 return gateway;
96 }
97
Remi NGUYEN VAN04c58fe2019-04-01 17:09:05 +090098 /**
99 * Get the DNS servers included in the configuration.
100 */
paulhu38068532019-03-15 17:17:02 +0800101 public @NonNull List<InetAddress> getDnsServers() {
Remi NGUYEN VAN8bd18cf2019-01-28 13:28:35 +0900102 return dnsServers;
103 }
104
Remi NGUYEN VAN04c58fe2019-04-01 17:09:05 +0900105 /**
Remi NGUYEN VAN9ed32082019-04-03 15:54:25 +0900106 * Get a {@link String} containing the comma separated domains to search when resolving host
107 * names on this link, in priority order.
Remi NGUYEN VAN04c58fe2019-04-01 17:09:05 +0900108 */
paulhu38068532019-03-15 17:17:02 +0800109 public @Nullable String getDomains() {
Remi NGUYEN VAN8bd18cf2019-01-28 13:28:35 +0900110 return domains;
111 }
112
Remi NGUYEN VAN04c58fe2019-04-01 17:09:05 +0900113 /**
114 * Helper class to build a new instance of {@link StaticIpConfiguration}.
115 */
116 public static final class Builder {
117 private LinkAddress mIpAddress;
118 private InetAddress mGateway;
119 private Iterable<InetAddress> mDnsServers;
120 private String mDomains;
121
122 /**
Etan Cohen1e86b3a2021-12-12 02:14:06 +0000123 * Set the IP address to be included in the configuration.
124 *
Remi NGUYEN VAN04c58fe2019-04-01 17:09:05 +0900125 * @return The {@link Builder} for chaining.
126 */
Etan Cohen1e86b3a2021-12-12 02:14:06 +0000127 public @NonNull Builder setIpAddress(@NonNull LinkAddress ipAddress) {
128 if (ipAddress != null && !(ipAddress.getAddress() instanceof Inet4Address)) {
129 throw new IllegalArgumentException(
130 "Only IPv4 addresses can be used for the IP configuration");
131 }
Remi NGUYEN VAN04c58fe2019-04-01 17:09:05 +0900132 mIpAddress = ipAddress;
133 return this;
134 }
135
136 /**
137 * Set the address of the gateway to be included in the configuration; null by default.
138 * @return The {@link Builder} for chaining.
139 */
140 public @NonNull Builder setGateway(@Nullable InetAddress gateway) {
Etan Cohen1e86b3a2021-12-12 02:14:06 +0000141 if (gateway != null && !(gateway instanceof Inet4Address)) {
142 throw new IllegalArgumentException(
143 "Only IPv4 addresses can be used for the gateway configuration");
144 }
Remi NGUYEN VAN04c58fe2019-04-01 17:09:05 +0900145 mGateway = gateway;
146 return this;
147 }
148
149 /**
150 * Set the addresses of the DNS servers included in the configuration; empty by default.
151 * @return The {@link Builder} for chaining.
152 */
153 public @NonNull Builder setDnsServers(@NonNull Iterable<InetAddress> dnsServers) {
Remi NGUYEN VAN81f68422021-03-15 07:31:54 +0000154 Objects.requireNonNull(dnsServers);
Etan Cohen1e86b3a2021-12-12 02:14:06 +0000155 for (InetAddress inetAddress: dnsServers) {
156 if (!(inetAddress instanceof Inet4Address)) {
157 throw new IllegalArgumentException(
158 "Only IPv4 addresses can be used for the DNS server configuration");
159 }
160 }
Remi NGUYEN VAN04c58fe2019-04-01 17:09:05 +0900161 mDnsServers = dnsServers;
162 return this;
163 }
164
165 /**
166 * Sets the DNS domain search path to be used on the link; null by default.
167 * @param newDomains A {@link String} containing the comma separated domains to search when
168 * resolving host names on this link, in priority order.
169 * @return The {@link Builder} for chaining.
170 */
171 public @NonNull Builder setDomains(@Nullable String newDomains) {
172 mDomains = newDomains;
173 return this;
174 }
175
176 /**
177 * Create a {@link StaticIpConfiguration} from the parameters in this {@link Builder}.
178 * @return The newly created StaticIpConfiguration.
Etan Cohen1e86b3a2021-12-12 02:14:06 +0000179 * @throws IllegalArgumentException if an invalid configuration is attempted, e.g.
180 * if an IP Address was not configured via {@link #setIpAddress(LinkAddress)}.
Remi NGUYEN VAN04c58fe2019-04-01 17:09:05 +0900181 */
182 public @NonNull StaticIpConfiguration build() {
183 final StaticIpConfiguration config = new StaticIpConfiguration();
184 config.ipAddress = mIpAddress;
185 config.gateway = mGateway;
Roshan Pius32b898b2019-11-14 12:20:41 -0800186 if (mDnsServers != null) {
187 for (InetAddress server : mDnsServers) {
188 config.dnsServers.add(server);
189 }
Remi NGUYEN VAN04c58fe2019-04-01 17:09:05 +0900190 }
191 config.domains = mDomains;
192 return config;
193 }
Remi NGUYEN VAN8bd18cf2019-01-28 13:28:35 +0900194 }
195
196 /**
197 * Add a DNS server to this configuration.
Etan Cohen1e86b3a2021-12-12 02:14:06 +0000198 * @hide
Remi NGUYEN VAN8bd18cf2019-01-28 13:28:35 +0900199 */
Etan Cohen1e86b3a2021-12-12 02:14:06 +0000200 @SystemApi
paulhu38068532019-03-15 17:17:02 +0800201 public void addDnsServer(@NonNull InetAddress server) {
Remi NGUYEN VAN8bd18cf2019-01-28 13:28:35 +0900202 dnsServers.add(server);
203 }
204
Lorenzo Colittief734f82014-07-31 00:48:01 +0900205 /**
206 * Returns the network routes specified by this object. Will typically include a
Remi NGUYEN VAN04c58fe2019-04-01 17:09:05 +0900207 * directly-connected route for the IP address's local subnet and a default route.
208 * @param iface Interface to include in the routes.
Etan Cohen1e86b3a2021-12-12 02:14:06 +0000209 * @hide
Lorenzo Colittief734f82014-07-31 00:48:01 +0900210 */
Etan Cohen1e86b3a2021-12-12 02:14:06 +0000211 @SystemApi
Remi NGUYEN VANbe381ab2019-03-25 16:41:08 +0900212 public @NonNull List<RouteInfo> getRoutes(@Nullable String iface) {
Lorenzo Colittic915d4c2015-01-20 15:53:02 +0900213 List<RouteInfo> routes = new ArrayList<RouteInfo>(3);
Lorenzo Colittief734f82014-07-31 00:48:01 +0900214 if (ipAddress != null) {
Lorenzo Colittic915d4c2015-01-20 15:53:02 +0900215 RouteInfo connectedRoute = new RouteInfo(ipAddress, null, iface);
216 routes.add(connectedRoute);
Remi NGUYEN VAN04c58fe2019-04-01 17:09:05 +0900217 // If the default gateway is not covered by the directly-connected route, also add a
218 // host route to the gateway as well. This configuration is arguably invalid, but it
219 // used to work in K and earlier, and other OSes appear to accept it.
Lorenzo Colittic915d4c2015-01-20 15:53:02 +0900220 if (gateway != null && !connectedRoute.matches(gateway)) {
221 routes.add(RouteInfo.makeHostRoute(gateway, iface));
222 }
Lorenzo Colittief734f82014-07-31 00:48:01 +0900223 }
224 if (gateway != null) {
Lorenzo Colittic915d4c2015-01-20 15:53:02 +0900225 routes.add(new RouteInfo((IpPrefix) null, gateway, iface));
Lorenzo Colittief734f82014-07-31 00:48:01 +0900226 }
227 return routes;
228 }
229
230 /**
231 * Returns a LinkProperties object expressing the data in this object. Note that the information
232 * contained in the LinkProperties will not be a complete picture of the link's configuration,
233 * because any configuration information that is obtained dynamically by the network (e.g.,
234 * IPv6 configuration) will not be included.
Remi NGUYEN VAN8bd18cf2019-01-28 13:28:35 +0900235 * @hide
Lorenzo Colittief734f82014-07-31 00:48:01 +0900236 */
paulhu38068532019-03-15 17:17:02 +0800237 public @NonNull LinkProperties toLinkProperties(String iface) {
Lorenzo Colittief734f82014-07-31 00:48:01 +0900238 LinkProperties lp = new LinkProperties();
239 lp.setInterfaceName(iface);
240 if (ipAddress != null) {
241 lp.addLinkAddress(ipAddress);
242 }
243 for (RouteInfo route : getRoutes(iface)) {
244 lp.addRoute(route);
245 }
246 for (InetAddress dns : dnsServers) {
247 lp.addDnsServer(dns);
248 }
Paul Jensen99366a82014-11-05 09:35:26 -0500249 lp.setDomains(domains);
Lorenzo Colittief734f82014-07-31 00:48:01 +0900250 return lp;
251 }
252
Aurimas Liutikas8fae99352019-08-28 13:01:05 -0700253 @NonNull
Remi NGUYEN VAN8bd18cf2019-01-28 13:28:35 +0900254 @Override
Lorenzo Colittief734f82014-07-31 00:48:01 +0900255 public String toString() {
256 StringBuffer str = new StringBuffer();
257
258 str.append("IP address ");
259 if (ipAddress != null ) str.append(ipAddress).append(" ");
260
261 str.append("Gateway ");
262 if (gateway != null) str.append(gateway.getHostAddress()).append(" ");
263
264 str.append(" DNS servers: [");
265 for (InetAddress dnsServer : dnsServers) {
266 str.append(" ").append(dnsServer.getHostAddress());
267 }
268
Erik Kline7b0a5812016-05-13 17:50:25 +0900269 str.append(" ] Domains ");
Lorenzo Colittief734f82014-07-31 00:48:01 +0900270 if (domains != null) str.append(domains);
271 return str.toString();
272 }
273
Remi NGUYEN VAN8bd18cf2019-01-28 13:28:35 +0900274 @Override
Lorenzo Colittief734f82014-07-31 00:48:01 +0900275 public int hashCode() {
276 int result = 13;
277 result = 47 * result + (ipAddress == null ? 0 : ipAddress.hashCode());
278 result = 47 * result + (gateway == null ? 0 : gateway.hashCode());
279 result = 47 * result + (domains == null ? 0 : domains.hashCode());
280 result = 47 * result + dnsServers.hashCode();
281 return result;
282 }
283
284 @Override
Aurimas Liutikas8fae99352019-08-28 13:01:05 -0700285 public boolean equals(@Nullable Object obj) {
Lorenzo Colittief734f82014-07-31 00:48:01 +0900286 if (this == obj) return true;
287
288 if (!(obj instanceof StaticIpConfiguration)) return false;
289
290 StaticIpConfiguration other = (StaticIpConfiguration) obj;
291
292 return other != null &&
293 Objects.equals(ipAddress, other.ipAddress) &&
294 Objects.equals(gateway, other.gateway) &&
295 dnsServers.equals(other.dnsServers) &&
296 Objects.equals(domains, other.domains);
297 }
298
299 /** Implement the Parcelable interface */
Jeff Sharkeyf8525282019-02-28 12:06:45 -0700300 public static final @android.annotation.NonNull Creator<StaticIpConfiguration> CREATOR =
Lorenzo Colittief734f82014-07-31 00:48:01 +0900301 new Creator<StaticIpConfiguration>() {
302 public StaticIpConfiguration createFromParcel(Parcel in) {
Remi NGUYEN VAN8bd18cf2019-01-28 13:28:35 +0900303 return readFromParcel(in);
Lorenzo Colittief734f82014-07-31 00:48:01 +0900304 }
305
306 public StaticIpConfiguration[] newArray(int size) {
307 return new StaticIpConfiguration[size];
308 }
309 };
310
311 /** Implement the Parcelable interface */
Remi NGUYEN VAN8bd18cf2019-01-28 13:28:35 +0900312 @Override
Lorenzo Colittief734f82014-07-31 00:48:01 +0900313 public int describeContents() {
314 return 0;
315 }
316
317 /** Implement the Parcelable interface */
Remi NGUYEN VAN8bd18cf2019-01-28 13:28:35 +0900318 @Override
Etan Cohen1e86b3a2021-12-12 02:14:06 +0000319 public void writeToParcel(@NonNull Parcel dest, int flags) {
Lorenzo Colittief734f82014-07-31 00:48:01 +0900320 dest.writeParcelable(ipAddress, flags);
Remi NGUYEN VAN6e82be42019-01-29 15:38:52 +0900321 InetAddressUtils.parcelInetAddress(dest, gateway, flags);
Lorenzo Colittief734f82014-07-31 00:48:01 +0900322 dest.writeInt(dnsServers.size());
323 for (InetAddress dnsServer : dnsServers) {
Remi NGUYEN VAN6e82be42019-01-29 15:38:52 +0900324 InetAddressUtils.parcelInetAddress(dest, dnsServer, flags);
Lorenzo Colittief734f82014-07-31 00:48:01 +0900325 }
Lorenzo Colitti68a1a342015-01-29 17:10:52 +0900326 dest.writeString(domains);
Lorenzo Colittief734f82014-07-31 00:48:01 +0900327 }
328
Remi NGUYEN VAN8bd18cf2019-01-28 13:28:35 +0900329 /** @hide */
Etan Cohen1e86b3a2021-12-12 02:14:06 +0000330 public static @NonNull StaticIpConfiguration readFromParcel(Parcel in) {
Remi NGUYEN VAN8bd18cf2019-01-28 13:28:35 +0900331 final StaticIpConfiguration s = new StaticIpConfiguration();
Lorenzo Colittief734f82014-07-31 00:48:01 +0900332 s.ipAddress = in.readParcelable(null);
Remi NGUYEN VAN6e82be42019-01-29 15:38:52 +0900333 s.gateway = InetAddressUtils.unparcelInetAddress(in);
Lorenzo Colittief734f82014-07-31 00:48:01 +0900334 s.dnsServers.clear();
335 int size = in.readInt();
336 for (int i = 0; i < size; i++) {
Remi NGUYEN VAN6e82be42019-01-29 15:38:52 +0900337 s.dnsServers.add(InetAddressUtils.unparcelInetAddress(in));
Lorenzo Colittief734f82014-07-31 00:48:01 +0900338 }
Lorenzo Colitti68a1a342015-01-29 17:10:52 +0900339 s.domains = in.readString();
Remi NGUYEN VAN8bd18cf2019-01-28 13:28:35 +0900340 return s;
Lorenzo Colittief734f82014-07-31 00:48:01 +0900341 }
342}