diff options
Diffstat (limited to 'common/device/com/android/net/module/util/ip/NetlinkMonitor.java')
-rw-r--r-- | common/device/com/android/net/module/util/ip/NetlinkMonitor.java | 188 |
1 files changed, 0 insertions, 188 deletions
diff --git a/common/device/com/android/net/module/util/ip/NetlinkMonitor.java b/common/device/com/android/net/module/util/ip/NetlinkMonitor.java deleted file mode 100644 index f882483d..00000000 --- a/common/device/com/android/net/module/util/ip/NetlinkMonitor.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (C) 2020 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.net.module.util.ip; - -import static android.system.OsConstants.AF_NETLINK; -import static android.system.OsConstants.ENOBUFS; -import static android.system.OsConstants.SOCK_DGRAM; -import static android.system.OsConstants.SOCK_NONBLOCK; -import static android.system.OsConstants.SOL_SOCKET; -import static android.system.OsConstants.SO_RCVBUF; - -import static com.android.net.module.util.SocketUtils.closeSocketQuietly; -import static com.android.net.module.util.SocketUtils.makeNetlinkSocketAddress; -import static com.android.net.module.util.netlink.NetlinkConstants.hexify; - -import android.annotation.NonNull; -import android.os.Handler; -import android.os.SystemClock; -import android.system.ErrnoException; -import android.system.Os; -import android.util.Log; - -import com.android.net.module.util.PacketReader; -import com.android.net.module.util.SharedLog; -import com.android.net.module.util.netlink.NetlinkErrorMessage; -import com.android.net.module.util.netlink.NetlinkMessage; -import com.android.net.module.util.netlink.NetlinkUtils; - -import java.io.FileDescriptor; -import java.net.SocketAddress; -import java.net.SocketException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -/** - * A simple base class to listen for netlink broadcasts. - * - * Opens a netlink socket of the given family and binds to the specified groups. Polls the socket - * from the event loop of the passed-in {@link Handler}, and calls the subclass-defined - * {@link #processNetlinkMessage} method on the handler thread for each netlink message that - * arrives. Currently ignores all netlink errors. - * @hide - */ -public class NetlinkMonitor extends PacketReader { - protected final SharedLog mLog; - protected final String mTag; - private final int mFamily; - private final int mBindGroups; - private final int mSockRcvbufSize; - - private static final boolean DBG = false; - - // Default socket receive buffer size. This means the specific buffer size is not set. - private static final int DEFAULT_SOCKET_RECV_BUFSIZE = -1; - - /** - * Constructs a new {@code NetlinkMonitor} instance. - * - * @param h The Handler on which to poll for messages and on which to call - * {@link #processNetlinkMessage}. - * @param log A SharedLog to log to. - * @param tag The log tag to use for log messages. - * @param family the Netlink socket family to, e.g., {@code NETLINK_ROUTE}. - * @param bindGroups the netlink groups to bind to. - * @param sockRcvbufSize the specific socket receive buffer size in bytes. -1 means that don't - * set the specific socket receive buffer size in #createFd and use the default value in - * /proc/sys/net/core/rmem_default file. See SO_RCVBUF in man-pages/socket. - */ - public NetlinkMonitor(@NonNull Handler h, @NonNull SharedLog log, @NonNull String tag, - int family, int bindGroups, int sockRcvbufSize) { - super(h, NetlinkUtils.DEFAULT_RECV_BUFSIZE); - mLog = log.forSubComponent(tag); - mTag = tag; - mFamily = family; - mBindGroups = bindGroups; - mSockRcvbufSize = sockRcvbufSize; - } - - public NetlinkMonitor(@NonNull Handler h, @NonNull SharedLog log, @NonNull String tag, - int family, int bindGroups) { - this(h, log, tag, family, bindGroups, DEFAULT_SOCKET_RECV_BUFSIZE); - } - - @Override - protected FileDescriptor createFd() { - FileDescriptor fd = null; - - try { - fd = Os.socket(AF_NETLINK, SOCK_DGRAM | SOCK_NONBLOCK, mFamily); - if (mSockRcvbufSize != DEFAULT_SOCKET_RECV_BUFSIZE) { - try { - Os.setsockoptInt(fd, SOL_SOCKET, SO_RCVBUF, mSockRcvbufSize); - } catch (ErrnoException e) { - Log.wtf(mTag, "Failed to set SO_RCVBUF to " + mSockRcvbufSize, e); - } - } - Os.bind(fd, makeNetlinkSocketAddress(0, mBindGroups)); - NetlinkUtils.connectSocketToNetlink(fd); - - if (DBG) { - final SocketAddress nlAddr = Os.getsockname(fd); - Log.d(mTag, "bound to sockaddr_nl{" + nlAddr.toString() + "}"); - } - } catch (ErrnoException | SocketException e) { - logError("Failed to create rtnetlink socket", e); - closeSocketQuietly(fd); - return null; - } - - return fd; - } - - @Override - protected void handlePacket(byte[] recvbuf, int length) { - final long whenMs = SystemClock.elapsedRealtime(); - final ByteBuffer byteBuffer = ByteBuffer.wrap(recvbuf, 0, length); - byteBuffer.order(ByteOrder.nativeOrder()); - - while (byteBuffer.remaining() > 0) { - try { - final int position = byteBuffer.position(); - final NetlinkMessage nlMsg = NetlinkMessage.parse(byteBuffer, mFamily); - if (nlMsg == null || nlMsg.getHeader() == null) { - byteBuffer.position(position); - mLog.e("unparsable netlink msg: " + hexify(byteBuffer)); - break; - } - - if (nlMsg instanceof NetlinkErrorMessage) { - mLog.e("netlink error: " + nlMsg); - continue; - } - - processNetlinkMessage(nlMsg, whenMs); - } catch (Exception e) { - mLog.e("Error handling netlink message", e); - } - } - } - - @Override - protected void logError(String msg, Exception e) { - mLog.e(msg, e); - } - - // Ignoring ENOBUFS may miss any important netlink messages, there are some messages which - // cannot be recovered by dumping current state once missed since kernel doesn't keep state - // for it. In addition, dumping current state will not result in any RTM_DELxxx messages, so - // reconstructing current state from a dump will be difficult. However, for those netlink - // messages don't cause any state changes, e.g. RTM_NEWLINK with current link state, maybe - // it's okay to ignore them, because these netlink messages won't cause any changes on the - // LinkProperties. Given the above trade-offs, try to ignore ENOBUFS and that's similar to - // what netd does today. - // - // TODO: log metrics when ENOBUFS occurs, or even force a disconnect, it will help see how - // often this error occurs on fields with the associated socket receive buffer size. - @Override - protected boolean handleReadError(ErrnoException e) { - logError("readPacket error: ", e); - if (e.errno == ENOBUFS) { - Log.wtf(mTag, "Errno: ENOBUFS"); - return false; - } - return true; - } - - /** - * Processes one netlink message. Must be overridden by subclasses. - * @param nlMsg the message to process. - * @param whenMs the timestamp, as measured by {@link SystemClock#elapsedRealtime}, when the - * message was received. - */ - protected void processNetlinkMessage(NetlinkMessage nlMsg, long whenMs) { } -} |