llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lldb Author: John Harrison (ashgti) <details> <summary>Changes</summary> 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. --- Full diff: https://github.com/llvm/llvm-project/pull/118330.diff 6 Files Affected: - (modified) lldb/include/lldb/Host/Socket.h (+3) - (modified) lldb/include/lldb/Host/common/TCPSocket.h (+2) - (modified) lldb/include/lldb/Host/posix/DomainSocket.h (+2) - (modified) lldb/source/Host/common/TCPSocket.cpp (+19-3) - (modified) lldb/source/Host/posix/DomainSocket.cpp (+16-1) - (modified) lldb/unittests/Host/SocketTest.cpp (+44-7) ``````````diff 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"); `````````` </details> https://github.com/llvm/llvm-project/pull/118330 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits