1 /*
2 *
3 * Copyright 2015 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 /* With the addition of a libuv endpoint, sockaddr.h now includes uv.h when
20 using that endpoint. Because of various transitive includes in uv.h,
21 including windows.h on Windows, uv.h must be included before other system
22 headers. Therefore, sockaddr.h must always be included first */
23 #include "src/core/lib/iomgr/sockaddr_utils.h"
24 #include "src/core/lib/iomgr/sockaddr.h"
25 #include "src/core/lib/iomgr/socket_utils.h"
26
27 #include <errno.h>
28 #include <string.h>
29
30 #include <grpc/support/alloc.h>
31 #include <grpc/support/log.h>
32 #include <grpc/support/port_platform.h>
33 #include "test/core/util/test_config.h"
34
make_addr4(const uint8_t * data,size_t data_len)35 static grpc_resolved_address make_addr4(const uint8_t* data, size_t data_len) {
36 grpc_resolved_address resolved_addr4;
37 grpc_sockaddr_in* addr4 =
38 reinterpret_cast<grpc_sockaddr_in*>(resolved_addr4.addr);
39 memset(&resolved_addr4, 0, sizeof(resolved_addr4));
40 addr4->sin_family = GRPC_AF_INET;
41 GPR_ASSERT(data_len == sizeof(addr4->sin_addr.s_addr));
42 memcpy(&addr4->sin_addr.s_addr, data, data_len);
43 addr4->sin_port = grpc_htons(12345);
44 resolved_addr4.len = static_cast<socklen_t>(sizeof(grpc_sockaddr_in));
45 return resolved_addr4;
46 }
47
make_addr6(const uint8_t * data,size_t data_len)48 static grpc_resolved_address make_addr6(const uint8_t* data, size_t data_len) {
49 grpc_resolved_address resolved_addr6;
50 grpc_sockaddr_in6* addr6 =
51 reinterpret_cast<grpc_sockaddr_in6*>(resolved_addr6.addr);
52 memset(&resolved_addr6, 0, sizeof(resolved_addr6));
53 addr6->sin6_family = GRPC_AF_INET6;
54 GPR_ASSERT(data_len == sizeof(addr6->sin6_addr.s6_addr));
55 memcpy(&addr6->sin6_addr.s6_addr, data, data_len);
56 addr6->sin6_port = grpc_htons(12345);
57 resolved_addr6.len = static_cast<socklen_t>(sizeof(grpc_sockaddr_in6));
58 return resolved_addr6;
59 }
60
set_addr6_scope_id(grpc_resolved_address * addr,uint32_t scope_id)61 static void set_addr6_scope_id(grpc_resolved_address* addr, uint32_t scope_id) {
62 grpc_sockaddr_in6* addr6 = reinterpret_cast<grpc_sockaddr_in6*>(addr->addr);
63 GPR_ASSERT(addr6->sin6_family == GRPC_AF_INET6);
64 addr6->sin6_scope_id = scope_id;
65 }
66
67 static const uint8_t kMapped[] = {0, 0, 0, 0, 0, 0, 0, 0,
68 0, 0, 0xff, 0xff, 192, 0, 2, 1};
69
70 static const uint8_t kNotQuiteMapped[] = {0, 0, 0, 0, 0, 0, 0, 0,
71 0, 0, 0xff, 0xfe, 192, 0, 2, 99};
72 static const uint8_t kIPv4[] = {192, 0, 2, 1};
73
74 static const uint8_t kIPv6[] = {0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0,
75 0, 0, 0, 0, 0, 0, 0, 1};
76
test_sockaddr_is_v4mapped(void)77 static void test_sockaddr_is_v4mapped(void) {
78 grpc_resolved_address input4;
79 grpc_resolved_address input6;
80 grpc_resolved_address output4;
81 grpc_resolved_address expect4;
82
83 gpr_log(GPR_INFO, "%s", "test_sockaddr_is_v4mapped");
84
85 /* v4mapped input should succeed. */
86 input6 = make_addr6(kMapped, sizeof(kMapped));
87 GPR_ASSERT(grpc_sockaddr_is_v4mapped(&input6, nullptr));
88 GPR_ASSERT(grpc_sockaddr_is_v4mapped(&input6, &output4));
89 expect4 = make_addr4(kIPv4, sizeof(kIPv4));
90 GPR_ASSERT(memcmp(&expect4, &output4, sizeof(expect4)) == 0);
91
92 /* Non-v4mapped input should fail. */
93 input6 = make_addr6(kNotQuiteMapped, sizeof(kNotQuiteMapped));
94 GPR_ASSERT(!grpc_sockaddr_is_v4mapped(&input6, nullptr));
95 GPR_ASSERT(!grpc_sockaddr_is_v4mapped(&input6, &output4));
96 /* Output is unchanged. */
97 GPR_ASSERT(memcmp(&expect4, &output4, sizeof(expect4)) == 0);
98
99 /* Plain IPv4 input should also fail. */
100 input4 = make_addr4(kIPv4, sizeof(kIPv4));
101 GPR_ASSERT(!grpc_sockaddr_is_v4mapped(&input4, nullptr));
102 }
103
test_sockaddr_to_v4mapped(void)104 static void test_sockaddr_to_v4mapped(void) {
105 grpc_resolved_address input4;
106 grpc_resolved_address input6;
107 grpc_resolved_address output6;
108 grpc_resolved_address expect6;
109
110 gpr_log(GPR_INFO, "%s", "test_sockaddr_to_v4mapped");
111
112 /* IPv4 input should succeed. */
113 input4 = make_addr4(kIPv4, sizeof(kIPv4));
114 GPR_ASSERT(grpc_sockaddr_to_v4mapped(&input4, &output6));
115 expect6 = make_addr6(kMapped, sizeof(kMapped));
116 GPR_ASSERT(memcmp(&expect6, &output6, sizeof(output6)) == 0);
117
118 /* IPv6 input should fail. */
119 input6 = make_addr6(kIPv6, sizeof(kIPv6));
120 GPR_ASSERT(!grpc_sockaddr_to_v4mapped(&input6, &output6));
121 /* Output is unchanged. */
122 GPR_ASSERT(memcmp(&expect6, &output6, sizeof(output6)) == 0);
123
124 /* Already-v4mapped input should also fail. */
125 input6 = make_addr6(kMapped, sizeof(kMapped));
126 GPR_ASSERT(!grpc_sockaddr_to_v4mapped(&input6, &output6));
127 }
128
test_sockaddr_is_wildcard(void)129 static void test_sockaddr_is_wildcard(void) {
130 grpc_resolved_address wild4;
131 grpc_resolved_address wild6;
132 grpc_resolved_address wild_mapped;
133 grpc_resolved_address dummy;
134 grpc_sockaddr_in* wild4_addr;
135 grpc_sockaddr_in6* wild6_addr;
136 grpc_sockaddr_in6* wild_mapped_addr;
137 int port;
138
139 gpr_log(GPR_INFO, "%s", "test_sockaddr_is_wildcard");
140
141 /* Generate wildcards. */
142 grpc_sockaddr_make_wildcards(555, &wild4, &wild6);
143 GPR_ASSERT(grpc_sockaddr_to_v4mapped(&wild4, &wild_mapped));
144
145 /* Test 0.0.0.0:555 */
146 port = -1;
147 GPR_ASSERT(grpc_sockaddr_is_wildcard(&wild4, &port));
148 GPR_ASSERT(port == 555);
149 wild4_addr = reinterpret_cast<grpc_sockaddr_in*>(&wild4.addr);
150 memset(&wild4_addr->sin_addr.s_addr, 0xbd, 1);
151 GPR_ASSERT(!grpc_sockaddr_is_wildcard(&wild4, &port));
152
153 /* Test [::]:555 */
154 port = -1;
155 GPR_ASSERT(grpc_sockaddr_is_wildcard(&wild6, &port));
156 GPR_ASSERT(port == 555);
157 wild6_addr = reinterpret_cast<grpc_sockaddr_in6*>(&wild6.addr);
158 memset(&wild6_addr->sin6_addr.s6_addr, 0xbd, 1);
159 GPR_ASSERT(!grpc_sockaddr_is_wildcard(&wild6, &port));
160
161 /* Test [::ffff:0.0.0.0]:555 */
162 port = -1;
163 GPR_ASSERT(grpc_sockaddr_is_wildcard(&wild_mapped, &port));
164 GPR_ASSERT(port == 555);
165 wild_mapped_addr = reinterpret_cast<grpc_sockaddr_in6*>(&wild_mapped.addr);
166 memset(&wild_mapped_addr->sin6_addr.s6_addr, 0xbd, 1);
167 GPR_ASSERT(!grpc_sockaddr_is_wildcard(&wild_mapped, &port));
168
169 /* Test AF_UNSPEC. */
170 port = -1;
171 memset(&dummy, 0, sizeof(dummy));
172 GPR_ASSERT(!grpc_sockaddr_is_wildcard(&dummy, &port));
173 GPR_ASSERT(port == -1);
174 }
175
expect_sockaddr_str(const char * expected,grpc_resolved_address * addr,int normalize)176 static void expect_sockaddr_str(const char* expected,
177 grpc_resolved_address* addr, int normalize) {
178 gpr_log(GPR_INFO, " expect_sockaddr_str(%s)", expected);
179 std::string actual = grpc_sockaddr_to_string(addr, normalize);
180 GPR_ASSERT(actual == expected);
181 }
182
expect_sockaddr_uri(const char * expected,grpc_resolved_address * addr)183 static void expect_sockaddr_uri(const char* expected,
184 grpc_resolved_address* addr) {
185 char* str;
186 gpr_log(GPR_INFO, " expect_sockaddr_uri(%s)", expected);
187 str = grpc_sockaddr_to_uri(addr);
188 GPR_ASSERT(str != nullptr);
189 GPR_ASSERT(strcmp(expected, str) == 0);
190 gpr_free(str);
191 }
192
test_sockaddr_to_string(void)193 static void test_sockaddr_to_string(void) {
194 grpc_resolved_address input4;
195 grpc_resolved_address input6;
196 grpc_resolved_address dummy;
197 grpc_sockaddr* dummy_addr;
198
199 gpr_log(GPR_INFO, "%s", "test_sockaddr_to_string");
200
201 errno = 0x7EADBEEF;
202
203 input4 = make_addr4(kIPv4, sizeof(kIPv4));
204 expect_sockaddr_str("192.0.2.1:12345", &input4, 0);
205 expect_sockaddr_str("192.0.2.1:12345", &input4, 1);
206 expect_sockaddr_uri("ipv4:192.0.2.1:12345", &input4);
207
208 input6 = make_addr6(kIPv6, sizeof(kIPv6));
209 expect_sockaddr_str("[2001:db8::1]:12345", &input6, 0);
210 expect_sockaddr_str("[2001:db8::1]:12345", &input6, 1);
211 expect_sockaddr_uri("ipv6:[2001:db8::1]:12345", &input6);
212
213 set_addr6_scope_id(&input6, 2);
214 expect_sockaddr_str("[2001:db8::1%252]:12345", &input6, 0);
215 expect_sockaddr_str("[2001:db8::1%252]:12345", &input6, 1);
216 expect_sockaddr_uri("ipv6:[2001:db8::1%252]:12345", &input6);
217
218 set_addr6_scope_id(&input6, 101);
219 expect_sockaddr_str("[2001:db8::1%25101]:12345", &input6, 0);
220 expect_sockaddr_str("[2001:db8::1%25101]:12345", &input6, 1);
221 expect_sockaddr_uri("ipv6:[2001:db8::1%25101]:12345", &input6);
222
223 input6 = make_addr6(kMapped, sizeof(kMapped));
224 expect_sockaddr_str("[::ffff:192.0.2.1]:12345", &input6, 0);
225 expect_sockaddr_str("192.0.2.1:12345", &input6, 1);
226 expect_sockaddr_uri("ipv4:192.0.2.1:12345", &input6);
227
228 input6 = make_addr6(kNotQuiteMapped, sizeof(kNotQuiteMapped));
229 expect_sockaddr_str("[::fffe:c000:263]:12345", &input6, 0);
230 expect_sockaddr_str("[::fffe:c000:263]:12345", &input6, 1);
231 expect_sockaddr_uri("ipv6:[::fffe:c000:263]:12345", &input6);
232
233 memset(&dummy, 0, sizeof(dummy));
234 dummy_addr = reinterpret_cast<grpc_sockaddr*>(dummy.addr);
235 dummy_addr->sa_family = 123;
236 expect_sockaddr_str("(sockaddr family=123)", &dummy, 0);
237 expect_sockaddr_str("(sockaddr family=123)", &dummy, 1);
238 GPR_ASSERT(grpc_sockaddr_to_uri(&dummy) == nullptr);
239 }
240
test_sockaddr_set_get_port(void)241 static void test_sockaddr_set_get_port(void) {
242 grpc_resolved_address input4;
243 grpc_resolved_address input6;
244 grpc_resolved_address dummy;
245 grpc_sockaddr* dummy_addr;
246
247 gpr_log(GPR_DEBUG, "test_sockaddr_set_get_port");
248
249 input4 = make_addr4(kIPv4, sizeof(kIPv4));
250 GPR_ASSERT(grpc_sockaddr_get_port(&input4) == 12345);
251 GPR_ASSERT(grpc_sockaddr_set_port(&input4, 54321));
252 GPR_ASSERT(grpc_sockaddr_get_port(&input4) == 54321);
253
254 input6 = make_addr6(kIPv6, sizeof(kIPv6));
255 GPR_ASSERT(grpc_sockaddr_get_port(&input6) == 12345);
256 GPR_ASSERT(grpc_sockaddr_set_port(&input6, 54321));
257 GPR_ASSERT(grpc_sockaddr_get_port(&input6) == 54321);
258
259 memset(&dummy, 0, sizeof(dummy));
260 dummy_addr = reinterpret_cast<grpc_sockaddr*>(dummy.addr);
261 dummy_addr->sa_family = 123;
262 GPR_ASSERT(grpc_sockaddr_get_port(&dummy) == 0);
263 GPR_ASSERT(grpc_sockaddr_set_port(&dummy, 1234) == 0);
264 }
265
main(int argc,char ** argv)266 int main(int argc, char** argv) {
267 grpc::testing::TestEnvironment env(argc, argv);
268
269 test_sockaddr_is_v4mapped();
270 test_sockaddr_to_v4mapped();
271 test_sockaddr_is_wildcard();
272 test_sockaddr_to_string();
273 test_sockaddr_set_get_port();
274
275 return 0;
276 }
277