1 //===-- SocketTest.cpp ----------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "SocketTestUtilities.h" 10 #include "TestingSupport/SubsystemRAII.h" 11 #include "lldb/Host/Config.h" 12 #include "lldb/Utility/UriParser.h" 13 #include "gtest/gtest.h" 14 15 using namespace lldb_private; 16 17 class SocketTest : public testing::Test { 18 public: 19 SubsystemRAII<Socket> subsystems; 20 }; 21 22 TEST_F(SocketTest, DecodeHostAndPort) { 23 std::string host_str; 24 std::string port_str; 25 int32_t port; 26 Status error; 27 EXPECT_TRUE(Socket::DecodeHostAndPort("localhost:1138", host_str, port_str, 28 port, &error)); 29 EXPECT_STREQ("localhost", host_str.c_str()); 30 EXPECT_STREQ("1138", port_str.c_str()); 31 EXPECT_EQ(1138, port); 32 EXPECT_TRUE(error.Success()); 33 34 EXPECT_FALSE(Socket::DecodeHostAndPort("google.com:65536", host_str, port_str, 35 port, &error)); 36 EXPECT_TRUE(error.Fail()); 37 EXPECT_STREQ("invalid host:port specification: 'google.com:65536'", 38 error.AsCString()); 39 40 EXPECT_FALSE(Socket::DecodeHostAndPort("google.com:-1138", host_str, port_str, 41 port, &error)); 42 EXPECT_TRUE(error.Fail()); 43 EXPECT_STREQ("invalid host:port specification: 'google.com:-1138'", 44 error.AsCString()); 45 46 EXPECT_FALSE(Socket::DecodeHostAndPort("google.com:65536", host_str, port_str, 47 port, &error)); 48 EXPECT_TRUE(error.Fail()); 49 EXPECT_STREQ("invalid host:port specification: 'google.com:65536'", 50 error.AsCString()); 51 52 EXPECT_TRUE( 53 Socket::DecodeHostAndPort("12345", host_str, port_str, port, &error)); 54 EXPECT_STREQ("", host_str.c_str()); 55 EXPECT_STREQ("12345", port_str.c_str()); 56 EXPECT_EQ(12345, port); 57 EXPECT_TRUE(error.Success()); 58 59 EXPECT_TRUE( 60 Socket::DecodeHostAndPort("*:0", host_str, port_str, port, &error)); 61 EXPECT_STREQ("*", host_str.c_str()); 62 EXPECT_STREQ("0", port_str.c_str()); 63 EXPECT_EQ(0, port); 64 EXPECT_TRUE(error.Success()); 65 66 EXPECT_TRUE( 67 Socket::DecodeHostAndPort("*:65535", host_str, port_str, port, &error)); 68 EXPECT_STREQ("*", host_str.c_str()); 69 EXPECT_STREQ("65535", port_str.c_str()); 70 EXPECT_EQ(65535, port); 71 EXPECT_TRUE(error.Success()); 72 73 EXPECT_TRUE( 74 Socket::DecodeHostAndPort("[::1]:12345", host_str, port_str, port, &error)); 75 EXPECT_STREQ("::1", host_str.c_str()); 76 EXPECT_STREQ("12345", port_str.c_str()); 77 EXPECT_EQ(12345, port); 78 EXPECT_TRUE(error.Success()); 79 80 EXPECT_TRUE( 81 Socket::DecodeHostAndPort("[abcd:12fg:AF58::1]:12345", host_str, port_str, port, &error)); 82 EXPECT_STREQ("abcd:12fg:AF58::1", host_str.c_str()); 83 EXPECT_STREQ("12345", port_str.c_str()); 84 EXPECT_EQ(12345, port); 85 EXPECT_TRUE(error.Success()); 86 } 87 88 #if LLDB_ENABLE_POSIX 89 TEST_F(SocketTest, DomainListenConnectAccept) { 90 llvm::SmallString<64> Path; 91 std::error_code EC = llvm::sys::fs::createUniqueDirectory("DomainListenConnectAccept", Path); 92 ASSERT_FALSE(EC); 93 llvm::sys::path::append(Path, "test"); 94 95 // Skip the test if the $TMPDIR is too long to hold a domain socket. 96 if (Path.size() > 107u) 97 return; 98 99 std::unique_ptr<DomainSocket> socket_a_up; 100 std::unique_ptr<DomainSocket> socket_b_up; 101 CreateDomainConnectedSockets(Path, &socket_a_up, &socket_b_up); 102 } 103 #endif 104 105 TEST_F(SocketTest, TCPListen0ConnectAccept) { 106 std::unique_ptr<TCPSocket> socket_a_up; 107 std::unique_ptr<TCPSocket> socket_b_up; 108 CreateTCPConnectedSockets("127.0.0.1", &socket_a_up, &socket_b_up); 109 } 110 111 TEST_F(SocketTest, TCPGetAddress) { 112 std::unique_ptr<TCPSocket> socket_a_up; 113 std::unique_ptr<TCPSocket> socket_b_up; 114 if (!HostSupportsIPv4()) 115 return; 116 CreateTCPConnectedSockets("127.0.0.1", &socket_a_up, &socket_b_up); 117 118 EXPECT_EQ(socket_a_up->GetLocalPortNumber(), 119 socket_b_up->GetRemotePortNumber()); 120 EXPECT_EQ(socket_b_up->GetLocalPortNumber(), 121 socket_a_up->GetRemotePortNumber()); 122 EXPECT_NE(socket_a_up->GetLocalPortNumber(), 123 socket_b_up->GetLocalPortNumber()); 124 EXPECT_STREQ("127.0.0.1", socket_a_up->GetRemoteIPAddress().c_str()); 125 EXPECT_STREQ("127.0.0.1", socket_b_up->GetRemoteIPAddress().c_str()); 126 } 127 128 TEST_F(SocketTest, UDPConnect) { 129 llvm::Expected<std::unique_ptr<UDPSocket>> socket = 130 UDPSocket::Connect("127.0.0.1:0", /*child_processes_inherit=*/false); 131 132 ASSERT_THAT_EXPECTED(socket, llvm::Succeeded()); 133 EXPECT_TRUE(socket.get()->IsValid()); 134 } 135 136 TEST_F(SocketTest, TCPListen0GetPort) { 137 Predicate<uint16_t> port_predicate; 138 port_predicate.SetValue(0, eBroadcastNever); 139 llvm::Expected<std::unique_ptr<TCPSocket>> sock = 140 Socket::TcpListen("10.10.12.3:0", false, &port_predicate); 141 ASSERT_THAT_EXPECTED(sock, llvm::Succeeded()); 142 ASSERT_TRUE(sock.get()->IsValid()); 143 EXPECT_NE(sock.get()->GetLocalPortNumber(), 0); 144 } 145 146 TEST_F(SocketTest, TCPGetConnectURI) { 147 std::unique_ptr<TCPSocket> socket_a_up; 148 std::unique_ptr<TCPSocket> socket_b_up; 149 if (!HostSupportsIPv4()) 150 return; 151 CreateTCPConnectedSockets("127.0.0.1", &socket_a_up, &socket_b_up); 152 153 llvm::StringRef scheme; 154 llvm::StringRef hostname; 155 int port; 156 llvm::StringRef path; 157 std::string uri(socket_a_up->GetRemoteConnectionURI()); 158 EXPECT_TRUE(UriParser::Parse(uri, scheme, hostname, port, path)); 159 EXPECT_EQ(scheme, "connect"); 160 EXPECT_EQ(port, socket_a_up->GetRemotePortNumber()); 161 } 162 163 TEST_F(SocketTest, UDPGetConnectURI) { 164 if (!HostSupportsIPv4()) 165 return; 166 llvm::Expected<std::unique_ptr<UDPSocket>> socket = 167 UDPSocket::Connect("127.0.0.1:0", /*child_processes_inherit=*/false); 168 ASSERT_THAT_EXPECTED(socket, llvm::Succeeded()); 169 170 llvm::StringRef scheme; 171 llvm::StringRef hostname; 172 int port; 173 llvm::StringRef path; 174 std::string uri = socket.get()->GetRemoteConnectionURI(); 175 EXPECT_TRUE(UriParser::Parse(uri, scheme, hostname, port, path)); 176 EXPECT_EQ(scheme, "udp"); 177 } 178 179 #if LLDB_ENABLE_POSIX 180 TEST_F(SocketTest, DomainGetConnectURI) { 181 llvm::SmallString<64> domain_path; 182 std::error_code EC = 183 llvm::sys::fs::createUniqueDirectory("DomainListenConnectAccept", domain_path); 184 ASSERT_FALSE(EC); 185 llvm::sys::path::append(domain_path, "test"); 186 187 // Skip the test if the $TMPDIR is too long to hold a domain socket. 188 if (domain_path.size() > 107u) 189 return; 190 191 std::unique_ptr<DomainSocket> socket_a_up; 192 std::unique_ptr<DomainSocket> socket_b_up; 193 CreateDomainConnectedSockets(domain_path, &socket_a_up, &socket_b_up); 194 195 llvm::StringRef scheme; 196 llvm::StringRef hostname; 197 int port; 198 llvm::StringRef path; 199 std::string uri(socket_a_up->GetRemoteConnectionURI()); 200 EXPECT_TRUE(UriParser::Parse(uri, scheme, hostname, port, path)); 201 EXPECT_EQ(scheme, "unix-connect"); 202 EXPECT_EQ(path, domain_path); 203 } 204 #endif 205