-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[lldb] For a host socket, add a method to print the listening address. #118330
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
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 listeniner.
@llvm/pr-subscribers-lldb Author: John Harrison (ashgti) ChangesThis 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. Full diff: https://github.com/llvm/llvm-project/pull/118330.diff 6 Files Affected:
diff --git a/lldb/include/lldb/Host/Socket.h b/lldb/include/lldb/Host/Socket.h
index e98797b36c8a5d..c937e0c02ff19e 100644
--- a/lldb/include/lldb/Host/Socket.h
+++ b/lldb/include/lldb/Host/Socket.h
@@ -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);
diff --git a/lldb/include/lldb/Host/common/TCPSocket.h b/lldb/include/lldb/Host/common/TCPSocket.h
index ca36622691fe9a..ab6bf5ab97cae7 100644
--- a/lldb/include/lldb/Host/common/TCPSocket.h
+++ b/lldb/include/lldb/Host/common/TCPSocket.h
@@ -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);
diff --git a/lldb/include/lldb/Host/posix/DomainSocket.h b/lldb/include/lldb/Host/posix/DomainSocket.h
index d4e0d43ee169c1..d79564cc76dafd 100644
--- a/lldb/include/lldb/Host/posix/DomainSocket.h
+++ b/lldb/include/lldb/Host/posix/DomainSocket.h
@@ -27,6 +27,8 @@ class DomainSocket : public Socket {
std::string GetRemoteConnectionURI() const override;
+ std::string GetListeningConnectionURI() const override;
+
protected:
DomainSocket(SocketProtocol protocol);
diff --git a/lldb/source/Host/common/TCPSocket.cpp b/lldb/source/Host/common/TCPSocket.cpp
index 5d863954ee8868..b7bd62ff04855e 100644
--- a/lldb/source/Host/common/TCPSocket.cpp
+++ b/lldb/source/Host/common/TCPSocket.cpp
@@ -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 "";
}
@@ -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())
@@ -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);
@@ -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);
diff --git a/lldb/source/Host/posix/DomainSocket.cpp b/lldb/source/Host/posix/DomainSocket.cpp
index 0451834630d33f..beec3c225ecc62 100644
--- a/lldb/source/Host/posix/DomainSocket.cpp
+++ b/lldb/source/Host/posix/DomainSocket.cpp
@@ -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;
@@ -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);
+}
diff --git a/lldb/unittests/Host/SocketTest.cpp b/lldb/unittests/Host/SocketTest.cpp
index b20cfe54640285..b69e8874ca01dc 100644
--- a/lldb/unittests/Host/SocketTest.cpp
+++ b/lldb/unittests/Host/SocketTest.cpp
@@ -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"),
@@ -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");
@@ -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 =
@@ -225,12 +246,28 @@ 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) {
+ 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;
@@ -260,8 +297,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");
|
…ocol is not supported.
…verting formatting changes.
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool. Thanks.
Local branch amd-gfx 401ed9d Merged main:95a4d30b0d64 into amd-gfx:e579a32bca2b Remote branch main 3845624 [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.