Loading services/core/java/com/android/server/connectivity/OsCompat.java 0 → 100644 +75 −0 Original line number Diff line number Diff line /* * 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); } } } services/core/java/com/android/server/connectivity/TcpKeepaliveController.java +8 −7 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading @@ -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); Loading Loading @@ -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; Loading @@ -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; Loading Loading
services/core/java/com/android/server/connectivity/OsCompat.java 0 → 100644 +75 −0 Original line number Diff line number Diff line /* * 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); } } }
services/core/java/com/android/server/connectivity/TcpKeepaliveController.java +8 −7 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading @@ -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); Loading Loading @@ -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; Loading @@ -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; Loading