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 <thread>
17 
18 #include "gtest/gtest.h"
19 
20 #include "lldb/Host/Socket.h"
21 
22 using namespace lldb_private;
23 
24 class SocketTest : public testing::Test
25 {
26   public:
27     void
28     SetUp() override
29     {
30 #if defined(_MSC_VER)
31         WSADATA data;
32         ::WSAStartup(MAKEWORD(2, 2), &data);
33 #endif
34     }
35 
36     void
37     TearDown() override
38     {
39 #if defined(_MSC_VER)
40         ::WSACleanup();
41 #endif
42     }
43 
44   protected:
45     static void
46     AcceptThread(Socket *listen_socket, const char *listen_remote_address, bool child_processes_inherit,
47                  Socket **accept_socket, Error *error)
48     {
49         *error = listen_socket->BlockingAccept(listen_remote_address, child_processes_inherit, *accept_socket);
50     }
51 
52     void
53     CreateConnectedSockets(std::unique_ptr<Socket> *a_up, std::unique_ptr<Socket> *b_up)
54     {
55         Predicate<uint16_t> port_predicate;
56         // Used when binding to port zero to wait for the thread
57         // that creates the socket, binds and listens to resolve
58         // the port number.
59 
60         port_predicate.SetValue(0, eBroadcastNever);
61 
62         bool child_processes_inherit = false;
63         Socket *socket = nullptr;
64         const char *listen_remote_address = "localhost:0";
65         Error error = Socket::TcpListen(listen_remote_address, child_processes_inherit, socket, &port_predicate);
66         std::unique_ptr<Socket> listen_socket_up(socket);
67         socket = nullptr;
68         EXPECT_FALSE(error.Fail());
69         EXPECT_NE(nullptr, listen_socket_up.get());
70         EXPECT_TRUE(listen_socket_up->IsValid());
71 
72         Error accept_error;
73         Socket *accept_socket;
74         std::thread accept_thread(AcceptThread, listen_socket_up.get(), listen_remote_address, child_processes_inherit,
75                                   &accept_socket, &accept_error);
76 
77         char connect_remote_address[64];
78         snprintf(connect_remote_address, sizeof(connect_remote_address), "localhost:%u", port_predicate.GetValue());
79         error = Socket::TcpConnect(connect_remote_address, child_processes_inherit, socket);
80         a_up->reset(socket);
81         socket = nullptr;
82         EXPECT_TRUE(error.Success());
83         EXPECT_NE(nullptr, a_up->get());
84         EXPECT_TRUE((*a_up)->IsValid());
85 
86         accept_thread.join();
87         b_up->reset(accept_socket);
88         EXPECT_TRUE(accept_error.Success());
89         EXPECT_NE(nullptr, b_up->get());
90         EXPECT_TRUE((*b_up)->IsValid());
91 
92         listen_socket_up.reset();
93     }
94 };
95 
96 TEST_F (SocketTest, DecodeHostAndPort)
97 {
98     std::string host_str;
99     std::string port_str;
100     int32_t port;
101     Error error;
102     EXPECT_TRUE (Socket::DecodeHostAndPort ("localhost:1138", host_str, port_str, port, &error));
103     EXPECT_STREQ ("localhost", host_str.c_str ());
104     EXPECT_STREQ ("1138", port_str.c_str ());
105     EXPECT_EQ (1138, port);
106     EXPECT_TRUE (error.Success ());
107 
108     EXPECT_FALSE (Socket::DecodeHostAndPort ("google.com:65536", host_str, port_str, port, &error));
109     EXPECT_TRUE (error.Fail ());
110     EXPECT_STREQ ("invalid host:port specification: 'google.com:65536'", error.AsCString ());
111 
112     EXPECT_FALSE (Socket::DecodeHostAndPort ("google.com:-1138", host_str, port_str, port, &error));
113     EXPECT_TRUE (error.Fail ());
114     EXPECT_STREQ ("invalid host:port specification: 'google.com:-1138'", error.AsCString ());
115 
116     EXPECT_TRUE (Socket::DecodeHostAndPort ("12345", host_str, port_str, port, &error));
117     EXPECT_STREQ ("", host_str.c_str ());
118     EXPECT_STREQ ("12345", port_str.c_str ());
119     EXPECT_EQ (12345, port);
120     EXPECT_TRUE (error.Success ());
121 
122     EXPECT_TRUE (Socket::DecodeHostAndPort ("*:0", host_str, port_str, port, &error));
123     EXPECT_STREQ ("*", host_str.c_str ());
124     EXPECT_STREQ ("0", port_str.c_str ());
125     EXPECT_EQ (0, port);
126     EXPECT_TRUE (error.Success ());
127 
128 }
129 
130 TEST_F (SocketTest, Listen0ConnectAccept)
131 {
132     std::unique_ptr<Socket> socket_a_up;
133     std::unique_ptr<Socket> socket_b_up;
134     CreateConnectedSockets (&socket_a_up, &socket_b_up);
135 }
136 
137 TEST_F (SocketTest, GetAddress)
138 {
139     std::unique_ptr<Socket> socket_a_up;
140     std::unique_ptr<Socket> socket_b_up;
141     CreateConnectedSockets (&socket_a_up, &socket_b_up);
142 
143     EXPECT_EQ (socket_a_up->GetLocalPortNumber (), socket_b_up->GetRemotePortNumber ());
144     EXPECT_EQ (socket_b_up->GetLocalPortNumber (), socket_a_up->GetRemotePortNumber ());
145     EXPECT_NE (socket_a_up->GetLocalPortNumber (), socket_b_up->GetLocalPortNumber ());
146     EXPECT_STREQ ("127.0.0.1", socket_a_up->GetRemoteIPAddress ().c_str ());
147     EXPECT_STREQ ("127.0.0.1", socket_b_up->GetRemoteIPAddress ().c_str ());
148 }
149