1 /* 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 17 package com.android.server.connectivity; 18 19 import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport; 20 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; 21 import static android.net.NetworkCapabilities.NET_CAPABILITY_LOCAL_NETWORK; 22 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; 23 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; 24 import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET; 25 import static android.net.NetworkCapabilities.TRANSPORT_TEST; 26 import static android.net.NetworkCapabilities.TRANSPORT_WIFI; 27 import static android.net.NetworkCapabilities.transportNamesOf; 28 import static android.system.OsConstants.EEXIST; 29 import static android.system.OsConstants.EIO; 30 import static android.system.OsConstants.ENOENT; 31 32 import static com.android.net.module.util.FrameworkConnectivityStatsLog.CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED; 33 import static com.android.net.module.util.FrameworkConnectivityStatsLog.CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_DISALLOW_BYPASS_VPN_FOR_DELEGATE_UID_ENOENT; 34 35 import android.annotation.NonNull; 36 import android.annotation.Nullable; 37 import android.content.Context; 38 import android.content.pm.PackageManager; 39 import android.net.CaptivePortalData; 40 import android.net.DscpPolicy; 41 import android.net.IDnsResolver; 42 import android.net.INetd; 43 import android.net.INetworkAgent; 44 import android.net.INetworkAgentRegistry; 45 import android.net.INetworkMonitor; 46 import android.net.LinkProperties; 47 import android.net.LocalNetworkConfig; 48 import android.net.NattKeepalivePacketData; 49 import android.net.Network; 50 import android.net.NetworkAgent; 51 import android.net.NetworkAgentConfig; 52 import android.net.NetworkCapabilities; 53 import android.net.NetworkInfo; 54 import android.net.NetworkMonitorManager; 55 import android.net.NetworkRequest; 56 import android.net.NetworkScore; 57 import android.net.NetworkStateSnapshot; 58 import android.net.QosCallbackException; 59 import android.net.QosFilter; 60 import android.net.QosFilterParcelable; 61 import android.net.QosSession; 62 import android.net.TcpKeepalivePacketData; 63 import android.os.Handler; 64 import android.os.IBinder; 65 import android.os.Message; 66 import android.os.RemoteException; 67 import android.os.ServiceSpecificException; 68 import android.os.SystemClock; 69 import android.telephony.data.EpsBearerQosSessionAttributes; 70 import android.telephony.data.NrQosSessionAttributes; 71 import android.util.ArrayMap; 72 import android.util.ArraySet; 73 import android.util.Log; 74 import android.util.Pair; 75 import android.util.SparseArray; 76 77 import com.android.internal.annotations.VisibleForTesting; 78 import com.android.internal.util.IndentingPrintWriter; 79 import com.android.internal.util.WakeupMessage; 80 import com.android.net.module.util.FrameworkConnectivityStatsLog; 81 import com.android.net.module.util.HandlerUtils; 82 import com.android.server.ConnectivityService; 83 import com.android.server.ConnectivityService.CaptivePortalImpl; 84 85 import java.io.PrintWriter; 86 import java.net.Inet4Address; 87 import java.net.Inet6Address; 88 import java.time.Instant; 89 import java.util.ArrayList; 90 import java.util.Arrays; 91 import java.util.List; 92 import java.util.NoSuchElementException; 93 import java.util.Objects; 94 import java.util.SortedSet; 95 import java.util.TreeSet; 96 import java.util.function.Consumer; 97 98 /** 99 * A bag class used by ConnectivityService for holding a collection of most recent 100 * information published by a particular NetworkAgent as well as the 101 * AsyncChannel/messenger for reaching that NetworkAgent and lists of NetworkRequests 102 * interested in using it. Default sort order is descending by score. 103 */ 104 // States of a network: 105 // -------------------- 106 // 1. registered, uncreated, disconnected, unvalidated 107 // This state is entered when a NetworkFactory registers a NetworkAgent in any state except 108 // the CONNECTED state. 109 // 2. registered, uncreated, connecting, unvalidated 110 // This state is entered when a registered NetworkAgent for a VPN network transitions to the 111 // CONNECTING state (TODO: go through this state for every network, not just VPNs). 112 // ConnectivityService will tell netd to create the network early in order to add extra UID 113 // routing rules referencing the netID. These rules need to be in place before the network is 114 // connected to avoid racing against client apps trying to connect to a half-setup network. 115 // 3. registered, uncreated, connected, unvalidated 116 // This state is entered when a registered NetworkAgent transitions to the CONNECTED state. 117 // ConnectivityService will tell netd to create the network if it was not already created, and 118 // immediately transition to state #4. 119 // 4. registered, created, connected, unvalidated 120 // If this network can satisfy the default NetworkRequest, then NetworkMonitor will 121 // probe for Internet connectivity. 122 // If this network cannot satisfy the default NetworkRequest, it will immediately be 123 // transitioned to state #5. 124 // A network may remain in this state if NetworkMonitor fails to find Internet connectivity, 125 // for example: 126 // a. a captive portal is present, or 127 // b. a WiFi router whose Internet backhaul is down, or 128 // c. a wireless connection stops transferring packets temporarily (e.g. device is in elevator 129 // or tunnel) but does not disconnect from the AP/cell tower, or 130 // d. a stand-alone device offering a WiFi AP without an uplink for configuration purposes. 131 // 5. registered, created, connected, validated 132 // 6. registered, created, connected, (validated or unvalidated), destroyed 133 // This is an optional state where the underlying native network is destroyed but the network is 134 // still connected for scoring purposes, so can satisfy requests, including the default request. 135 // It is used when the transport layer wants to replace a network with another network (e.g., 136 // when Wi-Fi has roamed to a different BSSID that is part of a different L3 network) and does 137 // not want the device to switch to another network until the replacement connects and validates. 138 // 139 // The device's default network connection: 140 // ---------------------------------------- 141 // Networks in states #4 and #5 may be used as a device's default network connection if they 142 // satisfy the default NetworkRequest. 143 // A network, that satisfies the default NetworkRequest, in state #5 should always be chosen 144 // in favor of a network, that satisfies the default NetworkRequest, in state #4. 145 // When deciding between two networks, that both satisfy the default NetworkRequest, to select 146 // for the default network connection, the one with the higher score should be chosen. 147 // 148 // When a network disconnects: 149 // --------------------------- 150 // If a network's transport disappears, for example: 151 // a. WiFi turned off, or 152 // b. cellular data turned off, or 153 // c. airplane mode is turned on, or 154 // d. a wireless connection disconnects from AP/cell tower entirely (e.g. device is out of range 155 // of AP for an extended period of time, or switches to another AP without roaming) 156 // then that network can transition from any state (#1-#5) to unregistered. This happens by 157 // the transport disconnecting their NetworkAgent's AsyncChannel with ConnectivityManager. 158 // ConnectivityService also tells netd to destroy the network. 159 // 160 // When ConnectivityService disconnects a network: 161 // ----------------------------------------------- 162 // If a network is just connected, ConnectivityService will think it will be used soon, but might 163 // not be used. Thus, a 5s timer will be held to prevent the network being torn down immediately. 164 // This "nascent" state is implemented by the "lingering" logic below without relating to any 165 // request, and is used in some cases where network requests race with network establishment. The 166 // nascent state ends when the 5-second timer fires, or as soon as the network satisfies a 167 // request, whichever is earlier. In this state, the network is considered in the background. 168 // 169 // If a network has no chance of satisfying any requests (even if it were to become validated 170 // and enter state #5), ConnectivityService will disconnect the NetworkAgent's AsyncChannel. 171 // 172 // If the network was satisfying a foreground NetworkRequest (i.e. had been the highest scoring that 173 // satisfied the NetworkRequest's constraints), but is no longer the highest scoring network for any 174 // foreground NetworkRequest, then there will be a 30s pause to allow network communication to be 175 // wrapped up rather than abruptly terminated. During this pause the network is said to be 176 // "lingering". During this pause if the network begins satisfying a foreground NetworkRequest, 177 // ConnectivityService will cancel the future disconnection of the NetworkAgent's AsyncChannel, and 178 // the network is no longer considered "lingering". After the linger timer expires, if the network 179 // is satisfying one or more background NetworkRequests it is kept up in the background. If it is 180 // not, ConnectivityService disconnects the NetworkAgent's AsyncChannel. 181 public class NetworkAgentInfo implements NetworkRanker.Scoreable { 182 183 @NonNull public NetworkInfo networkInfo; 184 // This Network object should always be used if possible, so as to encourage reuse of the 185 // enclosed socket factory and connection pool. Avoid creating other Network objects. 186 // This Network object is always valid. 187 @NonNull public final Network network; 188 @NonNull public LinkProperties linkProperties; 189 // This should only be modified by ConnectivityService, via setNetworkCapabilities(). 190 // TODO: make this private with a getter. 191 @NonNull public NetworkCapabilities networkCapabilities; 192 @NonNull public final NetworkAgentConfig networkAgentConfig; 193 @Nullable public LocalNetworkConfig localNetworkConfig; 194 195 // Underlying networks declared by the agent. 196 // The networks in this list might be declared by a VPN using setUnderlyingNetworks and are 197 // not guaranteed to be current or correct, or even to exist. 198 // 199 // This array is read and iterated on multiple threads with no locking so its contents must 200 // never be modified. When the list of networks changes, replace with a new array, on the 201 // handler thread. 202 public @Nullable volatile Network[] declaredUnderlyingNetworks; 203 204 // The capabilities originally announced by the NetworkAgent, regardless of any capabilities 205 // that were added or removed due to this network's underlying networks. 206 // 207 // As the name implies, these capabilities are not sanitized and are not to 208 // be trusted. Most callers should simply use the {@link networkCapabilities} 209 // field instead. 210 private @Nullable NetworkCapabilities mDeclaredCapabilitiesUnsanitized; 211 212 // Timestamp (SystemClock.elapsedRealtime()) when netd has been told to create this Network, or 213 // 0 if it hasn't been done yet. 214 // From this point on, the appropriate routing rules are setup and routes are added so packets 215 // can begin flowing over the Network. 216 // This is a sticky value; once set != 0 it is never changed. 217 private long mCreatedTime; 218 219 /** Notify this NAI that netd was just told to create this network */ setCreated()220 public void setCreated() { 221 if (0L != mCreatedTime) throw new IllegalStateException("Already created"); 222 mCreatedTime = SystemClock.elapsedRealtime(); 223 } 224 225 /** Returns whether netd was told to create this network */ isCreated()226 public boolean isCreated() { 227 return mCreatedTime != 0L; 228 } 229 230 // Get the time (SystemClock.elapsedRealTime) when this network was created (or 0 if never). getCreatedTime()231 public long getCreatedTime() { 232 return mCreatedTime; 233 } 234 235 // Timestamp of the first time (SystemClock.elapsedRealtime()) this network is marked as 236 // connected, or 0 if this network has never been marked connected. Once set to non-zero, the 237 // network shows up in API calls, is able to satisfy NetworkRequests and can become the default 238 // network. 239 // This is a sticky value; once set != 0 it is never changed. 240 private long mConnectedTime; 241 242 /** Notify this NAI that this network just connected */ setConnected()243 public void setConnected() { 244 if (0L != mConnectedTime) throw new IllegalStateException("Already connected"); 245 mConnectedTime = SystemClock.elapsedRealtime(); 246 } 247 248 /** Return whether this network ever connected */ everConnected()249 public boolean everConnected() { 250 return mConnectedTime != 0L; 251 } 252 253 // Get the time (SystemClock.elapsedRealTime()) when this network was first connected, or 0 if 254 // never. getConnectedTime()255 public long getConnectedTime() { 256 return mConnectedTime; 257 } 258 259 // When this network has been destroyed and is being kept temporarily until it is replaced, 260 // this is set to that timestamp (SystemClock.elapsedRealtime()). Zero otherwise. 261 private long mDestroyedTime; 262 263 /** Notify this NAI that this network was destroyed */ setDestroyed()264 public void setDestroyed() { 265 if (0L != mDestroyedTime) throw new IllegalStateException("Already destroyed"); 266 mDestroyedTime = SystemClock.elapsedRealtime(); 267 } 268 269 /** Return whether this network was destroyed */ isDestroyed()270 public boolean isDestroyed() { 271 return 0L != mDestroyedTime; 272 } 273 274 // Timestamp of the last roaming (SystemClock.elapsedRealtime()) or 0 if never roamed. 275 public long lastRoamTime; 276 277 // Timestamp (SystemClock.elapsedRealtime()) of the first time this network successfully 278 // passed validation or was deemed exempt of validation (see 279 // {@link NetworkMonitorUtils#isValidationRequired}). Zero if the network requires 280 // validation but never passed it successfully. 281 // This is a sticky value; once set it is never changed even if further validation attempts are 282 // made (whether they succeed or fail). 283 private long mFirstValidationTime; 284 285 // Timestamp (SystemClock.elapsedRealtime()) at which the latest validation attempt succeeded, 286 // or 0 if the latest validation attempt failed. 287 private long mCurrentValidationTime; 288 289 /** Notify this NAI that this network just finished a validation check */ setValidated(final boolean validated)290 public void setValidated(final boolean validated) { 291 final long nowOrZero = validated ? SystemClock.elapsedRealtime() : 0L; 292 if (validated && 0L == mFirstValidationTime) { 293 mFirstValidationTime = nowOrZero; 294 } 295 mCurrentValidationTime = nowOrZero; 296 } 297 298 /** 299 * Returns whether this network is currently validated. 300 * 301 * This is the result of the latest validation check. {@see #getCurrentValidationTime} for 302 * when that check was performed. 303 */ isValidated()304 public boolean isValidated() { 305 return 0L != mCurrentValidationTime; 306 } 307 308 /** 309 * Returns whether this network ever passed the validation checks successfully. 310 * 311 * Note that the network may no longer be validated at this time ever if this is true. 312 * @see #isValidated 313 */ everValidated()314 public boolean everValidated() { 315 return 0L != mFirstValidationTime; 316 } 317 318 // Get the time (SystemClock.elapsedRealTime()) when this network was most recently validated, 319 // or 0 if this network was found not to validate on the last attempt. getCurrentValidationTime()320 public long getCurrentValidationTime() { 321 return mCurrentValidationTime; 322 } 323 324 // Get the time (SystemClock.elapsedRealTime()) when this network was validated for the first 325 // time (or 0 if never). getFirstValidationTime()326 public long getFirstValidationTime() { 327 return mFirstValidationTime; 328 } 329 330 // Timestamp (SystemClock.elapsedRealtime()) at which the user requested this network be 331 // avoided when unvalidated. Zero if this never happened for this network. 332 // This is only meaningful if the system is configured to have some cell networks yield 333 // to bad wifi, e.g., if the config_networkAvoidBadWifi option is set to 0 and the user has 334 // not overridden that via Settings.Global.NETWORK_AVOID_BAD_WIFI. 335 // 336 // Normally the system always prefers a validated network to a non-validated one, even if 337 // the non-validated one is cheaper. However, some cell networks may be configured by the 338 // setting above to yield to WiFi even if that WiFi network goes bad. When this configuration 339 // is active, specific networks can be marked to override this configuration so that the 340 // system will revert to preferring such a cell to this network when this network goes bad. This 341 // is achieved by calling {@link ConnectivityManager#setAvoidUnvalidated()}, and this field 342 // is set to non-zero when this happened to this network. 343 private long mAvoidUnvalidated; 344 345 /** Set this network as being avoided when unvalidated. {@see mAvoidUnvalidated} */ setAvoidUnvalidated()346 public void setAvoidUnvalidated() { 347 if (0L != mAvoidUnvalidated) throw new IllegalStateException("Already avoided unvalidated"); 348 mAvoidUnvalidated = SystemClock.elapsedRealtime(); 349 } 350 351 // Get the time (SystemClock.elapsedRealTime()) when this network was set to being avoided 352 // when unvalidated, or 0 if this never happened. getAvoidUnvalidated()353 public long getAvoidUnvalidated() { 354 return mAvoidUnvalidated; 355 } 356 357 // Timestamp (SystemClock.elapsedRealtime()) at which a captive portal was first detected 358 // on this network, or zero if this never happened. 359 // This is a sticky value; once set != 0 it is never changed. 360 private long mFirstCaptivePortalDetectedTime; 361 362 // Timestamp (SystemClock.elapsedRealtime()) at which the latest validation attempt found a 363 // captive portal, or zero if the latest attempt didn't find a captive portal. 364 private long mCurrentCaptivePortalDetectedTime; 365 366 /** Notify this NAI that a captive portal has just been detected on this network */ setCaptivePortalDetected(final boolean hasCaptivePortal)367 public void setCaptivePortalDetected(final boolean hasCaptivePortal) { 368 if (!hasCaptivePortal) { 369 mCurrentCaptivePortalDetectedTime = 0L; 370 return; 371 } 372 final long now = SystemClock.elapsedRealtime(); 373 if (0L == mFirstCaptivePortalDetectedTime) mFirstCaptivePortalDetectedTime = now; 374 mCurrentCaptivePortalDetectedTime = now; 375 } 376 377 /** Return whether a captive portal has ever been detected on this network */ everCaptivePortalDetected()378 public boolean everCaptivePortalDetected() { 379 return 0L != mFirstCaptivePortalDetectedTime; 380 } 381 382 /** Return whether this network has been detected to be behind a captive portal at the moment */ captivePortalDetected()383 public boolean captivePortalDetected() { 384 return 0L != mCurrentCaptivePortalDetectedTime; 385 } 386 387 // Timestamp (SystemClock.elapsedRealtime()) at which the latest validation attempt found 388 // partial connectivity, or zero if the latest attempt didn't find partial connectivity. 389 private long mPartialConnectivityTime; 390 setPartialConnectivity(final boolean value)391 public void setPartialConnectivity(final boolean value) { 392 mPartialConnectivityTime = value ? SystemClock.elapsedRealtime() : 0L; 393 } 394 395 /** Return whether this NAI has partial connectivity */ partialConnectivity()396 public boolean partialConnectivity() { 397 return 0L != mPartialConnectivityTime; 398 } 399 400 // Timestamp (SystemClock.elapsedRealTime()) at which the first validation attempt concluded, 401 // or timed out after {@link ConnectivityService#PROMPT_UNVALIDATED_DELAY_MS}. 0 if not yet. 402 private long mFirstEvaluationConcludedTime; 403 404 /** 405 * Notify this NAI that this network has been evaluated. 406 * 407 * The stack considers that any result finding some working connectivity (valid, partial, 408 * captive portal) is an initial validation. Negative result (not valid), however, is not 409 * considered initial validation until {@link ConnectivityService#PROMPT_UNVALIDATED_DELAY_MS} 410 * have elapsed. This is because some networks may spuriously fail for a short time immediately 411 * after associating. If no positive result is found after the timeout has elapsed, then 412 * the network has been evaluated once. 413 * 414 * @return true the first time this is called on this object, then always returns false. 415 */ setEvaluated()416 public boolean setEvaluated() { 417 if (0L != mFirstEvaluationConcludedTime) return false; 418 mFirstEvaluationConcludedTime = SystemClock.elapsedRealtime(); 419 return true; 420 } 421 422 /** When this network ever concluded its first evaluation, or 0 if this never happened. */ 423 @VisibleForTesting getFirstEvaluationConcludedTime()424 public long getFirstEvaluationConcludedTime() { 425 return mFirstEvaluationConcludedTime; 426 } 427 428 // Delay between when the network is disconnected and when the native network is destroyed. 429 public int teardownDelayMs; 430 431 // Captive portal info of the network from RFC8908, if any. 432 // Obtained by ConnectivityService and merged into NetworkAgent-provided information. 433 public CaptivePortalData capportApiData; 434 435 // The UID of the remote entity that created this Network. 436 public final int creatorUid; 437 438 // Network agent portal info of the network, if any. This information is provided from 439 // non-RFC8908 sources, such as Wi-Fi Passpoint, which can provide information such as Venue 440 // URL, Terms & Conditions URL, and network friendly name. 441 public CaptivePortalData networkAgentPortalData; 442 443 // Indicate whether this device has the automotive feature. 444 private final boolean mHasAutomotiveFeature; 445 446 /** 447 * Checks that a proposed update to the NCs of this NAI satisfies structural constraints. 448 * 449 * Some changes to NetworkCapabilities are structurally not supported by the stack, and 450 * NetworkAgents are absolutely never allowed to try and do them. When one of these is 451 * violated, this method returns false, which has ConnectivityService disconnect the network ; 452 * this is meant to guarantee that no implementor ever tries to do this. 453 */ respectsNcStructuralConstraints(@onNull final NetworkCapabilities proposedNc)454 public boolean respectsNcStructuralConstraints(@NonNull final NetworkCapabilities proposedNc) { 455 if (networkCapabilities.hasCapability(NET_CAPABILITY_LOCAL_NETWORK) 456 != proposedNc.hasCapability(NET_CAPABILITY_LOCAL_NETWORK)) { 457 return false; 458 } 459 return true; 460 } 461 462 /** 463 * Sets the capabilities sent by the agent for later retrieval. 464 * <p> 465 * This method does not sanitize the capabilities before storing them ; instead, use 466 * {@link #getDeclaredCapabilitiesSanitized} to retrieve a sanitized copy of the capabilities 467 * as they were passed here. 468 * <p> 469 * This method makes a defensive copy to avoid issues where the passed object is later mutated. 470 * 471 * @param caps the caps sent by the agent 472 */ setDeclaredCapabilities(@onNull final NetworkCapabilities caps)473 public void setDeclaredCapabilities(@NonNull final NetworkCapabilities caps) { 474 mDeclaredCapabilitiesUnsanitized = new NetworkCapabilities(caps); 475 } 476 477 /** 478 * Get the latest capabilities sent by the network agent, after sanitizing them. 479 * 480 * These are the capabilities as they were sent by the agent (but sanitized to conform to 481 * their restrictions). They are NOT the capabilities currently applying to this agent ; 482 * for that, use {@link #networkCapabilities}. 483 * 484 * Agents have restrictions on what capabilities they can send to Connectivity. For example, 485 * they can't change the owner UID from what they declared before, and complex restrictions 486 * apply to the allowedUids field. 487 * They also should not mutate immutable capabilities, although for backward-compatibility 488 * this is not enforced and limited to just a log. 489 * Forbidden capabilities also make no sense for networks, so they are disallowed and 490 * will be ignored with a warning. 491 * 492 * @param carrierPrivilegeAuthenticator the authenticator, to check access UIDs. 493 */ getDeclaredCapabilitiesSanitized( final CarrierPrivilegeAuthenticator carrierPrivilegeAuthenticator)494 public NetworkCapabilities getDeclaredCapabilitiesSanitized( 495 final CarrierPrivilegeAuthenticator carrierPrivilegeAuthenticator) { 496 final NetworkCapabilities nc = new NetworkCapabilities(mDeclaredCapabilitiesUnsanitized); 497 if (nc.hasConnectivityManagedCapability()) { 498 Log.wtf(TAG, "BUG: " + this + " has CS-managed capability."); 499 nc.removeAllForbiddenCapabilities(); 500 } 501 if (networkCapabilities.getOwnerUid() != nc.getOwnerUid()) { 502 Log.e(TAG, toShortString() + ": ignoring attempt to change owner from " 503 + networkCapabilities.getOwnerUid() + " to " + nc.getOwnerUid()); 504 nc.setOwnerUid(networkCapabilities.getOwnerUid()); 505 } 506 restrictCapabilitiesFromNetworkAgent(nc, creatorUid, mHasAutomotiveFeature, 507 mConnServiceDeps, carrierPrivilegeAuthenticator); 508 return nc; 509 } 510 511 // Networks are lingered when they become unneeded as a result of their NetworkRequests being 512 // satisfied by a higher-scoring network. so as to allow communication to wrap up before the 513 // network is taken down. This usually only happens to the default network. Lingering ends with 514 // either the linger timeout expiring and the network being taken down, or the network 515 // satisfying a request again. 516 public static class InactivityTimer implements Comparable<InactivityTimer> { 517 public final int requestId; 518 public final long expiryMs; 519 InactivityTimer(int requestId, long expiryMs)520 public InactivityTimer(int requestId, long expiryMs) { 521 this.requestId = requestId; 522 this.expiryMs = expiryMs; 523 } equals(Object o)524 public boolean equals(Object o) { 525 if (!(o instanceof InactivityTimer)) return false; 526 InactivityTimer other = (InactivityTimer) o; 527 return (requestId == other.requestId) && (expiryMs == other.expiryMs); 528 } hashCode()529 public int hashCode() { 530 return Objects.hash(requestId, expiryMs); 531 } compareTo(InactivityTimer other)532 public int compareTo(InactivityTimer other) { 533 return (expiryMs != other.expiryMs) ? 534 Long.compare(expiryMs, other.expiryMs) : 535 Integer.compare(requestId, other.requestId); 536 } toString()537 public String toString() { 538 return String.format("%s, expires %dms", requestId, 539 expiryMs - SystemClock.elapsedRealtime()); 540 } 541 } 542 543 /** 544 * Inform ConnectivityService that the network LINGER period has 545 * expired. 546 * obj = this NetworkAgentInfo 547 */ 548 public static final int EVENT_NETWORK_LINGER_COMPLETE = 1001; 549 550 /** 551 * Inform ConnectivityService that the agent is half-connected. 552 * arg1 = ARG_AGENT_SUCCESS or ARG_AGENT_FAILURE 553 * obj = NetworkAgentInfo 554 * @hide 555 */ 556 public static final int EVENT_AGENT_REGISTERED = 1002; 557 558 /** 559 * Inform ConnectivityService that the agent was disconnected. 560 * obj = NetworkAgentInfo 561 * @hide 562 */ 563 public static final int EVENT_AGENT_DISCONNECTED = 1003; 564 565 /** 566 * Argument for EVENT_AGENT_HALF_CONNECTED indicating failure. 567 */ 568 public static final int ARG_AGENT_FAILURE = 0; 569 570 /** 571 * Argument for EVENT_AGENT_HALF_CONNECTED indicating success. 572 */ 573 public static final int ARG_AGENT_SUCCESS = 1; 574 575 // How long this network should linger for. 576 private int mLingerDurationMs; 577 578 // All inactivity timers for this network, sorted by expiry time. A timer is added whenever 579 // a request is moved to a network with a better score, regardless of whether the network is or 580 // was lingering or not. An inactivity timer is also added when a network connects 581 // without immediately satisfying any requests. 582 // TODO: determine if we can replace this with a smaller or unsorted data structure. (e.g., 583 // SparseLongArray) combined with the timestamp of when the last timer is scheduled to fire. 584 private final SortedSet<InactivityTimer> mInactivityTimers = new TreeSet<>(); 585 586 // For fast lookups. Indexes into mInactivityTimers by request ID. 587 private final SparseArray<InactivityTimer> mInactivityTimerForRequest = new SparseArray<>(); 588 589 // Map of delegated UIDs used to bypass VPN and its captive portal app caller. 590 private final ArrayMap<CaptivePortalImpl, Integer> mCaptivePortalDelegateUids = 591 new ArrayMap<>(); 592 593 // Inactivity expiry timer. Armed whenever mInactivityTimers is non-empty, regardless of 594 // whether the network is inactive or not. Always set to the expiry of the mInactivityTimers 595 // that expires last. When the timer fires, all inactivity state is cleared, and if the network 596 // has no requests, it is torn down. 597 private WakeupMessage mInactivityMessage; 598 599 // Inactivity expiry. Holds the expiry time of the inactivity timer, or 0 if the timer is not 600 // armed. 601 private long mInactivityExpiryMs; 602 603 // Whether the network is inactive or not. Must be maintained separately from the above because 604 // it depends on the state of other networks and requests, which only ConnectivityService knows. 605 // (Example: we don't linger a network if it would become the best for a NetworkRequest if it 606 // validated). 607 private boolean mInactive; 608 609 // This represents the quality of the network. As opposed to NetworkScore, FullScore includes 610 // the ConnectivityService-managed bits. 611 private FullScore mScore; 612 613 // The list of NetworkRequests being satisfied by this Network. 614 private final SparseArray<NetworkRequest> mNetworkRequests = new SparseArray<>(); 615 616 // How many of the satisfied requests are actual requests and not listens. 617 private int mNumRequestNetworkRequests = 0; 618 619 // How many of the satisfied requests are of type BACKGROUND_REQUEST. 620 private int mNumBackgroundNetworkRequests = 0; 621 622 // The last ConnectivityReport made available for this network. This value is only null before a 623 // report is generated. Once non-null, it will never be null again. 624 @Nullable private ConnectivityReport mConnectivityReport; 625 626 public final INetworkAgent networkAgent; 627 // Only accessed from ConnectivityService handler thread 628 private final AgentDeathMonitor mDeathMonitor = new AgentDeathMonitor(); 629 630 public final int factorySerialNumber; 631 632 // Used by ConnectivityService to keep track of 464xlat. 633 public final Nat464Xlat clatd; 634 635 private final ArrayList<Message> mMessagesPendingRegistration = new ArrayList<>(); 636 // Set after asynchronous creation of the NetworkMonitor. 637 private volatile NetworkMonitorManager mNetworkMonitor; 638 639 private static final String TAG = ConnectivityService.class.getSimpleName(); 640 private static final boolean VDBG = false; 641 private final ConnectivityService mConnService; 642 private final ConnectivityService.Dependencies mConnServiceDeps; 643 private final Context mContext; 644 private final Handler mHandler; 645 private final NetworkAgentMessageHandler mRegistry; 646 private final QosCallbackTracker mQosCallbackTracker; 647 private final INetd mNetd; 648 649 private final long mCreationTime; 650 NetworkAgentInfo(INetworkAgent na, Network net, NetworkInfo info, @NonNull LinkProperties lp, @NonNull NetworkCapabilities nc, @Nullable LocalNetworkConfig localNetworkConfig, @NonNull NetworkScore score, Context context, Handler handler, NetworkAgentConfig config, ConnectivityService connService, INetd netd, IDnsResolver dnsResolver, int factorySerialNumber, int creatorUid, int lingerDurationMs, QosCallbackTracker qosCallbackTracker, ConnectivityService.Dependencies deps)651 public NetworkAgentInfo(INetworkAgent na, Network net, NetworkInfo info, 652 @NonNull LinkProperties lp, @NonNull NetworkCapabilities nc, 653 @Nullable LocalNetworkConfig localNetworkConfig, 654 @NonNull NetworkScore score, Context context, 655 Handler handler, NetworkAgentConfig config, ConnectivityService connService, INetd netd, 656 IDnsResolver dnsResolver, int factorySerialNumber, int creatorUid, 657 int lingerDurationMs, QosCallbackTracker qosCallbackTracker, 658 ConnectivityService.Dependencies deps) { 659 Objects.requireNonNull(net); 660 Objects.requireNonNull(info); 661 Objects.requireNonNull(lp); 662 Objects.requireNonNull(nc); 663 Objects.requireNonNull(context); 664 Objects.requireNonNull(config); 665 Objects.requireNonNull(qosCallbackTracker); 666 networkAgent = na; 667 network = net; 668 networkInfo = info; 669 linkProperties = lp; 670 networkCapabilities = nc; 671 this.localNetworkConfig = localNetworkConfig; 672 networkAgentConfig = config; 673 mConnService = connService; 674 mConnServiceDeps = deps; 675 setScore(score); // uses members connService, networkCapabilities and networkAgentConfig 676 clatd = new Nat464Xlat(this, netd, dnsResolver, deps); 677 mNetd = netd; 678 mContext = context; 679 mHandler = handler; 680 mRegistry = new NetworkAgentMessageHandler(mHandler); 681 this.factorySerialNumber = factorySerialNumber; 682 this.creatorUid = creatorUid; 683 mLingerDurationMs = lingerDurationMs; 684 mQosCallbackTracker = qosCallbackTracker; 685 declaredUnderlyingNetworks = (nc.getUnderlyingNetworks() != null) 686 ? nc.getUnderlyingNetworks().toArray(new Network[0]) 687 : null; 688 mCreationTime = System.currentTimeMillis(); 689 mHasAutomotiveFeature = 690 mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE); 691 } 692 693 private class AgentDeathMonitor implements IBinder.DeathRecipient { 694 @Override binderDied()695 public void binderDied() { 696 notifyDisconnected(); 697 } 698 } 699 700 /** 701 * Notify the NetworkAgent that it was registered, and should be unregistered if it dies. 702 * 703 * Must be called from the ConnectivityService handler thread. A NetworkAgent can only be 704 * registered once. 705 */ notifyRegistered(final INetworkMonitor nm)706 public void notifyRegistered(final INetworkMonitor nm) { 707 HandlerUtils.ensureRunningOnHandlerThread(mHandler); 708 mNetworkMonitor = new NetworkMonitorManager(nm); 709 try { 710 networkAgent.asBinder().linkToDeath(mDeathMonitor, 0); 711 networkAgent.onRegistered(); 712 } catch (RemoteException e) { 713 Log.e(TAG, "Error registering NetworkAgent", e); 714 maybeUnlinkDeathMonitor(); 715 mHandler.obtainMessage(EVENT_AGENT_REGISTERED, ARG_AGENT_FAILURE, 0, this) 716 .sendToTarget(); 717 return; 718 } 719 720 mHandler.obtainMessage(EVENT_AGENT_REGISTERED, ARG_AGENT_SUCCESS, 0, this).sendToTarget(); 721 } 722 723 /** 724 * Pass all enqueued messages to the message processor argument, and clear the queue. 725 * 726 * This is called by ConnectivityService when it is ready to receive messages for this 727 * network agent. The processor may process the messages synchronously or asynchronously 728 * at its option. 729 * 730 * @param messageProcessor a function to process the messages 731 */ processEnqueuedMessages(final Consumer<Message> messageProcessor)732 public void processEnqueuedMessages(final Consumer<Message> messageProcessor) { 733 for (final Message enqueued : mMessagesPendingRegistration) { 734 messageProcessor.accept(enqueued); 735 } 736 mMessagesPendingRegistration.clear(); 737 } 738 739 /** 740 * Enqueues a message if it needs to be enqueued, and returns whether it was enqueued. 741 * 742 * The message is enqueued iff it can't be sent just yet. If it can be sent 743 * immediately, this method returns false and doesn't enqueue. 744 * 745 * If it enqueues, this method will make a copy of the message for enqueuing since 746 * messages can't be reused or recycled before the end of their processing by the 747 * handler. 748 */ maybeEnqueueMessage(final Message msg)749 public boolean maybeEnqueueMessage(final Message msg) { 750 HandlerUtils.ensureRunningOnHandlerThread(mHandler); 751 if (null != mNetworkMonitor) return false; 752 final Message m = mHandler.obtainMessage(); 753 m.copyFrom(msg); 754 mMessagesPendingRegistration.add(m); 755 return true; 756 } 757 758 /** 759 * Disconnect the NetworkAgent. Must be called from the ConnectivityService handler thread. 760 */ disconnect()761 public void disconnect() { 762 try { 763 networkAgent.onDisconnected(); 764 } catch (RemoteException e) { 765 Log.i(TAG, "Error disconnecting NetworkAgent", e); 766 // Fall through: it's fine if the remote has died 767 } 768 769 notifyDisconnected(); 770 maybeUnlinkDeathMonitor(); 771 } 772 maybeUnlinkDeathMonitor()773 private void maybeUnlinkDeathMonitor() { 774 try { 775 networkAgent.asBinder().unlinkToDeath(mDeathMonitor, 0); 776 } catch (NoSuchElementException e) { 777 // Was not linked: ignore 778 } 779 } 780 notifyDisconnected()781 private void notifyDisconnected() { 782 // Note this may be called multiple times if ConnectivityService disconnects while the 783 // NetworkAgent also dies. ConnectivityService ignores disconnects of already disconnected 784 // agents. 785 mHandler.obtainMessage(EVENT_AGENT_DISCONNECTED, this).sendToTarget(); 786 } 787 788 /** 789 * Notify the NetworkAgent that bandwidth update was requested. 790 */ onBandwidthUpdateRequested()791 public void onBandwidthUpdateRequested() { 792 try { 793 networkAgent.onBandwidthUpdateRequested(); 794 } catch (RemoteException e) { 795 Log.e(TAG, "Error sending bandwidth update request event", e); 796 } 797 } 798 799 /** 800 * Notify the NetworkAgent that validation status has changed. 801 */ onValidationStatusChanged(int validationStatus, @Nullable String captivePortalUrl)802 public void onValidationStatusChanged(int validationStatus, @Nullable String captivePortalUrl) { 803 try { 804 networkAgent.onValidationStatusChanged(validationStatus, captivePortalUrl); 805 } catch (RemoteException e) { 806 Log.e(TAG, "Error sending validation status change event", e); 807 } 808 } 809 810 /** 811 * Notify the NetworkAgent that the acceptUnvalidated setting should be saved. 812 */ onSaveAcceptUnvalidated(boolean acceptUnvalidated)813 public void onSaveAcceptUnvalidated(boolean acceptUnvalidated) { 814 try { 815 networkAgent.onSaveAcceptUnvalidated(acceptUnvalidated); 816 } catch (RemoteException e) { 817 Log.e(TAG, "Error sending accept unvalidated event", e); 818 } 819 } 820 821 /** 822 * Notify the NetworkAgent that NATT socket keepalive should be started. 823 */ onStartNattSocketKeepalive(int slot, int intervalDurationMs, @NonNull NattKeepalivePacketData packetData)824 public void onStartNattSocketKeepalive(int slot, int intervalDurationMs, 825 @NonNull NattKeepalivePacketData packetData) { 826 try { 827 networkAgent.onStartNattSocketKeepalive(slot, intervalDurationMs, packetData); 828 } catch (RemoteException e) { 829 Log.e(TAG, "Error sending NATT socket keepalive start event", e); 830 } 831 } 832 833 /** 834 * Notify the NetworkAgent that TCP socket keepalive should be started. 835 */ onStartTcpSocketKeepalive(int slot, int intervalDurationMs, @NonNull TcpKeepalivePacketData packetData)836 public void onStartTcpSocketKeepalive(int slot, int intervalDurationMs, 837 @NonNull TcpKeepalivePacketData packetData) { 838 try { 839 networkAgent.onStartTcpSocketKeepalive(slot, intervalDurationMs, packetData); 840 } catch (RemoteException e) { 841 Log.e(TAG, "Error sending TCP socket keepalive start event", e); 842 } 843 } 844 845 /** 846 * Notify the NetworkAgent that socket keepalive should be stopped. 847 */ onStopSocketKeepalive(int slot)848 public void onStopSocketKeepalive(int slot) { 849 try { 850 networkAgent.onStopSocketKeepalive(slot); 851 } catch (RemoteException e) { 852 Log.e(TAG, "Error sending TCP socket keepalive stop event", e); 853 } 854 } 855 856 /** 857 * Notify the NetworkAgent that signal strength thresholds should be updated. 858 */ onSignalStrengthThresholdsUpdated(@onNull int[] thresholds)859 public void onSignalStrengthThresholdsUpdated(@NonNull int[] thresholds) { 860 try { 861 networkAgent.onSignalStrengthThresholdsUpdated(thresholds); 862 } catch (RemoteException e) { 863 Log.e(TAG, "Error sending signal strength thresholds event", e); 864 } 865 } 866 867 /** 868 * Notify the NetworkAgent that automatic reconnect should be prevented. 869 */ onPreventAutomaticReconnect()870 public void onPreventAutomaticReconnect() { 871 try { 872 networkAgent.onPreventAutomaticReconnect(); 873 } catch (RemoteException e) { 874 Log.e(TAG, "Error sending prevent automatic reconnect event", e); 875 } 876 } 877 878 /** 879 * Notify the NetworkAgent that a NATT keepalive packet filter should be added. 880 */ onAddNattKeepalivePacketFilter(int slot, @NonNull NattKeepalivePacketData packetData)881 public void onAddNattKeepalivePacketFilter(int slot, 882 @NonNull NattKeepalivePacketData packetData) { 883 try { 884 networkAgent.onAddNattKeepalivePacketFilter(slot, packetData); 885 } catch (RemoteException e) { 886 Log.e(TAG, "Error sending add NATT keepalive packet filter event", e); 887 } 888 } 889 890 /** 891 * Notify the NetworkAgent that a TCP keepalive packet filter should be added. 892 */ onAddTcpKeepalivePacketFilter(int slot, @NonNull TcpKeepalivePacketData packetData)893 public void onAddTcpKeepalivePacketFilter(int slot, 894 @NonNull TcpKeepalivePacketData packetData) { 895 try { 896 networkAgent.onAddTcpKeepalivePacketFilter(slot, packetData); 897 } catch (RemoteException e) { 898 Log.e(TAG, "Error sending add TCP keepalive packet filter event", e); 899 } 900 } 901 902 /** 903 * Notify the NetworkAgent that a keepalive packet filter should be removed. 904 */ onRemoveKeepalivePacketFilter(int slot)905 public void onRemoveKeepalivePacketFilter(int slot) { 906 try { 907 networkAgent.onRemoveKeepalivePacketFilter(slot); 908 } catch (RemoteException e) { 909 Log.e(TAG, "Error sending remove keepalive packet filter event", e); 910 } 911 } 912 913 /** 914 * Notify the NetworkAgent that the qos filter should be registered against the given qos 915 * callback id. 916 */ onQosFilterCallbackRegistered(final int qosCallbackId, final QosFilter qosFilter)917 public void onQosFilterCallbackRegistered(final int qosCallbackId, 918 final QosFilter qosFilter) { 919 try { 920 networkAgent.onQosFilterCallbackRegistered(qosCallbackId, 921 new QosFilterParcelable(qosFilter)); 922 } catch (final RemoteException e) { 923 Log.e(TAG, "Error registering a qos callback id against a qos filter", e); 924 } 925 } 926 927 /** 928 * Notify the NetworkAgent that the given qos callback id should be unregistered. 929 */ onQosCallbackUnregistered(final int qosCallbackId)930 public void onQosCallbackUnregistered(final int qosCallbackId) { 931 try { 932 networkAgent.onQosCallbackUnregistered(qosCallbackId); 933 } catch (RemoteException e) { 934 Log.e(TAG, "Error unregistering a qos callback id", e); 935 } 936 } 937 938 /** 939 * Notify the NetworkAgent that the network is successfully connected. 940 */ onNetworkCreated()941 public void onNetworkCreated() { 942 try { 943 networkAgent.onNetworkCreated(); 944 } catch (RemoteException e) { 945 Log.e(TAG, "Error sending network created event", e); 946 } 947 } 948 949 /** 950 * Notify the NetworkAgent that the native network has been destroyed. 951 */ onNetworkDestroyed()952 public void onNetworkDestroyed() { 953 try { 954 networkAgent.onNetworkDestroyed(); 955 } catch (RemoteException e) { 956 Log.e(TAG, "Error sending network destroyed event", e); 957 } 958 } 959 960 // TODO: consider moving out of NetworkAgentInfo into its own class 961 private class NetworkAgentMessageHandler extends INetworkAgentRegistry.Stub { 962 private final Handler mHandler; 963 NetworkAgentMessageHandler(Handler handler)964 private NetworkAgentMessageHandler(Handler handler) { 965 mHandler = handler; 966 } 967 968 @Override sendNetworkCapabilities(@onNull NetworkCapabilities nc)969 public void sendNetworkCapabilities(@NonNull NetworkCapabilities nc) { 970 Objects.requireNonNull(nc); 971 mHandler.obtainMessage(NetworkAgent.EVENT_NETWORK_CAPABILITIES_CHANGED, 972 new Pair<>(NetworkAgentInfo.this, nc)).sendToTarget(); 973 } 974 975 @Override sendLinkProperties(@onNull LinkProperties lp)976 public void sendLinkProperties(@NonNull LinkProperties lp) { 977 Objects.requireNonNull(lp); 978 mHandler.obtainMessage(NetworkAgent.EVENT_NETWORK_PROPERTIES_CHANGED, 979 new Pair<>(NetworkAgentInfo.this, lp)).sendToTarget(); 980 } 981 982 @Override sendNetworkInfo(@onNull NetworkInfo info)983 public void sendNetworkInfo(@NonNull NetworkInfo info) { 984 Objects.requireNonNull(info); 985 mHandler.obtainMessage(NetworkAgent.EVENT_NETWORK_INFO_CHANGED, 986 new Pair<>(NetworkAgentInfo.this, info)).sendToTarget(); 987 } 988 989 @Override sendLocalNetworkConfig(@onNull final LocalNetworkConfig config)990 public void sendLocalNetworkConfig(@NonNull final LocalNetworkConfig config) { 991 mHandler.obtainMessage(NetworkAgent.EVENT_LOCAL_NETWORK_CONFIG_CHANGED, 992 new Pair<>(NetworkAgentInfo.this, config)).sendToTarget(); 993 } 994 995 @Override sendScore(@onNull final NetworkScore score)996 public void sendScore(@NonNull final NetworkScore score) { 997 mHandler.obtainMessage(NetworkAgent.EVENT_NETWORK_SCORE_CHANGED, 998 new Pair<>(NetworkAgentInfo.this, score)).sendToTarget(); 999 } 1000 1001 @Override sendExplicitlySelected(boolean explicitlySelected, boolean acceptPartial)1002 public void sendExplicitlySelected(boolean explicitlySelected, boolean acceptPartial) { 1003 mHandler.obtainMessage(NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED, 1004 explicitlySelected ? 1 : 0, acceptPartial ? 1 : 0, 1005 new Pair<>(NetworkAgentInfo.this, null)).sendToTarget(); 1006 } 1007 1008 @Override sendSocketKeepaliveEvent(int slot, int reason)1009 public void sendSocketKeepaliveEvent(int slot, int reason) { 1010 mHandler.obtainMessage(NetworkAgent.EVENT_SOCKET_KEEPALIVE, 1011 slot, reason, new Pair<>(NetworkAgentInfo.this, null)).sendToTarget(); 1012 } 1013 1014 @Override sendUnderlyingNetworks(@ullable List<Network> networks)1015 public void sendUnderlyingNetworks(@Nullable List<Network> networks) { 1016 mHandler.obtainMessage(NetworkAgent.EVENT_UNDERLYING_NETWORKS_CHANGED, 1017 new Pair<>(NetworkAgentInfo.this, networks)).sendToTarget(); 1018 } 1019 1020 @Override sendEpsQosSessionAvailable(final int qosCallbackId, final QosSession session, final EpsBearerQosSessionAttributes attributes)1021 public void sendEpsQosSessionAvailable(final int qosCallbackId, final QosSession session, 1022 final EpsBearerQosSessionAttributes attributes) { 1023 mQosCallbackTracker.sendEventEpsQosSessionAvailable(qosCallbackId, session, attributes); 1024 } 1025 1026 @Override sendNrQosSessionAvailable(final int qosCallbackId, final QosSession session, final NrQosSessionAttributes attributes)1027 public void sendNrQosSessionAvailable(final int qosCallbackId, final QosSession session, 1028 final NrQosSessionAttributes attributes) { 1029 mQosCallbackTracker.sendEventNrQosSessionAvailable(qosCallbackId, session, attributes); 1030 } 1031 1032 @Override sendQosSessionLost(final int qosCallbackId, final QosSession session)1033 public void sendQosSessionLost(final int qosCallbackId, final QosSession session) { 1034 mQosCallbackTracker.sendEventQosSessionLost(qosCallbackId, session); 1035 } 1036 1037 @Override sendQosCallbackError(final int qosCallbackId, @QosCallbackException.ExceptionType final int exceptionType)1038 public void sendQosCallbackError(final int qosCallbackId, 1039 @QosCallbackException.ExceptionType final int exceptionType) { 1040 mQosCallbackTracker.sendEventQosCallbackError(qosCallbackId, exceptionType); 1041 } 1042 1043 @Override sendTeardownDelayMs(int teardownDelayMs)1044 public void sendTeardownDelayMs(int teardownDelayMs) { 1045 mHandler.obtainMessage(NetworkAgent.EVENT_TEARDOWN_DELAY_CHANGED, 1046 teardownDelayMs, 0, new Pair<>(NetworkAgentInfo.this, null)).sendToTarget(); 1047 } 1048 1049 @Override sendLingerDuration(final int durationMs)1050 public void sendLingerDuration(final int durationMs) { 1051 mHandler.obtainMessage(NetworkAgent.EVENT_LINGER_DURATION_CHANGED, 1052 new Pair<>(NetworkAgentInfo.this, durationMs)).sendToTarget(); 1053 } 1054 1055 @Override sendAddDscpPolicy(final DscpPolicy policy)1056 public void sendAddDscpPolicy(final DscpPolicy policy) { 1057 mHandler.obtainMessage(NetworkAgent.EVENT_ADD_DSCP_POLICY, 1058 new Pair<>(NetworkAgentInfo.this, policy)).sendToTarget(); 1059 } 1060 1061 @Override sendRemoveDscpPolicy(final int policyId)1062 public void sendRemoveDscpPolicy(final int policyId) { 1063 mHandler.obtainMessage(NetworkAgent.EVENT_REMOVE_DSCP_POLICY, 1064 new Pair<>(NetworkAgentInfo.this, policyId)).sendToTarget(); 1065 } 1066 1067 @Override sendRemoveAllDscpPolicies()1068 public void sendRemoveAllDscpPolicies() { 1069 mHandler.obtainMessage(NetworkAgent.EVENT_REMOVE_ALL_DSCP_POLICIES, 1070 new Pair<>(NetworkAgentInfo.this, null)).sendToTarget(); 1071 } 1072 1073 @Override sendUnregisterAfterReplacement(final int timeoutMillis)1074 public void sendUnregisterAfterReplacement(final int timeoutMillis) { 1075 mHandler.obtainMessage(NetworkAgent.EVENT_UNREGISTER_AFTER_REPLACEMENT, 1076 new Pair<>(NetworkAgentInfo.this, timeoutMillis)).sendToTarget(); 1077 } 1078 } 1079 1080 /** 1081 * Set the NetworkCapabilities on this NetworkAgentInfo. Also attempts to notify NetworkMonitor 1082 * of the new capabilities, if NetworkMonitor has been created. 1083 * 1084 * <p>If {@link NetworkMonitor#notifyNetworkCapabilitiesChanged(NetworkCapabilities)} fails, 1085 * the exception is logged but not reported to callers. 1086 * 1087 * @return the old capabilities of this network. 1088 */ getAndSetNetworkCapabilities( @onNull final NetworkCapabilities nc)1089 @NonNull public synchronized NetworkCapabilities getAndSetNetworkCapabilities( 1090 @NonNull final NetworkCapabilities nc) { 1091 final NetworkCapabilities oldNc = networkCapabilities; 1092 networkCapabilities = nc; 1093 updateScoreForNetworkAgentUpdate(); 1094 final NetworkMonitorManager nm = mNetworkMonitor; 1095 if (nm != null) { 1096 nm.notifyNetworkCapabilitiesChanged(nc); 1097 } 1098 return oldNc; 1099 } 1100 yieldToBadWiFi()1101 private boolean yieldToBadWiFi() { 1102 // Only cellular networks yield to bad wifi 1103 return networkCapabilities.hasTransport(TRANSPORT_CELLULAR) && !mConnService.avoidBadWifi(); 1104 } 1105 connService()1106 public ConnectivityService connService() { 1107 return mConnService; 1108 } 1109 netAgentConfig()1110 public NetworkAgentConfig netAgentConfig() { 1111 return networkAgentConfig; 1112 } 1113 handler()1114 public Handler handler() { 1115 return mHandler; 1116 } 1117 network()1118 public Network network() { 1119 return network; 1120 } 1121 1122 /** 1123 * Get the generated v6 address of clat. 1124 */ 1125 @Nullable getClatv6SrcAddress()1126 public Inet6Address getClatv6SrcAddress() { 1127 return clatd.getClatv6SrcAddress(); 1128 } 1129 1130 /** 1131 * Get the generated v4 address of clat. 1132 */ 1133 @Nullable getClatv4SrcAddress()1134 public Inet4Address getClatv4SrcAddress() { 1135 return clatd.getClatv4SrcAddress(); 1136 } 1137 1138 /** 1139 * Translate the input v4 address to v6 clat address. 1140 */ 1141 @Nullable translateV4toClatV6(@onNull Inet4Address addr)1142 public Inet6Address translateV4toClatV6(@NonNull Inet4Address addr) { 1143 return clatd.translateV4toV6(addr); 1144 } 1145 1146 /** 1147 * Get the NetworkMonitorManager in this NetworkAgentInfo. 1148 * 1149 * <p>This will be null before {@link #onNetworkMonitorCreated(INetworkMonitor)} is called. 1150 */ networkMonitor()1151 public NetworkMonitorManager networkMonitor() { 1152 return mNetworkMonitor; 1153 } 1154 1155 /** 1156 * Get the registry in this NetworkAgentInfo. 1157 */ getRegistry()1158 public INetworkAgentRegistry getRegistry() { 1159 return mRegistry; 1160 } 1161 1162 // Functions for manipulating the requests satisfied by this network. 1163 // 1164 // These functions must only called on ConnectivityService's main thread. 1165 1166 private static final boolean ADD = true; 1167 private static final boolean REMOVE = false; 1168 updateRequestCounts(boolean add, NetworkRequest request)1169 private void updateRequestCounts(boolean add, NetworkRequest request) { 1170 int delta = add ? +1 : -1; 1171 switch (request.type) { 1172 case REQUEST: 1173 case RESERVATION: 1174 mNumRequestNetworkRequests += delta; 1175 break; 1176 1177 case BACKGROUND_REQUEST: 1178 mNumRequestNetworkRequests += delta; 1179 mNumBackgroundNetworkRequests += delta; 1180 break; 1181 1182 case LISTEN: 1183 case LISTEN_FOR_BEST: 1184 case TRACK_DEFAULT: 1185 case TRACK_SYSTEM_DEFAULT: 1186 break; 1187 1188 case NONE: 1189 default: 1190 Log.wtf(TAG, "Unhandled request type " + request.type); 1191 break; 1192 } 1193 } 1194 1195 /** 1196 * Add {@code networkRequest} to this network as it's satisfied by this network. 1197 * @return true if {@code networkRequest} was added or false if {@code networkRequest} was 1198 * already present. 1199 */ addRequest(NetworkRequest networkRequest)1200 public boolean addRequest(NetworkRequest networkRequest) { 1201 HandlerUtils.ensureRunningOnHandlerThread(mHandler); 1202 NetworkRequest existing = mNetworkRequests.get(networkRequest.requestId); 1203 if (existing == networkRequest) return false; 1204 if (existing != null) { 1205 // Should only happen if the requestId wraps. If that happens lots of other things will 1206 // be broken as well. 1207 Log.wtf(TAG, String.format("Duplicate requestId for %s and %s on %s", 1208 networkRequest, existing, toShortString())); 1209 updateRequestCounts(REMOVE, existing); 1210 } 1211 mNetworkRequests.put(networkRequest.requestId, networkRequest); 1212 updateRequestCounts(ADD, networkRequest); 1213 return true; 1214 } 1215 1216 /** 1217 * Remove the specified request from this network. 1218 */ removeRequest(int requestId)1219 public void removeRequest(int requestId) { 1220 HandlerUtils.ensureRunningOnHandlerThread(mHandler); 1221 NetworkRequest existing = mNetworkRequests.get(requestId); 1222 if (existing == null) return; 1223 updateRequestCounts(REMOVE, existing); 1224 mNetworkRequests.remove(requestId); 1225 if (existing.isRequest()) { 1226 unlingerRequest(existing.requestId); 1227 } 1228 } 1229 1230 /** 1231 * Returns whether this network is currently satisfying the request with the specified ID. 1232 */ isSatisfyingRequest(int id)1233 public boolean isSatisfyingRequest(int id) { 1234 return mNetworkRequests.get(id) != null; 1235 } 1236 1237 /** 1238 * Returns the request at the specified position in the list of requests satisfied by this 1239 * network. 1240 */ requestAt(int index)1241 public NetworkRequest requestAt(int index) { 1242 HandlerUtils.ensureRunningOnHandlerThread(mHandler); 1243 return mNetworkRequests.valueAt(index); 1244 } 1245 1246 /** 1247 * Returns the number of requests currently satisfied by this network for which 1248 * {@link android.net.NetworkRequest#isRequest} returns {@code true}. 1249 */ numRequestNetworkRequests()1250 public int numRequestNetworkRequests() { 1251 return mNumRequestNetworkRequests; 1252 } 1253 1254 /** 1255 * Returns the number of requests currently satisfied by this network of type 1256 * {@link android.net.NetworkRequest.Type#BACKGROUND_REQUEST}. 1257 */ numBackgroundNetworkRequests()1258 public int numBackgroundNetworkRequests() { 1259 return mNumBackgroundNetworkRequests; 1260 } 1261 1262 /** 1263 * Returns the number of foreground requests currently satisfied by this network. 1264 */ numForegroundNetworkRequests()1265 public int numForegroundNetworkRequests() { 1266 return mNumRequestNetworkRequests - mNumBackgroundNetworkRequests; 1267 } 1268 1269 /** 1270 * Returns the number of requests of any type currently satisfied by this network. 1271 */ numNetworkRequests()1272 public int numNetworkRequests() { 1273 HandlerUtils.ensureRunningOnHandlerThread(mHandler); 1274 return mNetworkRequests.size(); 1275 } 1276 1277 /** 1278 * Returns whether the network is a background network. A network is a background network if it 1279 * does not have the NET_CAPABILITY_FOREGROUND capability, which implies it is satisfying no 1280 * foreground request, is not lingering (i.e. kept for a while after being outscored), and is 1281 * not a speculative network (i.e. kept pending validation when validation would have it 1282 * outscore another foreground network). That implies it is being kept up by some background 1283 * request (otherwise it would be torn down), maybe the mobile always-on request. 1284 */ isBackgroundNetwork()1285 public boolean isBackgroundNetwork() { 1286 return !isVPN() && numForegroundNetworkRequests() == 0 && mNumBackgroundNetworkRequests > 0 1287 && !isLingering(); 1288 } 1289 1290 // Does this network satisfy request? satisfies(NetworkRequest request)1291 public boolean satisfies(NetworkRequest request) { 1292 return everConnected() 1293 && request.networkCapabilities.satisfiedByNetworkCapabilities(networkCapabilities); 1294 } 1295 satisfiesImmutableCapabilitiesOf(NetworkRequest request)1296 public boolean satisfiesImmutableCapabilitiesOf(NetworkRequest request) { 1297 return everConnected() 1298 && request.networkCapabilities.satisfiedByImmutableNetworkCapabilities( 1299 networkCapabilities); 1300 } 1301 1302 /** Whether this network is a VPN. */ isVPN()1303 public boolean isVPN() { 1304 return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN); 1305 } 1306 1307 /** Whether this network is a local network */ isLocalNetwork()1308 public boolean isLocalNetwork() { 1309 return networkCapabilities.hasCapability(NET_CAPABILITY_LOCAL_NETWORK); 1310 } 1311 1312 /** 1313 * Whether this network should propagate the capabilities from its underlying networks. 1314 * Currently only true for VPNs. 1315 */ propagateUnderlyingCapabilities()1316 public boolean propagateUnderlyingCapabilities() { 1317 return isVPN(); 1318 } 1319 1320 // Caller must not mutate. This method is called frequently and making a defensive copy 1321 // would be too expensive. This is used by NetworkRanker.Scoreable, so it can be compared 1322 // against other scoreables. getCapsNoCopy()1323 @Override public NetworkCapabilities getCapsNoCopy() { 1324 return networkCapabilities; 1325 } 1326 1327 // NetworkRanker.Scoreable getScore()1328 @Override public FullScore getScore() { 1329 return mScore; 1330 } 1331 1332 /** 1333 * Mix-in the ConnectivityService-managed bits in the score. 1334 */ setScore(final NetworkScore score)1335 public void setScore(final NetworkScore score) { 1336 final FullScore oldScore = mScore; 1337 mScore = FullScore.fromNetworkScore(score, networkCapabilities, networkAgentConfig, 1338 everValidated(), 0L != getAvoidUnvalidated(), yieldToBadWiFi(), 1339 0L != mFirstEvaluationConcludedTime, isDestroyed()); 1340 maybeLogDifferences(oldScore); 1341 } 1342 1343 /** 1344 * Update the ConnectivityService-managed bits in the score. 1345 * 1346 * Call this after changing any data that might affect the score (e.g., agent config). 1347 */ updateScoreForNetworkAgentUpdate()1348 public void updateScoreForNetworkAgentUpdate() { 1349 final FullScore oldScore = mScore; 1350 mScore = mScore.mixInScore(networkCapabilities, networkAgentConfig, 1351 everValidated(), 0L != getAvoidUnvalidated(), yieldToBadWiFi(), 1352 0L != mFirstEvaluationConcludedTime, isDestroyed()); 1353 maybeLogDifferences(oldScore); 1354 } 1355 1356 /** 1357 * Prints score differences to logcat, if any. 1358 * @param oldScore the old score. Differences from |oldScore| to |this| are logged, if any. 1359 */ maybeLogDifferences(final FullScore oldScore)1360 public void maybeLogDifferences(final FullScore oldScore) { 1361 final String differences = mScore.describeDifferencesFrom(oldScore); 1362 if (null != differences) { 1363 Log.i(TAG, "Update score for net " + network + " : " + differences); 1364 } 1365 } 1366 1367 /** 1368 * Returns a Scoreable identical to this NAI, but validated. 1369 * 1370 * This is useful to probe what scoring would be if this network validated, to know 1371 * whether to provisionally keep a network that may or may not validate. 1372 * 1373 * @return a Scoreable identical to this NAI, but validated. 1374 */ getValidatedScoreable()1375 public NetworkRanker.Scoreable getValidatedScoreable() { 1376 return new NetworkRanker.Scoreable() { 1377 @Override public FullScore getScore() { 1378 return mScore.asValidated(); 1379 } 1380 1381 @Override public NetworkCapabilities getCapsNoCopy() { 1382 return networkCapabilities; 1383 } 1384 }; 1385 } 1386 1387 /** 1388 * Return a {@link NetworkStateSnapshot} for this network. 1389 */ 1390 @NonNull 1391 public NetworkStateSnapshot getNetworkStateSnapshot() { 1392 synchronized (this) { 1393 // Network objects are outwardly immutable so there is no point in duplicating. 1394 // Duplicating also precludes sharing socket factories and connection pools. 1395 final String subscriberId = (networkAgentConfig != null) 1396 ? networkAgentConfig.subscriberId : null; 1397 return new NetworkStateSnapshot(network, new NetworkCapabilities(networkCapabilities), 1398 new LinkProperties(linkProperties), subscriberId, networkInfo.getType()); 1399 } 1400 } 1401 1402 /** 1403 * Sets the specified requestId to linger on this network for the specified time. Called by 1404 * ConnectivityService when any request is moved to another network with a higher score, or 1405 * when a network is newly created. 1406 * 1407 * @param requestId The requestId of the request that no longer need to be served by this 1408 * network. Or {@link NetworkRequest#REQUEST_ID_NONE} if this is the 1409 * {@code InactivityTimer} for a newly created network. 1410 */ 1411 // TODO: Consider creating a dedicated function for nascent network, e.g. start/stopNascent. 1412 public void lingerRequest(int requestId, long now, long duration) { 1413 if (mInactivityTimerForRequest.get(requestId) != null) { 1414 // Cannot happen. Once a request is lingering on a particular network, we cannot 1415 // re-linger it unless that network becomes the best for that request again, in which 1416 // case we should have unlingered it. 1417 Log.wtf(TAG, toShortString() + ": request " + requestId + " already lingered"); 1418 } 1419 final long expiryMs = now + duration; 1420 InactivityTimer timer = new InactivityTimer(requestId, expiryMs); 1421 if (VDBG) Log.d(TAG, "Adding InactivityTimer " + timer + " to " + toShortString()); 1422 mInactivityTimers.add(timer); 1423 mInactivityTimerForRequest.put(requestId, timer); 1424 } 1425 1426 /** 1427 * Sets the specified requestId to linger on this network for the timeout set when 1428 * initializing or modified by {@link #setLingerDuration(int)}. Called by 1429 * ConnectivityService when any request is moved to another network with a higher score. 1430 * 1431 * @param requestId The requestId of the request that no longer need to be served by this 1432 * network. 1433 * @param now current system timestamp obtained by {@code SystemClock.elapsedRealtime}. 1434 */ 1435 public void lingerRequest(int requestId, long now) { 1436 lingerRequest(requestId, now, mLingerDurationMs); 1437 } 1438 1439 /** 1440 * Cancel lingering. Called by ConnectivityService when a request is added to this network. 1441 * Returns true if the given requestId was lingering on this network, false otherwise. 1442 */ 1443 public boolean unlingerRequest(int requestId) { 1444 InactivityTimer timer = mInactivityTimerForRequest.get(requestId); 1445 if (timer != null) { 1446 if (VDBG) { 1447 Log.d(TAG, "Removing InactivityTimer " + timer + " from " + toShortString()); 1448 } 1449 mInactivityTimers.remove(timer); 1450 mInactivityTimerForRequest.remove(requestId); 1451 return true; 1452 } 1453 return false; 1454 } 1455 1456 public long getInactivityExpiry() { 1457 return mInactivityExpiryMs; 1458 } 1459 1460 public void updateInactivityTimer() { 1461 long newExpiry = mInactivityTimers.isEmpty() ? 0 : mInactivityTimers.last().expiryMs; 1462 if (newExpiry == mInactivityExpiryMs) return; 1463 1464 // Even if we're going to reschedule the timer, cancel it first. This is because the 1465 // semantics of WakeupMessage guarantee that if cancel is called then the alarm will 1466 // never call its callback (handleLingerComplete), even if it has already fired. 1467 // WakeupMessage makes no such guarantees about rescheduling a message, so if mLingerMessage 1468 // has already been dispatched, rescheduling to some time in the future won't stop it 1469 // from calling its callback immediately. 1470 if (mInactivityMessage != null) { 1471 mInactivityMessage.cancel(); 1472 mInactivityMessage = null; 1473 } 1474 1475 if (newExpiry > 0) { 1476 // If the newExpiry timestamp is in the past, the wakeup message will fire immediately. 1477 mInactivityMessage = new WakeupMessage( 1478 mContext, mHandler, 1479 "NETWORK_LINGER_COMPLETE." + network.getNetId() /* cmdName */, 1480 EVENT_NETWORK_LINGER_COMPLETE /* cmd */, 1481 0 /* arg1 (unused) */, 0 /* arg2 (unused) */, 1482 this /* obj (NetworkAgentInfo) */); 1483 mInactivityMessage.schedule(newExpiry); 1484 } 1485 1486 mInactivityExpiryMs = newExpiry; 1487 } 1488 1489 public void setInactive() { 1490 mInactive = true; 1491 } 1492 1493 public void unsetInactive() { 1494 mInactive = false; 1495 } 1496 1497 public boolean isInactive() { 1498 return mInactive; 1499 } 1500 1501 public boolean isLingering() { 1502 return mInactive && !isNascent(); 1503 } 1504 1505 /** 1506 * Set the linger duration for this NAI. 1507 * @param durationMs The new linger duration, in milliseconds. 1508 */ 1509 public void setLingerDuration(final int durationMs) { 1510 final long diff = durationMs - mLingerDurationMs; 1511 final ArrayList<InactivityTimer> newTimers = new ArrayList<>(); 1512 for (final InactivityTimer timer : mInactivityTimers) { 1513 if (timer.requestId == NetworkRequest.REQUEST_ID_NONE) { 1514 // Don't touch nascent timer, re-add as is. 1515 newTimers.add(timer); 1516 } else { 1517 newTimers.add(new InactivityTimer(timer.requestId, timer.expiryMs + diff)); 1518 } 1519 } 1520 mInactivityTimers.clear(); 1521 mInactivityTimers.addAll(newTimers); 1522 updateInactivityTimer(); 1523 mLingerDurationMs = durationMs; 1524 } 1525 1526 /** 1527 * Return whether the network satisfies no request, but is still being kept up 1528 * because it has just connected less than 1529 * {@code ConnectivityService#DEFAULT_NASCENT_DELAY_MS}ms ago and is thus still considered 1530 * nascent. Note that nascent mechanism uses inactivity timer which isn't 1531 * associated with a request. Thus, use {@link NetworkRequest#REQUEST_ID_NONE} to identify it. 1532 * 1533 */ 1534 public boolean isNascent() { 1535 return mInactive && mInactivityTimers.size() == 1 1536 && mInactivityTimers.first().requestId == NetworkRequest.REQUEST_ID_NONE; 1537 } 1538 1539 public void clearInactivityState() { 1540 if (mInactivityMessage != null) { 1541 mInactivityMessage.cancel(); 1542 mInactivityMessage = null; 1543 } 1544 mInactivityTimers.clear(); 1545 mInactivityTimerForRequest.clear(); 1546 // Sets mInactivityExpiryMs, cancels and nulls out mInactivityMessage. 1547 updateInactivityTimer(); 1548 mInactive = false; 1549 } 1550 1551 public void dumpInactivityTimers(PrintWriter pw) { 1552 for (InactivityTimer timer : mInactivityTimers) { 1553 pw.println(timer); 1554 } 1555 } 1556 1557 /** 1558 * Dump the NAT64 xlat information. 1559 * 1560 * @param pw print writer. 1561 */ 1562 public void dumpNat464Xlat(IndentingPrintWriter pw) { 1563 clatd.dump(pw); 1564 } 1565 1566 /** 1567 * Sets the most recent ConnectivityReport for this network. 1568 * 1569 * <p>This should only be called from the ConnectivityService thread. 1570 * 1571 * @hide 1572 */ 1573 public void setConnectivityReport(@NonNull ConnectivityReport connectivityReport) { 1574 mConnectivityReport = connectivityReport; 1575 } 1576 1577 /** 1578 * Returns the most recent ConnectivityReport for this network, or null if none have been 1579 * reported yet. 1580 * 1581 * <p>This should only be called from the ConnectivityService thread. 1582 * 1583 * @hide 1584 */ 1585 @Nullable 1586 public ConnectivityReport getConnectivityReport() { 1587 return mConnectivityReport; 1588 } 1589 1590 /** 1591 * Make sure the NC from network agents don't contain stuff they shouldn't. 1592 * 1593 * @param nc the capabilities to sanitize 1594 * @param creatorUid the UID of the process creating this network agent 1595 * @param hasAutomotiveFeature true if this device has the automotive feature, false otherwise 1596 * @param authenticator the carrier privilege authenticator to check for telephony constraints 1597 */ 1598 public static void restrictCapabilitiesFromNetworkAgent(@NonNull final NetworkCapabilities nc, 1599 final int creatorUid, final boolean hasAutomotiveFeature, 1600 @NonNull final ConnectivityService.Dependencies deps, 1601 @Nullable final CarrierPrivilegeAuthenticator authenticator) { 1602 if (nc.hasTransport(TRANSPORT_TEST)) { 1603 nc.restrictCapabilitiesForTestNetwork(creatorUid); 1604 } 1605 if (!areAllowedUidsAcceptableFromNetworkAgent( 1606 nc, hasAutomotiveFeature, deps, authenticator)) { 1607 nc.setAllowedUids(new ArraySet<>()); 1608 } 1609 } 1610 1611 private int allowBypassVpnOnNetwork(boolean allow, int uid, int netId) { 1612 try { 1613 mNetd.networkAllowBypassVpnOnNetwork(allow, uid, netId); 1614 return 0; 1615 } catch (RemoteException e) { 1616 // Netd has crashed, and this process is about to crash as well. 1617 return EIO; 1618 } catch (ServiceSpecificException e) { 1619 return e.errorCode; 1620 } 1621 } 1622 1623 /** 1624 * Set the delegate UID of the app that is allowed to perform network traffic for captive 1625 * portal login, and configure the netd bypass rule with this delegated UID. 1626 * 1627 * @param caller the captive portal app to that delegated UID 1628 * @param uid the delegated UID of the captive portal app. 1629 * @return Return 0 if set the UID and VPN bypass rule successfully or bypass rule corresponding 1630 * to this UID already exists otherwise return errno. 1631 */ 1632 public int setCaptivePortalDelegateUid(@NonNull final CaptivePortalImpl caller, int uid) { 1633 final int errorCode = allowBypassVpnOnNetwork(true /* allow */, uid, network.netId); 1634 if (errorCode == 0 || errorCode == EEXIST) { 1635 mCaptivePortalDelegateUids.put(caller, uid); 1636 } 1637 return errorCode == EEXIST ? 0 : errorCode; 1638 } 1639 1640 /** 1641 * Remove the delegate UID of the app that is allowed to perform network traffic for captive 1642 * portal login, and remove the netd bypass rule if no other caller is delegating this UID. 1643 * 1644 * @param caller the captive portal app to that delegated UID. 1645 * @return Return 0 if remove the UID and VPN bypass rule successfully or bypass rule 1646 * corresponding to this UID doesn't exist otherwise return errno. 1647 */ 1648 public int removeCaptivePortalDelegateUid(@NonNull final CaptivePortalImpl caller) { 1649 final Integer maybeDelegateUid = mCaptivePortalDelegateUids.remove(caller); 1650 if (maybeDelegateUid == null) return 0; 1651 if (mCaptivePortalDelegateUids.values().contains(maybeDelegateUid)) return 0; 1652 final int errorCode = 1653 allowBypassVpnOnNetwork(false /* allow */, maybeDelegateUid, network.netId); 1654 if (errorCode == ENOENT) { 1655 FrameworkConnectivityStatsLog.write( 1656 CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED, 1657 CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_DISALLOW_BYPASS_VPN_FOR_DELEGATE_UID_ENOENT 1658 ); 1659 } 1660 return errorCode == ENOENT ? 0 : errorCode; 1661 } 1662 1663 private static boolean areAllowedUidsAcceptableFromNetworkAgent( 1664 @NonNull final NetworkCapabilities nc, final boolean hasAutomotiveFeature, 1665 @NonNull final ConnectivityService.Dependencies deps, 1666 @Nullable final CarrierPrivilegeAuthenticator carrierPrivilegeAuthenticator) { 1667 // NCs without access UIDs are fine. 1668 if (!nc.hasAllowedUids()) return true; 1669 // S and below must never accept access UIDs, even if an agent sends them, because netd 1670 // didn't support the required feature in S. 1671 if (!deps.isAtLeastT()) return false; 1672 1673 // On a non-restricted network, access UIDs make no sense 1674 if (nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) return false; 1675 1676 // If this network has TRANSPORT_TEST and nothing else, then the caller can do whatever 1677 // they want to access UIDs 1678 if (nc.hasSingleTransport(TRANSPORT_TEST)) return true; 1679 1680 if (nc.hasTransport(TRANSPORT_ETHERNET)) { 1681 // Factories that make ethernet networks can allow UIDs for automotive devices. 1682 if (hasAutomotiveFeature) return true; 1683 // It's also admissible if the ethernet network has TRANSPORT_TEST, as long as it 1684 // doesn't have NET_CAPABILITY_INTERNET so it can't become the default network. 1685 if (nc.hasTransport(TRANSPORT_TEST) && !nc.hasCapability(NET_CAPABILITY_INTERNET)) { 1686 return true; 1687 } 1688 return false; 1689 } 1690 1691 // Factories that make cell/wifi networks can allow the UID for the carrier service package. 1692 // This can only work in T where there is support for CarrierPrivilegeAuthenticator 1693 if (null != carrierPrivilegeAuthenticator 1694 && (nc.hasSingleTransportBesidesTest(TRANSPORT_CELLULAR) 1695 || nc.hasSingleTransportBesidesTest(TRANSPORT_WIFI)) 1696 && (1 == nc.getAllowedUidsNoCopy().size()) 1697 && (carrierPrivilegeAuthenticator.isCarrierServiceUidForNetworkCapabilities( 1698 nc.getAllowedUidsNoCopy().valueAt(0), nc))) { 1699 return true; 1700 } 1701 1702 return false; 1703 } 1704 1705 // TODO: Print shorter members first and only print the boolean variable which value is true 1706 // to improve readability. 1707 public String toString() { 1708 return "NetworkAgentInfo{" 1709 + "network{" + network + "} handle{" + network.getNetworkHandle() + "} ni{" 1710 + networkInfo.toShortString() + "} " 1711 + "created=" + Instant.ofEpochMilli(mCreationTime) + " " 1712 + mScore + " " 1713 + (isCreated() ? " created " + getCreatedTime() : "") 1714 + (isDestroyed() ? " destroyed " + mDestroyedTime : "") 1715 + (isNascent() ? " nascent" : (isLingering() ? " lingering" : "")) 1716 + (everValidated() ? " firstValidated " + getFirstValidationTime() : "") 1717 + (isValidated() ? " lastValidated " + getCurrentValidationTime() : "") 1718 + (partialConnectivity() 1719 ? " partialConnectivity " + mPartialConnectivityTime : "") 1720 + (everCaptivePortalDetected() 1721 ? " firstCaptivePortalDetected " + mFirstCaptivePortalDetectedTime : "") 1722 + (captivePortalDetected() 1723 ? " currentCaptivePortalDetected " + mCurrentCaptivePortalDetectedTime : "") 1724 + (networkAgentConfig.explicitlySelected ? " explicitlySelected" : "") 1725 + (networkAgentConfig.acceptUnvalidated ? " acceptUnvalidated" : "") 1726 + (networkAgentConfig.acceptPartialConnectivity ? " acceptPartialConnectivity" : "") 1727 + (clatd.isStarted() ? " clat{" + clatd + "} " : "") 1728 + (declaredUnderlyingNetworks != null 1729 ? " underlying{" + Arrays.toString(declaredUnderlyingNetworks) + "}" : "") 1730 + " lp{" + linkProperties + "}" 1731 + " nc{" + networkCapabilities + "}" 1732 + " factorySerialNumber=" + factorySerialNumber 1733 + "}"; 1734 } 1735 1736 /** 1737 * Show a short string representing a Network. 1738 * 1739 * This is often not enough for debugging purposes for anything complex, but the full form 1740 * is very long and hard to read, so this is useful when there isn't a lot of ambiguity. 1741 * This represents the network with something like "[100 WIFI|VPN]" or "[108 CELLULAR]". 1742 */ 1743 public String toShortString() { 1744 return "[" + network.getNetId() + " " 1745 + transportNamesOf(networkCapabilities.getTransportTypes()) + "]"; 1746 } 1747 1748 /** 1749 * Null-guarding version of NetworkAgentInfo#toShortString() 1750 */ 1751 @NonNull 1752 public static String toShortString(@Nullable final NetworkAgentInfo nai) { 1753 return null != nai ? nai.toShortString() : "[null]"; 1754 } 1755 } 1756