blob: fec2df412adb17b0da5ea20df84bfa121d5968ac [file] [log] [blame]
Robert Greenwaltaa70f102011-04-28 14:28:50 -07001/*
2 * Copyright (C) 2011 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
paulhu819e0af2019-03-27 22:26:37 +080019import android.annotation.IntDef;
20import android.annotation.NonNull;
paulhud9736de2019-03-08 16:35:20 +080021import android.annotation.Nullable;
Remi NGUYEN VAN31f1d0c2019-01-20 12:52:43 +090022import android.annotation.SystemApi;
23import android.annotation.TestApi;
Artur Satayev26958002019-12-10 17:47:52 +000024import android.compat.annotation.UnsupportedAppUsage;
Aaron Huang94df39a2019-12-17 00:33:18 +080025import android.net.util.NetUtils;
Mathew Inwood55418ea2018-12-20 15:30:45 +000026import android.os.Build;
Robert Greenwaltaa70f102011-04-28 14:28:50 -070027import android.os.Parcel;
28import android.os.Parcelable;
29
paulhu819e0af2019-03-27 22:26:37 +080030import java.lang.annotation.Retention;
31import java.lang.annotation.RetentionPolicy;
Robert Greenwaltaa70f102011-04-28 14:28:50 -070032import java.net.Inet4Address;
33import java.net.Inet6Address;
Remi NGUYEN VAN31f1d0c2019-01-20 12:52:43 +090034import java.net.InetAddress;
35import java.net.UnknownHostException;
Robert Greenwaltf43396c2011-05-06 17:10:53 -070036import java.util.Collection;
Robert Greenwalt386aba82014-05-18 23:33:07 -070037import java.util.Objects;
Robert Greenwaltf43396c2011-05-06 17:10:53 -070038
Robert Greenwaltaa70f102011-04-28 14:28:50 -070039/**
Robert Greenwalt386aba82014-05-18 23:33:07 -070040 * Represents a network route.
Robert Greenwalt4095bd52014-05-18 12:05:05 -070041 * <p>
42 * This is used both to describe static network configuration and live network
Robert Greenwalt386aba82014-05-18 23:33:07 -070043 * configuration information.
Robert Greenwaltaa70f102011-04-28 14:28:50 -070044 *
Robert Greenwalt386aba82014-05-18 23:33:07 -070045 * A route contains three pieces of information:
Robert Greenwalt4095bd52014-05-18 12:05:05 -070046 * <ul>
Sreeram Ramachandrancc91c7b2014-06-03 18:41:43 -070047 * <li>a destination {@link IpPrefix} specifying the network destinations covered by this route.
48 * If this is {@code null} it indicates a default route of the address family (IPv4 or IPv6)
Robert Greenwalt386aba82014-05-18 23:33:07 -070049 * implied by the gateway IP address.
Sreeram Ramachandrancc91c7b2014-06-03 18:41:43 -070050 * <li>a gateway {@link InetAddress} indicating the next hop to use. If this is {@code null} it
Robert Greenwalt386aba82014-05-18 23:33:07 -070051 * indicates a directly-connected route.
52 * <li>an interface (which may be unspecified).
Robert Greenwalt4095bd52014-05-18 12:05:05 -070053 * </ul>
Robert Greenwalt386aba82014-05-18 23:33:07 -070054 * Either the destination or the gateway may be {@code null}, but not both. If the
55 * destination and gateway are both specified, they must be of the same address family
56 * (IPv4 or IPv6).
Robert Greenwaltaa70f102011-04-28 14:28:50 -070057 */
Robert Greenwalte595b972014-06-12 16:24:38 -070058public final class RouteInfo implements Parcelable {
paulhu819e0af2019-03-27 22:26:37 +080059 /** @hide */
60 @IntDef(value = {
61 RTN_UNICAST,
62 RTN_UNREACHABLE,
63 RTN_THROW,
64 })
65 @Retention(RetentionPolicy.SOURCE)
66 public @interface RouteType {}
67
Robert Greenwaltaa70f102011-04-28 14:28:50 -070068 /**
69 * The IP destination address for this route.
70 */
paulhu819e0af2019-03-27 22:26:37 +080071 @NonNull
Lorenzo Colitti1806b1f2014-08-12 12:37:50 +090072 private final IpPrefix mDestination;
Robert Greenwaltaa70f102011-04-28 14:28:50 -070073
74 /**
75 * The gateway address for this route.
76 */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +010077 @UnsupportedAppUsage
paulhu819e0af2019-03-27 22:26:37 +080078 @Nullable
Robert Greenwaltaa70f102011-04-28 14:28:50 -070079 private final InetAddress mGateway;
80
Lorenzo Colitti45b9a5b2013-03-08 11:30:39 -080081 /**
82 * The interface for this route.
83 */
paulhu819e0af2019-03-27 22:26:37 +080084 @Nullable
Lorenzo Colitti45b9a5b2013-03-08 11:30:39 -080085 private final String mInterface;
86
Lorenzo Colitti4b0f8e62014-09-19 01:49:05 +090087
88 /** Unicast route. @hide */
Remi NGUYEN VAN31f1d0c2019-01-20 12:52:43 +090089 @SystemApi
90 @TestApi
Lorenzo Colitti4b0f8e62014-09-19 01:49:05 +090091 public static final int RTN_UNICAST = 1;
92
93 /** Unreachable route. @hide */
Remi NGUYEN VAN31f1d0c2019-01-20 12:52:43 +090094 @SystemApi
95 @TestApi
Lorenzo Colitti4b0f8e62014-09-19 01:49:05 +090096 public static final int RTN_UNREACHABLE = 7;
97
98 /** Throw route. @hide */
Remi NGUYEN VAN31f1d0c2019-01-20 12:52:43 +090099 @SystemApi
100 @TestApi
Lorenzo Colitti4b0f8e62014-09-19 01:49:05 +0900101 public static final int RTN_THROW = 9;
102
103 /**
104 * The type of this route; one of the RTN_xxx constants above.
105 */
106 private final int mType;
107
Sarah Chin77a7ea62020-01-16 11:19:52 -0800108 /**
109 * The maximum transmission unit size for this route.
110 */
111 private final int mMtu;
112
Lorenzo Colitti4b0f8e62014-09-19 01:49:05 +0900113 // Derived data members.
114 // TODO: remove these.
Mathew Inwood55418ea2018-12-20 15:30:45 +0000115 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Robert Greenwalt0a46db52011-07-14 14:28:05 -0700116 private final boolean mIsHost;
Robert Greenwaltca441ee2013-04-11 13:48:16 -0700117 private final boolean mHasGateway;
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700118
Lorenzo Colitti45b9a5b2013-03-08 11:30:39 -0800119 /**
120 * Constructs a RouteInfo object.
121 *
Lorenzo Colitti574b00a2013-03-12 04:30:47 +0900122 * If destination is null, then gateway must be specified and the
Lorenzo Colitti45b9a5b2013-03-08 11:30:39 -0800123 * constructed route is either the IPv4 default route <code>0.0.0.0</code>
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700124 * if the gateway is an instance of {@link Inet4Address}, or the IPv6 default
Lorenzo Colitti574b00a2013-03-12 04:30:47 +0900125 * route <code>::/0</code> if gateway is an instance of
Lorenzo Colitti45b9a5b2013-03-08 11:30:39 -0800126 * {@link Inet6Address}.
Robert Greenwalt386aba82014-05-18 23:33:07 -0700127 * <p>
Lorenzo Colitti574b00a2013-03-12 04:30:47 +0900128 * destination and gateway may not both be null.
Lorenzo Colitti45b9a5b2013-03-08 11:30:39 -0800129 *
130 * @param destination the destination prefix
131 * @param gateway the IP address to route packets through
132 * @param iface the interface name to send packets on
paulhu819e0af2019-03-27 22:26:37 +0800133 * @param type the type of this route
Sreeram Ramachandrancc91c7b2014-06-03 18:41:43 -0700134 *
Sreeram Ramachandrancc91c7b2014-06-03 18:41:43 -0700135 * @hide
136 */
Remi NGUYEN VAN39fbb922019-01-24 00:55:43 +0900137 @SystemApi
138 @TestApi
paulhud9736de2019-03-08 16:35:20 +0800139 public RouteInfo(@Nullable IpPrefix destination, @Nullable InetAddress gateway,
paulhu819e0af2019-03-27 22:26:37 +0800140 @Nullable String iface, @RouteType int type) {
Sarah Chin77a7ea62020-01-16 11:19:52 -0800141 this(destination, gateway, iface, type, 0);
142 }
143
144 /**
145 * Constructs a RouteInfo object.
146 *
147 * If destination is null, then gateway must be specified and the
148 * constructed route is either the IPv4 default route <code>0.0.0.0</code>
149 * if the gateway is an instance of {@link Inet4Address}, or the IPv6 default
150 * route <code>::/0</code> if gateway is an instance of
151 * {@link Inet6Address}.
152 * <p>
153 * destination and gateway may not both be null.
154 *
155 * @param destination the destination prefix
156 * @param gateway the IP address to route packets through
157 * @param iface the interface name to send packets on
158 * @param type the type of this route
159 * @param mtu the maximum transmission unit size for this route
160 *
161 * @hide
162 */
163 @SystemApi
164 public RouteInfo(@Nullable IpPrefix destination, @Nullable InetAddress gateway,
165 @Nullable String iface, @RouteType int type, int mtu) {
Lorenzo Colitti4b0f8e62014-09-19 01:49:05 +0900166 switch (type) {
167 case RTN_UNICAST:
168 case RTN_UNREACHABLE:
169 case RTN_THROW:
170 // TODO: It would be nice to ensure that route types that don't have nexthops or
171 // interfaces, such as unreachable or throw, can't be created if an interface or
172 // a gateway is specified. This is a bit too complicated to do at the moment
173 // because:
174 //
175 // - LinkProperties sets the interface on routes added to it, and modifies the
176 // interfaces of all the routes when its interface name changes.
177 // - Even when the gateway is null, we store a non-null gateway here.
178 //
179 // For now, we just rely on the code that sets routes to do things properly.
180 break;
181 default:
182 throw new IllegalArgumentException("Unknown route type " + type);
183 }
184
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700185 if (destination == null) {
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700186 if (gateway != null) {
187 if (gateway instanceof Inet4Address) {
Lorenzo Colitti1806b1f2014-08-12 12:37:50 +0900188 destination = new IpPrefix(Inet4Address.ANY, 0);
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700189 } else {
Lorenzo Colitti1806b1f2014-08-12 12:37:50 +0900190 destination = new IpPrefix(Inet6Address.ANY, 0);
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700191 }
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700192 } else {
193 // no destination, no gateway. invalid.
Lorenzo Colitti45b9a5b2013-03-08 11:30:39 -0800194 throw new IllegalArgumentException("Invalid arguments passed in: " + gateway + "," +
Sarah Chin77a7ea62020-01-16 11:19:52 -0800195 destination);
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700196 }
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700197 }
Lorenzo Colitti1806b1f2014-08-12 12:37:50 +0900198 // TODO: set mGateway to null if there is no gateway. This is more correct, saves space, and
199 // matches the documented behaviour. Before we can do this we need to fix all callers (e.g.,
200 // ConnectivityService) to stop doing things like r.getGateway().equals(), ... .
Kazuhiro Ondo8c0b5282011-05-11 14:55:19 -0500201 if (gateway == null) {
202 if (destination.getAddress() instanceof Inet4Address) {
203 gateway = Inet4Address.ANY;
204 } else {
205 gateway = Inet6Address.ANY;
206 }
207 }
Robert Greenwaltca441ee2013-04-11 13:48:16 -0700208 mHasGateway = (!gateway.isAnyLocalAddress());
209
Sarah Chin77a7ea62020-01-16 11:19:52 -0800210 if ((destination.getAddress() instanceof Inet4Address
211 && !(gateway instanceof Inet4Address))
212 || (destination.getAddress() instanceof Inet6Address
213 && !(gateway instanceof Inet6Address))) {
Robert Greenwalt386aba82014-05-18 23:33:07 -0700214 throw new IllegalArgumentException("address family mismatch in RouteInfo constructor");
215 }
Lorenzo Colitti1806b1f2014-08-12 12:37:50 +0900216 mDestination = destination; // IpPrefix objects are immutable.
217 mGateway = gateway; // InetAddress objects are immutable.
218 mInterface = iface; // Strings are immutable.
Lorenzo Colitti4b0f8e62014-09-19 01:49:05 +0900219 mType = type;
Robert Greenwalt0a46db52011-07-14 14:28:05 -0700220 mIsHost = isHost();
Sarah Chin77a7ea62020-01-16 11:19:52 -0800221 mMtu = mtu;
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700222 }
223
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700224 /**
paulhu819e0af2019-03-27 22:26:37 +0800225 * Constructs a {@code RouteInfo} object.
226 *
227 * If destination is null, then gateway must be specified and the
228 * constructed route is either the IPv4 default route <code>0.0.0.0</code>
229 * if the gateway is an instance of {@link Inet4Address}, or the IPv6 default
230 * route <code>::/0</code> if gateway is an instance of {@link Inet6Address}.
231 * <p>
232 * Destination and gateway may not both be null.
233 *
234 * @param destination the destination address and prefix in an {@link IpPrefix}
235 * @param gateway the {@link InetAddress} to route packets through
236 * @param iface the interface name to send packets on
237 *
238 * @hide
Lorenzo Colitti4b0f8e62014-09-19 01:49:05 +0900239 */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +0100240 @UnsupportedAppUsage
paulhu819e0af2019-03-27 22:26:37 +0800241 public RouteInfo(@Nullable IpPrefix destination, @Nullable InetAddress gateway,
242 @Nullable String iface) {
Lorenzo Colitti4b0f8e62014-09-19 01:49:05 +0900243 this(destination, gateway, iface, RTN_UNICAST);
244 }
245
246 /**
Lorenzo Colitti1806b1f2014-08-12 12:37:50 +0900247 * @hide
248 */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +0100249 @UnsupportedAppUsage
paulhu819e0af2019-03-27 22:26:37 +0800250 public RouteInfo(@Nullable LinkAddress destination, @Nullable InetAddress gateway,
251 @Nullable String iface) {
Lorenzo Colitti1806b1f2014-08-12 12:37:50 +0900252 this(destination == null ? null :
253 new IpPrefix(destination.getAddress(), destination.getPrefixLength()),
254 gateway, iface);
255 }
256
257 /**
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700258 * Constructs a {@code RouteInfo} object.
259 *
260 * If destination is null, then gateway must be specified and the
261 * constructed route is either the IPv4 default route <code>0.0.0.0</code>
262 * if the gateway is an instance of {@link Inet4Address}, or the IPv6 default
263 * route <code>::/0</code> if gateway is an instance of {@link Inet6Address}.
264 * <p>
265 * Destination and gateway may not both be null.
266 *
Sreeram Ramachandrancc91c7b2014-06-03 18:41:43 -0700267 * @param destination the destination address and prefix in an {@link IpPrefix}
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700268 * @param gateway the {@link InetAddress} to route packets through
Sreeram Ramachandrancc91c7b2014-06-03 18:41:43 -0700269 *
270 * @hide
271 */
paulhu819e0af2019-03-27 22:26:37 +0800272 public RouteInfo(@Nullable IpPrefix destination, @Nullable InetAddress gateway) {
Sreeram Ramachandrancc91c7b2014-06-03 18:41:43 -0700273 this(destination, gateway, null);
274 }
275
276 /**
277 * @hide
Lorenzo Colitti4b0f8e62014-09-19 01:49:05 +0900278 *
279 * TODO: Remove this.
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700280 */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +0100281 @UnsupportedAppUsage
paulhu819e0af2019-03-27 22:26:37 +0800282 public RouteInfo(@Nullable LinkAddress destination, @Nullable InetAddress gateway) {
Lorenzo Colitti45b9a5b2013-03-08 11:30:39 -0800283 this(destination, gateway, null);
284 }
285
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700286 /**
287 * Constructs a default {@code RouteInfo} object.
288 *
289 * @param gateway the {@link InetAddress} to route packets through
Sreeram Ramachandrancc91c7b2014-06-03 18:41:43 -0700290 *
291 * @hide
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700292 */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +0100293 @UnsupportedAppUsage
paulhu819e0af2019-03-27 22:26:37 +0800294 public RouteInfo(@NonNull InetAddress gateway) {
Lorenzo Colitti1806b1f2014-08-12 12:37:50 +0900295 this((IpPrefix) null, gateway, null);
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700296 }
297
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700298 /**
299 * Constructs a {@code RouteInfo} object representing a direct connected subnet.
300 *
Sreeram Ramachandrancc91c7b2014-06-03 18:41:43 -0700301 * @param destination the {@link IpPrefix} describing the address and prefix
Robert Greenwalt386aba82014-05-18 23:33:07 -0700302 * length of the subnet.
Sreeram Ramachandrancc91c7b2014-06-03 18:41:43 -0700303 *
304 * @hide
305 */
paulhu819e0af2019-03-27 22:26:37 +0800306 public RouteInfo(@NonNull IpPrefix destination) {
Sreeram Ramachandrancc91c7b2014-06-03 18:41:43 -0700307 this(destination, null, null);
308 }
309
310 /**
311 * @hide
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700312 */
paulhu819e0af2019-03-27 22:26:37 +0800313 public RouteInfo(@NonNull LinkAddress destination) {
Robert Greenwalt386aba82014-05-18 23:33:07 -0700314 this(destination, null, null);
Robert Greenwalt4717c262012-10-31 14:32:53 -0700315 }
316
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700317 /**
318 * @hide
319 */
paulhu819e0af2019-03-27 22:26:37 +0800320 public RouteInfo(@NonNull IpPrefix destination, @RouteType int type) {
Lorenzo Colitti4b0f8e62014-09-19 01:49:05 +0900321 this(destination, null, null, type);
322 }
323
324 /**
325 * @hide
326 */
paulhu819e0af2019-03-27 22:26:37 +0800327 public static RouteInfo makeHostRoute(@NonNull InetAddress host, @Nullable String iface) {
Lorenzo Colittie1671352013-03-08 12:30:44 -0800328 return makeHostRoute(host, null, iface);
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700329 }
330
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700331 /**
332 * @hide
333 */
paulhu819e0af2019-03-27 22:26:37 +0800334 public static RouteInfo makeHostRoute(@Nullable InetAddress host, @Nullable InetAddress gateway,
335 @Nullable String iface) {
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700336 if (host == null) return null;
337
338 if (host instanceof Inet4Address) {
Lorenzo Colitti1806b1f2014-08-12 12:37:50 +0900339 return new RouteInfo(new IpPrefix(host, 32), gateway, iface);
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700340 } else {
Lorenzo Colitti1806b1f2014-08-12 12:37:50 +0900341 return new RouteInfo(new IpPrefix(host, 128), gateway, iface);
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700342 }
343 }
344
Mathew Inwood55418ea2018-12-20 15:30:45 +0000345 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Robert Greenwalt0a46db52011-07-14 14:28:05 -0700346 private boolean isHost() {
Lorenzo Colittifdadc4e2013-03-27 13:07:18 +0900347 return (mDestination.getAddress() instanceof Inet4Address &&
Lorenzo Colitti7dc78cf2014-06-09 22:58:46 +0900348 mDestination.getPrefixLength() == 32) ||
Lorenzo Colittifdadc4e2013-03-27 13:07:18 +0900349 (mDestination.getAddress() instanceof Inet6Address &&
Lorenzo Colitti7dc78cf2014-06-09 22:58:46 +0900350 mDestination.getPrefixLength() == 128);
Robert Greenwalt0a46db52011-07-14 14:28:05 -0700351 }
352
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700353 /**
Sreeram Ramachandrancc91c7b2014-06-03 18:41:43 -0700354 * Retrieves the destination address and prefix length in the form of an {@link IpPrefix}.
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700355 *
Sreeram Ramachandrancc91c7b2014-06-03 18:41:43 -0700356 * @return {@link IpPrefix} specifying the destination. This is never {@code null}.
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700357 */
paulhu819e0af2019-03-27 22:26:37 +0800358 @NonNull
Sreeram Ramachandrancc91c7b2014-06-03 18:41:43 -0700359 public IpPrefix getDestination() {
Lorenzo Colitti1806b1f2014-08-12 12:37:50 +0900360 return mDestination;
Sreeram Ramachandrancc91c7b2014-06-03 18:41:43 -0700361 }
362
363 /**
364 * TODO: Convert callers to use IpPrefix and then remove.
365 * @hide
366 */
paulhu819e0af2019-03-27 22:26:37 +0800367 @NonNull
Sreeram Ramachandrancc91c7b2014-06-03 18:41:43 -0700368 public LinkAddress getDestinationLinkAddress() {
Lorenzo Colitti1806b1f2014-08-12 12:37:50 +0900369 return new LinkAddress(mDestination.getAddress(), mDestination.getPrefixLength());
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700370 }
371
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700372 /**
373 * Retrieves the gateway or next hop {@link InetAddress} for this route.
374 *
Robert Greenwalt386aba82014-05-18 23:33:07 -0700375 * @return {@link InetAddress} specifying the gateway or next hop. This may be
Robert Greenwalte595b972014-06-12 16:24:38 -0700376 * {@code null} for a directly-connected route."
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700377 */
paulhu819e0af2019-03-27 22:26:37 +0800378 @Nullable
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700379 public InetAddress getGateway() {
380 return mGateway;
381 }
382
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700383 /**
Robert Greenwalt386aba82014-05-18 23:33:07 -0700384 * Retrieves the interface used for this route if specified, else {@code null}.
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700385 *
386 * @return The name of the interface used for this route.
387 */
paulhu819e0af2019-03-27 22:26:37 +0800388 @Nullable
Lorenzo Colitti45b9a5b2013-03-08 11:30:39 -0800389 public String getInterface() {
390 return mInterface;
391 }
392
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700393 /**
Lorenzo Colitti4b0f8e62014-09-19 01:49:05 +0900394 * Retrieves the type of this route.
395 *
396 * @return The type of this route; one of the {@code RTN_xxx} constants defined in this class.
397 *
398 * @hide
399 */
Remi NGUYEN VAN31f1d0c2019-01-20 12:52:43 +0900400 @TestApi
401 @SystemApi
paulhu819e0af2019-03-27 22:26:37 +0800402 @RouteType
Lorenzo Colitti4b0f8e62014-09-19 01:49:05 +0900403 public int getType() {
404 return mType;
405 }
406
407 /**
Sarah Chin77a7ea62020-01-16 11:19:52 -0800408 * Retrieves the MTU size for this route.
409 *
410 * @return The MTU size, or 0 if it has not been set.
411 * @hide
412 */
413 @SystemApi
414 public int getMtu() {
415 return mMtu;
416 }
417
418 /**
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700419 * Indicates if this route is a default route (ie, has no destination specified).
420 *
Robert Greenwalt386aba82014-05-18 23:33:07 -0700421 * @return {@code true} if the destination has a prefix length of 0.
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700422 */
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700423 public boolean isDefaultRoute() {
Lorenzo Colitti4b0f8e62014-09-19 01:49:05 +0900424 return mType == RTN_UNICAST && mDestination.getPrefixLength() == 0;
Lorenzo Colitti64c43b12014-06-23 21:27:53 +0900425 }
426
427 /**
428 * Indicates if this route is an IPv4 default route.
429 * @hide
430 */
431 public boolean isIPv4Default() {
432 return isDefaultRoute() && mDestination.getAddress() instanceof Inet4Address;
433 }
434
435 /**
436 * Indicates if this route is an IPv6 default route.
437 * @hide
438 */
439 public boolean isIPv6Default() {
440 return isDefaultRoute() && mDestination.getAddress() instanceof Inet6Address;
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700441 }
442
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700443 /**
444 * Indicates if this route is a host route (ie, matches only a single host address).
445 *
Sreeram Ramachandrancc91c7b2014-06-03 18:41:43 -0700446 * @return {@code true} if the destination has a prefix length of 32 or 128 for IPv4 or IPv6,
447 * respectively.
Robert Greenwalt386aba82014-05-18 23:33:07 -0700448 * @hide
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700449 */
Robert Greenwalt0a46db52011-07-14 14:28:05 -0700450 public boolean isHostRoute() {
451 return mIsHost;
452 }
453
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700454 /**
455 * Indicates if this route has a next hop ({@code true}) or is directly-connected
456 * ({@code false}).
457 *
458 * @return {@code true} if a gateway is specified
459 */
Robert Greenwaltca441ee2013-04-11 13:48:16 -0700460 public boolean hasGateway() {
461 return mHasGateway;
462 }
463
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700464 /**
Robert Greenwalt386aba82014-05-18 23:33:07 -0700465 * Determines whether the destination and prefix of this route includes the specified
466 * address.
467 *
468 * @param destination A {@link InetAddress} to test to see if it would match this route.
469 * @return {@code true} if the destination and prefix length cover the given address.
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700470 */
Robert Greenwalt386aba82014-05-18 23:33:07 -0700471 public boolean matches(InetAddress destination) {
Erik Klineacc8c092015-04-13 15:33:34 +0900472 return mDestination.contains(destination);
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700473 }
474
475 /**
476 * Find the route from a Collection of routes that best matches a given address.
477 * May return null if no routes are applicable.
478 * @param routes a Collection of RouteInfos to chose from
479 * @param dest the InetAddress your trying to get to
480 * @return the RouteInfo from the Collection that best fits the given address
481 *
482 * @hide
483 */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +0100484 @UnsupportedAppUsage
paulhu819e0af2019-03-27 22:26:37 +0800485 @Nullable
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700486 public static RouteInfo selectBestRoute(Collection<RouteInfo> routes, InetAddress dest) {
Aaron Huang94df39a2019-12-17 00:33:18 +0800487 return NetUtils.selectBestRoute(routes, dest);
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700488 }
489
Sreeram Ramachandrancc91c7b2014-06-03 18:41:43 -0700490 /**
491 * Returns a human-readable description of this object.
492 */
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700493 public String toString() {
494 String val = "";
495 if (mDestination != null) val = mDestination.toString();
Lorenzo Colitti4b0f8e62014-09-19 01:49:05 +0900496 if (mType == RTN_UNREACHABLE) {
497 val += " unreachable";
498 } else if (mType == RTN_THROW) {
499 val += " throw";
500 } else {
501 val += " ->";
502 if (mGateway != null) val += " " + mGateway.getHostAddress();
503 if (mInterface != null) val += " " + mInterface;
504 if (mType != RTN_UNICAST) {
505 val += " unknown type " + mType;
506 }
507 }
Sarah Chin77a7ea62020-01-16 11:19:52 -0800508 val += " mtu " + mMtu;
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700509 return val;
510 }
511
Sreeram Ramachandrancc91c7b2014-06-03 18:41:43 -0700512 /**
513 * Compares this RouteInfo object against the specified object and indicates if they are equal.
514 * @return {@code true} if the objects are equal, {@code false} otherwise.
515 */
Wink Savillebe2b0582011-05-18 15:59:04 -0700516 public boolean equals(Object obj) {
517 if (this == obj) return true;
518
519 if (!(obj instanceof RouteInfo)) return false;
520
521 RouteInfo target = (RouteInfo) obj;
522
Lorenzo Colitti1806b1f2014-08-12 12:37:50 +0900523 return Objects.equals(mDestination, target.getDestination()) &&
Robert Greenwalt386aba82014-05-18 23:33:07 -0700524 Objects.equals(mGateway, target.getGateway()) &&
Lorenzo Colitti4b0f8e62014-09-19 01:49:05 +0900525 Objects.equals(mInterface, target.getInterface()) &&
Sarah Chin77a7ea62020-01-16 11:19:52 -0800526 mType == target.getType() && mMtu == target.getMtu();
Wink Savillebe2b0582011-05-18 15:59:04 -0700527 }
528
Sreeram Ramachandrancc91c7b2014-06-03 18:41:43 -0700529 /**
Lorenzo Colittid86407b2020-03-18 07:52:25 +0000530 * Compares this RouteInfo object against the specified object and indicates if the
531 * destinations of both routes are equal.
532 * @return {@code true} if the route destinations are equal, {@code false} otherwise.
533 *
534 * @hide
535 */
536 public boolean isSameDestinationAs(@Nullable Object obj) {
537 if (this == obj) return true;
538
539 if (!(obj instanceof RouteInfo)) return false;
540
541 RouteInfo target = (RouteInfo) obj;
542
543 if (Objects.equals(mDestination, target.getDestination())) {
544 return true;
545 }
546 return false;
547 }
548
549 /**
Sreeram Ramachandrancc91c7b2014-06-03 18:41:43 -0700550 * Returns a hashcode for this <code>RouteInfo</code> object.
551 */
Wink Savillebe2b0582011-05-18 15:59:04 -0700552 public int hashCode() {
Lorenzo Colitti64c43b12014-06-23 21:27:53 +0900553 return (mDestination.hashCode() * 41)
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700554 + (mGateway == null ? 0 :mGateway.hashCode() * 47)
Lorenzo Colitti4b0f8e62014-09-19 01:49:05 +0900555 + (mInterface == null ? 0 :mInterface.hashCode() * 67)
Sarah Chin77a7ea62020-01-16 11:19:52 -0800556 + (mType * 71) + (mMtu * 89);
Wink Savillebe2b0582011-05-18 15:59:04 -0700557 }
558
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700559 /**
560 * Implement the Parcelable interface
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700561 */
562 public int describeContents() {
563 return 0;
564 }
565
566 /**
567 * Implement the Parcelable interface
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700568 */
569 public void writeToParcel(Parcel dest, int flags) {
Lorenzo Colitti1806b1f2014-08-12 12:37:50 +0900570 dest.writeParcelable(mDestination, flags);
571 byte[] gatewayBytes = (mGateway == null) ? null : mGateway.getAddress();
572 dest.writeByteArray(gatewayBytes);
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700573 dest.writeString(mInterface);
Lorenzo Colitti4b0f8e62014-09-19 01:49:05 +0900574 dest.writeInt(mType);
Sarah Chin77a7ea62020-01-16 11:19:52 -0800575 dest.writeInt(mMtu);
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700576 }
577
578 /**
579 * Implement the Parcelable interface.
Robert Greenwalt4095bd52014-05-18 12:05:05 -0700580 */
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700581 public static final @android.annotation.NonNull Creator<RouteInfo> CREATOR =
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700582 new Creator<RouteInfo>() {
583 public RouteInfo createFromParcel(Parcel in) {
Lorenzo Colitti1806b1f2014-08-12 12:37:50 +0900584 IpPrefix dest = in.readParcelable(null);
585
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700586 InetAddress gateway = null;
Lorenzo Colitti64c43b12014-06-23 21:27:53 +0900587 byte[] addr = in.createByteArray();
Lorenzo Colitti64c43b12014-06-23 21:27:53 +0900588 try {
Lorenzo Colitti1806b1f2014-08-12 12:37:50 +0900589 gateway = InetAddress.getByAddress(addr);
Lorenzo Colitti64c43b12014-06-23 21:27:53 +0900590 } catch (UnknownHostException e) {}
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700591
Lorenzo Colitti45b9a5b2013-03-08 11:30:39 -0800592 String iface = in.readString();
Lorenzo Colitti4b0f8e62014-09-19 01:49:05 +0900593 int type = in.readInt();
Sarah Chin77a7ea62020-01-16 11:19:52 -0800594 int mtu = in.readInt();
Lorenzo Colitti45b9a5b2013-03-08 11:30:39 -0800595
Sarah Chin77a7ea62020-01-16 11:19:52 -0800596 return new RouteInfo(dest, gateway, iface, type, mtu);
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700597 }
598
599 public RouteInfo[] newArray(int size) {
600 return new RouteInfo[size];
601 }
602 };
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700603}