mirror of
https://github.com/intel/llvm.git
synced 2026-01-20 10:18:14 +08:00
Fix debugserver accepting remote connections
While adding IPv6 support to debugserver I broke handling wildcard addresses and fully qualified address filtering. This patch resolves that bug and adds a test for matching the address "*". <rdar://problem/32947613> llvm-svn: 307957
This commit is contained in:
@@ -151,6 +151,11 @@ public:
|
||||
//------------------------------------------------------------------
|
||||
bool IsAnyAddr() const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Returns true if the socket is INADDR_LOOPBACK
|
||||
//------------------------------------------------------------------
|
||||
bool IsLocalhost() const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Direct access to all of the sockaddr structures
|
||||
//------------------------------------------------------------------
|
||||
|
||||
@@ -317,6 +317,13 @@ bool SocketAddress::IsAnyAddr() const {
|
||||
: 0 == memcmp(&m_socket_addr.sa_ipv6.sin6_addr, &in6addr_any, 16);
|
||||
}
|
||||
|
||||
bool SocketAddress::IsLocalhost() const {
|
||||
return (GetFamily() == AF_INET)
|
||||
? m_socket_addr.sa_ipv4.sin_addr.s_addr == htonl(INADDR_LOOPBACK)
|
||||
: 0 == memcmp(&m_socket_addr.sa_ipv6.sin6_addr, &in6addr_loopback,
|
||||
16);
|
||||
}
|
||||
|
||||
bool SocketAddress::operator==(const SocketAddress &rhs) const {
|
||||
if (GetFamily() != rhs.GetFamily())
|
||||
return false;
|
||||
|
||||
@@ -79,9 +79,17 @@ rnb_err_t RNBSocket::Listen(const char *listen_host, uint16_t port,
|
||||
return rnb_err;
|
||||
}
|
||||
|
||||
bool any_addr = (strcmp(listen_host, "*") == 0);
|
||||
|
||||
// If the user wants to allow connections from any address we should create
|
||||
// sockets on all families that can resolve localhost. This will allow us to
|
||||
// listen for IPv6 and IPv4 connections from all addresses if those interfaces
|
||||
// are available.
|
||||
const char *local_addr = any_addr ? "localhost" : listen_host;
|
||||
|
||||
std::map<int, lldb_private::SocketAddress> sockets;
|
||||
auto addresses = lldb_private::SocketAddress::GetAddressInfo(
|
||||
listen_host, NULL, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
|
||||
local_addr, NULL, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
|
||||
|
||||
for (auto address : addresses) {
|
||||
int sock_fd = ::socket(address.GetFamily(), SOCK_STREAM, IPPROTO_TCP);
|
||||
@@ -90,9 +98,15 @@ rnb_err_t RNBSocket::Listen(const char *listen_host, uint16_t port,
|
||||
|
||||
SetSocketOption(sock_fd, SOL_SOCKET, SO_REUSEADDR, 1);
|
||||
|
||||
address.SetPort(port);
|
||||
lldb_private::SocketAddress bind_address = address;
|
||||
|
||||
int error = ::bind(sock_fd, &address.sockaddr(), address.GetLength());
|
||||
if(any_addr || !bind_address.IsLocalhost())
|
||||
bind_address.SetToAnyAddress(bind_address.GetFamily(), port);
|
||||
else
|
||||
bind_address.SetPort(port);
|
||||
|
||||
int error =
|
||||
::bind(sock_fd, &bind_address.sockaddr(), bind_address.GetLength());
|
||||
if (error == -1) {
|
||||
ClosePort(sock_fd, false);
|
||||
continue;
|
||||
@@ -179,6 +193,7 @@ rnb_err_t RNBSocket::Listen(const char *listen_host, uint16_t port,
|
||||
DNBLogThreaded("error: rejecting connection from %s (expecting %s)\n",
|
||||
accept_addr.GetIPAddress().c_str(),
|
||||
addr_in.GetIPAddress().c_str());
|
||||
err.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,6 +85,8 @@ TEST(RNBSocket, LoopBackListenIPv4) { TestSocketListen("127.0.0.1"); }
|
||||
|
||||
TEST(RNBSocket, LoopBackListenIPv6) { TestSocketListen("::1"); }
|
||||
|
||||
TEST(RNBSocket, AnyListen) { TestSocketListen("*"); }
|
||||
|
||||
void TestSocketConnect(const char *addr) {
|
||||
// Skip IPv6 tests if there isn't a valid interafce
|
||||
auto addresses = lldb_private::SocketAddress::GetAddressInfo(
|
||||
|
||||
Reference in New Issue
Block a user