Skip to content

Commit 3845624

Browse files
authored
[lldb] For a host socket, add a method to print the listening address. (llvm#118330)
This is most useful if you are listening on an address like 'localhost:0' and want to know the resolved ip + port of the socket listener.
1 parent 0ccd18e commit 3845624

File tree

6 files changed

+76
-1
lines changed

6 files changed

+76
-1
lines changed

lldb/include/lldb/Host/Socket.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include <memory>
1313
#include <string>
14+
#include <vector>
1415

1516
#include "lldb/Host/MainLoopBase.h"
1617
#include "lldb/Utility/Timeout.h"
@@ -151,6 +152,11 @@ class Socket : public IOObject {
151152
// If this Socket is connected then return the URI used to connect.
152153
virtual std::string GetRemoteConnectionURI() const { return ""; };
153154

155+
// If the Socket is listening then return the URI for clients to connect.
156+
virtual std::vector<std::string> GetListeningConnectionURI() const {
157+
return {};
158+
}
159+
154160
protected:
155161
Socket(SocketProtocol protocol, bool should_close);
156162

lldb/include/lldb/Host/common/TCPSocket.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#include "lldb/Host/Socket.h"
1414
#include "lldb/Host/SocketAddress.h"
1515
#include <map>
16+
#include <string>
17+
#include <vector>
1618

1719
namespace lldb_private {
1820
class TCPSocket : public Socket {
@@ -52,6 +54,8 @@ class TCPSocket : public Socket {
5254

5355
std::string GetRemoteConnectionURI() const override;
5456

57+
std::vector<std::string> GetListeningConnectionURI() const override;
58+
5559
private:
5660
TCPSocket(NativeSocket socket, const TCPSocket &listen_socket);
5761

lldb/include/lldb/Host/posix/DomainSocket.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#define LLDB_HOST_POSIX_DOMAINSOCKET_H
1111

1212
#include "lldb/Host/Socket.h"
13+
#include <string>
14+
#include <vector>
1315

1416
namespace lldb_private {
1517
class DomainSocket : public Socket {
@@ -27,6 +29,8 @@ class DomainSocket : public Socket {
2729

2830
std::string GetRemoteConnectionURI() const override;
2931

32+
std::vector<std::string> GetListeningConnectionURI() const override;
33+
3034
protected:
3135
DomainSocket(SocketProtocol protocol);
3236

lldb/source/Host/common/TCPSocket.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,14 @@ std::string TCPSocket::GetRemoteConnectionURI() const {
115115
return "";
116116
}
117117

118+
std::vector<std::string> TCPSocket::GetListeningConnectionURI() const {
119+
std::vector<std::string> URIs;
120+
for (const auto &[fd, addr] : m_listen_sockets)
121+
URIs.emplace_back(llvm::formatv("connection://[{0}]:{1}",
122+
addr.GetIPAddress(), addr.GetPort()));
123+
return URIs;
124+
}
125+
118126
Status TCPSocket::CreateSocket(int domain) {
119127
Status error;
120128
if (IsValid())

lldb/source/Host/posix/DomainSocket.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,3 +175,17 @@ std::string DomainSocket::GetRemoteConnectionURI() const {
175175
"{0}://{1}",
176176
GetNameOffset() == 0 ? "unix-connect" : "unix-abstract-connect", name);
177177
}
178+
179+
std::vector<std::string> DomainSocket::GetListeningConnectionURI() const {
180+
if (m_socket == kInvalidSocketValue)
181+
return {};
182+
183+
struct sockaddr_un addr;
184+
bzero(&addr, sizeof(struct sockaddr_un));
185+
addr.sun_family = AF_UNIX;
186+
socklen_t addr_len = sizeof(struct sockaddr_un);
187+
if (::getsockname(m_socket, (struct sockaddr *)&addr, &addr_len) != 0)
188+
return {};
189+
190+
return {llvm::formatv("unix-connect://{0}", addr.sun_path)};
191+
}

lldb/unittests/Host/SocketTest.cpp

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,28 @@ TEST_P(SocketTest, DomainListenConnectAccept) {
8888
CreateDomainConnectedSockets(Path, &socket_a_up, &socket_b_up);
8989
}
9090

91+
TEST_P(SocketTest, DomainListenGetListeningConnectionURI) {
92+
llvm::SmallString<64> Path;
93+
std::error_code EC =
94+
llvm::sys::fs::createUniqueDirectory("DomainListenConnectAccept", Path);
95+
ASSERT_FALSE(EC);
96+
llvm::sys::path::append(Path, "test");
97+
98+
// Skip the test if the $TMPDIR is too long to hold a domain socket.
99+
if (Path.size() > 107u)
100+
return;
101+
102+
auto listen_socket_up = std::make_unique<DomainSocket>(
103+
/*should_close=*/true);
104+
Status error = listen_socket_up->Listen(Path, 5);
105+
ASSERT_THAT_ERROR(error.ToError(), llvm::Succeeded());
106+
ASSERT_TRUE(listen_socket_up->IsValid());
107+
108+
ASSERT_THAT(
109+
listen_socket_up->GetListeningConnectionURI(),
110+
testing::ElementsAre(llvm::formatv("unix-connect://{0}", Path).str()));
111+
}
112+
91113
TEST_P(SocketTest, DomainMainLoopAccept) {
92114
llvm::SmallString<64> Path;
93115
std::error_code EC =
@@ -225,12 +247,29 @@ TEST_P(SocketTest, TCPListen0GetPort) {
225247
if (!HostSupportsIPv4())
226248
return;
227249
llvm::Expected<std::unique_ptr<TCPSocket>> sock =
228-
Socket::TcpListen("10.10.12.3:0", false);
250+
Socket::TcpListen("10.10.12.3:0", 5);
229251
ASSERT_THAT_EXPECTED(sock, llvm::Succeeded());
230252
ASSERT_TRUE(sock.get()->IsValid());
231253
EXPECT_NE(sock.get()->GetLocalPortNumber(), 0);
232254
}
233255

256+
TEST_P(SocketTest, TCPListen0GetListeningConnectionURI) {
257+
if (!HostSupportsProtocol())
258+
return;
259+
260+
std::string addr = llvm::formatv("[{0}]:0", GetParam().localhost_ip).str();
261+
llvm::Expected<std::unique_ptr<TCPSocket>> sock = Socket::TcpListen(addr);
262+
ASSERT_THAT_EXPECTED(sock, llvm::Succeeded());
263+
ASSERT_TRUE(sock.get()->IsValid());
264+
265+
EXPECT_THAT(
266+
sock.get()->GetListeningConnectionURI(),
267+
testing::ElementsAre(llvm::formatv("connection://[{0}]:{1}",
268+
GetParam().localhost_ip,
269+
sock->get()->GetLocalPortNumber())
270+
.str()));
271+
}
272+
234273
TEST_P(SocketTest, TCPGetConnectURI) {
235274
std::unique_ptr<TCPSocket> socket_a_up;
236275
std::unique_ptr<TCPSocket> socket_b_up;

0 commit comments

Comments
 (0)