NetlinkTracker.java revision c18cbfdf8d40e7a526a088225cb32341e1ea0920
110accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti/* 210accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * Copyright (C) 2014 The Android Open Source Project 310accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * 410accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * Licensed under the Apache License, Version 2.0 (the "License"); 510accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * you may not use this file except in compliance with the License. 610accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * You may obtain a copy of the License at 710accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * 810accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * http://www.apache.org/licenses/LICENSE-2.0 910accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * 1010accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * Unless required by applicable law or agreed to in writing, software 1110accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * distributed under the License is distributed on an "AS IS" BASIS, 1210accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1310accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * See the License for the specific language governing permissions and 1410accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * limitations under the License. 1510accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti */ 1610accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti 1710accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colittipackage com.android.server.net; 1810accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti 1910accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colittiimport android.net.LinkAddress; 2010accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colittiimport android.net.LinkProperties; 21c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colittiimport android.net.RouteInfo; 2210accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colittiimport android.util.Log; 2310accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti 2410accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti/** 2510accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * Keeps track of link configuration received from Netlink. 2610accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * 2710accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * Instances of this class are expected to be owned by subsystems such as Wi-Fi 2810accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * or Ethernet that manage one or more network interfaces. Each interface to be 2910accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * tracked needs its own {@code NetlinkTracker}. 3010accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * 3110accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * An instance of this class is constructed by passing in an interface name and 3210accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * a callback. The owner is then responsible for registering the tracker with 3310accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * NetworkManagementService. When the class receives update notifications from 3410accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * the NetworkManagementService notification threads, it applies the update to 3510accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * its local LinkProperties, and if something has changed, notifies its owner of 3610accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * the update via the callback. 3710accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * 3810accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * The owner can then call {@code getLinkProperties()} in order to find out 3910accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * what changed. If in the meantime the LinkProperties stored here have changed, 4010accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * this class will return the current LinkProperties. Because each change 4110accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * triggers an update callback after the change is made, the owner may get more 4210accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * callbacks than strictly necessary (some of which may be no-ops), but will not 4310accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * be out of sync once all callbacks have been processed. 4410accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * 4510accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * Threading model: 4610accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * 4710accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * - The owner of this class is expected to create it, register it, and call 4810accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * getLinkProperties or clearLinkProperties on its thread. 4910accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * - Most of the methods in the class are inherited from BaseNetworkObserver 5010accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * and are called by NetworkManagementService notification threads. 5110accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * - All accesses to mLinkProperties must be synchronized(this). All the other 5210accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * member variables are immutable once the object is constructed. 5310accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * 5410accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * This class currently tracks IPv4 and IPv6 addresses. In the future it will 5510accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * track routes and DNS servers. 5610accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * 5710accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * @hide 5810accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti */ 5910accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colittipublic class NetlinkTracker extends BaseNetworkObserver { 6010accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti 6110accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti private final String TAG; 6210accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti 6310accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti public interface Callback { 6410accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti public void update(); 6510accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti } 6610accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti 6710accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti private final String mInterfaceName; 6810accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti private final Callback mCallback; 6910accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti private final LinkProperties mLinkProperties; 7010accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti 7110accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti private static final boolean DBG = true; 7210accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti 7310accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti public NetlinkTracker(String iface, Callback callback) { 7410accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti TAG = "NetlinkTracker/" + iface; 7510accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti mInterfaceName = iface; 7610accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti mCallback = callback; 7710accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti mLinkProperties = new LinkProperties(); 7810accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti mLinkProperties.setInterfaceName(mInterfaceName); 7910accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti } 8010accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti 8110accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti private void maybeLog(String operation, String iface, LinkAddress address) { 8210accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti if (DBG) { 8310accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti Log.d(TAG, operation + ": " + address + " on " + iface + 8410accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti " flags " + address.getFlags() + " scope " + address.getScope()); 8510accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti } 8610accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti } 8710accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti 88c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti private void maybeLog(String operation, Object o) { 89c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti if (DBG) { 90c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti Log.d(TAG, operation + ": " + o.toString()); 91c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti } 92c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti } 93c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti 9410accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti @Override 9510accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti public void addressUpdated(String iface, LinkAddress address) { 9610accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti if (mInterfaceName.equals(iface)) { 9710accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti maybeLog("addressUpdated", iface, address); 9810accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti boolean changed; 9910accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti synchronized (this) { 10010accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti changed = mLinkProperties.addLinkAddress(address); 10110accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti } 10210accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti if (changed) { 10310accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti mCallback.update(); 10410accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti } 10510accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti } 10610accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti } 10710accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti 10810accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti @Override 10910accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti public void addressRemoved(String iface, LinkAddress address) { 11010accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti if (mInterfaceName.equals(iface)) { 11110accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti maybeLog("addressRemoved", iface, address); 11210accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti boolean changed; 11310accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti synchronized (this) { 11410accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti changed = mLinkProperties.removeLinkAddress(address); 11510accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti } 11610accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti if (changed) { 11710accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti mCallback.update(); 11810accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti } 11910accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti } 12010accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti } 12110accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti 122c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti @Override 123c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti public void routeUpdated(RouteInfo route) { 124c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti if (mInterfaceName.equals(route.getInterface())) { 125c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti maybeLog("routeUpdated", route); 126c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti boolean changed; 127c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti synchronized (this) { 128c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti changed = mLinkProperties.addRoute(route); 129c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti } 130c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti if (changed) { 131c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti mCallback.update(); 132c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti } 133c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti } 134c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti } 135c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti 136c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti @Override 137c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti public void routeRemoved(RouteInfo route) { 138c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti if (mInterfaceName.equals(route.getInterface())) { 139c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti maybeLog("routeRemoved", route); 140c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti boolean changed; 141c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti synchronized (this) { 142c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti changed = mLinkProperties.removeRoute(route); 143c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti } 144c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti if (changed) { 145c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti mCallback.update(); 146c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti } 147c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti } 148c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti } 149c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti 15010accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti /** 15110accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * Returns a copy of this object's LinkProperties. 15210accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti */ 15310accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti public synchronized LinkProperties getLinkProperties() { 15410accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti return new LinkProperties(mLinkProperties); 15510accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti } 15610accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti 15710accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti public synchronized void clearLinkProperties() { 15810accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti mLinkProperties.clear(); 15910accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti mLinkProperties.setInterfaceName(mInterfaceName); 16010accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti } 16110accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti} 162