Merge "Allow the adb server to bind on ::1" am: 80a734f146
am: 4922f2aef2
Change-Id: I2a1b563770dd563a80fa83bed8d58f7ca4984ff3
diff --git a/adb/socket_spec.cpp b/adb/socket_spec.cpp
index 98468b5..27e8c46 100644
--- a/adb/socket_spec.cpp
+++ b/adb/socket_spec.cpp
@@ -272,7 +272,9 @@
if (hostname.empty() && gListenAll) {
result = network_inaddr_any_server(port, SOCK_STREAM, error);
} else if (tcp_host_is_local(hostname)) {
- result = network_loopback_server(port, SOCK_STREAM, error);
+ result = network_loopback_server(port, SOCK_STREAM, error, true);
+ } else if (hostname == "::1") {
+ result = network_loopback_server(port, SOCK_STREAM, error, false);
} else {
// TODO: Implement me.
*error = "listening on specified hostname currently unsupported";
diff --git a/adb/sysdeps/network.h b/adb/sysdeps/network.h
index 83ce371..fadd155 100644
--- a/adb/sysdeps/network.h
+++ b/adb/sysdeps/network.h
@@ -19,4 +19,4 @@
#include <string>
int network_loopback_client(int port, int type, std::string* error);
-int network_loopback_server(int port, int type, std::string* error);
+int network_loopback_server(int port, int type, std::string* error, bool prefer_ipv4);
diff --git a/adb/sysdeps/posix/network.cpp b/adb/sysdeps/posix/network.cpp
index c5c2275..a4d9013 100644
--- a/adb/sysdeps/posix/network.cpp
+++ b/adb/sysdeps/posix/network.cpp
@@ -119,12 +119,15 @@
return s.release();
}
-int network_loopback_server(int port, int type, std::string* error) {
- int rc = _network_loopback_server(false, port, type, error);
+int network_loopback_server(int port, int type, std::string* error, bool prefer_ipv4) {
+ int rc = -1;
+ if (prefer_ipv4) {
+ rc = _network_loopback_server(false, port, type, error);
+ }
- // Only attempt to listen on IPv6 if IPv4 is unavailable.
+ // Only attempt to listen on IPv6 if IPv4 is unavailable or prefer_ipv4 is false
// We don't want to start an IPv6 server if there's already an IPv4 one running.
- if (rc == -1 && (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT)) {
+ if (rc == -1 && (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT || !prefer_ipv4)) {
return _network_loopback_server(true, port, type, error);
}
return rc;
diff --git a/adb/sysdeps_win32.cpp b/adb/sysdeps_win32.cpp
index 4d6cf3d..d9cc36f 100644
--- a/adb/sysdeps_win32.cpp
+++ b/adb/sysdeps_win32.cpp
@@ -920,7 +920,8 @@
return fd;
}
-int network_loopback_server(int port, int type, std::string* error) {
+int network_loopback_server(int port, int type, std::string* error, bool prefer_ipv4) {
+ // TODO implement IPv6 support on windows
return _network_server(port, type, INADDR_LOOPBACK, error);
}
@@ -1132,7 +1133,7 @@
int local_port = -1;
std::string error;
- server = network_loopback_server(0, SOCK_STREAM, &error);
+ server = network_loopback_server(0, SOCK_STREAM, &error, true);
if (server < 0) {
D("adb_socketpair: failed to create server: %s", error.c_str());
goto fail;
diff --git a/adb/test_adb.py b/adb/test_adb.py
index 8272722..3d6de26 100755
--- a/adb/test_adb.py
+++ b/adb/test_adb.py
@@ -281,6 +281,37 @@
subprocess.check_output(["adb", "-P", str(port), "kill-server"],
stderr=subprocess.STDOUT)
+ @unittest.skipUnless(
+ os.name == "posix",
+ "adb doesn't yet support IPv6 on Windows",
+ )
+ def test_starts_on_ipv6_localhost(self):
+ """
+ Tests that the server can start up on ::1 and that it's accessible
+ """
+ server_port = 5037
+ # Kill any existing server on this non-default port.
+ subprocess.check_output(
+ ["adb", "-P", str(server_port), "kill-server"],
+ stderr=subprocess.STDOUT,
+ )
+ try:
+ subprocess.check_output(
+ ["adb", "-L", "tcp:[::1]:{}".format(server_port), "server"],
+ stderr=subprocess.STDOUT,
+ )
+ with fake_adbd() as (port, _):
+ with adb_connect(self, serial="localhost:{}".format(port)):
+ pass
+ finally:
+ # If we started a server, kill it.
+ subprocess.check_output(
+ ["adb", "-P", str(server_port), "kill-server"],
+ stderr=subprocess.STDOUT,
+ )
+
+
+
class EmulatorTest(unittest.TestCase):
"""Tests for the emulator connection."""