Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions lldb/include/lldb/Host/Socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,9 @@ class Socket : public IOObject {
// If this Socket is connected then return the URI used to connect.
virtual std::string GetRemoteConnectionURI() const { return ""; };

// If the Socket is listening then return the URI for clients to connect.
virtual std::string GetListeningConnectionURI() const { return ""; }

protected:
Socket(SocketProtocol protocol, bool should_close);

Expand Down
2 changes: 2 additions & 0 deletions lldb/include/lldb/Host/common/TCPSocket.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ class TCPSocket : public Socket {

std::string GetRemoteConnectionURI() const override;

std::string GetListeningConnectionURI() const override;

private:
TCPSocket(NativeSocket socket, const TCPSocket &listen_socket);

Expand Down
2 changes: 2 additions & 0 deletions lldb/include/lldb/Host/posix/DomainSocket.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ class DomainSocket : public Socket {

std::string GetRemoteConnectionURI() const override;

std::string GetListeningConnectionURI() const override;

protected:
DomainSocket(SocketProtocol protocol);

Expand Down
22 changes: 19 additions & 3 deletions lldb/source/Host/common/TCPSocket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ std::string TCPSocket::GetLocalIPAddress() const {
socklen_t sock_addr_len = sock_addr.GetMaxLength();
if (::getsockname(m_socket, sock_addr, &sock_addr_len) == 0)
return sock_addr.GetIPAddress();
} else if (!m_listen_sockets.empty()) {
SocketAddress sock_addr;
socklen_t sock_addr_len = sock_addr.GetMaxLength();
if (::getsockname(m_listen_sockets.begin()->first, sock_addr,
&sock_addr_len) == 0)
return sock_addr.GetIPAddress();
}
return "";
}
Expand Down Expand Up @@ -115,6 +121,15 @@ std::string TCPSocket::GetRemoteConnectionURI() const {
return "";
}

std::string TCPSocket::GetListeningConnectionURI() const {
if (!m_listen_sockets.empty()) {
return std::string(llvm::formatv(
"connection://[{0}]:{1}", GetLocalIPAddress(), GetLocalPortNumber()));
}

return "";
}

Status TCPSocket::CreateSocket(int domain) {
Status error;
if (IsValid())
Expand Down Expand Up @@ -176,8 +191,9 @@ Status TCPSocket::Listen(llvm::StringRef name, int backlog) {

if (host_port->hostname == "*")
host_port->hostname = "0.0.0.0";
std::vector<SocketAddress> addresses = SocketAddress::GetAddressInfo(
host_port->hostname.c_str(), nullptr, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
std::vector<SocketAddress> addresses =
SocketAddress::GetAddressInfo(host_port->hostname.c_str(), nullptr,
AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
for (SocketAddress &address : addresses) {
int fd =
Socket::CreateSocket(address.GetFamily(), kType, IPPROTO_TCP, error);
Expand All @@ -191,7 +207,7 @@ Status TCPSocket::Listen(llvm::StringRef name, int backlog) {
}

SocketAddress listen_address = address;
if(!listen_address.IsLocalhost())
if (!listen_address.IsLocalhost())
listen_address.SetToAnyAddress(address.GetFamily(), host_port->port);
else
listen_address.SetPort(host_port->port);
Expand Down
17 changes: 16 additions & 1 deletion lldb/source/Host/posix/DomainSocket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ Status DomainSocket::Connect(llvm::StringRef name) {
if (error.Fail())
return error;
if (llvm::sys::RetryAfterSignal(-1, ::connect, GetNativeSocket(),
(struct sockaddr *)&saddr_un, saddr_un_len) < 0)
(struct sockaddr *)&saddr_un,
saddr_un_len) < 0)
SetLastError(error);

return error;
Expand Down Expand Up @@ -175,3 +176,17 @@ std::string DomainSocket::GetRemoteConnectionURI() const {
"{0}://{1}",
GetNameOffset() == 0 ? "unix-connect" : "unix-abstract-connect", name);
}

std::string DomainSocket::GetListeningConnectionURI() const {
if (m_socket == kInvalidSocketValue)
return "";

struct sockaddr_un addr;
bzero(&addr, sizeof(struct sockaddr_un));
addr.sun_family = AF_UNIX;
socklen_t addr_len = sizeof(struct sockaddr_un);
if (::getsockname(m_socket, (struct sockaddr *)&addr, &addr_len) != 0)
return "";

return llvm::formatv("unix-connect://{0}", addr.sun_path);
}
54 changes: 47 additions & 7 deletions lldb/unittests/Host/SocketTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,8 @@ TEST_P(SocketTest, DecodeHostAndPort) {
EXPECT_THAT_EXPECTED(Socket::DecodeHostAndPort("*:65535"),
llvm::HasValue(Socket::HostAndPort{"*", 65535}));

EXPECT_THAT_EXPECTED(
Socket::DecodeHostAndPort("[::1]:12345"),
llvm::HasValue(Socket::HostAndPort{"::1", 12345}));
EXPECT_THAT_EXPECTED(Socket::DecodeHostAndPort("[::1]:12345"),
llvm::HasValue(Socket::HostAndPort{"::1", 12345}));

EXPECT_THAT_EXPECTED(
Socket::DecodeHostAndPort("[abcd:12fg:AF58::1]:12345"),
Expand All @@ -75,7 +74,8 @@ TEST_P(SocketTest, DecodeHostAndPort) {
#if LLDB_ENABLE_POSIX
TEST_P(SocketTest, DomainListenConnectAccept) {
llvm::SmallString<64> Path;
std::error_code EC = llvm::sys::fs::createUniqueDirectory("DomainListenConnectAccept", Path);
std::error_code EC =
llvm::sys::fs::createUniqueDirectory("DomainListenConnectAccept", Path);
ASSERT_FALSE(EC);
llvm::sys::path::append(Path, "test");

Expand All @@ -88,6 +88,27 @@ TEST_P(SocketTest, DomainListenConnectAccept) {
CreateDomainConnectedSockets(Path, &socket_a_up, &socket_b_up);
}

TEST_P(SocketTest, DomainListenGetListeningConnectionURI) {
llvm::SmallString<64> Path;
std::error_code EC =
llvm::sys::fs::createUniqueDirectory("DomainListenConnectAccept", Path);
ASSERT_FALSE(EC);
llvm::sys::path::append(Path, "test");

// Skip the test if the $TMPDIR is too long to hold a domain socket.
if (Path.size() > 107u)
return;

auto listen_socket_up = std::make_unique<DomainSocket>(
/*should_close=*/true);
Status error = listen_socket_up->Listen(Path, 5);
ASSERT_THAT_ERROR(error.ToError(), llvm::Succeeded());
ASSERT_TRUE(listen_socket_up->IsValid());

ASSERT_EQ(listen_socket_up->GetListeningConnectionURI(),
llvm::formatv("unix-connect://{0}", Path).str());
}

TEST_P(SocketTest, DomainMainLoopAccept) {
llvm::SmallString<64> Path;
std::error_code EC =
Expand Down Expand Up @@ -225,12 +246,31 @@ TEST_P(SocketTest, TCPListen0GetPort) {
if (!HostSupportsIPv4())
return;
llvm::Expected<std::unique_ptr<TCPSocket>> sock =
Socket::TcpListen("10.10.12.3:0", false);
Socket::TcpListen("10.10.12.3:0", 5);
ASSERT_THAT_EXPECTED(sock, llvm::Succeeded());
ASSERT_TRUE(sock.get()->IsValid());
EXPECT_NE(sock.get()->GetLocalPortNumber(), 0);
}

TEST_P(SocketTest, TCPListen0GetListeningConnectionURI) {
if (!HostSupportsProtocol())
return;

std::string addr = llvm::formatv("[{0}]:0", GetParam().localhost_ip).str();
llvm::Expected<std::unique_ptr<TCPSocket>> sock = Socket::TcpListen(addr);
ASSERT_THAT_EXPECTED(sock, llvm::Succeeded());
ASSERT_TRUE(sock.get()->IsValid());
std::string uri = sock.get()->GetListeningConnectionURI();

// Ensure the URI is not "".
EXPECT_FALSE(uri.empty());
EXPECT_NE(uri, addr);
EXPECT_EQ(uri,
llvm::formatv("connection://[{0}]:{1}", GetParam().localhost_ip,
sock->get()->GetLocalPortNumber())
.str());
}

TEST_P(SocketTest, TCPGetConnectURI) {
std::unique_ptr<TCPSocket> socket_a_up;
std::unique_ptr<TCPSocket> socket_b_up;
Expand Down Expand Up @@ -260,8 +300,8 @@ TEST_P(SocketTest, UDPGetConnectURI) {
#if LLDB_ENABLE_POSIX
TEST_P(SocketTest, DomainGetConnectURI) {
llvm::SmallString<64> domain_path;
std::error_code EC =
llvm::sys::fs::createUniqueDirectory("DomainListenConnectAccept", domain_path);
std::error_code EC = llvm::sys::fs::createUniqueDirectory(
"DomainListenConnectAccept", domain_path);
ASSERT_FALSE(EC);
llvm::sys::path::append(domain_path, "test");

Expand Down
Loading