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