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

Commit d90adbc4 authored by David Pursell's avatar David Pursell Committed by Gerrit Code Review
Browse files

Merge "libcutils: add socket_get_local_port()."

parents 650f6809 756e1c81
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -131,6 +131,11 @@ int socket_close(cutils_socket_t sock);
 */
int socket_set_receive_timeout(cutils_socket_t sock, int timeout_ms);

/*
 * Returns the local port the socket is bound to or -1 on error.
 */
int socket_get_local_port(cutils_socket_t sock);

/*
 * socket_peer_is_trusted - Takes a socket which is presumed to be a
 * connected local socket (e.g. AF_LOCAL) and returns whether the peer
+9 −8
Original line number Diff line number Diff line
@@ -17,21 +17,22 @@ LOCAL_PATH := $(my-dir)
include $(CLEAR_VARS)

libcutils_common_sources := \
        hashmap.c \
        atomic.c.arm \
        native_handle.c \
        config_utils.c \
        fs_config.c \
        hashmap.c \
        iosched_policy.c \
        load_file.c \
        strlcpy.c \
        native_handle.c \
        open_memstream.c \
        process_name.c \
        record_stream.c \
        sched_policy.c \
        sockets.cpp \
        strdup16to8.c \
        strdup8to16.c \
        record_stream.c \
        process_name.c \
        strlcpy.c \
        threads.c \
        sched_policy.c \
        iosched_policy.c \
        fs_config.c

# some files must not be compiled when building against Mingw
# they correspond to features not used by our host development tools

libcutils/sockets.cpp

0 → 100644
+47 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 The Android Open Source Project
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

// This file contains socket implementation that can be shared between
// platforms as long as the correct headers are included.

#include <cutils/sockets.h>

#if !defined(_WIN32)
#include <netinet/in.h>
#endif

int socket_get_local_port(cutils_socket_t sock) {
    sockaddr_storage addr;
    socklen_t addr_size = sizeof(addr);

    if (getsockname(sock, reinterpret_cast<sockaddr*>(&addr), &addr_size) == 0) {
        // sockaddr_in and sockaddr_in6 always overlap the port field.
        return ntohs(reinterpret_cast<sockaddr_in*>(&addr)->sin_port);
    }
    return -1;
}
+45 −30
Original line number Diff line number Diff line
@@ -15,9 +15,8 @@
 */

// Tests socket functionality using loopback connections. Requires IPv4 and
// IPv6 capabilities, and that kTestPort is available for loopback
// communication. These tests also assume that no UDP packets are lost,
// which should be the case for loopback communication, but is not guaranteed.
// IPv6 capabilities. These tests assume that no UDP packets are lost, which
// should be the case for loopback communication, but is not guaranteed.

#include <cutils/sockets.h>

@@ -25,11 +24,6 @@

#include <gtest/gtest.h>

enum {
    // This port must be available for loopback communication.
    kTestPort = 54321
};

// Makes sure the passed sockets are valid, sends data between them, and closes
// them. Any failures are logged with gtest.
//
@@ -87,22 +81,43 @@ void TestReceiveTimeout(cutils_socket_t sock) {
    EXPECT_LE(1.0, difftime(time(nullptr), start_time));
}

// Tests socket_get_local_port().
TEST(SocketsTest, TestGetLocalPort) {
    cutils_socket_t server;

    // Check a bunch of ports so that we can ignore any conflicts in case
    // of ports already being taken, but if a server is able to start up we
    // should always be able to read its port.
    for (int port : {10000, 12345, 15999, 20202, 25000}) {
        for (int type : {SOCK_DGRAM, SOCK_STREAM}) {
            server = socket_inaddr_any_server(port, SOCK_DGRAM);
            if (server != INVALID_SOCKET) {
                EXPECT_EQ(port, socket_get_local_port(server));
            }
            socket_close(server);
        }
    }

    // Check expected failure for an invalid socket.
    EXPECT_EQ(-1, socket_get_local_port(INVALID_SOCKET));
}

