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 android.content.Context; 20 import android.net.LinkProperties; 21 import android.net.Network; 22 import android.net.NetworkCapabilities; 23 import android.net.NetworkInfo; 24 import android.net.NetworkMisc; 25 import android.net.NetworkRequest; 26 import android.os.Handler; 27 import android.os.Messenger; 28 import android.util.SparseArray; 29 30 import com.android.internal.util.AsyncChannel; 31 import com.android.server.connectivity.NetworkMonitor; 32 33 import java.util.ArrayList; 34 35 /** 36 * A bag class used by ConnectivityService for holding a collection of most recent 37 * information published by a particular NetworkAgent as well as the 38 * AsyncChannel/messenger for reaching that NetworkAgent and lists of NetworkRequests 39 * interested in using it. 40 */ 41 public class NetworkAgentInfo { 42 public NetworkInfo networkInfo; 43 public Network network; 44 public LinkProperties linkProperties; 45 public NetworkCapabilities networkCapabilities; 46 public final NetworkMonitor networkMonitor; 47 public final NetworkMisc networkMisc; 48 // Indicates if netd has been told to create this Network. Once created the appropriate routing 49 // rules are setup and routes are added so packets can begin flowing over the Network. 50 // NOTE: This is a sticky bit; once set it is never cleared. 51 public boolean created; 52 // Set to true if this Network successfully passed validation or if it did not satisfy the 53 // default NetworkRequest in which case validation will not be attempted. 54 // NOTE: This is a sticky bit; once set it is never cleared even if future validation attempts 55 // fail. 56 public boolean everValidated; 57 58 // The result of the last validation attempt on this network (true if validated, false if not). 59 // This bit exists only because we never unvalidate a network once it's been validated, and that 60 // is because the network scoring and revalidation code does not (may not?) deal properly with 61 // networks becoming unvalidated. 62 // TODO: Fix the network scoring code, remove this, and rename everValidated to validated. 63 public boolean lastValidated; 64 65 // This represents the last score received from the NetworkAgent. 66 private int currentScore; 67 // Penalty applied to scores of Networks that have not been validated. 68 private static final int UNVALIDATED_SCORE_PENALTY = 40; 69 70 // Score for explicitly connected network. 71 private static final int EXPLICITLY_SELECTED_NETWORK_SCORE = 100; 72 73 // The list of NetworkRequests being satisfied by this Network. 74 public final SparseArray<NetworkRequest> networkRequests = new SparseArray<NetworkRequest>(); 75 // The list of NetworkRequests that this Network previously satisfied with the highest 76 // score. A non-empty list indicates that if this Network was validated it is lingered. 77 // NOTE: This list is only used for debugging. 78 public final ArrayList<NetworkRequest> networkLingered = new ArrayList<NetworkRequest>(); 79 80 public final Messenger messenger; 81 public final AsyncChannel asyncChannel; 82 83 // Used by ConnectivityService to keep track of 464xlat. 84 public Nat464Xlat clatd; 85 86 public NetworkAgentInfo(Messenger messenger, AsyncChannel ac, NetworkInfo info, 87 LinkProperties lp, NetworkCapabilities nc, int score, Context context, Handler handler, 88 NetworkMisc misc, NetworkRequest defaultRequest) { 89 this.messenger = messenger; 90 asyncChannel = ac; 91 network = null; 92 networkInfo = info; 93 linkProperties = lp; 94 networkCapabilities = nc; 95 currentScore = score; 96 networkMonitor = new NetworkMonitor(context, handler, this, defaultRequest); 97 networkMisc = misc; 98 created = false; 99 everValidated = false; 100 lastValidated = false; 101 } 102 103 public void addRequest(NetworkRequest networkRequest) { 104 networkRequests.put(networkRequest.requestId, networkRequest); 105 } 106 107 // Does this network satisfy request? 108 public boolean satisfies(NetworkRequest request) { 109 return created && 110 request.networkCapabilities.satisfiedByNetworkCapabilities(networkCapabilities); 111 } 112 113 public boolean isVPN() { 114 return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN); 115 } 116 117 private int getCurrentScore(boolean pretendValidated) { 118 // TODO: We may want to refactor this into a NetworkScore class that takes a base score from 119 // the NetworkAgent and signals from the NetworkAgent and uses those signals to modify the 120 // score. The NetworkScore class would provide a nice place to centralize score constants 121 // so they are not scattered about the transports. 122 123 int score = currentScore; 124 125 if (!everValidated && !pretendValidated) score -= UNVALIDATED_SCORE_PENALTY; 126 if (score < 0) score = 0; 127 128 if (networkMisc.explicitlySelected) score = EXPLICITLY_SELECTED_NETWORK_SCORE; 129 130 return score; 131 } 132 133 // Get the current score for this Network. This may be modified from what the 134 // NetworkAgent sent, as it has modifiers applied to it. 135 public int getCurrentScore() { 136 return getCurrentScore(false); 137 } 138 139 // Get the current score for this Network as if it was validated. This may be modified from 140 // what the NetworkAgent sent, as it has modifiers applied to it. 141 public int getCurrentScoreAsValidated() { 142 return getCurrentScore(true); 143 } 144 145 public void setCurrentScore(int newScore) { 146 currentScore = newScore; 147 } 148 149 public String toString() { 150 return "NetworkAgentInfo{ ni{" + networkInfo + "} network{" + 151 network + "} lp{" + 152 linkProperties + "} nc{" + 153 networkCapabilities + "} Score{" + getCurrentScore() + "} " + 154 "everValidated{" + everValidated + "} lastValidated{" + lastValidated + "} " + 155 "created{" + created + "} " + 156 "explicitlySelected{" + networkMisc.explicitlySelected + "} }"; 157 } 158 159 public String name() { 160 return "NetworkAgentInfo [" + networkInfo.getTypeName() + " (" + 161 networkInfo.getSubtypeName() + ") - " + 162 (network == null ? "null" : network.toString()) + "]"; 163 } 164 } 165