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.NETWORK_STACK; 22 import static android.Manifest.permission.SHUTDOWN; 23 import static android.net.INetd.FIREWALL_BLACKLIST; 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_STANDBY; 28 import static android.net.INetd.FIREWALL_RULE_ALLOW; 29 import static android.net.INetd.FIREWALL_RULE_DENY; 30 import static android.net.INetd.FIREWALL_WHITELIST; 31 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_DOZABLE; 32 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_POWERSAVE; 33 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_STANDBY; 34 import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT; 35 import static android.net.NetworkStats.SET_DEFAULT; 36 import static android.net.NetworkStats.STATS_PER_UID; 37 import static android.net.NetworkStats.TAG_ALL; 38 import static android.net.NetworkStats.TAG_NONE; 39 import static android.net.NetworkStats.UID_ALL; 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.ConnectivityManager; 48 import android.net.INetd; 49 import android.net.INetdUnsolicitedEventListener; 50 import android.net.INetworkManagementEventObserver; 51 import android.net.ITetheringStatsProvider; 52 import android.net.InetAddresses; 53 import android.net.InterfaceConfiguration; 54 import android.net.InterfaceConfigurationParcel; 55 import android.net.IpPrefix; 56 import android.net.LinkAddress; 57 import android.net.Network; 58 import android.net.NetworkPolicyManager; 59 import android.net.NetworkStats; 60 import android.net.NetworkUtils; 61 import android.net.RouteInfo; 62 import android.net.TetherStatsParcel; 63 import android.net.UidRange; 64 import android.net.UidRangeParcel; 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.INetworkActivityListener; 71 import android.os.INetworkManagementService; 72 import android.os.Process; 73 import android.os.RemoteCallbackList; 74 import android.os.RemoteException; 75 import android.os.ServiceManager; 76 import android.os.ServiceSpecificException; 77 import android.os.StrictMode; 78 import android.os.SystemClock; 79 import android.os.SystemProperties; 80 import android.os.Trace; 81 import android.telephony.DataConnectionRealTimeInfo; 82 import android.text.TextUtils; 83 import android.util.Log; 84 import android.util.Slog; 85 import android.util.SparseBooleanArray; 86 import android.util.SparseIntArray; 87 import android.util.StatsLog; 88 89 import com.android.internal.annotations.GuardedBy; 90 import com.android.internal.annotations.VisibleForTesting; 91 import com.android.internal.app.IBatteryStats; 92 import com.android.internal.util.DumpUtils; 93 import com.android.internal.util.HexDump; 94 import com.android.internal.util.Preconditions; 95 import com.android.server.net.NetworkStatsFactory; 96 97 import com.google.android.collect.Maps; 98 99 import java.io.BufferedReader; 100 import java.io.DataInputStream; 101 import java.io.FileDescriptor; 102 import java.io.FileInputStream; 103 import java.io.IOException; 104 import java.io.InputStreamReader; 105 import java.io.PrintWriter; 106 import java.net.InetAddress; 107 import java.net.InterfaceAddress; 108 import java.util.ArrayList; 109 import java.util.Arrays; 110 import java.util.HashMap; 111 import java.util.List; 112 import java.util.Map; 113 114 /** 115 * @hide 116 */ 117 public class NetworkManagementService extends INetworkManagementService.Stub { 118 119 /** 120 * Helper class that encapsulates NetworkManagementService dependencies and makes them 121 * easier to mock in unit tests. 122 */ 123 static class SystemServices { getService(String name)124 public IBinder getService(String name) { 125 return ServiceManager.getService(name); 126 } registerLocalService(NetworkManagementInternal nmi)127 public void registerLocalService(NetworkManagementInternal nmi) { 128 LocalServices.addService(NetworkManagementInternal.class, nmi); 129 } getNetd()130 public INetd getNetd() { 131 return NetdService.get(); 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 SystemServices mServices; 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 private final NetworkStatsFactory mStatsFactory = new NetworkStatsFactory(); 170 171 @GuardedBy("mTetheringStatsProviders") 172 private final HashMap<ITetheringStatsProvider, String> 173 mTetheringStatsProviders = Maps.newHashMap(); 174 175 /** 176 * If both locks need to be held, then they should be obtained in the order: 177 * first {@link #mQuotaLock} and then {@link #mRulesLock}. 178 */ 179 private final Object mQuotaLock = new Object(); 180 private final Object mRulesLock = new Object(); 181 182 /** Set of interfaces with active quotas. */ 183 @GuardedBy("mQuotaLock") 184 private HashMap<String, Long> mActiveQuotas = Maps.newHashMap(); 185 /** Set of interfaces with active alerts. */ 186 @GuardedBy("mQuotaLock") 187 private HashMap<String, Long> mActiveAlerts = Maps.newHashMap(); 188 /** Set of UIDs blacklisted on metered networks. */ 189 @GuardedBy("mRulesLock") 190 private SparseBooleanArray mUidRejectOnMetered = new SparseBooleanArray(); 191 /** Set of UIDs whitelisted on metered networks. */ 192 @GuardedBy("mRulesLock") 193 private SparseBooleanArray mUidAllowOnMetered = new SparseBooleanArray(); 194 /** Set of UIDs with cleartext penalties. */ 195 @GuardedBy("mQuotaLock") 196 private SparseIntArray mUidCleartextPolicy = new SparseIntArray(); 197 /** Set of UIDs that are to be blocked/allowed by firewall controller. */ 198 @GuardedBy("mRulesLock") 199 private SparseIntArray mUidFirewallRules = new SparseIntArray(); 200 /** 201 * Set of UIDs that are to be blocked/allowed by firewall controller. This set of Ids matches 202 * to application idles. 203 */ 204 @GuardedBy("mRulesLock") 205 private SparseIntArray mUidFirewallStandbyRules = new SparseIntArray(); 206 /** 207 * Set of UIDs that are to be blocked/allowed by firewall controller. This set of Ids matches 208 * to device idles. 209 */ 210 @GuardedBy("mRulesLock") 211 private SparseIntArray mUidFirewallDozableRules = new SparseIntArray(); 212 /** 213 * Set of UIDs that are to be blocked/allowed by firewall controller. This set of Ids matches 214 * to device on power-save mode. 215 */ 216 @GuardedBy("mRulesLock") 217 private SparseIntArray mUidFirewallPowerSaveRules = new SparseIntArray(); 218 /** Set of states for the child firewall chains. True if the chain is active. */ 219 @GuardedBy("mRulesLock") 220 final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray(); 221 222 @GuardedBy("mQuotaLock") 223 private volatile boolean mDataSaverMode; 224 225 private final Object mIdleTimerLock = new Object(); 226 /** Set of interfaces with active idle timers. */ 227 private static class IdleTimerParams { 228 public final int timeout; 229 public final int type; 230 public int networkCount; 231 IdleTimerParams(int timeout, int type)232 IdleTimerParams(int timeout, int type) { 233 this.timeout = timeout; 234 this.type = type; 235 this.networkCount = 1; 236 } 237 } 238 private HashMap<String, IdleTimerParams> mActiveIdleTimers = Maps.newHashMap(); 239 240 private volatile boolean mFirewallEnabled; 241 private volatile boolean mStrictEnabled; 242 243 private boolean mMobileActivityFromRadio = false; 244 private int mLastPowerStateFromRadio = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 245 private int mLastPowerStateFromWifi = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 246 247 private final RemoteCallbackList<INetworkActivityListener> mNetworkActivityListeners = 248 new RemoteCallbackList<>(); 249 private boolean mNetworkActive; 250 251 /** 252 * Constructs a new NetworkManagementService instance 253 * 254 * @param context Binder context for this service 255 */ NetworkManagementService( Context context, SystemServices services)256 private NetworkManagementService( 257 Context context, SystemServices services) { 258 mContext = context; 259 mServices = services; 260 261 mDaemonHandler = new Handler(FgThread.get().getLooper()); 262 263 mNetdUnsolicitedEventListener = new NetdUnsolicitedEventListener(); 264 265 mServices.registerLocalService(new LocalService()); 266 267 synchronized (mTetheringStatsProviders) { 268 mTetheringStatsProviders.put(new NetdTetheringStatsProvider(), "netd"); 269 } 270 } 271 272 @VisibleForTesting NetworkManagementService()273 NetworkManagementService() { 274 mContext = null; 275 mDaemonHandler = null; 276 mServices = null; 277 mNetdUnsolicitedEventListener = null; 278 } 279 create(Context context, SystemServices services)280 static NetworkManagementService create(Context context, SystemServices services) 281 throws InterruptedException { 282 final NetworkManagementService service = 283 new NetworkManagementService(context, services); 284 if (DBG) Slog.d(TAG, "Creating NetworkManagementService"); 285 if (DBG) Slog.d(TAG, "Connecting native netd service"); 286 service.connectNativeNetdService(); 287 if (DBG) Slog.d(TAG, "Connected"); 288 return service; 289 } 290 create(Context context)291 public static NetworkManagementService create(Context context) throws InterruptedException { 292 return create(context, new SystemServices()); 293 } 294 systemReady()295 public void systemReady() { 296 if (DBG) { 297 final long start = System.currentTimeMillis(); 298 prepareNativeDaemon(); 299 final long delta = System.currentTimeMillis() - start; 300 Slog.d(TAG, "Prepared in " + delta + "ms"); 301 return; 302 } else { 303 prepareNativeDaemon(); 304 } 305 } 306 getBatteryStats()307 private IBatteryStats getBatteryStats() { 308 synchronized (this) { 309 if (mBatteryStats != null) { 310 return mBatteryStats; 311 } 312 mBatteryStats = 313 IBatteryStats.Stub.asInterface(mServices.getService(BatteryStats.SERVICE_NAME)); 314 return mBatteryStats; 315 } 316 } 317 318 @Override registerObserver(INetworkManagementEventObserver observer)319 public void registerObserver(INetworkManagementEventObserver observer) { 320 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 321 mObservers.register(observer); 322 } 323 324 @Override unregisterObserver(INetworkManagementEventObserver observer)325 public void unregisterObserver(INetworkManagementEventObserver observer) { 326 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 327 mObservers.unregister(observer); 328 } 329 330 @FunctionalInterface 331 private interface NetworkManagementEventCallback { sendCallback(INetworkManagementEventObserver o)332 public void sendCallback(INetworkManagementEventObserver o) throws RemoteException; 333 } 334 invokeForAllObservers(NetworkManagementEventCallback eventCallback)335 private void invokeForAllObservers(NetworkManagementEventCallback eventCallback) { 336 final int length = mObservers.beginBroadcast(); 337 try { 338 for (int i = 0; i < length; i++) { 339 try { 340 eventCallback.sendCallback(mObservers.getBroadcastItem(i)); 341 } catch (RemoteException | RuntimeException e) { 342 } 343 } 344 } finally { 345 mObservers.finishBroadcast(); 346 } 347 } 348 349 /** 350 * Notify our observers of an interface status change 351 */ notifyInterfaceStatusChanged(String iface, boolean up)352 private void notifyInterfaceStatusChanged(String iface, boolean up) { 353 invokeForAllObservers(o -> o.interfaceStatusChanged(iface, up)); 354 } 355 356 /** 357 * Notify our observers of an interface link state change 358 * (typically, an Ethernet cable has been plugged-in or unplugged). 359 */ notifyInterfaceLinkStateChanged(String iface, boolean up)360 private void notifyInterfaceLinkStateChanged(String iface, boolean up) { 361 invokeForAllObservers(o -> o.interfaceLinkStateChanged(iface, up)); 362 } 363 364 /** 365 * Notify our observers of an interface addition. 366 */ notifyInterfaceAdded(String iface)367 private void notifyInterfaceAdded(String iface) { 368 invokeForAllObservers(o -> o.interfaceAdded(iface)); 369 } 370 371 /** 372 * Notify our observers of an interface removal. 373 */ notifyInterfaceRemoved(String iface)374 private void notifyInterfaceRemoved(String iface) { 375 // netd already clears out quota and alerts for removed ifaces; update 376 // our sanity-checking state. 377 mActiveAlerts.remove(iface); 378 mActiveQuotas.remove(iface); 379 invokeForAllObservers(o -> o.interfaceRemoved(iface)); 380 } 381 382 /** 383 * Notify our observers of a limit reached. 384 */ notifyLimitReached(String limitName, String iface)385 private void notifyLimitReached(String limitName, String iface) { 386 invokeForAllObservers(o -> o.limitReached(limitName, iface)); 387 } 388 389 /** 390 * Notify our observers of a change in the data activity state of the interface 391 */ notifyInterfaceClassActivity(int type, boolean isActive, long tsNanos, int uid, boolean fromRadio)392 private void notifyInterfaceClassActivity(int type, boolean isActive, long tsNanos, 393 int uid, boolean fromRadio) { 394 final boolean isMobile = ConnectivityManager.isNetworkTypeMobile(type); 395 int powerState = isActive 396 ? DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH 397 : DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 398 if (isMobile) { 399 if (!fromRadio) { 400 if (mMobileActivityFromRadio) { 401 // If this call is not coming from a report from the radio itself, but we 402 // have previously received reports from the radio, then we will take the 403 // power state to just be whatever the radio last reported. 404 powerState = mLastPowerStateFromRadio; 405 } 406 } else { 407 mMobileActivityFromRadio = true; 408 } 409 if (mLastPowerStateFromRadio != powerState) { 410 mLastPowerStateFromRadio = powerState; 411 try { 412 getBatteryStats().noteMobileRadioPowerState(powerState, tsNanos, uid); 413 } catch (RemoteException e) { 414 } 415 StatsLog.write_non_chained(StatsLog.MOBILE_RADIO_POWER_STATE_CHANGED, uid, null, 416 powerState); 417 } 418 } 419 420 if (ConnectivityManager.isNetworkTypeWifi(type)) { 421 if (mLastPowerStateFromWifi != powerState) { 422 mLastPowerStateFromWifi = powerState; 423 try { 424 getBatteryStats().noteWifiRadioPowerState(powerState, tsNanos, uid); 425 } catch (RemoteException e) { 426 } 427 StatsLog.write_non_chained(StatsLog.WIFI_RADIO_POWER_STATE_CHANGED, uid, null, 428 powerState); 429 } 430 } 431 432 if (!isMobile || fromRadio || !mMobileActivityFromRadio) { 433 // Report the change in data activity. We don't do this if this is a change 434 // on the mobile network, that is not coming from the radio itself, and we 435 // have previously seen change reports from the radio. In that case only 436 // the radio is the authority for the current state. 437 final boolean active = isActive; 438 invokeForAllObservers(o -> o.interfaceClassDataActivityChanged( 439 Integer.toString(type), active, tsNanos)); 440 } 441 442 boolean report = false; 443 synchronized (mIdleTimerLock) { 444 if (mActiveIdleTimers.isEmpty()) { 445 // If there are no idle timers, we are not monitoring activity, so we 446 // are always considered active. 447 isActive = true; 448 } 449 if (mNetworkActive != isActive) { 450 mNetworkActive = isActive; 451 report = isActive; 452 } 453 } 454 if (report) { 455 reportNetworkActive(); 456 } 457 } 458 459 @Override registerTetheringStatsProvider(ITetheringStatsProvider provider, String name)460 public void registerTetheringStatsProvider(ITetheringStatsProvider provider, String name) { 461 mContext.enforceCallingOrSelfPermission(NETWORK_STACK, TAG); 462 Preconditions.checkNotNull(provider); 463 synchronized(mTetheringStatsProviders) { 464 mTetheringStatsProviders.put(provider, name); 465 } 466 } 467 468 @Override unregisterTetheringStatsProvider(ITetheringStatsProvider provider)469 public void unregisterTetheringStatsProvider(ITetheringStatsProvider provider) { 470 mContext.enforceCallingOrSelfPermission(NETWORK_STACK, TAG); 471 synchronized(mTetheringStatsProviders) { 472 mTetheringStatsProviders.remove(provider); 473 } 474 } 475 476 @Override tetherLimitReached(ITetheringStatsProvider provider)477 public void tetherLimitReached(ITetheringStatsProvider provider) { 478 mContext.enforceCallingOrSelfPermission(NETWORK_STACK, TAG); 479 synchronized(mTetheringStatsProviders) { 480 if (!mTetheringStatsProviders.containsKey(provider)) { 481 return; 482 } 483 // No current code examines the interface parameter in a global alert. Just pass null. 484 mDaemonHandler.post(() -> notifyLimitReached(LIMIT_GLOBAL_ALERT, null)); 485 } 486 } 487 488 // Sync the state of the given chain with the native daemon. syncFirewallChainLocked(int chain, String name)489 private void syncFirewallChainLocked(int chain, String name) { 490 SparseIntArray rules; 491 synchronized (mRulesLock) { 492 final SparseIntArray uidFirewallRules = getUidFirewallRulesLR(chain); 493 // Make a copy of the current rules, and then clear them. This is because 494 // setFirewallUidRuleInternal only pushes down rules to the native daemon if they 495 // are different from the current rules stored in the mUidFirewall*Rules array for 496 // the specified chain. If we don't clear the rules, setFirewallUidRuleInternal 497 // will do nothing. 498 rules = uidFirewallRules.clone(); 499 uidFirewallRules.clear(); 500 } 501 if (rules.size() > 0) { 502 // Now push the rules. setFirewallUidRuleInternal will push each of these down to the 503 // native daemon, and also add them to the mUidFirewall*Rules array for the specified 504 // chain. 505 if (DBG) Slog.d(TAG, "Pushing " + rules.size() + " active firewall " 506 + name + "UID rules"); 507 for (int i = 0; i < rules.size(); i++) { 508 setFirewallUidRuleLocked(chain, rules.keyAt(i), rules.valueAt(i)); 509 } 510 } 511 } 512 connectNativeNetdService()513 private void connectNativeNetdService() { 514 mNetdService = mServices.getNetd(); 515 try { 516 mNetdService.registerUnsolicitedEventListener(mNetdUnsolicitedEventListener); 517 if (DBG) Slog.d(TAG, "Register unsolicited event listener"); 518 } catch (RemoteException | ServiceSpecificException e) { 519 Slog.e(TAG, "Failed to set Netd unsolicited event listener " + e); 520 } 521 } 522 523 /** 524 * Prepare native daemon once connected, enabling modules and pushing any 525 * existing in-memory rules. 526 */ prepareNativeDaemon()527 private void prepareNativeDaemon() { 528 529 // push any existing quota or UID rules 530 synchronized (mQuotaLock) { 531 532 // Netd unconditionally enable bandwidth control 533 SystemProperties.set(PROP_QTAGUID_ENABLED, "1"); 534 535 mStrictEnabled = true; 536 537 setDataSaverModeEnabled(mDataSaverMode); 538 539 int size = mActiveQuotas.size(); 540 if (size > 0) { 541 if (DBG) Slog.d(TAG, "Pushing " + size + " active quota rules"); 542 final HashMap<String, Long> activeQuotas = mActiveQuotas; 543 mActiveQuotas = Maps.newHashMap(); 544 for (Map.Entry<String, Long> entry : activeQuotas.entrySet()) { 545 setInterfaceQuota(entry.getKey(), entry.getValue()); 546 } 547 } 548 549 size = mActiveAlerts.size(); 550 if (size > 0) { 551 if (DBG) Slog.d(TAG, "Pushing " + size + " active alert rules"); 552 final HashMap<String, Long> activeAlerts = mActiveAlerts; 553 mActiveAlerts = Maps.newHashMap(); 554 for (Map.Entry<String, Long> entry : activeAlerts.entrySet()) { 555 setInterfaceAlert(entry.getKey(), entry.getValue()); 556 } 557 } 558 559 SparseBooleanArray uidRejectOnQuota = null; 560 SparseBooleanArray uidAcceptOnQuota = null; 561 synchronized (mRulesLock) { 562 size = mUidRejectOnMetered.size(); 563 if (size > 0) { 564 if (DBG) Slog.d(TAG, "Pushing " + size + " UIDs to metered blacklist rules"); 565 uidRejectOnQuota = mUidRejectOnMetered; 566 mUidRejectOnMetered = new SparseBooleanArray(); 567 } 568 569 size = mUidAllowOnMetered.size(); 570 if (size > 0) { 571 if (DBG) Slog.d(TAG, "Pushing " + size + " UIDs to metered whitelist rules"); 572 uidAcceptOnQuota = mUidAllowOnMetered; 573 mUidAllowOnMetered = new SparseBooleanArray(); 574 } 575 } 576 if (uidRejectOnQuota != null) { 577 for (int i = 0; i < uidRejectOnQuota.size(); i++) { 578 setUidMeteredNetworkBlacklist(uidRejectOnQuota.keyAt(i), 579 uidRejectOnQuota.valueAt(i)); 580 } 581 } 582 if (uidAcceptOnQuota != null) { 583 for (int i = 0; i < uidAcceptOnQuota.size(); i++) { 584 setUidMeteredNetworkWhitelist(uidAcceptOnQuota.keyAt(i), 585 uidAcceptOnQuota.valueAt(i)); 586 } 587 } 588 589 size = mUidCleartextPolicy.size(); 590 if (size > 0) { 591 if (DBG) Slog.d(TAG, "Pushing " + size + " active UID cleartext policies"); 592 final SparseIntArray local = mUidCleartextPolicy; 593 mUidCleartextPolicy = new SparseIntArray(); 594 for (int i = 0; i < local.size(); i++) { 595 setUidCleartextNetworkPolicy(local.keyAt(i), local.valueAt(i)); 596 } 597 } 598 599 setFirewallEnabled(mFirewallEnabled); 600 601 syncFirewallChainLocked(FIREWALL_CHAIN_NONE, ""); 602 syncFirewallChainLocked(FIREWALL_CHAIN_STANDBY, "standby "); 603 syncFirewallChainLocked(FIREWALL_CHAIN_DOZABLE, "dozable "); 604 syncFirewallChainLocked(FIREWALL_CHAIN_POWERSAVE, "powersave "); 605 606 final int[] chains = 607 {FIREWALL_CHAIN_STANDBY, FIREWALL_CHAIN_DOZABLE, FIREWALL_CHAIN_POWERSAVE}; 608 for (int chain : chains) { 609 if (getFirewallChainState(chain)) { 610 setFirewallChainEnabled(chain, true); 611 } 612 } 613 } 614 615 616 try { 617 getBatteryStats().noteNetworkStatsEnabled(); 618 } catch (RemoteException e) { 619 } 620 621 } 622 623 /** 624 * Notify our observers of a new or updated interface address. 625 */ notifyAddressUpdated(String iface, LinkAddress address)626 private void notifyAddressUpdated(String iface, LinkAddress address) { 627 invokeForAllObservers(o -> o.addressUpdated(iface, address)); 628 } 629 630 /** 631 * Notify our observers of a deleted interface address. 632 */ notifyAddressRemoved(String iface, LinkAddress address)633 private void notifyAddressRemoved(String iface, LinkAddress address) { 634 invokeForAllObservers(o -> o.addressRemoved(iface, address)); 635 } 636 637 /** 638 * Notify our observers of DNS server information received. 639 */ notifyInterfaceDnsServerInfo(String iface, long lifetime, String[] addresses)640 private void notifyInterfaceDnsServerInfo(String iface, long lifetime, String[] addresses) { 641 invokeForAllObservers(o -> o.interfaceDnsServerInfo(iface, lifetime, addresses)); 642 } 643 644 /** 645 * Notify our observers of a route change. 646 */ notifyRouteChange(boolean updated, RouteInfo route)647 private void notifyRouteChange(boolean updated, RouteInfo route) { 648 if (updated) { 649 invokeForAllObservers(o -> o.routeUpdated(route)); 650 } else { 651 invokeForAllObservers(o -> o.routeRemoved(route)); 652 } 653 } 654 655 private class NetdUnsolicitedEventListener extends INetdUnsolicitedEventListener.Stub { 656 @Override onInterfaceClassActivityChanged(boolean isActive, int label, long timestamp, int uid)657 public void onInterfaceClassActivityChanged(boolean isActive, 658 int label, long timestamp, int uid) throws RemoteException { 659 final long timestampNanos; 660 if (timestamp <= 0) { 661 timestampNanos = SystemClock.elapsedRealtimeNanos(); 662 } else { 663 timestampNanos = timestamp; 664 } 665 mDaemonHandler.post(() -> 666 notifyInterfaceClassActivity(label, isActive, timestampNanos, uid, false)); 667 } 668 669 @Override onQuotaLimitReached(String alertName, String ifName)670 public void onQuotaLimitReached(String alertName, String ifName) 671 throws RemoteException { 672 mDaemonHandler.post(() -> notifyLimitReached(alertName, ifName)); 673 } 674 675 @Override onInterfaceDnsServerInfo(String ifName, long lifetime, String[] servers)676 public void onInterfaceDnsServerInfo(String ifName, 677 long lifetime, String[] servers) throws RemoteException { 678 mDaemonHandler.post(() -> notifyInterfaceDnsServerInfo(ifName, lifetime, servers)); 679 } 680 681 @Override onInterfaceAddressUpdated(String addr, String ifName, int flags, int scope)682 public void onInterfaceAddressUpdated(String addr, 683 String ifName, int flags, int scope) throws RemoteException { 684 final LinkAddress address = new LinkAddress(addr, flags, scope); 685 mDaemonHandler.post(() -> notifyAddressUpdated(ifName, address)); 686 } 687 688 @Override onInterfaceAddressRemoved(String addr, String ifName, int flags, int scope)689 public void onInterfaceAddressRemoved(String addr, 690 String ifName, int flags, int scope) throws RemoteException { 691 final LinkAddress address = new LinkAddress(addr, flags, scope); 692 mDaemonHandler.post(() -> notifyAddressRemoved(ifName, address)); 693 } 694 695 @Override onInterfaceAdded(String ifName)696 public void onInterfaceAdded(String ifName) throws RemoteException { 697 mDaemonHandler.post(() -> notifyInterfaceAdded(ifName)); 698 } 699 700 @Override onInterfaceRemoved(String ifName)701 public void onInterfaceRemoved(String ifName) throws RemoteException { 702 mDaemonHandler.post(() -> notifyInterfaceRemoved(ifName)); 703 } 704 705 @Override onInterfaceChanged(String ifName, boolean up)706 public void onInterfaceChanged(String ifName, boolean up) 707 throws RemoteException { 708 mDaemonHandler.post(() -> notifyInterfaceStatusChanged(ifName, up)); 709 } 710 711 @Override onInterfaceLinkStateChanged(String ifName, boolean up)712 public void onInterfaceLinkStateChanged(String ifName, boolean up) 713 throws RemoteException { 714 mDaemonHandler.post(() -> notifyInterfaceLinkStateChanged(ifName, up)); 715 } 716 717 @Override onRouteChanged(boolean updated, String route, String gateway, String ifName)718 public void onRouteChanged(boolean updated, 719 String route, String gateway, String ifName) throws RemoteException { 720 final RouteInfo processRoute = new RouteInfo(new IpPrefix(route), 721 ("".equals(gateway)) ? null : InetAddresses.parseNumericAddress(gateway), 722 ifName); 723 mDaemonHandler.post(() -> notifyRouteChange(updated, processRoute)); 724 } 725 726 @Override onStrictCleartextDetected(int uid, String hex)727 public void onStrictCleartextDetected(int uid, String hex) throws RemoteException { 728 // Don't need to post to mDaemonHandler because the only thing 729 // that notifyCleartextNetwork does is post to a handler 730 ActivityManager.getService().notifyCleartextNetwork(uid, 731 HexDump.hexStringToByteArray(hex)); 732 } 733 734 @Override getInterfaceVersion()735 public int getInterfaceVersion() { 736 return INetdUnsolicitedEventListener.VERSION; 737 } 738 } 739 740 // 741 // INetworkManagementService members 742 // 743 @Override listInterfaces()744 public String[] listInterfaces() { 745 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 746 try { 747 return mNetdService.interfaceGetList(); 748 } catch (RemoteException | ServiceSpecificException e) { 749 throw new IllegalStateException(e); 750 } 751 } 752 753 /** 754 * Convert InterfaceConfiguration to InterfaceConfigurationParcel with given ifname. 755 */ toStableParcel(InterfaceConfiguration cfg, String iface)756 private static InterfaceConfigurationParcel toStableParcel(InterfaceConfiguration cfg, 757 String iface) { 758 InterfaceConfigurationParcel cfgParcel = new InterfaceConfigurationParcel(); 759 cfgParcel.ifName = iface; 760 String hwAddr = cfg.getHardwareAddress(); 761 if (!TextUtils.isEmpty(hwAddr)) { 762 cfgParcel.hwAddr = hwAddr; 763 } else { 764 cfgParcel.hwAddr = ""; 765 } 766 cfgParcel.ipv4Addr = cfg.getLinkAddress().getAddress().getHostAddress(); 767 cfgParcel.prefixLength = cfg.getLinkAddress().getPrefixLength(); 768 ArrayList<String> flags = new ArrayList<>(); 769 for (String flag : cfg.getFlags()) { 770 flags.add(flag); 771 } 772 cfgParcel.flags = flags.toArray(new String[0]); 773 774 return cfgParcel; 775 } 776 777 /** 778 * Construct InterfaceConfiguration from InterfaceConfigurationParcel. 779 */ fromStableParcel(InterfaceConfigurationParcel p)780 public static InterfaceConfiguration fromStableParcel(InterfaceConfigurationParcel p) { 781 InterfaceConfiguration cfg = new InterfaceConfiguration(); 782 cfg.setHardwareAddress(p.hwAddr); 783 784 final InetAddress addr = NetworkUtils.numericToInetAddress(p.ipv4Addr); 785 cfg.setLinkAddress(new LinkAddress(addr, p.prefixLength)); 786 for (String flag : p.flags) { 787 cfg.setFlag(flag); 788 } 789 790 return cfg; 791 } 792 793 @Override getInterfaceConfig(String iface)794 public InterfaceConfiguration getInterfaceConfig(String iface) { 795 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 796 final InterfaceConfigurationParcel result; 797 try { 798 result = mNetdService.interfaceGetCfg(iface); 799 } catch (RemoteException | ServiceSpecificException e) { 800 throw new IllegalStateException(e); 801 } 802 803 try { 804 final InterfaceConfiguration cfg = fromStableParcel(result); 805 return cfg; 806 } catch (IllegalArgumentException iae) { 807 throw new IllegalStateException("Invalid InterfaceConfigurationParcel", iae); 808 } 809 } 810 811 @Override setInterfaceConfig(String iface, InterfaceConfiguration cfg)812 public void setInterfaceConfig(String iface, InterfaceConfiguration cfg) { 813 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 814 LinkAddress linkAddr = cfg.getLinkAddress(); 815 if (linkAddr == null || linkAddr.getAddress() == null) { 816 throw new IllegalStateException("Null LinkAddress given"); 817 } 818 819 final InterfaceConfigurationParcel cfgParcel = toStableParcel(cfg, iface); 820 821 try { 822 mNetdService.interfaceSetCfg(cfgParcel); 823 } catch (RemoteException | ServiceSpecificException e) { 824 throw new IllegalStateException(e); 825 } 826 } 827 828 @Override setInterfaceDown(String iface)829 public void setInterfaceDown(String iface) { 830 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 831 final InterfaceConfiguration ifcg = getInterfaceConfig(iface); 832 ifcg.setInterfaceDown(); 833 setInterfaceConfig(iface, ifcg); 834 } 835 836 @Override setInterfaceUp(String iface)837 public void setInterfaceUp(String iface) { 838 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 839 final InterfaceConfiguration ifcg = getInterfaceConfig(iface); 840 ifcg.setInterfaceUp(); 841 setInterfaceConfig(iface, ifcg); 842 } 843 844 @Override setInterfaceIpv6PrivacyExtensions(String iface, boolean enable)845 public void setInterfaceIpv6PrivacyExtensions(String iface, boolean enable) { 846 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 847 try { 848 mNetdService.interfaceSetIPv6PrivacyExtensions(iface, enable); 849 } catch (RemoteException | ServiceSpecificException e) { 850 throw new IllegalStateException(e); 851 } 852 } 853 854 /* TODO: This is right now a IPv4 only function. Works for wifi which loses its 855 IPv6 addresses on interface down, but we need to do full clean up here */ 856 @Override clearInterfaceAddresses(String iface)857 public void clearInterfaceAddresses(String iface) { 858 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 859 try { 860 mNetdService.interfaceClearAddrs(iface); 861 } catch (RemoteException | ServiceSpecificException e) { 862 throw new IllegalStateException(e); 863 } 864 } 865 866 @Override enableIpv6(String iface)867 public void enableIpv6(String iface) { 868 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 869 try { 870 mNetdService.interfaceSetEnableIPv6(iface, true); 871 } catch (RemoteException | ServiceSpecificException e) { 872 throw new IllegalStateException(e); 873 } 874 } 875 876 @Override setIPv6AddrGenMode(String iface, int mode)877 public void setIPv6AddrGenMode(String iface, int mode) throws ServiceSpecificException { 878 try { 879 mNetdService.setIPv6AddrGenMode(iface, mode); 880 } catch (RemoteException e) { 881 throw e.rethrowAsRuntimeException(); 882 } 883 } 884 885 @Override disableIpv6(String iface)886 public void disableIpv6(String iface) { 887 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 888 try { 889 mNetdService.interfaceSetEnableIPv6(iface, false); 890 } catch (RemoteException | ServiceSpecificException e) { 891 throw new IllegalStateException(e); 892 } 893 } 894 895 @Override addRoute(int netId, RouteInfo route)896 public void addRoute(int netId, RouteInfo route) { 897 modifyRoute(MODIFY_OPERATION_ADD, netId, route); 898 } 899 900 @Override removeRoute(int netId, RouteInfo route)901 public void removeRoute(int netId, RouteInfo route) { 902 modifyRoute(MODIFY_OPERATION_REMOVE, netId, route); 903 } 904 modifyRoute(boolean add, int netId, RouteInfo route)905 private void modifyRoute(boolean add, int netId, RouteInfo route) { 906 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 907 908 final String ifName = route.getInterface(); 909 final String dst = route.getDestination().toString(); 910 final String nextHop; 911 912 switch (route.getType()) { 913 case RouteInfo.RTN_UNICAST: 914 if (route.hasGateway()) { 915 nextHop = route.getGateway().getHostAddress(); 916 } else { 917 nextHop = INetd.NEXTHOP_NONE; 918 } 919 break; 920 case RouteInfo.RTN_UNREACHABLE: 921 nextHop = INetd.NEXTHOP_UNREACHABLE; 922 break; 923 case RouteInfo.RTN_THROW: 924 nextHop = INetd.NEXTHOP_THROW; 925 break; 926 default: 927 nextHop = INetd.NEXTHOP_NONE; 928 break; 929 } 930 try { 931 if (add) { 932 mNetdService.networkAddRoute(netId, ifName, dst, nextHop); 933 } else { 934 mNetdService.networkRemoveRoute(netId, ifName, dst, nextHop); 935 } 936 } catch (RemoteException | ServiceSpecificException e) { 937 throw new IllegalStateException(e); 938 } 939 } 940 readRouteList(String filename)941 private ArrayList<String> readRouteList(String filename) { 942 FileInputStream fstream = null; 943 ArrayList<String> list = new ArrayList<>(); 944 945 try { 946 fstream = new FileInputStream(filename); 947 DataInputStream in = new DataInputStream(fstream); 948 BufferedReader br = new BufferedReader(new InputStreamReader(in)); 949 String s; 950 951 // throw away the title line 952 953 while (((s = br.readLine()) != null) && (s.length() != 0)) { 954 list.add(s); 955 } 956 } catch (IOException ex) { 957 // return current list, possibly empty 958 } finally { 959 if (fstream != null) { 960 try { 961 fstream.close(); 962 } catch (IOException ex) {} 963 } 964 } 965 966 return list; 967 } 968 969 @Override setMtu(String iface, int mtu)970 public void setMtu(String iface, int mtu) { 971 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 972 973 try { 974 mNetdService.interfaceSetMtu(iface, mtu); 975 } catch (RemoteException | ServiceSpecificException e) { 976 throw new IllegalStateException(e); 977 } 978 } 979 980 @Override shutdown()981 public void shutdown() { 982 // TODO: remove from aidl if nobody calls externally 983 mContext.enforceCallingOrSelfPermission(SHUTDOWN, TAG); 984 985 Slog.i(TAG, "Shutting down"); 986 } 987 988 @Override getIpForwardingEnabled()989 public boolean getIpForwardingEnabled() throws IllegalStateException{ 990 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 991 992 try { 993 final boolean isEnabled = mNetdService.ipfwdEnabled(); 994 return isEnabled; 995 } catch (RemoteException | ServiceSpecificException e) { 996 throw new IllegalStateException(e); 997 } 998 } 999 1000 @Override setIpForwardingEnabled(boolean enable)1001 public void setIpForwardingEnabled(boolean enable) { 1002 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1003 try { 1004 if (enable) { 1005 mNetdService.ipfwdEnableForwarding("tethering"); 1006 } else { 1007 mNetdService.ipfwdDisableForwarding("tethering"); 1008 } 1009 } catch (RemoteException | ServiceSpecificException e) { 1010 throw new IllegalStateException(e); 1011 } 1012 } 1013 1014 @Override startTethering(String[] dhcpRange)1015 public void startTethering(String[] dhcpRange) { 1016 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1017 // an odd number of addrs will fail 1018 1019 try { 1020 mNetdService.tetherStart(dhcpRange); 1021 } catch (RemoteException | ServiceSpecificException e) { 1022 throw new IllegalStateException(e); 1023 } 1024 } 1025 1026 @Override stopTethering()1027 public void stopTethering() { 1028 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1029 try { 1030 mNetdService.tetherStop(); 1031 } catch (RemoteException | ServiceSpecificException e) { 1032 throw new IllegalStateException(e); 1033 } 1034 } 1035 1036 @Override isTetheringStarted()1037 public boolean isTetheringStarted() { 1038 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1039 1040 try { 1041 final boolean isEnabled = mNetdService.tetherIsEnabled(); 1042 return isEnabled; 1043 } catch (RemoteException | ServiceSpecificException e) { 1044 throw new IllegalStateException(e); 1045 } 1046 } 1047 1048 @Override tetherInterface(String iface)1049 public void tetherInterface(String iface) { 1050 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1051 try { 1052 mNetdService.tetherInterfaceAdd(iface); 1053 } catch (RemoteException | ServiceSpecificException e) { 1054 throw new IllegalStateException(e); 1055 } 1056 List<RouteInfo> routes = new ArrayList<>(); 1057 // The RouteInfo constructor truncates the LinkAddress to a network prefix, thus making it 1058 // suitable to use as a route destination. 1059 routes.add(new RouteInfo(getInterfaceConfig(iface).getLinkAddress(), null, iface)); 1060 addInterfaceToLocalNetwork(iface, routes); 1061 } 1062 1063 @Override untetherInterface(String iface)1064 public void untetherInterface(String iface) { 1065 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1066 try { 1067 mNetdService.tetherInterfaceRemove(iface); 1068 } catch (RemoteException | ServiceSpecificException e) { 1069 throw new IllegalStateException(e); 1070 } finally { 1071 removeInterfaceFromLocalNetwork(iface); 1072 } 1073 } 1074 1075 @Override listTetheredInterfaces()1076 public String[] listTetheredInterfaces() { 1077 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1078 try { 1079 return mNetdService.tetherInterfaceList(); 1080 } catch (RemoteException | ServiceSpecificException e) { 1081 throw new IllegalStateException(e); 1082 } 1083 } 1084 1085 @Override setDnsForwarders(Network network, String[] dns)1086 public void setDnsForwarders(Network network, String[] dns) { 1087 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1088 1089 int netId = (network != null) ? network.netId : ConnectivityManager.NETID_UNSET; 1090 1091 try { 1092 mNetdService.tetherDnsSet(netId, dns); 1093 } catch (RemoteException | ServiceSpecificException e) { 1094 throw new IllegalStateException(e); 1095 } 1096 } 1097 1098 @Override getDnsForwarders()1099 public String[] getDnsForwarders() { 1100 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1101 try { 1102 return mNetdService.tetherDnsList(); 1103 } catch (RemoteException | ServiceSpecificException e) { 1104 throw new IllegalStateException(e); 1105 } 1106 } 1107 excludeLinkLocal(List<InterfaceAddress> addresses)1108 private List<InterfaceAddress> excludeLinkLocal(List<InterfaceAddress> addresses) { 1109 ArrayList<InterfaceAddress> filtered = new ArrayList<>(addresses.size()); 1110 for (InterfaceAddress ia : addresses) { 1111 if (!ia.getAddress().isLinkLocalAddress()) 1112 filtered.add(ia); 1113 } 1114 return filtered; 1115 } 1116 modifyInterfaceForward(boolean add, String fromIface, String toIface)1117 private void modifyInterfaceForward(boolean add, String fromIface, String toIface) { 1118 try { 1119 if (add) { 1120 mNetdService.ipfwdAddInterfaceForward(fromIface, toIface); 1121 } else { 1122 mNetdService.ipfwdRemoveInterfaceForward(fromIface, toIface); 1123 } 1124 } catch (RemoteException | ServiceSpecificException e) { 1125 throw new IllegalStateException(e); 1126 } 1127 } 1128 1129 @Override startInterfaceForwarding(String fromIface, String toIface)1130 public void startInterfaceForwarding(String fromIface, String toIface) { 1131 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1132 modifyInterfaceForward(true, fromIface, toIface); 1133 } 1134 1135 @Override stopInterfaceForwarding(String fromIface, String toIface)1136 public void stopInterfaceForwarding(String fromIface, String toIface) { 1137 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1138 modifyInterfaceForward(false, fromIface, toIface); 1139 } 1140 1141 @Override enableNat(String internalInterface, String externalInterface)1142 public void enableNat(String internalInterface, String externalInterface) { 1143 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1144 try { 1145 mNetdService.tetherAddForward(internalInterface, externalInterface); 1146 } catch (RemoteException | ServiceSpecificException e) { 1147 throw new IllegalStateException(e); 1148 } 1149 } 1150 1151 @Override disableNat(String internalInterface, String externalInterface)1152 public void disableNat(String internalInterface, String externalInterface) { 1153 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1154 try { 1155 mNetdService.tetherRemoveForward(internalInterface, externalInterface); 1156 } catch (RemoteException | ServiceSpecificException e) { 1157 throw new IllegalStateException(e); 1158 } 1159 } 1160 1161 @Override addIdleTimer(String iface, int timeout, final int type)1162 public void addIdleTimer(String iface, int timeout, final int type) { 1163 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1164 1165 if (DBG) Slog.d(TAG, "Adding idletimer"); 1166 1167 synchronized (mIdleTimerLock) { 1168 IdleTimerParams params = mActiveIdleTimers.get(iface); 1169 if (params != null) { 1170 // the interface already has idletimer, update network count 1171 params.networkCount++; 1172 return; 1173 } 1174 1175 try { 1176 mNetdService.idletimerAddInterface(iface, timeout, Integer.toString(type)); 1177 } catch (RemoteException | ServiceSpecificException e) { 1178 throw new IllegalStateException(e); 1179 } 1180 mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, type)); 1181 1182 // Networks start up. 1183 if (ConnectivityManager.isNetworkTypeMobile(type)) { 1184 mNetworkActive = false; 1185 } 1186 mDaemonHandler.post(() -> notifyInterfaceClassActivity(type, true, 1187 SystemClock.elapsedRealtimeNanos(), -1, false)); 1188 } 1189 } 1190 1191 @Override removeIdleTimer(String iface)1192 public void removeIdleTimer(String iface) { 1193 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1194 1195 if (DBG) Slog.d(TAG, "Removing idletimer"); 1196 1197 synchronized (mIdleTimerLock) { 1198 final IdleTimerParams params = mActiveIdleTimers.get(iface); 1199 if (params == null || --(params.networkCount) > 0) { 1200 return; 1201 } 1202 1203 try { 1204 mNetdService.idletimerRemoveInterface(iface, 1205 params.timeout, Integer.toString(params.type)); 1206 } catch (RemoteException | ServiceSpecificException e) { 1207 throw new IllegalStateException(e); 1208 } 1209 mActiveIdleTimers.remove(iface); 1210 mDaemonHandler.post(() -> notifyInterfaceClassActivity(params.type, false, 1211 SystemClock.elapsedRealtimeNanos(), -1, false)); 1212 } 1213 } 1214 1215 @Override getNetworkStatsSummaryDev()1216 public NetworkStats getNetworkStatsSummaryDev() { 1217 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1218 try { 1219 return mStatsFactory.readNetworkStatsSummaryDev(); 1220 } catch (IOException e) { 1221 throw new IllegalStateException(e); 1222 } 1223 } 1224 1225 @Override getNetworkStatsSummaryXt()1226 public NetworkStats getNetworkStatsSummaryXt() { 1227 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1228 try { 1229 return mStatsFactory.readNetworkStatsSummaryXt(); 1230 } catch (IOException e) { 1231 throw new IllegalStateException(e); 1232 } 1233 } 1234 1235 @Override getNetworkStatsDetail()1236 public NetworkStats getNetworkStatsDetail() { 1237 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1238 try { 1239 return mStatsFactory.readNetworkStatsDetail(UID_ALL, null, TAG_ALL, null); 1240 } catch (IOException e) { 1241 throw new IllegalStateException(e); 1242 } 1243 } 1244 1245 @Override setInterfaceQuota(String iface, long quotaBytes)1246 public void setInterfaceQuota(String iface, long quotaBytes) { 1247 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1248 1249 synchronized (mQuotaLock) { 1250 if (mActiveQuotas.containsKey(iface)) { 1251 throw new IllegalStateException("iface " + iface + " already has quota"); 1252 } 1253 1254 try { 1255 // TODO: support quota shared across interfaces 1256 mNetdService.bandwidthSetInterfaceQuota(iface, quotaBytes); 1257 1258 mActiveQuotas.put(iface, quotaBytes); 1259 } catch (RemoteException | ServiceSpecificException e) { 1260 throw new IllegalStateException(e); 1261 } 1262 1263 synchronized (mTetheringStatsProviders) { 1264 for (ITetheringStatsProvider provider : mTetheringStatsProviders.keySet()) { 1265 try { 1266 provider.setInterfaceQuota(iface, quotaBytes); 1267 } catch (RemoteException e) { 1268 Log.e(TAG, "Problem setting tethering data limit on provider " + 1269 mTetheringStatsProviders.get(provider) + ": " + e); 1270 } 1271 } 1272 } 1273 } 1274 } 1275 1276 @Override removeInterfaceQuota(String iface)1277 public void removeInterfaceQuota(String iface) { 1278 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1279 1280 synchronized (mQuotaLock) { 1281 if (!mActiveQuotas.containsKey(iface)) { 1282 // TODO: eventually consider throwing 1283 return; 1284 } 1285 1286 mActiveQuotas.remove(iface); 1287 mActiveAlerts.remove(iface); 1288 1289 try { 1290 // TODO: support quota shared across interfaces 1291 mNetdService.bandwidthRemoveInterfaceQuota(iface); 1292 } catch (RemoteException | ServiceSpecificException e) { 1293 throw new IllegalStateException(e); 1294 } 1295 1296 synchronized (mTetheringStatsProviders) { 1297 for (ITetheringStatsProvider provider : mTetheringStatsProviders.keySet()) { 1298 try { 1299 provider.setInterfaceQuota(iface, ITetheringStatsProvider.QUOTA_UNLIMITED); 1300 } catch (RemoteException e) { 1301 Log.e(TAG, "Problem removing tethering data limit on provider " + 1302 mTetheringStatsProviders.get(provider) + ": " + e); 1303 } 1304 } 1305 } 1306 } 1307 } 1308 1309 @Override setInterfaceAlert(String iface, long alertBytes)1310 public void setInterfaceAlert(String iface, long alertBytes) { 1311 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1312 1313 // quick sanity check 1314 if (!mActiveQuotas.containsKey(iface)) { 1315 throw new IllegalStateException("setting alert requires existing quota on iface"); 1316 } 1317 1318 synchronized (mQuotaLock) { 1319 if (mActiveAlerts.containsKey(iface)) { 1320 throw new IllegalStateException("iface " + iface + " already has alert"); 1321 } 1322 1323 try { 1324 // TODO: support alert shared across interfaces 1325 mNetdService.bandwidthSetInterfaceAlert(iface, alertBytes); 1326 mActiveAlerts.put(iface, alertBytes); 1327 } catch (RemoteException | ServiceSpecificException e) { 1328 throw new IllegalStateException(e); 1329 } 1330 } 1331 } 1332 1333 @Override removeInterfaceAlert(String iface)1334 public void removeInterfaceAlert(String iface) { 1335 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1336 1337 synchronized (mQuotaLock) { 1338 if (!mActiveAlerts.containsKey(iface)) { 1339 // TODO: eventually consider throwing 1340 return; 1341 } 1342 1343 try { 1344 // TODO: support alert shared across interfaces 1345 mNetdService.bandwidthRemoveInterfaceAlert(iface); 1346 mActiveAlerts.remove(iface); 1347 } catch (RemoteException | ServiceSpecificException e) { 1348 throw new IllegalStateException(e); 1349 } 1350 } 1351 } 1352 1353 @Override setGlobalAlert(long alertBytes)1354 public void setGlobalAlert(long alertBytes) { 1355 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1356 1357 try { 1358 mNetdService.bandwidthSetGlobalAlert(alertBytes); 1359 } catch (RemoteException | ServiceSpecificException e) { 1360 throw new IllegalStateException(e); 1361 } 1362 } 1363 setUidOnMeteredNetworkList(int uid, boolean blacklist, boolean enable)1364 private void setUidOnMeteredNetworkList(int uid, boolean blacklist, boolean enable) { 1365 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1366 1367 synchronized (mQuotaLock) { 1368 boolean oldEnable; 1369 SparseBooleanArray quotaList; 1370 synchronized (mRulesLock) { 1371 quotaList = blacklist ? mUidRejectOnMetered : mUidAllowOnMetered; 1372 oldEnable = quotaList.get(uid, false); 1373 } 1374 if (oldEnable == enable) { 1375 // TODO: eventually consider throwing 1376 return; 1377 } 1378 1379 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "inetd bandwidth"); 1380 try { 1381 if (blacklist) { 1382 if (enable) { 1383 mNetdService.bandwidthAddNaughtyApp(uid); 1384 } else { 1385 mNetdService.bandwidthRemoveNaughtyApp(uid); 1386 } 1387 } else { 1388 if (enable) { 1389 mNetdService.bandwidthAddNiceApp(uid); 1390 } else { 1391 mNetdService.bandwidthRemoveNiceApp(uid); 1392 } 1393 } 1394 synchronized (mRulesLock) { 1395 if (enable) { 1396 quotaList.put(uid, true); 1397 } else { 1398 quotaList.delete(uid); 1399 } 1400 } 1401 } catch (RemoteException | ServiceSpecificException e) { 1402 throw new IllegalStateException(e); 1403 } finally { 1404 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 1405 } 1406 } 1407 } 1408 1409 @Override setUidMeteredNetworkBlacklist(int uid, boolean enable)1410 public void setUidMeteredNetworkBlacklist(int uid, boolean enable) { 1411 setUidOnMeteredNetworkList(uid, true, enable); 1412 } 1413 1414 @Override setUidMeteredNetworkWhitelist(int uid, boolean enable)1415 public void setUidMeteredNetworkWhitelist(int uid, boolean enable) { 1416 setUidOnMeteredNetworkList(uid, false, enable); 1417 } 1418 1419 @Override setDataSaverModeEnabled(boolean enable)1420 public boolean setDataSaverModeEnabled(boolean enable) { 1421 mContext.enforceCallingOrSelfPermission(NETWORK_SETTINGS, TAG); 1422 1423 if (DBG) Log.d(TAG, "setDataSaverMode: " + enable); 1424 synchronized (mQuotaLock) { 1425 if (mDataSaverMode == enable) { 1426 Log.w(TAG, "setDataSaverMode(): already " + mDataSaverMode); 1427 return true; 1428 } 1429 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "bandwidthEnableDataSaver"); 1430 try { 1431 final boolean changed = mNetdService.bandwidthEnableDataSaver(enable); 1432 if (changed) { 1433 mDataSaverMode = enable; 1434 } else { 1435 Log.w(TAG, "setDataSaverMode(" + enable + "): netd command silently failed"); 1436 } 1437 return changed; 1438 } catch (RemoteException e) { 1439 Log.w(TAG, "setDataSaverMode(" + enable + "): netd command failed", e); 1440 return false; 1441 } finally { 1442 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 1443 } 1444 } 1445 } 1446 makeUidRangeParcel(int start, int stop)1447 private static UidRangeParcel makeUidRangeParcel(int start, int stop) { 1448 UidRangeParcel range = new UidRangeParcel(); 1449 range.start = start; 1450 range.stop = stop; 1451 return range; 1452 } 1453 toStableParcels(UidRange[] ranges)1454 private static UidRangeParcel[] toStableParcels(UidRange[] ranges) { 1455 UidRangeParcel[] stableRanges = new UidRangeParcel[ranges.length]; 1456 for (int i = 0; i < ranges.length; i++) { 1457 stableRanges[i] = makeUidRangeParcel(ranges[i].start, ranges[i].stop); 1458 } 1459 return stableRanges; 1460 } 1461 1462 @Override setAllowOnlyVpnForUids(boolean add, UidRange[] uidRanges)1463 public void setAllowOnlyVpnForUids(boolean add, UidRange[] uidRanges) 1464 throws ServiceSpecificException { 1465 mContext.enforceCallingOrSelfPermission(NETWORK_STACK, TAG); 1466 try { 1467 mNetdService.networkRejectNonSecureVpn(add, toStableParcels(uidRanges)); 1468 } catch (ServiceSpecificException e) { 1469 Log.w(TAG, "setAllowOnlyVpnForUids(" + add + ", " + Arrays.toString(uidRanges) + ")" 1470 + ": netd command failed", e); 1471 throw e; 1472 } catch (RemoteException e) { 1473 Log.w(TAG, "setAllowOnlyVpnForUids(" + add + ", " + Arrays.toString(uidRanges) + ")" 1474 + ": netd command failed", e); 1475 throw e.rethrowAsRuntimeException(); 1476 } 1477 } 1478 applyUidCleartextNetworkPolicy(int uid, int policy)1479 private void applyUidCleartextNetworkPolicy(int uid, int policy) { 1480 final int policyValue; 1481 switch (policy) { 1482 case StrictMode.NETWORK_POLICY_ACCEPT: 1483 policyValue = INetd.PENALTY_POLICY_ACCEPT; 1484 break; 1485 case StrictMode.NETWORK_POLICY_LOG: 1486 policyValue = INetd.PENALTY_POLICY_LOG; 1487 break; 1488 case StrictMode.NETWORK_POLICY_REJECT: 1489 policyValue = INetd.PENALTY_POLICY_REJECT; 1490 break; 1491 default: 1492 throw new IllegalArgumentException("Unknown policy " + policy); 1493 } 1494 1495 try { 1496 mNetdService.strictUidCleartextPenalty(uid, policyValue); 1497 mUidCleartextPolicy.put(uid, policy); 1498 } catch (RemoteException | ServiceSpecificException e) { 1499 throw new IllegalStateException(e); 1500 } 1501 } 1502 1503 @Override setUidCleartextNetworkPolicy(int uid, int policy)1504 public void setUidCleartextNetworkPolicy(int uid, int policy) { 1505 if (Binder.getCallingUid() != uid) { 1506 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1507 } 1508 1509 synchronized (mQuotaLock) { 1510 final int oldPolicy = mUidCleartextPolicy.get(uid, StrictMode.NETWORK_POLICY_ACCEPT); 1511 if (oldPolicy == policy) { 1512 // This also ensures we won't needlessly apply an ACCEPT policy if we've just 1513 // enabled strict and the underlying iptables rules are empty. 1514 return; 1515 } 1516 1517 // TODO: remove this code after removing prepareNativeDaemon() 1518 if (!mStrictEnabled) { 1519 // Module isn't enabled yet; stash the requested policy away to 1520 // apply later once the daemon is connected. 1521 mUidCleartextPolicy.put(uid, policy); 1522 return; 1523 } 1524 1525 // netd does not keep state on strict mode policies, and cannot replace a non-accept 1526 // policy without deleting it first. Rather than add state to netd, just always send 1527 // it an accept policy when switching between two non-accept policies. 1528 // TODO: consider keeping state in netd so we can simplify this code. 1529 if (oldPolicy != StrictMode.NETWORK_POLICY_ACCEPT && 1530 policy != StrictMode.NETWORK_POLICY_ACCEPT) { 1531 applyUidCleartextNetworkPolicy(uid, StrictMode.NETWORK_POLICY_ACCEPT); 1532 } 1533 1534 applyUidCleartextNetworkPolicy(uid, policy); 1535 } 1536 } 1537 1538 @Override isBandwidthControlEnabled()1539 public boolean isBandwidthControlEnabled() { 1540 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1541 return true; 1542 } 1543 1544 @Override getNetworkStatsUidDetail(int uid, String[] ifaces)1545 public NetworkStats getNetworkStatsUidDetail(int uid, String[] ifaces) { 1546 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1547 try { 1548 return mStatsFactory.readNetworkStatsDetail(uid, ifaces, TAG_ALL, null); 1549 } catch (IOException e) { 1550 throw new IllegalStateException(e); 1551 } 1552 } 1553 1554 private class NetdTetheringStatsProvider extends ITetheringStatsProvider.Stub { 1555 @Override getTetherStats(int how)1556 public NetworkStats getTetherStats(int how) { 1557 // We only need to return per-UID stats. Per-device stats are already counted by 1558 // interface counters. 1559 if (how != STATS_PER_UID) { 1560 return new NetworkStats(SystemClock.elapsedRealtime(), 0); 1561 } 1562 1563 final TetherStatsParcel[] tetherStatsVec; 1564 try { 1565 tetherStatsVec = mNetdService.tetherGetStats(); 1566 } catch (RemoteException | ServiceSpecificException e) { 1567 throw new IllegalStateException("problem parsing tethering stats: ", e); 1568 } 1569 1570 final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1571 tetherStatsVec.length); 1572 final NetworkStats.Entry entry = new NetworkStats.Entry(); 1573 1574 for (TetherStatsParcel tetherStats : tetherStatsVec) { 1575 try { 1576 entry.iface = tetherStats.iface; 1577 entry.uid = UID_TETHERING; 1578 entry.set = SET_DEFAULT; 1579 entry.tag = TAG_NONE; 1580 entry.rxBytes = tetherStats.rxBytes; 1581 entry.rxPackets = tetherStats.rxPackets; 1582 entry.txBytes = tetherStats.txBytes; 1583 entry.txPackets = tetherStats.txPackets; 1584 stats.combineValues(entry); 1585 } catch (ArrayIndexOutOfBoundsException e) { 1586 throw new IllegalStateException("invalid tethering stats " + e); 1587 } 1588 } 1589 1590 return stats; 1591 } 1592 1593 @Override setInterfaceQuota(String iface, long quotaBytes)1594 public void setInterfaceQuota(String iface, long quotaBytes) { 1595 // Do nothing. netd is already informed of quota changes in setInterfaceQuota. 1596 } 1597 } 1598 1599 @Override getNetworkStatsTethering(int how)1600 public NetworkStats getNetworkStatsTethering(int how) { 1601 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1602 1603 final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1); 1604 synchronized (mTetheringStatsProviders) { 1605 for (ITetheringStatsProvider provider: mTetheringStatsProviders.keySet()) { 1606 try { 1607 stats.combineAllValues(provider.getTetherStats(how)); 1608 } catch (RemoteException e) { 1609 Log.e(TAG, "Problem reading tethering stats from " + 1610 mTetheringStatsProviders.get(provider) + ": " + e); 1611 } 1612 } 1613 } 1614 return stats; 1615 } 1616 1617 @Override addVpnUidRanges(int netId, UidRange[] ranges)1618 public void addVpnUidRanges(int netId, UidRange[] ranges) { 1619 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1620 1621 try { 1622 mNetdService.networkAddUidRanges(netId, toStableParcels(ranges)); 1623 } catch (RemoteException | ServiceSpecificException e) { 1624 throw new IllegalStateException(e); 1625 } 1626 } 1627 1628 @Override removeVpnUidRanges(int netId, UidRange[] ranges)1629 public void removeVpnUidRanges(int netId, UidRange[] ranges) { 1630 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1631 try { 1632 mNetdService.networkRemoveUidRanges(netId, toStableParcels(ranges)); 1633 } catch (RemoteException | ServiceSpecificException e) { 1634 throw new IllegalStateException(e); 1635 } 1636 } 1637 1638 @Override setFirewallEnabled(boolean enabled)1639 public void setFirewallEnabled(boolean enabled) { 1640 enforceSystemUid(); 1641 try { 1642 mNetdService.firewallSetFirewallType( 1643 enabled ? INetd.FIREWALL_WHITELIST : INetd.FIREWALL_BLACKLIST); 1644 mFirewallEnabled = enabled; 1645 } catch (RemoteException | ServiceSpecificException e) { 1646 throw new IllegalStateException(e); 1647 } 1648 } 1649 1650 @Override isFirewallEnabled()1651 public boolean isFirewallEnabled() { 1652 enforceSystemUid(); 1653 return mFirewallEnabled; 1654 } 1655 1656 @Override setFirewallInterfaceRule(String iface, boolean allow)1657 public void setFirewallInterfaceRule(String iface, boolean allow) { 1658 enforceSystemUid(); 1659 Preconditions.checkState(mFirewallEnabled); 1660 try { 1661 mNetdService.firewallSetInterfaceRule(iface, 1662 allow ? INetd.FIREWALL_RULE_ALLOW : INetd.FIREWALL_RULE_DENY); 1663 } catch (RemoteException | ServiceSpecificException e) { 1664 throw new IllegalStateException(e); 1665 } 1666 } 1667 closeSocketsForFirewallChainLocked(int chain, String chainName)1668 private void closeSocketsForFirewallChainLocked(int chain, String chainName) { 1669 // UID ranges to close sockets on. 1670 UidRangeParcel[] ranges; 1671 // UID ranges whose sockets we won't touch. 1672 int[] exemptUids; 1673 1674 int numUids = 0; 1675 if (DBG) Slog.d(TAG, "Closing sockets after enabling chain " + chainName); 1676 if (getFirewallType(chain) == FIREWALL_WHITELIST) { 1677 // Close all sockets on all non-system UIDs... 1678 ranges = new UidRangeParcel[] { 1679 // TODO: is there a better way of finding all existing users? If so, we could 1680 // specify their ranges here. 1681 makeUidRangeParcel(Process.FIRST_APPLICATION_UID, Integer.MAX_VALUE), 1682 }; 1683 // ... except for the UIDs that have allow rules. 1684 synchronized (mRulesLock) { 1685 final SparseIntArray rules = getUidFirewallRulesLR(chain); 1686 exemptUids = new int[rules.size()]; 1687 for (int i = 0; i < exemptUids.length; i++) { 1688 if (rules.valueAt(i) == FIREWALL_RULE_ALLOW) { 1689 exemptUids[numUids] = rules.keyAt(i); 1690 numUids++; 1691 } 1692 } 1693 } 1694 // Normally, whitelist chains only contain deny rules, so numUids == exemptUids.length. 1695 // But the code does not guarantee this in any way, and at least in one case - if we add 1696 // a UID rule to the firewall, and then disable the firewall - the chains can contain 1697 // the wrong type of rule. In this case, don't close connections that we shouldn't. 1698 // 1699 // TODO: tighten up this code by ensuring we never set the wrong type of rule, and 1700 // fix setFirewallEnabled to grab mQuotaLock and clear rules. 1701 if (numUids != exemptUids.length) { 1702 exemptUids = Arrays.copyOf(exemptUids, numUids); 1703 } 1704 } else { 1705 // Close sockets for every UID that has a deny rule... 1706 synchronized (mRulesLock) { 1707 final SparseIntArray rules = getUidFirewallRulesLR(chain); 1708 ranges = new UidRangeParcel[rules.size()]; 1709 for (int i = 0; i < ranges.length; i++) { 1710 if (rules.valueAt(i) == FIREWALL_RULE_DENY) { 1711 int uid = rules.keyAt(i); 1712 ranges[numUids] = makeUidRangeParcel(uid, uid); 1713 numUids++; 1714 } 1715 } 1716 } 1717 // As above; usually numUids == ranges.length, but not always. 1718 if (numUids != ranges.length) { 1719 ranges = Arrays.copyOf(ranges, numUids); 1720 } 1721 // ... with no exceptions. 1722 exemptUids = new int[0]; 1723 } 1724 1725 try { 1726 mNetdService.socketDestroy(ranges, exemptUids); 1727 } catch(RemoteException | ServiceSpecificException e) { 1728 Slog.e(TAG, "Error closing sockets after enabling chain " + chainName + ": " + e); 1729 } 1730 } 1731 1732 @Override setFirewallChainEnabled(int chain, boolean enable)1733 public void setFirewallChainEnabled(int chain, boolean enable) { 1734 enforceSystemUid(); 1735 synchronized (mQuotaLock) { 1736 synchronized (mRulesLock) { 1737 if (getFirewallChainState(chain) == enable) { 1738 // All is the same, nothing to do. This relies on the fact that netd has child 1739 // chains default detached. 1740 return; 1741 } 1742 setFirewallChainState(chain, enable); 1743 } 1744 1745 final String chainName = getFirewallChainName(chain); 1746 if (chain == FIREWALL_CHAIN_NONE) { 1747 throw new IllegalArgumentException("Bad child chain: " + chainName); 1748 } 1749 1750 try { 1751 mNetdService.firewallEnableChildChain(chain, enable); 1752 } catch (RemoteException | ServiceSpecificException e) { 1753 throw new IllegalStateException(e); 1754 } 1755 1756 // Close any sockets that were opened by the affected UIDs. This has to be done after 1757 // disabling network connectivity, in case they react to the socket close by reopening 1758 // the connection and race with the iptables commands that enable the firewall. All 1759 // whitelist and blacklist chains allow RSTs through. 1760 if (enable) { 1761 closeSocketsForFirewallChainLocked(chain, chainName); 1762 } 1763 } 1764 } 1765 getFirewallChainName(int chain)1766 private String getFirewallChainName(int chain) { 1767 switch (chain) { 1768 case FIREWALL_CHAIN_STANDBY: 1769 return FIREWALL_CHAIN_NAME_STANDBY; 1770 case FIREWALL_CHAIN_DOZABLE: 1771 return FIREWALL_CHAIN_NAME_DOZABLE; 1772 case FIREWALL_CHAIN_POWERSAVE: 1773 return FIREWALL_CHAIN_NAME_POWERSAVE; 1774 default: 1775 throw new IllegalArgumentException("Bad child chain: " + chain); 1776 } 1777 } 1778 getFirewallType(int chain)1779 private int getFirewallType(int chain) { 1780 switch (chain) { 1781 case FIREWALL_CHAIN_STANDBY: 1782 return FIREWALL_BLACKLIST; 1783 case FIREWALL_CHAIN_DOZABLE: 1784 return FIREWALL_WHITELIST; 1785 case FIREWALL_CHAIN_POWERSAVE: 1786 return FIREWALL_WHITELIST; 1787 default: 1788 return isFirewallEnabled() ? FIREWALL_WHITELIST : FIREWALL_BLACKLIST; 1789 } 1790 } 1791 1792 @Override setFirewallUidRules(int chain, int[] uids, int[] rules)1793 public void setFirewallUidRules(int chain, int[] uids, int[] rules) { 1794 enforceSystemUid(); 1795 synchronized (mQuotaLock) { 1796 synchronized (mRulesLock) { 1797 SparseIntArray uidFirewallRules = getUidFirewallRulesLR(chain); 1798 SparseIntArray newRules = new SparseIntArray(); 1799 // apply new set of rules 1800 for (int index = uids.length - 1; index >= 0; --index) { 1801 int uid = uids[index]; 1802 int rule = rules[index]; 1803 updateFirewallUidRuleLocked(chain, uid, rule); 1804 newRules.put(uid, rule); 1805 } 1806 // collect the rules to remove. 1807 SparseIntArray rulesToRemove = new SparseIntArray(); 1808 for (int index = uidFirewallRules.size() - 1; index >= 0; --index) { 1809 int uid = uidFirewallRules.keyAt(index); 1810 if (newRules.indexOfKey(uid) < 0) { 1811 rulesToRemove.put(uid, FIREWALL_RULE_DEFAULT); 1812 } 1813 } 1814 // remove dead rules 1815 for (int index = rulesToRemove.size() - 1; index >= 0; --index) { 1816 int uid = rulesToRemove.keyAt(index); 1817 updateFirewallUidRuleLocked(chain, uid, FIREWALL_RULE_DEFAULT); 1818 } 1819 } 1820 try { 1821 switch (chain) { 1822 case FIREWALL_CHAIN_DOZABLE: 1823 mNetdService.firewallReplaceUidChain("fw_dozable", true, uids); 1824 break; 1825 case FIREWALL_CHAIN_STANDBY: 1826 mNetdService.firewallReplaceUidChain("fw_standby", false, uids); 1827 break; 1828 case FIREWALL_CHAIN_POWERSAVE: 1829 mNetdService.firewallReplaceUidChain("fw_powersave", true, uids); 1830 break; 1831 case FIREWALL_CHAIN_NONE: 1832 default: 1833 Slog.d(TAG, "setFirewallUidRules() called on invalid chain: " + chain); 1834 } 1835 } catch (RemoteException e) { 1836 Slog.w(TAG, "Error flushing firewall chain " + chain, e); 1837 } 1838 } 1839 } 1840 1841 @Override setFirewallUidRule(int chain, int uid, int rule)1842 public void setFirewallUidRule(int chain, int uid, int rule) { 1843 enforceSystemUid(); 1844 synchronized (mQuotaLock) { 1845 setFirewallUidRuleLocked(chain, uid, rule); 1846 } 1847 } 1848 setFirewallUidRuleLocked(int chain, int uid, int rule)1849 private void setFirewallUidRuleLocked(int chain, int uid, int rule) { 1850 if (updateFirewallUidRuleLocked(chain, uid, rule)) { 1851 final int ruleType = getFirewallRuleType(chain, rule); 1852 try { 1853 mNetdService.firewallSetUidRule(chain, uid, ruleType); 1854 } catch (RemoteException | ServiceSpecificException e) { 1855 throw new IllegalStateException(e); 1856 } 1857 } 1858 } 1859 1860 // TODO: now that netd supports batching, NMS should not keep these data structures anymore... updateFirewallUidRuleLocked(int chain, int uid, int rule)1861 private boolean updateFirewallUidRuleLocked(int chain, int uid, int rule) { 1862 synchronized (mRulesLock) { 1863 SparseIntArray uidFirewallRules = getUidFirewallRulesLR(chain); 1864 1865 final int oldUidFirewallRule = uidFirewallRules.get(uid, FIREWALL_RULE_DEFAULT); 1866 if (DBG) { 1867 Slog.d(TAG, "oldRule = " + oldUidFirewallRule 1868 + ", newRule=" + rule + " for uid=" + uid + " on chain " + chain); 1869 } 1870 if (oldUidFirewallRule == rule) { 1871 if (DBG) Slog.d(TAG, "!!!!! Skipping change"); 1872 // TODO: eventually consider throwing 1873 return false; 1874 } 1875 1876 String ruleName = getFirewallRuleName(chain, rule); 1877 String oldRuleName = getFirewallRuleName(chain, oldUidFirewallRule); 1878 1879 if (rule == NetworkPolicyManager.FIREWALL_RULE_DEFAULT) { 1880 uidFirewallRules.delete(uid); 1881 } else { 1882 uidFirewallRules.put(uid, rule); 1883 } 1884 return !ruleName.equals(oldRuleName); 1885 } 1886 } 1887 getFirewallRuleName(int chain, int rule)1888 private @NonNull String getFirewallRuleName(int chain, int rule) { 1889 String ruleName; 1890 if (getFirewallType(chain) == FIREWALL_WHITELIST) { 1891 if (rule == FIREWALL_RULE_ALLOW) { 1892 ruleName = "allow"; 1893 } else { 1894 ruleName = "deny"; 1895 } 1896 } else { // Blacklist mode 1897 if (rule == FIREWALL_RULE_DENY) { 1898 ruleName = "deny"; 1899 } else { 1900 ruleName = "allow"; 1901 } 1902 } 1903 return ruleName; 1904 } 1905 1906 @GuardedBy("mRulesLock") getUidFirewallRulesLR(int chain)1907 private @NonNull SparseIntArray getUidFirewallRulesLR(int chain) { 1908 switch (chain) { 1909 case FIREWALL_CHAIN_STANDBY: 1910 return mUidFirewallStandbyRules; 1911 case FIREWALL_CHAIN_DOZABLE: 1912 return mUidFirewallDozableRules; 1913 case FIREWALL_CHAIN_POWERSAVE: 1914 return mUidFirewallPowerSaveRules; 1915 case FIREWALL_CHAIN_NONE: 1916 return mUidFirewallRules; 1917 default: 1918 throw new IllegalArgumentException("Unknown chain:" + chain); 1919 } 1920 } 1921 getFirewallRuleType(int chain, int rule)1922 private int getFirewallRuleType(int chain, int rule) { 1923 if (rule == NetworkPolicyManager.FIREWALL_RULE_DEFAULT) { 1924 return getFirewallType(chain) == FIREWALL_WHITELIST 1925 ? INetd.FIREWALL_RULE_DENY : INetd.FIREWALL_RULE_ALLOW; 1926 } 1927 return rule; 1928 } 1929 enforceSystemUid()1930 private static void enforceSystemUid() { 1931 final int uid = Binder.getCallingUid(); 1932 if (uid != Process.SYSTEM_UID) { 1933 throw new SecurityException("Only available to AID_SYSTEM"); 1934 } 1935 } 1936 1937 @Override registerNetworkActivityListener(INetworkActivityListener listener)1938 public void registerNetworkActivityListener(INetworkActivityListener listener) { 1939 mNetworkActivityListeners.register(listener); 1940 } 1941 1942 @Override unregisterNetworkActivityListener(INetworkActivityListener listener)1943 public void unregisterNetworkActivityListener(INetworkActivityListener listener) { 1944 mNetworkActivityListeners.unregister(listener); 1945 } 1946 1947 @Override isNetworkActive()1948 public boolean isNetworkActive() { 1949 synchronized (mNetworkActivityListeners) { 1950 return mNetworkActive || mActiveIdleTimers.isEmpty(); 1951 } 1952 } 1953 reportNetworkActive()1954 private void reportNetworkActive() { 1955 final int length = mNetworkActivityListeners.beginBroadcast(); 1956 try { 1957 for (int i = 0; i < length; i++) { 1958 try { 1959 mNetworkActivityListeners.getBroadcastItem(i).onNetworkActive(); 1960 } catch (RemoteException | RuntimeException e) { 1961 } 1962 } 1963 } finally { 1964 mNetworkActivityListeners.finishBroadcast(); 1965 } 1966 } 1967 1968 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)1969 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1970 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; 1971 1972 pw.print("mMobileActivityFromRadio="); pw.print(mMobileActivityFromRadio); 1973 pw.print(" mLastPowerStateFromRadio="); pw.println(mLastPowerStateFromRadio); 1974 pw.print("mNetworkActive="); pw.println(mNetworkActive); 1975 1976 synchronized (mQuotaLock) { 1977 pw.print("Active quota ifaces: "); pw.println(mActiveQuotas.toString()); 1978 pw.print("Active alert ifaces: "); pw.println(mActiveAlerts.toString()); 1979 pw.print("Data saver mode: "); pw.println(mDataSaverMode); 1980 synchronized (mRulesLock) { 1981 dumpUidRuleOnQuotaLocked(pw, "blacklist", mUidRejectOnMetered); 1982 dumpUidRuleOnQuotaLocked(pw, "whitelist", mUidAllowOnMetered); 1983 } 1984 } 1985 1986 synchronized (mRulesLock) { 1987 dumpUidFirewallRule(pw, "", mUidFirewallRules); 1988 1989 pw.print("UID firewall standby chain enabled: "); pw.println( 1990 getFirewallChainState(FIREWALL_CHAIN_STANDBY)); 1991 dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_STANDBY, mUidFirewallStandbyRules); 1992 1993 pw.print("UID firewall dozable chain enabled: "); pw.println( 1994 getFirewallChainState(FIREWALL_CHAIN_DOZABLE)); 1995 dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_DOZABLE, mUidFirewallDozableRules); 1996 1997 pw.println("UID firewall powersave chain enabled: " + 1998 getFirewallChainState(FIREWALL_CHAIN_POWERSAVE)); 1999 dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_POWERSAVE, mUidFirewallPowerSaveRules); 2000 } 2001 2002 synchronized (mIdleTimerLock) { 2003 pw.println("Idle timers:"); 2004 for (HashMap.Entry<String, IdleTimerParams> ent : mActiveIdleTimers.entrySet()) { 2005 pw.print(" "); pw.print(ent.getKey()); pw.println(":"); 2006 IdleTimerParams params = ent.getValue(); 2007 pw.print(" timeout="); pw.print(params.timeout); 2008 pw.print(" type="); pw.print(params.type); 2009 pw.print(" networkCount="); pw.println(params.networkCount); 2010 } 2011 } 2012 2013 pw.print("Firewall enabled: "); pw.println(mFirewallEnabled); 2014 pw.print("Netd service status: " ); 2015 if (mNetdService == null) { 2016 pw.println("disconnected"); 2017 } else { 2018 try { 2019 final boolean alive = mNetdService.isAlive(); 2020 pw.println(alive ? "alive": "dead"); 2021 } catch (RemoteException e) { 2022 pw.println("unreachable"); 2023 } 2024 } 2025 } 2026 dumpUidRuleOnQuotaLocked(PrintWriter pw, String name, SparseBooleanArray list)2027 private void dumpUidRuleOnQuotaLocked(PrintWriter pw, String name, SparseBooleanArray list) { 2028 pw.print("UID bandwith control "); 2029 pw.print(name); 2030 pw.print(" rule: ["); 2031 final int size = list.size(); 2032 for (int i = 0; i < size; i++) { 2033 pw.print(list.keyAt(i)); 2034 if (i < size - 1) pw.print(","); 2035 } 2036 pw.println("]"); 2037 } 2038 dumpUidFirewallRule(PrintWriter pw, String name, SparseIntArray rules)2039 private void dumpUidFirewallRule(PrintWriter pw, String name, SparseIntArray rules) { 2040 pw.print("UID firewall "); 2041 pw.print(name); 2042 pw.print(" rule: ["); 2043 final int size = rules.size(); 2044 for (int i = 0; i < size; i++) { 2045 pw.print(rules.keyAt(i)); 2046 pw.print(":"); 2047 pw.print(rules.valueAt(i)); 2048 if (i < size - 1) pw.print(","); 2049 } 2050 pw.println("]"); 2051 } 2052 2053 @Override addInterfaceToNetwork(String iface, int netId)2054 public void addInterfaceToNetwork(String iface, int netId) { 2055 modifyInterfaceInNetwork(MODIFY_OPERATION_ADD, netId, iface); 2056 } 2057 2058 @Override removeInterfaceFromNetwork(String iface, int netId)2059 public void removeInterfaceFromNetwork(String iface, int netId) { 2060 modifyInterfaceInNetwork(MODIFY_OPERATION_REMOVE, netId, iface); 2061 } 2062 modifyInterfaceInNetwork(boolean add, int netId, String iface)2063 private void modifyInterfaceInNetwork(boolean add, int netId, String iface) { 2064 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 2065 try { 2066 if (add) { 2067 mNetdService.networkAddInterface(netId, iface); 2068 } else { 2069 mNetdService.networkRemoveInterface(netId, iface); 2070 } 2071 } catch (RemoteException | ServiceSpecificException e) { 2072 throw new IllegalStateException(e); 2073 } 2074 } 2075 2076 @Override addLegacyRouteForNetId(int netId, RouteInfo routeInfo, int uid)2077 public void addLegacyRouteForNetId(int netId, RouteInfo routeInfo, int uid) { 2078 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 2079 2080 final LinkAddress la = routeInfo.getDestinationLinkAddress(); 2081 final String ifName = routeInfo.getInterface(); 2082 final String dst = la.toString(); 2083 final String nextHop; 2084 2085 if (routeInfo.hasGateway()) { 2086 nextHop = routeInfo.getGateway().getHostAddress(); 2087 } else { 2088 nextHop = ""; 2089 } 2090 try { 2091 mNetdService.networkAddLegacyRoute(netId, ifName, dst, nextHop, uid); 2092 } catch (RemoteException | ServiceSpecificException e) { 2093 throw new IllegalStateException(e); 2094 } 2095 } 2096 2097 @Override setDefaultNetId(int netId)2098 public void setDefaultNetId(int netId) { 2099 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 2100 2101 try { 2102 mNetdService.networkSetDefault(netId); 2103 } catch (RemoteException | ServiceSpecificException e) { 2104 throw new IllegalStateException(e); 2105 } 2106 } 2107 2108 @Override clearDefaultNetId()2109 public void clearDefaultNetId() { 2110 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 2111 2112 try { 2113 mNetdService.networkClearDefault(); 2114 } catch (RemoteException | ServiceSpecificException e) { 2115 throw new IllegalStateException(e); 2116 } 2117 } 2118 2119 @Override setNetworkPermission(int netId, int permission)2120 public void setNetworkPermission(int netId, int permission) { 2121 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 2122 2123 try { 2124 mNetdService.networkSetPermissionForNetwork(netId, permission); 2125 } catch (RemoteException | ServiceSpecificException e) { 2126 throw new IllegalStateException(e); 2127 } 2128 } 2129 2130 @Override allowProtect(int uid)2131 public void allowProtect(int uid) { 2132 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 2133 2134 try { 2135 mNetdService.networkSetProtectAllow(uid); 2136 } catch (RemoteException | ServiceSpecificException e) { 2137 throw new IllegalStateException(e); 2138 } 2139 } 2140 2141 @Override denyProtect(int uid)2142 public void denyProtect(int uid) { 2143 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 2144 2145 try { 2146 mNetdService.networkSetProtectDeny(uid); 2147 } catch (RemoteException | ServiceSpecificException e) { 2148 throw new IllegalStateException(e); 2149 } 2150 } 2151 2152 @Override addInterfaceToLocalNetwork(String iface, List<RouteInfo> routes)2153 public void addInterfaceToLocalNetwork(String iface, List<RouteInfo> routes) { 2154 modifyInterfaceInNetwork(MODIFY_OPERATION_ADD, INetd.LOCAL_NET_ID, iface); 2155 2156 for (RouteInfo route : routes) { 2157 if (!route.isDefaultRoute()) { 2158 modifyRoute(MODIFY_OPERATION_ADD, INetd.LOCAL_NET_ID, route); 2159 } 2160 } 2161 2162 // IPv6 link local should be activated always. 2163 modifyRoute(MODIFY_OPERATION_ADD, INetd.LOCAL_NET_ID, 2164 new RouteInfo(new IpPrefix("fe80::/64"), null, iface)); 2165 } 2166 2167 @Override removeInterfaceFromLocalNetwork(String iface)2168 public void removeInterfaceFromLocalNetwork(String iface) { 2169 modifyInterfaceInNetwork(MODIFY_OPERATION_REMOVE, INetd.LOCAL_NET_ID, iface); 2170 } 2171 2172 @Override removeRoutesFromLocalNetwork(List<RouteInfo> routes)2173 public int removeRoutesFromLocalNetwork(List<RouteInfo> routes) { 2174 int failures = 0; 2175 2176 for (RouteInfo route : routes) { 2177 try { 2178 modifyRoute(MODIFY_OPERATION_REMOVE, INetd.LOCAL_NET_ID, route); 2179 } catch (IllegalStateException e) { 2180 failures++; 2181 } 2182 } 2183 2184 return failures; 2185 } 2186 2187 @Override isNetworkRestricted(int uid)2188 public boolean isNetworkRestricted(int uid) { 2189 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 2190 return isNetworkRestrictedInternal(uid); 2191 } 2192 isNetworkRestrictedInternal(int uid)2193 private boolean isNetworkRestrictedInternal(int uid) { 2194 synchronized (mRulesLock) { 2195 if (getFirewallChainState(FIREWALL_CHAIN_STANDBY) 2196 && mUidFirewallStandbyRules.get(uid) == FIREWALL_RULE_DENY) { 2197 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of app standby mode"); 2198 return true; 2199 } 2200 if (getFirewallChainState(FIREWALL_CHAIN_DOZABLE) 2201 && mUidFirewallDozableRules.get(uid) != FIREWALL_RULE_ALLOW) { 2202 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of device idle mode"); 2203 return true; 2204 } 2205 if (getFirewallChainState(FIREWALL_CHAIN_POWERSAVE) 2206 && mUidFirewallPowerSaveRules.get(uid) != FIREWALL_RULE_ALLOW) { 2207 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of power saver mode"); 2208 return true; 2209 } 2210 if (mUidRejectOnMetered.get(uid)) { 2211 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of no metered data" 2212 + " in the background"); 2213 return true; 2214 } 2215 if (mDataSaverMode && !mUidAllowOnMetered.get(uid)) { 2216 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of data saver mode"); 2217 return true; 2218 } 2219 return false; 2220 } 2221 } 2222 setFirewallChainState(int chain, boolean state)2223 private void setFirewallChainState(int chain, boolean state) { 2224 synchronized (mRulesLock) { 2225 mFirewallChainStates.put(chain, state); 2226 } 2227 } 2228 getFirewallChainState(int chain)2229 private boolean getFirewallChainState(int chain) { 2230 synchronized (mRulesLock) { 2231 return mFirewallChainStates.get(chain); 2232 } 2233 } 2234 2235 @VisibleForTesting 2236 class LocalService extends NetworkManagementInternal { 2237 @Override isNetworkRestrictedForUid(int uid)2238 public boolean isNetworkRestrictedForUid(int uid) { 2239 return isNetworkRestrictedInternal(uid); 2240 } 2241 } 2242 2243 @VisibleForTesting getInjector()2244 Injector getInjector() { 2245 return new Injector(); 2246 } 2247 2248 @VisibleForTesting 2249 class Injector { setDataSaverMode(boolean dataSaverMode)2250 void setDataSaverMode(boolean dataSaverMode) { 2251 mDataSaverMode = dataSaverMode; 2252 } 2253 setFirewallChainState(int chain, boolean state)2254 void setFirewallChainState(int chain, boolean state) { 2255 NetworkManagementService.this.setFirewallChainState(chain, state); 2256 } 2257 setFirewallRule(int chain, int uid, int rule)2258 void setFirewallRule(int chain, int uid, int rule) { 2259 synchronized (mRulesLock) { 2260 getUidFirewallRulesLR(chain).put(uid, rule); 2261 } 2262 } 2263 setUidOnMeteredNetworkList(boolean blacklist, int uid, boolean enable)2264 void setUidOnMeteredNetworkList(boolean blacklist, int uid, boolean enable) { 2265 synchronized (mRulesLock) { 2266 if (blacklist) { 2267 mUidRejectOnMetered.put(uid, enable); 2268 } else { 2269 mUidAllowOnMetered.put(uid, enable); 2270 } 2271 } 2272 } 2273 reset()2274 void reset() { 2275 synchronized (mRulesLock) { 2276 setDataSaverMode(false); 2277 final int[] chains = { 2278 FIREWALL_CHAIN_DOZABLE, 2279 FIREWALL_CHAIN_STANDBY, 2280 FIREWALL_CHAIN_POWERSAVE 2281 }; 2282 for (int chain : chains) { 2283 setFirewallChainState(chain, false); 2284 getUidFirewallRulesLR(chain).clear(); 2285 } 2286 mUidAllowOnMetered.clear(); 2287 mUidRejectOnMetered.clear(); 2288 } 2289 } 2290 } 2291 } 2292