1 //===-- SocketTest.cpp ------------------------------------------*- C++ -*-===// 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 "lldb/Utility/UriParser.h" 11 #include "gtest/gtest.h" 12 13 using namespace lldb_private; 14 15 class SocketTest : public testing::Test { 16 public: 17 void SetUp() override { 18 ASSERT_THAT_ERROR(Socket::Initialize(), llvm::Succeeded()); 19 } 20 21 void TearDown() override { Socket::Terminate(); } 22 }; 23 24 TEST_F(SocketTest, DecodeHostAndPort) { 25 std::string host_str; 26 std::string port_str; 27 int32_t port; 28 Status error; 29 EXPECT_TRUE(Socket::DecodeHostAndPort("localhost:1138", host_str, port_str, 30 port, &error)); 31 EXPECT_STREQ("localhost", host_str.c_str()); 32 EXPECT_STREQ("1138", port_str.c_str()); 33 EXPECT_EQ(1138, port); 34 EXPECT_TRUE(error.Success()); 35 36 EXPECT_FALSE(Socket::DecodeHostAndPort("google.com:65536", host_str, port_str, 37 port, &error)); 38 EXPECT_TRUE(error.Fail()); 39 EXPECT_STREQ("invalid host:port specification: 'google.com:65536'", 40 error.AsCString()); 41 42 EXPECT_FALSE(Socket::DecodeHostAndPort("google.com:-1138", host_str, port_str, 43 port, &error)); 44 EXPECT_TRUE(error.Fail()); 45 EXPECT_STREQ("invalid host:port specification: 'google.com:-1138'", 46 error.AsCString()); 47 48 EXPECT_FALSE(Socket::DecodeHostAndPort("google.com:65536", host_str, port_str, 49 port, &error)); 50 EXPECT_TRUE(error.Fail()); 51 EXPECT_STREQ("invalid host:port specification: 'google.com:65536'", 52 error.AsCString()); 53 54 EXPECT_TRUE( 55 Socket::DecodeHostAndPort("12345", host_str, port_str, port, &error)); 56 EXPECT_STREQ("", host_str.c_str()); 57 EXPECT_STREQ("12345", port_str.c_str()); 58 EXPECT_EQ(12345, port); 59 EXPECT_TRUE(error.Success()); 60 61 EXPECT_TRUE( 62 Socket::DecodeHostAndPort("*:0", host_str, port_str, port, &error)); 63 EXPECT_STREQ("*", host_str.c_str()); 64 EXPECT_STREQ("0", port_str.c_str()); 65 EXPECT_EQ(0, port); 66 EXPECT_TRUE(error.Success()); 67 68 EXPECT_TRUE( 69 Socket::DecodeHostAndPort("*:65535", host_str, port_str, port, &error)); 70 EXPECT_STREQ("*", host_str.c_str()); 71 EXPECT_STREQ("65535", port_str.c_str()); 72 EXPECT_EQ(65535, port); 73 EXPECT_TRUE(error.Success()); 74 75 EXPECT_TRUE( 76 Socket::DecodeHostAndPort("[::1]:12345", host_str, port_str, port, &error)); 77 EXPECT_STREQ("::1", host_str.c_str()); 78 EXPECT_STREQ("12345", port_str.c_str()); 79 EXPECT_EQ(12345, port); 80 EXPECT_TRUE(error.Success()); 81 82 EXPECT_TRUE( 83 Socket::DecodeHostAndPort("[abcd:12fg:AF58::1]:12345", host_str, port_str, port, &error)); 84 EXPECT_STREQ("abcd:12fg:AF58::1", host_str.c_str()); 85 EXPECT_STREQ("12345", port_str.c_str()); 86 EXPECT_EQ(12345, port); 87 EXPECT_TRUE(error.Success()); 88 } 89 90 #ifndef LLDB_DISABLE_POSIX 91 TEST_F(SocketTest, DomainListenConnectAccept) { 92 llvm::SmallString<64> Path; 93 std::error_code EC = llvm::sys::fs::createUniqueDirectory("DomainListenConnectAccept", Path); 94 ASSERT_FALSE(EC); 95 llvm::sys::path::append(Path, "test"); 96 97 std::unique_ptr<DomainSocket> socket_a_up; 98 std::unique_ptr<DomainSocket> socket_b_up; 99 CreateDomainConnectedSockets(Path, &socket_a_up, &socket_b_up); 100 } 101 #endif 102 103 TEST_F(SocketTest, TCPListen0ConnectAccept) { 104 std::unique_ptr<TCPSocket> socket_a_up; 105 std::unique_ptr<TCPSocket> socket_b_up; 106 CreateTCPConnectedSockets("127.0.0.1", &socket_a_up, &socket_b_up); 107 } 108 109 TEST_F(SocketTest, TCPGetAddress) { 110 std::unique_ptr<TCPSocket> socket_a_up; 111 std::unique_ptr<TCPSocket> socket_b_up; 112 if (!IsAddressFamilySupported("127.0.0.1")) { 113 GTEST_LOG_(WARNING) << "Skipping test due to missing IPv4 support."; 114 return; 115 } 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 Socket *socket; 130 131 bool child_processes_inherit = false; 132 auto error = UDPSocket::Connect("127.0.0.1:0", child_processes_inherit, 133 socket); 134 135 std::unique_ptr<Socket> socket_up(socket); 136 137 EXPECT_TRUE(error.Success()); 138 EXPECT_TRUE(socket_up->IsValid()); 139 } 140 141 TEST_F(SocketTest, TCPListen0GetPort) { 142 Socket *server_socket; 143 Predicate<uint16_t> port_predicate; 144 port_predicate.SetValue(0, eBroadcastNever); 145 Status err = 146 Socket::TcpListen("10.10.12.3:0", false, server_socket, &port_predicate); 147 std::unique_ptr<TCPSocket> socket_up((TCPSocket*)server_socket); 148 EXPECT_TRUE(socket_up->IsValid()); 149 EXPECT_NE(socket_up->GetLocalPortNumber(), 0); 150 } 151 152 TEST_F(SocketTest, TCPGetConnectURI) { 153 std::unique_ptr<TCPSocket> socket_a_up; 154 std::unique_ptr<TCPSocket> socket_b_up; 155 if (!IsAddressFamilySupported("127.0.0.1")) { 156 GTEST_LOG_(WARNING) << "Skipping test due to missing IPv4 support."; 157 return; 158 } 159 CreateTCPConnectedSockets("127.0.0.1", &socket_a_up, &socket_b_up); 160 161 llvm::StringRef scheme; 162 llvm::StringRef hostname; 163 int port; 164 llvm::StringRef path; 165 std::string uri(socket_a_up->GetRemoteConnectionURI()); 166 EXPECT_TRUE(UriParser::Parse(uri, scheme, hostname, port, path)); 167 EXPECT_EQ(scheme, "connect"); 168 EXPECT_EQ(port, socket_a_up->GetRemotePortNumber()); 169 } 170 171 TEST_F(SocketTest, UDPGetConnectURI) { 172 if (!IsAddressFamilySupported("127.0.0.1")) { 173 GTEST_LOG_(WARNING) << "Skipping test due to missing IPv4 support."; 174 return; 175 } 176 Socket *socket; 177 bool child_processes_inherit = false; 178 auto error = 179 UDPSocket::Connect("127.0.0.1:0", child_processes_inherit, socket); 180 181 llvm::StringRef scheme; 182 llvm::StringRef hostname; 183 int port; 184 llvm::StringRef path; 185 std::string uri(socket->GetRemoteConnectionURI()); 186 EXPECT_TRUE(UriParser::Parse(uri, scheme, hostname, port, path)); 187 EXPECT_EQ(scheme, "udp"); 188 } 189 190 #ifndef LLDB_DISABLE_POSIX 191 TEST_F(SocketTest, DomainGetConnectURI) { 192 llvm::SmallString<64> domain_path; 193 std::error_code EC = 194 llvm::sys::fs::createUniqueDirectory("DomainListenConnectAccept", domain_path); 195 ASSERT_FALSE(EC); 196 llvm::sys::path::append(domain_path, "test"); 197 198 std::unique_ptr<DomainSocket> socket_a_up; 199 std::unique_ptr<DomainSocket> socket_b_up; 200 CreateDomainConnectedSockets(domain_path, &socket_a_up, &socket_b_up); 201 202 llvm::StringRef scheme; 203 llvm::StringRef hostname; 204 int port; 205 llvm::StringRef path; 206 std::string uri(socket_a_up->GetRemoteConnectionURI()); 207 EXPECT_TRUE(UriParser::Parse(uri, scheme, hostname, port, path)); 208 EXPECT_EQ(scheme, "unix-connect"); 209 EXPECT_EQ(path, domain_path); 210 } 211 #endif