// Tests socket_inaddr_any_server() and socket_network_client() for IPv4 UDP.
TEST(SocketsTest, TestIpv4UdpLoopback) {
    cutils_socket_t server = socket_inaddr_any_server(kTestPort, SOCK_DGRAM);
    cutils_socket_t client = socket_network_client("127.0.0.1", kTestPort,
                                                   SOCK_DGRAM);
    cutils_socket_t server = socket_inaddr_any_server(0, SOCK_DGRAM);
    cutils_socket_t client = socket_network_client(
            "127.0.0.1", socket_get_local_port(server), SOCK_DGRAM);

    TestConnectedSockets(server, client, SOCK_DGRAM);
}

// Tests socket_inaddr_any_server() and socket_network_client() for IPv4 TCP.
TEST(SocketsTest, TestIpv4TcpLoopback) {
    cutils_socket_t server = socket_inaddr_any_server(kTestPort, SOCK_STREAM);
    cutils_socket_t server = socket_inaddr_any_server(0, SOCK_STREAM);
    ASSERT_NE(INVALID_SOCKET, server);

    cutils_socket_t client = socket_network_client("127.0.0.1", kTestPort,
                                                   SOCK_STREAM);
    cutils_socket_t client = socket_network_client(
            "127.0.0.1", socket_get_local_port(server), SOCK_STREAM);
    cutils_socket_t handler = accept(server, nullptr, nullptr);
    EXPECT_EQ(0, socket_close(server));

@@ -111,20 +126,20 @@ TEST(SocketsTest, TestIpv4TcpLoopback) {

// Tests socket_inaddr_any_server() and socket_network_client() for IPv6 UDP.
TEST(SocketsTest, TestIpv6UdpLoopback) {
    cutils_socket_t server = socket_inaddr_any_server(kTestPort, SOCK_DGRAM);
    cutils_socket_t client = socket_network_client("::1", kTestPort,
                                                   SOCK_DGRAM);
    cutils_socket_t server = socket_inaddr_any_server(0, SOCK_DGRAM);
    cutils_socket_t client = socket_network_client(
            "::1", socket_get_local_port(server), SOCK_DGRAM);

    TestConnectedSockets(server, client, SOCK_DGRAM);
}

// Tests socket_inaddr_any_server() and socket_network_client() for IPv6 TCP.
TEST(SocketsTest, TestIpv6TcpLoopback) {
    cutils_socket_t server = socket_inaddr_any_server(kTestPort, SOCK_STREAM);
    cutils_socket_t server = socket_inaddr_any_server(0, SOCK_STREAM);
    ASSERT_NE(INVALID_SOCKET, server);

    cutils_socket_t client = socket_network_client("::1", kTestPort,
                                                   SOCK_STREAM);
    cutils_socket_t client = socket_network_client(
            "::1", socket_get_local_port(server), SOCK_STREAM);
    cutils_socket_t handler = accept(server, nullptr, nullptr);
    EXPECT_EQ(0, socket_close(server));

@@ -133,7 +148,7 @@ TEST(SocketsTest, TestIpv6TcpLoopback) {

// Tests setting a receive timeout for UDP sockets.
TEST(SocketsTest, TestUdpReceiveTimeout) {
    cutils_socket_t sock = socket_inaddr_any_server(kTestPort, SOCK_DGRAM);
    cutils_socket_t sock = socket_inaddr_any_server(0, SOCK_DGRAM);
    ASSERT_NE(INVALID_SOCKET, sock);

    TestReceiveTimeout(sock);
@@ -143,11 +158,11 @@ TEST(SocketsTest, TestUdpReceiveTimeout) {

// Tests setting a receive timeout for TCP sockets.
TEST(SocketsTest, TestTcpReceiveTimeout) {
    cutils_socket_t server = socket_inaddr_any_server(kTestPort, SOCK_STREAM);
    cutils_socket_t server = socket_inaddr_any_server(0, SOCK_STREAM);
    ASSERT_NE(INVALID_SOCKET, server);

    cutils_socket_t client = socket_network_client("localhost", kTestPort,
                                                   SOCK_STREAM);
    cutils_socket_t client = socket_network_client(
            "localhost", socket_get_local_port(server), SOCK_STREAM);
    cutils_socket_t handler = accept(server, nullptr, nullptr);
    EXPECT_EQ(0, socket_close(server));