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

Commit 7a568dbd authored by David Pursell's avatar David Pursell Committed by android-build-merger
Browse files

Merge "libcutils: share Windows networking code."

am: 1906de1e

* commit '1906de1e':
  libcutils: share Windows networking code.
parents 0c422cb3 1906de1e
Loading
Loading
Loading
Loading
+4 −5
Original line number Diff line number Diff line
@@ -34,10 +34,10 @@ LOCAL_CFLAGS += -Wall -Wextra -Werror -Wunreachable-code
LOCAL_CFLAGS += -DFASTBOOT_REVISION='"$(fastboot_version)"'

LOCAL_SRC_FILES_linux := socket_unix.cpp usb_linux.cpp util_linux.cpp
LOCAL_STATIC_LIBRARIES_linux := libcutils libselinux
LOCAL_STATIC_LIBRARIES_linux := libselinux

LOCAL_SRC_FILES_darwin := socket_unix.cpp usb_osx.cpp util_osx.cpp
LOCAL_STATIC_LIBRARIES_darwin := libcutils libselinux
LOCAL_STATIC_LIBRARIES_darwin := libselinux
LOCAL_LDLIBS_darwin := -lpthread -framework CoreFoundation -framework IOKit -framework Carbon
LOCAL_CFLAGS_darwin := -Wno-unused-parameter

@@ -56,6 +56,7 @@ LOCAL_STATIC_LIBRARIES := \
    libz \
    libdiagnose_usb \
    libbase \
    libcutils \

# libf2fs_dlutils_host will dlopen("libf2fs_fmt_host_dyn")
LOCAL_CFLAGS_linux := -DUSE_F2FS
@@ -98,17 +99,15 @@ LOCAL_MODULE := fastboot_test
LOCAL_MODULE_HOST_OS := darwin linux windows

LOCAL_SRC_FILES := socket_test.cpp
LOCAL_STATIC_LIBRARIES := libbase
LOCAL_STATIC_LIBRARIES := libbase libcutils

LOCAL_CFLAGS += -Wall -Wextra -Werror -Wunreachable-code

LOCAL_SRC_FILES_linux := socket_unix.cpp
LOCAL_STATIC_LIBRARIES_linux := libcutils

LOCAL_SRC_FILES_darwin := socket_unix.cpp
LOCAL_LDLIBS_darwin := -lpthread -framework CoreFoundation -framework IOKit -framework Carbon
LOCAL_CFLAGS_darwin := -Wno-unused-parameter
LOCAL_STATIC_LIBRARIES_darwin := libcutils

LOCAL_SRC_FILES_windows := socket_windows.cpp
LOCAL_LDLIBS_windows := -lws2_32
+2 −114
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@
#include <memory>

#include <android-base/stringprintf.h>
#include <cutils/sockets.h>

// Windows UDP socket functionality.
class WindowsUdpSocket : public UdpSocket {
@@ -108,118 +109,9 @@ int WindowsUdpSocket::Close() {
    return result;
}

static int GetProtocol(int sock_type) {
    switch (sock_type) {
        case SOCK_DGRAM:
            return IPPROTO_UDP;
        case SOCK_STREAM:
            return IPPROTO_TCP;
        default:
            // 0 lets the system decide which protocol to use.
            return 0;
    }
}

// Windows implementation of this libcutils function. This function does not make any calls to
// WSAStartup() or WSACleanup() so that must be handled by the caller.
// TODO(dpursell): share this code with adb.
static SOCKET socket_network_client(const std::string& host, int port, int type) {
    // First resolve the host and port parameters into a usable network address.
    addrinfo hints;
    memset(&hints, 0, sizeof(hints));
    hints.ai_socktype = type;
    hints.ai_protocol = GetProtocol(type);

    addrinfo* address = nullptr;
    getaddrinfo(host.c_str(), android::base::StringPrintf("%d", port).c_str(), &hints, &address);
    if (address == nullptr) {
        return INVALID_SOCKET;
    }

    // Now create and connect the socket.
    SOCKET sock = socket(address->ai_family, address->ai_socktype, address->ai_protocol);
    if (sock == INVALID_SOCKET) {
        freeaddrinfo(address);
        return INVALID_SOCKET;
    }

    if (connect(sock, address->ai_addr, address->ai_addrlen) == SOCKET_ERROR) {
        closesocket(sock);
        freeaddrinfo(address);
        return INVALID_SOCKET;
    }

    freeaddrinfo(address);
    return sock;
}

// Windows implementation of this libcutils function. This implementation creates a dual-stack
// server socket that can accept incoming IPv4 or IPv6 packets. This function does not make any
// calls to WSAStartup() or WSACleanup() so that must be handled by the caller.
// TODO(dpursell): share this code with adb.
static SOCKET socket_inaddr_any_server(int port, int type) {
    SOCKET sock = socket(AF_INET6, type, GetProtocol(type));
    if (sock == INVALID_SOCKET) {
        return INVALID_SOCKET;
    }

    // Enforce exclusive addresses (1), and enable dual-stack so both IPv4 and IPv6 work (2).
    // (1) https://msdn.microsoft.com/en-us/library/windows/desktop/ms740621(v=vs.85).aspx.
    // (2) https://msdn.microsoft.com/en-us/library/windows/desktop/bb513665(v=vs.85).aspx.
    int exclusive = 1;
    DWORD v6_only = 0;
    if (setsockopt(sock, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, reinterpret_cast<const char*>(&exclusive),
                   sizeof(exclusive)) == SOCKET_ERROR ||
        setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast<const char*>(&v6_only),
                   sizeof(v6_only)) == SOCKET_ERROR) {
        closesocket(sock);
        return INVALID_SOCKET;
    }

