/*
 * Copyright 2016 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.
 *
 * sock_diag_test.cpp - unit tests for SockDiag.cpp
 */

#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <linux/inet_diag.h>

#include <gtest/gtest.h>
#include <netdutils/NetNativeTestBase.h>

#include "Fwmark.h"
#include "NetdConstants.h"
#include "SockDiag.h"
#include "UidRanges.h"

namespace android {
namespace net {

class SockDiagTest : public NetNativeTestBase {
protected:
    static bool isLoopbackSocket(const inet_diag_msg *msg) {
        return SockDiag::isLoopbackSocket(msg);
    };
};

uint16_t bindAndListen(int s) {
    for (int i = 0; i < 10; i++) {
        uint16_t port = 1024 + arc4random_uniform(0xffff - 1024);
        sockaddr_in6 sin6 = { .sin6_family = AF_INET6, .sin6_port = htons(port) };
        if (bind(s, (sockaddr *) &sin6, sizeof(sin6)) == 0) {
            listen(s, 1);
            return port;
        }
    }
    close(s);
    return 0;
}

const char *tcpStateName(uint8_t state) {
    static const char *states[] = {
        "???",
        "TCP_ESTABLISHED",
        "TCP_SYN_SENT",
        "TCP_SYN_RECV",
        "TCP_FIN_WAIT1",
        "TCP_FIN_WAIT2",
        "TCP_TIME_WAIT",
        "TCP_CLOSE",
        "TCP_CLOSE_WAIT",
        "TCP_LAST_ACK",
        "TCP_LISTEN",
        "TCP_CLOSING",
        "TCP_NEW_SYN_RECV",
    };
    return states[(state < ARRAY_SIZE(states)) ? state : 0];
}

TEST_F(SockDiagTest, TestDump) {
    int v4socket = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
    ASSERT_NE(-1, v4socket) << "Failed to open IPv4 socket: " << strerror(errno);
    int v6socket = socket(AF_INET6, SOCK_STREAM | SOCK_CLOEXEC, 0);
    ASSERT_NE(-1, v6socket) << "Failed to open IPv6 socket: " << strerror(errno);
    int listensocket = socket(AF_INET6, SOCK_STREAM | SOCK_CLOEXEC, 0);
    ASSERT_NE(-1, listensocket) << "Failed to open listen socket: " << strerror(errno);

    uint16_t port = bindAndListen(listensocket);
    ASSERT_NE(0, port) << "Can't bind to server port";

    // Connect to loopback.
    sockaddr_in server4 = { .sin_family = AF_INET, .sin_port = htons(port) };
    sockaddr_in6 server6 = { .sin6_family = AF_INET6, .sin6_port = htons(port) };
    ASSERT_EQ(0, connect(v4socket, (sockaddr *) &server4, sizeof(server4)))
        << "IPv4 connect failed: " << strerror(errno);
    ASSERT_EQ(0, connect(v6socket, (sockaddr *) &server6, sizeof(server6)))
        << "IPv6 connect failed: " << strerror(errno);

    sockaddr_in6 client46, client6;
    socklen_t clientlen = std::max(sizeof(client46), sizeof(client6));
    int accepted4 = accept4(
            listensocket, (sockaddr *) &client46, &clientlen, SOCK_CLOEXEC);
    int accepted6 = accept4(
            listensocket, (sockaddr *) &client6, &clientlen, SOCK_CLOEXEC);
    ASSERT_NE(-1, accepted4);
    ASSERT_NE(-1, accepted6);

    int v4SocketsSeen = 0;
    bool seenclient46 = false;
    char src[INET6_ADDRSTRLEN], dst[INET6_ADDRSTRLEN];

    fprintf(stderr, "Ports:\n  server=%d. client46=%d, client6=%d\n",
            port, ntohs(client46.sin6_port), ntohs(client6.sin6_port));

    auto checkIPv4Dump = [&] (uint8_t /* proto */, const inet_diag_msg *msg) {
        EXPECT_EQ(htonl(INADDR_LOOPBACK), msg->id.idiag_src[0]);
        v4SocketsSeen++;
        seenclient46 |= (msg->id.idiag_sport == client46.sin6_port);
        inet_ntop(AF_INET, msg->id.idiag_src, src, sizeof(src));
        inet_ntop(AF_INET, msg->id.idiag_src, dst, sizeof(dst));
        fprintf(stderr, "  v4 %s:%d -> %s:%d %s\n",
                src, htons(msg->id.idiag_sport),
                dst, htons(msg->id.idiag_dport),
                tcpStateName(msg->idiag_state));
        if (msg->idiag_state == TCP_ESTABLISHED) {
            EXPECT_TRUE(isLoopbackSocket(msg));
        }
        return false;
    };

    int v6SocketsSeen = 0;
    bool seenClient6 = false, seenServer46 = false, seenServer6 = false;

    auto checkIPv6Dump = [&] (uint8_t /* proto */, const inet_diag_msg *msg) {
        struct in6_addr *saddr = (struct in6_addr *) msg->id.idiag_src;
        EXPECT_TRUE(
            IN6_IS_ADDR_LOOPBACK(saddr) ||
            (IN6_IS_ADDR_V4MAPPED(saddr) && saddr->s6_addr32[3] == htonl(INADDR_LOOPBACK)));
        v6SocketsSeen++;
        seenClient6 |= (msg->id.idiag_sport == client6.sin6_port);
        seenServer46 |= (msg->id.idiag_sport == htons(port));
        seenServer6 |= (msg->id.idiag_sport == htons(port));
        inet_ntop(AF_INET6, msg->id.idiag_src, src, sizeof(src));
        inet_ntop(AF_INET6, msg->id.idiag_src, dst, sizeof(dst));
        fprintf(stderr, "  v6 [%s]:%d -> [%s]:%d %s\n",
                src, htons(msg->id.idiag_sport),
                dst, htons(msg->id.idiag_dport),
                tcpStateName(msg->idiag_state));
        if (msg->idiag_state == TCP_ESTABLISHED) {
            EXPECT_TRUE(isLoopbackSocket(msg));
        }
        return false;
    };

    SockDiag sd;
    ASSERT_TRUE(sd.open()) << "Failed to open SOCK_DIAG socket";

    int ret = sd.sendDumpRequest(IPPROTO_TCP, AF_INET, "127.0.0.1");
    ASSERT_EQ(0, ret) << "Failed to send IPv4 dump request: " << strerror(-ret);
    fprintf(stderr, "Sent IPv4 dump\n");
    sd.readDiagMsg(IPPROTO_TCP, checkIPv4Dump);
    EXPECT_GE(v4SocketsSeen, 1);
    EXPECT_TRUE(seenclient46);
    EXPECT_FALSE(seenServer46);

    ret = sd.sendDumpRequest(IPPROTO_TCP, AF_INET6, "127.0.0.1");
    ASSERT_EQ(0, ret) << "Failed to send mapped dump request: " << strerror(-ret);
    fprintf(stderr, "Sent mapped dump\n");
    sd.readDiagMsg(IPPROTO_TCP, checkIPv6Dump);
    EXPECT_TRUE(seenServer46);

    ret = sd.sendDumpRequest(IPPROTO_TCP, AF_INET6, "::1");
    ASSERT_EQ(0, ret) << "Failed to send IPv6 dump request: " << strerror(-ret);
    fprintf(stderr, "Sent IPv6 dump\n");

    sd.readDiagMsg(IPPROTO_TCP, checkIPv6Dump);
    EXPECT_GE(v6SocketsSeen, 1);
    EXPECT_TRUE(seenClient6);
    EXPECT_TRUE(seenServer6);

    close(v4socket);
    close(v6socket);
    close(listensocket);
    close(accepted4);
    close(accepted6);
}

bool fillDiagAddr(__be32 addr[4], const sockaddr *sa) {
    switch (sa->sa_family) {
        case AF_INET: {
            sockaddr_in *sin = (sockaddr_in *) sa;
            memcpy(addr, &sin->sin_addr, sizeof(sin->sin_addr));
            return true;
        }
        case AF_INET6: {
            sockaddr_in6 *sin6 = (sockaddr_in6 *) sa;
            memcpy(addr, &sin6->sin6_addr, sizeof(sin6->sin6_addr));
            return true;
        }
        default:
            return false;
    }
}

inet_diag_msg makeDiagMessage(__u8 family,  const sockaddr *src, const sockaddr *dst) {
    inet_diag_msg msg = {
            .idiag_family = family,
            .idiag_state = TCP_ESTABLISHED,
            .id =
                    {
                            .idiag_sport = 1234,
                            .idiag_dport = 4321,
                    },
            .idiag_uid = AID_APP + 123,
            .idiag_inode = 123456789,
    };
    EXPECT_TRUE(fillDiagAddr(msg.id.idiag_src, src));
    EXPECT_TRUE(fillDiagAddr(msg.id.idiag_dst, dst));
    return msg;
}

inet_diag_msg makeDiagMessage(const char* srcstr, const char* dststr) {
    addrinfo hints = { .ai_flags = AI_NUMERICHOST }, *src, *dst;
    EXPECT_EQ(0, getaddrinfo(srcstr, nullptr, &hints, &src));
    EXPECT_EQ(0, getaddrinfo(dststr, nullptr, &hints, &dst));
    EXPECT_EQ(src->ai_addr->sa_family, dst->ai_addr->sa_family);
    inet_diag_msg msg = makeDiagMessage(src->ai_addr->sa_family, src->ai_addr, dst->ai_addr);
    freeaddrinfo(src);
    freeaddrinfo(dst);
    return msg;
}

TEST_F(SockDiagTest, TestIsLoopbackSocket) {
    inet_diag_msg msg;

    msg = makeDiagMessage("127.0.0.1", "127.0.0.1");
    EXPECT_TRUE(isLoopbackSocket(&msg));

    msg = makeDiagMessage("::1", "::1");
    EXPECT_TRUE(isLoopbackSocket(&msg));

    msg = makeDiagMessage("::1", "::ffff:127.0.0.1");
    EXPECT_TRUE(isLoopbackSocket(&msg));

    msg = makeDiagMessage("192.0.2.1", "192.0.2.1");
    EXPECT_TRUE(isLoopbackSocket(&msg));

    msg = makeDiagMessage("192.0.2.1", "8.8.8.8");
    EXPECT_FALSE(isLoopbackSocket(&msg));

    msg = makeDiagMessage("192.0.2.1", "127.0.0.1");
    EXPECT_TRUE(isLoopbackSocket(&msg));

    msg = makeDiagMessage("2001:db8::1", "2001:db8::1");
    EXPECT_TRUE(isLoopbackSocket(&msg));

    msg = makeDiagMessage("2001:db8::1", "2001:4860:4860::6464");
    EXPECT_FALSE(isLoopbackSocket(&msg));

    // While isLoopbackSocket returns true on these sockets, we usually don't want to close them
    // because they aren't specific to any particular network and thus don't become unusable when
    // an app's routing changes or its network access is removed.
    //
    // This isn't a problem, as anything that calls destroyLiveSockets will skip them because
    // destroyLiveSockets only enumerates ESTABLISHED, SYN_SENT, and SYN_RECV sockets.
    msg = makeDiagMessage("127.0.0.1", "0.0.0.0");
    EXPECT_TRUE(isLoopbackSocket(&msg));

    msg = makeDiagMessage("::1", "::");
    EXPECT_TRUE(isLoopbackSocket(&msg));
}

enum MicroBenchmarkTestType {
    ADDRESS,
    UID,
    UID_EXCLUDE_LOOPBACK,
    UIDRANGE,
    UIDRANGE_EXCLUDE_LOOPBACK,
    PERMISSION,
};

const char *testTypeName(MicroBenchmarkTestType mode) {
#define TO_STRING_TYPE(x) case ((x)): return #x;
    switch((mode)) {
        TO_STRING_TYPE(ADDRESS);
        TO_STRING_TYPE(UID);
        TO_STRING_TYPE(UID_EXCLUDE_LOOPBACK);
        TO_STRING_TYPE(UIDRANGE);
        TO_STRING_TYPE(UIDRANGE_EXCLUDE_LOOPBACK);
        TO_STRING_TYPE(PERMISSION);
    }
#undef TO_STRING_TYPE
}

static struct {
    unsigned netId;
    bool explicitlySelected;
    Permission permission;
} permissionTestcases[] = {
    { 42, false, PERMISSION_NONE,    },
    { 42, false, PERMISSION_NETWORK, },
    { 42, false, PERMISSION_SYSTEM,  },
    { 42, true,  PERMISSION_NONE,    },
    { 42, true,  PERMISSION_NETWORK, },
    { 42, true,  PERMISSION_SYSTEM,  },
    { 43, false, PERMISSION_NONE,    },
    { 43, false, PERMISSION_NETWORK, },
    { 43, false, PERMISSION_SYSTEM,  },
    { 43, true,  PERMISSION_NONE,    },
    { 43, true,  PERMISSION_NETWORK, },
    { 43, true,  PERMISSION_SYSTEM,  },
};

class SockDiagMicroBenchmarkTest : public ::testing::TestWithParam<MicroBenchmarkTestType> {

public:
    void SetUp() {
        ASSERT_TRUE(mSd.open()) << "Failed to open SOCK_DIAG socket";
    }

protected:
    SockDiag mSd;

