1 //===-- SocketTest.cpp ------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include <cstdio> 11 #include <functional> 12 #include <thread> 13 14 #include "gtest/gtest.h" 15 16 #include "lldb/Host/Config.h" 17 #include "lldb/Host/Socket.h" 18 #include "lldb/Host/common/TCPSocket.h" 19 #include "lldb/Host/common/UDPSocket.h" 20 21 #ifndef LLDB_DISABLE_POSIX 22 #include "lldb/Host/posix/DomainSocket.h" 23 #endif 24 25 using namespace lldb_private; 26 27 class SocketTest : public testing::Test { 28 public: 29 void SetUp() override { 30 #if defined(_MSC_VER) 31 WSADATA data; 32 ::WSAStartup(MAKEWORD(2, 2), &data); 33 #endif 34 } 35 36 void TearDown() override { 37 #if defined(_MSC_VER) 38 ::WSACleanup(); 39 #endif 40 } 41 42 protected: 43 static void AcceptThread(Socket *listen_socket, 44 const char *listen_remote_address, 45 bool child_processes_inherit, Socket **accept_socket, 46 Status *error) { 47 *error = listen_socket->Accept(*accept_socket); 48 } 49 50 template <typename SocketType> 51 void CreateConnectedSockets( 52 const char *listen_remote_address, 53 const std::function<std::string(const SocketType &)> &get_connect_addr, 54 std::unique_ptr<SocketType> *a_up, std::unique_ptr<SocketType> *b_up) { 55 bool child_processes_inherit = false; 56 Status error; 57 std::unique_ptr<SocketType> listen_socket_up( 58 new SocketType(true, child_processes_inherit)); 59 EXPECT_FALSE(error.Fail()); 60 error = listen_socket_up->Listen(listen_remote_address, 5); 61 EXPECT_FALSE(error.Fail()); 62 EXPECT_TRUE(listen_socket_up->IsValid()); 63 64 Status accept_error; 65 Socket *accept_socket; 66 std::thread accept_thread(AcceptThread, listen_socket_up.get(), 67 listen_remote_address, child_processes_inherit, 68 &accept_socket, &accept_error); 69 70 std::string connect_remote_address = get_connect_addr(*listen_socket_up); 71 std::unique_ptr<SocketType> connect_socket_up( 72 new SocketType(true, child_processes_inherit)); 73 EXPECT_FALSE(error.Fail()); 74 error = connect_socket_up->Connect(connect_remote_address); 75 EXPECT_FALSE(error.Fail()); 76 EXPECT_TRUE(connect_socket_up->IsValid()); 77 78 a_up->swap(connect_socket_up); 79 EXPECT_TRUE(error.Success()); 80 EXPECT_NE(nullptr, a_up->get()); 81 EXPECT_TRUE((*a_up)->IsValid()); 82 83 accept_thread.join(); 84 b_up->reset(static_cast<SocketType *>(accept_socket)); 85 EXPECT_TRUE(accept_error.Success()); 86 EXPECT_NE(nullptr, b_up->get()); 87 EXPECT_TRUE((*b_up)->IsValid()); 88 89 listen_socket_up.reset(); 90 } 91 }; 92 93 TEST_F(SocketTest, DecodeHostAndPort) { 94 std::string host_str; 95 std::string port_str; 96 int32_t port; 97 Status error; 98 EXPECT_TRUE(Socket::DecodeHostAndPort("localhost:1138", host_str, port_str, 99 port, &error)); 100 EXPECT_STREQ("localhost", host_str.c_str()); 101 EXPECT_STREQ("1138", port_str.c_str()); 102 EXPECT_EQ(1138, port); 103 EXPECT_TRUE(error.Success()); 104 105 EXPECT_FALSE(Socket::DecodeHostAndPort("google.com:65536", host_str, port_str, 106 port, &error)); 107 EXPECT_TRUE(error.Fail()); 108 EXPECT_STREQ("invalid host:port specification: 'google.com:65536'", 109 error.AsCString()); 110 111 EXPECT_FALSE(Socket::DecodeHostAndPort("google.com:-1138", host_str, port_str, 112 port, &error)); 113 EXPECT_TRUE(error.Fail()); 114 EXPECT_STREQ("invalid host:port specification: 'google.com:-1138'", 115 error.AsCString()); 116 117 EXPECT_FALSE(Socket::DecodeHostAndPort("google.com:65536", host_str, port_str, 118 port, &error)); 119 EXPECT_TRUE(error.Fail()); 120 EXPECT_STREQ("invalid host:port specification: 'google.com:65536'", 121 error.AsCString()); 122 123 EXPECT_TRUE( 124 Socket::DecodeHostAndPort("12345", host_str, port_str, port, &error)); 125 EXPECT_STREQ("", host_str.c_str()); 126 EXPECT_STREQ("12345", port_str.c_str()); 127 EXPECT_EQ(12345, port); 128 EXPECT_TRUE(error.Success()); 129 130 EXPECT_TRUE( 131 Socket::DecodeHostAndPort("*:0", host_str, port_str, port, &error)); 132 EXPECT_STREQ("*", host_str.c_str()); 133 EXPECT_STREQ("0", port_str.c_str()); 134 EXPECT_EQ(0, port); 135 EXPECT_TRUE(error.Success()); 136 137 EXPECT_TRUE( 138 Socket::DecodeHostAndPort("*:65535", host_str, port_str, port, &error)); 139 EXPECT_STREQ("*", host_str.c_str()); 140 EXPECT_STREQ("65535", port_str.c_str()); 141 EXPECT_EQ(65535, port); 142 EXPECT_TRUE(error.Success()); 143 144 EXPECT_TRUE( 145 Socket::DecodeHostAndPort("[::1]:12345", host_str, port_str, port, &error)); 146 EXPECT_STREQ("::1", host_str.c_str()); 147 EXPECT_STREQ("12345", port_str.c_str()); 148 EXPECT_EQ(12345, port); 149 EXPECT_TRUE(error.Success()); 150 151 EXPECT_TRUE( 152 Socket::DecodeHostAndPort("[abcd:12fg:AF58::1]:12345", host_str, port_str, port, &error)); 153 EXPECT_STREQ("abcd:12fg:AF58::1", host_str.c_str()); 154 EXPECT_STREQ("12345", port_str.c_str()); 155 EXPECT_EQ(12345, port); 156 EXPECT_TRUE(error.Success()); 157 } 158 159 #ifndef LLDB_DISABLE_POSIX 160 TEST_F(SocketTest, DomainListenConnectAccept) { 161 char *file_name_str = tempnam(nullptr, nullptr); 162 EXPECT_NE(nullptr, file_name_str); 163 const std::string file_name(file_name_str); 164 free(file_name_str); 165 166 std::unique_ptr<DomainSocket> socket_a_up; 167 std::unique_ptr<DomainSocket> socket_b_up; 168 CreateConnectedSockets<DomainSocket>( 169 file_name.c_str(), [=](const DomainSocket &) { return file_name; }, 170 &socket_a_up, &socket_b_up); 171 } 172 #endif 173 174 TEST_F(SocketTest, TCPListen0ConnectAccept) { 175 std::unique_ptr<TCPSocket> socket_a_up; 176 std::unique_ptr<TCPSocket> socket_b_up; 177 CreateConnectedSockets<TCPSocket>( 178 "127.0.0.1:0", 179 [=](const TCPSocket &s) { 180 char connect_remote_address[64]; 181 snprintf(connect_remote_address, sizeof(connect_remote_address), 182 "localhost:%u", s.GetLocalPortNumber()); 183 return std::string(connect_remote_address); 184 }, 185 &socket_a_up, &socket_b_up); 186 } 187 188 TEST_F(SocketTest, TCPGetAddress) { 189 std::unique_ptr<TCPSocket> socket_a_up; 190 std::unique_ptr<TCPSocket> socket_b_up; 191 CreateConnectedSockets<TCPSocket>( 192 "127.0.0.1:0", 193 [=](const TCPSocket &s) { 194 char connect_remote_address[64]; 195 snprintf(connect_remote_address, sizeof(connect_remote_address), 196 "localhost:%u", s.GetLocalPortNumber()); 197 return std::string(connect_remote_address); 198 }, 199 &socket_a_up, &socket_b_up); 200 201 EXPECT_EQ(socket_a_up->GetLocalPortNumber(), 202 socket_b_up->GetRemotePortNumber()); 203 EXPECT_EQ(socket_b_up->GetLocalPortNumber(), 204 socket_a_up->GetRemotePortNumber()); 205 EXPECT_NE(socket_a_up->GetLocalPortNumber(), 206 socket_b_up->GetLocalPortNumber()); 207 EXPECT_STREQ("127.0.0.1", socket_a_up->GetRemoteIPAddress().c_str()); 208 EXPECT_STREQ("127.0.0.1", socket_b_up->GetRemoteIPAddress().c_str()); 209 } 210 211 TEST_F(SocketTest, UDPConnect) { 212 Socket *socket; 213 214 bool child_processes_inherit = false; 215 auto error = UDPSocket::Connect("127.0.0.1:0", child_processes_inherit, 216 socket); 217 218 std::unique_ptr<Socket> socket_up(socket); 219 220 EXPECT_TRUE(error.Success()); 221 EXPECT_TRUE(socket_up->IsValid()); 222 } 223 224 TEST_F(SocketTest, TCPListen0GetPort) { 225 Socket *server_socket; 226 Predicate<uint16_t> port_predicate; 227 port_predicate.SetValue(0, eBroadcastNever); 228 Status err = 229 Socket::TcpListen("10.10.12.3:0", false, server_socket, &port_predicate); 230 std::unique_ptr<TCPSocket> socket_up((TCPSocket*)server_socket); 231 EXPECT_TRUE(socket_up->IsValid()); 232 EXPECT_NE(socket_up->GetLocalPortNumber(), 0); 233 } 234