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 Error *error) { 47 *error = listen_socket->Accept(listen_remote_address, 48 child_processes_inherit, *accept_socket); 49 } 50 51 template <typename SocketType> 52 void CreateConnectedSockets( 53 const char *listen_remote_address, 54 const std::function<std::string(const SocketType &)> &get_connect_addr, 55 std::unique_ptr<SocketType> *a_up, std::unique_ptr<SocketType> *b_up) { 56 bool child_processes_inherit = false; 57 Error error; 58 std::unique_ptr<SocketType> listen_socket_up( 59 new SocketType(child_processes_inherit, error)); 60 EXPECT_FALSE(error.Fail()); 61 error = listen_socket_up->Listen(listen_remote_address, 5); 62 EXPECT_FALSE(error.Fail()); 63 EXPECT_TRUE(listen_socket_up->IsValid()); 64 65 Error accept_error; 66 Socket *accept_socket; 67 std::thread accept_thread(AcceptThread, listen_socket_up.get(), 68 listen_remote_address, child_processes_inherit, 69 &accept_socket, &accept_error); 70 71 std::string connect_remote_address = get_connect_addr(*listen_socket_up); 72 std::unique_ptr<SocketType> connect_socket_up( 73 new SocketType(child_processes_inherit, error)); 74 EXPECT_FALSE(error.Fail()); 75 error = connect_socket_up->Connect(connect_remote_address); 76 EXPECT_FALSE(error.Fail()); 77 EXPECT_TRUE(connect_socket_up->IsValid()); 78 79 a_up->swap(connect_socket_up); 80 EXPECT_TRUE(error.Success()); 81 EXPECT_NE(nullptr, a_up->get()); 82 EXPECT_TRUE((*a_up)->IsValid()); 83 84 accept_thread.join(); 85 b_up->reset(static_cast<SocketType *>(accept_socket)); 86 EXPECT_TRUE(accept_error.Success()); 87 EXPECT_NE(nullptr, b_up->get()); 88 EXPECT_TRUE((*b_up)->IsValid()); 89 90 listen_socket_up.reset(); 91 } 92 }; 93 94 TEST_F(SocketTest, DecodeHostAndPort) { 95 std::string host_str; 96 std::string port_str; 97 int32_t port; 98 Error error; 99 EXPECT_TRUE(Socket::DecodeHostAndPort("localhost:1138", host_str, port_str, 100 port, &error)); 101 EXPECT_STREQ("localhost", host_str.c_str()); 102 EXPECT_STREQ("1138", port_str.c_str()); 103 EXPECT_EQ(1138, port); 104 EXPECT_TRUE(error.Success()); 105 106 EXPECT_FALSE(Socket::DecodeHostAndPort("google.com:65536", host_str, port_str, 107 port, &error)); 108 EXPECT_TRUE(error.Fail()); 109 EXPECT_STREQ("invalid host:port specification: 'google.com:65536'", 110 error.AsCString()); 111 112 EXPECT_FALSE(Socket::DecodeHostAndPort("google.com:-1138", host_str, port_str, 113 port, &error)); 114 EXPECT_TRUE(error.Fail()); 115 EXPECT_STREQ("invalid host:port specification: 'google.com:-1138'", 116 error.AsCString()); 117 118 EXPECT_FALSE(Socket::DecodeHostAndPort("google.com:65536", host_str, port_str, 119 port, &error)); 120 EXPECT_TRUE(error.Fail()); 121 EXPECT_STREQ("invalid host:port specification: 'google.com:65536'", 122 error.AsCString()); 123 124 EXPECT_TRUE( 125 Socket::DecodeHostAndPort("12345", host_str, port_str, port, &error)); 126 EXPECT_STREQ("", host_str.c_str()); 127 EXPECT_STREQ("12345", port_str.c_str()); 128 EXPECT_EQ(12345, port); 129 EXPECT_TRUE(error.Success()); 130 131 EXPECT_TRUE( 132 Socket::DecodeHostAndPort("*:0", host_str, port_str, port, &error)); 133 EXPECT_STREQ("*", host_str.c_str()); 134 EXPECT_STREQ("0", port_str.c_str()); 135 EXPECT_EQ(0, port); 136 EXPECT_TRUE(error.Success()); 137 138 EXPECT_TRUE( 139 Socket::DecodeHostAndPort("*:65535", host_str, port_str, port, &error)); 140 EXPECT_STREQ("*", host_str.c_str()); 141 EXPECT_STREQ("65535", port_str.c_str()); 142 EXPECT_EQ(65535, port); 143 EXPECT_TRUE(error.Success()); 144 } 145 146 #ifndef LLDB_DISABLE_POSIX 147 TEST_F(SocketTest, DomainListenConnectAccept) { 148 char *file_name_str = tempnam(nullptr, nullptr); 149 EXPECT_NE(nullptr, file_name_str); 150 const std::string file_name(file_name_str); 151 free(file_name_str); 152 153 std::unique_ptr<DomainSocket> socket_a_up; 154 std::unique_ptr<DomainSocket> socket_b_up; 155 CreateConnectedSockets<DomainSocket>( 156 file_name.c_str(), [=](const DomainSocket &) { return file_name; }, 157 &socket_a_up, &socket_b_up); 158 } 159 #endif 160 161 TEST_F(SocketTest, TCPListen0ConnectAccept) { 162 std::unique_ptr<TCPSocket> socket_a_up; 163 std::unique_ptr<TCPSocket> socket_b_up; 164 CreateConnectedSockets<TCPSocket>( 165 "127.0.0.1:0", 166 [=](const TCPSocket &s) { 167 char connect_remote_address[64]; 168 snprintf(connect_remote_address, sizeof(connect_remote_address), 169 "localhost:%u", s.GetLocalPortNumber()); 170 return std::string(connect_remote_address); 171 }, 172 &socket_a_up, &socket_b_up); 173 } 174 175 TEST_F(SocketTest, TCPGetAddress) { 176 std::unique_ptr<TCPSocket> socket_a_up; 177 std::unique_ptr<TCPSocket> socket_b_up; 178 CreateConnectedSockets<TCPSocket>( 179 "127.0.0.1:0", 180 [=](const TCPSocket &s) { 181 char connect_remote_address[64]; 182 snprintf(connect_remote_address, sizeof(connect_remote_address), 183 "localhost:%u", s.GetLocalPortNumber()); 184 return std::string(connect_remote_address); 185 }, 186 &socket_a_up, &socket_b_up); 187 188 EXPECT_EQ(socket_a_up->GetLocalPortNumber(), 189 socket_b_up->GetRemotePortNumber()); 190 EXPECT_EQ(socket_b_up->GetLocalPortNumber(), 191 socket_a_up->GetRemotePortNumber()); 192 EXPECT_NE(socket_a_up->GetLocalPortNumber(), 193 socket_b_up->GetLocalPortNumber()); 194 EXPECT_STREQ("127.0.0.1", socket_a_up->GetRemoteIPAddress().c_str()); 195 EXPECT_STREQ("127.0.0.1", socket_b_up->GetRemoteIPAddress().c_str()); 196 } 197 198 TEST_F(SocketTest, UDPConnect) { 199 Socket *socket; 200 201 bool child_processes_inherit = false; 202 auto error = UDPSocket::Connect("127.0.0.1:0", child_processes_inherit, 203 socket); 204 205 std::unique_ptr<Socket> socket_up(socket); 206 207 EXPECT_TRUE(error.Success()); 208 EXPECT_TRUE(socket_up->IsValid()); 209 } 210