    constexpr static int MAX_SOCKETS = 500;
    constexpr static int ADDRESS_SOCKETS = 500;
    constexpr static int UID_SOCKETS = 50;
    constexpr static int PERMISSION_SOCKETS = 16;

    constexpr static uid_t START_UID = 8000;  // START_UID + number of sockets must be <= 9999.
    constexpr static int CLOSE_UID = START_UID + UID_SOCKETS - 42;  // Close to the end
    static_assert(START_UID + MAX_SOCKETS < 9999, "Too many sockets");

    constexpr static int TEST_NETID = 42;  // One of the OEM netIds.


    int howManySockets() {
        MicroBenchmarkTestType mode = GetParam();
        switch (mode) {
        case ADDRESS:
            return ADDRESS_SOCKETS;
        case UID:
        case UID_EXCLUDE_LOOPBACK:
        case UIDRANGE:
        case UIDRANGE_EXCLUDE_LOOPBACK:
            return UID_SOCKETS;
        case PERMISSION:
            return ARRAY_SIZE(permissionTestcases);
        }
    }

    int modifySocketForTest(int s, int i) {
        MicroBenchmarkTestType mode = GetParam();
        switch (mode) {
        case UID:
        case UID_EXCLUDE_LOOPBACK:
        case UIDRANGE:
        case UIDRANGE_EXCLUDE_LOOPBACK: {
            uid_t uid = START_UID + i;
            return fchown(s, uid, -1);
        }
        case PERMISSION: {
            Fwmark fwmark;
            fwmark.netId = permissionTestcases[i].netId;
            fwmark.explicitlySelected = permissionTestcases[i].explicitlySelected;
            fwmark.permission = permissionTestcases[i].permission;
            return setsockopt(s, SOL_SOCKET, SO_MARK, &fwmark.intValue, sizeof(fwmark.intValue));
        }
        default:
            return 0;
        }
    }

