Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(143)

Side by Side Diff: native_client_sdk/src/tests/nacl_io_test/host_resolver_test.cc

Issue 99933002: [NaCl SDK] nacl_io: implement getaddrinfo() (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <arpa/inet.h> 5 #include <arpa/inet.h>
6 #include <netinet/in.h> 6 #include <netinet/in.h>
7 #include <sys/types.h> 7 #include <sys/types.h>
8 #include <sys/socket.h> 8 #include <sys/socket.h>
9 9
10 #include "fake_ppapi/fake_pepper_interface.h" 10 #include "fake_ppapi/fake_pepper_interface.h"
11 #include "gtest/gtest.h" 11 #include "gtest/gtest.h"
12 #include "nacl_io/kernel_intercept.h" 12 #include "nacl_io/kernel_intercept.h"
13 13
14 using namespace nacl_io; 14 using namespace nacl_io;
15 using namespace sdk_util; 15 using namespace sdk_util;
16 16
17 namespace { 17 namespace {
18 18
19 class HostResolverTest : public ::testing::Test { 19 class HostResolverTest : public ::testing::Test {
20 public: 20 public:
21 HostResolverTest() : pepper_(NULL) {} 21 HostResolverTest() {}
22
23 void SetUp() {
24 ki_init(NULL);
25 }
26
27 void TearDown() {
28 ki_uninit();
29 }
30 };
31
32 #define FAKE_HOSTNAME "example.com"
33 #define FAKE_IP 0x01020304
34
35 class FakeHostResolverTest : public ::testing::Test {
36 public:
37 FakeHostResolverTest() : pepper_(NULL), fake_resolver_(NULL) {}
22 38
23 void SetUp() { 39 void SetUp() {
24 pepper_ = new FakePepperInterface(); 40 pepper_ = new FakePepperInterface();
41 fake_resolver_ = static_cast<FakeHostResolverInterface*>(
42 pepper_->GetHostResolverInterface());
43
44 // Seed the fake resolver with some data
45 fake_resolver_->fake_hostname = FAKE_HOSTNAME;
46 AddFakeAddress(AF_INET);
47
25 ki_init_interface(NULL, pepper_); 48 ki_init_interface(NULL, pepper_);
26 } 49 }
27 50
51 void AddFakeAddress(int family) {
52 if (family == AF_INET) {
53 int address_count = fake_resolver_->fake_addresses_v4.size();
54 // Each new address we add is FAKE_IP incremented by 1
55 // each time to be unique.
56 sockaddr_in fake_addr;
57 fake_addr.sin_family = family;
58 fake_addr.sin_addr.s_addr = htonl(FAKE_IP + address_count);
59 fake_resolver_->fake_addresses_v4.push_back(fake_addr);
60 } else if (family == AF_INET6) {
61 sockaddr_in6 fake_addr;
62 fake_addr.sin6_family = family;
63 int address_count = fake_resolver_->fake_addresses_v6.size();
64 for (uint8_t i = 0; i < 16; i++) {
65 fake_addr.sin6_addr.s6_addr[i] = i + address_count;
66 }
67 fake_resolver_->fake_addresses_v6.push_back(fake_addr);
68 }
69 }
70
28 void TearDown() { 71 void TearDown() {
29 ki_uninit(); 72 ki_uninit();
30 pepper_ = NULL; 73 pepper_ = NULL;
31 } 74 }
32 75
33 protected: 76 protected:
34 FakePepperInterface* pepper_; 77 FakePepperInterface* pepper_;
78 FakeHostResolverInterface* fake_resolver_;
35 }; 79 };
36 80
37 } // namespace 81 } // namespace
38 82
83 #define NULL_INFO ((struct addrinfo*)NULL)
84 #define NULL_ADDR ((struct sockaddr*)NULL)
39 #define NULL_HOST (static_cast<hostent*>(NULL)) 85 #define NULL_HOST (static_cast<hostent*>(NULL))
40 86
41 TEST_F(HostResolverTest, GethostbynameNumeric) { 87 TEST_F(HostResolverTest, Getaddrinfo_Numeric) {
88 struct addrinfo* ai = NULL;
89 struct sockaddr_in* in;
90 struct addrinfo hints;
91
92 // Numberic only
93 memset(&hints, 0, sizeof(hints));
94 hints.ai_family = AF_INET;
95 hints.ai_socktype = SOCK_STREAM;
96
97 uint32_t expected_addr = htonl(0x01020304);
98 ASSERT_EQ(0, ki_getaddrinfo("1.2.3.4", NULL, &hints, &ai));
99 ASSERT_NE(NULL_INFO, ai);
100 ASSERT_NE(NULL_ADDR, ai->ai_addr);
101 ASSERT_EQ(AF_INET, ai->ai_family);
102 ASSERT_EQ(SOCK_STREAM, ai->ai_socktype);
103 in = (struct sockaddr_in*)ai->ai_addr;
104 ASSERT_EQ(expected_addr, in->sin_addr.s_addr);
105 ASSERT_EQ(NULL_INFO, ai->ai_next);
106
107 ki_freeaddrinfo(ai);
108 }
109
110 TEST_F(HostResolverTest, Getaddrinfo_MissingPPAPI) {
111 // Verify that full lookups fail due to lack of PPAPI interfaces
112 struct addrinfo* ai = NULL;
113 ASSERT_EQ(EAI_SYSTEM, ki_getaddrinfo("google.com", NULL, NULL, &ai));
114 }
115
116 TEST_F(HostResolverTest, Getaddrinfo_Passive) {
117 struct addrinfo* ai = NULL;
118 struct sockaddr_in* in;
119 struct sockaddr_in6* in6;
120 struct addrinfo hints;
121 memset(&hints, 0, sizeof(hints));
122
123 uint32_t expected_port = htons(22);
124 in_addr_t expected_addr = htonl(INADDR_ANY);
125 in6_addr expected_addr6 = IN6ADDR_ANY_INIT;
126
127 // AI_PASSIVE means that the returned address will be a wildcard
128 // address suitable for binding and listening. This should not
129 // hit PPAPI at all, so we don't need fakes.
130 hints.ai_family = AF_INET;
131 hints.ai_flags = AI_PASSIVE;
132 hints.ai_socktype = SOCK_DGRAM;
133 ASSERT_EQ(0, ki_getaddrinfo(NULL, "22", &hints, &ai));
134 ASSERT_NE(NULL_INFO, ai);
135 ASSERT_NE(NULL_ADDR, ai->ai_addr);
136 ASSERT_EQ(NULL_INFO, ai->ai_next);
137 in = (struct sockaddr_in*)ai->ai_addr;
138 ASSERT_EQ(expected_addr, in->sin_addr.s_addr);
139 ASSERT_EQ(expected_port, in->sin_port);
140 ASSERT_EQ(AF_INET, in->sin_family);
141 ki_freeaddrinfo(ai);
142
143 // Same test with AF_INET6
144 hints.ai_family = AF_INET6;
145 ASSERT_EQ(0, ki_getaddrinfo(NULL, "22", &hints, &ai));
146 ASSERT_NE(NULL_INFO, ai);
147 ASSERT_NE(NULL_ADDR, ai->ai_addr);
148 ASSERT_EQ(NULL_INFO, ai->ai_next);
149 in6 = (struct sockaddr_in6*)ai->ai_addr;
150 ASSERT_EQ(expected_port, in6->sin6_port);
151 ASSERT_EQ(AF_INET6, in6->sin6_family);
152 ASSERT_EQ(0, memcmp(in6->sin6_addr.s6_addr,
153 &expected_addr6,
154 sizeof(expected_addr6)));
155 ki_freeaddrinfo(ai);
156 }
157
158 TEST_F(HostResolverTest, Getaddrinfo_Passive_Any) {
159 // Similar to Getaddrinfo_Passive but don't set
160 // ai_family in the hints, so we should get muplitple
161 // results back for the different families.
162 struct addrinfo* ai = NULL;
163 struct sockaddr_in* in;
164 struct sockaddr_in6* in6;
165 struct addrinfo hints;
166 memset(&hints, 0, sizeof(hints));
167
168 uint32_t expected_port = htons(22);
169 in_addr_t expected_addr = htonl(INADDR_ANY);
170 in6_addr expected_addr6 = IN6ADDR_ANY_INIT;
171
172 hints.ai_flags = AI_PASSIVE;
173 hints.ai_socktype = SOCK_DGRAM;
174 ASSERT_EQ(0, ki_getaddrinfo(NULL, "22", &hints, &ai));
175 ASSERT_NE(NULL_INFO, ai);
176 int count = 0;
177 bool got_v4 = false;
178 bool got_v6 = false;
179 while (ai) {
180 ASSERT_NE(NULL_ADDR, ai->ai_addr);
181 switch (ai->ai_addr->sa_family) {
182 case AF_INET:
183 in = (struct sockaddr_in*)ai->ai_addr;
184 ASSERT_EQ(expected_port, in->sin_port);
185 ASSERT_EQ(AF_INET, in->sin_family);
186 ASSERT_EQ(expected_addr, in->sin_addr.s_addr);
187 got_v4 = true;
188 break;
189 case AF_INET6:
190 in6 = (struct sockaddr_in6*)ai->ai_addr;
191 ASSERT_EQ(expected_port, in6->sin6_port);
192 ASSERT_EQ(AF_INET6, in6->sin6_family);
193 ASSERT_EQ(0, memcmp(in6->sin6_addr.s6_addr,
194 &expected_addr6,
195 sizeof(expected_addr6)));
196 got_v6 = true;
197 break;
198 default:
199 ASSERT_TRUE(false) << "Unknown address type: " << ai->ai_addr;
200 break;
201 }
202 ai = ai->ai_next;
203 count++;
204 }
205
206 ASSERT_EQ(2, count);
207 ASSERT_TRUE(got_v4);
208 ASSERT_TRUE(got_v6);
209 }
210
211 TEST_F(FakeHostResolverTest, Getaddrinfo_Lookup) {
212 struct addrinfo* ai = NULL;
213 struct sockaddr_in* in;
214 struct addrinfo hints;
215 memset(&hints, 0, sizeof(hints));
216
217 in_addr_t expected_addr = htonl(FAKE_IP);
218
219 // Lookup the fake hostname using getaddrinfo
220 hints.ai_family = AF_INET;
221 hints.ai_socktype = SOCK_STREAM;
222 ASSERT_EQ(0, ki_getaddrinfo(FAKE_HOSTNAME, NULL, &hints, &ai));
223 ASSERT_NE(NULL_INFO, ai);
224 ASSERT_NE(NULL_ADDR, ai->ai_addr);
225 ASSERT_EQ(AF_INET, ai->ai_family);
226 ASSERT_EQ(SOCK_STREAM, ai->ai_socktype);
227 in = (struct sockaddr_in*)ai->ai_addr;
228 ASSERT_EQ(expected_addr, in->sin_addr.s_addr);
229 ASSERT_EQ(NULL_INFO, ai->ai_next);
230
231 ki_freeaddrinfo(ai);
232 }
233
234 TEST_F(FakeHostResolverTest, Getaddrinfo_Multi) {
235 struct addrinfo* ai = NULL;
236 struct addrinfo hints;
237 memset(&hints, 0, sizeof(hints));
238
239 // Add four fake address on top of the initial one
240 // that the fixture creates.
241 AddFakeAddress(AF_INET);
242 AddFakeAddress(AF_INET);
243 AddFakeAddress(AF_INET6);
244 AddFakeAddress(AF_INET6);
245
246 hints.ai_socktype = SOCK_STREAM;
247
248 // First we test with AF_INET
249 hints.ai_family = AF_INET;
250 ASSERT_EQ(0, ki_getaddrinfo(FAKE_HOSTNAME, NULL, &hints, &ai));
251 ASSERT_NE(NULL_INFO, ai);
252
253 // We expect to be returned 3 AF_INET address with
254 // address FAKE_IP, FAKE_IP+1 and FAKE_IP+2, since that
255 // is that the fake was seeded with.
256 uint32_t expected_addr = htonl(FAKE_IP);
257 int count = 0;
258 struct addrinfo* current = ai;
259 while (current != NULL) {
260 ASSERT_NE(NULL_ADDR, current->ai_addr);
261 ASSERT_EQ(AF_INET, current->ai_family);
262 ASSERT_EQ(SOCK_STREAM, current->ai_socktype);
263 sockaddr_in* in = (sockaddr_in*)current->ai_addr;
264 ASSERT_EQ(expected_addr, in->sin_addr.s_addr);
265 expected_addr += htonl(1);
266 current = current->ai_next;
267 count++;
268 }
269 ASSERT_EQ(3, count);
270 ki_freeaddrinfo(ai);
271
272 // Same test but with AF_INET6
273 hints.ai_family = AF_INET6;
274 ASSERT_EQ(0, ki_getaddrinfo(FAKE_HOSTNAME, NULL, &hints, &ai));
275 ASSERT_NE(NULL_INFO, ai);
276
277 count = 0;
278 current = ai;
279 while (current != NULL) {
280 ASSERT_NE(NULL_ADDR, current->ai_addr);
281 ASSERT_EQ(AF_INET6, current->ai_family);
282 ASSERT_EQ(SOCK_STREAM, current->ai_socktype);
283 sockaddr_in6* in = (sockaddr_in6*)current->ai_addr;
284 for (int i = 0; i < 16; i++) {
285 ASSERT_EQ(i + count, in->sin6_addr.s6_addr[i]);
286 }
287 current = current->ai_next;
288 count++;
289 }
290 ASSERT_EQ(2, count);
291 ki_freeaddrinfo(ai);
292
293 // Same test but with AF_UNSPEC. Here we expect to get
294 // 5 address back: 3 * v4 and 2 * v6.
295 hints.ai_family = AF_UNSPEC;
296 ASSERT_EQ(0, ki_getaddrinfo(FAKE_HOSTNAME, NULL, &hints, &ai));
297 ASSERT_NE(NULL_INFO, ai);
298
299 count = 0;
300 current = ai;
301 while (current != NULL) {
302 ASSERT_NE(NULL_ADDR, ai->ai_addr);
303 ASSERT_EQ(SOCK_STREAM, ai->ai_socktype);
304 current = current->ai_next;
305 count++;
306 }
307 ASSERT_EQ(5, count);
308
309 ki_freeaddrinfo(ai);
310 }
311
312 TEST_F(FakeHostResolverTest, Gethostbyname) {
42 hostent* host = ki_gethostbyname(FAKE_HOSTNAME); 313 hostent* host = ki_gethostbyname(FAKE_HOSTNAME);
43 314
44 // Verify the returned hostent structure 315 // Verify the returned hostent structure
45 ASSERT_NE(NULL_HOST, host); 316 ASSERT_NE(NULL_HOST, host);
46 ASSERT_EQ(AF_INET, host->h_addrtype); 317 ASSERT_EQ(AF_INET, host->h_addrtype);
47 ASSERT_EQ(sizeof(in_addr_t), host->h_length); 318 ASSERT_EQ(sizeof(in_addr_t), host->h_length);
48 ASSERT_STREQ(FAKE_HOSTNAME, host->h_name); 319 ASSERT_STREQ(FAKE_HOSTNAME, host->h_name);
49 320
50 in_addr_t** addr_list = reinterpret_cast<in_addr_t**>(host->h_addr_list); 321 in_addr_t** addr_list = reinterpret_cast<in_addr_t**>(host->h_addr_list);
51 ASSERT_NE(reinterpret_cast<in_addr_t**>(NULL), addr_list); 322 ASSERT_NE(reinterpret_cast<in_addr_t**>(NULL), addr_list);
52 ASSERT_EQ(NULL, addr_list[1]); 323 ASSERT_EQ(NULL, addr_list[1]);
53 in_addr_t exptected_addr = htonl(FAKE_IP); 324 in_addr_t exptected_addr = htonl(FAKE_IP);
54 ASSERT_EQ(exptected_addr, *addr_list[0]); 325 ASSERT_EQ(exptected_addr, *addr_list[0]);
55 } 326 }
327
328 TEST_F(FakeHostResolverTest, Gethostbyname_Failure) {
329 hostent* host = ki_gethostbyname("nosuchhost.com");
330 ASSERT_EQ(NULL_HOST, host);
331 ASSERT_EQ(HOST_NOT_FOUND, h_errno);
332 }
333
334 // Looking up purely numeric hostnames should work without PPAPI
335 // so we don't need the fakes for this test
336 TEST_F(HostResolverTest, Gethostbyname_Numeric) {
337 struct hostent* host = ki_gethostbyname("8.8.8.8");
338
339 // Verify the returned hostent structure
340 ASSERT_NE(NULL_HOST, host);
341 ASSERT_EQ(AF_INET, host->h_addrtype);
342 ASSERT_EQ(sizeof(in_addr_t), host->h_length);
343 ASSERT_STREQ("8.8.8.8", host->h_name);
344
345 in_addr_t** addr_list = reinterpret_cast<in_addr_t**>(host->h_addr_list);
346 ASSERT_NE(reinterpret_cast<in_addr_t**>(NULL), addr_list);
347 ASSERT_EQ(NULL, addr_list[1]);
348 ASSERT_EQ(inet_addr("8.8.8.8"), *addr_list[0]);
349 }
350
351 // These utility functions are only used for newlib (glibc provides its own
352 // implementations of these functions).
353 #if !defined(__GLIBC__)
354
355 TEST(SocketUtilityFunctions, Hstrerror) {
356 EXPECT_STREQ("Unknown error in gethostbyname: 2718.", hstrerror(2718));
357 }
358
359 TEST(SocketUtilityFunctions, Gai_Strerror) {
360 EXPECT_STREQ("Unknown error in getaddrinfo: 2719.", gai_strerror(2719));
361 }
362
363 #endif // !defined(__GLIBC__)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698