| OLD | NEW |
| 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__) |
| OLD | NEW |