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

Commit 910b83dd authored by Hungming Chen's avatar Hungming Chen Committed by Nucca Chen
Browse files

ConntrackMonitor: enlarge the socket receive buffer size

Needed because FdEventsReader gets the error ENOBUFS while too many
connections are disconnected by losing network.

Manual test:
1. Enable IPv4-only mobile data as upstream.
2. Enable {USB, WIFI} tethering.
3. Create total 200+ connections from tethered clients.
4. Check the offload rules in dumpsys.
5. Disable mobile data.
6. Enable mobile data.
7. Create total 200+ connections from tethered clients.
8. Check the offload rules in dumpsys.

Test: atest NetworkStackTests

Change-Id: Id2d034e103c1ca3bd3a5935bb72c7d5520afc8b0
parent f47788f7
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -51,6 +51,12 @@ public class ConntrackMonitor extends NetlinkMonitor {
    public static final int NF_NETLINK_CONNTRACK_UPDATE = 2;
    public static final int NF_NETLINK_CONNTRACK_DESTROY = 4;

    // The socket receive buffer size in bytes. If too many conntrack messages are sent too
    // quickly, the conntrack messages can overflow the socket receive buffer. This can happen
    // if too many connections are disconnected by losing network and so on. Use a large-enough
    // buffer to avoid the error ENOBUFS while listening to the conntrack messages.
    private static final int SOCKET_RECV_BUFSIZE = 6 * 1024 * 1024;

    /**
     * A class for describing parsed netfilter conntrack events.
     */
@@ -176,7 +182,7 @@ public class ConntrackMonitor extends NetlinkMonitor {
    public ConntrackMonitor(@NonNull Handler h, @NonNull SharedLog log,
            @NonNull ConntrackEventConsumer cb) {
        super(h, log, TAG, OsConstants.NETLINK_NETFILTER, NF_NETLINK_CONNTRACK_NEW
                | NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY);
                | NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY, SOCKET_RECV_BUFSIZE);
        mConsumer = cb;
    }

+19 −1
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@ import static android.net.util.SocketUtils.makeNetlinkSocketAddress;
import static android.system.OsConstants.AF_NETLINK;
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 android.annotation.NonNull;
import android.net.netlink.NetlinkErrorMessage;
@@ -56,9 +58,13 @@ public class NetlinkMonitor extends PacketReader {
    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.
     *
@@ -68,14 +74,23 @@ public class NetlinkMonitor extends PacketReader {
     * @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 family, int bindGroups, int sockRcvbufSize) {
        super(h, NetlinkSocket.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
@@ -84,6 +99,9 @@ public class NetlinkMonitor extends PacketReader {

        try {
            fd = Os.socket(AF_NETLINK, SOCK_DGRAM | SOCK_NONBLOCK, mFamily);
            if (mSockRcvbufSize != DEFAULT_SOCKET_RECV_BUFSIZE) {
                Os.setsockoptInt(fd, SOL_SOCKET, SO_RCVBUF, mSockRcvbufSize);
            }
            Os.bind(fd, makeNetlinkSocketAddress(0, mBindGroups));
            NetlinkSocket.connectToKernel(fd);