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

Commit dfc2d87c authored by Cody Schuffelen's avatar Cody Schuffelen Committed by android-build-merger
Browse files

Merge "Combine tcp_connect and socket_spec_connect." am: 539c4d42

am: 6d05846a

Change-Id: I6339087d16b4f579e00fe608c5562702b0375c92
parents 18589dbb 6d05846a
Loading
Loading
Loading
Loading
+12 −14
Original line number Original line Diff line number Diff line
@@ -144,53 +144,51 @@ static int _adb_connect(const std::string& service, std::string* error) {
    }
    }


    std::string reason;
    std::string reason;
    int fd = socket_spec_connect(__adb_server_socket_spec, &reason);
    unique_fd fd;
    if (fd < 0) {
    if (!socket_spec_connect(&fd, __adb_server_socket_spec, nullptr, nullptr, &reason)) {
        *error = android::base::StringPrintf("cannot connect to daemon at %s: %s",
        *error = android::base::StringPrintf("cannot connect to daemon at %s: %s",
                                             __adb_server_socket_spec, reason.c_str());
                                             __adb_server_socket_spec, reason.c_str());
        return -2;
        return -2;
    }
    }


    if (memcmp(&service[0], "host", 4) != 0 && switch_socket_transport(fd, error)) {
    if (memcmp(&service[0], "host", 4) != 0 && switch_socket_transport(fd.get(), error)) {
        return -1;
        return -1;
    }
    }


    if (!SendProtocolString(fd, service)) {
    if (!SendProtocolString(fd.get(), service)) {
        *error = perror_str("write failure during connection");
        *error = perror_str("write failure during connection");
        adb_close(fd);
        return -1;
        return -1;
    }
    }


    if (!adb_status(fd, error)) {
    if (!adb_status(fd.get(), error)) {
        adb_close(fd);
        return -1;
        return -1;
    }
    }


    D("_adb_connect: return fd %d", fd);
    D("_adb_connect: return fd %d", fd.get());
    return fd;
    return fd.release();
}
}


bool adb_kill_server() {
bool adb_kill_server() {
    D("adb_kill_server");
    D("adb_kill_server");
    std::string reason;
    std::string reason;
    int fd = socket_spec_connect(__adb_server_socket_spec, &reason);
    unique_fd fd;
    if (fd < 0) {
    if (!socket_spec_connect(&fd, __adb_server_socket_spec, nullptr, nullptr, &reason)) {
        fprintf(stderr, "cannot connect to daemon at %s: %s\n", __adb_server_socket_spec,
        fprintf(stderr, "cannot connect to daemon at %s: %s\n", __adb_server_socket_spec,
                reason.c_str());
                reason.c_str());
        return true;
        return true;
    }
    }


    if (!SendProtocolString(fd, "host:kill")) {
    if (!SendProtocolString(fd.get(), "host:kill")) {
        fprintf(stderr, "error: write failure during connection: %s\n", strerror(errno));
        fprintf(stderr, "error: write failure during connection: %s\n", strerror(errno));
        return false;
        return false;
    }
    }


    // The server might send OKAY, so consume that.
    // The server might send OKAY, so consume that.
    char buf[4];
    char buf[4];
    ReadFdExactly(fd, buf, 4);
    ReadFdExactly(fd.get(), buf, 4);
    // Now that no more data is expected, wait for socket orderly shutdown or error, indicating
    // Now that no more data is expected, wait for socket orderly shutdown or error, indicating
    // server death.
    // server death.
    ReadOrderlyShutdown(fd);
    ReadOrderlyShutdown(fd.get());
    return true;
    return true;
}
}


+4 −5
Original line number Original line Diff line number Diff line
@@ -72,24 +72,23 @@ unique_fd create_service_thread(const char* service_name, std::function<void(uni
}
}


