• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   gpr_log(GPR_INFO, "  expect_sockaddr_uri(%s)", expected);
186   std::string actual = grpc_sockaddr_to_uri(addr);
187   GPR_ASSERT(actual == expected);
188 }
189 
test_sockaddr_to_string(void)190 static void test_sockaddr_to_string(void) {
191   grpc_resolved_address input4;
192   grpc_resolved_address input6;
193   grpc_resolved_address dummy;
194   grpc_sockaddr* dummy_addr;
195 
196   gpr_log(GPR_INFO, "%s", "test_sockaddr_to_string");
197 
198   errno = 0x7EADBEEF;
199 
200   input4 = make_addr4(kIPv4, sizeof(kIPv4));
201   expect_sockaddr_str("192.0.2.1:12345", &input4, 0);
202   expect_sockaddr_str("192.0.2.1:12345", &input4, 1);
203   expect_sockaddr_uri("ipv4:192.0.2.1:12345", &input4);
204 
205   input6 = make_addr6(kIPv6, sizeof(kIPv6));
206   expect_sockaddr_str("[2001:db8::1]:12345", &input6, 0);
207   expect_sockaddr_str("[2001:db8::1]:12345", &input6, 1);
208   expect_sockaddr_uri("ipv6:[2001:db8::1]:12345", &input6);
209 
210   set_addr6_scope_id(&input6, 2);
211   expect_sockaddr_str("[2001:db8::1%252]:12345", &input6, 0);
212   expect_sockaddr_str("[2001:db8::1%252]:12345", &input6, 1);
213   expect_sockaddr_uri("ipv6:[2001:db8::1%252]:12345", &input6);
214 
215   set_addr6_scope_id(&input6, 101);
216   expect_sockaddr_str("[2001:db8::1%25101]:12345", &input6, 0);
217   expect_sockaddr_str("[2001:db8::1%25101]:12345", &input6, 1);
218   expect_sockaddr_uri("ipv6:[2001:db8::1%25101]:12345", &input6);
219 
220   input6 = make_addr6(kMapped, sizeof(kMapped));
221   expect_sockaddr_str("[::ffff:192.0.2.1]:12345", &input6, 0);
222   expect_sockaddr_str("192.0.2.1:12345", &input6, 1);
223   expect_sockaddr_uri("ipv4:192.0.2.1:12345", &input6);
224 
225   input6 = make_addr6(kNotQuiteMapped, sizeof(kNotQuiteMapped));
226   expect_sockaddr_str("[::fffe:c000:263]:12345", &input6, 0);
227   expect_sockaddr_str("[::fffe:c000:263]:12345", &input6, 1);
228   expect_sockaddr_uri("ipv6:[::fffe:c000:263]:12345", &input6);
229 
230   memset(&dummy, 0, sizeof(dummy));
231   dummy_addr = reinterpret_cast<grpc_sockaddr*>(dummy.addr);
232   dummy_addr->sa_family = 123;
233   expect_sockaddr_str("(sockaddr family=123)", &dummy, 0);
234   expect_sockaddr_str("(sockaddr family=123)", &dummy, 1);
235   GPR_ASSERT(grpc_sockaddr_to_uri(&dummy).empty());
236 }
237 
test_sockaddr_set_get_port(void)238 static void test_sockaddr_set_get_port(void) {
239   grpc_resolved_address input4;
240   grpc_resolved_address input6;
241   grpc_resolved_address dummy;
242   grpc_sockaddr* dummy_addr;
243 
244   gpr_log(GPR_DEBUG, "test_sockaddr_set_get_port");
245 
246   input4 = make_addr4(kIPv4, sizeof(kIPv4));
247   GPR_ASSERT(grpc_sockaddr_get_port(&input4) == 12345);
248   GPR_ASSERT(grpc_sockaddr_set_port(&input4, 54321));
249   GPR_ASSERT(grpc_sockaddr_get_port(&input4) == 54321);
250 
251   input6 = make_addr6(kIPv6, sizeof(kIPv6));
252   GPR_ASSERT(grpc_sockaddr_get_port(&input6) == 12345);
253   GPR_ASSERT(grpc_sockaddr_set_port(&input6, 54321));
254   GPR_ASSERT(grpc_sockaddr_get_port(&input6) == 54321);
255 
256   memset(&dummy, 0, sizeof(dummy));
257   dummy_addr = reinterpret_cast<grpc_sockaddr*>(dummy.addr);
258   dummy_addr->sa_family = 123;
259   GPR_ASSERT(grpc_sockaddr_get_port(&dummy) == 0);
260   GPR_ASSERT(grpc_sockaddr_set_port(&dummy, 1234) == 0);
261 }
262 
main(int argc,char ** argv)263 int main(int argc, char** argv) {
264   grpc::testing::TestEnvironment env(argc, argv);
265 
266   test_sockaddr_is_v4mapped();
267   test_sockaddr_to_v4mapped();
268   test_sockaddr_is_wildcard();
269   test_sockaddr_to_string();
270   test_sockaddr_set_get_port();
271 
272   return 0;
273 }
274