1 //
2 //
3 // Copyright 2017 gRPC authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 //
18
19 #include "src/core/lib/address_utils/parse_address.h"
20 #ifdef GRPC_HAVE_UNIX_SOCKET
21 #ifdef GPR_WINDOWS
22 // clang-format off
23 #include <ws2def.h>
24 #include <afunix.h>
25 // clang-format on
26 #else
27 #include <sys/un.h>
28 #endif // GPR_WINDOWS
29 #endif // GRPC_HAVE_UNIX_SOCKET
30
31 #ifdef GRPC_HAVE_VSOCK
32 #include <linux/vm_sockets.h>
33 #endif
34
35 #include <grpc/grpc.h>
36
37 #include <string>
38
39 #include "absl/log/log.h"
40 #include "absl/status/status.h"
41 #include "absl/strings/match.h"
42 #include "gtest/gtest.h"
43 #include "src/core/lib/iomgr/exec_ctx.h"
44 #include "src/core/lib/iomgr/port.h"
45 #include "src/core/lib/iomgr/sockaddr.h"
46 #include "src/core/lib/iomgr/socket_utils.h"
47 #include "test/core/test_util/test_config.h"
48
49 #ifdef GRPC_HAVE_UNIX_SOCKET
50
test_grpc_parse_unix(const char * uri_text,const char * pathname)51 static void test_grpc_parse_unix(const char* uri_text, const char* pathname) {
52 grpc_core::ExecCtx exec_ctx;
53 absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(uri_text);
54 if (!uri.ok()) {
55 LOG(ERROR) << uri.status();
56 ASSERT_TRUE(uri.ok());
57 }
58 grpc_resolved_address addr;
59
60 ASSERT_TRUE(grpc_parse_uri(*uri, &addr));
61 struct sockaddr_un* addr_un =
62 reinterpret_cast<struct sockaddr_un*>(addr.addr);
63 ASSERT_EQ(AF_UNIX, addr_un->sun_family);
64 ASSERT_STREQ(addr_un->sun_path, pathname);
65 }
66
test_grpc_parse_unix_abstract(const char * uri_text,const char * pathname)67 static void test_grpc_parse_unix_abstract(const char* uri_text,
68 const char* pathname) {
69 grpc_core::ExecCtx exec_ctx;
70 absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(uri_text);
71 if (!uri.ok()) {
72 LOG(ERROR) << uri.status();
73 ASSERT_TRUE(uri.ok());
74 }
75 grpc_resolved_address addr;
76
77 ASSERT_TRUE(grpc_parse_uri(*uri, &addr));
78 struct sockaddr_un* addr_un =
79 reinterpret_cast<struct sockaddr_un*>(addr.addr);
80 ASSERT_EQ(AF_UNIX, addr_un->sun_family);
81 ASSERT_EQ('\0', addr_un->sun_path[0]);
82 ASSERT_TRUE(absl::StartsWith(addr_un->sun_path + 1, pathname));
83 }
84
85 #else // GRPC_HAVE_UNIX_SOCKET
86
test_grpc_parse_unix(const char * uri_text,const char * pathname)87 static void test_grpc_parse_unix(const char* uri_text, const char* pathname) {}
test_grpc_parse_unix_abstract(const char * uri_text,const char * pathname)88 static void test_grpc_parse_unix_abstract(const char* uri_text,
89 const char* pathname) {}
90
91 #endif // GRPC_HAVE_UNIX_SOCKET
92
93 #ifdef GRPC_HAVE_VSOCK
94
test_grpc_parse_vsock(const char * uri_text,uint32_t cid,uint32_t port)95 static void test_grpc_parse_vsock(const char* uri_text, uint32_t cid,
96 uint32_t port) {
97 grpc_core::ExecCtx exec_ctx;
98 absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(uri_text);
99 if (!uri.ok()) {
100 LOG(ERROR) << uri.status();
101 ASSERT_TRUE(uri.ok());
102 }
103 grpc_resolved_address addr;
104
105 ASSERT_TRUE(grpc_parse_uri(*uri, &addr));
106 struct sockaddr_vm* addr_vm =
107 reinterpret_cast<struct sockaddr_vm*>(addr.addr);
108 ASSERT_EQ(AF_VSOCK, addr_vm->svm_family);
109 ASSERT_EQ(grpc_ntohl(addr_vm->svm_cid), cid);
110 ASSERT_EQ(addr_vm->svm_port, port);
111 }
112
113 #else // GRPC_HAVE_VSOCK
114
test_grpc_parse_vsock(const char *,...)115 static void test_grpc_parse_vsock(const char* /* uri_text */, ...) {}
116
117 #endif // GRPC_HAVE_VSOCK
118
test_grpc_parse_ipv4(const char * uri_text,const char * host,unsigned short port)119 static void test_grpc_parse_ipv4(const char* uri_text, const char* host,
120 unsigned short port) {
121 grpc_core::ExecCtx exec_ctx;
122 absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(uri_text);
123 if (!uri.ok()) {
124 LOG(ERROR) << uri.status();
125 ASSERT_TRUE(uri.ok());
126 }
127 grpc_resolved_address addr;
128 char ntop_buf[GRPC_INET_ADDRSTRLEN];
129
130 ASSERT_TRUE(grpc_parse_ipv4(*uri, &addr));
131 grpc_sockaddr_in* addr_in = reinterpret_cast<grpc_sockaddr_in*>(addr.addr);
132 ASSERT_EQ(GRPC_AF_INET, addr_in->sin_family);
133 ASSERT_NE(nullptr, grpc_inet_ntop(GRPC_AF_INET, &addr_in->sin_addr, ntop_buf,
134 sizeof(ntop_buf)));
135 ASSERT_STREQ(ntop_buf, host);
136 ASSERT_EQ(grpc_ntohs(addr_in->sin_port), port);
137 }
138
test_grpc_parse_ipv6(const char * uri_text,const char * host,unsigned short port,uint32_t scope_id)139 static void test_grpc_parse_ipv6(const char* uri_text, const char* host,
140 unsigned short port, uint32_t scope_id) {
141 grpc_core::ExecCtx exec_ctx;
142 absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(uri_text);
143 if (!uri.ok()) {
144 LOG(ERROR) << uri.status();
145 ASSERT_TRUE(uri.ok());
146 }
147 grpc_resolved_address addr;
148 char ntop_buf[GRPC_INET6_ADDRSTRLEN];
149 ASSERT_TRUE(grpc_parse_ipv6(*uri, &addr));
150 grpc_sockaddr_in6* addr_in6 = reinterpret_cast<grpc_sockaddr_in6*>(addr.addr);
151 ASSERT_EQ(GRPC_AF_INET6, addr_in6->sin6_family);
152 ASSERT_NE(nullptr, grpc_inet_ntop(GRPC_AF_INET6, &addr_in6->sin6_addr,
153 ntop_buf, sizeof(ntop_buf)));
154 ASSERT_STREQ(ntop_buf, host);
155 ASSERT_EQ(grpc_ntohs(addr_in6->sin6_port), port);
156 ASSERT_EQ(addr_in6->sin6_scope_id, scope_id);
157 }
158
159 // Test parsing invalid ipv6 addresses (valid uri_text but invalid ipv6 addr)
test_grpc_parse_ipv6_invalid(const char * uri_text)160 static void test_grpc_parse_ipv6_invalid(const char* uri_text) {
161 grpc_core::ExecCtx exec_ctx;
162 absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(uri_text);
163 if (!uri.ok()) {
164 LOG(ERROR) << uri.status();
165 ASSERT_TRUE(uri.ok());
166 }
167 grpc_resolved_address addr;
168 ASSERT_FALSE(grpc_parse_ipv6(*uri, &addr));
169 }
170
TEST(ParseAddressTest,MainTest)171 TEST(ParseAddressTest, MainTest) {
172 grpc_init();
173
174 test_grpc_parse_unix("unix:/path/name", "/path/name");
175 test_grpc_parse_unix_abstract("unix-abstract:foobar", "foobar");
176 test_grpc_parse_vsock("vsock:-1:12345", -1, 12345);
177 test_grpc_parse_ipv4("ipv4:192.0.2.1:12345", "192.0.2.1", 12345);
178 test_grpc_parse_ipv6("ipv6:[2001:db8::1]:12345", "2001:db8::1", 12345, 0);
179 test_grpc_parse_ipv6("ipv6:[2001:db8::1%252]:12345", "2001:db8::1", 12345, 2);
180
181 // Address length greater than GRPC_INET6_ADDRSTRLEN
182 test_grpc_parse_ipv6_invalid(
183 "ipv6:WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW45%"
184 "25v6:45%25x$1*");
185
186 grpc_shutdown();
187 }
188
main(int argc,char ** argv)189 int main(int argc, char** argv) {
190 grpc::testing::TestEnvironment env(&argc, argv);
191 ::testing::InitGoogleTest(&argc, argv);
192 return RUN_ALL_TESTS();
193 }
194