int service_to_fd(std::string_view name, atransport* transport) {
int service_to_fd(std::string_view name, atransport* transport) {
    int ret = -1;
    unique_fd ret;


    if (is_socket_spec(name)) {
    if (is_socket_spec(name)) {
        std::string error;
        std::string error;
        ret = socket_spec_connect(name, &error);
        if (!socket_spec_connect(&ret, name, nullptr, nullptr, &error)) {
        if (ret < 0) {
            LOG(ERROR) << "failed to connect to socket '" << name << "': " << error;
            LOG(ERROR) << "failed to connect to socket '" << name << "': " << error;
        }
        }
    } else {
    } else {
#if !ADB_HOST
#if !ADB_HOST
        ret = daemon_service_to_fd(name, transport).release();
        ret = daemon_service_to_fd(name, transport);
#endif
#endif
    }
    }


    if (ret >= 0) {
    if (ret >= 0) {
        close_on_exec(ret);
        close_on_exec(ret);
    }
    }
    return ret;
    return ret.release();
}
}


#if ADB_HOST
#if ADB_HOST
+27 −22
Original line number Original line Diff line number Diff line
@@ -67,7 +67,7 @@ static auto& kLocalSocketTypes = *new std::unordered_map<std::string, LocalSocke
});
});


bool parse_tcp_socket_spec(std::string_view spec, std::string* hostname, int* port,
bool parse_tcp_socket_spec(std::string_view spec, std::string* hostname, int* port,
                           std::string* error) {
                           std::string* serial, std::string* error) {
    if (!spec.starts_with("tcp:")) {
    if (!spec.starts_with("tcp:")) {
        *error = "specification is not tcp: ";
        *error = "specification is not tcp: ";
        *error += spec;
        *error += spec;
@@ -92,7 +92,7 @@ bool parse_tcp_socket_spec(std::string_view spec, std::string* hostname, int* po


        // FIXME: ParseNetAddress rejects port 0. This currently doesn't hurt, because listening
        // FIXME: ParseNetAddress rejects port 0. This currently doesn't hurt, because listening
        //        on an address that isn't 'localhost' is unsupported.
        //        on an address that isn't 'localhost' is unsupported.
        if (!android::base::ParseNetAddress(addr, &hostname_value, &port_value, nullptr, error)) {
        if (!android::base::ParseNetAddress(addr, &hostname_value, &port_value, serial, error)) {
            return false;
            return false;
        }
        }


@@ -139,63 +139,68 @@ bool is_local_socket_spec(std::string_view spec) {


    std::string error;
    std::string error;
    std::string hostname;
    std::string hostname;
    if (!parse_tcp_socket_spec(spec, &hostname, nullptr, &error)) {
    if (!parse_tcp_socket_spec(spec, &hostname, nullptr, nullptr, &error)) {
        return false;
        return false;
    }
    }
    return tcp_host_is_local(hostname);
    return tcp_host_is_local(hostname);
}
}


int socket_spec_connect(std::string_view spec, std::string* error) {
bool socket_spec_connect(unique_fd* fd, std::string_view address, int* port, std::string* serial,
    if (spec.starts_with("tcp:")) {
                         std::string* error) {
    if (address.starts_with("tcp:")) {
        std::string hostname;
        std::string hostname;
        int port;
        int port_value = port ? *port : 0;
        if (!parse_tcp_socket_spec(spec, &hostname, &port, error)) {
        if (!parse_tcp_socket_spec(address, &hostname, &port_value, serial, error)) {
            return -1;
            return false;
        }
        }


        int result;
        if (tcp_host_is_local(hostname)) {
        if (tcp_host_is_local(hostname)) {
            result = network_loopback_client(port, SOCK_STREAM, error);
            fd->reset(network_loopback_client(port_value, SOCK_STREAM, error));
        } else {
        } else {
#if ADB_HOST
#if ADB_HOST
            result = network_connect(hostname, port, SOCK_STREAM, 0, error);
            fd->reset(network_connect(hostname, port_value, SOCK_STREAM, 0, error));
#else
#else
            // Disallow arbitrary connections in adbd.
            // Disallow arbitrary connections in adbd.
            *error = "adbd does not support arbitrary tcp connections";
            *error = "adbd does not support arbitrary tcp connections";
            return -1;
            return false;
#endif
#endif
        }
        }


        if (result >= 0) {
        if (fd->get() > 0) {
            disable_tcp_nagle(result);
            disable_tcp_nagle(fd->get());
            if (port) {
                *port = port_value;
            }
            }
        return result;
            return true;
        }
        return false;
    }
    }


    for (const auto& it : kLocalSocketTypes) {
    for (const auto& it : kLocalSocketTypes) {
        std::string prefix = it.first + ":";
        std::string prefix = it.first + ":";
        if (spec.starts_with(prefix)) {
        if (address.starts_with(prefix)) {
            if (!it.second.available) {
            if (!it.second.available) {
                *error = StringPrintf("socket type %s is unavailable on this platform",
                *error = StringPrintf("socket type %s is unavailable on this platform",
                                      it.first.c_str());
                                      it.first.c_str());
                return -1;
                return false;
            }
            }


            return network_local_client(&spec[prefix.length()], it.second.socket_namespace,
            fd->reset(network_local_client(&address[prefix.length()], it.second.socket_namespace,
                                        SOCK_STREAM, error);
                                           SOCK_STREAM, error));
            return true;
        }
        }
    }
    }


    *error = "unknown socket specification: ";
    *error = "unknown socket specification: ";
    *error += spec;
    *error += address;
    return -1;
    return false;
}
}


int socket_spec_listen(std::string_view spec, std::string* error, int* resolved_tcp_port) {
int socket_spec_listen(std::string_view spec, std::string* error, int* resolved_tcp_port) {
    if (spec.starts_with("tcp:")) {
    if (spec.starts_with("tcp:")) {
        std::string hostname;
        std::string hostname;
        int port;
        int port;
        if (!parse_tcp_socket_spec(spec, &hostname, &port, error)) {
        if (!parse_tcp_socket_spec(spec, &hostname, &port, nullptr, error)) {
            return -1;
            return -1;
        }
        }


+6 −2
Original line number Original line Diff line number Diff line
@@ -17,14 +17,18 @@
#pragma once
#pragma once


#include <string>
#include <string>
#include <tuple>

#include "adb_unique_fd.h"


// Returns true if the argument starts with a plausible socket prefix.
// Returns true if the argument starts with a plausible socket prefix.
bool is_socket_spec(std::string_view spec);
bool is_socket_spec(std::string_view spec);
bool is_local_socket_spec(std::string_view spec);
bool is_local_socket_spec(std::string_view spec);


int socket_spec_connect(std::string_view spec, std::string* error);
bool socket_spec_connect(unique_fd* fd, std::string_view address, int* port, std::string* serial,
                         std::string* error);
int socket_spec_listen(std::string_view spec, std::string* error, int* resolved_tcp_port = nullptr);
int socket_spec_listen(std::string_view spec, std::string* error, int* resolved_tcp_port = nullptr);


// Exposed for testing.
// Exposed for testing.
bool parse_tcp_socket_spec(std::string_view spec, std::string* hostname, int* port,
bool parse_tcp_socket_spec(std::string_view spec, std::string* hostname, int* port,
                           std::string* error);
                           std::string* serial, std::string* error);
+19 −16
Original line number Original line Diff line number Diff line
@@ -21,34 +21,37 @@
#include <gtest/gtest.h>
#include <gtest/gtest.h>


TEST(socket_spec, parse_tcp_socket_spec) {
TEST(socket_spec, parse_tcp_socket_spec) {
    std::string hostname, error;
    std::string hostname, error, serial;
    int port;
    int port;
    EXPECT_TRUE(parse_tcp_socket_spec("tcp:5037", &hostname, &port, &error));
    EXPECT_TRUE(parse_tcp_socket_spec("tcp:5037", &hostname, &port, &serial, &error));
    EXPECT_EQ("", hostname);
    EXPECT_EQ("", hostname);
    EXPECT_EQ(5037, port);
    EXPECT_EQ(5037, port);
    EXPECT_EQ("", serial);


    // Bad ports:
    // Bad ports:
    EXPECT_FALSE(parse_tcp_socket_spec("tcp:", &hostname, &port, &error));
    EXPECT_FALSE(parse_tcp_socket_spec("tcp:", &hostname, &port, &serial, &error));
    EXPECT_FALSE(parse_tcp_socket_spec("tcp:-1", &hostname, &port, &error));
    EXPECT_FALSE(parse_tcp_socket_spec("tcp:-1", &hostname, &port, &serial, &error));
    EXPECT_FALSE(parse_tcp_socket_spec("tcp:65536", &hostname, &port, &error));
    EXPECT_FALSE(parse_tcp_socket_spec("tcp:65536", &hostname, &port, &serial, &error));


    EXPECT_TRUE(parse_tcp_socket_spec("tcp:localhost:1234", &hostname, &port, &error));
    EXPECT_TRUE(parse_tcp_socket_spec("tcp:localhost:1234", &hostname, &port, &serial, &error));
    EXPECT_EQ("localhost", hostname);
    EXPECT_EQ("localhost", hostname);
    EXPECT_EQ(1234, port);
    EXPECT_EQ(1234, port);
    EXPECT_EQ("localhost:1234", serial);


    EXPECT_FALSE(parse_tcp_socket_spec("tcp:localhost", &hostname, &port, &error));
    EXPECT_FALSE(parse_tcp_socket_spec("tcp:localhost", &hostname, &port, &serial, &error));
    EXPECT_FALSE(parse_tcp_socket_spec("tcp:localhost:", &hostname, &port, &error));
    EXPECT_FALSE(parse_tcp_socket_spec("tcp:localhost:", &hostname, &port, &serial, &error));
    EXPECT_FALSE(parse_tcp_socket_spec("tcp:localhost:-1", &hostname, &port, &error));
    EXPECT_FALSE(parse_tcp_socket_spec("tcp:localhost:-1", &hostname, &port, &serial, &error));
    EXPECT_FALSE(parse_tcp_socket_spec("tcp:localhost:65536", &hostname, &port, &error));
    EXPECT_FALSE(parse_tcp_socket_spec("tcp:localhost:65536", &hostname, &port, &serial, &error));


    // IPv6:
    // IPv6:
    EXPECT_TRUE(parse_tcp_socket_spec("tcp:[::1]:1234", &hostname, &port, &error));
    EXPECT_TRUE(parse_tcp_socket_spec("tcp:[::1]:1234", &hostname, &port, &serial, &error));
    EXPECT_EQ("::1", hostname);
    EXPECT_EQ("::1", hostname);
    EXPECT_EQ(1234, port);
    EXPECT_EQ(1234, port);
    EXPECT_EQ("[::1]:1234", serial);


    EXPECT_FALSE(parse_tcp_socket_spec("tcp:[::1]", &hostname, &port, &error));
    EXPECT_FALSE(parse_tcp_socket_spec("tcp:[::1]", &hostname, &port, &serial, &error));
    EXPECT_FALSE(parse_tcp_socket_spec("tcp:[::1]:", &hostname, &port, &error));
    EXPECT_FALSE(parse_tcp_socket_spec("tcp:[::1]:", &hostname, &port, &serial, &error));
    EXPECT_FALSE(parse_tcp_socket_spec("tcp:[::1]:-1", &hostname, &port, &error));
    EXPECT_FALSE(parse_tcp_socket_spec("tcp:[::1]:-1", &hostname, &port, &serial, &error));
    EXPECT_FALSE(parse_tcp_socket_spec("tcp:::1", &hostname, &port, &error));
    EXPECT_FALSE(parse_tcp_socket_spec("tcp:::1", &hostname, &port, &serial, &error));
    EXPECT_FALSE(parse_tcp_socket_spec("tcp:::1:1234", &hostname, &port, &error));
    EXPECT_FALSE(parse_tcp_socket_spec("tcp:::1:1234", &hostname, &port, &serial, &error));
}
}
Loading