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