Loading services/core/java/com/android/server/connectivity/Tethering.java +10 −0 Original line number Diff line number Diff line Loading @@ -1392,6 +1392,8 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering for (Integer netType : mUpstreamIfaceTypes) { NetworkInfo info = cm.getNetworkInfo(netType.intValue()); // TODO: if the network is suspended we should consider // that to be the same as connected here. if ((info != null) && info.isConnected()) { upType = netType.intValue(); break; Loading Loading @@ -1465,6 +1467,10 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering // it immediately, because there likely will be no second // EVENT_ON_AVAILABLE (it was already received). handleNewUpstreamNetworkState(ns); } else if (mCurrentUpstreamIface == null) { // There are no available upstream networks, or none that // have an IPv4 default route (current metric for success). handleNewUpstreamNetworkState(null); } } Loading Loading @@ -1639,6 +1645,7 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering chooseUpstreamType(mTryCell); mTryCell = !mTryCell; } @Override public void exit() { // TODO: examine if we should check the return value. Loading @@ -1646,7 +1653,9 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering mUpstreamNetworkMonitor.stop(); stopListeningForSimChanges(); notifyTetheredOfNewUpstreamIface(null); handleNewUpstreamNetworkState(null); } @Override public boolean processMessage(Message message) { maybeLogMessage(this, message.what); Loading Loading @@ -1734,6 +1743,7 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering // reevaluation is triggered via received CONNECTIVITY_ACTION // broadcasts that result in being passed a // TetherMasterSM.CMD_UPSTREAM_CHANGED. handleNewUpstreamNetworkState(null); break; default: break; Loading services/core/java/com/android/server/connectivity/tethering/IPv6TetheringCoordinator.java +9 −9 Original line number Diff line number Diff line Loading @@ -55,7 +55,7 @@ public class IPv6TetheringCoordinator { if (VDBG) { Log.d(TAG, "updateUpstreamNetworkState: " + toDebugString(ns)); } if (ns == null || ns.network == null) { if (!canTetherIPv6(ns)) { stopIPv6TetheringOnAllInterfaces(); setUpstreamNetworkState(null); return; Loading @@ -65,8 +65,9 @@ public class IPv6TetheringCoordinator { !ns.network.equals(mUpstreamNetworkState.network)) { stopIPv6TetheringOnAllInterfaces(); } setUpstreamNetworkState(ns); maybeUpdateIPv6TetheringInterfaces(); updateIPv6TetheringInterfaces(); } private void stopIPv6TetheringOnAllInterfaces() { Loading @@ -77,9 +78,10 @@ public class IPv6TetheringCoordinator { } private void setUpstreamNetworkState(NetworkState ns) { if (!canTetherIPv6(ns)) { if (ns == null) { mUpstreamNetworkState = null; } else { // Make a deep copy of the parts we need. mUpstreamNetworkState = new NetworkState( null, new LinkProperties(ns.linkProperties), Loading @@ -94,19 +96,17 @@ public class IPv6TetheringCoordinator { } } private void maybeUpdateIPv6TetheringInterfaces() { if (mUpstreamNetworkState == null) return; private void updateIPv6TetheringInterfaces() { for (TetherInterfaceStateMachine sm : mNotifyList) { final LinkProperties lp = getInterfaceIPv6LinkProperties(sm.interfaceType()); if (lp != null) { sm.sendMessage(TetherInterfaceStateMachine.CMD_IPV6_TETHER_UPDATE, 0, 0, lp); } break; } } private LinkProperties getInterfaceIPv6LinkProperties(int interfaceType) { if (mUpstreamNetworkState == null) return null; // NOTE: Here, in future, we would have policies to decide how to divvy // up the available dedicated prefixes among downstream interfaces. // At this time we have no such mechanism--we only support tethering Loading services/core/java/com/android/server/connectivity/tethering/IPv6TetheringInterfaceServices.java +148 −60 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.connectivity.tethering; import android.net.INetd; import android.net.IpPrefix; import android.net.LinkAddress; import android.net.LinkProperties; Loading @@ -27,13 +28,16 @@ import android.net.ip.RouterAdvertisementDaemon.RaParams; import android.os.INetworkManagementService; import android.os.RemoteException; import android.util.Log; import android.util.Slog; import java.net.Inet6Address; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.HashSet; import java.util.Objects; /** Loading @@ -41,13 +45,15 @@ import java.util.HashSet; */ class IPv6TetheringInterfaceServices { private static final String TAG = IPv6TetheringInterfaceServices.class.getSimpleName(); private static final IpPrefix LINK_LOCAL_PREFIX = new IpPrefix("fe80::/64"); private static final int RFC7421_IP_PREFIX_LENGTH = 64; private final String mIfName; private final INetworkManagementService mNMService; private NetworkInterface mNetworkInterface; private byte[] mHwAddr; private ArrayList<RouteInfo> mLastLocalRoutes; private LinkProperties mLastIPv6LinkProperties; private RouterAdvertisementDaemon mRaDaemon; private RaParams mLastRaParams; Loading Loading @@ -86,8 +92,7 @@ class IPv6TetheringInterfaceServices { public void stop() { mNetworkInterface = null; mHwAddr = null; updateLocalRoutes(null); updateRaParams(null); setRaParams(null); if (mRaDaemon != null) { mRaDaemon.stop(); Loading @@ -104,95 +109,178 @@ class IPv6TetheringInterfaceServices { public void updateUpstreamIPv6LinkProperties(LinkProperties v6only) { if (mRaDaemon == null) return; if (v6only == null) { updateLocalRoutes(null); updateRaParams(null); // Avoid unnecessary work on spurious updates. if (Objects.equals(mLastIPv6LinkProperties, v6only)) { return; } RaParams params = new RaParams(); RaParams params = null; if (v6only != null) { params = new RaParams(); params.mtu = v6only.getMtu(); params.hasDefaultRoute = v6only.hasIPv6DefaultRoute(); ArrayList<RouteInfo> localRoutes = new ArrayList<RouteInfo>(); for (LinkAddress linkAddr : v6only.getLinkAddresses()) { final IpPrefix prefix = new IpPrefix(linkAddr.getAddress(), linkAddr.getPrefixLength()); // Accumulate routes representing "prefixes to be assigned to the // local interface", for subsequent addition to the local network // in the routing rules. localRoutes.add(new RouteInfo(prefix, null, mIfName)); if (linkAddr.getPrefixLength() != RFC7421_IP_PREFIX_LENGTH) continue; final IpPrefix prefix = new IpPrefix( linkAddr.getAddress(), linkAddr.getPrefixLength()); params.prefixes.add(prefix); final Inet6Address dnsServer = getLocalDnsIpFor(prefix); if (dnsServer != null) { params.dnses.add(dnsServer); } } } // If v6only is null, we pass in null to setRaParams(), which handles // deprecation of any existing RA data. setRaParams(params); mLastIPv6LinkProperties = v6only; } // We need to be able to send unicast RAs, and clients might like to // ping the default router's link-local address, so add that as well. localRoutes.add(new RouteInfo(new IpPrefix("fe80::/64"), null, mIfName)); // TODO: Add a local interface address, update dnsmasq to listen on the // new address, and use only that address as a DNS server. for (InetAddress dnsServer : v6only.getDnsServers()) { if (dnsServer instanceof Inet6Address) { params.dnses.add((Inet6Address) dnsServer); private void configureLocalRoutes( HashSet<IpPrefix> deprecatedPrefixes, HashSet<IpPrefix> newPrefixes) { // [1] Remove the routes that are deprecated. if (!deprecatedPrefixes.isEmpty()) { final ArrayList<RouteInfo> toBeRemoved = getLocalRoutesFor(deprecatedPrefixes); try { final int removalFailures = mNMService.removeRoutesFromLocalNetwork(toBeRemoved); if (removalFailures > 0) { Log.e(TAG, String.format("Failed to remove %d IPv6 routes from local table.", removalFailures)); } } catch (RemoteException e) { Log.e(TAG, "Failed to remove IPv6 routes from local table: ", e); } } updateLocalRoutes(localRoutes); updateRaParams(params); // [2] Add only the routes that have not previously been added. if (newPrefixes != null && !newPrefixes.isEmpty()) { HashSet<IpPrefix> addedPrefixes = (HashSet) newPrefixes.clone(); if (mLastRaParams != null) { addedPrefixes.removeAll(mLastRaParams.prefixes); } private void updateLocalRoutes(ArrayList<RouteInfo> localRoutes) { if (localRoutes != null) { // TODO: Compare with mLastLocalRoutes and take appropriate // appropriate action on the difference between the two. if (mLastRaParams == null || mLastRaParams.prefixes.isEmpty()) { // We need to be able to send unicast RAs, and clients might // like to ping the default router's link-local address. Note // that we never remove the link-local route from the network // until Tethering disables tethering on the interface. addedPrefixes.add(LINK_LOCAL_PREFIX); } if (!localRoutes.isEmpty()) { if (!addedPrefixes.isEmpty()) { final ArrayList<RouteInfo> toBeAdded = getLocalRoutesFor(addedPrefixes); try { mNMService.addInterfaceToLocalNetwork(mIfName, localRoutes); // It's safe to call addInterfaceToLocalNetwork() even if // the interface is already in the local_network. mNMService.addInterfaceToLocalNetwork(mIfName, toBeAdded); } catch (RemoteException e) { Log.e(TAG, "Failed to add IPv6 routes to local table: ", e); } } } else { if (mLastLocalRoutes != null && !mLastLocalRoutes.isEmpty()) { } } private void configureLocalDns( HashSet<Inet6Address> deprecatedDnses, HashSet<Inet6Address> newDnses) { INetd netd = getNetdServiceOrNull(); if (netd == null) { if (newDnses != null) newDnses.clear(); Log.e(TAG, "No netd service instance available; not setting local IPv6 addresses"); return; } // [1] Remove deprecated local DNS IP addresses. if (!deprecatedDnses.isEmpty()) { for (Inet6Address dns : deprecatedDnses) { final String dnsString = dns.getHostAddress(); try { final int removalFailures = mNMService.removeRoutesFromLocalNetwork(mLastLocalRoutes); if (removalFailures > 0) { Log.e(TAG, String.format("Failed to remove %d IPv6 routes from local table.", removalFailures)); netd.interfaceDelAddress(mIfName, dnsString, RFC7421_IP_PREFIX_LENGTH); } catch (RemoteException e) { Log.e(TAG, "Failed to remove local dns IP: " + dnsString, e); } } } // [2] Add only the local DNS IP addresses that have not previously been added. if (newDnses != null && !newDnses.isEmpty()) { final HashSet<Inet6Address> addedDnses = (HashSet) newDnses.clone(); if (mLastRaParams != null) { addedDnses.removeAll(mLastRaParams.dnses); } for (Inet6Address dns : addedDnses) { final String dnsString = dns.getHostAddress(); try { netd.interfaceAddAddress(mIfName, dnsString, RFC7421_IP_PREFIX_LENGTH); } catch (RemoteException e) { Log.e(TAG, "Failed to remove IPv6 routes from local table: ", e); Log.e(TAG, "Failed to add local dns IP: " + dnsString, e); newDnses.remove(dns); } } } mLastLocalRoutes = localRoutes; try { netd.tetherApplyDnsInterfaces(); } catch (RemoteException e) { Log.e(TAG, "Failed to update local DNS caching server"); if (newDnses != null) newDnses.clear(); } } private void updateRaParams(RaParams params) { private void setRaParams(RaParams newParams) { if (mRaDaemon != null) { HashSet<IpPrefix> deprecated = null; final RaParams deprecatedParams = RaParams.getDeprecatedRaParams(mLastRaParams, newParams); if (mLastRaParams != null) { deprecated = new HashSet<>(); configureLocalRoutes(deprecatedParams.prefixes, (newParams != null) ? newParams.prefixes : null); configureLocalDns(deprecatedParams.dnses, (newParams != null) ? newParams.dnses : null); for (IpPrefix ipp : mLastRaParams.prefixes) { if (params == null || !params.prefixes.contains(ipp)) { deprecated.add(ipp); mRaDaemon.buildNewRa(deprecatedParams, newParams); } mLastRaParams = newParams; } // Accumulate routes representing "prefixes to be assigned to the local // interface", for subsequent modification of local_network routing. private ArrayList<RouteInfo> getLocalRoutesFor(HashSet<IpPrefix> prefixes) { final ArrayList<RouteInfo> localRoutes = new ArrayList<RouteInfo>(); for (IpPrefix ipp : prefixes) { localRoutes.add(new RouteInfo(ipp, null, mIfName)); } return localRoutes; } // Currently, we send spurious RAs (5) whenever there's any update. // TODO: Compare params with mLastParams to avoid spurious updates. mRaDaemon.buildNewRa(params, deprecated); private INetd getNetdServiceOrNull() { if (mNMService != null) { try { return mNMService.getNetdService(); } catch (RemoteException ignored) { // This blocks until netd can be reached, but it can return // null during a netd crash. } } return null; } mLastRaParams = params; // Given a prefix like 2001:db8::/64 return 2001:db8::1. private static Inet6Address getLocalDnsIpFor(IpPrefix localPrefix) { final byte[] dnsBytes = localPrefix.getRawAddress(); dnsBytes[dnsBytes.length - 1] = 0x1; try { return Inet6Address.getByAddress(null, dnsBytes, 0); } catch (UnknownHostException e) { Slog.wtf(TAG, "Failed to construct Inet6Address from: " + localPrefix); return null; } } } services/net/java/android/net/ip/RouterAdvertisementDaemon.java +153 −81 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
services/core/java/com/android/server/connectivity/Tethering.java +10 −0 Original line number Diff line number Diff line Loading @@ -1392,6 +1392,8 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering for (Integer netType : mUpstreamIfaceTypes) { NetworkInfo info = cm.getNetworkInfo(netType.intValue()); // TODO: if the network is suspended we should consider // that to be the same as connected here. if ((info != null) && info.isConnected()) { upType = netType.intValue(); break; Loading Loading @@ -1465,6 +1467,10 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering // it immediately, because there likely will be no second // EVENT_ON_AVAILABLE (it was already received). handleNewUpstreamNetworkState(ns); } else if (mCurrentUpstreamIface == null) { // There are no available upstream networks, or none that // have an IPv4 default route (current metric for success). handleNewUpstreamNetworkState(null); } } Loading Loading @@ -1639,6 +1645,7 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering chooseUpstreamType(mTryCell); mTryCell = !mTryCell; } @Override public void exit() { // TODO: examine if we should check the return value. Loading @@ -1646,7 +1653,9 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering mUpstreamNetworkMonitor.stop(); stopListeningForSimChanges(); notifyTetheredOfNewUpstreamIface(null); handleNewUpstreamNetworkState(null); } @Override public boolean processMessage(Message message) { maybeLogMessage(this, message.what); Loading Loading @@ -1734,6 +1743,7 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering // reevaluation is triggered via received CONNECTIVITY_ACTION // broadcasts that result in being passed a // TetherMasterSM.CMD_UPSTREAM_CHANGED. handleNewUpstreamNetworkState(null); break; default: break; Loading
services/core/java/com/android/server/connectivity/tethering/IPv6TetheringCoordinator.java +9 −9 Original line number Diff line number Diff line Loading @@ -55,7 +55,7 @@ public class IPv6TetheringCoordinator { if (VDBG) { Log.d(TAG, "updateUpstreamNetworkState: " + toDebugString(ns)); } if (ns == null || ns.network == null) { if (!canTetherIPv6(ns)) { stopIPv6TetheringOnAllInterfaces(); setUpstreamNetworkState(null); return; Loading @@ -65,8 +65,9 @@ public class IPv6TetheringCoordinator { !ns.network.equals(mUpstreamNetworkState.network)) { stopIPv6TetheringOnAllInterfaces(); } setUpstreamNetworkState(ns); maybeUpdateIPv6TetheringInterfaces(); updateIPv6TetheringInterfaces(); } private void stopIPv6TetheringOnAllInterfaces() { Loading @@ -77,9 +78,10 @@ public class IPv6TetheringCoordinator { } private void setUpstreamNetworkState(NetworkState ns) { if (!canTetherIPv6(ns)) { if (ns == null) { mUpstreamNetworkState = null; } else { // Make a deep copy of the parts we need. mUpstreamNetworkState = new NetworkState( null, new LinkProperties(ns.linkProperties), Loading @@ -94,19 +96,17 @@ public class IPv6TetheringCoordinator { } } private void maybeUpdateIPv6TetheringInterfaces() { if (mUpstreamNetworkState == null) return; private void updateIPv6TetheringInterfaces() { for (TetherInterfaceStateMachine sm : mNotifyList) { final LinkProperties lp = getInterfaceIPv6LinkProperties(sm.interfaceType()); if (lp != null) { sm.sendMessage(TetherInterfaceStateMachine.CMD_IPV6_TETHER_UPDATE, 0, 0, lp); } break; } } private LinkProperties getInterfaceIPv6LinkProperties(int interfaceType) { if (mUpstreamNetworkState == null) return null; // NOTE: Here, in future, we would have policies to decide how to divvy // up the available dedicated prefixes among downstream interfaces. // At this time we have no such mechanism--we only support tethering Loading
services/core/java/com/android/server/connectivity/tethering/IPv6TetheringInterfaceServices.java +148 −60 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.connectivity.tethering; import android.net.INetd; import android.net.IpPrefix; import android.net.LinkAddress; import android.net.LinkProperties; Loading @@ -27,13 +28,16 @@ import android.net.ip.RouterAdvertisementDaemon.RaParams; import android.os.INetworkManagementService; import android.os.RemoteException; import android.util.Log; import android.util.Slog; import java.net.Inet6Address; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.HashSet; import java.util.Objects; /** Loading @@ -41,13 +45,15 @@ import java.util.HashSet; */ class IPv6TetheringInterfaceServices { private static final String TAG = IPv6TetheringInterfaceServices.class.getSimpleName(); private static final IpPrefix LINK_LOCAL_PREFIX = new IpPrefix("fe80::/64"); private static final int RFC7421_IP_PREFIX_LENGTH = 64; private final String mIfName; private final INetworkManagementService mNMService; private NetworkInterface mNetworkInterface; private byte[] mHwAddr; private ArrayList<RouteInfo> mLastLocalRoutes; private LinkProperties mLastIPv6LinkProperties; private RouterAdvertisementDaemon mRaDaemon; private RaParams mLastRaParams; Loading Loading @@ -86,8 +92,7 @@ class IPv6TetheringInterfaceServices { public void stop() { mNetworkInterface = null; mHwAddr = null; updateLocalRoutes(null); updateRaParams(null); setRaParams(null); if (mRaDaemon != null) { mRaDaemon.stop(); Loading @@ -104,95 +109,178 @@ class IPv6TetheringInterfaceServices { public void updateUpstreamIPv6LinkProperties(LinkProperties v6only) { if (mRaDaemon == null) return; if (v6only == null) { updateLocalRoutes(null); updateRaParams(null); // Avoid unnecessary work on spurious updates. if (Objects.equals(mLastIPv6LinkProperties, v6only)) { return; } RaParams params = new RaParams(); RaParams params = null; if (v6only != null) { params = new RaParams(); params.mtu = v6only.getMtu(); params.hasDefaultRoute = v6only.hasIPv6DefaultRoute(); ArrayList<RouteInfo> localRoutes = new ArrayList<RouteInfo>(); for (LinkAddress linkAddr : v6only.getLinkAddresses()) { final IpPrefix prefix = new IpPrefix(linkAddr.getAddress(), linkAddr.getPrefixLength()); // Accumulate routes representing "prefixes to be assigned to the // local interface", for subsequent addition to the local network // in the routing rules. localRoutes.add(new RouteInfo(prefix, null, mIfName)); if (linkAddr.getPrefixLength() != RFC7421_IP_PREFIX_LENGTH) continue; final IpPrefix prefix = new IpPrefix( linkAddr.getAddress(), linkAddr.getPrefixLength()); params.prefixes.add(prefix); final Inet6Address dnsServer = getLocalDnsIpFor(prefix); if (dnsServer != null) { params.dnses.add(dnsServer); } } } // If v6only is null, we pass in null to setRaParams(), which handles // deprecation of any existing RA data. setRaParams(params); mLastIPv6LinkProperties = v6only; } // We need to be able to send unicast RAs, and clients might like to // ping the default router's link-local address, so add that as well. localRoutes.add(new RouteInfo(new IpPrefix("fe80::/64"), null, mIfName)); // TODO: Add a local interface address, update dnsmasq to listen on the // new address, and use only that address as a DNS server. for (InetAddress dnsServer : v6only.getDnsServers()) { if (dnsServer instanceof Inet6Address) { params.dnses.add((Inet6Address) dnsServer); private void configureLocalRoutes( HashSet<IpPrefix> deprecatedPrefixes, HashSet<IpPrefix> newPrefixes) { // [1] Remove the routes that are deprecated. if (!deprecatedPrefixes.isEmpty()) { final ArrayList<RouteInfo> toBeRemoved = getLocalRoutesFor(deprecatedPrefixes); try { final int removalFailures = mNMService.removeRoutesFromLocalNetwork(toBeRemoved); if (removalFailures > 0) { Log.e(TAG, String.format("Failed to remove %d IPv6 routes from local table.", removalFailures)); } } catch (RemoteException e) { Log.e(TAG, "Failed to remove IPv6 routes from local table: ", e); } } updateLocalRoutes(localRoutes); updateRaParams(params); // [2] Add only the routes that have not previously been added. if (newPrefixes != null && !newPrefixes.isEmpty()) { HashSet<IpPrefix> addedPrefixes = (HashSet) newPrefixes.clone(); if (mLastRaParams != null) { addedPrefixes.removeAll(mLastRaParams.prefixes); } private void updateLocalRoutes(ArrayList<RouteInfo> localRoutes) { if (localRoutes != null) { // TODO: Compare with mLastLocalRoutes and take appropriate // appropriate action on the difference between the two. if (mLastRaParams == null || mLastRaParams.prefixes.isEmpty()) { // We need to be able to send unicast RAs, and clients might // like to ping the default router's link-local address. Note // that we never remove the link-local route from the network // until Tethering disables tethering on the interface. addedPrefixes.add(LINK_LOCAL_PREFIX); } if (!localRoutes.isEmpty()) { if (!addedPrefixes.isEmpty()) { final ArrayList<RouteInfo> toBeAdded = getLocalRoutesFor(addedPrefixes); try { mNMService.addInterfaceToLocalNetwork(mIfName, localRoutes); // It's safe to call addInterfaceToLocalNetwork() even if // the interface is already in the local_network. mNMService.addInterfaceToLocalNetwork(mIfName, toBeAdded); } catch (RemoteException e) { Log.e(TAG, "Failed to add IPv6 routes to local table: ", e); } } } else { if (mLastLocalRoutes != null && !mLastLocalRoutes.isEmpty()) { } } private void configureLocalDns( HashSet<Inet6Address> deprecatedDnses, HashSet<Inet6Address> newDnses) { INetd netd = getNetdServiceOrNull(); if (netd == null) { if (newDnses != null) newDnses.clear(); Log.e(TAG, "No netd service instance available; not setting local IPv6 addresses"); return; } // [1] Remove deprecated local DNS IP addresses. if (!deprecatedDnses.isEmpty()) { for (Inet6Address dns : deprecatedDnses) { final String dnsString = dns.getHostAddress(); try { final int removalFailures = mNMService.removeRoutesFromLocalNetwork(mLastLocalRoutes); if (removalFailures > 0) { Log.e(TAG, String.format("Failed to remove %d IPv6 routes from local table.", removalFailures)); netd.interfaceDelAddress(mIfName, dnsString, RFC7421_IP_PREFIX_LENGTH); } catch (RemoteException e) { Log.e(TAG, "Failed to remove local dns IP: " + dnsString, e); } } } // [2] Add only the local DNS IP addresses that have not previously been added. if (newDnses != null && !newDnses.isEmpty()) { final HashSet<Inet6Address> addedDnses = (HashSet) newDnses.clone(); if (mLastRaParams != null) { addedDnses.removeAll(mLastRaParams.dnses); } for (Inet6Address dns : addedDnses) { final String dnsString = dns.getHostAddress(); try { netd.interfaceAddAddress(mIfName, dnsString, RFC7421_IP_PREFIX_LENGTH); } catch (RemoteException e) { Log.e(TAG, "Failed to remove IPv6 routes from local table: ", e); Log.e(TAG, "Failed to add local dns IP: " + dnsString, e); newDnses.remove(dns); } } } mLastLocalRoutes = localRoutes; try { netd.tetherApplyDnsInterfaces(); } catch (RemoteException e) { Log.e(TAG, "Failed to update local DNS caching server"); if (newDnses != null) newDnses.clear(); } } private void updateRaParams(RaParams params) { private void setRaParams(RaParams newParams) { if (mRaDaemon != null) { HashSet<IpPrefix> deprecated = null; final RaParams deprecatedParams = RaParams.getDeprecatedRaParams(mLastRaParams, newParams); if (mLastRaParams != null) { deprecated = new HashSet<>(); configureLocalRoutes(deprecatedParams.prefixes, (newParams != null) ? newParams.prefixes : null); configureLocalDns(deprecatedParams.dnses, (newParams != null) ? newParams.dnses : null); for (IpPrefix ipp : mLastRaParams.prefixes) { if (params == null || !params.prefixes.contains(ipp)) { deprecated.add(ipp); mRaDaemon.buildNewRa(deprecatedParams, newParams); } mLastRaParams = newParams; } // Accumulate routes representing "prefixes to be assigned to the local // interface", for subsequent modification of local_network routing. private ArrayList<RouteInfo> getLocalRoutesFor(HashSet<IpPrefix> prefixes) { final ArrayList<RouteInfo> localRoutes = new ArrayList<RouteInfo>(); for (IpPrefix ipp : prefixes) { localRoutes.add(new RouteInfo(ipp, null, mIfName)); } return localRoutes; } // Currently, we send spurious RAs (5) whenever there's any update. // TODO: Compare params with mLastParams to avoid spurious updates. mRaDaemon.buildNewRa(params, deprecated); private INetd getNetdServiceOrNull() { if (mNMService != null) { try { return mNMService.getNetdService(); } catch (RemoteException ignored) { // This blocks until netd can be reached, but it can return // null during a netd crash. } } return null; } mLastRaParams = params; // Given a prefix like 2001:db8::/64 return 2001:db8::1. private static Inet6Address getLocalDnsIpFor(IpPrefix localPrefix) { final byte[] dnsBytes = localPrefix.getRawAddress(); dnsBytes[dnsBytes.length - 1] = 0x1; try { return Inet6Address.getByAddress(null, dnsBytes, 0); } catch (UnknownHostException e) { Slog.wtf(TAG, "Failed to construct Inet6Address from: " + localPrefix); return null; } } }
services/net/java/android/net/ip/RouterAdvertisementDaemon.java +153 −81 File changed.Preview size limit exceeded, changes collapsed. Show changes