Merge "[KA02] internal cleanup and refactor for SocketKeepalive"
This commit is contained in:
@@ -1816,7 +1816,7 @@ public class ConnectivityManager {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
switch (message.what) {
|
||||
case NetworkAgent.EVENT_PACKET_KEEPALIVE:
|
||||
case NetworkAgent.EVENT_SOCKET_KEEPALIVE:
|
||||
int error = message.arg2;
|
||||
try {
|
||||
if (error == SUCCESS) {
|
||||
|
||||
@@ -16,22 +16,20 @@
|
||||
|
||||
package android.net;
|
||||
|
||||
import static android.net.ConnectivityManager.PacketKeepalive.*;
|
||||
import static android.net.SocketKeepalive.ERROR_INVALID_IP_ADDRESS;
|
||||
import static android.net.SocketKeepalive.ERROR_INVALID_PORT;
|
||||
|
||||
import android.net.SocketKeepalive.InvalidPacketException;
|
||||
import android.net.util.IpUtils;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.system.OsConstants;
|
||||
import android.util.Log;
|
||||
|
||||
import java.net.Inet4Address;
|
||||
import java.net.InetAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
/**
|
||||
* Represents the actual packets that are sent by the
|
||||
* {@link android.net.ConnectivityManager.PacketKeepalive} API.
|
||||
* {@link android.net.SocketKeepalive} API.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@@ -53,8 +51,8 @@ public class KeepalivePacketData implements Parcelable {
|
||||
/** Packet data. A raw byte string of packet data, not including the link-layer header. */
|
||||
private final byte[] mPacket;
|
||||
|
||||
private static final int IPV4_HEADER_LENGTH = 20;
|
||||
private static final int UDP_HEADER_LENGTH = 8;
|
||||
protected static final int IPV4_HEADER_LENGTH = 20;
|
||||
protected static final int UDP_HEADER_LENGTH = 8;
|
||||
|
||||
// This should only be constructed via static factory methods, such as
|
||||
// nattKeepalivePacket
|
||||
@@ -80,53 +78,10 @@ public class KeepalivePacketData implements Parcelable {
|
||||
}
|
||||
}
|
||||
|
||||
public static class InvalidPacketException extends Exception {
|
||||
public final int error;
|
||||
public InvalidPacketException(int error) {
|
||||
this.error = error;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] getPacket() {
|
||||
return mPacket.clone();
|
||||
}
|
||||
|
||||
public static KeepalivePacketData nattKeepalivePacket(
|
||||
InetAddress srcAddress, int srcPort, InetAddress dstAddress, int dstPort)
|
||||
throws InvalidPacketException {
|
||||
|
||||
if (!(srcAddress instanceof Inet4Address) || !(dstAddress instanceof Inet4Address)) {
|
||||
throw new InvalidPacketException(ERROR_INVALID_IP_ADDRESS);
|
||||
}
|
||||
|
||||
if (dstPort != NATT_PORT) {
|
||||
throw new InvalidPacketException(ERROR_INVALID_PORT);
|
||||
}
|
||||
|
||||
int length = IPV4_HEADER_LENGTH + UDP_HEADER_LENGTH + 1;
|
||||
ByteBuffer buf = ByteBuffer.allocate(length);
|
||||
buf.order(ByteOrder.BIG_ENDIAN);
|
||||
buf.putShort((short) 0x4500); // IP version and TOS
|
||||
buf.putShort((short) length);
|
||||
buf.putInt(0); // ID, flags, offset
|
||||
buf.put((byte) 64); // TTL
|
||||
buf.put((byte) OsConstants.IPPROTO_UDP);
|
||||
int ipChecksumOffset = buf.position();
|
||||
buf.putShort((short) 0); // IP checksum
|
||||
buf.put(srcAddress.getAddress());
|
||||
buf.put(dstAddress.getAddress());
|
||||
buf.putShort((short) srcPort);
|
||||
buf.putShort((short) dstPort);
|
||||
buf.putShort((short) (length - 20)); // UDP length
|
||||
int udpChecksumOffset = buf.position();
|
||||
buf.putShort((short) 0); // UDP checksum
|
||||
buf.put((byte) 0xff); // NAT-T keepalive
|
||||
buf.putShort(ipChecksumOffset, IpUtils.ipChecksum(buf, 0));
|
||||
buf.putShort(udpChecksumOffset, IpUtils.udpChecksum(buf, 0, IPV4_HEADER_LENGTH));
|
||||
|
||||
return new KeepalivePacketData(srcAddress, srcPort, dstAddress, dstPort, buf.array());
|
||||
}
|
||||
|
||||
/* Parcelable Implementation */
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
|
||||
77
core/java/android/net/NattKeepalivePacketData.java
Normal file
77
core/java/android/net/NattKeepalivePacketData.java
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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 android.net.SocketKeepalive.InvalidPacketException;
|
||||
import android.net.util.IpUtils;
|
||||
import android.system.OsConstants;
|
||||
|
||||
import java.net.Inet4Address;
|
||||
import java.net.InetAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
/** @hide */
|
||||
public final class NattKeepalivePacketData extends KeepalivePacketData {
|
||||
|
||||
// This should only be constructed via static factory methods, such as
|
||||
// nattKeepalivePacket
|
||||
private NattKeepalivePacketData(InetAddress srcAddress, int srcPort,
|
||||
InetAddress dstAddress, int dstPort, byte[] data) throws
|
||||
InvalidPacketException {
|
||||
super(srcAddress, srcPort, dstAddress, dstPort, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to create Nat-T keepalive packet structure.
|
||||
*/
|
||||
public static NattKeepalivePacketData nattKeepalivePacket(
|
||||
InetAddress srcAddress, int srcPort, InetAddress dstAddress, int dstPort)
|
||||
throws InvalidPacketException {
|
||||
|
||||
if (!(srcAddress instanceof Inet4Address) || !(dstAddress instanceof Inet4Address)) {
|
||||
throw new InvalidPacketException(SocketKeepalive.ERROR_INVALID_IP_ADDRESS);
|
||||
}
|
||||
|
||||
if (dstPort != NattSocketKeepalive.NATT_PORT) {
|
||||
throw new InvalidPacketException(SocketKeepalive.ERROR_INVALID_PORT);
|
||||
}
|
||||
|
||||
int length = IPV4_HEADER_LENGTH + UDP_HEADER_LENGTH + 1;
|
||||
ByteBuffer buf = ByteBuffer.allocate(length);
|
||||
buf.order(ByteOrder.BIG_ENDIAN);
|
||||
buf.putShort((short) 0x4500); // IP version and TOS
|
||||
buf.putShort((short) length);
|
||||
buf.putInt(0); // ID, flags, offset
|
||||
buf.put((byte) 64); // TTL
|
||||
buf.put((byte) OsConstants.IPPROTO_UDP);
|
||||
int ipChecksumOffset = buf.position();
|
||||
buf.putShort((short) 0); // IP checksum
|
||||
buf.put(srcAddress.getAddress());
|
||||
buf.put(dstAddress.getAddress());
|
||||
buf.putShort((short) srcPort);
|
||||
buf.putShort((short) dstPort);
|
||||
buf.putShort((short) (length - 20)); // UDP length
|
||||
int udpChecksumOffset = buf.position();
|
||||
buf.putShort((short) 0); // UDP checksum
|
||||
buf.put((byte) 0xff); // NAT-T keepalive
|
||||
buf.putShort(ipChecksumOffset, IpUtils.ipChecksum(buf, 0));
|
||||
buf.putShort(udpChecksumOffset, IpUtils.udpChecksum(buf, 0, IPV4_HEADER_LENGTH));
|
||||
|
||||
return new NattKeepalivePacketData(srcAddress, srcPort, dstAddress, dstPort, buf.array());
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,6 @@ package android.net;
|
||||
|
||||
import android.annotation.UnsupportedAppUsage;
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager.PacketKeepalive;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
@@ -154,7 +153,7 @@ public abstract class NetworkAgent extends Handler {
|
||||
*
|
||||
* Also used internally by ConnectivityService / KeepaliveTracker, with different semantics.
|
||||
*/
|
||||
public static final int CMD_START_PACKET_KEEPALIVE = BASE + 11;
|
||||
public static final int CMD_START_SOCKET_KEEPALIVE = BASE + 11;
|
||||
|
||||
/**
|
||||
* Requests that the specified keepalive packet be stopped.
|
||||
@@ -163,20 +162,20 @@ public abstract class NetworkAgent extends Handler {
|
||||
*
|
||||
* Also used internally by ConnectivityService / KeepaliveTracker, with different semantics.
|
||||
*/
|
||||
public static final int CMD_STOP_PACKET_KEEPALIVE = BASE + 12;
|
||||
public static final int CMD_STOP_SOCKET_KEEPALIVE = BASE + 12;
|
||||
|
||||
/**
|
||||
* Sent by the NetworkAgent to ConnectivityService to provide status on a packet keepalive
|
||||
* request. This may either be the reply to a CMD_START_PACKET_KEEPALIVE, or an asynchronous
|
||||
* Sent by the NetworkAgent to ConnectivityService to provide status on a socket keepalive
|
||||
* request. This may either be the reply to a CMD_START_SOCKET_KEEPALIVE, or an asynchronous
|
||||
* error notification.
|
||||
*
|
||||
* This is also sent by KeepaliveTracker to the app's ConnectivityManager.PacketKeepalive to
|
||||
* so that the app's PacketKeepaliveCallback methods can be called.
|
||||
* This is also sent by KeepaliveTracker to the app's {@link SocketKeepalive},
|
||||
* so that the app's {@link SocketKeepalive.Callback} methods can be called.
|
||||
*
|
||||
* arg1 = slot number of the keepalive
|
||||
* arg2 = error code
|
||||
*/
|
||||
public static final int EVENT_PACKET_KEEPALIVE = BASE + 13;
|
||||
public static final int EVENT_SOCKET_KEEPALIVE = BASE + 13;
|
||||
|
||||
/**
|
||||
* Sent by ConnectivityService to inform this network transport of signal strength thresholds
|
||||
@@ -288,12 +287,12 @@ public abstract class NetworkAgent extends Handler {
|
||||
saveAcceptUnvalidated(msg.arg1 != 0);
|
||||
break;
|
||||
}
|
||||
case CMD_START_PACKET_KEEPALIVE: {
|
||||
startPacketKeepalive(msg);
|
||||
case CMD_START_SOCKET_KEEPALIVE: {
|
||||
startSocketKeepalive(msg);
|
||||
break;
|
||||
}
|
||||
case CMD_STOP_PACKET_KEEPALIVE: {
|
||||
stopPacketKeepalive(msg);
|
||||
case CMD_STOP_SOCKET_KEEPALIVE: {
|
||||
stopSocketKeepalive(msg);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -443,22 +442,22 @@ public abstract class NetworkAgent extends Handler {
|
||||
/**
|
||||
* Requests that the network hardware send the specified packet at the specified interval.
|
||||
*/
|
||||
protected void startPacketKeepalive(Message msg) {
|
||||
onPacketKeepaliveEvent(msg.arg1, PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED);
|
||||
protected void startSocketKeepalive(Message msg) {
|
||||
onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_HARDWARE_UNSUPPORTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the network hardware send the specified packet at the specified interval.
|
||||
* Requests that the network hardware stops sending keepalive packets.
|
||||
*/
|
||||
protected void stopPacketKeepalive(Message msg) {
|
||||
onPacketKeepaliveEvent(msg.arg1, PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED);
|
||||
protected void stopSocketKeepalive(Message msg) {
|
||||
onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_HARDWARE_UNSUPPORTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the network when a packet keepalive event occurs.
|
||||
* Called by the network when a socket keepalive event occurs.
|
||||
*/
|
||||
public void onPacketKeepaliveEvent(int slot, int reason) {
|
||||
queueOrSendMessage(EVENT_PACKET_KEEPALIVE, slot, reason);
|
||||
public void onSocketKeepaliveEvent(int slot, int reason) {
|
||||
queueOrSendMessage(EVENT_SOCKET_KEEPALIVE, slot, reason);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -109,6 +109,18 @@ public abstract class SocketKeepalive implements AutoCloseable {
|
||||
**/
|
||||
public static final int MAX_INTERVAL_SEC = 3600;
|
||||
|
||||
/**
|
||||
* This packet is invalid.
|
||||
* See the error code for details.
|
||||
* @hide
|
||||
*/
|
||||
public static class InvalidPacketException extends Exception {
|
||||
public final int error;
|
||||
public InvalidPacketException(int error) {
|
||||
this.error = error;
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull final IConnectivityManager mService;
|
||||
@NonNull final Network mNetwork;
|
||||
@NonNull private final Executor mExecutor;
|
||||
@@ -135,7 +147,7 @@ public abstract class SocketKeepalive implements AutoCloseable {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
switch (message.what) {
|
||||
case NetworkAgent.EVENT_PACKET_KEEPALIVE:
|
||||
case NetworkAgent.EVENT_SOCKET_KEEPALIVE:
|
||||
final int status = message.arg2;
|
||||
try {
|
||||
if (status == SUCCESS) {
|
||||
|
||||
Reference in New Issue
Block a user