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 (!IsAddressFamilySupported("127.0.0.1")) { 115 GTEST_LOG_(WARNING) << "Skipping test due to missing IPv4 support."; 116 return; 117 } 118 CreateTCPConnectedSockets("127.0.0.1", &socket_a_up, &socket_b_up); 119 120 EXPECT_EQ(socket_a_up->GetLocalPortNumber(), 121 socket_b_up->GetRemotePortNumber()); 122 EXPECT_EQ(socket_b_up->GetLocalPortNumber(), 123 socket_a_up->GetRemotePortNumber()); 124 EXPECT_NE(socket_a_up->GetLocalPortNumber(), 125 socket_b_up->GetLocalPortNumber()); 126 EXPECT_STREQ("127.0.0.1", socket_a_up->GetRemoteIPAddress().c_str()); 127 EXPECT_STREQ("127.0.0.1", socket_b_up->GetRemoteIPAddress().c_str()); 128 } 129 130 TEST_F(SocketTest, UDPConnect) { 131 Socket *socket; 132 133 bool child_processes_inherit = false; 134 auto error = UDPSocket::Connect("127.0.0.1:0", child_processes_inherit, 135 socket); 136 137 std::unique_ptr<Socket> socket_up(socket); 138 139 EXPECT_TRUE(error.Success()); 140 EXPECT_TRUE(socket_up->IsValid()); 141 } 142 143 TEST_F(SocketTest, TCPListen0GetPort) { 144 Socket *server_socket; 145 Predicate<uint16_t> port_predicate; 146 port_predicate.SetValue(0, eBroadcastNever); 147 Status err = 148 Socket::TcpListen("10.10.12.3:0", false, server_socket, &port_predicate); 149 std::unique_ptr<TCPSocket> socket_up((TCPSocket*)server_socket); 150 EXPECT_TRUE(socket_up->IsValid()); 151 EXPECT_NE(socket_up->GetLocalPortNumber(), 0); 152 } 153 154 TEST_F(SocketTest, TCPGetConnectURI) { 155 std::unique_ptr<TCPSocket> socket_a_up; 156 std::unique_ptr<TCPSocket> socket_b_up; 157 if (!IsAddressFamilySupported("127.0.0.1")) { 158 GTEST_LOG_(WARNING) << "Skipping test due to missing IPv4 support."; 159 return; 160 } 161 CreateTCPConnectedSockets("127.0.0.1", &socket_a_up, &socket_b_up); 162 163 llvm::StringRef scheme; 164 llvm::StringRef hostname; 165 int port; 166 llvm::StringRef path; 167 std::string uri(socket_a_up->GetRemoteConnectionURI()); 168 EXPECT_TRUE(UriParser::Parse(uri, scheme, hostname, port, path)); 169 EXPECT_EQ(scheme, "connect"); 170 EXPECT_EQ(port, socket_a_up->GetRemotePortNumber()); 171 } 172 173 TEST_F(SocketTest, UDPGetConnectURI) { 174 if (!IsAddressFamilySupported("127.0.0.1")) { 175 GTEST_LOG_(WARNING) << "Skipping test due to missing IPv4 support."; 176 return; 177 } 178 Socket *socket; 179 bool child_processes_inherit = false; 180 auto error = 181 UDPSocket::Connect("127.0.0.1:0", child_processes_inherit, socket); 182 183 llvm::StringRef scheme; 184 llvm::StringRef hostname; 185 int port; 186 llvm::StringRef path; 187 std::string uri(socket->GetRemoteConnectionURI()); 188 EXPECT_TRUE(UriParser::Parse(uri, scheme, hostname, port, path)); 189 EXPECT_EQ(scheme, "udp"); 190 } 191 192 #if LLDB_ENABLE_POSIX 193 TEST_F(SocketTest, DomainGetConnectURI) { 194 llvm::SmallString<64> domain_path; 195 std::error_code EC = 196 llvm::sys::fs::createUniqueDirectory("DomainListenConnectAccept", domain_path); 197 ASSERT_FALSE(EC); 198 llvm::sys::path::append(domain_path, "test"); 199 200 // Skip the test if the $TMPDIR is too long to hold a domain socket. 201 if (domain_path.size() > 107u) 202 return; 203 204 std::unique_ptr<DomainSocket> socket_a_up; 205 std::unique_ptr<DomainSocket> socket_b_up; 206 CreateDomainConnectedSockets(domain_path, &socket_a_up, &socket_b_up); 207 208 llvm::StringRef scheme; 209 llvm::StringRef hostname; 210 int port; 211 llvm::StringRef path; 212 std::string uri(socket_a_up->GetRemoteConnectionURI()); 213 EXPECT_TRUE(UriParser::Parse(uri, scheme, hostname, port, path)); 214 EXPECT_EQ(scheme, "unix-connect"); 215 EXPECT_EQ(path, domain_path); 216 } 217 #endif 218