Merge "Cap number of NetworkRequests a UID can make to 100" into nyc-dev am: eaa8684da7
am: 6a8a98c57a
* commit '6a8a98c57a28e42ad2bb4cd3e2f91b484343071f':
Cap number of NetworkRequests a UID can make to 100
Change-Id: I44df1d666f710f938951820227090c4dbbbb7293
This commit is contained in:
@@ -2330,6 +2330,18 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
if (VDBG || (DBG && nri.isRequest())) log("releasing NetworkRequest " + request);
|
if (VDBG || (DBG && nri.isRequest())) log("releasing NetworkRequest " + request);
|
||||||
nri.unlinkDeathRecipient();
|
nri.unlinkDeathRecipient();
|
||||||
mNetworkRequests.remove(request);
|
mNetworkRequests.remove(request);
|
||||||
|
synchronized (mUidToNetworkRequestCount) {
|
||||||
|
int requests = mUidToNetworkRequestCount.get(nri.mUid, 0);
|
||||||
|
if (requests < 1) {
|
||||||
|
Slog.wtf(TAG, "BUG: too small request count " + requests + " for UID " +
|
||||||
|
nri.mUid);
|
||||||
|
} else if (requests == 1) {
|
||||||
|
mUidToNetworkRequestCount.removeAt(
|
||||||
|
mUidToNetworkRequestCount.indexOfKey(nri.mUid));
|
||||||
|
} else {
|
||||||
|
mUidToNetworkRequestCount.put(nri.mUid, requests - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
mNetworkRequestInfoLogs.log("RELEASE " + nri);
|
mNetworkRequestInfoLogs.log("RELEASE " + nri);
|
||||||
if (nri.isRequest()) {
|
if (nri.isRequest()) {
|
||||||
// Find all networks that are satisfying this request and remove the request
|
// Find all networks that are satisfying this request and remove the request
|
||||||
@@ -3677,6 +3689,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests =
|
private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests =
|
||||||
new HashMap<NetworkRequest, NetworkRequestInfo>();
|
new HashMap<NetworkRequest, NetworkRequestInfo>();
|
||||||
|
|
||||||
|
private static final int MAX_NETWORK_REQUESTS_PER_UID = 100;
|
||||||
|
// Map from UID to number of NetworkRequests that UID has filed.
|
||||||
|
@GuardedBy("mUidToNetworkRequestCount")
|
||||||
|
private final SparseIntArray mUidToNetworkRequestCount = new SparseIntArray();
|
||||||
|
|
||||||
private static class NetworkFactoryInfo {
|
private static class NetworkFactoryInfo {
|
||||||
public final String name;
|
public final String name;
|
||||||
public final Messenger messenger;
|
public final Messenger messenger;
|
||||||
@@ -3737,6 +3754,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
mPid = getCallingPid();
|
mPid = getCallingPid();
|
||||||
mUid = getCallingUid();
|
mUid = getCallingUid();
|
||||||
mType = type;
|
mType = type;
|
||||||
|
enforceRequestCountLimit();
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkRequestInfo(Messenger m, NetworkRequest r, IBinder binder, NetworkRequestType type) {
|
NetworkRequestInfo(Messenger m, NetworkRequest r, IBinder binder, NetworkRequestType type) {
|
||||||
@@ -3748,6 +3766,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
mUid = getCallingUid();
|
mUid = getCallingUid();
|
||||||
mType = type;
|
mType = type;
|
||||||
mPendingIntent = null;
|
mPendingIntent = null;
|
||||||
|
enforceRequestCountLimit();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mBinder.linkToDeath(this, 0);
|
mBinder.linkToDeath(this, 0);
|
||||||
@@ -3756,6 +3775,16 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void enforceRequestCountLimit() {
|
||||||
|
synchronized (mUidToNetworkRequestCount) {
|
||||||
|
int networkRequests = mUidToNetworkRequestCount.get(mUid, 0) + 1;
|
||||||
|
if (networkRequests >= MAX_NETWORK_REQUESTS_PER_UID) {
|
||||||
|
throw new IllegalArgumentException("Too many NetworkRequests filed");
|
||||||
|
}
|
||||||
|
mUidToNetworkRequestCount.put(mUid, networkRequests);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private String typeString() {
|
private String typeString() {
|
||||||
switch (mType) {
|
switch (mType) {
|
||||||
case LISTEN: return "Listen";
|
case LISTEN: return "Listen";
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ import com.android.server.connectivity.NetworkMonitor.CaptivePortalProbeResult;
|
|||||||
import com.android.server.net.NetworkPinner;
|
import com.android.server.net.NetworkPinner;
|
||||||
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@@ -1788,4 +1789,96 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
|||||||
waitFor(cv);
|
waitFor(cv);
|
||||||
assertPinnedToWifiWithCellDefault();
|
assertPinnedToWifiWithCellDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SmallTest
|
||||||
|
public void testNetworkRequestMaximum() {
|
||||||
|
final int MAX_REQUESTS = 100;
|
||||||
|
// Test that the limit is enforced when MAX_REQUESTS simultaneous requests are added.
|
||||||
|
NetworkRequest networkRequest = new NetworkRequest.Builder().build();
|
||||||
|
ArrayList<NetworkCallback> networkCallbacks = new ArrayList<NetworkCallback>();
|
||||||
|
try {
|
||||||
|
for (int i = 0; i < MAX_REQUESTS; i++) {
|
||||||
|
NetworkCallback networkCallback = new NetworkCallback();
|
||||||
|
mCm.requestNetwork(networkRequest, networkCallback);
|
||||||
|
networkCallbacks.add(networkCallback);
|
||||||
|
}
|
||||||
|
fail("Registering " + MAX_REQUESTS + " NetworkRequests did not throw exception");
|
||||||
|
} catch (IllegalArgumentException expected) {}
|
||||||
|
for (NetworkCallback networkCallback : networkCallbacks) {
|
||||||
|
mCm.unregisterNetworkCallback(networkCallback);
|
||||||
|
}
|
||||||
|
networkCallbacks.clear();
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (int i = 0; i < MAX_REQUESTS; i++) {
|
||||||
|
NetworkCallback networkCallback = new NetworkCallback();
|
||||||
|
mCm.registerNetworkCallback(networkRequest, networkCallback);
|
||||||
|
networkCallbacks.add(networkCallback);
|
||||||
|
}
|
||||||
|
fail("Registering " + MAX_REQUESTS + " NetworkCallbacks did not throw exception");
|
||||||
|
} catch (IllegalArgumentException expected) {}
|
||||||
|
for (NetworkCallback networkCallback : networkCallbacks) {
|
||||||
|
mCm.unregisterNetworkCallback(networkCallback);
|
||||||
|
}
|
||||||
|
networkCallbacks.clear();
|
||||||
|
|
||||||
|
ArrayList<PendingIntent> pendingIntents = new ArrayList<PendingIntent>();
|
||||||
|
try {
|
||||||
|
for (int i = 0; i < MAX_REQUESTS + 1; i++) {
|
||||||
|
PendingIntent pendingIntent =
|
||||||
|
PendingIntent.getBroadcast(mContext, 0, new Intent("a" + i), 0);
|
||||||
|
mCm.requestNetwork(networkRequest, pendingIntent);
|
||||||
|
pendingIntents.add(pendingIntent);
|
||||||
|
}
|
||||||
|
fail("Registering " + MAX_REQUESTS +
|
||||||
|
" PendingIntent NetworkRequests did not throw exception");
|
||||||
|
} catch (IllegalArgumentException expected) {}
|
||||||
|
for (PendingIntent pendingIntent : pendingIntents) {
|
||||||
|
mCm.unregisterNetworkCallback(pendingIntent);
|
||||||
|
}
|
||||||
|
pendingIntents.clear();
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (int i = 0; i < MAX_REQUESTS + 1; i++) {
|
||||||
|
PendingIntent pendingIntent =
|
||||||
|
PendingIntent.getBroadcast(mContext, 0, new Intent("a" + i), 0);
|
||||||
|
mCm.registerNetworkCallback(networkRequest, pendingIntent);
|
||||||
|
pendingIntents.add(pendingIntent);
|
||||||
|
}
|
||||||
|
fail("Registering " + MAX_REQUESTS +
|
||||||
|
" PendingIntent NetworkCallbacks did not throw exception");
|
||||||
|
} catch (IllegalArgumentException expected) {}
|
||||||
|
for (PendingIntent pendingIntent : pendingIntents) {
|
||||||
|
mCm.unregisterNetworkCallback(pendingIntent);
|
||||||
|
}
|
||||||
|
pendingIntents.clear();
|
||||||
|
mService.waitForIdle(5000);
|
||||||
|
|
||||||
|
// Test that the limit is not hit when MAX_REQUESTS requests are added and removed.
|
||||||
|
for (int i = 0; i < MAX_REQUESTS; i++) {
|
||||||
|
NetworkCallback networkCallback = new NetworkCallback();
|
||||||
|
mCm.requestNetwork(networkRequest, networkCallback);
|
||||||
|
mCm.unregisterNetworkCallback(networkCallback);
|
||||||
|
}
|
||||||
|
mService.waitForIdle();
|
||||||
|
for (int i = 0; i < MAX_REQUESTS; i++) {
|
||||||
|
NetworkCallback networkCallback = new NetworkCallback();
|
||||||
|
mCm.registerNetworkCallback(networkRequest, networkCallback);
|
||||||
|
mCm.unregisterNetworkCallback(networkCallback);
|
||||||
|
}
|
||||||
|
mService.waitForIdle();
|
||||||
|
for (int i = 0; i < MAX_REQUESTS; i++) {
|
||||||
|
PendingIntent pendingIntent =
|
||||||
|
PendingIntent.getBroadcast(mContext, 0, new Intent("b" + i), 0);
|
||||||
|
mCm.requestNetwork(networkRequest, pendingIntent);
|
||||||
|
mCm.unregisterNetworkCallback(pendingIntent);
|
||||||
|
}
|
||||||
|
mService.waitForIdle();
|
||||||
|
for (int i = 0; i < MAX_REQUESTS; i++) {
|
||||||
|
PendingIntent pendingIntent =
|
||||||
|
PendingIntent.getBroadcast(mContext, 0, new Intent("c" + i), 0);
|
||||||
|
mCm.registerNetworkCallback(networkRequest, pendingIntent);
|
||||||
|
mCm.unregisterNetworkCallback(pendingIntent);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user