]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - unittests/debugserver/RNBSocketTest.cpp
Vendor import of lldb trunk r351319 (just before the release_80 branch
[FreeBSD/FreeBSD.git] / unittests / debugserver / RNBSocketTest.cpp
1 //===-- RNBSocketTest.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 "gtest/gtest.h"
11
12 #include <arpa/inet.h>
13 #include <sys/sysctl.h>
14 #include <unistd.h>
15
16 #include "RNBDefs.h"
17 #include "RNBSocket.h"
18 #include "lldb/Host/Socket.h"
19 #include "lldb/Host/StringConvert.h"
20 #include "lldb/Host/common/TCPSocket.h"
21
22 using namespace lldb_private;
23
24 std::string hello = "Hello, world!";
25 std::string goodbye = "Goodbye!";
26
27 static void ServerCallbackv4(const void *baton, in_port_t port) {
28   auto child_pid = fork();
29   if (child_pid == 0) {
30     Socket *client_socket;
31     char addr_buffer[256];
32     sprintf(addr_buffer, "%s:%d", baton, port);
33     Status err = Socket::TcpConnect(addr_buffer, false, client_socket);
34     if (err.Fail())
35       abort();
36     char buffer[32];
37     size_t read_size = 32;
38     err = client_socket->Read((void *)&buffer[0], read_size);
39     if (err.Fail())
40       abort();
41     std::string Recv(&buffer[0], read_size);
42     if (Recv != hello)
43       abort();
44     size_t write_size = goodbye.length();
45     err = client_socket->Write(goodbye.c_str(), write_size);
46     if (err.Fail())
47       abort();
48     if (write_size != goodbye.length())
49       abort();
50     delete client_socket;
51     exit(0);
52   }
53 }
54
55 void TestSocketListen(const char *addr) {
56   // Skip IPv6 tests if there isn't a valid interafce
57   auto addresses = lldb_private::SocketAddress::GetAddressInfo(
58       addr, NULL, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
59   if (addresses.size() == 0)
60     return;
61
62   char addr_wrap[256];
63   if (addresses.front().GetFamily() == AF_INET6)
64     sprintf(addr_wrap, "[%s]", addr);
65   else
66     sprintf(addr_wrap, "%s", addr);
67
68   RNBSocket server_socket;
69   auto result =
70       server_socket.Listen(addr, 0, ServerCallbackv4, (const void *)addr_wrap);
71   ASSERT_TRUE(result == rnb_success);
72   result = server_socket.Write(hello.c_str(), hello.length());
73   ASSERT_TRUE(result == rnb_success);
74   std::string bye;
75   result = server_socket.Read(bye);
76   ASSERT_TRUE(result == rnb_success);
77   ASSERT_EQ(bye, goodbye);
78
79   int exit_status;
80   wait(&exit_status);
81   ASSERT_EQ(exit_status, 0);
82 }
83
84 TEST(RNBSocket, LoopBackListenIPv4) { TestSocketListen("127.0.0.1"); }
85
86 TEST(RNBSocket, LoopBackListenIPv6) { TestSocketListen("::1"); }
87
88 TEST(RNBSocket, AnyListen) { TestSocketListen("*"); }
89
90 void TestSocketConnect(const char *addr) {
91   // Skip IPv6 tests if there isn't a valid interafce
92   auto addresses = lldb_private::SocketAddress::GetAddressInfo(
93       addr, NULL, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
94   if (addresses.size() == 0)
95     return;
96
97   char addr_wrap[256];
98   if (addresses.front().GetFamily() == AF_INET6)
99     sprintf(addr_wrap, "[%s]:0", addr);
100   else
101     sprintf(addr_wrap, "%s:0", addr);
102
103   Socket *server_socket;
104   Predicate<uint16_t> port_predicate;
105   port_predicate.SetValue(0, eBroadcastNever);
106   Status err =
107       Socket::TcpListen(addr_wrap, false, server_socket, &port_predicate);
108   ASSERT_FALSE(err.Fail());
109
110   auto port = ((TCPSocket *)server_socket)->GetLocalPortNumber();
111   auto child_pid = fork();
112   if (child_pid != 0) {
113     RNBSocket client_socket;
114     auto result = client_socket.Connect(addr, port);
115     ASSERT_TRUE(result == rnb_success);
116     result = client_socket.Write(hello.c_str(), hello.length());
117     ASSERT_TRUE(result == rnb_success);
118     std::string bye;
119     result = client_socket.Read(bye);
120     ASSERT_TRUE(result == rnb_success);
121     ASSERT_EQ(bye, goodbye);
122   } else {
123     Socket *connected_socket;
124     err = server_socket->Accept(connected_socket);
125     if (err.Fail()) {
126       llvm::errs() << err.AsCString();
127       abort();
128     }
129     char buffer[32];
130     size_t read_size = 32;
131     err = connected_socket->Read((void *)&buffer[0], read_size);
132     if (err.Fail()) {
133       llvm::errs() << err.AsCString();
134       abort();
135     }
136     std::string Recv(&buffer[0], read_size);
137     if (Recv != hello) {
138       llvm::errs() << err.AsCString();
139       abort();
140     }
141     size_t write_size = goodbye.length();
142     err = connected_socket->Write(goodbye.c_str(), write_size);
143     if (err.Fail()) {
144       llvm::errs() << err.AsCString();
145       abort();
146     }
147     if (write_size != goodbye.length()) {
148       llvm::errs() << err.AsCString();
149       abort();
150     }
151     exit(0);
152   }
153   int exit_status;
154   wait(&exit_status);
155   ASSERT_EQ(exit_status, 0);
156 }
157
158 TEST(RNBSocket, LoopBackConnectIPv4) { TestSocketConnect("127.0.0.1"); }
159
160 TEST(RNBSocket, LoopBackConnectIPv6) { TestSocketConnect("::1"); }