summaryrefslogtreecommitdiff
path: root/src/android/net/ip/IpClient.java
diff options
context:
space:
mode:
authorXiao Ma <xiaom@google.com>2019-07-19 10:39:06 +0900
committerXiao Ma <xiaom@google.com>2019-12-04 17:28:33 +0900
commit4a8d1d42b52223cb81ecacb60cc578aeb4452fd5 (patch)
tree11bc7944d63afbb5f61665c05caa239c4ec03aad /src/android/net/ip/IpClient.java
parent0656b1be55e323126ab267fe4dcfdbc6fa03ab05 (diff)
Add DHCP Rapid Commit FILS support.
Bug: 140223017 Test: atest FrameworksNetTests NetworkStackTests Test: atest NetworkStackIntegrationTests Test: manual Change-Id: Ibf200891c9742825a599a21b43f02927869f98ab
Diffstat (limited to 'src/android/net/ip/IpClient.java')
-rw-r--r--src/android/net/ip/IpClient.java142
1 files changed, 135 insertions, 7 deletions
diff --git a/src/android/net/ip/IpClient.java b/src/android/net/ip/IpClient.java
index 669dbfd..8e95ab5 100644
--- a/src/android/net/ip/IpClient.java
+++ b/src/android/net/ip/IpClient.java
@@ -27,6 +27,7 @@ import android.net.ConnectivityManager;
import android.net.DhcpResults;
import android.net.INetd;
import android.net.IpPrefix;
+import android.net.Layer2PacketParcelable;
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.NattKeepalivePacketDataParcelable;
@@ -38,6 +39,7 @@ import android.net.TcpKeepalivePacketDataParcelable;
import android.net.apf.ApfCapabilities;
import android.net.apf.ApfFilter;
import android.net.dhcp.DhcpClient;
+import android.net.dhcp.DhcpClient.Configuration;
import android.net.metrics.IpConnectivityLog;
import android.net.metrics.IpManagerEvent;
import android.net.shared.InitialConfiguration;
@@ -76,6 +78,7 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Set;
@@ -178,6 +181,10 @@ public class IpClient extends StateMachine {
mLog.e(PREFIX + msg, e);
}
+ /**
+ * Callback called prior to DHCP discovery/renewal only if the pre DHCP action
+ * is enabled.
+ */
public void onPreDhcpAction() {
log("onPreDhcpAction()");
try {
@@ -187,6 +194,10 @@ public class IpClient extends StateMachine {
}
}
+ /**
+ * Callback called after DHCP discovery/renewal only if the pre DHCP action
+ * is enabled.
+ */
public void onPostDhcpAction() {
log("onPostDhcpAction()");
try {
@@ -196,6 +207,9 @@ public class IpClient extends StateMachine {
}
}
+ /**
+ * Callback called when new DHCP results are available.
+ */
public void onNewDhcpResults(DhcpResults dhcpResults) {
log("onNewDhcpResults({" + dhcpResults + "})");
try {
@@ -205,6 +219,9 @@ public class IpClient extends StateMachine {
}
}
+ /**
+ * Indicates that provisioning was successful.
+ */
public void onProvisioningSuccess(LinkProperties newLp) {
log("onProvisioningSuccess({" + newLp + "})");
try {
@@ -214,6 +231,9 @@ public class IpClient extends StateMachine {
}
}
+ /**
+ * Indicates that provisioning failed.
+ */
public void onProvisioningFailure(LinkProperties newLp) {
log("onProvisioningFailure({" + newLp + "})");
try {
@@ -223,6 +243,9 @@ public class IpClient extends StateMachine {
}
}
+ /**
+ * Invoked on LinkProperties changes.
+ */
public void onLinkPropertiesChange(LinkProperties newLp) {
log("onLinkPropertiesChange({" + newLp + "})");
try {
@@ -232,6 +255,10 @@ public class IpClient extends StateMachine {
}
}
+ /**
+ * Called when the internal IpReachabilityMonitor (if enabled) has detected the loss of
+ * required neighbors (e.g. on-link default gw or dns servers) due to NUD_FAILED.
+ */
public void onReachabilityLost(String logMsg) {
log("onReachabilityLost(" + logMsg + ")");
try {
@@ -241,6 +268,9 @@ public class IpClient extends StateMachine {
}
}
+ /**
+ * Called when the IpClient state machine terminates.
+ */
public void onQuit() {
log("onQuit()");
try {
@@ -250,6 +280,9 @@ public class IpClient extends StateMachine {
}
}
+ /**
+ * Called to indicate that a new APF program must be installed to filter incoming packets.
+ */
public void installPacketFilter(byte[] filter) {
log("installPacketFilter(byte[" + filter.length + "])");
try {
@@ -259,6 +292,10 @@ public class IpClient extends StateMachine {
}
}
+ /**
+ * Called to indicate that the APF Program & data buffer must be read asynchronously from
+ * the wifi driver.
+ */
public void startReadPacketFilter() {
log("startReadPacketFilter()");
try {
@@ -268,6 +305,10 @@ public class IpClient extends StateMachine {
}
}
+ /**
+ * If multicast filtering cannot be accomplished with APF, this function will be called to
+ * actuate multicast filtering using another means.
+ */
public void setFallbackMulticastFilter(boolean enabled) {
log("setFallbackMulticastFilter(" + enabled + ")");
try {
@@ -277,6 +318,10 @@ public class IpClient extends StateMachine {
}
}
+ /**
+ * Enabled/disable Neighbor Discover offload functionality. This is called, for example,
+ * whenever 464xlat is being started or stopped.
+ */
public void setNeighborDiscoveryOffload(boolean enable) {
log("setNeighborDiscoveryOffload(" + enable + ")");
try {
@@ -285,6 +330,18 @@ public class IpClient extends StateMachine {
log("Failed to call setNeighborDiscoveryOffload", e);
}
}
+
+ /**
+ * Invoked on starting preconnection process.
+ */
+ public void onPreconnectionStart(List<Layer2PacketParcelable> packets) {
+ log("onPreconnectionStart(Layer2Packets[" + packets.size() + "])");
+ try {
+ mCallback.onPreconnectionStart(packets);
+ } catch (RemoteException e) {
+ log("Failed to call onPreconnectionStart", e);
+ }
+ }
}
public static final String DUMP_ARG_CONFIRM = "confirm";
@@ -306,6 +363,7 @@ public class IpClient extends StateMachine {
private static final int CMD_ADD_KEEPALIVE_PACKET_FILTER_TO_APF = 13;
private static final int CMD_REMOVE_KEEPALIVE_PACKET_FILTER_FROM_APF = 14;
private static final int CMD_UPDATE_L2KEY_GROUPHINT = 15;
+ protected static final int CMD_COMPLETE_PRECONNECTION = 16;
// Internal commands to use instead of trying to call transitionTo() inside
// a given State's enter() method. Calling transitionTo() from enter/exit
@@ -345,6 +403,7 @@ public class IpClient extends StateMachine {
private final State mClearingIpAddressesState = new ClearingIpAddressesState();
private final State mStartedState = new StartedState();
private final State mRunningState = new RunningState();
+ private final State mPreconnectingState = new PreconnectingState();
private final String mTag;
private final Context mContext;
@@ -607,6 +666,11 @@ public class IpClient extends StateMachine {
enforceNetworkStackCallingPermission();
IpClient.this.removeKeepalivePacketFilter(slot);
}
+ @Override
+ public void notifyPreconnectionComplete(boolean success) {
+ enforceNetworkStackCallingPermission();
+ IpClient.this.notifyPreconnectionComplete(success);
+ }
@Override
public int getInterfaceVersion() {
@@ -622,6 +686,7 @@ public class IpClient extends StateMachine {
// CHECKSTYLE:OFF IndentationCheck
addState(mStoppedState);
addState(mStartedState);
+ addState(mPreconnectingState, mStartedState);
addState(mClearingIpAddressesState, mStartedState);
addState(mRunningState, mStartedState);
addState(mStoppingState);
@@ -767,6 +832,15 @@ public class IpClient extends StateMachine {
}
/**
+ * Notify IpClient that preconnection is complete and that the link is ready for use.
+ * The success parameter indicates whether the packets passed in by onPreconnectionStart were
+ * successfully sent to the network or not.
+ */
+ public void notifyPreconnectionComplete(boolean success) {
+ sendMessage(CMD_COMPLETE_PRECONNECTION, success ? 1 : 0);
+ }
+
+ /**
* Dump logs of this IpClient.
*/
public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
@@ -1229,11 +1303,10 @@ public class IpClient extends StateMachine {
return false;
}
} else {
- // Start DHCPv4.
- mDhcpClient = DhcpClient.makeDhcpClient(mContext, IpClient.this, mInterfaceParams,
- mDependencies.getDhcpClientDependencies(mIpMemoryStore));
- mDhcpClient.registerForPreDhcpNotification();
- mDhcpClient.sendMessage(DhcpClient.CMD_START_DHCP, mL2Key);
+ if (mDhcpClient != null) {
+ Log.wtf(mTag, "DhcpClient should never be non-null in startIPv4()");
+ }
+ startDhcpClient();
}
return true;
@@ -1439,6 +1512,25 @@ public class IpClient extends StateMachine {
}
}
+ private boolean isUsingPreconnection() {
+ return mConfiguration.mEnablePreconnection && mConfiguration.mStaticIpConfig == null;
+ }
+
+ private void startDhcpClient() {
+ // Start DHCPv4.
+ mDhcpClient = DhcpClient.makeDhcpClient(mContext, IpClient.this, mInterfaceParams,
+ mDependencies.getDhcpClientDependencies(mIpMemoryStore));
+
+ // 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
+ // ensure that future renews still do the DHCP action (if configured),
+ // registerForPreDhcpNotification is called later when processing the CMD_*_PRECONNECTION
+ // messages.
+ if (!isUsingPreconnection()) mDhcpClient.registerForPreDhcpNotification();
+ mDhcpClient.sendMessage(DhcpClient.CMD_START_DHCP, new Configuration(mL2Key,
+ isUsingPreconnection()));
+ }
+
class ClearingIpAddressesState extends State {
@Override
public void enter() {
@@ -1456,7 +1548,7 @@ public class IpClient extends StateMachine {
public boolean processMessage(Message msg) {
switch (msg.what) {
case CMD_ADDRESSES_CLEARED:
- transitionTo(mRunningState);
+ transitionTo(isUsingPreconnection() ? mPreconnectingState : mRunningState);
break;
case EVENT_NETLINK_LINKPROPERTIES_CHANGED:
@@ -1487,6 +1579,42 @@ public class IpClient extends StateMachine {
}
}
+ class PreconnectingState extends State {
+ @Override
+ public void enter() {
+ startDhcpClient();
+ }
+
+ @Override
+ public boolean processMessage(Message msg) {
+ switch (msg.what) {
+ case CMD_COMPLETE_PRECONNECTION:
+ boolean success = (msg.arg1 == 1);
+ mDhcpClient.registerForPreDhcpNotification();
+ if (!success) {
+ mDhcpClient.sendMessage(DhcpClient.CMD_ABORT_PRECONNECTION);
+ }
+ // The link is ready for use. Advance to running state, start IPv6, etc.
+ transitionTo(mRunningState);
+ break;
+
+ case DhcpClient.CMD_START_PRECONNECTION:
+ final Layer2PacketParcelable l2Packet = (Layer2PacketParcelable) msg.obj;
+ mCallback.onPreconnectionStart(Collections.singletonList(l2Packet));
+ break;
+
+ case CMD_STOP:
+ case EVENT_PROVISIONING_TIMEOUT:
+ // Fall through to StartedState.
+ return NOT_HANDLED;
+
+ default:
+ deferMessage(msg);
+ }
+ return HANDLED;
+ }
+ }
+
class StartedState extends State {
@Override
public void enter() {
@@ -1566,7 +1694,7 @@ public class IpClient extends StateMachine {
return;
}
- if (mConfiguration.mEnableIPv4 && !startIPv4()) {
+ if (mConfiguration.mEnableIPv4 && !isUsingPreconnection() && !startIPv4()) {
doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV4);
enqueueJumpToStoppingState();
return;