// This test checks if we can close sockets in CLOSE_WAIT state.
TEST_F(LocalSocketTest, close_socket_in_CLOSE_WAIT_state) {
    std::string error;
    int listen_fd = network_inaddr_any_server(5038, SOCK_STREAM, &error);
    ASSERT_GE(listen_fd, 0);

    adb_thread_t client_thread;
    ASSERT_TRUE(adb_thread_create(reinterpret_cast<void (*)(void*)>(ClientThreadFunc), nullptr,
                                  &client_thread));

    struct sockaddr addr;
    socklen_t alen;
    alen = sizeof(addr);
    int accept_fd = adb_socket_accept(listen_fd, &addr, &alen);
    ASSERT_GE(accept_fd, 0);
    CloseRdHupSocketArg arg;
    arg.socket_fd = accept_fd;

    PrepareThread();
    adb_thread_t thread;
    ASSERT_TRUE(adb_thread_create(reinterpret_cast<void (*)(void*)>(CloseRdHupSocketThreadFunc),
                                  &arg, &thread));

    // Wait until the fdevent_loop() starts.
    adb_sleep_ms(SLEEP_FOR_FDEVENT_IN_MS);
    EXPECT_EQ(1u + GetAdditionalLocalSocketCount(), fdevent_installed_count());

    // Wait until the client closes its socket.
    ASSERT_TRUE(adb_thread_join(client_thread));

    adb_sleep_ms(SLEEP_FOR_FDEVENT_IN_MS);
    ASSERT_EQ(GetAdditionalLocalSocketCount(), fdevent_installed_count());
    TerminateThread(thread);
}
static void server_socket_thread(void* arg) {
    int serverfd, fd;
    sockaddr_storage ss;
    sockaddr *addrp = reinterpret_cast<sockaddr*>(&ss);
    socklen_t alen;
    int port = (int) (uintptr_t) arg;

    adb_thread_setname("server socket");
    D("transport: server_socket_thread() starting");
    serverfd = -1;
    for(;;) {
        if(serverfd == -1) {
            std::string error;
            serverfd = network_inaddr_any_server(port, SOCK_STREAM, &error);
            if(serverfd < 0) {
                D("server: cannot bind socket yet: %s", error.c_str());
                adb_sleep_ms(1000);
                continue;
            }
            close_on_exec(serverfd);
        }

        alen = sizeof(ss);
        D("server: trying to get new connection from %d", port);
        fd = adb_socket_accept(serverfd, addrp, &alen);
        if(fd >= 0) {
            D("server: new connection on fd %d", fd);
            close_on_exec(fd);
            disable_tcp_nagle(fd);
            register_socket_transport(fd, "host", port, 1);
        }
    }
    D("transport: server_socket_thread() exiting");
}
Example #3
0
static void server_socket_thread(void* arg) {
    int serverfd, fd;
    int port = (int) (uintptr_t) arg;

    adb_thread_setname("server socket");
    D("transport: server_socket_thread() starting");
    serverfd = -1;
    for(;;) {
        if(serverfd == -1) {
            std::string error;
            serverfd = network_inaddr_any_server(port, SOCK_STREAM, &error);
            if(serverfd < 0) {
                D("server: cannot bind socket yet: %s", error.c_str());
                std::this_thread::sleep_for(1s);
                continue;
            }
            close_on_exec(serverfd);
        }

        D("server: trying to get new connection from %d", port);
        fd = adb_socket_accept(serverfd, nullptr, nullptr);
        if(fd >= 0) {
            D("server: new connection on fd %d", fd);
            close_on_exec(fd);
            disable_tcp_nagle(fd);
            std::string serial = android::base::StringPrintf("host-%d", fd);
            if (register_socket_transport(fd, serial.c_str(), port, 1) != 0) {
                adb_close(fd);
            }
        }
    }
    D("transport: server_socket_thread() exiting");
}
int local_name_to_fd(alistener* listener, int* resolved_tcp_port, std::string* error) {
    if (android::base::StartsWith(listener->local_name, "tcp:")) {
        int requested_port = atoi(&listener->local_name[4]);
        int sock = -1;
        if (gListenAll > 0) {
            sock = network_inaddr_any_server(requested_port, SOCK_STREAM, error);
        } else {
            sock = network_loopback_server(requested_port, SOCK_STREAM, error);
        }

        // If the caller requested port 0, update the listener name with the resolved port.
        if (sock >= 0 && requested_port == 0) {
            int local_port = adb_socket_get_local_port(sock);
            if (local_port > 0) {
                listener->local_name = android::base::StringPrintf("tcp:%d", local_port);
                if (resolved_tcp_port != nullptr) {
                    *resolved_tcp_port = local_port;
                }
            }
        }

        return sock;
    }
#if !defined(_WIN32)  // No Unix-domain sockets on Windows.
    // It's nonsensical to support the "reserved" space on the adb host side.
    if (android::base::StartsWith(listener->local_name, "local:")) {
        return network_local_server(&listener->local_name[6], ANDROID_SOCKET_NAMESPACE_ABSTRACT,
                                    SOCK_STREAM, error);
    } else if (android::base::StartsWith(listener->local_name, "localabstract:")) {
        return network_local_server(&listener->local_name[14], ANDROID_SOCKET_NAMESPACE_ABSTRACT,
                                    SOCK_STREAM, error);
    } else if (android::base::StartsWith(listener->local_name, "localfilesystem:")) {
        return network_local_server(&listener->local_name[16], ANDROID_SOCKET_NAMESPACE_FILESYSTEM,
                                    SOCK_STREAM, error);
    }

#endif
    *error = android::base::StringPrintf("unknown local portname '%s'",
                                         listener->local_name.c_str());
    return -1;
}