    // Bind the socket to our local port.
    sockaddr_in6 addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin6_family = AF_INET6;
    addr.sin6_port = htons(port);
    addr.sin6_addr = in6addr_any;
    if (bind(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == SOCKET_ERROR) {
        closesocket(sock);
        return INVALID_SOCKET;
    }

    return sock;
}

// Documentation at https://msdn.microsoft.com/en-us/library/windows/desktop/ms741549(v=vs.85).aspx
// claims WSACleanup() should be called before program exit, but general consensus seems to be that
// it hasn't actually been necessary for a long time, possibly since Windows 3.1.
//
// Both adb (1) and Chrome (2) purposefully avoid WSACleanup(), and since no adverse affects have
// been found we may as well do the same here to keep this code simpler.
// (1) https://android.googlesource.com/platform/system/core.git/+/master/adb/sysdeps_win32.cpp#816
// (2) https://code.google.com/p/chromium/codesearch#chromium/src/net/base/winsock_init.cc&l=35
static bool InitWinsock() {
    static bool init_success = false;

    if (!init_success) {
        WSADATA wsaData;
        init_success = (WSAStartup(MAKEWORD(2, 2), &wsaData) == 0);
    }

    return init_success;
}

std::unique_ptr<UdpSocket> UdpSocket::NewUdpClient(const std::string& host, int port,
                                                   std::string* error) {
    if (!InitWinsock()) {
        if (error) {
            *error = android::base::StringPrintf("Failed to initialize Winsock (error %d)",
                                                 WSAGetLastError());
        }
        return nullptr;
    }

    SOCKET sock = socket_network_client(host, port, SOCK_DGRAM);
    SOCKET sock = socket_network_client(host.c_str(), port, SOCK_DGRAM);
    if (sock == INVALID_SOCKET) {
        if (error) {
            *error = android::base::StringPrintf("Failed to connect to %s:%d (error %d)",
@@ -233,10 +125,6 @@ std::unique_ptr<UdpSocket> UdpSocket::NewUdpClient(const std::string& host, int

// This functionality is currently only used by tests so we don't need any error messages.
std::unique_ptr<UdpSocket> UdpSocket::NewUdpServer(int port) {
    if (!InitWinsock()) {
        return nullptr;
    }

    SOCKET sock = socket_inaddr_any_server(port, SOCK_DGRAM);
    if (sock == INVALID_SOCKET) {
        return nullptr;
+50 −13
Original line number Diff line number Diff line
@@ -24,10 +24,20 @@
#include <stdbool.h>

#if defined(_WIN32)

#include <winsock2.h>
#include <ws2tcpip.h>

typedef int  socklen_t;
typedef SOCKET cutils_socket_t;

#else

#include <sys/socket.h>

typedef int cutils_socket_t;
#define INVALID_SOCKET (-1)

#endif

#define ANDROID_SOCKET_ENV_PREFIX	"ANDROID_SOCKET_"
@@ -74,17 +84,44 @@ static inline int android_get_control_socket(const char *name)
// Normal filesystem namespace
#define ANDROID_SOCKET_NAMESPACE_FILESYSTEM 2

extern int socket_loopback_client(int port, int type);
extern int socket_network_client(const char *host, int port, int type);
extern int socket_network_client_timeout(const char *host, int port, int type,
/*
 * Functions to create sockets for some common usages.
 *
 * All these functions are implemented for Unix, but only a few are implemented
 * for Windows. Those which are can be identified by the cutils_socket_t
 * return type. The idea is to be able to use this return value with the
 * standard Unix socket functions on any platform.
 *
 * On Unix the returned cutils_socket_t is a standard int file descriptor and
 * can always be used as normal with all file descriptor functions.
 *
 * On Windows utils_socket_t is an unsigned int pointer, and is only valid
 * with functions that specifically take a socket, e.g. send(), sendto(),
 * recv(), and recvfrom(). General file descriptor functions such as read(),
 * write(), and close() will not work with utils_socket_t and will require
 * special handling.
 *
 * These functions return INVALID_SOCKET (-1) on failure for all platforms.
 */
int socket_loopback_client(int port, int type);
cutils_socket_t socket_network_client(const char* host, int port, int type);
int socket_network_client_timeout(const char* host, int port, int type,
                                  int timeout, int* getaddrinfo_error);
extern int socket_loopback_server(int port, int type);
extern int socket_local_server(const char *name, int namespaceId, int type);
extern int socket_local_server_bind(int s, const char *name, int namespaceId);
extern int socket_local_client_connect(int fd, 
        const char *name, int namespaceId, int type);
extern int socket_local_client(const char *name, int namespaceId, int type);
extern int socket_inaddr_any_server(int port, int type);
int socket_loopback_server(int port, int type);
int socket_local_server(const char* name, int namespaceId, int type);
int socket_local_server_bind(int s, const char* name, int namespaceId);
int socket_local_client_connect(int fd, const char *name, int namespaceId,
                                int type);
int socket_local_client(const char* name, int namespaceId, int type);
cutils_socket_t socket_inaddr_any_server(int port, int type);

/*
 * Closes a cutils_socket_t. Windows doesn't allow calling close() on a socket
 * so this is a cross-platform way to close a cutils_socket_t.
 *
 * Returns 0 on success.
 */
int socket_close(cutils_socket_t sock);

/*
 * socket_peer_is_trusted - Takes a socket which is presumed to be a
+15 −8
Original line number Diff line number Diff line
@@ -39,26 +39,33 @@ libcutils_common_sources := \
libcutils_nonwindows_sources := \
        fs.c \
        multiuser.c \
        socket_inaddr_any_server.c \
        socket_local_client.c \
        socket_local_server.c \
        socket_loopback_client.c \
        socket_loopback_server.c \
        socket_network_client.c \
        sockets.c \
        socket_inaddr_any_server_unix.c \
        socket_local_client_unix.c \
        socket_local_server_unix.c \
        socket_loopback_client_unix.c \
        socket_loopback_server_unix.c \
        socket_network_client_unix.c \
        sockets_unix.c \
        str_parms.c \

libcutils_nonwindows_host_sources := \
        ashmem-host.c \
        trace-host.c
        trace-host.c \

libcutils_windows_host_sources := \
        socket_inaddr_any_server_windows.c \
        socket_network_client_windows.c \
        sockets_windows.c \

# Shared and static library for host
# Note: when linking this library on Windows, you must also link to Winsock2
# using "LOCAL_LDLIBS_windows := -lws2_32".
# ========================================================
LOCAL_MODULE := libcutils
LOCAL_SRC_FILES := $(libcutils_common_sources) dlmalloc_stubs.c
LOCAL_SRC_FILES_darwin := $(libcutils_nonwindows_sources) $(libcutils_nonwindows_host_sources)
LOCAL_SRC_FILES_linux := $(libcutils_nonwindows_sources) $(libcutils_nonwindows_host_sources)
LOCAL_SRC_FILES_windows := $(libcutils_windows_host_sources)
LOCAL_STATIC_LIBRARIES := liblog
LOCAL_CFLAGS := -Werror -Wall -Wextra
LOCAL_MULTILIB := both
+0 −2
Original line number Diff line number Diff line
@@ -20,12 +20,10 @@
#include <string.h>
#include <unistd.h>

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

#include <cutils/sockets.h>

Loading