1 //===-- RNBSocketTest.cpp -------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "gtest/gtest.h"
11 #include <arpa/inet.h>
12 #include <sys/sysctl.h>
16 #include "RNBSocket.h"
17 #include "lldb/Host/Socket.h"
18 #include "lldb/Host/common/TCPSocket.h"
19 #include "llvm/Testing/Support/Error.h"
21 using namespace lldb_private
;
23 std::string hello
= "Hello, world!";
24 std::string goodbye
= "Goodbye!";
26 static void ServerCallbackv4(const void *baton
, in_port_t port
) {
27 auto child_pid
= fork();
29 char addr_buffer
[256];
30 sprintf(addr_buffer
, "%s:%d", (const char *)baton
, port
);
31 llvm::Expected
<std::unique_ptr
<Socket
>> socket_or_err
=
32 Socket::TcpConnect(addr_buffer
, false);
33 ASSERT_THAT_EXPECTED(socket_or_err
, llvm::Succeeded());
34 Socket
*client_socket
= socket_or_err
->get();
37 size_t read_size
= 32;
38 Status err
= client_socket
->Read((void *)&buffer
[0], read_size
);
41 std::string
Recv(&buffer
[0], read_size
);
44 size_t write_size
= goodbye
.length();
45 err
= client_socket
->Write(goodbye
.c_str(), write_size
);
48 if (write_size
!= goodbye
.length())
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)
63 if (addresses
.front().GetFamily() == AF_INET6
)
64 sprintf(addr_wrap
, "[%s]", addr
);
66 sprintf(addr_wrap
, "%s", addr
);
68 RNBSocket server_socket
;
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
);
75 result
= server_socket
.Read(bye
);
76 ASSERT_TRUE(result
== rnb_success
);
77 ASSERT_EQ(bye
, goodbye
);
81 ASSERT_EQ(exit_status
, 0);
84 TEST(RNBSocket
, LoopBackListenIPv4
) { TestSocketListen("127.0.0.1"); }
86 TEST(RNBSocket
, LoopBackListenIPv6
) { TestSocketListen("::1"); }
88 TEST(RNBSocket
, AnyListen
) { TestSocketListen("*"); }
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)
98 if (addresses
.front().GetFamily() == AF_INET6
)
99 sprintf(addr_wrap
, "[%s]:0", addr
);
101 sprintf(addr_wrap
, "%s:0", addr
);
103 Socket
*server_socket
;
104 llvm::Expected
<std::unique_ptr
<Socket
>> socket_or_err
=
105 Socket::TcpListen(addr_wrap
, false);
106 ASSERT_THAT_EXPECTED(socket_or_err
, llvm::Succeeded());
107 server_socket
= socket_or_err
->get();
109 auto port
= ((TCPSocket
*)server_socket
)->GetLocalPortNumber();
110 auto child_pid
= fork();
111 if (child_pid
!= 0) {
112 RNBSocket client_socket
;
113 auto result
= client_socket
.Connect(addr
, port
);
114 ASSERT_TRUE(result
== rnb_success
);
115 result
= client_socket
.Write(hello
.c_str(), hello
.length());
116 ASSERT_TRUE(result
== rnb_success
);
118 result
= client_socket
.Read(bye
);
119 ASSERT_TRUE(result
== rnb_success
);
120 ASSERT_EQ(bye
, goodbye
);
122 Socket
*connected_socket
;
123 Status err
= server_socket
->Accept(connected_socket
);
125 llvm::errs() << err
.AsCString();
129 size_t read_size
= 32;
130 err
= connected_socket
->Read((void *)&buffer
[0], read_size
);
132 llvm::errs() << err
.AsCString();
135 std::string
Recv(&buffer
[0], read_size
);
137 llvm::errs() << err
.AsCString();
140 size_t write_size
= goodbye
.length();
141 err
= connected_socket
->Write(goodbye
.c_str(), write_size
);
143 llvm::errs() << err
.AsCString();
146 if (write_size
!= goodbye
.length()) {
147 llvm::errs() << err
.AsCString();
154 ASSERT_EQ(exit_status
, 0);
157 TEST(RNBSocket
, LoopBackConnectIPv4
) { TestSocketConnect("127.0.0.1"); }
159 TEST(RNBSocket
, LoopBackConnectIPv6
) { TestSocketConnect("::1"); }