Home | History | Annotate | Download | only in connectivity
      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