This source file includes following definitions.
- SetUp
- TearDown
- fake_resolver_
- SetUp
- AddFakeAddress
- TearDown
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST
- TEST
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "fake_ppapi/fake_pepper_interface.h"
#include "gtest/gtest.h"
#include "nacl_io/kernel_intercept.h"
using namespace nacl_io;
using namespace sdk_util;
namespace {
class HostResolverTest : public ::testing::Test {
public:
HostResolverTest() {}
void SetUp() {
ASSERT_EQ(0, ki_push_state_for_testing());
ASSERT_EQ(0, ki_init(NULL));
}
void TearDown() {
ki_uninit();
}
};
#define FAKE_HOSTNAME "example.com"
#define FAKE_IP 0x01020304
class FakeHostResolverTest : public ::testing::Test {
public:
FakeHostResolverTest() : pepper_(NULL), fake_resolver_(NULL) {}
void SetUp() {
pepper_ = new FakePepperInterface();
fake_resolver_ = static_cast<FakeHostResolverInterface*>(
pepper_->GetHostResolverInterface());
fake_resolver_->fake_hostname = FAKE_HOSTNAME;
AddFakeAddress(AF_INET);
ASSERT_EQ(0, ki_push_state_for_testing());
ASSERT_EQ(0, ki_init_interface(NULL, pepper_));
}
void AddFakeAddress(int family) {
if (family == AF_INET) {
int address_count = fake_resolver_->fake_addresses_v4.size();
sockaddr_in fake_addr;
fake_addr.sin_family = family;
fake_addr.sin_addr.s_addr = htonl(FAKE_IP + address_count);
fake_resolver_->fake_addresses_v4.push_back(fake_addr);
} else if (family == AF_INET6) {
sockaddr_in6 fake_addr;
fake_addr.sin6_family = family;
int address_count = fake_resolver_->fake_addresses_v6.size();
for (uint8_t i = 0; i < 16; i++) {
fake_addr.sin6_addr.s6_addr[i] = i + address_count;
}
fake_resolver_->fake_addresses_v6.push_back(fake_addr);
}
}
void TearDown() {
ki_uninit();
pepper_ = NULL;
}
protected:
FakePepperInterface* pepper_;
FakeHostResolverInterface* fake_resolver_;
};
}
#define NULL_INFO ((struct addrinfo*)NULL)
#define NULL_ADDR ((struct sockaddr*)NULL)
#define NULL_HOST (static_cast<hostent*>(NULL))
TEST_F(HostResolverTest, Getaddrinfo_Numeric) {
struct addrinfo* ai = NULL;
struct sockaddr_in* in;
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
uint32_t expected_addr = htonl(0x01020304);
ASSERT_EQ(0, ki_getaddrinfo("1.2.3.4", NULL, &hints, &ai));
ASSERT_NE(NULL_INFO, ai);
ASSERT_NE(NULL_ADDR, ai->ai_addr);
ASSERT_EQ(AF_INET, ai->ai_family);
ASSERT_EQ(SOCK_STREAM, ai->ai_socktype);
in = (struct sockaddr_in*)ai->ai_addr;
ASSERT_EQ(expected_addr, in->sin_addr.s_addr);
ASSERT_EQ(NULL_INFO, ai->ai_next);
ki_freeaddrinfo(ai);
}
TEST_F(HostResolverTest, Getaddrinfo_MissingPPAPI) {
struct addrinfo* ai = NULL;
ASSERT_EQ(EAI_SYSTEM, ki_getaddrinfo("google.com", NULL, NULL, &ai));
}
TEST_F(HostResolverTest, Getaddrinfo_Passive) {
struct addrinfo* ai = NULL;
struct sockaddr_in* in;
struct sockaddr_in6* in6;
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
uint32_t expected_port = htons(22);
in_addr_t expected_addr = htonl(INADDR_ANY);
in6_addr expected_addr6 = IN6ADDR_ANY_INIT;
hints.ai_family = AF_INET;
hints.ai_flags = AI_PASSIVE;
hints.ai_socktype = SOCK_DGRAM;
ASSERT_EQ(0, ki_getaddrinfo(NULL, "22", &hints, &ai));
ASSERT_NE(NULL_INFO, ai);
ASSERT_NE(NULL_ADDR, ai->ai_addr);
ASSERT_EQ(NULL_INFO, ai->ai_next);
in = (struct sockaddr_in*)ai->ai_addr;
ASSERT_EQ(expected_addr, in->sin_addr.s_addr);
ASSERT_EQ(expected_port, in->sin_port);
ASSERT_EQ(AF_INET, in->sin_family);
ki_freeaddrinfo(ai);
hints.ai_family = AF_INET6;
ASSERT_EQ(0, ki_getaddrinfo(NULL, "22", &hints, &ai));
ASSERT_NE(NULL_INFO, ai);
ASSERT_NE(NULL_ADDR, ai->ai_addr);
ASSERT_EQ(NULL_INFO, ai->ai_next);
in6 = (struct sockaddr_in6*)ai->ai_addr;
ASSERT_EQ(expected_port, in6->sin6_port);
ASSERT_EQ(AF_INET6, in6->sin6_family);
ASSERT_EQ(0, memcmp(in6->sin6_addr.s6_addr,
&expected_addr6,
sizeof(expected_addr6)));
ki_freeaddrinfo(ai);
}
TEST_F(HostResolverTest, Getaddrinfo_Passive_Any) {
struct addrinfo* ai = NULL;
struct sockaddr_in* in;
struct sockaddr_in6* in6;
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
uint32_t expected_port = htons(22);
in_addr_t expected_addr = htonl(INADDR_ANY);
in6_addr expected_addr6 = IN6ADDR_ANY_INIT;
hints.ai_flags = AI_PASSIVE;
hints.ai_socktype = SOCK_DGRAM;
ASSERT_EQ(0, ki_getaddrinfo(NULL, "22", &hints, &ai));
ASSERT_NE(NULL_INFO, ai);
int count = 0;
bool got_v4 = false;
bool got_v6 = false;
while (ai) {
ASSERT_NE(NULL_ADDR, ai->ai_addr);
switch (ai->ai_addr->sa_family) {
case AF_INET:
in = (struct sockaddr_in*)ai->ai_addr;
ASSERT_EQ(expected_port, in->sin_port);
ASSERT_EQ(AF_INET, in->sin_family);
ASSERT_EQ(expected_addr, in->sin_addr.s_addr);
got_v4 = true;
break;
case AF_INET6:
in6 = (struct sockaddr_in6*)ai->ai_addr;
ASSERT_EQ(expected_port, in6->sin6_port);
ASSERT_EQ(AF_INET6, in6->sin6_family);
ASSERT_EQ(0, memcmp(in6->sin6_addr.s6_addr,
&expected_addr6,
sizeof(expected_addr6)));
got_v6 = true;
break;
default:
ASSERT_TRUE(false) << "Unknown address type: " << ai->ai_addr;
break;
}
ai = ai->ai_next;
count++;
}
ASSERT_EQ(2, count);
ASSERT_TRUE(got_v4);
ASSERT_TRUE(got_v6);
}
TEST_F(FakeHostResolverTest, Getaddrinfo_Lookup) {
struct addrinfo* ai = NULL;
struct sockaddr_in* in;
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
in_addr_t expected_addr = htonl(FAKE_IP);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
ASSERT_EQ(0, ki_getaddrinfo(FAKE_HOSTNAME, NULL, &hints, &ai));
ASSERT_NE(NULL_INFO, ai);
ASSERT_NE(NULL_ADDR, ai->ai_addr);
ASSERT_EQ(AF_INET, ai->ai_family);
ASSERT_EQ(SOCK_STREAM, ai->ai_socktype);
in = (struct sockaddr_in*)ai->ai_addr;
ASSERT_EQ(expected_addr, in->sin_addr.s_addr);
ASSERT_EQ(NULL_INFO, ai->ai_next);
ki_freeaddrinfo(ai);
}
TEST_F(FakeHostResolverTest, Getaddrinfo_Multi) {
struct addrinfo* ai = NULL;
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
AddFakeAddress(AF_INET);
AddFakeAddress(AF_INET);
AddFakeAddress(AF_INET6);
AddFakeAddress(AF_INET6);
hints.ai_socktype = SOCK_STREAM;
hints.ai_family = AF_INET;
ASSERT_EQ(0, ki_getaddrinfo(FAKE_HOSTNAME, NULL, &hints, &ai));
ASSERT_NE(NULL_INFO, ai);
uint32_t expected_addr = htonl(FAKE_IP);
int count = 0;
struct addrinfo* current = ai;
while (current != NULL) {
ASSERT_NE(NULL_ADDR, current->ai_addr);
ASSERT_EQ(AF_INET, current->ai_family);
ASSERT_EQ(SOCK_STREAM, current->ai_socktype);
sockaddr_in* in = (sockaddr_in*)current->ai_addr;
ASSERT_EQ(expected_addr, in->sin_addr.s_addr);
expected_addr += htonl(1);
current = current->ai_next;
count++;
}
ASSERT_EQ(3, count);
ki_freeaddrinfo(ai);
hints.ai_family = AF_INET6;
ASSERT_EQ(0, ki_getaddrinfo(FAKE_HOSTNAME, NULL, &hints, &ai));
ASSERT_NE(NULL_INFO, ai);
count = 0;
current = ai;
while (current != NULL) {
ASSERT_NE(NULL_ADDR, current->ai_addr);
ASSERT_EQ(AF_INET6, current->ai_family);
ASSERT_EQ(SOCK_STREAM, current->ai_socktype);
sockaddr_in6* in = (sockaddr_in6*)current->ai_addr;
for (int i = 0; i < 16; i++) {
ASSERT_EQ(i + count, in->sin6_addr.s6_addr[i]);
}
current = current->ai_next;
count++;
}
ASSERT_EQ(2, count);
ki_freeaddrinfo(ai);
hints.ai_family = AF_UNSPEC;
ASSERT_EQ(0, ki_getaddrinfo(FAKE_HOSTNAME, NULL, &hints, &ai));
ASSERT_NE(NULL_INFO, ai);
count = 0;
current = ai;
while (current != NULL) {
ASSERT_NE(NULL_ADDR, ai->ai_addr);
ASSERT_EQ(SOCK_STREAM, ai->ai_socktype);
current = current->ai_next;
count++;
}
ASSERT_EQ(5, count);
ki_freeaddrinfo(ai);
}
TEST_F(FakeHostResolverTest, Gethostbyname) {
hostent* host = ki_gethostbyname(FAKE_HOSTNAME);
ASSERT_NE(NULL_HOST, host);
ASSERT_EQ(AF_INET, host->h_addrtype);
ASSERT_EQ(sizeof(in_addr_t), host->h_length);
ASSERT_STREQ(FAKE_HOSTNAME, host->h_name);
in_addr_t** addr_list = reinterpret_cast<in_addr_t**>(host->h_addr_list);
ASSERT_NE(reinterpret_cast<in_addr_t**>(NULL), addr_list);
ASSERT_EQ(NULL, addr_list[1]);
in_addr_t exptected_addr = htonl(FAKE_IP);
ASSERT_EQ(exptected_addr, *addr_list[0]);
}
TEST_F(FakeHostResolverTest, Gethostbyname_Failure) {
hostent* host = ki_gethostbyname("nosuchhost.com");
ASSERT_EQ(NULL_HOST, host);
ASSERT_EQ(HOST_NOT_FOUND, h_errno);
}
TEST_F(HostResolverTest, Gethostbyname_Numeric) {
struct hostent* host = ki_gethostbyname("8.8.8.8");
ASSERT_NE(NULL_HOST, host);
ASSERT_EQ(AF_INET, host->h_addrtype);
ASSERT_EQ(sizeof(in_addr_t), host->h_length);
ASSERT_STREQ("8.8.8.8", host->h_name);
in_addr_t** addr_list = reinterpret_cast<in_addr_t**>(host->h_addr_list);
ASSERT_NE(reinterpret_cast<in_addr_t**>(NULL), addr_list);
ASSERT_EQ(NULL, addr_list[1]);
ASSERT_EQ(inet_addr("8.8.8.8"), *addr_list[0]);
}
#if !defined(__GLIBC__)
TEST(SocketUtilityFunctions, Hstrerror) {
EXPECT_STREQ("Unknown error in gethostbyname: 2718.", hstrerror(2718));
}
TEST(SocketUtilityFunctions, Gai_Strerror) {
EXPECT_STREQ("Unknown error in getaddrinfo: 2719.", gai_strerror(2719));
}
#endif