    int destroySockets() {
        MicroBenchmarkTestType mode = GetParam();
        int ret;
        switch (mode) {
            case ADDRESS:
                ret = mSd.destroySockets("::1", 0 /* ifindex */);
                EXPECT_LE(0, ret) << ": Failed to destroy sockets on ::1: " << strerror(-ret);
                break;
            case UID:
            case UID_EXCLUDE_LOOPBACK: {
                bool excludeLoopback = (mode == UID_EXCLUDE_LOOPBACK);
                ret = mSd.destroySockets(IPPROTO_TCP, CLOSE_UID, excludeLoopback);
                EXPECT_LE(0, ret) << ": Failed to destroy sockets for UID " << CLOSE_UID << ": " <<
                        strerror(-ret);
                break;
            }
            case UIDRANGE:
            case UIDRANGE_EXCLUDE_LOOPBACK: {
                bool excludeLoopback = (mode == UIDRANGE_EXCLUDE_LOOPBACK);
                const char *uidRangeStrings[] = { "8005-8012", "8042", "8043", "8090-8099" };
                std::set<uid_t> skipUids { 8007, 8043, 8098, 8099 };
                UidRanges uidRanges;
                uidRanges.parseFrom(ARRAY_SIZE(uidRangeStrings), (char **) uidRangeStrings);
                ret = mSd.destroySockets(uidRanges, skipUids, excludeLoopback);
                break;
            }
            case PERMISSION: {
                ret = mSd.destroySocketsLackingPermission(TEST_NETID, PERMISSION_NETWORK, false);
                break;
            }
        }
        return ret;
    }

