Loading jarjar-rules-shared.txt +3 −0 Original line number Original line Diff line number Diff line # Classes from net-utils-framework-common rule com.android.net.module.util.** com.android.networkstack.util.@1 rule com.android.internal.util.** android.net.networkstack.util.@1 rule com.android.internal.util.** android.net.networkstack.util.@1 rule android.net.shared.Inet4AddressUtils* android.net.networkstack.shared.Inet4AddressUtils@1 rule android.net.shared.Inet4AddressUtils* android.net.networkstack.shared.Inet4AddressUtils@1 Loading src/android/net/dhcp/DhcpClient.java +30 −1 Original line number Original line Diff line number Diff line Loading @@ -80,6 +80,7 @@ import android.os.Message; import android.os.PowerManager; import android.os.PowerManager; import android.os.SystemClock; import android.os.SystemClock; import android.provider.Settings; import android.provider.Settings; import android.stats.connectivity.DhcpFeature; import android.system.ErrnoException; import android.system.ErrnoException; import android.system.Os; import android.system.Os; import android.util.EventLog; import android.util.EventLog; Loading @@ -101,6 +102,7 @@ import com.android.networkstack.apishim.CaptivePortalDataShimImpl; import com.android.networkstack.apishim.SocketUtilsShimImpl; import com.android.networkstack.apishim.SocketUtilsShimImpl; import com.android.networkstack.apishim.common.ShimUtils; import com.android.networkstack.apishim.common.ShimUtils; import com.android.networkstack.arp.ArpPacket; import com.android.networkstack.arp.ArpPacket; import com.android.networkstack.metrics.IpProvisioningMetrics; import java.io.FileDescriptor; import java.io.FileDescriptor; import java.io.IOException; import java.io.IOException; Loading Loading @@ -305,6 +307,8 @@ public class DhcpClient extends StateMachine { private final Context mContext; private final Context mContext; private final Random mRandom; private final Random mRandom; private final IpConnectivityLog mMetricsLog = new IpConnectivityLog(); private final IpConnectivityLog mMetricsLog = new IpConnectivityLog(); @NonNull private final IpProvisioningMetrics mMetrics; // We use a UDP socket to send, so the kernel handles ARP and routing for us (DHCP servers can // We use a UDP socket to send, so the kernel handles ARP and routing for us (DHCP servers can // be off-link as well as on-link). // be off-link as well as on-link). Loading Loading @@ -378,9 +382,11 @@ public class DhcpClient extends StateMachine { */ */ public static class Dependencies { public static class Dependencies { private final NetworkStackIpMemoryStore mNetworkStackIpMemoryStore; private final NetworkStackIpMemoryStore mNetworkStackIpMemoryStore; private final IpProvisioningMetrics mMetrics; public Dependencies(NetworkStackIpMemoryStore store) { public Dependencies(NetworkStackIpMemoryStore store, IpProvisioningMetrics metrics) { mNetworkStackIpMemoryStore = store; mNetworkStackIpMemoryStore = store; mMetrics = metrics; } } /** /** Loading @@ -406,6 +412,13 @@ public class DhcpClient extends StateMachine { return mNetworkStackIpMemoryStore; return mNetworkStackIpMemoryStore; } } /** * Get a IpProvisioningMetrics instance. */ public IpProvisioningMetrics getIpProvisioningMetrics() { return mMetrics; } /** /** * Return whether a feature guarded by a feature flag is enabled. * Return whether a feature guarded by a feature flag is enabled. * @see NetworkStackUtils#isFeatureEnabled(Context, String, String) * @see NetworkStackUtils#isFeatureEnabled(Context, String, String) Loading Loading @@ -444,6 +457,7 @@ public class DhcpClient extends StateMachine { mController = controller; mController = controller; mIfaceName = iface; mIfaceName = iface; mIpMemoryStore = deps.getIpMemoryStore(); mIpMemoryStore = deps.getIpMemoryStore(); mMetrics = deps.getIpProvisioningMetrics(); // CHECKSTYLE:OFF IndentationCheck // CHECKSTYLE:OFF IndentationCheck addState(mStoppedState); addState(mStoppedState); Loading Loading @@ -484,6 +498,7 @@ public class DhcpClient extends StateMachine { final boolean sendHostname = deps.getSendHostnameOption(context); final boolean sendHostname = deps.getSendHostnameOption(context); mHostname = sendHostname ? new HostnameTransliterator().transliterate( mHostname = sendHostname ? new HostnameTransliterator().transliterate( deps.getDeviceName(mContext)) : null; deps.getDeviceName(mContext)) : null; mMetrics.setHostnameTransinfo(sendHostname, mHostname != null); } } public void registerForPreDhcpNotification() { public void registerForPreDhcpNotification() { Loading Loading @@ -529,6 +544,15 @@ public class DhcpClient extends StateMachine { false /* defaultEnabled */); false /* defaultEnabled */); } } private void recordMetricEnabledFeatures() { if (isDhcpLeaseCacheEnabled()) mMetrics.setDhcpEnabledFeature(DhcpFeature.DF_INITREBOOT); if (isDhcpRapidCommitEnabled()) mMetrics.setDhcpEnabledFeature(DhcpFeature.DF_RAPIDCOMMIT); if (isDhcpIpConflictDetectEnabled()) mMetrics.setDhcpEnabledFeature(DhcpFeature.DF_DAD); if (mConfiguration.isPreconnectionEnabled) { mMetrics.setDhcpEnabledFeature(DhcpFeature.DF_FILS); } } private void confirmDhcpLease(DhcpPacket packet, DhcpResults results) { private void confirmDhcpLease(DhcpPacket packet, DhcpResults results) { setDhcpLeaseExpiry(packet); setDhcpLeaseExpiry(packet); acceptDhcpResults(results, "Confirmed"); acceptDhcpResults(results, "Confirmed"); Loading Loading @@ -610,6 +634,7 @@ public class DhcpClient extends StateMachine { EventLog.writeEvent(snetTagId, bugId, uid, data); EventLog.writeEvent(snetTagId, bugId, uid, data); } } mMetricsLog.log(mIfaceName, new DhcpErrorEvent(e.errorCode)); mMetricsLog.log(mIfaceName, new DhcpErrorEvent(e.errorCode)); mMetrics.addDhcpErrorCode(e.errorCode); } } } } Loading Loading @@ -687,6 +712,7 @@ public class DhcpClient extends StateMachine { final ByteBuffer packet = DhcpPacket.buildDiscoverPacket( final ByteBuffer packet = DhcpPacket.buildDiscoverPacket( DhcpPacket.ENCAP_L2, mTransactionId, getSecs(), mHwAddr, DhcpPacket.ENCAP_L2, mTransactionId, getSecs(), mHwAddr, DO_UNICAST, getRequestedParams(), isDhcpRapidCommitEnabled(), mHostname); DO_UNICAST, getRequestedParams(), isDhcpRapidCommitEnabled(), mHostname); mMetrics.incrementCountForDiscover(); return transmitPacket(packet, "DHCPDISCOVER", DhcpPacket.ENCAP_L2, INADDR_BROADCAST); return transmitPacket(packet, "DHCPDISCOVER", DhcpPacket.ENCAP_L2, INADDR_BROADCAST); } } Loading @@ -705,6 +731,7 @@ public class DhcpClient extends StateMachine { String description = "DHCPREQUEST ciaddr=" + clientAddress.getHostAddress() + String description = "DHCPREQUEST ciaddr=" + clientAddress.getHostAddress() + " request=" + requestedAddress.getHostAddress() + " request=" + requestedAddress.getHostAddress() + " serverid=" + serverStr; " serverid=" + serverStr; mMetrics.incrementCountForRequest(); return transmitPacket(packet, description, encap, to); return transmitPacket(packet, description, encap, to); } } Loading Loading @@ -937,6 +964,7 @@ public class DhcpClient extends StateMachine { } else { } else { startInitRebootOrInit(); startInitRebootOrInit(); } } recordMetricEnabledFeatures(); return HANDLED; return HANDLED; default: default: return NOT_HANDLED; return NOT_HANDLED; Loading Loading @@ -1422,6 +1450,7 @@ public class DhcpClient extends StateMachine { try { try { final ArpPacket packet = ArpPacket.parseArpPacket(recvbuf, length); final ArpPacket packet = ArpPacket.parseArpPacket(recvbuf, length); if (hasIpAddressConflict(packet, mTargetIp)) { if (hasIpAddressConflict(packet, mTargetIp)) { mMetrics.incrementCountForIpConflict(); sendMessage(EVENT_IP_CONFLICT); sendMessage(EVENT_IP_CONFLICT); } } } catch (ArpPacket.ParseException e) { } catch (ArpPacket.ParseException e) { Loading src/android/net/ip/IpClient.java +52 −20 Original line number Original line Diff line number Diff line Loading @@ -60,6 +60,7 @@ import android.os.Message; import android.os.RemoteException; import android.os.RemoteException; import android.os.ServiceSpecificException; import android.os.ServiceSpecificException; import android.os.SystemClock; import android.os.SystemClock; import android.stats.connectivity.DisconnectCode; import android.text.TextUtils; import android.text.TextUtils; import android.util.LocalLog; import android.util.LocalLog; import android.util.Log; import android.util.Log; Loading @@ -79,6 +80,7 @@ import com.android.internal.util.WakeupMessage; import com.android.networkstack.apishim.NetworkInformationShimImpl; import com.android.networkstack.apishim.NetworkInformationShimImpl; import com.android.networkstack.apishim.common.NetworkInformationShim; import com.android.networkstack.apishim.common.NetworkInformationShim; import com.android.networkstack.apishim.common.ShimUtils; import com.android.networkstack.apishim.common.ShimUtils; import com.android.networkstack.metrics.IpProvisioningMetrics; import com.android.server.NetworkObserverRegistry; import com.android.server.NetworkObserverRegistry; import com.android.server.NetworkStackService.NetworkStackServiceManager; import com.android.server.NetworkStackService.NetworkStackServiceManager; Loading Loading @@ -129,6 +131,7 @@ public class IpClient extends StateMachine { private static final ConcurrentHashMap<String, LocalLog> sPktLogs = new ConcurrentHashMap<>(); private static final ConcurrentHashMap<String, LocalLog> sPktLogs = new ConcurrentHashMap<>(); private final NetworkStackIpMemoryStore mIpMemoryStore; private final NetworkStackIpMemoryStore mIpMemoryStore; private final NetworkInformationShim mShim = NetworkInformationShimImpl.newInstance(); private final NetworkInformationShim mShim = NetworkInformationShimImpl.newInstance(); private final IpProvisioningMetrics mIpProvisioningMetrics = new IpProvisioningMetrics(); /** /** * Dump all state machine and connectivity packet logs to the specified writer. * Dump all state machine and connectivity packet logs to the specified writer. Loading Loading @@ -527,8 +530,8 @@ public class IpClient extends StateMachine { * Get a DhcpClient Dependencies instance. * Get a DhcpClient Dependencies instance. */ */ public DhcpClient.Dependencies getDhcpClientDependencies( public DhcpClient.Dependencies getDhcpClientDependencies( NetworkStackIpMemoryStore ipMemoryStore) { NetworkStackIpMemoryStore ipMemoryStore, IpProvisioningMetrics metrics) { return new DhcpClient.Dependencies(ipMemoryStore); return new DhcpClient.Dependencies(ipMemoryStore, metrics); } } /** /** Loading Loading @@ -818,7 +821,10 @@ public class IpClient extends StateMachine { * <p>This does not shut down the StateMachine itself, which is handled by {@link #shutdown()}. * <p>This does not shut down the StateMachine itself, which is handled by {@link #shutdown()}. */ */ public void stop() { public void stop() { sendMessage(CMD_STOP); // The message "arg1" parameter is used to record the disconnect code metrics. // Usually this method is called by the peer (e.g. wifi) intentionally to stop IpClient, // consider that's the normal user termination. sendMessage(CMD_STOP, DisconnectCode.DC_NORMAL_TERMINATION.getNumber()); } } /** /** Loading Loading @@ -1072,6 +1078,14 @@ public class IpClient extends StateMachine { mMetricsLog.log(mInterfaceName, new IpManagerEvent(type, duration)); mMetricsLog.log(mInterfaceName, new IpManagerEvent(type, duration)); } } // Record the DisconnectCode and transition to StoppingState. // When jumping to mStoppingState This function will ensure // that you will not forget to fill in DisconnectCode. private void transitionToStoppingState(final DisconnectCode code) { mIpProvisioningMetrics.setDisconnectCode(code); transitionTo(mStoppingState); } // For now: use WifiStateMachine's historical notion of provisioned. // For now: use WifiStateMachine's historical notion of provisioned. @VisibleForTesting @VisibleForTesting static boolean isProvisioned(LinkProperties lp, InitialConfiguration config) { static boolean isProvisioned(LinkProperties lp, InitialConfiguration config) { Loading Loading @@ -1352,6 +1366,12 @@ public class IpClient extends StateMachine { if (Objects.equals(newLp, mLinkProperties)) { if (Objects.equals(newLp, mLinkProperties)) { return true; return true; } } // Either success IPv4 or IPv6 provisioning triggers new LinkProperties update, // wait for the provisioning completion and record the latency. mIpProvisioningMetrics.setIPv4ProvisionedLatencyOnFirstTime(newLp.isIpv4Provisioned()); mIpProvisioningMetrics.setIPv6ProvisionedLatencyOnFirstTime(newLp.isIpv6Provisioned()); final int delta = setLinkProperties(newLp); final int delta = setLinkProperties(newLp); // Most of the attributes stored in the memory store are deduced from // Most of the attributes stored in the memory store are deduced from // the link properties, therefore when the properties update the memory // the link properties, therefore when the properties update the memory Loading Loading @@ -1447,10 +1467,10 @@ public class IpClient extends StateMachine { } } mCallback.onNewDhcpResults(null); mCallback.onNewDhcpResults(null); handleProvisioningFailure(); handleProvisioningFailure(DisconnectCode.DC_PROVISIONING_FAIL); } } private void handleProvisioningFailure() { private void handleProvisioningFailure(final DisconnectCode code) { final LinkProperties newLp = assembleLinkProperties(); final LinkProperties newLp = assembleLinkProperties(); int delta = setLinkProperties(newLp); int delta = setLinkProperties(newLp); // If we've gotten here and we're still not provisioned treat that as // If we've gotten here and we're still not provisioned treat that as Loading @@ -1467,7 +1487,7 @@ public class IpClient extends StateMachine { dispatchCallback(delta, newLp); dispatchCallback(delta, newLp); if (delta == PROV_CHANGE_LOST_PROVISIONING) { if (delta == PROV_CHANGE_LOST_PROVISIONING) { transitionTo(mStoppingState); transitionToStoppingState(code); } } } } Loading Loading @@ -1723,7 +1743,7 @@ public class IpClient extends StateMachine { private void startDhcpClient() { private void startDhcpClient() { // Start DHCPv4. // Start DHCPv4. mDhcpClient = mDependencies.makeDhcpClient(mContext, IpClient.this, mInterfaceParams, mDhcpClient = mDependencies.makeDhcpClient(mContext, IpClient.this, mInterfaceParams, mDependencies.getDhcpClientDependencies(mIpMemoryStore)); mDependencies.getDhcpClientDependencies(mIpMemoryStore, mIpProvisioningMetrics)); // If preconnection is enabled, there is no need to ask Wi-Fi to disable powersaving // If preconnection is enabled, there is no need to ask Wi-Fi to disable powersaving // during DHCP, because the DHCP handshake will happen during association. In order to // during DHCP, because the DHCP handshake will happen during association. In order to Loading @@ -1744,7 +1764,8 @@ public class IpClient extends StateMachine { if (mInterfaceParams == null) { if (mInterfaceParams == null) { logError("Failed to find InterfaceParams for " + mInterfaceName); logError("Failed to find InterfaceParams for " + mInterfaceName); doImmediateProvisioningFailure(IpManagerEvent.ERROR_INTERFACE_NOT_FOUND); doImmediateProvisioningFailure(IpManagerEvent.ERROR_INTERFACE_NOT_FOUND); deferMessage(obtainMessage(CMD_STOP)); deferMessage(obtainMessage(CMD_STOP, DisconnectCode.DC_INTERFACE_NOT_FOUND.getNumber())); return; return; } } Loading Loading @@ -1772,7 +1793,7 @@ public class IpClient extends StateMachine { case EVENT_NETLINK_LINKPROPERTIES_CHANGED: case EVENT_NETLINK_LINKPROPERTIES_CHANGED: handleLinkPropertiesUpdate(NO_CALLBACKS); handleLinkPropertiesUpdate(NO_CALLBACKS); if (readyToProceed()) { if (readyToProceed()) { transitionTo(mRunningState); transitionTo(isUsingPreconnection() ? mPreconnectingState : mRunningState); } } break; break; Loading Loading @@ -1836,6 +1857,7 @@ public class IpClient extends StateMachine { class StartedState extends State { class StartedState extends State { @Override @Override public void enter() { public void enter() { mIpProvisioningMetrics.reset(); mStartTimeMillis = SystemClock.elapsedRealtime(); mStartTimeMillis = SystemClock.elapsedRealtime(); if (mConfiguration.mProvisioningTimeoutMs > 0) { if (mConfiguration.mProvisioningTimeoutMs > 0) { final long alarmTime = SystemClock.elapsedRealtime() final long alarmTime = SystemClock.elapsedRealtime() Loading @@ -1847,13 +1869,17 @@ public class IpClient extends StateMachine { @Override @Override public void exit() { public void exit() { mProvisioningTimeoutAlarm.cancel(); mProvisioningTimeoutAlarm.cancel(); // Record metrics information once this provisioning has completed due to certain // reason (normal termination, provisioning timeout, lost provisioning and etc). mIpProvisioningMetrics.statsWrite(); } } @Override @Override public boolean processMessage(Message msg) { public boolean processMessage(Message msg) { switch (msg.what) { switch (msg.what) { case CMD_STOP: case CMD_STOP: transitionTo(mStoppingState); transitionToStoppingState(DisconnectCode.forNumber(msg.arg1)); break; break; case CMD_UPDATE_L2KEY_CLUSTER: { case CMD_UPDATE_L2KEY_CLUSTER: { Loading @@ -1875,7 +1901,7 @@ public class IpClient extends StateMachine { break; break; case EVENT_PROVISIONING_TIMEOUT: case EVENT_PROVISIONING_TIMEOUT: handleProvisioningFailure(); handleProvisioningFailure(DisconnectCode.DC_PROVISIONING_TIMEOUT); break; break; default: default: Loading Loading @@ -1912,13 +1938,13 @@ public class IpClient extends StateMachine { if (mConfiguration.mEnableIPv6 && !startIPv6()) { if (mConfiguration.mEnableIPv6 && !startIPv6()) { doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV6); doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV6); enqueueJumpToStoppingState(); enqueueJumpToStoppingState(DisconnectCode.DC_ERROR_STARTING_IPV6); return; return; } } if (mConfiguration.mEnableIPv4 && !isUsingPreconnection() && !startIPv4()) { if (mConfiguration.mEnableIPv4 && !isUsingPreconnection() && !startIPv4()) { doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV4); doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV4); enqueueJumpToStoppingState(); enqueueJumpToStoppingState(DisconnectCode.DC_ERROR_STARTING_IPV4); return; return; } } Loading @@ -1926,14 +1952,14 @@ public class IpClient extends StateMachine { if ((config != null) && !applyInitialConfig(config)) { if ((config != null) && !applyInitialConfig(config)) { // TODO introduce a new IpManagerEvent constant to distinguish this error case. // TODO introduce a new IpManagerEvent constant to distinguish this error case. doImmediateProvisioningFailure(IpManagerEvent.ERROR_INVALID_PROVISIONING); doImmediateProvisioningFailure(IpManagerEvent.ERROR_INVALID_PROVISIONING); enqueueJumpToStoppingState(); enqueueJumpToStoppingState(DisconnectCode.DC_INVALID_PROVISIONING); return; return; } } if (mConfiguration.mUsingIpReachabilityMonitor && !startIpReachabilityMonitor()) { if (mConfiguration.mUsingIpReachabilityMonitor && !startIpReachabilityMonitor()) { doImmediateProvisioningFailure( doImmediateProvisioningFailure( IpManagerEvent.ERROR_STARTING_IPREACHABILITYMONITOR); IpManagerEvent.ERROR_STARTING_IPREACHABILITYMONITOR); enqueueJumpToStoppingState(); enqueueJumpToStoppingState(DisconnectCode.DC_ERROR_STARTING_IPREACHABILITYMONITOR); return; return; } } } } Loading Loading @@ -1965,8 +1991,8 @@ public class IpClient extends StateMachine { resetLinkProperties(); resetLinkProperties(); } } private void enqueueJumpToStoppingState() { private void enqueueJumpToStoppingState(final DisconnectCode code) { deferMessage(obtainMessage(CMD_JUMP_RUNNING_TO_STOPPING)); deferMessage(obtainMessage(CMD_JUMP_RUNNING_TO_STOPPING, code.getNumber())); } } private ConnectivityPacketTracker createPacketTracker() { private ConnectivityPacketTracker createPacketTracker() { Loading Loading @@ -2001,7 +2027,7 @@ public class IpClient extends StateMachine { switch (msg.what) { switch (msg.what) { case CMD_JUMP_RUNNING_TO_STOPPING: case CMD_JUMP_RUNNING_TO_STOPPING: case CMD_STOP: case CMD_STOP: transitionTo(mStoppingState); transitionToStoppingState(DisconnectCode.forNumber(msg.arg1)); break; break; case CMD_START: case CMD_START: Loading @@ -2028,8 +2054,14 @@ public class IpClient extends StateMachine { break; break; case EVENT_NETLINK_LINKPROPERTIES_CHANGED: case EVENT_NETLINK_LINKPROPERTIES_CHANGED: // EVENT_NETLINK_LINKPROPERTIES_CHANGED message will be received in both of // provisioning loss and normal user termination case (e.g. turn off wifi or // switch to another wifi ssid), hence, checking current interface change // status (down or up) would help distinguish. final boolean ifUp = (msg.arg1 != 0); if (!handleLinkPropertiesUpdate(SEND_CALLBACKS)) { if (!handleLinkPropertiesUpdate(SEND_CALLBACKS)) { transitionTo(mStoppingState); transitionToStoppingState(ifUp ? DisconnectCode.DC_PROVISIONING_FAIL : DisconnectCode.DC_NORMAL_TERMINATION); } } break; break; Loading Loading @@ -2109,7 +2141,7 @@ public class IpClient extends StateMachine { } else { } else { logError("Failed to set IPv4 address."); logError("Failed to set IPv4 address."); dispatchCallback(PROV_CHANGE_LOST_PROVISIONING, mLinkProperties); dispatchCallback(PROV_CHANGE_LOST_PROVISIONING, mLinkProperties); transitionTo(mStoppingState); transitionToStoppingState(DisconnectCode.DC_PROVISIONING_FAIL); } } break; break; } } Loading src/android/net/util/NetworkStackUtils.java +18 −0 Original line number Original line Diff line number Diff line Loading @@ -436,4 +436,22 @@ public class NetworkStackUtils { return addr instanceof Inet6Address return addr instanceof Inet6Address && ((addr.getAddress()[0] & 0xfe) == 0xfc); && ((addr.getAddress()[0] & 0xfe) == 0xfc); } } /** * Returns the {@code int} nearest in value to {@code value}. * * @param value any {@code long} value * @return the same value cast to {@code int} if it is in the range of the {@code int} * type, {@link Integer#MAX_VALUE} if it is too large, or {@link Integer#MIN_VALUE} if * it is too small */ public static int saturatedCast(long value) { if (value > Integer.MAX_VALUE) { return Integer.MAX_VALUE; } if (value < Integer.MIN_VALUE) { return Integer.MIN_VALUE; } return (int) value; } } } src/android/net/util/Stopwatch.java +8 −0 Original line number Original line Diff line number Diff line Loading @@ -48,6 +48,14 @@ public class Stopwatch { return this; return this; } } /** * Retart the Stopwatch. */ public Stopwatch restart() { mStartTimeNs = SystemClock.elapsedRealtimeNanos(); return this; } /** /** * Stop the Stopwatch. * Stop the Stopwatch. * @return the total time recorded, in microseconds, or 0 if not started. * @return the total time recorded, in microseconds, or 0 if not started. Loading Loading
jarjar-rules-shared.txt +3 −0 Original line number Original line Diff line number Diff line # Classes from net-utils-framework-common rule com.android.net.module.util.** com.android.networkstack.util.@1 rule com.android.internal.util.** android.net.networkstack.util.@1 rule com.android.internal.util.** android.net.networkstack.util.@1 rule android.net.shared.Inet4AddressUtils* android.net.networkstack.shared.Inet4AddressUtils@1 rule android.net.shared.Inet4AddressUtils* android.net.networkstack.shared.Inet4AddressUtils@1 Loading
src/android/net/dhcp/DhcpClient.java +30 −1 Original line number Original line Diff line number Diff line Loading @@ -80,6 +80,7 @@ import android.os.Message; import android.os.PowerManager; import android.os.PowerManager; import android.os.SystemClock; import android.os.SystemClock; import android.provider.Settings; import android.provider.Settings; import android.stats.connectivity.DhcpFeature; import android.system.ErrnoException; import android.system.ErrnoException; import android.system.Os; import android.system.Os; import android.util.EventLog; import android.util.EventLog; Loading @@ -101,6 +102,7 @@ import com.android.networkstack.apishim.CaptivePortalDataShimImpl; import com.android.networkstack.apishim.SocketUtilsShimImpl; import com.android.networkstack.apishim.SocketUtilsShimImpl; import com.android.networkstack.apishim.common.ShimUtils; import com.android.networkstack.apishim.common.ShimUtils; import com.android.networkstack.arp.ArpPacket; import com.android.networkstack.arp.ArpPacket; import com.android.networkstack.metrics.IpProvisioningMetrics; import java.io.FileDescriptor; import java.io.FileDescriptor; import java.io.IOException; import java.io.IOException; Loading Loading @@ -305,6 +307,8 @@ public class DhcpClient extends StateMachine { private final Context mContext; private final Context mContext; private final Random mRandom; private final Random mRandom; private final IpConnectivityLog mMetricsLog = new IpConnectivityLog(); private final IpConnectivityLog mMetricsLog = new IpConnectivityLog(); @NonNull private final IpProvisioningMetrics mMetrics; // We use a UDP socket to send, so the kernel handles ARP and routing for us (DHCP servers can // We use a UDP socket to send, so the kernel handles ARP and routing for us (DHCP servers can // be off-link as well as on-link). // be off-link as well as on-link). Loading Loading @@ -378,9 +382,11 @@ public class DhcpClient extends StateMachine { */ */ public static class Dependencies { public static class Dependencies { private final NetworkStackIpMemoryStore mNetworkStackIpMemoryStore; private final NetworkStackIpMemoryStore mNetworkStackIpMemoryStore; private final IpProvisioningMetrics mMetrics; public Dependencies(NetworkStackIpMemoryStore store) { public Dependencies(NetworkStackIpMemoryStore store, IpProvisioningMetrics metrics) { mNetworkStackIpMemoryStore = store; mNetworkStackIpMemoryStore = store; mMetrics = metrics; } } /** /** Loading @@ -406,6 +412,13 @@ public class DhcpClient extends StateMachine { return mNetworkStackIpMemoryStore; return mNetworkStackIpMemoryStore; } } /** * Get a IpProvisioningMetrics instance. */ public IpProvisioningMetrics getIpProvisioningMetrics() { return mMetrics; } /** /** * Return whether a feature guarded by a feature flag is enabled. * Return whether a feature guarded by a feature flag is enabled. * @see NetworkStackUtils#isFeatureEnabled(Context, String, String) * @see NetworkStackUtils#isFeatureEnabled(Context, String, String) Loading Loading @@ -444,6 +457,7 @@ public class DhcpClient extends StateMachine { mController = controller; mController = controller; mIfaceName = iface; mIfaceName = iface; mIpMemoryStore = deps.getIpMemoryStore(); mIpMemoryStore = deps.getIpMemoryStore(); mMetrics = deps.getIpProvisioningMetrics(); // CHECKSTYLE:OFF IndentationCheck // CHECKSTYLE:OFF IndentationCheck addState(mStoppedState); addState(mStoppedState); Loading Loading @@ -484,6 +498,7 @@ public class DhcpClient extends StateMachine { final boolean sendHostname = deps.getSendHostnameOption(context); final boolean sendHostname = deps.getSendHostnameOption(context); mHostname = sendHostname ? new HostnameTransliterator().transliterate( mHostname = sendHostname ? new HostnameTransliterator().transliterate( deps.getDeviceName(mContext)) : null; deps.getDeviceName(mContext)) : null; mMetrics.setHostnameTransinfo(sendHostname, mHostname != null); } } public void registerForPreDhcpNotification() { public void registerForPreDhcpNotification() { Loading Loading @@ -529,6 +544,15 @@ public class DhcpClient extends StateMachine { false /* defaultEnabled */); false /* defaultEnabled */); } } private void recordMetricEnabledFeatures() { if (isDhcpLeaseCacheEnabled()) mMetrics.setDhcpEnabledFeature(DhcpFeature.DF_INITREBOOT); if (isDhcpRapidCommitEnabled()) mMetrics.setDhcpEnabledFeature(DhcpFeature.DF_RAPIDCOMMIT); if (isDhcpIpConflictDetectEnabled()) mMetrics.setDhcpEnabledFeature(DhcpFeature.DF_DAD); if (mConfiguration.isPreconnectionEnabled) { mMetrics.setDhcpEnabledFeature(DhcpFeature.DF_FILS); } } private void confirmDhcpLease(DhcpPacket packet, DhcpResults results) { private void confirmDhcpLease(DhcpPacket packet, DhcpResults results) { setDhcpLeaseExpiry(packet); setDhcpLeaseExpiry(packet); acceptDhcpResults(results, "Confirmed"); acceptDhcpResults(results, "Confirmed"); Loading Loading @@ -610,6 +634,7 @@ public class DhcpClient extends StateMachine { EventLog.writeEvent(snetTagId, bugId, uid, data); EventLog.writeEvent(snetTagId, bugId, uid, data); } } mMetricsLog.log(mIfaceName, new DhcpErrorEvent(e.errorCode)); mMetricsLog.log(mIfaceName, new DhcpErrorEvent(e.errorCode)); mMetrics.addDhcpErrorCode(e.errorCode); } } } } Loading Loading @@ -687,6 +712,7 @@ public class DhcpClient extends StateMachine { final ByteBuffer packet = DhcpPacket.buildDiscoverPacket( final ByteBuffer packet = DhcpPacket.buildDiscoverPacket( DhcpPacket.ENCAP_L2, mTransactionId, getSecs(), mHwAddr, DhcpPacket.ENCAP_L2, mTransactionId, getSecs(), mHwAddr, DO_UNICAST, getRequestedParams(), isDhcpRapidCommitEnabled(), mHostname); DO_UNICAST, getRequestedParams(), isDhcpRapidCommitEnabled(), mHostname); mMetrics.incrementCountForDiscover(); return transmitPacket(packet, "DHCPDISCOVER", DhcpPacket.ENCAP_L2, INADDR_BROADCAST); return transmitPacket(packet, "DHCPDISCOVER", DhcpPacket.ENCAP_L2, INADDR_BROADCAST); } } Loading @@ -705,6 +731,7 @@ public class DhcpClient extends StateMachine { String description = "DHCPREQUEST ciaddr=" + clientAddress.getHostAddress() + String description = "DHCPREQUEST ciaddr=" + clientAddress.getHostAddress() + " request=" + requestedAddress.getHostAddress() + " request=" + requestedAddress.getHostAddress() + " serverid=" + serverStr; " serverid=" + serverStr; mMetrics.incrementCountForRequest(); return transmitPacket(packet, description, encap, to); return transmitPacket(packet, description, encap, to); } } Loading Loading @@ -937,6 +964,7 @@ public class DhcpClient extends StateMachine { } else { } else { startInitRebootOrInit(); startInitRebootOrInit(); } } recordMetricEnabledFeatures(); return HANDLED; return HANDLED; default: default: return NOT_HANDLED; return NOT_HANDLED; Loading Loading @@ -1422,6 +1450,7 @@ public class DhcpClient extends StateMachine { try { try { final ArpPacket packet = ArpPacket.parseArpPacket(recvbuf, length); final ArpPacket packet = ArpPacket.parseArpPacket(recvbuf, length); if (hasIpAddressConflict(packet, mTargetIp)) { if (hasIpAddressConflict(packet, mTargetIp)) { mMetrics.incrementCountForIpConflict(); sendMessage(EVENT_IP_CONFLICT); sendMessage(EVENT_IP_CONFLICT); } } } catch (ArpPacket.ParseException e) { } catch (ArpPacket.ParseException e) { Loading
src/android/net/ip/IpClient.java +52 −20 Original line number Original line Diff line number Diff line Loading @@ -60,6 +60,7 @@ import android.os.Message; import android.os.RemoteException; import android.os.RemoteException; import android.os.ServiceSpecificException; import android.os.ServiceSpecificException; import android.os.SystemClock; import android.os.SystemClock; import android.stats.connectivity.DisconnectCode; import android.text.TextUtils; import android.text.TextUtils; import android.util.LocalLog; import android.util.LocalLog; import android.util.Log; import android.util.Log; Loading @@ -79,6 +80,7 @@ import com.android.internal.util.WakeupMessage; import com.android.networkstack.apishim.NetworkInformationShimImpl; import com.android.networkstack.apishim.NetworkInformationShimImpl; import com.android.networkstack.apishim.common.NetworkInformationShim; import com.android.networkstack.apishim.common.NetworkInformationShim; import com.android.networkstack.apishim.common.ShimUtils; import com.android.networkstack.apishim.common.ShimUtils; import com.android.networkstack.metrics.IpProvisioningMetrics; import com.android.server.NetworkObserverRegistry; import com.android.server.NetworkObserverRegistry; import com.android.server.NetworkStackService.NetworkStackServiceManager; import com.android.server.NetworkStackService.NetworkStackServiceManager; Loading Loading @@ -129,6 +131,7 @@ public class IpClient extends StateMachine { private static final ConcurrentHashMap<String, LocalLog> sPktLogs = new ConcurrentHashMap<>(); private static final ConcurrentHashMap<String, LocalLog> sPktLogs = new ConcurrentHashMap<>(); private final NetworkStackIpMemoryStore mIpMemoryStore; private final NetworkStackIpMemoryStore mIpMemoryStore; private final NetworkInformationShim mShim = NetworkInformationShimImpl.newInstance(); private final NetworkInformationShim mShim = NetworkInformationShimImpl.newInstance(); private final IpProvisioningMetrics mIpProvisioningMetrics = new IpProvisioningMetrics(); /** /** * Dump all state machine and connectivity packet logs to the specified writer. * Dump all state machine and connectivity packet logs to the specified writer. Loading Loading @@ -527,8 +530,8 @@ public class IpClient extends StateMachine { * Get a DhcpClient Dependencies instance. * Get a DhcpClient Dependencies instance. */ */ public DhcpClient.Dependencies getDhcpClientDependencies( public DhcpClient.Dependencies getDhcpClientDependencies( NetworkStackIpMemoryStore ipMemoryStore) { NetworkStackIpMemoryStore ipMemoryStore, IpProvisioningMetrics metrics) { return new DhcpClient.Dependencies(ipMemoryStore); return new DhcpClient.Dependencies(ipMemoryStore, metrics); } } /** /** Loading Loading @@ -818,7 +821,10 @@ public class IpClient extends StateMachine { * <p>This does not shut down the StateMachine itself, which is handled by {@link #shutdown()}. * <p>This does not shut down the StateMachine itself, which is handled by {@link #shutdown()}. */ */ public void stop() { public void stop() { sendMessage(CMD_STOP); // The message "arg1" parameter is used to record the disconnect code metrics. // Usually this method is called by the peer (e.g. wifi) intentionally to stop IpClient, // consider that's the normal user termination. sendMessage(CMD_STOP, DisconnectCode.DC_NORMAL_TERMINATION.getNumber()); } } /** /** Loading Loading @@ -1072,6 +1078,14 @@ public class IpClient extends StateMachine { mMetricsLog.log(mInterfaceName, new IpManagerEvent(type, duration)); mMetricsLog.log(mInterfaceName, new IpManagerEvent(type, duration)); } } // Record the DisconnectCode and transition to StoppingState. // When jumping to mStoppingState This function will ensure // that you will not forget to fill in DisconnectCode. private void transitionToStoppingState(final DisconnectCode code) { mIpProvisioningMetrics.setDisconnectCode(code); transitionTo(mStoppingState); } // For now: use WifiStateMachine's historical notion of provisioned. // For now: use WifiStateMachine's historical notion of provisioned. @VisibleForTesting @VisibleForTesting static boolean isProvisioned(LinkProperties lp, InitialConfiguration config) { static boolean isProvisioned(LinkProperties lp, InitialConfiguration config) { Loading Loading @@ -1352,6 +1366,12 @@ public class IpClient extends StateMachine { if (Objects.equals(newLp, mLinkProperties)) { if (Objects.equals(newLp, mLinkProperties)) { return true; return true; } } // Either success IPv4 or IPv6 provisioning triggers new LinkProperties update, // wait for the provisioning completion and record the latency. mIpProvisioningMetrics.setIPv4ProvisionedLatencyOnFirstTime(newLp.isIpv4Provisioned()); mIpProvisioningMetrics.setIPv6ProvisionedLatencyOnFirstTime(newLp.isIpv6Provisioned()); final int delta = setLinkProperties(newLp); final int delta = setLinkProperties(newLp); // Most of the attributes stored in the memory store are deduced from // Most of the attributes stored in the memory store are deduced from // the link properties, therefore when the properties update the memory // the link properties, therefore when the properties update the memory Loading Loading @@ -1447,10 +1467,10 @@ public class IpClient extends StateMachine { } } mCallback.onNewDhcpResults(null); mCallback.onNewDhcpResults(null); handleProvisioningFailure(); handleProvisioningFailure(DisconnectCode.DC_PROVISIONING_FAIL); } } private void handleProvisioningFailure() { private void handleProvisioningFailure(final DisconnectCode code) { final LinkProperties newLp = assembleLinkProperties(); final LinkProperties newLp = assembleLinkProperties(); int delta = setLinkProperties(newLp); int delta = setLinkProperties(newLp); // If we've gotten here and we're still not provisioned treat that as // If we've gotten here and we're still not provisioned treat that as Loading @@ -1467,7 +1487,7 @@ public class IpClient extends StateMachine { dispatchCallback(delta, newLp); dispatchCallback(delta, newLp); if (delta == PROV_CHANGE_LOST_PROVISIONING) { if (delta == PROV_CHANGE_LOST_PROVISIONING) { transitionTo(mStoppingState); transitionToStoppingState(code); } } } } Loading Loading @@ -1723,7 +1743,7 @@ public class IpClient extends StateMachine { private void startDhcpClient() { private void startDhcpClient() { // Start DHCPv4. // Start DHCPv4. mDhcpClient = mDependencies.makeDhcpClient(mContext, IpClient.this, mInterfaceParams, mDhcpClient = mDependencies.makeDhcpClient(mContext, IpClient.this, mInterfaceParams, mDependencies.getDhcpClientDependencies(mIpMemoryStore)); mDependencies.getDhcpClientDependencies(mIpMemoryStore, mIpProvisioningMetrics)); // If preconnection is enabled, there is no need to ask Wi-Fi to disable powersaving // If preconnection is enabled, there is no need to ask Wi-Fi to disable powersaving // during DHCP, because the DHCP handshake will happen during association. In order to // during DHCP, because the DHCP handshake will happen during association. In order to Loading @@ -1744,7 +1764,8 @@ public class IpClient extends StateMachine { if (mInterfaceParams == null) { if (mInterfaceParams == null) { logError("Failed to find InterfaceParams for " + mInterfaceName); logError("Failed to find InterfaceParams for " + mInterfaceName); doImmediateProvisioningFailure(IpManagerEvent.ERROR_INTERFACE_NOT_FOUND); doImmediateProvisioningFailure(IpManagerEvent.ERROR_INTERFACE_NOT_FOUND); deferMessage(obtainMessage(CMD_STOP)); deferMessage(obtainMessage(CMD_STOP, DisconnectCode.DC_INTERFACE_NOT_FOUND.getNumber())); return; return; } } Loading Loading @@ -1772,7 +1793,7 @@ public class IpClient extends StateMachine { case EVENT_NETLINK_LINKPROPERTIES_CHANGED: case EVENT_NETLINK_LINKPROPERTIES_CHANGED: handleLinkPropertiesUpdate(NO_CALLBACKS); handleLinkPropertiesUpdate(NO_CALLBACKS); if (readyToProceed()) { if (readyToProceed()) { transitionTo(mRunningState); transitionTo(isUsingPreconnection() ? mPreconnectingState : mRunningState); } } break; break; Loading Loading @@ -1836,6 +1857,7 @@ public class IpClient extends StateMachine { class StartedState extends State { class StartedState extends State { @Override @Override public void enter() { public void enter() { mIpProvisioningMetrics.reset(); mStartTimeMillis = SystemClock.elapsedRealtime(); mStartTimeMillis = SystemClock.elapsedRealtime(); if (mConfiguration.mProvisioningTimeoutMs > 0) { if (mConfiguration.mProvisioningTimeoutMs > 0) { final long alarmTime = SystemClock.elapsedRealtime() final long alarmTime = SystemClock.elapsedRealtime() Loading @@ -1847,13 +1869,17 @@ public class IpClient extends StateMachine { @Override @Override public void exit() { public void exit() { mProvisioningTimeoutAlarm.cancel(); mProvisioningTimeoutAlarm.cancel(); // Record metrics information once this provisioning has completed due to certain // reason (normal termination, provisioning timeout, lost provisioning and etc). mIpProvisioningMetrics.statsWrite(); } } @Override @Override public boolean processMessage(Message msg) { public boolean processMessage(Message msg) { switch (msg.what) { switch (msg.what) { case CMD_STOP: case CMD_STOP: transitionTo(mStoppingState); transitionToStoppingState(DisconnectCode.forNumber(msg.arg1)); break; break; case CMD_UPDATE_L2KEY_CLUSTER: { case CMD_UPDATE_L2KEY_CLUSTER: { Loading @@ -1875,7 +1901,7 @@ public class IpClient extends StateMachine { break; break; case EVENT_PROVISIONING_TIMEOUT: case EVENT_PROVISIONING_TIMEOUT: handleProvisioningFailure(); handleProvisioningFailure(DisconnectCode.DC_PROVISIONING_TIMEOUT); break; break; default: default: Loading Loading @@ -1912,13 +1938,13 @@ public class IpClient extends StateMachine { if (mConfiguration.mEnableIPv6 && !startIPv6()) { if (mConfiguration.mEnableIPv6 && !startIPv6()) { doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV6); doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV6); enqueueJumpToStoppingState(); enqueueJumpToStoppingState(DisconnectCode.DC_ERROR_STARTING_IPV6); return; return; } } if (mConfiguration.mEnableIPv4 && !isUsingPreconnection() && !startIPv4()) { if (mConfiguration.mEnableIPv4 && !isUsingPreconnection() && !startIPv4()) { doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV4); doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV4); enqueueJumpToStoppingState(); enqueueJumpToStoppingState(DisconnectCode.DC_ERROR_STARTING_IPV4); return; return; } } Loading @@ -1926,14 +1952,14 @@ public class IpClient extends StateMachine { if ((config != null) && !applyInitialConfig(config)) { if ((config != null) && !applyInitialConfig(config)) { // TODO introduce a new IpManagerEvent constant to distinguish this error case. // TODO introduce a new IpManagerEvent constant to distinguish this error case. doImmediateProvisioningFailure(IpManagerEvent.ERROR_INVALID_PROVISIONING); doImmediateProvisioningFailure(IpManagerEvent.ERROR_INVALID_PROVISIONING); enqueueJumpToStoppingState(); enqueueJumpToStoppingState(DisconnectCode.DC_INVALID_PROVISIONING); return; return; } } if (mConfiguration.mUsingIpReachabilityMonitor && !startIpReachabilityMonitor()) { if (mConfiguration.mUsingIpReachabilityMonitor && !startIpReachabilityMonitor()) { doImmediateProvisioningFailure( doImmediateProvisioningFailure( IpManagerEvent.ERROR_STARTING_IPREACHABILITYMONITOR); IpManagerEvent.ERROR_STARTING_IPREACHABILITYMONITOR); enqueueJumpToStoppingState(); enqueueJumpToStoppingState(DisconnectCode.DC_ERROR_STARTING_IPREACHABILITYMONITOR); return; return; } } } } Loading Loading @@ -1965,8 +1991,8 @@ public class IpClient extends StateMachine { resetLinkProperties(); resetLinkProperties(); } } private void enqueueJumpToStoppingState() { private void enqueueJumpToStoppingState(final DisconnectCode code) { deferMessage(obtainMessage(CMD_JUMP_RUNNING_TO_STOPPING)); deferMessage(obtainMessage(CMD_JUMP_RUNNING_TO_STOPPING, code.getNumber())); } } private ConnectivityPacketTracker createPacketTracker() { private ConnectivityPacketTracker createPacketTracker() { Loading Loading @@ -2001,7 +2027,7 @@ public class IpClient extends StateMachine { switch (msg.what) { switch (msg.what) { case CMD_JUMP_RUNNING_TO_STOPPING: case CMD_JUMP_RUNNING_TO_STOPPING: case CMD_STOP: case CMD_STOP: transitionTo(mStoppingState); transitionToStoppingState(DisconnectCode.forNumber(msg.arg1)); break; break; case CMD_START: case CMD_START: Loading @@ -2028,8 +2054,14 @@ public class IpClient extends StateMachine { break; break; case EVENT_NETLINK_LINKPROPERTIES_CHANGED: case EVENT_NETLINK_LINKPROPERTIES_CHANGED: // EVENT_NETLINK_LINKPROPERTIES_CHANGED message will be received in both of // provisioning loss and normal user termination case (e.g. turn off wifi or // switch to another wifi ssid), hence, checking current interface change // status (down or up) would help distinguish. final boolean ifUp = (msg.arg1 != 0); if (!handleLinkPropertiesUpdate(SEND_CALLBACKS)) { if (!handleLinkPropertiesUpdate(SEND_CALLBACKS)) { transitionTo(mStoppingState); transitionToStoppingState(ifUp ? DisconnectCode.DC_PROVISIONING_FAIL : DisconnectCode.DC_NORMAL_TERMINATION); } } break; break; Loading Loading @@ -2109,7 +2141,7 @@ public class IpClient extends StateMachine { } else { } else { logError("Failed to set IPv4 address."); logError("Failed to set IPv4 address."); dispatchCallback(PROV_CHANGE_LOST_PROVISIONING, mLinkProperties); dispatchCallback(PROV_CHANGE_LOST_PROVISIONING, mLinkProperties); transitionTo(mStoppingState); transitionToStoppingState(DisconnectCode.DC_PROVISIONING_FAIL); } } break; break; } } Loading
src/android/net/util/NetworkStackUtils.java +18 −0 Original line number Original line Diff line number Diff line Loading @@ -436,4 +436,22 @@ public class NetworkStackUtils { return addr instanceof Inet6Address return addr instanceof Inet6Address && ((addr.getAddress()[0] & 0xfe) == 0xfc); && ((addr.getAddress()[0] & 0xfe) == 0xfc); } } /** * Returns the {@code int} nearest in value to {@code value}. * * @param value any {@code long} value * @return the same value cast to {@code int} if it is in the range of the {@code int} * type, {@link Integer#MAX_VALUE} if it is too large, or {@link Integer#MIN_VALUE} if * it is too small */ public static int saturatedCast(long value) { if (value > Integer.MAX_VALUE) { return Integer.MAX_VALUE; } if (value < Integer.MIN_VALUE) { return Integer.MIN_VALUE; } return (int) value; } } }
src/android/net/util/Stopwatch.java +8 −0 Original line number Original line Diff line number Diff line Loading @@ -48,6 +48,14 @@ public class Stopwatch { return this; return this; } } /** * Retart the Stopwatch. */ public Stopwatch restart() { mStartTimeNs = SystemClock.elapsedRealtimeNanos(); return this; } /** /** * Stop the Stopwatch. * Stop the Stopwatch. * @return the total time recorded, in microseconds, or 0 if not started. * @return the total time recorded, in microseconds, or 0 if not started. Loading