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

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

Powered by Google App Engine
This is Rietveld 408576698