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

Commit 706955ff authored by David Pursell's avatar David Pursell
Browse files

base: add network address parsing function from adb.

This CL moves the network address parsing function from adb to libbase
so that it can be used by fastboot as well as adb.

libbase seemed like the right choice because:
  1. It already has some parsing functions (parseint)
  2. The net address parsing function uses the libbase string
     functions so we have a libbase dependency anyway.

The parsing function has been modified slightly to make the canonical
address optional, and debug logging on success has been removed.

For adb the only functional difference is that parsing a network
address will no longer print the result to the debug log, which seemed
unnecessary.

Bug: http://b/26236380
Change-Id: Ife6df02937225fc66de87884d3572d79c092c522
parent bbedd952
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@

#include <android-base/logging.h>
#include <android-base/macros.h>
#include <android-base/parsenetaddress.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>

@@ -1037,7 +1038,7 @@ int handle_host_request(const char* service, TransportType type,
        std::string host;
        int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
        std::string error;
        if (!parse_host_and_port(address, &serial, &host, &port, &error)) {
        if (!android::base::ParseNetAddress(address, &host, &port, &serial, &error)) {
            return SendFail(reply_fd, android::base::StringPrintf("couldn't parse '%s': %s",
                                                                  address.c_str(), error.c_str()));
        }
+0 −53
Original line number Diff line number Diff line
@@ -208,59 +208,6 @@ std::string dump_hex(const void* data, size_t byte_count) {
    return line;
}

bool parse_host_and_port(const std::string& address,
                         std::string* canonical_address,
                         std::string* host, int* port,
                         std::string* error) {
    host->clear();

    bool ipv6 = true;
    bool saw_port = false;
    size_t colons = std::count(address.begin(), address.end(), ':');
    size_t dots = std::count(address.begin(), address.end(), '.');
    std::string port_str;
    if (address[0] == '[') {
      // [::1]:123
      if (address.rfind("]:") == std::string::npos) {
        *error = android::base::StringPrintf("bad IPv6 address '%s'", address.c_str());
        return false;
      }
      *host = address.substr(1, (address.find("]:") - 1));
      port_str = address.substr(address.rfind("]:") + 2);
      saw_port = true;
    } else if (dots == 0 && colons >= 2 && colons <= 7) {
      // ::1
      *host = address;
    } else if (colons <= 1) {
      // 1.2.3.4 or some.accidental.domain.com
      ipv6 = false;
      std::vector<std::string> pieces = android::base::Split(address, ":");
      *host = pieces[0];
      if (pieces.size() > 1) {
        port_str = pieces[1];
        saw_port = true;
      }
    }

    if (host->empty()) {
      *error = android::base::StringPrintf("no host in '%s'", address.c_str());
      return false;
    }

    if (saw_port) {
      if (sscanf(port_str.c_str(), "%d", port) != 1 || *port <= 0 || *port > 65535) {
        *error = android::base::StringPrintf("bad port number '%s' in '%s'",
                                             port_str.c_str(), address.c_str());
        return false;
      }
    }

    *canonical_address = android::base::StringPrintf(ipv6 ? "[%s]:%d" : "%s:%d", host->c_str(), *port);
    LOG(DEBUG) << "parsed " << address << " as " << *host << " and " << *port
               << " (" << *canonical_address << ")";
    return true;
}

std::string perror_str(const char* msg) {
    return android::base::StringPrintf("%s: %s", msg, strerror(errno));
}
+0 −11
Original line number Diff line number Diff line
@@ -35,17 +35,6 @@ std::string escape_arg(const std::string& s);

std::string dump_hex(const void* ptr, size_t byte_count);

// Parses 'address' into 'host' and 'port'.
// If no port is given, takes the default from *port.
// 'canonical_address' then becomes "host:port" or "[host]:port" as appropriate.
// Note that no real checking is done that 'host' or 'port' is valid; that's
// left to getaddrinfo(3).
// Returns false on failure and sets *error to an appropriate message.
bool parse_host_and_port(const std::string& address,
                         std::string* canonical_address,
                         std::string* host, int* port,
                         std::string* error);

std::string perror_str(const char* msg);

bool set_file_block_mode(int fd, bool block);
+0 −82
Original line number Diff line number Diff line
@@ -111,88 +111,6 @@ TEST(adb_utils, adb_dirname) {
  EXPECT_EQ("/system/bin", adb_dirname("/system/bin/sh/"));
}

TEST(adb_utils, parse_host_and_port) {
  std::string canonical_address;
  std::string host;
  int port;
  std::string error;

  // Name, default port.
  port = 123;
  ASSERT_TRUE(parse_host_and_port("www.google.com", &canonical_address, &host, &port, &error));
  ASSERT_EQ("www.google.com:123", canonical_address);
  ASSERT_EQ("www.google.com", host);
  ASSERT_EQ(123, port);

  // Name, explicit port.
  ASSERT_TRUE(parse_host_and_port("www.google.com:666", &canonical_address, &host, &port, &error));
  ASSERT_EQ("www.google.com:666", canonical_address);
  ASSERT_EQ("www.google.com", host);
  ASSERT_EQ(666, port);

  // IPv4, default port.
  port = 123;
  ASSERT_TRUE(parse_host_and_port("1.2.3.4", &canonical_address, &host, &port, &error));
  ASSERT_EQ("1.2.3.4:123", canonical_address);
  ASSERT_EQ("1.2.3.4", host);
  ASSERT_EQ(123, port);

  // IPv4, explicit port.
  ASSERT_TRUE(parse_host_and_port("1.2.3.4:666", &canonical_address, &host, &port, &error));
  ASSERT_EQ("1.2.3.4:666", canonical_address);
  ASSERT_EQ("1.2.3.4", host);
  ASSERT_EQ(666, port);

  // Simple IPv6, default port.
  port = 123;
  ASSERT_TRUE(parse_host_and_port("::1", &canonical_address, &host, &port, &error));
  ASSERT_EQ("[::1]:123", canonical_address);
  ASSERT_EQ("::1", host);
  ASSERT_EQ(123, port);

  // Simple IPv6, explicit port.
  ASSERT_TRUE(parse_host_and_port("[::1]:666", &canonical_address, &host, &port, &error));
  ASSERT_EQ("[::1]:666", canonical_address);
  ASSERT_EQ("::1", host);
  ASSERT_EQ(666, port);

  // Hairy IPv6, default port.
  port = 123;
  ASSERT_TRUE(parse_host_and_port("fe80::200:5aee:feaa:20a2", &canonical_address, &host, &port, &error));
  ASSERT_EQ("[fe80::200:5aee:feaa:20a2]:123", canonical_address);
  ASSERT_EQ("fe80::200:5aee:feaa:20a2", host);
  ASSERT_EQ(123, port);

  // Simple IPv6, explicit port.
  ASSERT_TRUE(parse_host_and_port("[fe80::200:5aee:feaa:20a2]:666", &canonical_address, &host, &port, &error));
  ASSERT_EQ("[fe80::200:5aee:feaa:20a2]:666", canonical_address);
  ASSERT_EQ("fe80::200:5aee:feaa:20a2", host);
  ASSERT_EQ(666, port);

  // Invalid IPv4.
  EXPECT_FALSE(parse_host_and_port("1.2.3.4:", &canonical_address, &host, &port, &error));
  EXPECT_FALSE(parse_host_and_port("1.2.3.4::", &canonical_address, &host, &port, &error));
  EXPECT_FALSE(parse_host_and_port("1.2.3.4:hello", &canonical_address, &host, &port, &error));
  EXPECT_FALSE(parse_host_and_port(":123", &canonical_address, &host, &port, &error));

  // Invalid IPv6.
  EXPECT_FALSE(parse_host_and_port(":1", &canonical_address, &host, &port, &error));
  EXPECT_FALSE(parse_host_and_port("::::::::1", &canonical_address, &host, &port, &error));
  EXPECT_FALSE(parse_host_and_port("[::1", &canonical_address, &host, &port, &error));
  EXPECT_FALSE(parse_host_and_port("[::1]", &canonical_address, &host, &port, &error));
  EXPECT_FALSE(parse_host_and_port("[::1]:", &canonical_address, &host, &port, &error));
  EXPECT_FALSE(parse_host_and_port("[::1]::", &canonical_address, &host, &port, &error));
  EXPECT_FALSE(parse_host_and_port("[::1]:hello", &canonical_address, &host, &port, &error));

  // Invalid ports.
  EXPECT_FALSE(parse_host_and_port("[::1]:-1", &canonical_address, &host, &port, &error));
  EXPECT_FALSE(parse_host_and_port("[::1]:0", &canonical_address, &host, &port, &error));
  EXPECT_FALSE(parse_host_and_port("[::1]:65536", &canonical_address, &host, &port, &error));
  EXPECT_FALSE(parse_host_and_port("1.2.3.4:-1", &canonical_address, &host, &port, &error));
  EXPECT_FALSE(parse_host_and_port("1.2.3.4:0", &canonical_address, &host, &port, &error));
  EXPECT_FALSE(parse_host_and_port("1.2.3.4:65536", &canonical_address, &host, &port, &error));
}

void test_mkdirs(const std::string basepath) {
  EXPECT_TRUE(mkdirs(basepath));
  EXPECT_NE(-1, adb_creat(basepath.c_str(), 0600));
+2 −1
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#endif

#include <android-base/file.h>
#include <android-base/parsenetaddress.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <cutils/sockets.h>
@@ -396,7 +397,7 @@ static void connect_device(const std::string& address, std::string* response) {
    std::string serial;
    std::string host;
    int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
    if (!parse_host_and_port(address, &serial, &host, &port, response)) {
    if (!android::base::ParseNetAddress(address, &host, &port, &serial, response)) {
        return;
    }

Loading