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

Commit b9e70c46 authored by Erik Kline's avatar Erik Kline Committed by Android Git Automerger
Browse files

am 6f611d72: Merge "Set NLM_F_ACK in our RTM_NEWNEIGH requests" into mnc-dev

* commit '6f611d72':
  Set NLM_F_ACK in our RTM_NEWNEIGH requests
parents 87293453 6f611d72
Loading
Loading
Loading
Loading
+57 −31
Original line number Diff line number Diff line
@@ -76,6 +76,60 @@ public class IpReachabilityMonitor {
    private final NetlinkSocketObserver mNetlinkSocketObserver;
    private final Thread mObserverThread;

    /**
     * Make the kernel to perform neighbor reachability detection (IPv4 ARP or IPv6 ND)
     * for the given IP address on the specified interface index.
     *
     * @return true, if the request was successfully passed to the kernel; false otherwise.
     */
    public static boolean probeNeighbor(int ifIndex, InetAddress ip) {
        final long IO_TIMEOUT = 300L;
        // This currently does not cause neighbor probing if the target |ip|
        // has been confirmed reachable within the past "delay_probe_time"
        // seconds, i.e. within the past 5 seconds.
        //
        // TODO: replace with a transition directly to NUD_PROBE state once
        // kernels are updated to do so correctly.
        if (DBG) { Log.d(TAG, "Probing ip=" + ip.getHostAddress()); }

        final byte[] msg = RtNetlinkNeighborMessage.newNewNeighborMessage(
                1, ip, StructNdMsg.NUD_DELAY, ifIndex, null);
        NetlinkSocket nlSocket = null;
        boolean returnValue = false;

        try {
            nlSocket = new NetlinkSocket(OsConstants.NETLINK_ROUTE);
            nlSocket.connectToKernel();
            nlSocket.sendMessage(msg, 0, msg.length, IO_TIMEOUT);
            final ByteBuffer bytes = nlSocket.recvMessage(IO_TIMEOUT);
            final NetlinkMessage response = NetlinkMessage.parse(bytes);
            if (response != null && response instanceof NetlinkErrorMessage &&
                    (((NetlinkErrorMessage) response).getNlMsgError() != null) &&
                    (((NetlinkErrorMessage) response).getNlMsgError().error == 0)) {
                returnValue = true;
            } else {
                String errmsg;
                if (bytes == null) {
                    errmsg = "null recvMessage";
                } else if (response == null) {
                    bytes.position(0);
                    errmsg = "raw bytes: " + NetlinkConstants.hexify(bytes);
                } else {
                    errmsg = response.toString();
                }
                Log.e(TAG, "Error probing ip=" + ip.getHostAddress() +
                        ", errmsg=" + errmsg);
            }
        } catch (ErrnoException | InterruptedIOException | SocketException e) {
            Log.d(TAG, "Error probing ip=" + ip.getHostAddress(), e);
        }

        if (nlSocket != null) {
            nlSocket.close();
        }
        return returnValue;
    }

    public IpReachabilityMonitor(String ifName, Callback callback) throws IllegalArgumentException {
        mInterfaceName = ifName;
        int ifIndex = -1;
@@ -216,38 +270,10 @@ public class IpReachabilityMonitor {
            ipProbeList.addAll(mIpWatchList);
        }
        for (InetAddress target : ipProbeList) {
            if (!stillRunning()) { break; }
            probeIp(target);
        }
    }

    private void probeIp(InetAddress ip) {
        // This currently does not cause neighbor probing if the target |ip|
        // has been confirmed reachable within the past "delay_probe_time"
        // seconds, i.e. within the past 5 seconds.
        //
        // TODO: replace with a transition directly to NUD_PROBE state once
        // kernels are updated to do so correctly.
        if (DBG) { Log.d(TAG, "Probing ip=" + ip.getHostAddress()); }

        final byte[] msg = RtNetlinkNeighborMessage.newNewNeighborMessage(
                1, ip, StructNdMsg.NUD_DELAY, mInterfaceIndex, null);
        NetlinkSocket nlSocket = null;

        try {
            nlSocket = new NetlinkSocket(OsConstants.NETLINK_ROUTE);
            nlSocket.connectToKernel();
            nlSocket.sendMessage(msg, 0, msg.length, 300);
            final NetlinkMessage response = NetlinkMessage.parse(nlSocket.recvMessage(300));
            if (response != null && response instanceof NetlinkErrorMessage) {
                Log.e(TAG, "Error probing ip=" + response.toString());
            }
        } catch (ErrnoException | InterruptedIOException | SocketException e) {
            Log.d(TAG, "Error probing ip=" + ip.getHostAddress(), e);
            if (!stillRunning()) {
                break;
            }

        if (nlSocket != null) {
            nlSocket.close();
            probeNeighbor(mInterfaceIndex, target);
        }
    }

+0 −1
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package android.net.netlink;

import android.net.netlink.StructNlMsgHdr;
import android.net.netlink.NetlinkMessage;
import android.util.Log;

import java.nio.ByteBuffer;

+1 −1
Original line number Diff line number Diff line
@@ -60,7 +60,7 @@ public class NetlinkMessage {
        switch (nlmsghdr.nlmsg_type) {
            //case NetlinkConstants.NLMSG_NOOP:
            case NetlinkConstants.NLMSG_ERROR:
                return (NetlinkMessage) NetlinkErrorMessage.parse(byteBuffer);
                return (NetlinkMessage) NetlinkErrorMessage.parse(nlmsghdr, byteBuffer);
            case NetlinkConstants.NLMSG_DONE:
                byteBuffer.position(byteBuffer.position() + payloadLength);
                return new NetlinkMessage(nlmsghdr);
+7 −2
Original line number Diff line number Diff line
@@ -16,6 +16,11 @@

package android.net.netlink;

import static android.net.netlink.StructNlMsgHdr.NLM_F_ACK;
import static android.net.netlink.StructNlMsgHdr.NLM_F_DUMP;
import static android.net.netlink.StructNlMsgHdr.NLM_F_REPLACE;
import static android.net.netlink.StructNlMsgHdr.NLM_F_REQUEST;

import android.net.netlink.StructNdaCacheInfo;
import android.net.netlink.StructNdMsg;
import android.net.netlink.StructNlAttr;
@@ -123,7 +128,7 @@ public class RtNetlinkNeighborMessage extends NetlinkMessage {
        final StructNlMsgHdr nlmsghdr = new StructNlMsgHdr();
        nlmsghdr.nlmsg_len = length;
        nlmsghdr.nlmsg_type = NetlinkConstants.RTM_GETNEIGH;
        nlmsghdr.nlmsg_flags = StructNlMsgHdr.NLM_F_REQUEST|StructNlMsgHdr.NLM_F_DUMP;
        nlmsghdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
        nlmsghdr.nlmsg_seq = seqNo;
        nlmsghdr.pack(byteBuffer);

@@ -141,7 +146,7 @@ public class RtNetlinkNeighborMessage extends NetlinkMessage {
            int seqNo, InetAddress ip, short nudState, int ifIndex, byte[] llAddr) {
        final StructNlMsgHdr nlmsghdr = new StructNlMsgHdr();
        nlmsghdr.nlmsg_type = NetlinkConstants.RTM_NEWNEIGH;
        nlmsghdr.nlmsg_flags = StructNlMsgHdr.NLM_F_REQUEST | StructNlMsgHdr.NLM_F_REPLACE;
        nlmsghdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_REPLACE;
        nlmsghdr.nlmsg_seq = seqNo;

        final RtNetlinkNeighborMessage msg = new RtNetlinkNeighborMessage(nlmsghdr);
+0 −5
Original line number Diff line number Diff line
@@ -52,11 +52,6 @@ public class StructNlMsgErr {
    public int error;
    public StructNlMsgHdr msg;

    public StructNlMsgErr() {
        error = 0;
        msg = null;
    }

    public void pack(ByteBuffer byteBuffer) {
        // The ByteOrder must have already been set by the caller.  In most
        // cases ByteOrder.nativeOrder() is correct, with the possible
Loading