Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
4 changes: 4 additions & 0 deletions lldb/include/lldb/Host/Socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include <memory>
#include <string>
#include <vector>

#include "lldb/Host/MainLoopBase.h"
#include "lldb/Utility/Timeout.h"
Expand Down Expand Up @@ -151,6 +152,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::vector<std::string> GetListeningConnectionURI() const { return {}; }

protected:
Socket(SocketProtocol protocol, bool should_close);

Expand Down
4 changes: 4 additions & 0 deletions lldb/include/lldb/Host/common/TCPSocket.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include "lldb/Host/Socket.h"
#include "lldb/Host/SocketAddress.h"
#include <map>
#include <string>
#include <vector>

namespace lldb_private {
class TCPSocket : public Socket {
Expand Down Expand Up @@ -52,6 +54,8 @@ class TCPSocket : public Socket {

std::string GetRemoteConnectionURI() const override;

std::vector<std::string> GetListeningConnectionURI() const override;

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

Expand Down
4 changes: 4 additions & 0 deletions lldb/include/lldb/Host/posix/DomainSocket.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#define LLDB_HOST_POSIX_DOMAINSOCKET_H

#include "lldb/Host/Socket.h"
#include <string>
#include <vector>

namespace lldb_private {
class DomainSocket : public Socket {
Expand All @@ -27,6 +29,8 @@ class DomainSocket : public Socket {

std::string GetRemoteConnectionURI() const override;

std::vector<std::string> GetListeningConnectionURI() const override;

protected:
DomainSocket(SocketProtocol protocol);

Expand Down
12 changes: 12 additions & 0 deletions lldb/source/Host/common/TCPSocket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,18 @@ std::string TCPSocket::GetRemoteConnectionURI() const {
return "";
}

std::vector<std::string> TCPSocket::GetListeningConnectionURI() const {
if (m_listen_sockets.empty())
return {};

std::vector<std::string> URIs;
for (auto &s : m_listen_sockets)
URIs.emplace_back(llvm::formatv(
"connection://[{0}]:{1}", s.second.GetIPAddress(), s.second.GetPort()));

return URIs;
}

Status TCPSocket::CreateSocket(int domain) {
Status error;
if (IsValid())
Expand Down
14 changes: 14 additions & 0 deletions lldb/source/Host/posix/DomainSocket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,17 @@ std::string DomainSocket::GetRemoteConnectionURI() const {
"{0}://{1}",
GetNameOffset() == 0 ? "unix-connect" : "unix-abstract-connect", name);
}

std::vector<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)};
}
41 changes: 40 additions & 1 deletion lldb/unittests/Host/SocketTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,28 @@ 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());

const auto &URIs = listen_socket_up->GetListeningConnectionURI();
ASSERT_EQ(URIs.size(), 1u);
ASSERT_EQ(URIs[0], 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 +247,29 @@ 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());

for (const auto &URI : sock.get()->GetListeningConnectionURI()) {
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
Loading