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 #if defined(_MSC_VER) && (_HAS_EXCEPTIONS == 0) 11 // Workaround for MSVC standard library bug, which fails to include <thread> when 12 // exceptions are disabled. 13 #include <eh.h> 14 #endif 15 16 #include <cstdio> 17 #include <functional> 18 #include <thread> 19 20 #include "gtest/gtest.h" 21 22 #include "lldb/Host/Config.h" 23 #include "lldb/Host/Socket.h" 24 #include "lldb/Host/common/TCPSocket.h" 25 #include "lldb/Host/common/UDPSocket.h" 26 27 #ifndef LLDB_DISABLE_POSIX 28 #include "lldb/Host/posix/DomainSocket.h" 29 #endif 30 31 using namespace lldb_private; 32 33 class SocketTest : public testing::Test 34 { 35 public: 36 void 37 SetUp() override 38 { 39 #if defined(_MSC_VER) 40 WSADATA data; 41 ::WSAStartup(MAKEWORD(2, 2), &data); 42 #endif 43 } 44 45 void 46 TearDown() override 47 { 48 #if defined(_MSC_VER) 49 ::WSACleanup(); 50 #endif 51 } 52 53 protected: 54 static void 55 AcceptThread(Socket *listen_socket, const char *listen_remote_address, bool child_processes_inherit, 56 Socket **accept_socket, Error *error) 57 { 58 *error = listen_socket->Accept(listen_remote_address, child_processes_inherit, *accept_socket); 59 } 60 61 template<typename SocketType> 62 void 63 CreateConnectedSockets(const char *listen_remote_address, const std::function<std::string(const SocketType&)> &get_connect_addr, std::unique_ptr<SocketType> *a_up, std::unique_ptr<SocketType> *b_up) 64 { 65 bool child_processes_inherit = false; 66 Error error; 67 std::unique_ptr<SocketType> listen_socket_up(new SocketType(child_processes_inherit, error)); 68 EXPECT_FALSE(error.Fail()); 69 error = listen_socket_up->Listen(listen_remote_address, 5); 70 EXPECT_FALSE(error.Fail()); 71 EXPECT_TRUE(listen_socket_up->IsValid()); 72 73 Error accept_error; 74 Socket *accept_socket; 75 std::thread accept_thread(AcceptThread, listen_socket_up.get(), listen_remote_address, child_processes_inherit, 76 &accept_socket, &accept_error); 77 78 std::string connect_remote_address = get_connect_addr(*listen_socket_up); 79 std::unique_ptr<SocketType> connect_socket_up(new SocketType(child_processes_inherit, error)); 80 EXPECT_FALSE(error.Fail()); 81 error = connect_socket_up->Connect(connect_remote_address.c_str()); 82 EXPECT_FALSE(error.Fail()); 83 EXPECT_TRUE(connect_socket_up->IsValid()); 84 85 a_up->swap(connect_socket_up); 86 EXPECT_TRUE(error.Success()); 87 EXPECT_NE(nullptr, a_up->get()); 88 EXPECT_TRUE((*a_up)->IsValid()); 89 90 accept_thread.join(); 91 b_up->reset(static_cast<SocketType*>(accept_socket)); 92 EXPECT_TRUE(accept_error.Success()); 93 EXPECT_NE(nullptr, b_up->get()); 94 EXPECT_TRUE((*b_up)->IsValid()); 95 96 listen_socket_up.reset(); 97 } 98 }; 99 100 TEST_F (SocketTest, DecodeHostAndPort) 101 { 102 std::string host_str; 103 std::string port_str; 104 int32_t port; 105 Error error; 106 EXPECT_TRUE (Socket::DecodeHostAndPort ("localhost:1138", host_str, port_str, port, &error)); 107 EXPECT_STREQ ("localhost", host_str.c_str ()); 108 EXPECT_STREQ ("1138", port_str.c_str ()); 109 EXPECT_EQ (1138, port); 110 EXPECT_TRUE (error.Success ()); 111 112 EXPECT_FALSE (Socket::DecodeHostAndPort ("google.com:65536", host_str, port_str, port, &error)); 113 EXPECT_TRUE (error.Fail ()); 114 EXPECT_STREQ ("invalid host:port specification: 'google.com:65536'", error.AsCString ()); 115 116 EXPECT_FALSE (Socket::DecodeHostAndPort ("google.com:-1138", host_str, port_str, port, &error)); 117 EXPECT_TRUE (error.Fail ()); 118 EXPECT_STREQ ("invalid host:port specification: 'google.com:-1138'", error.AsCString ()); 119 120 EXPECT_FALSE(Socket::DecodeHostAndPort("google.com:65536", host_str, port_str, port, &error)); 121 EXPECT_TRUE(error.Fail()); 122 EXPECT_STREQ("invalid host:port specification: 'google.com:65536'", error.AsCString()); 123 124 EXPECT_TRUE (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 (Socket::DecodeHostAndPort ("*:0", host_str, port_str, port, &error)); 131 EXPECT_STREQ ("*", host_str.c_str ()); 132 EXPECT_STREQ ("0", port_str.c_str ()); 133 EXPECT_EQ (0, port); 134 EXPECT_TRUE (error.Success ()); 135 136 EXPECT_TRUE(Socket::DecodeHostAndPort("*:65535", host_str, port_str, port, &error)); 137 EXPECT_STREQ("*", host_str.c_str()); 138 EXPECT_STREQ("65535", port_str.c_str()); 139 EXPECT_EQ(65535, port); 140 EXPECT_TRUE(error.Success()); 141 } 142 143 #ifndef LLDB_DISABLE_POSIX 144 TEST_F (SocketTest, DomainListenConnectAccept) 145 { 146 char* file_name_str = tempnam(nullptr, nullptr); 147 EXPECT_NE (nullptr, file_name_str); 148 const std::string file_name(file_name_str); 149 free(file_name_str); 150 151 std::unique_ptr<DomainSocket> socket_a_up; 152 std::unique_ptr<DomainSocket> socket_b_up; 153 CreateConnectedSockets<DomainSocket>(file_name.c_str(), 154 [=](const DomainSocket &) 155 { 156 return file_name; 157 }, 158 &socket_a_up, &socket_b_up); 159 } 160 #endif 161 162 TEST_F (SocketTest, TCPListen0ConnectAccept) 163 { 164 std::unique_ptr<TCPSocket> socket_a_up; 165 std::unique_ptr<TCPSocket> socket_b_up; 166 CreateConnectedSockets<TCPSocket>("127.0.0.1:0", 167 [=](const TCPSocket &s) 168 { 169 char connect_remote_address[64]; 170 snprintf(connect_remote_address, sizeof(connect_remote_address), "localhost:%u", s.GetLocalPortNumber()); 171 return std::string(connect_remote_address); 172 }, 173 &socket_a_up, &socket_b_up); 174 } 175 176 TEST_F (SocketTest, TCPGetAddress) 177 { 178 std::unique_ptr<TCPSocket> socket_a_up; 179 std::unique_ptr<TCPSocket> socket_b_up; 180 CreateConnectedSockets<TCPSocket>("127.0.0.1:0", 181 [=](const TCPSocket &s) 182 { 183 char connect_remote_address[64]; 184 snprintf(connect_remote_address, sizeof(connect_remote_address), "localhost:%u", s.GetLocalPortNumber()); 185 return std::string(connect_remote_address); 186 }, 187 &socket_a_up, 188 &socket_b_up); 189 190 EXPECT_EQ (socket_a_up->GetLocalPortNumber (), socket_b_up->GetRemotePortNumber ()); 191 EXPECT_EQ (socket_b_up->GetLocalPortNumber (), socket_a_up->GetRemotePortNumber ()); 192 EXPECT_NE (socket_a_up->GetLocalPortNumber (), socket_b_up->GetLocalPortNumber ()); 193 EXPECT_STREQ ("127.0.0.1", socket_a_up->GetRemoteIPAddress ().c_str ()); 194 EXPECT_STREQ ("127.0.0.1", socket_b_up->GetRemoteIPAddress ().c_str ()); 195 } 196 197 TEST_F (SocketTest, UDPConnect) 198 { 199 Socket* socket_a; 200 Socket* socket_b; 201 202 bool child_processes_inherit = false; 203 auto error = UDPSocket::Connect("127.0.0.1:0", child_processes_inherit, socket_a, socket_b); 204 205 std::unique_ptr<Socket> a_up(socket_a); 206 std::unique_ptr<Socket> b_up(socket_b); 207 208 EXPECT_TRUE(error.Success ()); 209 EXPECT_TRUE(a_up->IsValid()); 210 EXPECT_TRUE(b_up->IsValid()); 211 } 212