15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <arpa/inet.h>
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <netinet/in.h>
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <sys/types.h>
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <sys/socket.h>
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "fake_ppapi/fake_pepper_interface.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "gtest/gtest.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nacl_io/kernel_intercept.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using namespace nacl_io;
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using namespace sdk_util;
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class HostResolverTest : public ::testing::Test {
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  HostResolverTest() {}
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void SetUp() {
24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ASSERT_EQ(0, ki_push_state_for_testing());
25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ASSERT_EQ(0, ki_init(NULL));
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void TearDown() {
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ki_uninit();
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define FAKE_HOSTNAME "example.com"
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define FAKE_IP 0x01020304
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class FakeHostResolverTest : public ::testing::Test {
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
38010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  FakeHostResolverTest() : fake_resolver_(NULL) {}
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void SetUp() {
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    fake_resolver_ = static_cast<FakeHostResolverInterface*>(
42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        pepper_.GetHostResolverInterface());
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Seed the fake resolver with some data
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    fake_resolver_->fake_hostname = FAKE_HOSTNAME;
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    AddFakeAddress(AF_INET);
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ASSERT_EQ(0, ki_push_state_for_testing());
49010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    ASSERT_EQ(0, ki_init_interface(NULL, &pepper_));
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void AddFakeAddress(int family) {
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (family == AF_INET) {
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      int address_count = fake_resolver_->fake_addresses_v4.size();
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Each new address we add is FAKE_IP incremented by 1
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // each time to be unique.
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      sockaddr_in fake_addr;
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      fake_addr.sin_family = family;
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      fake_addr.sin_addr.s_addr = htonl(FAKE_IP + address_count);
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      fake_resolver_->fake_addresses_v4.push_back(fake_addr);
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else if (family == AF_INET6) {
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      sockaddr_in6 fake_addr;
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      fake_addr.sin6_family = family;
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      int address_count = fake_resolver_->fake_addresses_v6.size();
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      for (uint8_t i = 0; i < 16; i++) {
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        fake_addr.sin6_addr.s6_addr[i] = i + address_count;
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      fake_resolver_->fake_addresses_v6.push_back(fake_addr);
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void TearDown() {
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ki_uninit();
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected:
77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  FakePepperInterface pepper_;
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FakeHostResolverInterface* fake_resolver_;
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define NULL_INFO ((struct addrinfo*)NULL)
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define NULL_ADDR ((struct sockaddr*)NULL)
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define NULL_HOST (static_cast<hostent*>(NULL))
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(HostResolverTest, Getaddrinfo_Numeric) {
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct addrinfo* ai = NULL;
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct sockaddr_in* in;
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct addrinfo hints;
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
926d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // Numeric only
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  memset(&hints, 0, sizeof(hints));
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  hints.ai_family = AF_INET;
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  hints.ai_socktype = SOCK_STREAM;
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint32_t expected_addr = htonl(0x01020304);
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(0, ki_getaddrinfo("1.2.3.4", NULL, &hints, &ai));
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_NE(NULL_INFO, ai);
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_NE(NULL_ADDR, ai->ai_addr);
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(AF_INET, ai->ai_family);
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(SOCK_STREAM, ai->ai_socktype);
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  in = (struct sockaddr_in*)ai->ai_addr;
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(expected_addr, in->sin_addr.s_addr);
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(NULL_INFO, ai->ai_next);
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ki_freeaddrinfo(ai);
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1106d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(HostResolverTest, Getaddrinfo_NumericService) {
1116d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  struct addrinfo* ai = NULL;
1126d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  struct sockaddr_in* in;
1136d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  struct addrinfo hints;
1146d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1156d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  memset(&hints, 0, sizeof(hints));
1166d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  hints.ai_family = AF_INET;
1176d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  hints.ai_socktype = SOCK_STREAM;
1186d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ASSERT_EQ(0, ki_getaddrinfo("1.2.3.4", "0", &hints, &ai));
1206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ASSERT_NE(NULL_INFO, ai);
1216d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ASSERT_NE(NULL_ADDR, ai->ai_addr);
1226d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  in = (struct sockaddr_in*)ai->ai_addr;
1236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  uint16_t expected_port = htons(0);
1246d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ASSERT_EQ(expected_port, in->sin_port);
1256d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ASSERT_EQ(NULL_INFO, ai->ai_next);
1266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ki_freeaddrinfo(ai);
1276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ASSERT_EQ(0, ki_getaddrinfo("1.2.3.4", "65000", &hints, &ai));
1296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ASSERT_NE(NULL_INFO, ai);
1306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ASSERT_NE(NULL_ADDR, ai->ai_addr);
1316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  in = (struct sockaddr_in*)ai->ai_addr;
1326d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  expected_port = htons(65000);
1336d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ASSERT_EQ(expected_port, in->sin_port);
1346d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ASSERT_EQ(NULL_INFO, ai->ai_next);
1356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ki_freeaddrinfo(ai);
1366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
1376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(HostResolverTest, Getaddrinfo_MissingPPAPI) {
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Verify that full lookups fail due to lack of PPAPI interfaces
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct addrinfo* ai = NULL;
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(EAI_SYSTEM, ki_getaddrinfo("google.com", NULL, NULL, &ai));
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(HostResolverTest, Getaddrinfo_Passive) {
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct addrinfo* ai = NULL;
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct sockaddr_in* in;
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct sockaddr_in6* in6;
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct addrinfo hints;
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  memset(&hints, 0, sizeof(hints));
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint32_t expected_port = htons(22);
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  in_addr_t expected_addr = htonl(INADDR_ANY);
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  in6_addr expected_addr6 = IN6ADDR_ANY_INIT;
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // AI_PASSIVE means that the returned address will be a wildcard
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // address suitable for binding and listening.  This should not
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // hit PPAPI at all, so we don't need fakes.
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  hints.ai_family = AF_INET;
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  hints.ai_flags = AI_PASSIVE;
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  hints.ai_socktype = SOCK_DGRAM;
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(0, ki_getaddrinfo(NULL, "22", &hints, &ai));
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_NE(NULL_INFO, ai);
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_NE(NULL_ADDR, ai->ai_addr);
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(NULL_INFO, ai->ai_next);
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  in = (struct sockaddr_in*)ai->ai_addr;
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(expected_addr, in->sin_addr.s_addr);
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(expected_port, in->sin_port);
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(AF_INET, in->sin_family);
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ki_freeaddrinfo(ai);
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Same test with AF_INET6
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  hints.ai_family = AF_INET6;
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(0, ki_getaddrinfo(NULL, "22", &hints, &ai));
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_NE(NULL_INFO, ai);
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_NE(NULL_ADDR, ai->ai_addr);
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(NULL_INFO, ai->ai_next);
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  in6 = (struct sockaddr_in6*)ai->ai_addr;
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(expected_port, in6->sin6_port);
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(AF_INET6, in6->sin6_family);
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(0, memcmp(in6->sin6_addr.s6_addr,
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)               &expected_addr6,
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)               sizeof(expected_addr6)));
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ki_freeaddrinfo(ai);
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(HostResolverTest, Getaddrinfo_Passive_Any) {
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Similar to Getaddrinfo_Passive but don't set
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // ai_family in the hints, so we should get muplitple
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // results back for the different families.
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct addrinfo* ai = NULL;
191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  struct addrinfo* ai_orig = NULL;
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct sockaddr_in* in;
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct sockaddr_in6* in6;
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct addrinfo hints;
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  memset(&hints, 0, sizeof(hints));
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint32_t expected_port = htons(22);
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  in_addr_t expected_addr = htonl(INADDR_ANY);
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  in6_addr expected_addr6 = IN6ADDR_ANY_INIT;
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  hints.ai_flags = AI_PASSIVE;
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  hints.ai_socktype = SOCK_DGRAM;
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(0, ki_getaddrinfo(NULL, "22", &hints, &ai));
204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ai_orig = ai;
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_NE(NULL_INFO, ai);
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int count = 0;
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool got_v4 = false;
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool got_v6 = false;
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  while (ai) {
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_NE(NULL_ADDR, ai->ai_addr);
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    switch (ai->ai_addr->sa_family) {
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case AF_INET:
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        in = (struct sockaddr_in*)ai->ai_addr;
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        ASSERT_EQ(expected_port, in->sin_port);
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        ASSERT_EQ(AF_INET, in->sin_family);
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        ASSERT_EQ(expected_addr, in->sin_addr.s_addr);
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        got_v4 = true;
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case AF_INET6:
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        in6 = (struct sockaddr_in6*)ai->ai_addr;
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        ASSERT_EQ(expected_port, in6->sin6_port);
2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        ASSERT_EQ(AF_INET6, in6->sin6_family);
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        ASSERT_EQ(0, memcmp(in6->sin6_addr.s6_addr,
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            &expected_addr6,
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            sizeof(expected_addr6)));
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        got_v6 = true;
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      default:
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        ASSERT_TRUE(false) << "Unknown address type: " << ai->ai_addr;
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ai = ai->ai_next;
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    count++;
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(2, count);
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(got_v4);
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(got_v6);
239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ki_freeaddrinfo(ai_orig);
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(FakeHostResolverTest, Getaddrinfo_Lookup) {
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct addrinfo* ai = NULL;
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct sockaddr_in* in;
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct addrinfo hints;
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  memset(&hints, 0, sizeof(hints));
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  in_addr_t expected_addr = htonl(FAKE_IP);
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Lookup the fake hostname using getaddrinfo
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  hints.ai_family = AF_INET;
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  hints.ai_socktype = SOCK_STREAM;
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(0, ki_getaddrinfo(FAKE_HOSTNAME, NULL, &hints, &ai));
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_NE(NULL_INFO, ai);
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_NE(NULL_ADDR, ai->ai_addr);
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(AF_INET, ai->ai_family);
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(SOCK_STREAM, ai->ai_socktype);
2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  in = (struct sockaddr_in*)ai->ai_addr;
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(expected_addr, in->sin_addr.s_addr);
2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(NULL_INFO, ai->ai_next);
2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ki_freeaddrinfo(ai);
2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(FakeHostResolverTest, Getaddrinfo_Multi) {
2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct addrinfo* ai = NULL;
2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct addrinfo hints;
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  memset(&hints, 0, sizeof(hints));
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Add four fake address on top of the initial one
2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // that the fixture creates.
2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AddFakeAddress(AF_INET);
2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AddFakeAddress(AF_INET);
2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AddFakeAddress(AF_INET6);
2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AddFakeAddress(AF_INET6);
2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  hints.ai_socktype = SOCK_STREAM;
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // First we test with AF_INET
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  hints.ai_family = AF_INET;
2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(0, ki_getaddrinfo(FAKE_HOSTNAME, NULL, &hints, &ai));
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_NE(NULL_INFO, ai);
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We expect to be returned 3 AF_INET address with
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // address FAKE_IP, FAKE_IP+1 and FAKE_IP+2, since that
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // is that the fake was seeded with.
2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint32_t expected_addr = htonl(FAKE_IP);
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int count = 0;
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct addrinfo* current = ai;
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  while (current != NULL) {
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_NE(NULL_ADDR, current->ai_addr);
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_EQ(AF_INET, current->ai_family);
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_EQ(SOCK_STREAM, current->ai_socktype);
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    sockaddr_in* in = (sockaddr_in*)current->ai_addr;
2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_EQ(expected_addr, in->sin_addr.s_addr);
2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    expected_addr += htonl(1);
2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    current = current->ai_next;
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    count++;
3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(3, count);
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ki_freeaddrinfo(ai);
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Same test but with AF_INET6
3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  hints.ai_family = AF_INET6;
3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(0, ki_getaddrinfo(FAKE_HOSTNAME, NULL, &hints, &ai));
3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_NE(NULL_INFO, ai);
3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  count = 0;
3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  current = ai;
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  while (current != NULL) {
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_NE(NULL_ADDR, current->ai_addr);
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_EQ(AF_INET6, current->ai_family);
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_EQ(SOCK_STREAM, current->ai_socktype);
3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    sockaddr_in6* in = (sockaddr_in6*)current->ai_addr;
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for (int i = 0; i < 16; i++) {
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ASSERT_EQ(i + count, in->sin6_addr.s6_addr[i]);
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    current = current->ai_next;
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    count++;
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(2, count);
3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ki_freeaddrinfo(ai);
3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Same test but with AF_UNSPEC.  Here we expect to get
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // 5 address back: 3 * v4 and 2 * v6.
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  hints.ai_family = AF_UNSPEC;
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(0, ki_getaddrinfo(FAKE_HOSTNAME, NULL, &hints, &ai));
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_NE(NULL_INFO, ai);
3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  count = 0;
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  current = ai;
3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  while (current != NULL) {
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_NE(NULL_ADDR, ai->ai_addr);
3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_EQ(SOCK_STREAM, ai->ai_socktype);
3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    current = current->ai_next;
3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    count++;
3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(5, count);
3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ki_freeaddrinfo(ai);
3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(FakeHostResolverTest, Gethostbyname) {
3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  hostent* host = ki_gethostbyname(FAKE_HOSTNAME);
3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Verify the returned hostent structure
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_NE(NULL_HOST, host);
3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(AF_INET, host->h_addrtype);
3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(sizeof(in_addr_t), host->h_length);
3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_STREQ(FAKE_HOSTNAME, host->h_name);
3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  in_addr_t** addr_list = reinterpret_cast<in_addr_t**>(host->h_addr_list);
3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_NE(reinterpret_cast<in_addr_t**>(NULL), addr_list);
3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(NULL, addr_list[1]);
356cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  in_addr_t expected_addr = htonl(FAKE_IP);
357cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_EQ(expected_addr, *addr_list[0]);
358cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Check that h_addr also matches as in some libc's it may be a separate
359cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // member.
360cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  in_addr_t* first_addr = reinterpret_cast<in_addr_t*>(host->h_addr);
361cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_EQ(expected_addr, *first_addr);
3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(FakeHostResolverTest, Gethostbyname_Failure) {
3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  hostent* host = ki_gethostbyname("nosuchhost.com");
3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(NULL_HOST, host);
3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(HOST_NOT_FOUND, h_errno);
3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Looking up purely numeric hostnames should work without PPAPI
3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// so we don't need the fakes for this test
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(HostResolverTest, Gethostbyname_Numeric) {
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct hostent* host = ki_gethostbyname("8.8.8.8");
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Verify the returned hostent structure
3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_NE(NULL_HOST, host);
3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(AF_INET, host->h_addrtype);
3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(sizeof(in_addr_t), host->h_length);
3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_STREQ("8.8.8.8", host->h_name);
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  in_addr_t** addr_list = reinterpret_cast<in_addr_t**>(host->h_addr_list);
3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_NE(reinterpret_cast<in_addr_t**>(NULL), addr_list);
3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(NULL, addr_list[1]);
3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(inet_addr("8.8.8.8"), *addr_list[0]);
385cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Check that h_addr also matches as in some libc's it may be a separate
386cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // member.
387cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  in_addr_t* first_addr = reinterpret_cast<in_addr_t*>(host->h_addr);
388cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_EQ(inet_addr("8.8.8.8"), *first_addr);
3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// These utility functions are only used for newlib (glibc provides its own
3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// implementations of these functions).
3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if !defined(__GLIBC__)
3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST(SocketUtilityFunctions, Hstrerror) {
3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_STREQ("Unknown error in gethostbyname: 2718.", hstrerror(2718));
3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST(SocketUtilityFunctions, Gai_Strerror) {
4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_STREQ("Unknown error in getaddrinfo: 2719.", gai_strerror(2719));
4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif  // !defined(__GLIBC__)
404