1 //===-- SocketTest.cpp ------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
14 #include "gtest/gtest.h"
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"
21 #ifndef LLDB_DISABLE_POSIX
22 #include "lldb/Host/posix/DomainSocket.h"
25 using namespace lldb_private;
27 class SocketTest : public testing::Test {
29 void SetUp() override {
32 ::WSAStartup(MAKEWORD(2, 2), &data);
36 void TearDown() override {
43 static void AcceptThread(Socket *listen_socket,
44 const char *listen_remote_address,
45 bool child_processes_inherit, Socket **accept_socket,
47 *error = listen_socket->Accept(*accept_socket);
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;
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());
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);
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());
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());
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());
89 listen_socket_up.reset();
93 TEST_F(SocketTest, DecodeHostAndPort) {
98 EXPECT_TRUE(Socket::DecodeHostAndPort("localhost:1138", host_str, port_str,
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());
105 EXPECT_FALSE(Socket::DecodeHostAndPort("google.com:65536", host_str, port_str,
107 EXPECT_TRUE(error.Fail());
108 EXPECT_STREQ("invalid host:port specification: 'google.com:65536'",
111 EXPECT_FALSE(Socket::DecodeHostAndPort("google.com:-1138", host_str, port_str,
113 EXPECT_TRUE(error.Fail());
114 EXPECT_STREQ("invalid host:port specification: 'google.com:-1138'",
117 EXPECT_FALSE(Socket::DecodeHostAndPort("google.com:65536", host_str, port_str,
119 EXPECT_TRUE(error.Fail());
120 EXPECT_STREQ("invalid host:port specification: 'google.com:65536'",
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());
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());
135 EXPECT_TRUE(error.Success());
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());
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());
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());
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);
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);
174 TEST_F(SocketTest, TCPListen0ConnectAccept) {
175 std::unique_ptr<TCPSocket> socket_a_up;
176 std::unique_ptr<TCPSocket> socket_b_up;
177 CreateConnectedSockets<TCPSocket>(
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);
185 &socket_a_up, &socket_b_up);
188 TEST_F(SocketTest, TCPGetAddress) {
189 std::unique_ptr<TCPSocket> socket_a_up;
190 std::unique_ptr<TCPSocket> socket_b_up;
191 CreateConnectedSockets<TCPSocket>(
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);
199 &socket_a_up, &socket_b_up);
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());
211 TEST_F(SocketTest, UDPConnect) {
214 bool child_processes_inherit = false;
215 auto error = UDPSocket::Connect("127.0.0.1:0", child_processes_inherit,
218 std::unique_ptr<Socket> socket_up(socket);
220 EXPECT_TRUE(error.Success());
221 EXPECT_TRUE(socket_up->IsValid());
224 TEST_F(SocketTest, TCPListen0GetPort) {
225 Socket *server_socket;
226 Predicate<uint16_t> port_predicate;
227 port_predicate.SetValue(0, eBroadcastNever);
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);