From 931ec8efa03acfb7f8aea9769e3b04341da4fb4d Mon Sep 17 00:00:00 2001 From: junyulai Date: Tue, 4 Jun 2019 05:26:38 -0700 Subject: [PATCH] Fix cannot create Nat-T keepalive on mobile data Currently phone process fail to unparcel NattKeepalivePacketData since it is not in framework. Moves NattKeepalivePacketData to framework to make it can be utilized by telephony. This change also removes the error feedback triggered by calling add keepalive packet filter to an unsupported network agent. This is misinterpreted by KeepaliveTracker that start keepalive is failing. Bug: 134048171 Test: 1. atest android.net.cts.ConnectivityManagerTest#testSocketKeepaliveLimitTelephony 2. atest android.net.cts.ConnectivityManagerTest 3. atest FrameworksNetTests 4. atest FrameworksTelephonyTests Merged-In: If630d5b339aa722717258c721daa8ead8c431e2d Change-Id: Ic0f168be6f5a6263a5e0565b6381dcb5c645660f (cherry picked from commit 9ede677bb2c081ccdc41c8c3c19c949114bcc138) --- .../android/net/NattKeepalivePacketData.java | 51 ++++++++++++++----- core/java/android/net/NetworkAgent.java | 2 - .../server/connectivity/KeepaliveTracker.java | 1 + .../java/android/net/ip/IpClientManager.java | 4 +- .../net/util/KeepalivePacketDataUtil.java | 39 ++++++++++++++ 5 files changed, 80 insertions(+), 17 deletions(-) rename {services/net => core}/java/android/net/NattKeepalivePacketData.java (66%) create mode 100644 services/net/java/android/net/util/KeepalivePacketDataUtil.java diff --git a/services/net/java/android/net/NattKeepalivePacketData.java b/core/java/android/net/NattKeepalivePacketData.java similarity index 66% rename from services/net/java/android/net/NattKeepalivePacketData.java rename to core/java/android/net/NattKeepalivePacketData.java index 06838fe655b76..a77c244d6b404 100644 --- a/services/net/java/android/net/NattKeepalivePacketData.java +++ b/core/java/android/net/NattKeepalivePacketData.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,9 +19,9 @@ package android.net; import static android.net.SocketKeepalive.ERROR_INVALID_IP_ADDRESS; import static android.net.SocketKeepalive.ERROR_INVALID_PORT; -import android.annotation.NonNull; import android.net.SocketKeepalive.InvalidPacketException; import android.net.util.IpUtils; +import android.os.Parcel; import android.os.Parcelable; import android.system.OsConstants; @@ -79,17 +79,40 @@ public final class NattKeepalivePacketData extends KeepalivePacketData implement return new NattKeepalivePacketData(srcAddress, srcPort, dstAddress, dstPort, buf.array()); } - /** - * Convert this NattKeepalivePacketData to a NattKeepalivePacketDataParcelable. - */ - @NonNull - public NattKeepalivePacketDataParcelable toStableParcelable() { - final NattKeepalivePacketDataParcelable parcel = new NattKeepalivePacketDataParcelable(); - - parcel.srcAddress = srcAddress.getAddress(); - parcel.srcPort = srcPort; - parcel.dstAddress = dstAddress.getAddress(); - parcel.dstPort = dstPort; - return parcel; + /** Parcelable Implementation */ + public int describeContents() { + return 0; } + + /** Write to parcel */ + public void writeToParcel(Parcel out, int flags) { + out.writeString(srcAddress.getHostAddress()); + out.writeString(dstAddress.getHostAddress()); + out.writeInt(srcPort); + out.writeInt(dstPort); + } + + /** Parcelable Creator */ + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + public NattKeepalivePacketData createFromParcel(Parcel in) { + final InetAddress srcAddress = + InetAddresses.parseNumericAddress(in.readString()); + final InetAddress dstAddress = + InetAddresses.parseNumericAddress(in.readString()); + final int srcPort = in.readInt(); + final int dstPort = in.readInt(); + try { + return NattKeepalivePacketData.nattKeepalivePacket(srcAddress, srcPort, + dstAddress, dstPort); + } catch (InvalidPacketException e) { + throw new IllegalArgumentException( + "Invalid NAT-T keepalive data: " + e.error); + } + } + + public NattKeepalivePacketData[] newArray(int size) { + return new NattKeepalivePacketData[size]; + } + }; } diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java index 419fa7a61de55..f416fc7959906 100644 --- a/core/java/android/net/NetworkAgent.java +++ b/core/java/android/net/NetworkAgent.java @@ -511,7 +511,6 @@ public abstract class NetworkAgent extends Handler { * override this method. */ protected void addKeepalivePacketFilter(Message msg) { - onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_UNSUPPORTED); } /** @@ -520,7 +519,6 @@ public abstract class NetworkAgent extends Handler { * must override this method. */ protected void removeKeepalivePacketFilter(Message msg) { - onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_UNSUPPORTED); } /** diff --git a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java index 3de2537cffc73..4b2e21d943ce6 100644 --- a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java +++ b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java @@ -216,6 +216,7 @@ public class KeepaliveTracker { public String toString() { return "KeepaliveInfo [" + + " type=" + mType + " network=" + mNai.network + " startedState=" + startedStateString(mStartedState) + " " diff --git a/services/net/java/android/net/ip/IpClientManager.java b/services/net/java/android/net/ip/IpClientManager.java index f8d7e845da2c2..1e653cd29aeda 100644 --- a/services/net/java/android/net/ip/IpClientManager.java +++ b/services/net/java/android/net/ip/IpClientManager.java @@ -21,6 +21,7 @@ import android.net.NattKeepalivePacketData; import android.net.ProxyInfo; import android.net.TcpKeepalivePacketData; import android.net.shared.ProvisioningConfiguration; +import android.net.util.KeepalivePacketDataUtil; import android.os.Binder; import android.os.RemoteException; import android.util.Log; @@ -229,7 +230,8 @@ public class IpClientManager { public boolean addKeepalivePacketFilter(int slot, NattKeepalivePacketData pkt) { final long token = Binder.clearCallingIdentity(); try { - mIpClient.addNattKeepalivePacketFilter(slot, pkt.toStableParcelable()); + mIpClient.addNattKeepalivePacketFilter( + slot, KeepalivePacketDataUtil.toStableParcelable(pkt)); return true; } catch (RemoteException e) { log("Error adding Keepalive Packet Filter ", e); diff --git a/services/net/java/android/net/util/KeepalivePacketDataUtil.java b/services/net/java/android/net/util/KeepalivePacketDataUtil.java new file mode 100644 index 0000000000000..9a51729212f7b --- /dev/null +++ b/services/net/java/android/net/util/KeepalivePacketDataUtil.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.util; + +import android.annotation.NonNull; +import android.net.NattKeepalivePacketData; +import android.net.NattKeepalivePacketDataParcelable; + +/** @hide */ +public final class KeepalivePacketDataUtil { + /** + * Convert this NattKeepalivePacketData to a NattKeepalivePacketDataParcelable. + */ + @NonNull + public static NattKeepalivePacketDataParcelable toStableParcelable( + NattKeepalivePacketData pkt) { + final NattKeepalivePacketDataParcelable parcel = new NattKeepalivePacketDataParcelable(); + + parcel.srcAddress = pkt.srcAddress.getAddress(); + parcel.srcPort = pkt.srcPort; + parcel.dstAddress = pkt.dstAddress.getAddress(); + parcel.dstPort = pkt.dstPort; + return parcel; + } +}