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

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 #if defined(__GLIBC__) && defined(__linux__)
88 // When writing new tests for name resolution functions
89 // it can be useful to test directly against the system
90 // name resolution service.
91 //#define USE_SYSTEM_NS
92 #endif
93
94 #ifdef USE_SYSTEM_NS
95 #define ki_getaddrinfo getaddrinfo
96 #define ki_gethostbyname gethostbyname
97 #define ki_freeaddrinfo freeaddrinfo
98 #endif
99
100 TEST_F(HostResolverTest, Getaddrinfo_Numeric) {
101 struct addrinfo* ai = NULL;
102 struct sockaddr_in* in;
103 struct addrinfo hints;
104
105 // Numberic only
106 memset(&hints, 0, sizeof(hints));
107 hints.ai_family = AF_INET;
108 hints.ai_socktype = SOCK_STREAM;
109
110 uint32_t expected_addr = htonl(0x01020304);
111 ASSERT_EQ(0, ki_getaddrinfo("1.2.3.4", NULL, &hints, &ai));
112 ASSERT_NE(NULL_INFO, ai);
113 ASSERT_NE(NULL_ADDR, ai->ai_addr);
114 ASSERT_EQ(AF_INET, ai->ai_family);
115 ASSERT_EQ(SOCK_STREAM, ai->ai_socktype);
116 in = (struct sockaddr_in*)ai->ai_addr;
117 ASSERT_EQ(expected_addr, in->sin_addr.s_addr);
118 ASSERT_EQ(NULL_INFO, ai->ai_next);
119
120 ki_freeaddrinfo(ai);
121 }
122
123 #ifndef USE_SYSTEM_NS
124 TEST_F(HostResolverTest, Getaddrinfo_MissingPPAPI) {
125 // Verify that full lookups fail due to lack of PPAPI interfaces
126 struct addrinfo* ai = NULL;
127 ASSERT_EQ(EAI_SYSTEM, ki_getaddrinfo("google.com", NULL, NULL, &ai));
128 }
129 #endif
130
131 TEST_F(HostResolverTest, Getaddrinfo_Passive) {
132 struct addrinfo* ai = NULL;
133 struct sockaddr_in* in;
134 struct sockaddr_in6* in6;
135 struct addrinfo hints;
136 memset(&hints, 0, sizeof(hints));
137
138 uint32_t expected_port = htons(22);
139 in_addr_t expected_addr = htonl(INADDR_ANY);
140 in6_addr expected_addr6 = IN6ADDR_ANY_INIT;
141
142 // AI_PASSIVE means that the returned address will be a wildcard
143 // address suitable for binding and listening. This should not
144 // hit PPAPI at all, so we don't need fakes.
145 hints.ai_family = AF_INET;
146 hints.ai_flags = AI_PASSIVE;
147 hints.ai_socktype = SOCK_DGRAM;
148 ASSERT_EQ(0, ki_getaddrinfo(NULL, "22", &hints, &ai));
149 ASSERT_NE(NULL_INFO, ai);
150 ASSERT_NE(NULL_ADDR, ai->ai_addr);
151 ASSERT_EQ(NULL_INFO, ai->ai_next);
152 in = (struct sockaddr_in*)ai->ai_addr;
153 ASSERT_EQ(expected_addr, in->sin_addr.s_addr);
154 ASSERT_EQ(expected_port, in->sin_port);
155 ASSERT_EQ(AF_INET, in->sin_family);
156 ki_freeaddrinfo(ai);
157
158 // Same test with AF_INET6
159 hints.ai_family = AF_INET6;
160 ASSERT_EQ(0, ki_getaddrinfo(NULL, "22", &hints, &ai));
161 ASSERT_NE(NULL_INFO, ai);
162 ASSERT_NE(NULL_ADDR, ai->ai_addr);
163 ASSERT_EQ(NULL_INFO, ai->ai_next);
164 in6 = (struct sockaddr_in6*)ai->ai_addr;
165 ASSERT_EQ(expected_port, in6->sin6_port);
166 ASSERT_EQ(AF_INET6, in6->sin6_family);
167 ASSERT_EQ(0, memcmp(in6->sin6_addr.s6_addr,
168 &expected_addr6,
169 sizeof(expected_addr6)));
170 ki_freeaddrinfo(ai);
171 }
172
173 TEST_F(HostResolverTest, Getaddrinfo_Passive_Any) {
174 // Similar to Getaddrinfo_Passive but don't set
175 // ai_family in the hints, so we should get muplitple
176 // results back for the different families.
177 struct addrinfo* ai = NULL;
178 struct sockaddr_in* in;
179 struct sockaddr_in6* in6;
180 struct addrinfo hints;
181 memset(&hints, 0, sizeof(hints));
182
183 uint32_t expected_port = htons(22);
184 in_addr_t expected_addr = htonl(INADDR_ANY);
185 in6_addr expected_addr6 = IN6ADDR_ANY_INIT;
186
187 hints.ai_flags = AI_PASSIVE;
188 hints.ai_socktype = SOCK_DGRAM;
189 ASSERT_EQ(0, ki_getaddrinfo(NULL, "22", &hints, &ai));
190 ASSERT_NE(NULL_INFO, ai);
191 int count = 0;
192 bool got_v4 = false;
193 bool got_v6 = false;
194 while (ai) {
195 ASSERT_NE(NULL_ADDR, ai->ai_addr);
196 switch (ai->ai_addr->sa_family) {
197 case AF_INET:
198 in = (struct sockaddr_in*)ai->ai_addr;
199 ASSERT_EQ(expected_port, in->sin_port);
200 ASSERT_EQ(AF_INET, in->sin_family);
201 ASSERT_EQ(expected_addr, in->sin_addr.s_addr);
202 got_v4 = true;
203 break;
204 case AF_INET6:
205 in6 = (struct sockaddr_in6*)ai->ai_addr;
206 ASSERT_EQ(expected_port, in6->sin6_port);
207 ASSERT_EQ(AF_INET6, in6->sin6_family);
208 ASSERT_EQ(0, memcmp(in6->sin6_addr.s6_addr,
209 &expected_addr6,
210 sizeof(expected_addr6)));
211 got_v6 = true;
212 break;
213 default:
214 ASSERT_TRUE(false) << "Unknown address type: " << ai->ai_addr;
215 break;
216 }
217 ai = ai->ai_next;
218 count++;
219 }
220
221 ASSERT_EQ(2, count);
222 ASSERT_TRUE(got_v4);
223 ASSERT_TRUE(got_v6);
224 }
225
226 #ifndef USE_SYSTEM_NS
227
228 TEST_F(FakeHostResolverTest, Getaddrinfo_Lookup) {
229 struct addrinfo* ai = NULL;
230 struct sockaddr_in* in;
231 struct addrinfo hints;
232 memset(&hints, 0, sizeof(hints));
233
234 in_addr_t expected_addr = htonl(FAKE_IP);
235
236 // Lookup the fake hostname using getaddrinfo
237 hints.ai_family = AF_INET;
238 hints.ai_socktype = SOCK_STREAM;
239 ASSERT_EQ(0, ki_getaddrinfo(FAKE_HOSTNAME, NULL, &hints, &ai));
240 ASSERT_NE(NULL_INFO, ai);
241 ASSERT_NE(NULL_ADDR, ai->ai_addr);
242 ASSERT_EQ(AF_INET, ai->ai_family);
243 ASSERT_EQ(SOCK_STREAM, ai->ai_socktype);
244 in = (struct sockaddr_in*)ai->ai_addr;
245 ASSERT_EQ(expected_addr, in->sin_addr.s_addr);
246 ASSERT_EQ(NULL_INFO, ai->ai_next);
247
248 ki_freeaddrinfo(ai);
249 }
250 #endif
251
252 TEST_F(FakeHostResolverTest, Getaddrinfo_Multi) {
253 struct addrinfo* ai = NULL;
254 struct addrinfo hints;
255 memset(&hints, 0, sizeof(hints));
256
257 // Add four fake address on top of the initial one
258 // that the fixture creates.
259 AddFakeAddress(AF_INET);
260 AddFakeAddress(AF_INET);
261 AddFakeAddress(AF_INET6);
262 AddFakeAddress(AF_INET6);
263
264 hints.ai_socktype = SOCK_STREAM;
265
266 // First we test with AF_INET
267 hints.ai_family = AF_INET;
268 ASSERT_EQ(0, ki_getaddrinfo(FAKE_HOSTNAME, NULL, &hints, &ai));
269 ASSERT_NE(NULL_INFO, ai);
270
271 // We expect to be returned 3 AF_INET address with
272 // address FAKE_IP, FAKE_IP+1 and FAKE_IP+2, since that
273 // is that the fake was seeded with.
274 uint32_t expected_addr = htonl(FAKE_IP);
275 int count = 0;
276 struct addrinfo* current = ai;
277 while (current != NULL) {
278 ASSERT_NE(NULL_ADDR, current->ai_addr);
279 ASSERT_EQ(AF_INET, current->ai_family);
280 ASSERT_EQ(SOCK_STREAM, current->ai_socktype);
281 sockaddr_in* in = (sockaddr_in*)current->ai_addr;
282 ASSERT_EQ(expected_addr, in->sin_addr.s_addr);
283 expected_addr += htonl(1);
284 current = current->ai_next;
285 count++;
286 }
287 ASSERT_EQ(3, count);
288 ki_freeaddrinfo(ai);
289
290 // Same test but with AF_INET6
291 hints.ai_family = AF_INET6;
292 ASSERT_EQ(0, ki_getaddrinfo(FAKE_HOSTNAME, NULL, &hints, &ai));
293 ASSERT_NE(NULL_INFO, ai);
294
295 count = 0;
296 current = ai;
297 while (current != NULL) {
298 ASSERT_NE(NULL_ADDR, current->ai_addr);
299 ASSERT_EQ(AF_INET6, current->ai_family);
300 ASSERT_EQ(SOCK_STREAM, current->ai_socktype);
301 sockaddr_in6* in = (sockaddr_in6*)current->ai_addr;
302 for (int i = 0; i < 16; i++) {
303 ASSERT_EQ(i + count, in->sin6_addr.s6_addr[i]);
304 }
305 current = current->ai_next;
306 count++;
307 }
308 ASSERT_EQ(2, count);
309 ki_freeaddrinfo(ai);
310
311 // Same test but with AF_UNSPEC. Here we expect to get
312 // 5 address back: 3 * v4 and 2 * v6.
313 hints.ai_family = AF_UNSPEC;
314 ASSERT_EQ(0, ki_getaddrinfo(FAKE_HOSTNAME, NULL, &hints, &ai));
315 ASSERT_NE(NULL_INFO, ai);
316
317 count = 0;
318 current = ai;
319 while (current != NULL) {
320 ASSERT_NE(NULL_ADDR, ai->ai_addr);
321 ASSERT_EQ(SOCK_STREAM, ai->ai_socktype);
322 current = current->ai_next;
323 count++;
324 }
325 ASSERT_EQ(5, count);
326
327 ki_freeaddrinfo(ai);
328 }
329
330 TEST_F(FakeHostResolverTest, Gethostbyname) {
42 hostent* host = ki_gethostbyname(FAKE_HOSTNAME); 331 hostent* host = ki_gethostbyname(FAKE_HOSTNAME);
43 332
44 // Verify the returned hostent structure 333 // Verify the returned hostent structure
45 ASSERT_NE(NULL_HOST, host); 334 ASSERT_NE(NULL_HOST, host);
46 ASSERT_EQ(AF_INET, host->h_addrtype); 335 ASSERT_EQ(AF_INET, host->h_addrtype);
47 ASSERT_EQ(sizeof(in_addr_t), host->h_length); 336 ASSERT_EQ(sizeof(in_addr_t), host->h_length);
48 ASSERT_STREQ(FAKE_HOSTNAME, host->h_name); 337 ASSERT_STREQ(FAKE_HOSTNAME, host->h_name);
49 338
50 in_addr_t** addr_list = reinterpret_cast<in_addr_t**>(host->h_addr_list); 339 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); 340 ASSERT_NE(reinterpret_cast<in_addr_t**>(NULL), addr_list);
52 ASSERT_EQ(NULL, addr_list[1]); 341 ASSERT_EQ(NULL, addr_list[1]);
53 in_addr_t exptected_addr = htonl(FAKE_IP); 342 in_addr_t exptected_addr = htonl(FAKE_IP);
54 ASSERT_EQ(exptected_addr, *addr_list[0]); 343 ASSERT_EQ(exptected_addr, *addr_list[0]);
55 } 344 }
345
346 TEST_F(FakeHostResolverTest, Gethostbyname_Failure) {
347 hostent* host = ki_gethostbyname("nosuchhost.com");
348 ASSERT_EQ(NULL_HOST, host);
349 ASSERT_EQ(HOST_NOT_FOUND, h_errno);
350 }
351
352 // Looking up purely numeric hostnames should work without PPAPI
353 // so we don't need the fakes for this test
354 TEST_F(HostResolverTest, Gethostbyname_Numeric) {
355 struct hostent* host = ki_gethostbyname("8.8.8.8");
356
357 // Verify the returned hostent structure
358 ASSERT_NE(NULL_HOST, host);
359 ASSERT_EQ(AF_INET, host->h_addrtype);
360 ASSERT_EQ(sizeof(in_addr_t), host->h_length);
361 ASSERT_STREQ("8.8.8.8", host->h_name);
362
363 in_addr_t** addr_list = reinterpret_cast<in_addr_t**>(host->h_addr_list);
364 ASSERT_NE(reinterpret_cast<in_addr_t**>(NULL), addr_list);
365 ASSERT_EQ(NULL, addr_list[1]);
366 ASSERT_EQ(inet_addr("8.8.8.8"), *addr_list[0]);
367 }
368
369 // These utility functions are only used for newlib (glibc provides its own
370 // implementations of these functions).
371 #if !defined(__GLIBC__)
372
373 TEST(SocketUtilityFunctions, Hstrerror) {
374 EXPECT_STREQ("Unknown error in gethostbyname: 2718.", hstrerror(2718));
375 }
376
377 TEST(SocketUtilityFunctions, Gai_Strerror) {
378 EXPECT_STREQ("Unknown error in getaddrinfo: 2719.", gai_strerror(2719));
379 }
380
381 #endif // !defined(__GLIBC__)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698