diff options
21 files changed, 562 insertions, 319 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt index de8e18046a39..b982dd745672 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -6401,6 +6401,19 @@ package android.net { method @NonNull public android.net.StaticIpConfiguration.Builder setIpAddress(@Nullable android.net.LinkAddress); } + public final class TcpKeepalivePacketData extends android.net.KeepalivePacketData implements android.os.Parcelable { + ctor public TcpKeepalivePacketData(@NonNull java.net.InetAddress, int, @NonNull java.net.InetAddress, int, @NonNull byte[], int, int, int, int, int, int) throws android.net.InvalidPacketException; + method public int describeContents(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.net.TcpKeepalivePacketData> CREATOR; + field public final int ipTos; + field public final int ipTtl; + field public final int tcpAck; + field public final int tcpSeq; + field public final int tcpWindow; + field public final int tcpWindowScale; + } + public class TrafficStats { method public static void setThreadStatsTagApp(); method public static void setThreadStatsTagBackup(); diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index 496ac3bbb8e9..82e48bfb61a7 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -113,7 +113,6 @@ import android.media.tv.tunerresourcemanager.ITunerResourceManager; import android.media.tv.tunerresourcemanager.TunerResourceManager; import android.net.ConnectivityDiagnosticsManager; import android.net.ConnectivityManager; -import android.net.ConnectivityThread; import android.net.EthernetManager; import android.net.IConnectivityManager; import android.net.IEthernetManager; @@ -768,8 +767,7 @@ public final class SystemServiceRegistry { public LowpanManager createService(ContextImpl ctx) throws ServiceNotFoundException { IBinder b = ServiceManager.getServiceOrThrow(Context.LOWPAN_SERVICE); ILowpanManager service = ILowpanManager.Stub.asInterface(b); - return new LowpanManager(ctx.getOuterContext(), service, - ConnectivityThread.getInstanceLooper()); + return new LowpanManager(ctx.getOuterContext(), service); }}); registerService(Context.ETHERNET_SERVICE, EthernetManager.class, diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index cf5d4e579f85..1e968721e637 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -2108,17 +2108,6 @@ public class ConnectivityManager { // ignored } - /** {@hide} */ - @Deprecated - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public NetworkQuotaInfo getActiveNetworkQuotaInfo() { - try { - return mService.getActiveNetworkQuotaInfo(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - /** * @hide * @deprecated Talk to TelephonyManager directly diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index 41732008b4ee..fb0128363310 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -25,7 +25,6 @@ import android.net.Network; import android.net.NetworkAgentConfig; import android.net.NetworkCapabilities; import android.net.NetworkInfo; -import android.net.NetworkQuotaInfo; import android.net.NetworkRequest; import android.net.NetworkState; import android.net.ISocketKeepaliveCallback; @@ -76,7 +75,6 @@ interface IConnectivityManager @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) NetworkState[] getAllNetworkState(); - NetworkQuotaInfo getActiveNetworkQuotaInfo(); boolean isActiveNetworkMetered(); boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress, diff --git a/core/java/android/net/TcpKeepalivePacketData.java b/core/java/android/net/TcpKeepalivePacketData.java new file mode 100644 index 000000000000..ddb3a6a72fb4 --- /dev/null +++ b/core/java/android/net/TcpKeepalivePacketData.java @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2020 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; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; + +import java.net.InetAddress; +import java.util.Objects; + +/** + * Represents the actual tcp keep alive packets which will be used for hardware offload. + * @hide + */ +@SystemApi +public final class TcpKeepalivePacketData extends KeepalivePacketData implements Parcelable { + private static final String TAG = "TcpKeepalivePacketData"; + + /** TCP sequence number. */ + public final int tcpSeq; + + /** TCP ACK number. */ + public final int tcpAck; + + /** TCP RCV window. */ + public final int tcpWindow; + + /** TCP RCV window scale. */ + public final int tcpWindowScale; + + /** IP TOS. */ + public final int ipTos; + + /** IP TTL. */ + public final int ipTtl; + + public TcpKeepalivePacketData(@NonNull final InetAddress srcAddress, int srcPort, + @NonNull final InetAddress dstAddress, int dstPort, @NonNull final byte[] data, + int tcpSeq, int tcpAck, int tcpWindow, int tcpWindowScale, int ipTos, int ipTtl) + throws InvalidPacketException { + super(srcAddress, srcPort, dstAddress, dstPort, data); + this.tcpSeq = tcpSeq; + this.tcpAck = tcpAck; + this.tcpWindow = tcpWindow; + this.tcpWindowScale = tcpWindowScale; + this.ipTos = ipTos; + this.ipTtl = ipTtl; + } + + @Override + public boolean equals(@Nullable final Object o) { + if (!(o instanceof TcpKeepalivePacketData)) return false; + final TcpKeepalivePacketData other = (TcpKeepalivePacketData) o; + final InetAddress srcAddress = getSrcAddress(); + final InetAddress dstAddress = getDstAddress(); + return srcAddress.equals(other.getSrcAddress()) + && dstAddress.equals(other.getDstAddress()) + && getSrcPort() == other.getSrcPort() + && getDstPort() == other.getDstPort() + && this.tcpAck == other.tcpAck + && this.tcpSeq == other.tcpSeq + && this.tcpWindow == other.tcpWindow + && this.tcpWindowScale == other.tcpWindowScale + && this.ipTos == other.ipTos + && this.ipTtl == other.ipTtl; + } + + @Override + public int hashCode() { + return Objects.hash(getSrcAddress(), getDstAddress(), getSrcPort(), getDstPort(), + tcpAck, tcpSeq, tcpWindow, tcpWindowScale, ipTos, ipTtl); + } + + /** + * Parcelable Implementation. + * Note that this object implements parcelable (and needs to keep doing this as it inherits + * from a class that does), but should usually be parceled as a stable parcelable using + * the toStableParcelable() and fromStableParcelable() methods. + */ + @Override + public int describeContents() { + return 0; + } + + /** Write to parcel. */ + @Override + public void writeToParcel(@NonNull Parcel out, int flags) { + out.writeString(getSrcAddress().getHostAddress()); + out.writeString(getDstAddress().getHostAddress()); + out.writeInt(getSrcPort()); + out.writeInt(getDstPort()); + out.writeByteArray(getPacket()); + out.writeInt(tcpSeq); + out.writeInt(tcpAck); + out.writeInt(tcpWindow); + out.writeInt(tcpWindowScale); + out.writeInt(ipTos); + out.writeInt(ipTtl); + } + + private static TcpKeepalivePacketData readFromParcel(Parcel in) throws InvalidPacketException { + InetAddress srcAddress = InetAddresses.parseNumericAddress(in.readString()); + InetAddress dstAddress = InetAddresses.parseNumericAddress(in.readString()); + int srcPort = in.readInt(); + int dstPort = in.readInt(); + byte[] packet = in.createByteArray(); + int tcpSeq = in.readInt(); + int tcpAck = in.readInt(); + int tcpWnd = in.readInt(); + int tcpWndScale = in.readInt(); + int ipTos = in.readInt(); + int ipTtl = in.readInt(); + return new TcpKeepalivePacketData(srcAddress, srcPort, dstAddress, dstPort, packet, tcpSeq, + tcpAck, tcpWnd, tcpWndScale, ipTos, ipTtl); + } + + /** Parcelable Creator. */ + public static final @NonNull Parcelable.Creator<TcpKeepalivePacketData> CREATOR = + new Parcelable.Creator<TcpKeepalivePacketData>() { + public TcpKeepalivePacketData createFromParcel(Parcel in) { + try { + return readFromParcel(in); + } catch (InvalidPacketException e) { + throw new IllegalArgumentException( + "Invalid TCP keepalive data: " + e.getError()); + } + } + + public TcpKeepalivePacketData[] newArray(int size) { + return new TcpKeepalivePacketData[size]; + } + }; + + @Override + public String toString() { + return "saddr: " + getSrcAddress() + + " daddr: " + getDstAddress() + + " sport: " + getSrcPort() + + " dport: " + getDstPort() + + " seq: " + tcpSeq + + " ack: " + tcpAck + + " window: " + tcpWindow + + " windowScale: " + tcpWindowScale + + " tos: " + ipTos + + " ttl: " + ipTtl; + } +} diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS index 2baae7a7bea5..563ff621392e 100644 --- a/core/java/android/os/OWNERS +++ b/core/java/android/os/OWNERS @@ -30,5 +30,4 @@ per-file *Telephony* = file:/telephony/OWNERS per-file *Zygote* = file:/ZYGOTE_OWNERS # RecoverySystem -per-file IRecoverySystem.aidl = rvrolyk@google.com, zhaojiac@google.com -per-file RecoverySystem.java = rvrolyk@google.com, zhaojiac@google.com +per-file *Recovery* = file:/services/core/java/com/android/server/recoverysystem/OWNERS diff --git a/graphics/java/android/graphics/OWNERS b/graphics/java/android/graphics/OWNERS index c3fb6f8eba7c..a8a3631f4a7d 100644 --- a/graphics/java/android/graphics/OWNERS +++ b/graphics/java/android/graphics/OWNERS @@ -6,3 +6,6 @@ njawad@google.com sumir@google.com per-file BLASTBufferQueue.java = file:/services/core/java/com/android/server/wm/OWNERS +per-file FontFamily.java = file:fonts/OWNERS +per-file FontListParser.java = file:fonts/OWNERS +per-file Typeface.java = file:fonts/OWNERS diff --git a/lowpan/java/android/net/lowpan/LowpanManager.java b/lowpan/java/android/net/lowpan/LowpanManager.java index 76876ce01c96..33b35e6af7af 100644 --- a/lowpan/java/android/net/lowpan/LowpanManager.java +++ b/lowpan/java/android/net/lowpan/LowpanManager.java @@ -24,6 +24,10 @@ import android.os.IBinder; import android.os.Looper; import android.os.RemoteException; import android.os.ServiceManager; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.os.BackgroundThread; + import java.lang.ref.WeakReference; import java.util.HashMap; import java.util.Map; @@ -97,10 +101,14 @@ public class LowpanManager { * * @param context the application context * @param service the Binder interface - * @param looper the default Looper to run callbacks on * @hide - hide this because it takes in a parameter of type ILowpanManager, which is a system * private class. */ + public LowpanManager(Context context, ILowpanManager service) { + this(context, service, BackgroundThread.get().getLooper()); + } + + @VisibleForTesting public LowpanManager(Context context, ILowpanManager service, Looper looper) { mContext = context; mService = service; diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 4590aa258703..2c765bd896fa 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -113,7 +113,6 @@ import android.net.NetworkInfo.DetailedState; import android.net.NetworkMonitorManager; import android.net.NetworkPolicyManager; import android.net.NetworkProvider; -import android.net.NetworkQuotaInfo; import android.net.NetworkRequest; import android.net.NetworkSpecifier; import android.net.NetworkStack; @@ -1781,14 +1780,6 @@ public class ConnectivityService extends IConnectivityManager.Stub } @Override - @Deprecated - public NetworkQuotaInfo getActiveNetworkQuotaInfo() { - Log.w(TAG, "Shame on UID " + Binder.getCallingUid() - + " for calling the hidden API getNetworkQuotaInfo(). Shame!"); - return new NetworkQuotaInfo(); - } - - @Override public boolean isActiveNetworkMetered() { enforceAccessPermission(); diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java index 086cc1ca32ed..636da6f34abc 100644 --- a/services/core/java/com/android/server/NetworkManagementService.java +++ b/services/core/java/com/android/server/NetworkManagementService.java @@ -90,7 +90,6 @@ import android.util.SparseIntArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.app.IBatteryStats; import com.android.internal.util.DumpUtils; -import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.HexDump; import com.android.internal.util.Preconditions; @@ -419,8 +418,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub { getBatteryStats().noteMobileRadioPowerState(powerState, tsNanos, uid); } catch (RemoteException e) { } - FrameworkStatsLog.write_non_chained( - FrameworkStatsLog.MOBILE_RADIO_POWER_STATE_CHANGED, uid, null, powerState); } } @@ -431,8 +428,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub { getBatteryStats().noteWifiRadioPowerState(powerState, tsNanos, uid); } catch (RemoteException e) { } - FrameworkStatsLog.write_non_chained( - FrameworkStatsLog.WIFI_RADIO_POWER_STATE_CHANGED, uid, null, powerState); } } diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index 090ac5467c68..1ade8e7e9311 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -688,6 +688,8 @@ public final class BatteryStatsService extends IBatteryStats.Stub if (update) { mWorker.scheduleSync("modem-data", BatteryExternalStatsWorker.UPDATE_RADIO); } + FrameworkStatsLog.write_non_chained( + FrameworkStatsLog.MOBILE_RADIO_POWER_STATE_CHANGED, uid, null, powerState); } public void notePhoneOn() { @@ -869,6 +871,8 @@ public final class BatteryStatsService extends IBatteryStats.Stub } mStats.noteWifiRadioPowerState(powerState, tsNanos, uid); } + FrameworkStatsLog.write_non_chained( + FrameworkStatsLog.WIFI_RADIO_POWER_STATE_CHANGED, uid, null, powerState); } public void noteWifiRunning(WorkSource ws) { diff --git a/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java b/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java index 1129899ee3ff..b5f20d70db7f 100644 --- a/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java +++ b/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java @@ -36,6 +36,7 @@ import android.net.SocketKeepalive.InvalidSocketException; import android.net.TcpKeepalivePacketData; import android.net.TcpKeepalivePacketDataParcelable; import android.net.TcpRepairWindow; +import android.net.util.KeepalivePacketDataUtil; import android.os.Handler; import android.os.MessageQueue; import android.os.Messenger; @@ -112,7 +113,7 @@ public class TcpKeepaliveController { throws InvalidPacketException, InvalidSocketException { try { final TcpKeepalivePacketDataParcelable tcpDetails = switchToRepairMode(fd); - return TcpKeepalivePacketData.tcpKeepalivePacket(tcpDetails); + return KeepalivePacketDataUtil.fromStableParcelable(tcpDetails); } catch (InvalidPacketException | InvalidSocketException e) { switchOutOfRepairMode(fd); throw e; @@ -122,7 +123,7 @@ public class TcpKeepaliveController { * Switch the tcp socket to repair mode and query detail tcp information. * * @param fd the fd of socket on which to use keepalive offload. - * @return a {@link TcpKeepalivePacketData#TcpKeepalivePacketDataParcelable} object for current + * @return a {@link TcpKeepalivePacketDataParcelable} object for current * tcp/ip information. */ private static TcpKeepalivePacketDataParcelable switchToRepairMode(FileDescriptor fd) diff --git a/services/core/java/com/android/server/locksettings/OWNERS b/services/core/java/com/android/server/locksettings/OWNERS index dad6e39be47f..08b8a8c106b7 100644 --- a/services/core/java/com/android/server/locksettings/OWNERS +++ b/services/core/java/com/android/server/locksettings/OWNERS @@ -1,2 +1,3 @@ jaggies@google.com kchyn@google.com +rubinxu@google.com diff --git a/services/net/Android.bp b/services/net/Android.bp index 29bf37460568..ae9bd41b9db0 100644 --- a/services/net/Android.bp +++ b/services/net/Android.bp @@ -37,7 +37,6 @@ java_library { "java/android/net/util/NetworkConstants.java", "java/android/net/IpMemoryStore.java", "java/android/net/NetworkMonitorManager.java", - "java/android/net/TcpKeepalivePacketData.java", ], sdk_version: "module_current", min_sdk_version: "30", diff --git a/services/net/java/android/net/TcpKeepalivePacketData.java b/services/net/java/android/net/TcpKeepalivePacketData.java deleted file mode 100644 index 4875c7cc4263..000000000000 --- a/services/net/java/android/net/TcpKeepalivePacketData.java +++ /dev/null @@ -1,268 +0,0 @@ -/* - * 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; - -import static android.net.SocketKeepalive.ERROR_INVALID_IP_ADDRESS; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.os.Parcel; -import android.os.Parcelable; -import android.system.OsConstants; - -import com.android.net.module.util.IpUtils; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.Objects; - -/** - * Represents the actual tcp keep alive packets which will be used for hardware offload. - * @hide - */ -public class TcpKeepalivePacketData extends KeepalivePacketData implements Parcelable { - private static final String TAG = "TcpKeepalivePacketData"; - - /** TCP sequence number. */ - public final int tcpSeq; - - /** TCP ACK number. */ - public final int tcpAck; - - /** TCP RCV window. */ - public final int tcpWnd; - - /** TCP RCV window scale. */ - public final int tcpWndScale; - - /** IP TOS. */ - public final int ipTos; - - /** IP TTL. */ - public final int ipTtl; - - private static final int IPV4_HEADER_LENGTH = 20; - private static final int IPV6_HEADER_LENGTH = 40; - private static final int TCP_HEADER_LENGTH = 20; - - // This should only be constructed via static factory methods, such as - // tcpKeepalivePacket. - private TcpKeepalivePacketData(final TcpKeepalivePacketDataParcelable tcpDetails, - final byte[] data) throws InvalidPacketException, UnknownHostException { - super(InetAddress.getByAddress(tcpDetails.srcAddress), tcpDetails.srcPort, - InetAddress.getByAddress(tcpDetails.dstAddress), tcpDetails.dstPort, data); - tcpSeq = tcpDetails.seq; - tcpAck = tcpDetails.ack; - // In the packet, the window is shifted right by the window scale. - tcpWnd = tcpDetails.rcvWnd; - tcpWndScale = tcpDetails.rcvWndScale; - ipTos = tcpDetails.tos; - ipTtl = tcpDetails.ttl; - } - - private TcpKeepalivePacketData(final InetAddress srcAddress, int srcPort, - final InetAddress dstAddress, int dstPort, final byte[] data, int tcpSeq, - int tcpAck, int tcpWnd, int tcpWndScale, int ipTos, int ipTtl) - throws InvalidPacketException { - super(srcAddress, srcPort, dstAddress, dstPort, data); - this.tcpSeq = tcpSeq; - this.tcpAck = tcpAck; - this.tcpWnd = tcpWnd; - this.tcpWndScale = tcpWndScale; - this.ipTos = ipTos; - this.ipTtl = ipTtl; - } - - /** - * Factory method to create tcp keepalive packet structure. - */ - public static TcpKeepalivePacketData tcpKeepalivePacket( - TcpKeepalivePacketDataParcelable tcpDetails) throws InvalidPacketException { - final byte[] packet; - try { - if ((tcpDetails.srcAddress != null) && (tcpDetails.dstAddress != null) - && (tcpDetails.srcAddress.length == 4 /* V4 IP length */) - && (tcpDetails.dstAddress.length == 4 /* V4 IP length */)) { - packet = buildV4Packet(tcpDetails); - } else { - // TODO: support ipv6 - throw new InvalidPacketException(ERROR_INVALID_IP_ADDRESS); - } - return new TcpKeepalivePacketData(tcpDetails, packet); - } catch (UnknownHostException e) { - throw new InvalidPacketException(ERROR_INVALID_IP_ADDRESS); - } - - } - - /** - * Build ipv4 tcp keepalive packet, not including the link-layer header. - */ - // TODO : if this code is ever moved to the network stack, factorize constants with the ones - // over there. - private static byte[] buildV4Packet(TcpKeepalivePacketDataParcelable tcpDetails) { - final int length = IPV4_HEADER_LENGTH + TCP_HEADER_LENGTH; - ByteBuffer buf = ByteBuffer.allocate(length); - buf.order(ByteOrder.BIG_ENDIAN); - buf.put((byte) 0x45); // IP version and IHL - buf.put((byte) tcpDetails.tos); // TOS - buf.putShort((short) length); - buf.putInt(0x00004000); // ID, flags=DF, offset - buf.put((byte) tcpDetails.ttl); // TTL - buf.put((byte) OsConstants.IPPROTO_TCP); - final int ipChecksumOffset = buf.position(); - buf.putShort((short) 0); // IP checksum - buf.put(tcpDetails.srcAddress); - buf.put(tcpDetails.dstAddress); - buf.putShort((short) tcpDetails.srcPort); - buf.putShort((short) tcpDetails.dstPort); - buf.putInt(tcpDetails.seq); // Sequence Number - buf.putInt(tcpDetails.ack); // ACK - buf.putShort((short) 0x5010); // TCP length=5, flags=ACK - buf.putShort((short) (tcpDetails.rcvWnd >> tcpDetails.rcvWndScale)); // Window size - final int tcpChecksumOffset = buf.position(); - buf.putShort((short) 0); // TCP checksum - // URG is not set therefore the urgent pointer is zero. - buf.putShort((short) 0); // Urgent pointer - - buf.putShort(ipChecksumOffset, IpUtils.ipChecksum(buf, 0)); - buf.putShort(tcpChecksumOffset, IpUtils.tcpChecksum( - buf, 0, IPV4_HEADER_LENGTH, TCP_HEADER_LENGTH)); - - return buf.array(); - } - - // TODO: add buildV6Packet. - - @Override - public boolean equals(@Nullable final Object o) { - if (!(o instanceof TcpKeepalivePacketData)) return false; - final TcpKeepalivePacketData other = (TcpKeepalivePacketData) o; - final InetAddress srcAddress = getSrcAddress(); - final InetAddress dstAddress = getDstAddress(); - return srcAddress.equals(other.getSrcAddress()) - && dstAddress.equals(other.getDstAddress()) - && getSrcPort() == other.getSrcPort() - && getDstPort() == other.getDstPort() - && this.tcpAck == other.tcpAck - && this.tcpSeq == other.tcpSeq - && this.tcpWnd == other.tcpWnd - && this.tcpWndScale == other.tcpWndScale - && this.ipTos == other.ipTos - && this.ipTtl == other.ipTtl; - } - - @Override - public int hashCode() { - return Objects.hash(getSrcAddress(), getDstAddress(), getSrcPort(), getDstPort(), - tcpAck, tcpSeq, tcpWnd, tcpWndScale, ipTos, ipTtl); - } - - /** - * Parcelable Implementation. - * Note that this object implements parcelable (and needs to keep doing this as it inherits - * from a class that does), but should usually be parceled as a stable parcelable using - * the toStableParcelable() and fromStableParcelable() methods. - */ - public int describeContents() { - return 0; - } - - /** Write to parcel. */ - public void writeToParcel(Parcel out, int flags) { - out.writeString(getSrcAddress().getHostAddress()); - out.writeString(getDstAddress().getHostAddress()); - out.writeInt(getSrcPort()); - out.writeInt(getDstPort()); - out.writeByteArray(getPacket()); - out.writeInt(tcpSeq); - out.writeInt(tcpAck); - out.writeInt(tcpWnd); - out.writeInt(tcpWndScale); - out.writeInt(ipTos); - out.writeInt(ipTtl); - } - - private static TcpKeepalivePacketData readFromParcel(Parcel in) throws InvalidPacketException { - InetAddress srcAddress = InetAddresses.parseNumericAddress(in.readString()); - InetAddress dstAddress = InetAddresses.parseNumericAddress(in.readString()); - int srcPort = in.readInt(); - int dstPort = in.readInt(); - byte[] packet = in.createByteArray(); - int tcpSeq = in.readInt(); - int tcpAck = in.readInt(); - int tcpWnd = in.readInt(); - int tcpWndScale = in.readInt(); - int ipTos = in.readInt(); - int ipTtl = in.readInt(); - return new TcpKeepalivePacketData(srcAddress, srcPort, dstAddress, dstPort, packet, tcpSeq, - tcpAck, tcpWnd, tcpWndScale, ipTos, ipTtl); - } - - /** Parcelable Creator. */ - public static final @NonNull Parcelable.Creator<TcpKeepalivePacketData> CREATOR = - new Parcelable.Creator<TcpKeepalivePacketData>() { - public TcpKeepalivePacketData createFromParcel(Parcel in) { - try { - return readFromParcel(in); - } catch (InvalidPacketException e) { - throw new IllegalArgumentException( - "Invalid NAT-T keepalive data: " + e.getError()); - } - } - - public TcpKeepalivePacketData[] newArray(int size) { - return new TcpKeepalivePacketData[size]; - } - }; - - /** - * Convert this TcpKeepalivePacketData to a TcpKeepalivePacketDataParcelable. - */ - @NonNull - public TcpKeepalivePacketDataParcelable toStableParcelable() { - final TcpKeepalivePacketDataParcelable parcel = new TcpKeepalivePacketDataParcelable(); - final InetAddress srcAddress = getSrcAddress(); - final InetAddress dstAddress = getDstAddress(); - parcel.srcAddress = srcAddress.getAddress(); - parcel.srcPort = getSrcPort(); - parcel.dstAddress = dstAddress.getAddress(); - parcel.dstPort = getDstPort(); - parcel.seq = tcpSeq; - parcel.ack = tcpAck; - parcel.rcvWnd = tcpWnd; - parcel.rcvWndScale = tcpWndScale; - parcel.tos = ipTos; - parcel.ttl = ipTtl; - return parcel; - } - - @Override - public String toString() { - return "saddr: " + getSrcAddress() - + " daddr: " + getDstAddress() - + " sport: " + getSrcPort() - + " dport: " + getDstPort() - + " seq: " + tcpSeq - + " ack: " + tcpAck - + " wnd: " + tcpWnd - + " wndScale: " + tcpWndScale - + " tos: " + ipTos - + " ttl: " + ipTtl; - } -} diff --git a/services/net/java/android/net/ip/IpClientManager.java b/services/net/java/android/net/ip/IpClientManager.java index db464e732e91..274b6dc1769b 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.annotation.NonNull; import android.net.NattKeepalivePacketData; import android.net.ProxyInfo; import android.net.TcpKeepalivePacketData; +import android.net.TcpKeepalivePacketDataParcelable; import android.net.shared.Layer2Information; import android.net.shared.ProvisioningConfiguration; import android.net.util.KeepalivePacketDataUtil; @@ -215,9 +216,20 @@ public class IpClientManager { * Add a TCP keepalive packet filter before setting up keepalive offload. */ public boolean addKeepalivePacketFilter(int slot, TcpKeepalivePacketData pkt) { + return addKeepalivePacketFilter(slot, KeepalivePacketDataUtil.toStableParcelable(pkt)); + } + + /** + * Add a TCP keepalive packet filter before setting up keepalive offload. + * @deprecated This method is for use on pre-S platforms where TcpKeepalivePacketData is not + * system API. On newer platforms use + * addKeepalivePacketFilter(int, TcpKeepalivePacketData) instead. + */ + @Deprecated + public boolean addKeepalivePacketFilter(int slot, TcpKeepalivePacketDataParcelable pkt) { final long token = Binder.clearCallingIdentity(); try { - mIpClient.addKeepalivePacketFilter(slot, pkt.toStableParcelable()); + mIpClient.addKeepalivePacketFilter(slot, 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 index 4466ea0abe0e..6e539bbaf9fe 100644 --- a/services/net/java/android/net/util/KeepalivePacketDataUtil.java +++ b/services/net/java/android/net/util/KeepalivePacketDataUtil.java @@ -16,20 +16,47 @@ package android.net.util; +import static android.net.SocketKeepalive.ERROR_INVALID_IP_ADDRESS; + import android.annotation.NonNull; +import android.annotation.Nullable; +import android.net.InvalidPacketException; +import android.net.KeepalivePacketData; import android.net.NattKeepalivePacketData; import android.net.NattKeepalivePacketDataParcelable; +import android.net.TcpKeepalivePacketData; +import android.net.TcpKeepalivePacketDataParcelable; +import android.os.Build; +import android.system.OsConstants; +import android.util.Log; + +import com.android.net.module.util.IpUtils; import java.net.InetAddress; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; -/** @hide */ +/** + * Utility class to convert to/from keepalive data parcelables. + * + * TODO: move to networkstack-client library when it is moved to frameworks/libs/net. + * This class cannot go into other shared libraries as it depends on NetworkStack AIDLs. + * @hide + */ public final class KeepalivePacketDataUtil { - /** - * Convert this NattKeepalivePacketData to a NattKeepalivePacketDataParcelable. + private static final int IPV4_HEADER_LENGTH = 20; + private static final int IPV6_HEADER_LENGTH = 40; + private static final int TCP_HEADER_LENGTH = 20; + + private static final String TAG = KeepalivePacketDataUtil.class.getSimpleName(); + + /** + * Convert a NattKeepalivePacketData to a NattKeepalivePacketDataParcelable. */ @NonNull public static NattKeepalivePacketDataParcelable toStableParcelable( - NattKeepalivePacketData pkt) { + @NonNull NattKeepalivePacketData pkt) { final NattKeepalivePacketDataParcelable parcel = new NattKeepalivePacketDataParcelable(); final InetAddress srcAddress = pkt.getSrcAddress(); final InetAddress dstAddress = pkt.getDstAddress(); @@ -39,4 +66,158 @@ public final class KeepalivePacketDataUtil { parcel.dstPort = pkt.getDstPort(); return parcel; } + + /** + * Convert a TcpKeepalivePacketData to a TcpKeepalivePacketDataParcelable. + */ + @NonNull + public static TcpKeepalivePacketDataParcelable toStableParcelable( + @NonNull TcpKeepalivePacketData pkt) { + final TcpKeepalivePacketDataParcelable parcel = new TcpKeepalivePacketDataParcelable(); + final InetAddress srcAddress = pkt.getSrcAddress(); + final InetAddress dstAddress = pkt.getDstAddress(); + parcel.srcAddress = srcAddress.getAddress(); + parcel.srcPort = pkt.getSrcPort(); + parcel.dstAddress = dstAddress.getAddress(); + parcel.dstPort = pkt.getDstPort(); + parcel.seq = pkt.tcpSeq; + parcel.ack = pkt.tcpAck; + parcel.rcvWnd = pkt.tcpWindow; + parcel.rcvWndScale = pkt.tcpWindowScale; + parcel.tos = pkt.ipTos; + parcel.ttl = pkt.ipTtl; + return parcel; + } + + /** + * Factory method to create tcp keepalive packet structure. + * @hide + */ + public static TcpKeepalivePacketData fromStableParcelable( + TcpKeepalivePacketDataParcelable tcpDetails) throws InvalidPacketException { + final byte[] packet; + try { + if ((tcpDetails.srcAddress != null) && (tcpDetails.dstAddress != null) + && (tcpDetails.srcAddress.length == 4 /* V4 IP length */) + && (tcpDetails.dstAddress.length == 4 /* V4 IP length */)) { + packet = buildV4Packet(tcpDetails); + } else { + // TODO: support ipv6 + throw new InvalidPacketException(ERROR_INVALID_IP_ADDRESS); + } + return new TcpKeepalivePacketData( + InetAddress.getByAddress(tcpDetails.srcAddress), + tcpDetails.srcPort, + InetAddress.getByAddress(tcpDetails.dstAddress), + tcpDetails.dstPort, + packet, + tcpDetails.seq, tcpDetails.ack, tcpDetails.rcvWnd, tcpDetails.rcvWndScale, + tcpDetails.tos, tcpDetails.ttl); + } catch (UnknownHostException e) { + throw new InvalidPacketException(ERROR_INVALID_IP_ADDRESS); + } + + } + + /** + * Build ipv4 tcp keepalive packet, not including the link-layer header. + */ + // TODO : if this code is ever moved to the network stack, factorize constants with the ones + // over there. + private static byte[] buildV4Packet(TcpKeepalivePacketDataParcelable tcpDetails) { + final int length = IPV4_HEADER_LENGTH + TCP_HEADER_LENGTH; + ByteBuffer buf = ByteBuffer.allocate(length); + buf.order(ByteOrder.BIG_ENDIAN); + buf.put((byte) 0x45); // IP version and IHL + buf.put((byte) tcpDetails.tos); // TOS + buf.putShort((short) length); + buf.putInt(0x00004000); // ID, flags=DF, offset + buf.put((byte) tcpDetails.ttl); // TTL + buf.put((byte) OsConstants.IPPROTO_TCP); + final int ipChecksumOffset = buf.position(); + buf.putShort((short) 0); // IP checksum + buf.put(tcpDetails.srcAddress); + buf.put(tcpDetails.dstAddress); + buf.putShort((short) tcpDetails.srcPort); + buf.putShort((short) tcpDetails.dstPort); + buf.putInt(tcpDetails.seq); // Sequence Number + buf.putInt(tcpDetails.ack); // ACK + buf.putShort((short) 0x5010); // TCP length=5, flags=ACK + buf.putShort((short) (tcpDetails.rcvWnd >> tcpDetails.rcvWndScale)); // Window size + final int tcpChecksumOffset = buf.position(); + buf.putShort((short) 0); // TCP checksum + // URG is not set therefore the urgent pointer is zero. + buf.putShort((short) 0); // Urgent pointer + + buf.putShort(ipChecksumOffset, com.android.net.module.util.IpUtils.ipChecksum(buf, 0)); + buf.putShort(tcpChecksumOffset, IpUtils.tcpChecksum( + buf, 0, IPV4_HEADER_LENGTH, TCP_HEADER_LENGTH)); + + return buf.array(); + } + + // TODO: add buildV6Packet. + + /** + * Get a {@link TcpKeepalivePacketDataParcelable} from {@link KeepalivePacketData}, if the + * generic class actually contains TCP keepalive data. + * + * @deprecated This method is used on R platforms where android.net.TcpKeepalivePacketData was + * not yet system API. Newer platforms should use android.net.TcpKeepalivePacketData directly. + * + * @param data A {@link KeepalivePacketData} that may contain TCP keepalive data. + * @return A parcelable containing TCP keepalive data, or null if the input data does not + * contain TCP keepalive data. + */ + @Deprecated + @SuppressWarnings("AndroidFrameworkCompatChange") // API version check used to Log.wtf + @Nullable + public static TcpKeepalivePacketDataParcelable parseTcpKeepalivePacketData( + @Nullable KeepalivePacketData data) { + if (data == null) return null; + + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) { + Log.wtf(TAG, "parseTcpKeepalivePacketData should not be used after R, use " + + "TcpKeepalivePacketData instead."); + } + + // Reconstruct TcpKeepalivePacketData from the packet contained in KeepalivePacketData + final ByteBuffer buffer = ByteBuffer.wrap(data.getPacket()); + buffer.order(ByteOrder.BIG_ENDIAN); + + // Most of the fields are accessible from the KeepalivePacketData superclass: instead of + // using Struct to parse everything, just extract the extra fields necessary for + // TcpKeepalivePacketData. + final int tcpSeq; + final int tcpAck; + final int wndSize; + final int ipTos; + final int ttl; + try { + // This only support IPv4, because TcpKeepalivePacketData only supports IPv4 for R and + // below, and this method should not be used on newer platforms. + tcpSeq = buffer.getInt(IPV4_HEADER_LENGTH + 4); + tcpAck = buffer.getInt(IPV4_HEADER_LENGTH + 8); + wndSize = buffer.getShort(IPV4_HEADER_LENGTH + 14); + ipTos = buffer.get(1); + ttl = buffer.get(8); + } catch (IndexOutOfBoundsException e) { + return null; + } + + final TcpKeepalivePacketDataParcelable p = new TcpKeepalivePacketDataParcelable(); + p.srcAddress = data.getSrcAddress().getAddress(); + p.srcPort = data.getSrcPort(); + p.dstAddress = data.getDstAddress().getAddress(); + p.dstPort = data.getDstPort(); + p.seq = tcpSeq; + p.ack = tcpAck; + // TcpKeepalivePacketData could actually use non-zero wndScale, but this does not affect + // actual functionality as generated packets will be the same (no wndScale option added) + p.rcvWnd = wndSize; + p.rcvWndScale = 0; + p.tos = ipTos; + p.ttl = ttl; + return p; + } } diff --git a/test-mock/src/android/test/mock/OWNERS b/test-mock/src/android/test/mock/OWNERS index 36d9cb2654bb..9551245bd5c9 100644 --- a/test-mock/src/android/test/mock/OWNERS +++ b/test-mock/src/android/test/mock/OWNERS @@ -1 +1,3 @@ set noparent + +* diff --git a/tests/net/common/java/android/net/TcpKeepalivePacketDataTest.kt b/tests/net/common/java/android/net/TcpKeepalivePacketDataTest.kt new file mode 100644 index 000000000000..677006692f84 --- /dev/null +++ b/tests/net/common/java/android/net/TcpKeepalivePacketDataTest.kt @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2020 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 + +import android.net.InetAddresses.parseNumericAddress +import android.os.Build +import com.android.testutils.DevSdkIgnoreRule +import com.android.testutils.DevSdkIgnoreRunner +import com.android.testutils.assertFieldCountEquals +import com.android.testutils.assertParcelSane +import org.junit.Test +import org.junit.runner.RunWith +import java.net.InetAddress +import kotlin.test.assertEquals +import kotlin.test.assertNotEquals +import kotlin.test.assertTrue + +@RunWith(DevSdkIgnoreRunner::class) +@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R) // TcpKeepalivePacketData added to SDK in S +class TcpKeepalivePacketDataTest { + private fun makeData( + srcAddress: InetAddress = parseNumericAddress("192.0.2.123"), + srcPort: Int = 1234, + dstAddress: InetAddress = parseNumericAddress("192.0.2.231"), + dstPort: Int = 4321, + data: ByteArray = byteArrayOf(1, 2, 3), + tcpSeq: Int = 135, + tcpAck: Int = 246, + tcpWnd: Int = 1234, + tcpWndScale: Int = 2, + ipTos: Int = 0x12, + ipTtl: Int = 10 + ) = TcpKeepalivePacketData(srcAddress, srcPort, dstAddress, dstPort, data, tcpSeq, tcpAck, + tcpWnd, tcpWndScale, ipTos, ipTtl) + + @Test + fun testEquals() { + val data1 = makeData() + val data2 = makeData() + assertEquals(data1, data2) + assertEquals(data1.hashCode(), data2.hashCode()) + } + + @Test + fun testNotEquals() { + assertNotEquals(makeData(srcAddress = parseNumericAddress("192.0.2.124")), makeData()) + assertNotEquals(makeData(srcPort = 1235), makeData()) + assertNotEquals(makeData(dstAddress = parseNumericAddress("192.0.2.232")), makeData()) + assertNotEquals(makeData(dstPort = 4322), makeData()) + // .equals does not test .packet, as it should be generated from the other fields + assertNotEquals(makeData(tcpSeq = 136), makeData()) + assertNotEquals(makeData(tcpAck = 247), makeData()) + assertNotEquals(makeData(tcpWnd = 1235), makeData()) + assertNotEquals(makeData(tcpWndScale = 3), makeData()) + assertNotEquals(makeData(ipTos = 0x14), makeData()) + assertNotEquals(makeData(ipTtl = 11), makeData()) + + // Update above assertions if field is added + assertFieldCountEquals(5, KeepalivePacketData::class.java) + assertFieldCountEquals(6, TcpKeepalivePacketData::class.java) + } + + @Test + fun testParcelUnparcel() { + assertParcelSane(makeData(), fieldCount = 6) { a, b -> + // .equals() does not verify .packet + a == b && a.packet contentEquals b.packet + } + } + + @Test + fun testToString() { + val data = makeData() + val str = data.toString() + + assertTrue(str.contains(data.srcAddress.hostAddress)) + assertTrue(str.contains(data.srcPort.toString())) + assertTrue(str.contains(data.dstAddress.hostAddress)) + assertTrue(str.contains(data.dstPort.toString())) + // .packet not included in toString() + assertTrue(str.contains(data.tcpSeq.toString())) + assertTrue(str.contains(data.tcpAck.toString())) + assertTrue(str.contains(data.tcpWindow.toString())) + assertTrue(str.contains(data.tcpWindowScale.toString())) + assertTrue(str.contains(data.ipTos.toString())) + assertTrue(str.contains(data.ipTtl.toString())) + + // Update above assertions if field is added + assertFieldCountEquals(5, KeepalivePacketData::class.java) + assertFieldCountEquals(6, TcpKeepalivePacketData::class.java) + } +}
\ No newline at end of file diff --git a/tests/net/java/android/net/TcpKeepalivePacketDataTest.java b/tests/net/java/android/net/KeepalivePacketDataUtilTest.java index c5b25bdcac48..fc739fbfac61 100644 --- a/tests/net/java/android/net/TcpKeepalivePacketDataTest.java +++ b/tests/net/java/android/net/KeepalivePacketDataUtilTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 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. @@ -20,8 +20,11 @@ import static com.android.testutils.ParcelUtils.assertParcelingIsLossless; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import android.net.util.KeepalivePacketDataUtil; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -31,7 +34,7 @@ import java.net.InetAddress; import java.nio.ByteBuffer; @RunWith(JUnit4.class) -public final class TcpKeepalivePacketDataTest { +public final class KeepalivePacketDataUtilTest { private static final byte[] IPV4_KEEPALIVE_SRC_ADDR = {10, 0, 0, 1}; private static final byte[] IPV4_KEEPALIVE_DST_ADDR = {10, 0, 0, 5}; @@ -39,7 +42,7 @@ public final class TcpKeepalivePacketDataTest { public void setUp() {} @Test - public void testV4TcpKeepalivePacket() throws Exception { + public void testFromTcpKeepaliveStableParcelable() throws Exception { final int srcPort = 1234; final int dstPort = 4321; final int seq = 0x11111111; @@ -61,7 +64,7 @@ public final class TcpKeepalivePacketDataTest { testInfo.tos = tos; testInfo.ttl = ttl; try { - resultData = TcpKeepalivePacketData.tcpKeepalivePacket(testInfo); + resultData = KeepalivePacketDataUtil.fromStableParcelable(testInfo); } catch (InvalidPacketException e) { fail("InvalidPacketException: " + e); } @@ -72,8 +75,8 @@ public final class TcpKeepalivePacketDataTest { assertEquals(testInfo.dstPort, resultData.getDstPort()); assertEquals(testInfo.seq, resultData.tcpSeq); assertEquals(testInfo.ack, resultData.tcpAck); - assertEquals(testInfo.rcvWnd, resultData.tcpWnd); - assertEquals(testInfo.rcvWndScale, resultData.tcpWndScale); + assertEquals(testInfo.rcvWnd, resultData.tcpWindow); + assertEquals(testInfo.rcvWndScale, resultData.tcpWindowScale); assertEquals(testInfo.tos, resultData.ipTos); assertEquals(testInfo.ttl, resultData.ipTtl); @@ -113,7 +116,7 @@ public final class TcpKeepalivePacketDataTest { //TODO: add ipv6 test when ipv6 supported @Test - public void testParcel() throws Exception { + public void testToTcpKeepaliveStableParcelable() throws Exception { final int srcPort = 1234; final int dstPort = 4321; final int sequence = 0x11111111; @@ -135,8 +138,8 @@ public final class TcpKeepalivePacketDataTest { testInfo.ttl = ttl; TcpKeepalivePacketData testData = null; TcpKeepalivePacketDataParcelable resultData = null; - testData = TcpKeepalivePacketData.tcpKeepalivePacket(testInfo); - resultData = testData.toStableParcelable(); + testData = KeepalivePacketDataUtil.fromStableParcelable(testInfo); + resultData = KeepalivePacketDataUtil.toStableParcelable(testData); assertArrayEquals(resultData.srcAddress, IPV4_KEEPALIVE_SRC_ADDR); assertArrayEquals(resultData.dstAddress, IPV4_KEEPALIVE_DST_ADDR); assertEquals(resultData.srcPort, srcPort); @@ -154,4 +157,49 @@ public final class TcpKeepalivePacketDataTest { + " ack: 572662306, rcvWnd: 48000, rcvWndScale: 2, tos: 4, ttl: 64}"; assertEquals(expected, resultData.toString()); } + + @Test + public void testParseTcpKeepalivePacketData() throws Exception { + final int srcPort = 1234; + final int dstPort = 4321; + final int sequence = 0x11111111; + final int ack = 0x22222222; + final int wnd = 4800; + final int wndScale = 2; + final int tos = 4; + final int ttl = 64; + final TcpKeepalivePacketDataParcelable testParcel = new TcpKeepalivePacketDataParcelable(); + testParcel.srcAddress = IPV4_KEEPALIVE_SRC_ADDR; + testParcel.srcPort = srcPort; + testParcel.dstAddress = IPV4_KEEPALIVE_DST_ADDR; + testParcel.dstPort = dstPort; + testParcel.seq = sequence; + testParcel.ack = ack; + testParcel.rcvWnd = wnd; + testParcel.rcvWndScale = wndScale; + testParcel.tos = tos; + testParcel.ttl = ttl; + + final KeepalivePacketData testData = + KeepalivePacketDataUtil.fromStableParcelable(testParcel); + final TcpKeepalivePacketDataParcelable parsedParcelable = + KeepalivePacketDataUtil.parseTcpKeepalivePacketData(testData); + final TcpKeepalivePacketData roundTripData = + KeepalivePacketDataUtil.fromStableParcelable(parsedParcelable); + + // Generated packet is the same, but rcvWnd / wndScale will differ if scale is non-zero + assertTrue(testData.getPacket().length > 0); + assertArrayEquals(testData.getPacket(), roundTripData.getPacket()); + + testParcel.rcvWndScale = 0; + final KeepalivePacketData noScaleTestData = + KeepalivePacketDataUtil.fromStableParcelable(testParcel); + final TcpKeepalivePacketDataParcelable noScaleParsedParcelable = + KeepalivePacketDataUtil.parseTcpKeepalivePacketData(noScaleTestData); + final TcpKeepalivePacketData noScaleRoundTripData = + KeepalivePacketDataUtil.fromStableParcelable(noScaleParsedParcelable); + assertEquals(noScaleTestData, noScaleRoundTripData); + assertTrue(noScaleTestData.getPacket().length > 0); + assertArrayEquals(noScaleTestData.getPacket(), noScaleRoundTripData.getPacket()); + } } diff --git a/wifi/jarjar-rules.txt b/wifi/jarjar-rules.txt index 75b5e728eb0d..4099c27a0fae 100644 --- a/wifi/jarjar-rules.txt +++ b/wifi/jarjar-rules.txt @@ -21,6 +21,7 @@ rule android.net.ProvisioningConfigurationParcelable* com.android.wifi.x.@0 rule android.net.ResolverParamsParcel* com.android.wifi.x.@0 rule android.net.RouteInfoParcel* com.android.wifi.x.@0 rule android.net.ScanResultInfoParcelable* com.android.wifi.x.@0 +rule android.net.TcpKeepalivePacketDataParcelable* com.android.wifi.x.@0 rule android.net.TetherConfigParcel* com.android.wifi.x.@0 rule android.net.TetherOffloadRuleParcel* com.android.wifi.x.@0 rule android.net.TetherStatsParcel* com.android.wifi.x.@0 @@ -43,7 +44,6 @@ rule android.net.DhcpResults* com.android.wifi.x.@0 rule android.net.InterfaceConfiguration* com.android.wifi.x.@0 rule android.net.IpMemoryStore* com.android.wifi.x.@0 rule android.net.NetworkMonitorManager* com.android.wifi.x.@0 -rule android.net.TcpKeepalivePacketData* com.android.wifi.x.@0 rule android.net.NetworkFactory* com.android.wifi.x.@0 rule android.net.ip.IpClientCallbacks* com.android.wifi.x.@0 rule android.net.ip.IpClientManager* com.android.wifi.x.@0 |