Merge "Add OsCompat"
This commit is contained in:
75
service/src/com/android/server/connectivity/OsCompat.java
Normal file
75
service/src/com/android/server/connectivity/OsCompat.java
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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 com.android.server.connectivity;
|
||||
|
||||
import android.system.ErrnoException;
|
||||
import android.system.Os;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
|
||||
/**
|
||||
* Compatibility utility for android.system.Os core platform APIs.
|
||||
*
|
||||
* Connectivity has access to such APIs, but they are not part of the module_current stubs yet
|
||||
* (only core_current). Most stable core platform APIs are included manually in the connectivity
|
||||
* build rules, but because Os is also part of the base java SDK that is earlier on the
|
||||
* classpath, the extra core platform APIs are not seen.
|
||||
*
|
||||
* TODO (b/157639992, b/183097033): remove as soon as core_current is part of system_server_current
|
||||
* @hide
|
||||
*/
|
||||
public class OsCompat {
|
||||
// This value should be correct on all architectures supported by Android, but hardcoding ioctl
|
||||
// numbers should be avoided.
|
||||
/**
|
||||
* @see android.system.OsConstants#TIOCOUTQ
|
||||
*/
|
||||
public static final int TIOCOUTQ = 0x5411;
|
||||
|
||||
/**
|
||||
* @see android.system.Os#getsockoptInt(FileDescriptor, int, int)
|
||||
*/
|
||||
public static int getsockoptInt(FileDescriptor fd, int level, int option) throws
|
||||
ErrnoException {
|
||||
try {
|
||||
return (int) Os.class.getMethod(
|
||||
"getsockoptInt", FileDescriptor.class, int.class, int.class)
|
||||
.invoke(null, fd, level, option);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
if (e.getCause() instanceof ErrnoException) {
|
||||
throw (ErrnoException) e.getCause();
|
||||
}
|
||||
throw new IllegalStateException("Error calling getsockoptInt", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see android.system.Os#ioctlInt(FileDescriptor, int)
|
||||
*/
|
||||
public static int ioctlInt(FileDescriptor fd, int cmd) throws
|
||||
ErrnoException {
|
||||
try {
|
||||
return (int) Os.class.getMethod(
|
||||
"ioctlInt", FileDescriptor.class, int.class).invoke(null, fd, cmd);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
if (e.getCause() instanceof ErrnoException) {
|
||||
throw (ErrnoException) e.getCause();
|
||||
}
|
||||
throw new IllegalStateException("Error calling ioctlInt", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,8 @@ import static android.system.OsConstants.IPPROTO_IP;
|
||||
import static android.system.OsConstants.IPPROTO_TCP;
|
||||
import static android.system.OsConstants.IP_TOS;
|
||||
import static android.system.OsConstants.IP_TTL;
|
||||
import static android.system.OsConstants.TIOCOUTQ;
|
||||
|
||||
import static com.android.server.connectivity.OsCompat.TIOCOUTQ;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.net.InvalidPacketException;
|
||||
@@ -175,10 +176,10 @@ public class TcpKeepaliveController {
|
||||
}
|
||||
// Query write sequence number from SEND_QUEUE.
|
||||
Os.setsockoptInt(fd, IPPROTO_TCP, TCP_REPAIR_QUEUE, TCP_SEND_QUEUE);
|
||||
tcpDetails.seq = Os.getsockoptInt(fd, IPPROTO_TCP, TCP_QUEUE_SEQ);
|
||||
tcpDetails.seq = OsCompat.getsockoptInt(fd, IPPROTO_TCP, TCP_QUEUE_SEQ);
|
||||
// Query read sequence number from RECV_QUEUE.
|
||||
Os.setsockoptInt(fd, IPPROTO_TCP, TCP_REPAIR_QUEUE, TCP_RECV_QUEUE);
|
||||
tcpDetails.ack = Os.getsockoptInt(fd, IPPROTO_TCP, TCP_QUEUE_SEQ);
|
||||
tcpDetails.ack = OsCompat.getsockoptInt(fd, IPPROTO_TCP, TCP_QUEUE_SEQ);
|
||||
// Switch to NO_QUEUE to prevent illegal socket read/write in repair mode.
|
||||
Os.setsockoptInt(fd, IPPROTO_TCP, TCP_REPAIR_QUEUE, TCP_NO_QUEUE);
|
||||
// Finally, check if socket is still idle. TODO : this check needs to move to
|
||||
@@ -198,9 +199,9 @@ public class TcpKeepaliveController {
|
||||
tcpDetails.rcvWndScale = trw.rcvWndScale;
|
||||
if (tcpDetails.srcAddress.length == 4 /* V4 address length */) {
|
||||
// Query TOS.
|
||||
tcpDetails.tos = Os.getsockoptInt(fd, IPPROTO_IP, IP_TOS);
|
||||
tcpDetails.tos = OsCompat.getsockoptInt(fd, IPPROTO_IP, IP_TOS);
|
||||
// Query TTL.
|
||||
tcpDetails.ttl = Os.getsockoptInt(fd, IPPROTO_IP, IP_TTL);
|
||||
tcpDetails.ttl = OsCompat.getsockoptInt(fd, IPPROTO_IP, IP_TTL);
|
||||
}
|
||||
} catch (ErrnoException e) {
|
||||
Log.e(TAG, "Exception reading TCP state from socket", e);
|
||||
@@ -305,7 +306,7 @@ public class TcpKeepaliveController {
|
||||
|
||||
private static boolean isReceiveQueueEmpty(FileDescriptor fd)
|
||||
throws ErrnoException {
|
||||
final int result = Os.ioctlInt(fd, SIOCINQ);
|
||||
final int result = OsCompat.ioctlInt(fd, SIOCINQ);
|
||||
if (result != 0) {
|
||||
Log.e(TAG, "Read queue has data");
|
||||
return false;
|
||||
@@ -315,7 +316,7 @@ public class TcpKeepaliveController {
|
||||
|
||||
private static boolean isSendQueueEmpty(FileDescriptor fd)
|
||||
throws ErrnoException {
|
||||
final int result = Os.ioctlInt(fd, SIOCOUTQ);
|
||||
final int result = OsCompat.ioctlInt(fd, SIOCOUTQ);
|
||||
if (result != 0) {
|
||||
Log.e(TAG, "Write queue has data");
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user