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 
NetworkAgentInfo(Messenger messenger, AsyncChannel ac, NetworkInfo info, LinkProperties lp, NetworkCapabilities nc, int score, Context context, Handler handler, NetworkMisc misc, NetworkRequest defaultRequest)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 
addRequest(NetworkRequest networkRequest)103     public void addRequest(NetworkRequest networkRequest) {
104         networkRequests.put(networkRequest.requestId, networkRequest);
105     }
106 
107     // Does this network satisfy request?
satisfies(NetworkRequest request)108     public boolean satisfies(NetworkRequest request) {
109         return created &&
110                 request.networkCapabilities.satisfiedByNetworkCapabilities(networkCapabilities);
111     }
112 
isVPN()113     public boolean isVPN() {
114         return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN);
115     }
116 
getCurrentScore(boolean pretendValidated)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.
getCurrentScore()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.
getCurrentScoreAsValidated()141     public int getCurrentScoreAsValidated() {
142         return getCurrentScore(true);
143     }
144 
setCurrentScore(int newScore)145     public void setCurrentScore(int newScore) {
146         currentScore = newScore;
147     }
148 
toString()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 
name()159     public String name() {
160         return "NetworkAgentInfo [" + networkInfo.getTypeName() + " (" +
161                 networkInfo.getSubtypeName() + ") - " +
162                 (network == null ? "null" : network.toString()) + "]";
163     }
164 }
165