Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 40190840 authored by Remi NGUYEN VAN's avatar Remi NGUYEN VAN Committed by Automerger Merge Worker
Browse files

Add TcpKeepalivePacketData to SystemApi am: 103ec4aa am: a232c680

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1494038

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: Ic764adda49e414e6ed34a101fd83c3fc62f5734c
parents c6036ee3 a232c680
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -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();
+163 −0
Original line number Diff line number Diff line
/*
 * 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.
@@ -15,27 +15,21 @@
 */
package android.net;

import static android.net.SocketKeepalive.ERROR_INVALID_IP_ADDRESS;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
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 {
@SystemApi
public final class TcpKeepalivePacketData extends KeepalivePacketData implements Parcelable {
    private static final String TAG = "TcpKeepalivePacketData";

    /** TCP sequence number. */
@@ -45,10 +39,10 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
    public final int tcpAck;

    /** TCP RCV window. */
    public final int tcpWnd;
    public final int tcpWindow;

    /** TCP RCV window scale. */
    public final int tcpWndScale;
    public final int tcpWindowScale;

    /** IP TOS. */
    public final int ipTos;
@@ -56,99 +50,19 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
    /** 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)
    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.tcpWnd = tcpWnd;
        this.tcpWndScale = tcpWndScale;
        this.tcpWindow = tcpWindow;
        this.tcpWindowScale = tcpWindowScale;
        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;
@@ -161,8 +75,8 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
                && getDstPort() == other.getDstPort()
                && this.tcpAck == other.tcpAck
                && this.tcpSeq == other.tcpSeq
                && this.tcpWnd == other.tcpWnd
                && this.tcpWndScale == other.tcpWndScale
                && this.tcpWindow == other.tcpWindow
                && this.tcpWindowScale == other.tcpWindowScale
                && this.ipTos == other.ipTos
                && this.ipTtl == other.ipTtl;
    }
@@ -170,7 +84,7 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
    @Override
    public int hashCode() {
        return Objects.hash(getSrcAddress(), getDstAddress(), getSrcPort(), getDstPort(),
                tcpAck, tcpSeq, tcpWnd, tcpWndScale, ipTos, ipTtl);
                tcpAck, tcpSeq, tcpWindow, tcpWindowScale, ipTos, ipTtl);
    }

    /**
@@ -179,12 +93,14 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
     * 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. */
    public void writeToParcel(Parcel out, int flags) {
    @Override
    public void writeToParcel(@NonNull Parcel out, int flags) {
        out.writeString(getSrcAddress().getHostAddress());
        out.writeString(getDstAddress().getHostAddress());
        out.writeInt(getSrcPort());
@@ -192,8 +108,8 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
        out.writeByteArray(getPacket());
        out.writeInt(tcpSeq);
        out.writeInt(tcpAck);
        out.writeInt(tcpWnd);
        out.writeInt(tcpWndScale);
        out.writeInt(tcpWindow);
        out.writeInt(tcpWindowScale);
        out.writeInt(ipTos);
        out.writeInt(ipTtl);
    }
@@ -222,7 +138,7 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
                        return readFromParcel(in);
                    } catch (InvalidPacketException e) {
                        throw new IllegalArgumentException(
                                "Invalid NAT-T keepalive data: " + e.getError());
                                "Invalid TCP keepalive data: " + e.getError());
                    }
                }

@@ -231,27 +147,6 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
                }
            };

    /**
     * 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()
@@ -260,8 +155,8 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
                + " dport: " + getDstPort()
                + " seq: " + tcpSeq
                + " ack: " + tcpAck
                + " wnd: " + tcpWnd
                + " wndScale: " + tcpWndScale
                + " window: " + tcpWindow
                + " windowScale: " + tcpWindowScale
                + " tos: " + ipTos
                + " ttl: " + ipTtl;
    }
+3 −2
Original line number Diff line number Diff line
@@ -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)
+0 −1
Original line number Diff line number Diff line
@@ -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",
+13 −1
Original line number Diff line number Diff line
@@ -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);
Loading