Skip to content

Commit 19f9d04

Browse files
authored
CPP-795 Add hostname and SNI support to Address (#270)
1 parent 0605e26 commit 19f9d04

26 files changed

Lines changed: 386 additions & 254 deletions

cpp-driver/gtests/src/integration/rest_client.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ const Response RestClient::send_request(const Request& request) {
8080
// Start the request and attach the HTTP request to send to the REST server
8181
uv_connect_t connect;
8282
connect.data = &http_request;
83-
uv_tcp_connect(&connect, &tcp, address.addr(), handle_connected);
83+
Address::SocketStorage storage;
84+
uv_tcp_connect(&connect, &tcp, address.to_sockaddr(&storage), handle_connected);
8485

8586
uv_run(&loop, UV_RUN_DEFAULT);
8687
uv_loop_close(&loop);

cpp-driver/gtests/src/unit/mockssandra.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,8 @@ void ServerConnection::internal_listen() {
560560

561561
inc_ref(); // For the TCP handle
562562

563-
rc = tcp_.bind(address_.addr());
563+
Address::SocketStorage storage;
564+
rc = tcp_.bind(address_.to_sockaddr(&storage));
564565
if (rc != 0) {
565566
fprintf(stderr, "Unable to bind address %s\n", address_.to_string(true).c_str());
566567
uv_close(tcp_.as_handle(), on_close);
@@ -871,7 +872,7 @@ const char* decode_query_params_v3v4(const char* input, const char* end, QueryPa
871872
}
872873

873874
const char* decode_query_params_v5(const char* input, const char* end, QueryParameters* params) {
874-
int32_t flags;
875+
int32_t flags = 0;
875876
const char* pos = input;
876877
pos = decode_uint16(pos, end, &params->consistency);
877878
pos = decode_int32(pos, end, &flags);
@@ -1600,8 +1601,8 @@ void SystemPeers::on_run(Request* request) const {
16001601
}
16011602

16021603
String ip = query.substr(pos, end_pos - pos);
1603-
Address address;
1604-
if (!Address::from_string(ip, request->address().port(), &address)) {
1604+
Address address(ip, request->address().port());
1605+
if (!address.is_valid_and_resolved()) {
16051606
request->error(ERROR_INVALID_QUERY, "Invalid inet address in WHERE clause");
16061607
return;
16071608
}
@@ -1669,8 +1670,8 @@ void SystemPeersDse::on_run(Request* request) const {
16691670
}
16701671

16711672
String ip = query.substr(pos, end_pos - pos);
1672-
Address address;
1673-
if (!Address::from_string(ip, request->address().port(), &address)) {
1673+
Address address(ip, request->address().port());
1674+
if (!address.is_valid_and_resolved()) {
16741675
request->error(ERROR_INVALID_QUERY, "Invalid inet address in WHERE clause");
16751676
return;
16761677
}

cpp-driver/gtests/src/unit/tests/test_address.cpp

Lines changed: 103 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,112 @@
1919
#include "address.hpp"
2020

2121
using datastax::internal::core::Address;
22+
using datastax::internal::core::AddressSet;
23+
24+
TEST(AddressUnitTest, FromString) {
25+
EXPECT_TRUE(Address("127.0.0.1", 9042).is_resolved());
26+
EXPECT_TRUE(Address("0.0.0.0", 9042).is_resolved());
27+
EXPECT_TRUE(Address("::", 9042).is_resolved());
28+
EXPECT_TRUE(Address("::1", 9042).is_resolved());
29+
EXPECT_TRUE(Address("2001:0db8:85a3:0000:0000:8a2e:0370:7334", 9042).is_resolved());
30+
31+
EXPECT_FALSE(Address().is_resolved());
32+
EXPECT_FALSE(Address("localhost", 9042).is_resolved());
33+
EXPECT_FALSE(Address("datastax.com", 9042).is_resolved());
34+
}
2235

2336
TEST(AddressUnitTest, CompareIPv4) {
24-
EXPECT_GT(Address("255.255.255.255", 9042).compare(Address("0.0.0.0", 9042)), 0);
25-
EXPECT_LT(Address("0.0.0.0", 9042).compare(Address("255.255.255.255", 9042)), 0);
26-
EXPECT_EQ(Address("1.2.3.4", 9042).compare(Address("1.2.3.4", 9042)), 0);
37+
EXPECT_LT(Address("0.0.0.0", 9042), Address("255.255.255.255", 9042));
38+
EXPECT_EQ(Address("1.2.3.4", 9042), Address("1.2.3.4", 9042));
39+
EXPECT_NE(Address("1.2.3.4", 9042), Address("5.6.7.8", 9042));
40+
41+
EXPECT_LT(Address("0.0.0.0", 9041), Address("0.0.0.0", 9042));
42+
EXPECT_NE(Address("0.0.0.0", 9041), Address("0.0.0.0", 9042));
43+
44+
// Without comparing port
45+
EXPECT_TRUE(Address("0.0.0.0", 9041).equals(Address("0.0.0.0", 9042), false));
46+
EXPECT_FALSE(Address("127.0.0.1", 9042).equals(Address("0.0.0.0", 9042), false));
2747
}
2848

2949
TEST(AddressUnitTest, CompareIPv6) {
30-
EXPECT_GT(Address("0.0.0.0", 1).compare(Address("0.0.0.0", 0), true), 0);
31-
EXPECT_LT(Address("0.0.0.0", 0).compare(Address("0.0.0.0", 1), true), 0);
32-
EXPECT_EQ(Address("0.0.0.0", 0).compare(Address("0.0.0.0", 1), false), 0);
50+
EXPECT_LT(Address("0:0:0:0:0:0:0:0", 9042), Address("0:0:0:0:0:0:0:FFFF", 9042));
51+
EXPECT_EQ(Address("0:0:0:0:0:0:0:1234", 9042), Address("0:0:0:0:0:0:0:1234", 9042));
52+
EXPECT_NE(Address("0:0:0:0:0:0:0:1234", 9042), Address("0:0:0:0:0:0:0:5678", 9042));
53+
54+
EXPECT_LT(Address("0:0:0:0:0:0:0:0", 9041), Address("0:0:0:0:0:0:0:0", 9042));
55+
EXPECT_NE(Address("0:0:0:0:0:0:0:0", 9041), Address("0:0:0:0:0:0:0:0", 9042));
56+
57+
// Without comparing port
58+
EXPECT_TRUE(Address("::", 9041).equals(Address("::", 9042), false));
59+
EXPECT_FALSE(Address("::1", 9042).equals(Address("::", 9042), false));
60+
61+
EXPECT_EQ(Address("0:0:0:0:0:0:0:0", 9042), Address("::", 9042)); // Normalization
62+
}
63+
64+
TEST(AddressUnitTest, ToSockAddrIPv4) {
65+
Address expected("127.0.0.1", 9042);
66+
Address::SocketStorage storage;
67+
Address actual(expected.to_sockaddr(&storage));
68+
EXPECT_EQ(expected, actual);
69+
}
70+
71+
TEST(AddressUnitTest, ToSockAddrIPv6) {
72+
Address expected("::1", 9042);
73+
Address::SocketStorage storage;
74+
Address actual(expected.to_sockaddr(&storage));
75+
EXPECT_EQ(expected, actual);
76+
}
77+
78+
TEST(AddressUnitTest, ToInetIPv4) {
79+
Address expected("127.0.0.1", 9042);
80+
81+
uint8_t inet_address[4];
82+
uint8_t inet_address_length = expected.to_inet(inet_address);
83+
EXPECT_EQ(inet_address_length, 4u);
84+
85+
Address actual(inet_address, inet_address_length, 9042);
86+
EXPECT_EQ(expected, actual);
87+
}
88+
89+
TEST(AddressUnitTest, ToInetIPv6) {
90+
Address expected("::1", 9042);
91+
92+
uint8_t inet_address[16];
93+
uint8_t inet_address_length = expected.to_inet(inet_address);
94+
EXPECT_EQ(inet_address_length, 16u);
95+
96+
Address actual(inet_address, inet_address_length, 9042);
97+
EXPECT_EQ(expected, actual);
98+
}
99+
100+
TEST(AddressUnitTest, Hash) {
101+
AddressSet set;
102+
103+
EXPECT_EQ(set.size(), 0u); // Empty
104+
105+
set.insert(Address("0.0.0.0", 9042));
106+
EXPECT_EQ(set.size(), 1u); // Added
107+
108+
// Reinsert
109+
set.insert(Address("0.0.0.0", 9042));
110+
EXPECT_EQ(set.size(), 1u); // No change
111+
112+
// Remove
113+
set.erase(Address("0.0.0.0", 9042));
114+
EXPECT_EQ(set.size(), 0u); // Removed
115+
116+
// Multiple
117+
set.insert(Address("0.0.0.0", 9042));
118+
set.insert(Address("127.0.0.1", 9042));
119+
set.insert(Address("localhost", 9042));
120+
set.insert(Address("::1", 9042));
121+
EXPECT_EQ(set.size(), 4u); // Added
122+
EXPECT_EQ(set.count(Address("0.0.0.0", 9042)), 1u);
123+
EXPECT_EQ(set.count(Address("127.0.0.1", 9042)), 1u);
124+
EXPECT_EQ(set.count(Address("localhost", 9042)), 1u);
125+
EXPECT_EQ(set.count(Address("::1", 9042)), 1u);
126+
127+
// Different port
128+
set.insert(Address("0.0.0.0", 9041));
129+
EXPECT_EQ(set.size(), 5u); // Added
33130
}

cpp-driver/gtests/src/unit/tests/test_socket.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -286,11 +286,10 @@ TEST_F(SocketUnitTest, SslVerifyIdentity) {
286286

287287
TEST_F(SocketUnitTest, SslVerifyIdentityDns) {
288288
// Verify address can be resolved
289-
Address verify_entry;
290-
Address::from_string(SSL_VERIFY_PEER_DNS_IP_ADDRESS, 8888, &verify_entry);
289+
Address verify_entry(SSL_VERIFY_PEER_DNS_IP_ADDRESS, 8888);
291290
uv_getnameinfo_t request;
292-
ASSERT_EQ(0, uv_getnameinfo(loop(), &request, on_request,
293-
static_cast<const Address>(verify_entry).addr(), 0));
291+
Address::SocketStorage storage;
292+
ASSERT_EQ(0, uv_getnameinfo(loop(), &request, on_request, verify_entry.to_sockaddr(&storage), 0));
294293
uv_run(loop(), UV_RUN_DEFAULT);
295294
if (this->HasFailure()) { // Make test fail due to DNS not configured
296295
return;

cpp-driver/gtests/src/unit/tests/test_statement.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ class StatementUnitTest : public Unit {
5454
CassInet inet;
5555
ASSERT_TRUE(value->decoder().as_inet(value->size(), &inet));
5656

57-
ASSERT_TRUE(Address::from_inet(inet.address, inet.address_length, 9042, output));
57+
*output = Address(inet.address, inet.address_length, 9042);
58+
ASSERT_TRUE(output->is_valid_and_resolved());
5859
}
5960

6061
Session session;

0 commit comments

Comments
 (0)