    bool shouldHaveClosedSocket(int i) {
        MicroBenchmarkTestType mode = GetParam();
        switch (mode) {
            case ADDRESS:
                return true;
            case UID:
                return i == CLOSE_UID - START_UID;
            case UIDRANGE: {
                uid_t uid = i + START_UID;
                // Skip UIDs in skipUids.
                if (uid == 8007 || uid == 8043 || uid == 8098 || uid == 8099) {
                    return false;
                }
                // Include UIDs in uidRanges.
                if ((8005 <= uid && uid <= 8012) || uid == 8042 || (8090 <= uid && uid <= 8099)) {
                    return true;
                }
                return false;
            }
            case UID_EXCLUDE_LOOPBACK:
            case UIDRANGE_EXCLUDE_LOOPBACK:
                return false;
            case PERMISSION:
                if (permissionTestcases[i].netId != 42) return false;
                if (permissionTestcases[i].explicitlySelected != 1) return true;
                Permission permission = permissionTestcases[i].permission;
                return permission != PERMISSION_NETWORK && permission != PERMISSION_SYSTEM;
        }
    }

    bool checkSocketState(int i, int sock, const char *msg) {
        const char data[] = "foo";
        const int ret = send(sock, data, sizeof(data), 0);
        const int err = errno;
        if (!shouldHaveClosedSocket(i)) {
            EXPECT_EQ((ssize_t) sizeof(data), ret) <<
                    "Write on open socket failed: " << strerror(err);
            return false;
        }

        EXPECT_EQ(-1, ret) << msg << " " << i << " not closed";
        if (ret != -1) {
            return false;
        }

        // Since we're connected to ourselves, the error might be ECONNABORTED (if we destroyed the
        // socket) or ECONNRESET (if the other end was destroyed and sent a RST).
        EXPECT_TRUE(err == ECONNABORTED || err == ECONNRESET)
            << msg << ": unexpected error: " << strerror(err);
        return (err == ECONNABORTED);  // Return true iff. SOCK_DESTROY closed this socket.
    }
};

TEST_P(SockDiagMicroBenchmarkTest, TestMicroBenchmark) {
    MicroBenchmarkTestType mode = GetParam();

    int numSockets = howManySockets();

    fprintf(stderr, "Benchmarking closing %d sockets based on %s\n",
            numSockets, testTypeName(mode));

    int listensocket = socket(AF_INET6, SOCK_STREAM | SOCK_CLOEXEC, 0);
    ASSERT_NE(-1, listensocket) << "Failed to open listen socket";

    uint16_t port = bindAndListen(listensocket);
    ASSERT_NE(0, port) << "Can't bind to server port";
    sockaddr_in6 server = { .sin6_family = AF_INET6, .sin6_port = htons(port) };

    using ms = std::chrono::duration<float, std::ratio<1, 1000>>;

    int clientsockets[MAX_SOCKETS], serversockets[MAX_SOCKETS];
    uint16_t clientports[MAX_SOCKETS];
    sockaddr_in6 client;
    socklen_t clientlen;

    auto start = std::chrono::steady_clock::now();
    for (int i = 0; i < numSockets; i++) {
        int s = socket(AF_INET6, SOCK_STREAM | SOCK_CLOEXEC, 0);
        clientlen = sizeof(client);
        ASSERT_EQ(0, connect(s, (sockaddr *) &server, sizeof(server)))
            << "Connecting socket " << i << " failed " << strerror(errno);
        ASSERT_EQ(0, modifySocketForTest(s, i));
        serversockets[i] = accept4(
                listensocket, (sockaddr *) &client, &clientlen, SOCK_CLOEXEC);
        ASSERT_NE(-1, serversockets[i])
            << "Accepting socket " << i << " failed " << strerror(errno);
        clientports[i] = client.sin6_port;
        clientsockets[i] = s;
    }
    fprintf(stderr, "  Connecting: %6.1f ms\n",
            std::chrono::duration_cast<ms>(std::chrono::steady_clock::now() - start).count());

    start = std::chrono::steady_clock::now();
    destroySockets();
    fprintf(stderr, "  Destroying: %6.1f ms\n",
            std::chrono::duration_cast<ms>(std::chrono::steady_clock::now() - start).count());

    start = std::chrono::steady_clock::now();
    int socketsClosed = 0;
    for (int i = 0; i < numSockets; i++) {
        socketsClosed += checkSocketState(i, clientsockets[i], "Client socket");
        socketsClosed += checkSocketState(i, serversockets[i], "Server socket");
    }
    fprintf(stderr, "   Verifying: %6.1f ms (%d sockets destroyed)\n",
            std::chrono::duration_cast<ms>(std::chrono::steady_clock::now() - start).count(),
            socketsClosed);
    if (strstr(testTypeName(mode), "_EXCLUDE_LOOPBACK") == nullptr) {
        EXPECT_GT(socketsClosed, 0);  // Just in case there's a bug in the test.
    }

    start = std::chrono::steady_clock::now();
    for (int i = 0; i < numSockets; i++) {
        close(clientsockets[i]);
        close(serversockets[i]);
    }
    fprintf(stderr, "     Closing: %6.1f ms\n",
            std::chrono::duration_cast<ms>(std::chrono::steady_clock::now() - start).count());

    close(listensocket);
}

// "SockDiagTest.cpp:232: error: undefined reference to 'SockDiagMicroBenchmarkTest::CLOSE_UID'".
constexpr int SockDiagMicroBenchmarkTest::CLOSE_UID;

INSTANTIATE_TEST_CASE_P(Address, SockDiagMicroBenchmarkTest,
                        testing::Values(ADDRESS, UID, UIDRANGE,
                                        UID_EXCLUDE_LOOPBACK, UIDRANGE_EXCLUDE_LOOPBACK,
                                        PERMISSION));

}  // namespace net
}  // namespace android
