1 /* 2 * Copyright (C) 2007 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; 18 19 import static android.Manifest.permission.CONNECTIVITY_INTERNAL; 20 import static android.Manifest.permission.NETWORK_SETTINGS; 21 import static android.Manifest.permission.OBSERVE_NETWORK_POLICY; 22 import static android.Manifest.permission.SHUTDOWN; 23 import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE; 24 import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY; 25 import static android.net.ConnectivityManager.FIREWALL_CHAIN_POWERSAVE; 26 import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED; 27 import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY; 28 import static android.net.INetd.FIREWALL_ALLOWLIST; 29 import static android.net.INetd.FIREWALL_CHAIN_NONE; 30 import static android.net.INetd.FIREWALL_DENYLIST; 31 import static android.net.INetd.FIREWALL_RULE_ALLOW; 32 import static android.net.INetd.FIREWALL_RULE_DENY; 33 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_DOZABLE; 34 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY; 35 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_POWERSAVE; 36 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_RESTRICTED; 37 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_STANDBY; 38 import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT; 39 40 import static com.android.net.module.util.NetworkStatsUtils.LIMIT_GLOBAL_ALERT; 41 42 import android.annotation.NonNull; 43 import android.app.ActivityManager; 44 import android.content.Context; 45 import android.net.ConnectivityManager; 46 import android.net.INetd; 47 import android.net.INetdUnsolicitedEventListener; 48 import android.net.INetworkManagementEventObserver; 49 import android.net.ITetheringStatsProvider; 50 import android.net.InetAddresses; 51 import android.net.InterfaceConfiguration; 52 import android.net.InterfaceConfigurationParcel; 53 import android.net.IpPrefix; 54 import android.net.LinkAddress; 55 import android.net.NetworkPolicyManager; 56 import android.net.NetworkStack; 57 import android.net.NetworkStats; 58 import android.net.RouteInfo; 59 import android.net.UidRangeParcel; 60 import android.net.util.NetdService; 61 import android.os.BatteryStats; 62 import android.os.Binder; 63 import android.os.Handler; 64 import android.os.IBinder; 65 import android.os.INetworkManagementService; 66 import android.os.Process; 67 import android.os.RemoteCallbackList; 68 import android.os.RemoteException; 69 import android.os.ServiceManager; 70 import android.os.ServiceSpecificException; 71 import android.os.StrictMode; 72 import android.os.SystemClock; 73 import android.os.Trace; 74 import android.text.TextUtils; 75 import android.util.Log; 76 import android.util.Slog; 77 import android.util.SparseBooleanArray; 78 import android.util.SparseIntArray; 79 80 import com.android.internal.annotations.GuardedBy; 81 import com.android.internal.app.IBatteryStats; 82 import com.android.internal.util.DumpUtils; 83 import com.android.internal.util.HexDump; 84 import com.android.internal.util.Preconditions; 85 import com.android.net.module.util.NetdUtils; 86 import com.android.net.module.util.NetdUtils.ModifyOperation; 87 88 import com.google.android.collect.Maps; 89 90 import java.io.BufferedReader; 91 import java.io.DataInputStream; 92 import java.io.FileDescriptor; 93 import java.io.FileInputStream; 94 import java.io.IOException; 95 import java.io.InputStreamReader; 96 import java.io.PrintWriter; 97 import java.net.InetAddress; 98 import java.net.InterfaceAddress; 99 import java.util.ArrayList; 100 import java.util.Arrays; 101 import java.util.HashMap; 102 import java.util.List; 103 import java.util.Map; 104 import java.util.Objects; 105 106 /** 107 * @hide 108 */ 109 public class NetworkManagementService extends INetworkManagementService.Stub { 110 111 /** 112 * Helper class that encapsulates NetworkManagementService dependencies and makes them 113 * easier to mock in unit tests. 114 */ 115 static class Dependencies { getService(String name)116 public IBinder getService(String name) { 117 return ServiceManager.getService(name); 118 } registerLocalService(NetworkManagementInternal nmi)119 public void registerLocalService(NetworkManagementInternal nmi) { 120 LocalServices.addService(NetworkManagementInternal.class, nmi); 121 } getNetd()122 public INetd getNetd() { 123 return NetdService.get(); 124 } 125 getCallingUid()126 public int getCallingUid() { 127 return Binder.getCallingUid(); 128 } 129 } 130 131 private static final String TAG = "NetworkManagement"; 132 private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG); 133 134 private static final int MAX_UID_RANGES_PER_COMMAND = 10; 135 136 static final int DAEMON_MSG_MOBILE_CONN_REAL_TIME_INFO = 1; 137 138 static final boolean MODIFY_OPERATION_ADD = true; 139 static final boolean MODIFY_OPERATION_REMOVE = false; 140 141 /** 142 * Binder context for this service 143 */ 144 private final Context mContext; 145 146 private final Handler mDaemonHandler; 147 148 private final Dependencies mDeps; 149 150 private INetd mNetdService; 151 152 private final NetdUnsolicitedEventListener mNetdUnsolicitedEventListener; 153 154 private IBatteryStats mBatteryStats; 155 156 private final RemoteCallbackList<INetworkManagementEventObserver> mObservers = 157 new RemoteCallbackList<>(); 158 159 @GuardedBy("mTetheringStatsProviders") 160 private final HashMap<ITetheringStatsProvider, String> 161 mTetheringStatsProviders = Maps.newHashMap(); 162 163 /** 164 * If both locks need to be held, then they should be obtained in the order: 165 * first {@link #mQuotaLock} and then {@link #mRulesLock}. 166 */ 167 private final Object mQuotaLock = new Object(); 168 private final Object mRulesLock = new Object(); 169 170 /** Set of interfaces with active quotas. */ 171 @GuardedBy("mQuotaLock") 172 private HashMap<String, Long> mActiveQuotas = Maps.newHashMap(); 173 /** Set of interfaces with active alerts. */ 174 @GuardedBy("mQuotaLock") 175 private HashMap<String, Long> mActiveAlerts = Maps.newHashMap(); 176 /** Set of UIDs denied on metered networks. */ 177 @GuardedBy("mRulesLock") 178 private SparseBooleanArray mUidRejectOnMetered = new SparseBooleanArray(); 179 /** Set of UIDs allowed on metered networks. */ 180 @GuardedBy("mRulesLock") 181 private SparseBooleanArray mUidAllowOnMetered = new SparseBooleanArray(); 182 /** Set of UIDs with cleartext penalties. */ 183 @GuardedBy("mQuotaLock") 184 private SparseIntArray mUidCleartextPolicy = new SparseIntArray(); 185 /** Set of UIDs that are to be blocked/allowed by firewall controller. */ 186 @GuardedBy("mRulesLock") 187 private SparseIntArray mUidFirewallRules = new SparseIntArray(); 188 /** 189 * Set of UIDs that are to be blocked/allowed by firewall controller. This set of Ids matches 190 * to application idles. 191 */ 192 @GuardedBy("mRulesLock") 193 private SparseIntArray mUidFirewallStandbyRules = new SparseIntArray(); 194 /** 195 * Set of UIDs that are to be blocked/allowed by firewall controller. This set of Ids matches 196 * to device idles. 197 */ 198 @GuardedBy("mRulesLock") 199 private SparseIntArray mUidFirewallDozableRules = new SparseIntArray(); 200 /** 201 * Set of UIDs that are to be blocked/allowed by firewall controller. This set of Ids matches 202 * to device on power-save mode. 203 */ 204 @GuardedBy("mRulesLock") 205 private SparseIntArray mUidFirewallPowerSaveRules = new SparseIntArray(); 206 /** 207 * Contains the per-UID firewall rules that are used when Restricted Networking Mode is enabled. 208 */ 209 @GuardedBy("mRulesLock") 210 private SparseIntArray mUidFirewallRestrictedRules = new SparseIntArray(); 211 /** 212 * Contains the per-UID firewall rules that are used when Low Power Standby is enabled. 213 */ 214 @GuardedBy("mRulesLock") 215 private SparseIntArray mUidFirewallLowPowerStandbyRules = new SparseIntArray(); 216 /** Set of states for the child firewall chains. True if the chain is active. */ 217 @GuardedBy("mRulesLock") 218 final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray(); 219 220 @GuardedBy("mQuotaLock") 221 private volatile boolean mDataSaverMode; 222 223 private volatile boolean mFirewallEnabled; 224 private volatile boolean mStrictEnabled; 225 226 /** 227 * Constructs a new NetworkManagementService instance 228 * 229 * @param context Binder context for this service 230 */ NetworkManagementService( Context context, Dependencies deps)231 private NetworkManagementService( 232 Context context, Dependencies deps) { 233 mContext = context; 234 mDeps = deps; 235 236 mDaemonHandler = new Handler(FgThread.get().getLooper()); 237 238 mNetdUnsolicitedEventListener = new NetdUnsolicitedEventListener(); 239 240 mDeps.registerLocalService(new LocalService()); 241 242 synchronized (mTetheringStatsProviders) { 243 mTetheringStatsProviders.put(new NetdTetheringStatsProvider(), "netd"); 244 } 245 } 246 NetworkManagementService()247 private NetworkManagementService() { 248 mContext = null; 249 mDaemonHandler = null; 250 mDeps = null; 251 mNetdUnsolicitedEventListener = null; 252 } 253 create(Context context, Dependencies deps)254 static NetworkManagementService create(Context context, Dependencies deps) 255 throws InterruptedException { 256 final NetworkManagementService service = 257 new NetworkManagementService(context, deps); 258 if (DBG) Slog.d(TAG, "Creating NetworkManagementService"); 259 if (DBG) Slog.d(TAG, "Connecting native netd service"); 260 service.connectNativeNetdService(); 261 if (DBG) Slog.d(TAG, "Connected"); 262 return service; 263 } 264 create(Context context)265 public static NetworkManagementService create(Context context) throws InterruptedException { 266 return create(context, new Dependencies()); 267 } 268 systemReady()269 public void systemReady() { 270 if (DBG) { 271 final long start = System.currentTimeMillis(); 272 prepareNativeDaemon(); 273 final long delta = System.currentTimeMillis() - start; 274 Slog.d(TAG, "Prepared in " + delta + "ms"); 275 return; 276 } else { 277 prepareNativeDaemon(); 278 } 279 } 280 getBatteryStats()281 private IBatteryStats getBatteryStats() { 282 synchronized (this) { 283 if (mBatteryStats != null) { 284 return mBatteryStats; 285 } 286 mBatteryStats = 287 IBatteryStats.Stub.asInterface(mDeps.getService(BatteryStats.SERVICE_NAME)); 288 return mBatteryStats; 289 } 290 } 291 292 @Override registerObserver(INetworkManagementEventObserver observer)293 public void registerObserver(INetworkManagementEventObserver observer) { 294 NetworkStack.checkNetworkStackPermission(mContext); 295 mObservers.register(observer); 296 } 297 298 @Override unregisterObserver(INetworkManagementEventObserver observer)299 public void unregisterObserver(INetworkManagementEventObserver observer) { 300 NetworkStack.checkNetworkStackPermission(mContext); 301 mObservers.unregister(observer); 302 } 303 304 @FunctionalInterface 305 private interface NetworkManagementEventCallback { sendCallback(INetworkManagementEventObserver o)306 public void sendCallback(INetworkManagementEventObserver o) throws RemoteException; 307 } 308 invokeForAllObservers(NetworkManagementEventCallback eventCallback)309 private void invokeForAllObservers(NetworkManagementEventCallback eventCallback) { 310 final int length = mObservers.beginBroadcast(); 311 try { 312 for (int i = 0; i < length; i++) { 313 try { 314 eventCallback.sendCallback(mObservers.getBroadcastItem(i)); 315 } catch (RemoteException | RuntimeException e) { 316 } 317 } 318 } finally { 319 mObservers.finishBroadcast(); 320 } 321 } 322 323 /** 324 * Notify our observers of an interface status change 325 */ notifyInterfaceStatusChanged(String iface, boolean up)326 private void notifyInterfaceStatusChanged(String iface, boolean up) { 327 invokeForAllObservers(o -> o.interfaceStatusChanged(iface, up)); 328 } 329 330 /** 331 * Notify our observers of an interface link state change 332 * (typically, an Ethernet cable has been plugged-in or unplugged). 333 */ notifyInterfaceLinkStateChanged(String iface, boolean up)334 private void notifyInterfaceLinkStateChanged(String iface, boolean up) { 335 invokeForAllObservers(o -> o.interfaceLinkStateChanged(iface, up)); 336 } 337 338 /** 339 * Notify our observers of an interface addition. 340 */ notifyInterfaceAdded(String iface)341 private void notifyInterfaceAdded(String iface) { 342 invokeForAllObservers(o -> o.interfaceAdded(iface)); 343 } 344 345 /** 346 * Notify our observers of an interface removal. 347 */ notifyInterfaceRemoved(String iface)348 private void notifyInterfaceRemoved(String iface) { 349 // netd already clears out quota and alerts for removed ifaces; update 350 // our validity-checking state. 351 mActiveAlerts.remove(iface); 352 mActiveQuotas.remove(iface); 353 invokeForAllObservers(o -> o.interfaceRemoved(iface)); 354 } 355 356 /** 357 * Notify our observers of a limit reached. 358 */ notifyLimitReached(String limitName, String iface)359 private void notifyLimitReached(String limitName, String iface) { 360 invokeForAllObservers(o -> o.limitReached(limitName, iface)); 361 } 362 363 /** 364 * Notify our observers of a change in the data activity state of the interface 365 */ notifyInterfaceClassActivity(int type, boolean isActive, long tsNanos, int uid)366 private void notifyInterfaceClassActivity(int type, boolean isActive, long tsNanos, 367 int uid) { 368 invokeForAllObservers(o -> o.interfaceClassDataActivityChanged( 369 type, isActive, tsNanos, uid)); 370 } 371 372 @Override registerTetheringStatsProvider(ITetheringStatsProvider provider, String name)373 public void registerTetheringStatsProvider(ITetheringStatsProvider provider, String name) { 374 NetworkStack.checkNetworkStackPermission(mContext); 375 Objects.requireNonNull(provider); 376 synchronized(mTetheringStatsProviders) { 377 mTetheringStatsProviders.put(provider, name); 378 } 379 } 380 381 @Override unregisterTetheringStatsProvider(ITetheringStatsProvider provider)382 public void unregisterTetheringStatsProvider(ITetheringStatsProvider provider) { 383 NetworkStack.checkNetworkStackPermission(mContext); 384 synchronized(mTetheringStatsProviders) { 385 mTetheringStatsProviders.remove(provider); 386 } 387 } 388 389 @Override tetherLimitReached(ITetheringStatsProvider provider)390 public void tetherLimitReached(ITetheringStatsProvider provider) { 391 NetworkStack.checkNetworkStackPermission(mContext); 392 synchronized(mTetheringStatsProviders) { 393 if (!mTetheringStatsProviders.containsKey(provider)) { 394 return; 395 } 396 // No current code examines the interface parameter in a global alert. Just pass null. 397 mDaemonHandler.post(() -> notifyLimitReached(LIMIT_GLOBAL_ALERT, null)); 398 } 399 } 400 401 // Sync the state of the given chain with the native daemon. syncFirewallChainLocked(int chain, String name)402 private void syncFirewallChainLocked(int chain, String name) { 403 SparseIntArray rules; 404 synchronized (mRulesLock) { 405 final SparseIntArray uidFirewallRules = getUidFirewallRulesLR(chain); 406 // Make a copy of the current rules, and then clear them. This is because 407 // setFirewallUidRuleInternal only pushes down rules to the native daemon if they 408 // are different from the current rules stored in the mUidFirewall*Rules array for 409 // the specified chain. If we don't clear the rules, setFirewallUidRuleInternal 410 // will do nothing. 411 rules = uidFirewallRules.clone(); 412 uidFirewallRules.clear(); 413 } 414 if (rules.size() > 0) { 415 // Now push the rules. setFirewallUidRuleInternal will push each of these down to the 416 // native daemon, and also add them to the mUidFirewall*Rules array for the specified 417 // chain. 418 if (DBG) Slog.d(TAG, "Pushing " + rules.size() + " active firewall " 419 + name + "UID rules"); 420 for (int i = 0; i < rules.size(); i++) { 421 setFirewallUidRuleLocked(chain, rules.keyAt(i), rules.valueAt(i)); 422 } 423 } 424 } 425 connectNativeNetdService()426 private void connectNativeNetdService() { 427 mNetdService = mDeps.getNetd(); 428 try { 429 mNetdService.registerUnsolicitedEventListener(mNetdUnsolicitedEventListener); 430 if (DBG) Slog.d(TAG, "Register unsolicited event listener"); 431 } catch (RemoteException | ServiceSpecificException e) { 432 Slog.e(TAG, "Failed to set Netd unsolicited event listener " + e); 433 } 434 } 435 436 /** 437 * Prepare native daemon once connected, enabling modules and pushing any 438 * existing in-memory rules. 439 */ prepareNativeDaemon()440 private void prepareNativeDaemon() { 441 442 // push any existing quota or UID rules 443 synchronized (mQuotaLock) { 444 445 mStrictEnabled = true; 446 447 setDataSaverModeEnabled(mDataSaverMode); 448 449 int size = mActiveQuotas.size(); 450 if (size > 0) { 451 if (DBG) Slog.d(TAG, "Pushing " + size + " active quota rules"); 452 final HashMap<String, Long> activeQuotas = mActiveQuotas; 453 mActiveQuotas = Maps.newHashMap(); 454 for (Map.Entry<String, Long> entry : activeQuotas.entrySet()) { 455 setInterfaceQuota(entry.getKey(), entry.getValue()); 456 } 457 } 458 459 size = mActiveAlerts.size(); 460 if (size > 0) { 461 if (DBG) Slog.d(TAG, "Pushing " + size + " active alert rules"); 462 final HashMap<String, Long> activeAlerts = mActiveAlerts; 463 mActiveAlerts = Maps.newHashMap(); 464 for (Map.Entry<String, Long> entry : activeAlerts.entrySet()) { 465 setInterfaceAlert(entry.getKey(), entry.getValue()); 466 } 467 } 468 469 SparseBooleanArray uidRejectOnQuota = null; 470 SparseBooleanArray uidAcceptOnQuota = null; 471 synchronized (mRulesLock) { 472 size = mUidRejectOnMetered.size(); 473 if (size > 0) { 474 if (DBG) Slog.d(TAG, "Pushing " + size + " UIDs to metered denylist rules"); 475 uidRejectOnQuota = mUidRejectOnMetered; 476 mUidRejectOnMetered = new SparseBooleanArray(); 477 } 478 479 size = mUidAllowOnMetered.size(); 480 if (size > 0) { 481 if (DBG) Slog.d(TAG, "Pushing " + size + " UIDs to metered allowlist rules"); 482 uidAcceptOnQuota = mUidAllowOnMetered; 483 mUidAllowOnMetered = new SparseBooleanArray(); 484 } 485 } 486 if (uidRejectOnQuota != null) { 487 for (int i = 0; i < uidRejectOnQuota.size(); i++) { 488 setUidOnMeteredNetworkDenylist(uidRejectOnQuota.keyAt(i), 489 uidRejectOnQuota.valueAt(i)); 490 } 491 } 492 if (uidAcceptOnQuota != null) { 493 for (int i = 0; i < uidAcceptOnQuota.size(); i++) { 494 setUidOnMeteredNetworkAllowlist(uidAcceptOnQuota.keyAt(i), 495 uidAcceptOnQuota.valueAt(i)); 496 } 497 } 498 499 size = mUidCleartextPolicy.size(); 500 if (size > 0) { 501 if (DBG) Slog.d(TAG, "Pushing " + size + " active UID cleartext policies"); 502 final SparseIntArray local = mUidCleartextPolicy; 503 mUidCleartextPolicy = new SparseIntArray(); 504 for (int i = 0; i < local.size(); i++) { 505 setUidCleartextNetworkPolicy(local.keyAt(i), local.valueAt(i)); 506 } 507 } 508 509 setFirewallEnabled(mFirewallEnabled); 510 511 syncFirewallChainLocked(FIREWALL_CHAIN_NONE, ""); 512 syncFirewallChainLocked(FIREWALL_CHAIN_STANDBY, "standby "); 513 syncFirewallChainLocked(FIREWALL_CHAIN_DOZABLE, "dozable "); 514 syncFirewallChainLocked(FIREWALL_CHAIN_POWERSAVE, "powersave "); 515 syncFirewallChainLocked(FIREWALL_CHAIN_RESTRICTED, "restricted "); 516 syncFirewallChainLocked(FIREWALL_CHAIN_LOW_POWER_STANDBY, "low power standby "); 517 518 final int[] chains = { 519 FIREWALL_CHAIN_STANDBY, 520 FIREWALL_CHAIN_DOZABLE, 521 FIREWALL_CHAIN_POWERSAVE, 522 FIREWALL_CHAIN_RESTRICTED, 523 FIREWALL_CHAIN_LOW_POWER_STANDBY 524 }; 525 526 for (int chain : chains) { 527 if (getFirewallChainState(chain)) { 528 setFirewallChainEnabled(chain, true); 529 } 530 } 531 } 532 533 534 try { 535 getBatteryStats().noteNetworkStatsEnabled(); 536 } catch (RemoteException e) { 537 } 538 539 } 540 541 /** 542 * Notify our observers of a new or updated interface address. 543 */ notifyAddressUpdated(String iface, LinkAddress address)544 private void notifyAddressUpdated(String iface, LinkAddress address) { 545 invokeForAllObservers(o -> o.addressUpdated(iface, address)); 546 } 547 548 /** 549 * Notify our observers of a deleted interface address. 550 */ notifyAddressRemoved(String iface, LinkAddress address)551 private void notifyAddressRemoved(String iface, LinkAddress address) { 552 invokeForAllObservers(o -> o.addressRemoved(iface, address)); 553 } 554 555 /** 556 * Notify our observers of DNS server information received. 557 */ notifyInterfaceDnsServerInfo(String iface, long lifetime, String[] addresses)558 private void notifyInterfaceDnsServerInfo(String iface, long lifetime, String[] addresses) { 559 invokeForAllObservers(o -> o.interfaceDnsServerInfo(iface, lifetime, addresses)); 560 } 561 562 /** 563 * Notify our observers of a route change. 564 */ notifyRouteChange(boolean updated, RouteInfo route)565 private void notifyRouteChange(boolean updated, RouteInfo route) { 566 if (updated) { 567 invokeForAllObservers(o -> o.routeUpdated(route)); 568 } else { 569 invokeForAllObservers(o -> o.routeRemoved(route)); 570 } 571 } 572 573 private class NetdUnsolicitedEventListener extends INetdUnsolicitedEventListener.Stub { 574 @Override onInterfaceClassActivityChanged(boolean isActive, int label, long timestamp, int uid)575 public void onInterfaceClassActivityChanged(boolean isActive, 576 int label, long timestamp, int uid) throws RemoteException { 577 final long timestampNanos; 578 if (timestamp <= 0) { 579 timestampNanos = SystemClock.elapsedRealtimeNanos(); 580 } else { 581 timestampNanos = timestamp; 582 } 583 mDaemonHandler.post(() -> 584 notifyInterfaceClassActivity(label, isActive, timestampNanos, uid)); 585 } 586 587 @Override onQuotaLimitReached(String alertName, String ifName)588 public void onQuotaLimitReached(String alertName, String ifName) 589 throws RemoteException { 590 mDaemonHandler.post(() -> notifyLimitReached(alertName, ifName)); 591 } 592 593 @Override onInterfaceDnsServerInfo(String ifName, long lifetime, String[] servers)594 public void onInterfaceDnsServerInfo(String ifName, 595 long lifetime, String[] servers) throws RemoteException { 596 mDaemonHandler.post(() -> notifyInterfaceDnsServerInfo(ifName, lifetime, servers)); 597 } 598 599 @Override onInterfaceAddressUpdated(String addr, String ifName, int flags, int scope)600 public void onInterfaceAddressUpdated(String addr, 601 String ifName, int flags, int scope) throws RemoteException { 602 final LinkAddress address = new LinkAddress(addr, flags, scope); 603 mDaemonHandler.post(() -> notifyAddressUpdated(ifName, address)); 604 } 605 606 @Override onInterfaceAddressRemoved(String addr, String ifName, int flags, int scope)607 public void onInterfaceAddressRemoved(String addr, 608 String ifName, int flags, int scope) throws RemoteException { 609 final LinkAddress address = new LinkAddress(addr, flags, scope); 610 mDaemonHandler.post(() -> notifyAddressRemoved(ifName, address)); 611 } 612 613 @Override onInterfaceAdded(String ifName)614 public void onInterfaceAdded(String ifName) throws RemoteException { 615 mDaemonHandler.post(() -> notifyInterfaceAdded(ifName)); 616 } 617 618 @Override onInterfaceRemoved(String ifName)619 public void onInterfaceRemoved(String ifName) throws RemoteException { 620 mDaemonHandler.post(() -> notifyInterfaceRemoved(ifName)); 621 } 622 623 @Override onInterfaceChanged(String ifName, boolean up)624 public void onInterfaceChanged(String ifName, boolean up) 625 throws RemoteException { 626 mDaemonHandler.post(() -> notifyInterfaceStatusChanged(ifName, up)); 627 } 628 629 @Override onInterfaceLinkStateChanged(String ifName, boolean up)630 public void onInterfaceLinkStateChanged(String ifName, boolean up) 631 throws RemoteException { 632 mDaemonHandler.post(() -> notifyInterfaceLinkStateChanged(ifName, up)); 633 } 634 635 @Override onRouteChanged(boolean updated, String route, String gateway, String ifName)636 public void onRouteChanged(boolean updated, 637 String route, String gateway, String ifName) throws RemoteException { 638 final RouteInfo processRoute = new RouteInfo(new IpPrefix(route), 639 ("".equals(gateway)) ? null : InetAddresses.parseNumericAddress(gateway), 640 ifName, RouteInfo.RTN_UNICAST); 641 mDaemonHandler.post(() -> notifyRouteChange(updated, processRoute)); 642 } 643 644 @Override onStrictCleartextDetected(int uid, String hex)645 public void onStrictCleartextDetected(int uid, String hex) throws RemoteException { 646 // Don't need to post to mDaemonHandler because the only thing 647 // that notifyCleartextNetwork does is post to a handler 648 ActivityManager.getService().notifyCleartextNetwork(uid, 649 HexDump.hexStringToByteArray(hex)); 650 } 651 652 @Override getInterfaceVersion()653 public int getInterfaceVersion() { 654 return INetdUnsolicitedEventListener.VERSION; 655 } 656 657 @Override getInterfaceHash()658 public String getInterfaceHash() { 659 return INetdUnsolicitedEventListener.HASH; 660 } 661 } 662 663 // 664 // INetworkManagementService members 665 // 666 @Override listInterfaces()667 public String[] listInterfaces() { 668 // TODO: Remove CONNECTIVITY_INTERNAL after bluetooth tethering has no longer called these 669 // APIs. 670 NetworkStack.checkNetworkStackPermissionOr(mContext, CONNECTIVITY_INTERNAL); 671 try { 672 return mNetdService.interfaceGetList(); 673 } catch (RemoteException | ServiceSpecificException e) { 674 throw new IllegalStateException(e); 675 } 676 } 677 678 /** 679 * Convert InterfaceConfiguration to InterfaceConfigurationParcel with given ifname. 680 */ toStableParcel(InterfaceConfiguration cfg, String iface)681 private static InterfaceConfigurationParcel toStableParcel(InterfaceConfiguration cfg, 682 String iface) { 683 InterfaceConfigurationParcel cfgParcel = new InterfaceConfigurationParcel(); 684 cfgParcel.ifName = iface; 685 String hwAddr = cfg.getHardwareAddress(); 686 if (!TextUtils.isEmpty(hwAddr)) { 687 cfgParcel.hwAddr = hwAddr; 688 } else { 689 cfgParcel.hwAddr = ""; 690 } 691 cfgParcel.ipv4Addr = cfg.getLinkAddress().getAddress().getHostAddress(); 692 cfgParcel.prefixLength = cfg.getLinkAddress().getPrefixLength(); 693 ArrayList<String> flags = new ArrayList<>(); 694 for (String flag : cfg.getFlags()) { 695 flags.add(flag); 696 } 697 cfgParcel.flags = flags.toArray(new String[0]); 698 699 return cfgParcel; 700 } 701 702 /** 703 * Construct InterfaceConfiguration from InterfaceConfigurationParcel. 704 */ fromStableParcel(InterfaceConfigurationParcel p)705 public static InterfaceConfiguration fromStableParcel(InterfaceConfigurationParcel p) { 706 InterfaceConfiguration cfg = new InterfaceConfiguration(); 707 cfg.setHardwareAddress(p.hwAddr); 708 709 final InetAddress addr = InetAddresses.parseNumericAddress(p.ipv4Addr); 710 cfg.setLinkAddress(new LinkAddress(addr, p.prefixLength)); 711 for (String flag : p.flags) { 712 cfg.setFlag(flag); 713 } 714 715 return cfg; 716 } 717 718 @Override getInterfaceConfig(String iface)719 public InterfaceConfiguration getInterfaceConfig(String iface) { 720 // TODO: Remove CONNECTIVITY_INTERNAL after bluetooth tethering has no longer called these 721 // APIs. 722 NetworkStack.checkNetworkStackPermissionOr(mContext, CONNECTIVITY_INTERNAL); 723 final InterfaceConfigurationParcel result; 724 try { 725 result = mNetdService.interfaceGetCfg(iface); 726 } catch (RemoteException | ServiceSpecificException e) { 727 throw new IllegalStateException(e); 728 } 729 730 try { 731 final InterfaceConfiguration cfg = fromStableParcel(result); 732 return cfg; 733 } catch (IllegalArgumentException iae) { 734 throw new IllegalStateException("Invalid InterfaceConfigurationParcel", iae); 735 } 736 } 737 738 @Override setInterfaceConfig(String iface, InterfaceConfiguration cfg)739 public void setInterfaceConfig(String iface, InterfaceConfiguration cfg) { 740 // TODO: Remove CONNECTIVITY_INTERNAL after bluetooth tethering has no longer called these 741 // APIs. 742 NetworkStack.checkNetworkStackPermissionOr(mContext, CONNECTIVITY_INTERNAL); 743 LinkAddress linkAddr = cfg.getLinkAddress(); 744 if (linkAddr == null || linkAddr.getAddress() == null) { 745 throw new IllegalStateException("Null LinkAddress given"); 746 } 747 748 final InterfaceConfigurationParcel cfgParcel = toStableParcel(cfg, iface); 749 750 try { 751 mNetdService.interfaceSetCfg(cfgParcel); 752 } catch (RemoteException | ServiceSpecificException e) { 753 throw new IllegalStateException(e); 754 } 755 } 756 757 @Override setInterfaceDown(String iface)758 public void setInterfaceDown(String iface) { 759 NetworkStack.checkNetworkStackPermission(mContext); 760 final InterfaceConfiguration ifcg = getInterfaceConfig(iface); 761 ifcg.setInterfaceDown(); 762 setInterfaceConfig(iface, ifcg); 763 } 764 765 @Override setInterfaceUp(String iface)766 public void setInterfaceUp(String iface) { 767 NetworkStack.checkNetworkStackPermission(mContext); 768 final InterfaceConfiguration ifcg = getInterfaceConfig(iface); 769 ifcg.setInterfaceUp(); 770 setInterfaceConfig(iface, ifcg); 771 } 772 773 @Override setInterfaceIpv6PrivacyExtensions(String iface, boolean enable)774 public void setInterfaceIpv6PrivacyExtensions(String iface, boolean enable) { 775 NetworkStack.checkNetworkStackPermission(mContext); 776 try { 777 mNetdService.interfaceSetIPv6PrivacyExtensions(iface, enable); 778 } catch (RemoteException | ServiceSpecificException e) { 779 throw new IllegalStateException(e); 780 } 781 } 782 783 /* TODO: This is right now a IPv4 only function. Works for wifi which loses its 784 IPv6 addresses on interface down, but we need to do full clean up here */ 785 @Override clearInterfaceAddresses(String iface)786 public void clearInterfaceAddresses(String iface) { 787 NetworkStack.checkNetworkStackPermission(mContext); 788 try { 789 mNetdService.interfaceClearAddrs(iface); 790 } catch (RemoteException | ServiceSpecificException e) { 791 throw new IllegalStateException(e); 792 } 793 } 794 795 @Override enableIpv6(String iface)796 public void enableIpv6(String iface) { 797 NetworkStack.checkNetworkStackPermission(mContext); 798 try { 799 mNetdService.interfaceSetEnableIPv6(iface, true); 800 } catch (RemoteException | ServiceSpecificException e) { 801 throw new IllegalStateException(e); 802 } 803 } 804 805 @Override setIPv6AddrGenMode(String iface, int mode)806 public void setIPv6AddrGenMode(String iface, int mode) throws ServiceSpecificException { 807 NetworkStack.checkNetworkStackPermission(mContext); 808 try { 809 mNetdService.setIPv6AddrGenMode(iface, mode); 810 } catch (RemoteException e) { 811 throw e.rethrowAsRuntimeException(); 812 } 813 } 814 815 @Override disableIpv6(String iface)816 public void disableIpv6(String iface) { 817 NetworkStack.checkNetworkStackPermission(mContext); 818 try { 819 mNetdService.interfaceSetEnableIPv6(iface, false); 820 } catch (RemoteException | ServiceSpecificException e) { 821 throw new IllegalStateException(e); 822 } 823 } 824 825 @Override addRoute(int netId, RouteInfo route)826 public void addRoute(int netId, RouteInfo route) { 827 NetworkStack.checkNetworkStackPermission(mContext); 828 NetdUtils.modifyRoute(mNetdService, ModifyOperation.ADD, netId, route); 829 } 830 831 @Override removeRoute(int netId, RouteInfo route)832 public void removeRoute(int netId, RouteInfo route) { 833 NetworkStack.checkNetworkStackPermission(mContext); 834 NetdUtils.modifyRoute(mNetdService, ModifyOperation.REMOVE, netId, route); 835 } 836 readRouteList(String filename)837 private ArrayList<String> readRouteList(String filename) { 838 FileInputStream fstream = null; 839 ArrayList<String> list = new ArrayList<>(); 840 841 try { 842 fstream = new FileInputStream(filename); 843 DataInputStream in = new DataInputStream(fstream); 844 BufferedReader br = new BufferedReader(new InputStreamReader(in)); 845 String s; 846 847 // throw away the title line 848 849 while (((s = br.readLine()) != null) && (s.length() != 0)) { 850 list.add(s); 851 } 852 } catch (IOException ex) { 853 // return current list, possibly empty 854 } finally { 855 if (fstream != null) { 856 try { 857 fstream.close(); 858 } catch (IOException ex) {} 859 } 860 } 861 862 return list; 863 } 864 865 @Override shutdown()866 public void shutdown() { 867 // TODO: remove from aidl if nobody calls externally 868 mContext.enforceCallingOrSelfPermission(SHUTDOWN, TAG); 869 870 Slog.i(TAG, "Shutting down"); 871 } 872 873 @Override getIpForwardingEnabled()874 public boolean getIpForwardingEnabled() throws IllegalStateException{ 875 NetworkStack.checkNetworkStackPermission(mContext); 876 877 try { 878 final boolean isEnabled = mNetdService.ipfwdEnabled(); 879 return isEnabled; 880 } catch (RemoteException | ServiceSpecificException e) { 881 throw new IllegalStateException(e); 882 } 883 } 884 885 @Override setIpForwardingEnabled(boolean enable)886 public void setIpForwardingEnabled(boolean enable) { 887 NetworkStack.checkNetworkStackPermission(mContext); 888 try { 889 if (enable) { 890 mNetdService.ipfwdEnableForwarding("tethering"); 891 } else { 892 mNetdService.ipfwdDisableForwarding("tethering"); 893 } 894 } catch (RemoteException | ServiceSpecificException e) { 895 throw new IllegalStateException(e); 896 } 897 } 898 899 @Override startTethering(String[] dhcpRange)900 public void startTethering(String[] dhcpRange) { 901 startTetheringWithConfiguration(true, dhcpRange); 902 } 903 904 @Override startTetheringWithConfiguration(boolean usingLegacyDnsProxy, String[] dhcpRange)905 public void startTetheringWithConfiguration(boolean usingLegacyDnsProxy, String[] dhcpRange) { 906 NetworkStack.checkNetworkStackPermission(mContext); 907 try { 908 NetdUtils.tetherStart(mNetdService, usingLegacyDnsProxy, dhcpRange); 909 } catch (RemoteException | ServiceSpecificException e) { 910 throw new IllegalStateException(e); 911 } 912 } 913 914 @Override stopTethering()915 public void stopTethering() { 916 NetworkStack.checkNetworkStackPermission(mContext); 917 try { 918 mNetdService.tetherStop(); 919 } catch (RemoteException | ServiceSpecificException e) { 920 throw new IllegalStateException(e); 921 } 922 } 923 924 @Override isTetheringStarted()925 public boolean isTetheringStarted() { 926 NetworkStack.checkNetworkStackPermission(mContext); 927 928 try { 929 final boolean isEnabled = mNetdService.tetherIsEnabled(); 930 return isEnabled; 931 } catch (RemoteException | ServiceSpecificException e) { 932 throw new IllegalStateException(e); 933 } 934 } 935 936 @Override tetherInterface(String iface)937 public void tetherInterface(String iface) { 938 NetworkStack.checkNetworkStackPermission(mContext); 939 try { 940 final LinkAddress addr = getInterfaceConfig(iface).getLinkAddress(); 941 final IpPrefix dest = new IpPrefix(addr.getAddress(), addr.getPrefixLength()); 942 NetdUtils.tetherInterface(mNetdService, iface, dest); 943 } catch (RemoteException | ServiceSpecificException e) { 944 throw new IllegalStateException(e); 945 } 946 } 947 948 @Override untetherInterface(String iface)949 public void untetherInterface(String iface) { 950 NetworkStack.checkNetworkStackPermission(mContext); 951 try { 952 NetdUtils.untetherInterface(mNetdService, iface); 953 } catch (RemoteException | ServiceSpecificException e) { 954 throw new IllegalStateException(e); 955 } 956 } 957 958 @Override listTetheredInterfaces()959 public String[] listTetheredInterfaces() { 960 NetworkStack.checkNetworkStackPermission(mContext); 961 try { 962 return mNetdService.tetherInterfaceList(); 963 } catch (RemoteException | ServiceSpecificException e) { 964 throw new IllegalStateException(e); 965 } 966 } 967 968 @Override getDnsForwarders()969 public String[] getDnsForwarders() { 970 NetworkStack.checkNetworkStackPermission(mContext); 971 try { 972 return mNetdService.tetherDnsList(); 973 } catch (RemoteException | ServiceSpecificException e) { 974 throw new IllegalStateException(e); 975 } 976 } 977 excludeLinkLocal(List<InterfaceAddress> addresses)978 private List<InterfaceAddress> excludeLinkLocal(List<InterfaceAddress> addresses) { 979 ArrayList<InterfaceAddress> filtered = new ArrayList<>(addresses.size()); 980 for (InterfaceAddress ia : addresses) { 981 if (!ia.getAddress().isLinkLocalAddress()) 982 filtered.add(ia); 983 } 984 return filtered; 985 } 986 modifyInterfaceForward(boolean add, String fromIface, String toIface)987 private void modifyInterfaceForward(boolean add, String fromIface, String toIface) { 988 try { 989 if (add) { 990 mNetdService.ipfwdAddInterfaceForward(fromIface, toIface); 991 } else { 992 mNetdService.ipfwdRemoveInterfaceForward(fromIface, toIface); 993 } 994 } catch (RemoteException | ServiceSpecificException e) { 995 throw new IllegalStateException(e); 996 } 997 } 998 999 @Override startInterfaceForwarding(String fromIface, String toIface)1000 public void startInterfaceForwarding(String fromIface, String toIface) { 1001 NetworkStack.checkNetworkStackPermission(mContext); 1002 modifyInterfaceForward(true, fromIface, toIface); 1003 } 1004 1005 @Override stopInterfaceForwarding(String fromIface, String toIface)1006 public void stopInterfaceForwarding(String fromIface, String toIface) { 1007 NetworkStack.checkNetworkStackPermission(mContext); 1008 modifyInterfaceForward(false, fromIface, toIface); 1009 } 1010 1011 @Override enableNat(String internalInterface, String externalInterface)1012 public void enableNat(String internalInterface, String externalInterface) { 1013 NetworkStack.checkNetworkStackPermission(mContext); 1014 try { 1015 mNetdService.tetherAddForward(internalInterface, externalInterface); 1016 } catch (RemoteException | ServiceSpecificException e) { 1017 throw new IllegalStateException(e); 1018 } 1019 } 1020 1021 @Override disableNat(String internalInterface, String externalInterface)1022 public void disableNat(String internalInterface, String externalInterface) { 1023 NetworkStack.checkNetworkStackPermission(mContext); 1024 try { 1025 mNetdService.tetherRemoveForward(internalInterface, externalInterface); 1026 } catch (RemoteException | ServiceSpecificException e) { 1027 throw new IllegalStateException(e); 1028 } 1029 } 1030 1031 @Override setInterfaceQuota(String iface, long quotaBytes)1032 public void setInterfaceQuota(String iface, long quotaBytes) { 1033 NetworkStack.checkNetworkStackPermission(mContext); 1034 1035 synchronized (mQuotaLock) { 1036 if (mActiveQuotas.containsKey(iface)) { 1037 throw new IllegalStateException("iface " + iface + " already has quota"); 1038 } 1039 1040 try { 1041 // TODO: support quota shared across interfaces 1042 mNetdService.bandwidthSetInterfaceQuota(iface, quotaBytes); 1043 1044 mActiveQuotas.put(iface, quotaBytes); 1045 } catch (RemoteException | ServiceSpecificException e) { 1046 throw new IllegalStateException(e); 1047 } 1048 1049 synchronized (mTetheringStatsProviders) { 1050 for (ITetheringStatsProvider provider : mTetheringStatsProviders.keySet()) { 1051 try { 1052 provider.setInterfaceQuota(iface, quotaBytes); 1053 } catch (RemoteException e) { 1054 Log.e(TAG, "Problem setting tethering data limit on provider " + 1055 mTetheringStatsProviders.get(provider) + ": " + e); 1056 } 1057 } 1058 } 1059 } 1060 } 1061 1062 @Override removeInterfaceQuota(String iface)1063 public void removeInterfaceQuota(String iface) { 1064 NetworkStack.checkNetworkStackPermission(mContext); 1065 1066 synchronized (mQuotaLock) { 1067 if (!mActiveQuotas.containsKey(iface)) { 1068 // TODO: eventually consider throwing 1069 return; 1070 } 1071 1072 mActiveQuotas.remove(iface); 1073 mActiveAlerts.remove(iface); 1074 1075 try { 1076 // TODO: support quota shared across interfaces 1077 mNetdService.bandwidthRemoveInterfaceQuota(iface); 1078 } catch (RemoteException | ServiceSpecificException e) { 1079 throw new IllegalStateException(e); 1080 } 1081 1082 synchronized (mTetheringStatsProviders) { 1083 for (ITetheringStatsProvider provider : mTetheringStatsProviders.keySet()) { 1084 try { 1085 provider.setInterfaceQuota(iface, ITetheringStatsProvider.QUOTA_UNLIMITED); 1086 } catch (RemoteException e) { 1087 Log.e(TAG, "Problem removing tethering data limit on provider " + 1088 mTetheringStatsProviders.get(provider) + ": " + e); 1089 } 1090 } 1091 } 1092 } 1093 } 1094 1095 @Override setInterfaceAlert(String iface, long alertBytes)1096 public void setInterfaceAlert(String iface, long alertBytes) { 1097 NetworkStack.checkNetworkStackPermission(mContext); 1098 1099 // quick validity check 1100 if (!mActiveQuotas.containsKey(iface)) { 1101 throw new IllegalStateException("setting alert requires existing quota on iface"); 1102 } 1103 1104 synchronized (mQuotaLock) { 1105 if (mActiveAlerts.containsKey(iface)) { 1106 throw new IllegalStateException("iface " + iface + " already has alert"); 1107 } 1108 1109 try { 1110 // TODO: support alert shared across interfaces 1111 mNetdService.bandwidthSetInterfaceAlert(iface, alertBytes); 1112 mActiveAlerts.put(iface, alertBytes); 1113 } catch (RemoteException | ServiceSpecificException e) { 1114 throw new IllegalStateException(e); 1115 } 1116 } 1117 } 1118 1119 @Override removeInterfaceAlert(String iface)1120 public void removeInterfaceAlert(String iface) { 1121 NetworkStack.checkNetworkStackPermission(mContext); 1122 1123 synchronized (mQuotaLock) { 1124 if (!mActiveAlerts.containsKey(iface)) { 1125 // TODO: eventually consider throwing 1126 return; 1127 } 1128 1129 try { 1130 // TODO: support alert shared across interfaces 1131 mNetdService.bandwidthRemoveInterfaceAlert(iface); 1132 mActiveAlerts.remove(iface); 1133 } catch (RemoteException | ServiceSpecificException e) { 1134 throw new IllegalStateException(e); 1135 } 1136 } 1137 } 1138 1139 @Override setGlobalAlert(long alertBytes)1140 public void setGlobalAlert(long alertBytes) { 1141 NetworkStack.checkNetworkStackPermission(mContext); 1142 1143 try { 1144 mNetdService.bandwidthSetGlobalAlert(alertBytes); 1145 } catch (RemoteException | ServiceSpecificException e) { 1146 throw new IllegalStateException(e); 1147 } 1148 } 1149 setUidOnMeteredNetworkList(int uid, boolean allowlist, boolean enable)1150 private void setUidOnMeteredNetworkList(int uid, boolean allowlist, boolean enable) { 1151 NetworkStack.checkNetworkStackPermission(mContext); 1152 1153 synchronized (mQuotaLock) { 1154 boolean oldEnable; 1155 SparseBooleanArray quotaList; 1156 synchronized (mRulesLock) { 1157 quotaList = allowlist ? mUidAllowOnMetered : mUidRejectOnMetered; 1158 oldEnable = quotaList.get(uid, false); 1159 } 1160 if (oldEnable == enable) { 1161 // TODO: eventually consider throwing 1162 return; 1163 } 1164 1165 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "inetd bandwidth"); 1166 final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class); 1167 try { 1168 if (allowlist) { 1169 if (enable) { 1170 cm.addUidToMeteredNetworkAllowList(uid); 1171 } else { 1172 cm.removeUidFromMeteredNetworkAllowList(uid); 1173 } 1174 } else { 1175 if (enable) { 1176 cm.addUidToMeteredNetworkDenyList(uid); 1177 } else { 1178 cm.removeUidFromMeteredNetworkDenyList(uid); 1179 } 1180 } 1181 synchronized (mRulesLock) { 1182 if (enable) { 1183 quotaList.put(uid, true); 1184 } else { 1185 quotaList.delete(uid); 1186 } 1187 } 1188 } catch (RuntimeException e) { 1189 throw new IllegalStateException(e); 1190 } finally { 1191 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 1192 } 1193 } 1194 } 1195 1196 @Override setUidOnMeteredNetworkDenylist(int uid, boolean enable)1197 public void setUidOnMeteredNetworkDenylist(int uid, boolean enable) { 1198 setUidOnMeteredNetworkList(uid, false, enable); 1199 } 1200 1201 @Override setUidOnMeteredNetworkAllowlist(int uid, boolean enable)1202 public void setUidOnMeteredNetworkAllowlist(int uid, boolean enable) { 1203 setUidOnMeteredNetworkList(uid, true, enable); 1204 } 1205 1206 @Override setDataSaverModeEnabled(boolean enable)1207 public boolean setDataSaverModeEnabled(boolean enable) { 1208 mContext.enforceCallingOrSelfPermission(NETWORK_SETTINGS, TAG); 1209 1210 if (DBG) Log.d(TAG, "setDataSaverMode: " + enable); 1211 synchronized (mQuotaLock) { 1212 if (mDataSaverMode == enable) { 1213 Log.w(TAG, "setDataSaverMode(): already " + mDataSaverMode); 1214 return true; 1215 } 1216 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "bandwidthEnableDataSaver"); 1217 try { 1218 final boolean changed = mNetdService.bandwidthEnableDataSaver(enable); 1219 if (changed) { 1220 mDataSaverMode = enable; 1221 } else { 1222 Log.w(TAG, "setDataSaverMode(" + enable + "): netd command silently failed"); 1223 } 1224 return changed; 1225 } catch (RemoteException e) { 1226 Log.w(TAG, "setDataSaverMode(" + enable + "): netd command failed", e); 1227 return false; 1228 } finally { 1229 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 1230 } 1231 } 1232 } 1233 applyUidCleartextNetworkPolicy(int uid, int policy)1234 private void applyUidCleartextNetworkPolicy(int uid, int policy) { 1235 final int policyValue; 1236 switch (policy) { 1237 case StrictMode.NETWORK_POLICY_ACCEPT: 1238 policyValue = INetd.PENALTY_POLICY_ACCEPT; 1239 break; 1240 case StrictMode.NETWORK_POLICY_LOG: 1241 policyValue = INetd.PENALTY_POLICY_LOG; 1242 break; 1243 case StrictMode.NETWORK_POLICY_REJECT: 1244 policyValue = INetd.PENALTY_POLICY_REJECT; 1245 break; 1246 default: 1247 throw new IllegalArgumentException("Unknown policy " + policy); 1248 } 1249 1250 try { 1251 mNetdService.strictUidCleartextPenalty(uid, policyValue); 1252 mUidCleartextPolicy.put(uid, policy); 1253 } catch (RemoteException | ServiceSpecificException e) { 1254 throw new IllegalStateException(e); 1255 } 1256 } 1257 1258 @Override setUidCleartextNetworkPolicy(int uid, int policy)1259 public void setUidCleartextNetworkPolicy(int uid, int policy) { 1260 if (mDeps.getCallingUid() != uid) { 1261 NetworkStack.checkNetworkStackPermission(mContext); 1262 } 1263 1264 synchronized (mQuotaLock) { 1265 final int oldPolicy = mUidCleartextPolicy.get(uid, StrictMode.NETWORK_POLICY_ACCEPT); 1266 if (oldPolicy == policy) { 1267 // This also ensures we won't needlessly apply an ACCEPT policy if we've just 1268 // enabled strict and the underlying iptables rules are empty. 1269 return; 1270 } 1271 1272 // TODO: remove this code after removing prepareNativeDaemon() 1273 if (!mStrictEnabled) { 1274 // Module isn't enabled yet; stash the requested policy away to 1275 // apply later once the daemon is connected. 1276 mUidCleartextPolicy.put(uid, policy); 1277 return; 1278 } 1279 1280 // netd does not keep state on strict mode policies, and cannot replace a non-accept 1281 // policy without deleting it first. Rather than add state to netd, just always send 1282 // it an accept policy when switching between two non-accept policies. 1283 // TODO: consider keeping state in netd so we can simplify this code. 1284 if (oldPolicy != StrictMode.NETWORK_POLICY_ACCEPT && 1285 policy != StrictMode.NETWORK_POLICY_ACCEPT) { 1286 applyUidCleartextNetworkPolicy(uid, StrictMode.NETWORK_POLICY_ACCEPT); 1287 } 1288 1289 applyUidCleartextNetworkPolicy(uid, policy); 1290 } 1291 } 1292 1293 @Override isBandwidthControlEnabled()1294 public boolean isBandwidthControlEnabled() { 1295 return true; 1296 } 1297 1298 private class NetdTetheringStatsProvider extends ITetheringStatsProvider.Stub { 1299 @Override getTetherStats(int how)1300 public NetworkStats getTetherStats(int how) { 1301 // Remove the implementation of NetdTetheringStatsProvider#getTetherStats 1302 // since all callers are migrated to use INetd#tetherGetStats directly. 1303 throw new UnsupportedOperationException(); 1304 } 1305 1306 @Override setInterfaceQuota(String iface, long quotaBytes)1307 public void setInterfaceQuota(String iface, long quotaBytes) { 1308 // Do nothing. netd is already informed of quota changes in setInterfaceQuota. 1309 } 1310 } 1311 1312 @Override getNetworkStatsTethering(int how)1313 public NetworkStats getNetworkStatsTethering(int how) { 1314 // Remove the implementation of getNetworkStatsTethering since all callers are migrated 1315 // to use INetd#tetherGetStats directly. 1316 throw new UnsupportedOperationException(); 1317 } 1318 1319 @Override setFirewallEnabled(boolean enabled)1320 public void setFirewallEnabled(boolean enabled) { 1321 enforceSystemUid(); 1322 try { 1323 mNetdService.firewallSetFirewallType( 1324 enabled ? INetd.FIREWALL_ALLOWLIST : INetd.FIREWALL_DENYLIST); 1325 mFirewallEnabled = enabled; 1326 } catch (RemoteException | ServiceSpecificException e) { 1327 throw new IllegalStateException(e); 1328 } 1329 } 1330 1331 @Override isFirewallEnabled()1332 public boolean isFirewallEnabled() { 1333 enforceSystemUid(); 1334 return mFirewallEnabled; 1335 } 1336 1337 @Override setFirewallInterfaceRule(String iface, boolean allow)1338 public void setFirewallInterfaceRule(String iface, boolean allow) { 1339 enforceSystemUid(); 1340 Preconditions.checkState(mFirewallEnabled); 1341 try { 1342 mNetdService.firewallSetInterfaceRule(iface, 1343 allow ? INetd.FIREWALL_RULE_ALLOW : INetd.FIREWALL_RULE_DENY); 1344 } catch (RemoteException | ServiceSpecificException e) { 1345 throw new IllegalStateException(e); 1346 } 1347 } 1348 closeSocketsForFirewallChainLocked(int chain, String chainName)1349 private void closeSocketsForFirewallChainLocked(int chain, String chainName) { 1350 // UID ranges to close sockets on. 1351 UidRangeParcel[] ranges; 1352 // UID ranges whose sockets we won't touch. 1353 int[] exemptUids; 1354 1355 int numUids = 0; 1356 if (DBG) Slog.d(TAG, "Closing sockets after enabling chain " + chainName); 1357 if (getFirewallType(chain) == FIREWALL_ALLOWLIST) { 1358 // Close all sockets on all non-system UIDs... 1359 ranges = new UidRangeParcel[] { 1360 // TODO: is there a better way of finding all existing users? If so, we could 1361 // specify their ranges here. 1362 new UidRangeParcel(Process.FIRST_APPLICATION_UID, Integer.MAX_VALUE), 1363 }; 1364 // ... except for the UIDs that have allow rules. 1365 synchronized (mRulesLock) { 1366 final SparseIntArray rules = getUidFirewallRulesLR(chain); 1367 exemptUids = new int[rules.size()]; 1368 for (int i = 0; i < exemptUids.length; i++) { 1369 if (rules.valueAt(i) == FIREWALL_RULE_ALLOW) { 1370 exemptUids[numUids] = rules.keyAt(i); 1371 numUids++; 1372 } 1373 } 1374 } 1375 // Normally, allowlist chains only contain deny rules, so numUids == exemptUids.length. 1376 // But the code does not guarantee this in any way, and at least in one case - if we add 1377 // a UID rule to the firewall, and then disable the firewall - the chains can contain 1378 // the wrong type of rule. In this case, don't close connections that we shouldn't. 1379 // 1380 // TODO: tighten up this code by ensuring we never set the wrong type of rule, and 1381 // fix setFirewallEnabled to grab mQuotaLock and clear rules. 1382 if (numUids != exemptUids.length) { 1383 exemptUids = Arrays.copyOf(exemptUids, numUids); 1384 } 1385 } else { 1386 // Close sockets for every UID that has a deny rule... 1387 synchronized (mRulesLock) { 1388 final SparseIntArray rules = getUidFirewallRulesLR(chain); 1389 ranges = new UidRangeParcel[rules.size()]; 1390 for (int i = 0; i < ranges.length; i++) { 1391 if (rules.valueAt(i) == FIREWALL_RULE_DENY) { 1392 int uid = rules.keyAt(i); 1393 ranges[numUids] = new UidRangeParcel(uid, uid); 1394 numUids++; 1395 } 1396 } 1397 } 1398 // As above; usually numUids == ranges.length, but not always. 1399 if (numUids != ranges.length) { 1400 ranges = Arrays.copyOf(ranges, numUids); 1401 } 1402 // ... with no exceptions. 1403 exemptUids = new int[0]; 1404 } 1405 1406 try { 1407 mNetdService.socketDestroy(ranges, exemptUids); 1408 } catch(RemoteException | ServiceSpecificException e) { 1409 Slog.e(TAG, "Error closing sockets after enabling chain " + chainName + ": " + e); 1410 } 1411 } 1412 1413 @Override setFirewallChainEnabled(int chain, boolean enable)1414 public void setFirewallChainEnabled(int chain, boolean enable) { 1415 enforceSystemUid(); 1416 synchronized (mQuotaLock) { 1417 synchronized (mRulesLock) { 1418 if (getFirewallChainState(chain) == enable) { 1419 // All is the same, nothing to do. This relies on the fact that netd has child 1420 // chains default detached. 1421 return; 1422 } 1423 setFirewallChainState(chain, enable); 1424 } 1425 1426 final String chainName = getFirewallChainName(chain); 1427 if (chain == FIREWALL_CHAIN_NONE) { 1428 throw new IllegalArgumentException("Bad child chain: " + chainName); 1429 } 1430 1431 final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class); 1432 try { 1433 cm.setFirewallChainEnabled(chain, enable); 1434 } catch (RuntimeException e) { 1435 throw new IllegalStateException(e); 1436 } 1437 1438 // Close any sockets that were opened by the affected UIDs. This has to be done after 1439 // disabling network connectivity, in case they react to the socket close by reopening 1440 // the connection and race with the iptables commands that enable the firewall. All 1441 // allowlist and denylist chains allow RSTs through. 1442 if (enable) { 1443 closeSocketsForFirewallChainLocked(chain, chainName); 1444 } 1445 } 1446 } 1447 getFirewallChainName(int chain)1448 private String getFirewallChainName(int chain) { 1449 switch (chain) { 1450 case FIREWALL_CHAIN_STANDBY: 1451 return FIREWALL_CHAIN_NAME_STANDBY; 1452 case FIREWALL_CHAIN_DOZABLE: 1453 return FIREWALL_CHAIN_NAME_DOZABLE; 1454 case FIREWALL_CHAIN_POWERSAVE: 1455 return FIREWALL_CHAIN_NAME_POWERSAVE; 1456 case FIREWALL_CHAIN_RESTRICTED: 1457 return FIREWALL_CHAIN_NAME_RESTRICTED; 1458 case FIREWALL_CHAIN_LOW_POWER_STANDBY: 1459 return FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY; 1460 default: 1461 throw new IllegalArgumentException("Bad child chain: " + chain); 1462 } 1463 } 1464 getFirewallType(int chain)1465 private int getFirewallType(int chain) { 1466 switch (chain) { 1467 case FIREWALL_CHAIN_STANDBY: 1468 return FIREWALL_DENYLIST; 1469 case FIREWALL_CHAIN_DOZABLE: 1470 return FIREWALL_ALLOWLIST; 1471 case FIREWALL_CHAIN_POWERSAVE: 1472 return FIREWALL_ALLOWLIST; 1473 case FIREWALL_CHAIN_RESTRICTED: 1474 return FIREWALL_ALLOWLIST; 1475 case FIREWALL_CHAIN_LOW_POWER_STANDBY: 1476 return FIREWALL_ALLOWLIST; 1477 default: 1478 return isFirewallEnabled() ? FIREWALL_ALLOWLIST : FIREWALL_DENYLIST; 1479 } 1480 } 1481 1482 @Override setFirewallUidRules(int chain, int[] uids, int[] rules)1483 public void setFirewallUidRules(int chain, int[] uids, int[] rules) { 1484 enforceSystemUid(); 1485 synchronized (mQuotaLock) { 1486 synchronized (mRulesLock) { 1487 SparseIntArray uidFirewallRules = getUidFirewallRulesLR(chain); 1488 SparseIntArray newRules = new SparseIntArray(); 1489 // apply new set of rules 1490 for (int index = uids.length - 1; index >= 0; --index) { 1491 int uid = uids[index]; 1492 int rule = rules[index]; 1493 updateFirewallUidRuleLocked(chain, uid, rule); 1494 newRules.put(uid, rule); 1495 } 1496 // collect the rules to remove. 1497 SparseIntArray rulesToRemove = new SparseIntArray(); 1498 for (int index = uidFirewallRules.size() - 1; index >= 0; --index) { 1499 int uid = uidFirewallRules.keyAt(index); 1500 if (newRules.indexOfKey(uid) < 0) { 1501 rulesToRemove.put(uid, FIREWALL_RULE_DEFAULT); 1502 } 1503 } 1504 // remove dead rules 1505 for (int index = rulesToRemove.size() - 1; index >= 0; --index) { 1506 int uid = rulesToRemove.keyAt(index); 1507 updateFirewallUidRuleLocked(chain, uid, FIREWALL_RULE_DEFAULT); 1508 } 1509 } 1510 final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class); 1511 try { 1512 cm.replaceFirewallChain(chain, uids); 1513 } catch (RuntimeException e) { 1514 Slog.w(TAG, "Error flushing firewall chain " + chain, e); 1515 } 1516 } 1517 } 1518 1519 @Override setFirewallUidRule(int chain, int uid, int rule)1520 public void setFirewallUidRule(int chain, int uid, int rule) { 1521 enforceSystemUid(); 1522 synchronized (mQuotaLock) { 1523 setFirewallUidRuleLocked(chain, uid, rule); 1524 } 1525 } 1526 setFirewallUidRuleLocked(int chain, int uid, int rule)1527 private void setFirewallUidRuleLocked(int chain, int uid, int rule) { 1528 if (updateFirewallUidRuleLocked(chain, uid, rule)) { 1529 final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class); 1530 try { 1531 cm.setUidFirewallRule(chain, uid, rule); 1532 } catch (RuntimeException e) { 1533 throw new IllegalStateException(e); 1534 } 1535 } 1536 } 1537 1538 // TODO: now that netd supports batching, NMS should not keep these data structures anymore... updateFirewallUidRuleLocked(int chain, int uid, int rule)1539 private boolean updateFirewallUidRuleLocked(int chain, int uid, int rule) { 1540 synchronized (mRulesLock) { 1541 SparseIntArray uidFirewallRules = getUidFirewallRulesLR(chain); 1542 1543 final int oldUidFirewallRule = uidFirewallRules.get(uid, FIREWALL_RULE_DEFAULT); 1544 if (DBG) { 1545 Slog.d(TAG, "oldRule = " + oldUidFirewallRule 1546 + ", newRule=" + rule + " for uid=" + uid + " on chain " + chain); 1547 } 1548 if (oldUidFirewallRule == rule) { 1549 if (DBG) Slog.d(TAG, "!!!!! Skipping change"); 1550 // TODO: eventually consider throwing 1551 return false; 1552 } 1553 1554 String ruleName = getFirewallRuleName(chain, rule); 1555 String oldRuleName = getFirewallRuleName(chain, oldUidFirewallRule); 1556 1557 if (rule == NetworkPolicyManager.FIREWALL_RULE_DEFAULT) { 1558 uidFirewallRules.delete(uid); 1559 } else { 1560 uidFirewallRules.put(uid, rule); 1561 } 1562 return !ruleName.equals(oldRuleName); 1563 } 1564 } 1565 getFirewallRuleName(int chain, int rule)1566 private @NonNull String getFirewallRuleName(int chain, int rule) { 1567 String ruleName; 1568 if (getFirewallType(chain) == FIREWALL_ALLOWLIST) { 1569 if (rule == FIREWALL_RULE_ALLOW) { 1570 ruleName = "allow"; 1571 } else { 1572 ruleName = "deny"; 1573 } 1574 } else { // Deny mode 1575 if (rule == FIREWALL_RULE_DENY) { 1576 ruleName = "deny"; 1577 } else { 1578 ruleName = "allow"; 1579 } 1580 } 1581 return ruleName; 1582 } 1583 1584 @GuardedBy("mRulesLock") getUidFirewallRulesLR(int chain)1585 private @NonNull SparseIntArray getUidFirewallRulesLR(int chain) { 1586 switch (chain) { 1587 case FIREWALL_CHAIN_STANDBY: 1588 return mUidFirewallStandbyRules; 1589 case FIREWALL_CHAIN_DOZABLE: 1590 return mUidFirewallDozableRules; 1591 case FIREWALL_CHAIN_POWERSAVE: 1592 return mUidFirewallPowerSaveRules; 1593 case FIREWALL_CHAIN_RESTRICTED: 1594 return mUidFirewallRestrictedRules; 1595 case FIREWALL_CHAIN_LOW_POWER_STANDBY: 1596 return mUidFirewallLowPowerStandbyRules; 1597 case FIREWALL_CHAIN_NONE: 1598 return mUidFirewallRules; 1599 default: 1600 throw new IllegalArgumentException("Unknown chain:" + chain); 1601 } 1602 } 1603 enforceSystemUid()1604 private void enforceSystemUid() { 1605 final int uid = mDeps.getCallingUid(); 1606 if (uid != Process.SYSTEM_UID) { 1607 throw new SecurityException("Only available to AID_SYSTEM"); 1608 } 1609 } 1610 1611 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)1612 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1613 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; 1614 1615 synchronized (mQuotaLock) { 1616 pw.print("Active quota ifaces: "); pw.println(mActiveQuotas.toString()); 1617 pw.print("Active alert ifaces: "); pw.println(mActiveAlerts.toString()); 1618 pw.print("Data saver mode: "); pw.println(mDataSaverMode); 1619 synchronized (mRulesLock) { 1620 dumpUidRuleOnQuotaLocked(pw, "denied UIDs", mUidRejectOnMetered); 1621 dumpUidRuleOnQuotaLocked(pw, "allowed UIDs", mUidAllowOnMetered); 1622 } 1623 } 1624 1625 synchronized (mRulesLock) { 1626 dumpUidFirewallRule(pw, "", mUidFirewallRules); 1627 1628 pw.print("UID firewall standby chain enabled: "); 1629 pw.println(getFirewallChainState(FIREWALL_CHAIN_STANDBY)); 1630 dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_STANDBY, mUidFirewallStandbyRules); 1631 1632 pw.print("UID firewall dozable chain enabled: "); 1633 pw.println(getFirewallChainState(FIREWALL_CHAIN_DOZABLE)); 1634 dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_DOZABLE, mUidFirewallDozableRules); 1635 1636 pw.print("UID firewall powersave chain enabled: "); 1637 pw.println(getFirewallChainState(FIREWALL_CHAIN_POWERSAVE)); 1638 dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_POWERSAVE, mUidFirewallPowerSaveRules); 1639 1640 pw.print("UID firewall restricted mode chain enabled: "); 1641 pw.println(getFirewallChainState(FIREWALL_CHAIN_RESTRICTED)); 1642 dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_RESTRICTED, 1643 mUidFirewallRestrictedRules); 1644 1645 pw.print("UID firewall low power standby chain enabled: "); 1646 pw.println(getFirewallChainState(FIREWALL_CHAIN_LOW_POWER_STANDBY)); 1647 dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY, 1648 mUidFirewallLowPowerStandbyRules); 1649 } 1650 1651 pw.print("Firewall enabled: "); pw.println(mFirewallEnabled); 1652 pw.print("Netd service status: " ); 1653 if (mNetdService == null) { 1654 pw.println("disconnected"); 1655 } else { 1656 try { 1657 final boolean alive = mNetdService.isAlive(); 1658 pw.println(alive ? "alive": "dead"); 1659 } catch (RemoteException e) { 1660 pw.println("unreachable"); 1661 } 1662 } 1663 } 1664 dumpUidRuleOnQuotaLocked(PrintWriter pw, String name, SparseBooleanArray list)1665 private void dumpUidRuleOnQuotaLocked(PrintWriter pw, String name, SparseBooleanArray list) { 1666 pw.print("UID bandwith control "); 1667 pw.print(name); 1668 pw.print(": ["); 1669 final int size = list.size(); 1670 for (int i = 0; i < size; i++) { 1671 pw.print(list.keyAt(i)); 1672 if (i < size - 1) pw.print(","); 1673 } 1674 pw.println("]"); 1675 } 1676 dumpUidFirewallRule(PrintWriter pw, String name, SparseIntArray rules)1677 private void dumpUidFirewallRule(PrintWriter pw, String name, SparseIntArray rules) { 1678 pw.print("UID firewall "); 1679 pw.print(name); 1680 pw.print(" rule: ["); 1681 final int size = rules.size(); 1682 for (int i = 0; i < size; i++) { 1683 pw.print(rules.keyAt(i)); 1684 pw.print(":"); 1685 pw.print(rules.valueAt(i)); 1686 if (i < size - 1) pw.print(","); 1687 } 1688 pw.println("]"); 1689 } 1690 modifyInterfaceInNetwork(boolean add, int netId, String iface)1691 private void modifyInterfaceInNetwork(boolean add, int netId, String iface) { 1692 NetworkStack.checkNetworkStackPermission(mContext); 1693 try { 1694 if (add) { 1695 mNetdService.networkAddInterface(netId, iface); 1696 } else { 1697 mNetdService.networkRemoveInterface(netId, iface); 1698 } 1699 } catch (RemoteException | ServiceSpecificException e) { 1700 throw new IllegalStateException(e); 1701 } 1702 } 1703 1704 @Override allowProtect(int uid)1705 public void allowProtect(int uid) { 1706 NetworkStack.checkNetworkStackPermission(mContext); 1707 1708 try { 1709 mNetdService.networkSetProtectAllow(uid); 1710 } catch (RemoteException | ServiceSpecificException e) { 1711 throw new IllegalStateException(e); 1712 } 1713 } 1714 1715 @Override denyProtect(int uid)1716 public void denyProtect(int uid) { 1717 NetworkStack.checkNetworkStackPermission(mContext); 1718 1719 try { 1720 mNetdService.networkSetProtectDeny(uid); 1721 } catch (RemoteException | ServiceSpecificException e) { 1722 throw new IllegalStateException(e); 1723 } 1724 } 1725 1726 @Override addInterfaceToLocalNetwork(String iface, List<RouteInfo> routes)1727 public void addInterfaceToLocalNetwork(String iface, List<RouteInfo> routes) { 1728 modifyInterfaceInNetwork(MODIFY_OPERATION_ADD, INetd.LOCAL_NET_ID, iface); 1729 // modifyInterfaceInNetwork already check calling permission. 1730 NetdUtils.addRoutesToLocalNetwork(mNetdService, iface, routes); 1731 } 1732 1733 @Override removeInterfaceFromLocalNetwork(String iface)1734 public void removeInterfaceFromLocalNetwork(String iface) { 1735 modifyInterfaceInNetwork(MODIFY_OPERATION_REMOVE, INetd.LOCAL_NET_ID, iface); 1736 } 1737 1738 @Override removeRoutesFromLocalNetwork(List<RouteInfo> routes)1739 public int removeRoutesFromLocalNetwork(List<RouteInfo> routes) { 1740 NetworkStack.checkNetworkStackPermission(mContext); 1741 return NetdUtils.removeRoutesFromLocalNetwork(mNetdService, routes); 1742 } 1743 1744 @Override isNetworkRestricted(int uid)1745 public boolean isNetworkRestricted(int uid) { 1746 mContext.enforceCallingOrSelfPermission(OBSERVE_NETWORK_POLICY, TAG); 1747 return isNetworkRestrictedInternal(uid); 1748 } 1749 isNetworkRestrictedInternal(int uid)1750 private boolean isNetworkRestrictedInternal(int uid) { 1751 synchronized (mRulesLock) { 1752 if (getFirewallChainState(FIREWALL_CHAIN_STANDBY) 1753 && mUidFirewallStandbyRules.get(uid) == FIREWALL_RULE_DENY) { 1754 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of app standby mode"); 1755 return true; 1756 } 1757 if (getFirewallChainState(FIREWALL_CHAIN_DOZABLE) 1758 && mUidFirewallDozableRules.get(uid) != FIREWALL_RULE_ALLOW) { 1759 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of device idle mode"); 1760 return true; 1761 } 1762 if (getFirewallChainState(FIREWALL_CHAIN_POWERSAVE) 1763 && mUidFirewallPowerSaveRules.get(uid) != FIREWALL_RULE_ALLOW) { 1764 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of power saver mode"); 1765 return true; 1766 } 1767 if (getFirewallChainState(FIREWALL_CHAIN_RESTRICTED) 1768 && mUidFirewallRestrictedRules.get(uid) != FIREWALL_RULE_ALLOW) { 1769 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of restricted mode"); 1770 return true; 1771 } 1772 if (getFirewallChainState(FIREWALL_CHAIN_LOW_POWER_STANDBY) 1773 && mUidFirewallLowPowerStandbyRules.get(uid) != FIREWALL_RULE_ALLOW) { 1774 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of low power standby"); 1775 return true; 1776 } 1777 if (mUidRejectOnMetered.get(uid)) { 1778 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of no metered data" 1779 + " in the background"); 1780 return true; 1781 } 1782 if (mDataSaverMode && !mUidAllowOnMetered.get(uid)) { 1783 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of data saver mode"); 1784 return true; 1785 } 1786 return false; 1787 } 1788 } 1789 setFirewallChainState(int chain, boolean state)1790 private void setFirewallChainState(int chain, boolean state) { 1791 synchronized (mRulesLock) { 1792 mFirewallChainStates.put(chain, state); 1793 } 1794 } 1795 getFirewallChainState(int chain)1796 private boolean getFirewallChainState(int chain) { 1797 synchronized (mRulesLock) { 1798 return mFirewallChainStates.get(chain); 1799 } 1800 } 1801 1802 private class LocalService extends NetworkManagementInternal { 1803 @Override isNetworkRestrictedForUid(int uid)1804 public boolean isNetworkRestrictedForUid(int uid) { 1805 return isNetworkRestrictedInternal(uid); 1806 } 1807 } 1808 } 1809