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

Commit e443e6b0 authored by Remi NGUYEN VAN's avatar Remi NGUYEN VAN
Browse files

Add OsCompat

Although the InetAddress symbols used by Connectivity are stable core
platform API, and should be usable, the core_current stubs are not yet
part of the module_current API.
Until that is fixed, add an InetAddressCompat utility that calls the
three static methods by reflection.

Test: atest FrameworksNetTests CtsNetTestCases
Bug: 183097033
Change-Id: I8d1a4811a1cc7dbc62f4033c2b320246d1d72b28
parent 5a328c2a
Loading
Loading
Loading
Loading
+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);
        }
    }
}
+8 −7
Original line number Diff line number Diff line
@@ -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;