1bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved. 2bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// found in the LICENSE file. 4bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 56d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#ifndef __STDC_LIMIT_MACROS 66d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#define __STDC_LIMIT_MACROS 76d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#endif 86d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 9bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "nacl_io/host_resolver.h" 10bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <assert.h> 126d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include <stdint.h> 13bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include <stdlib.h> 14bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include <string.h> 15bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 16bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "nacl_io/kernel_proxy.h" 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "nacl_io/log.h" 18bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "nacl_io/ossocket.h" 19bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "nacl_io/pepper_interface.h" 20bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 21bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#ifdef PROVIDES_SOCKET_API 22bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void HintsToPPHints(const addrinfo* hints, PP_HostResolver_Hint* pp_hints) { 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) memset(pp_hints, 0, sizeof(*pp_hints)); 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (hints->ai_family == AF_INET) 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pp_hints->family = PP_NETADDRESS_FAMILY_IPV4; 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else if (hints->ai_family == AF_INET6) 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pp_hints->family = PP_NETADDRESS_FAMILY_IPV6; 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (hints->ai_flags & AI_CANONNAME) 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pp_hints->flags = PP_HOSTRESOLVER_FLAG_CANONNAME; 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CreateAddrInfo(const addrinfo* hints, 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct sockaddr* addr, 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const char* name, 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) addrinfo** list_start, 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) addrinfo** list_end) { 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) addrinfo* ai = static_cast<addrinfo*>(malloc(sizeof(addrinfo))); 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) memset(ai, 0, sizeof(*ai)); 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (hints && hints->ai_socktype) 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ai->ai_socktype = hints->ai_socktype; 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ai->ai_socktype = SOCK_STREAM; 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (hints && hints->ai_protocol) 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ai->ai_protocol = hints->ai_protocol; 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (name) 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ai->ai_canonname = strdup(name); 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) switch (addr->sa_family) { 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case AF_INET6: { 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sockaddr_in6* in = 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static_cast<sockaddr_in6*>(malloc(sizeof(sockaddr_in6))); 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *in = *(sockaddr_in6*)addr; 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ai->ai_family = AF_INET6; 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ai->ai_addr = reinterpret_cast<sockaddr*>(in); 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ai->ai_addrlen = sizeof(*in); 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case AF_INET: { 6746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) sockaddr_in* in = static_cast<sockaddr_in*>(malloc(sizeof(sockaddr_in))); 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *in = *(sockaddr_in*)addr; 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ai->ai_family = AF_INET; 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ai->ai_addr = reinterpret_cast<sockaddr*>(in); 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ai->ai_addrlen = sizeof(*in); 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) default: 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert(0); 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (*list_start == NULL) { 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *list_start = ai; 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *list_end = ai; 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (*list_end)->ai_next = ai; 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *list_end = ai; 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 91bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochnamespace nacl_io { 92bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 93bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochHostResolver::HostResolver() : hostent_(), ppapi_(NULL) { 94bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 95bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 96bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochHostResolver::~HostResolver() { 97bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch hostent_cleanup(); 98bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 99bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 100bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochvoid HostResolver::Init(PepperInterface* ppapi) { 101bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch ppapi_ = ppapi; 102bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 103bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 104bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochstruct hostent* HostResolver::gethostbyname(const char* name) { 105bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch h_errno = NETDB_INTERNAL; 106bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct addrinfo* ai; 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct addrinfo hints; 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) memset(&hints, 0, sizeof(hints)); 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) hints.ai_flags = AI_CANONNAME; 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) hints.ai_family = AF_INET; 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int err = getaddrinfo(name, NULL, &hints, &ai); 113bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (err) { 114bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch switch (err) { 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case EAI_SYSTEM: 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) h_errno = NO_RECOVERY; 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case EAI_NONAME: 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) h_errno = HOST_NOT_FOUND; 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) default: 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) h_errno = NETDB_INTERNAL; 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 124bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 125bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return NULL; 126bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 127bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 128bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // We use a single hostent struct for all calls to to gethostbyname 129bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // (as explicitly permitted by the spec - gethostbyname is NOT supposed to 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // be threadsafe!). However by using a lock around all the global data 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // manipulation we can at least ensure that the call doesn't crash. 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AUTO_LOCK(gethostbyname_lock_); 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The first thing we do is free any malloced data left over from 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the last call. 136bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch hostent_cleanup(); 137bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) switch (ai->ai_family) { 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case AF_INET: 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) hostent_.h_addrtype = AF_INET; 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) hostent_.h_length = sizeof(in_addr); 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case AF_INET6: 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) hostent_.h_addrtype = AF_INET6; 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) hostent_.h_length = sizeof(in6_addr); 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) default: 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return NULL; 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 150bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (ai->ai_canonname != NULL) 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) hostent_.h_name = strdup(ai->ai_canonname); 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) hostent_.h_name = strdup(name); 155bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 156bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Aliases aren't supported at the moment, so we just make an empty list. 157bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch hostent_.h_aliases = static_cast<char**>(malloc(sizeof(char*))); 158bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (NULL == hostent_.h_aliases) 159bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return NULL; 160bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch hostent_.h_aliases[0] = NULL; 161bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Count number of address in list 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int num_addresses = 0; 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct addrinfo* current = ai; 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) while (current != NULL) { 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Only count address that have the same type as first address 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (current->ai_family == hostent_.h_addrtype) 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) num_addresses++; 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) current = current->ai_next; 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Allocate address list 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) hostent_.h_addr_list = static_cast<char**>(calloc(num_addresses + 1, 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sizeof(char*))); 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (NULL == hostent_.h_addr_list) 176bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return NULL; 177bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Copy all addresses of the relevant family. 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) current = ai; 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) char** hostent_addr = hostent_.h_addr_list; 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) while (current != NULL) { 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (current->ai_family != hostent_.h_addrtype) { 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) current = current->ai_next; 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) continue; 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *hostent_addr = static_cast<char*>(malloc(hostent_.h_length)); 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) switch (current->ai_family) { 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case AF_INET: { 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sockaddr_in* in = reinterpret_cast<sockaddr_in*>(current->ai_addr); 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) memcpy(*hostent_addr, &in->sin_addr.s_addr, hostent_.h_length); 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case AF_INET6: { 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sockaddr_in6* in6 = reinterpret_cast<sockaddr_in6*>(current->ai_addr); 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) memcpy(*hostent_addr, &in6->sin6_addr.s6_addr, hostent_.h_length); 1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) current = current->ai_next; 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) hostent_addr++; 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) freeaddrinfo(ai); 204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if !defined(h_addr) 206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Copy element zero of h_addr_list to h_addr when h_addr is not defined 207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // as in some libc's h_addr may be a separate member instead of a macro. 208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) hostent_.h_addr = hostent_.h_addr_list[0]; 209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif 210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return &hostent_; 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 21446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void HostResolver::freeaddrinfo(struct addrinfo* res) { 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) while (res) { 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct addrinfo* cur = res; 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) res = res->ai_next; 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) free(cur->ai_addr); 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) free(cur->ai_canonname); 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) free(cur); 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint HostResolver::getnameinfo(const struct sockaddr *sa, 2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci socklen_t salen, 2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci char *host, 2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci size_t hostlen, 2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci char *serv, 2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci size_t servlen, 2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int flags) { 2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return ENOSYS; 2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 23446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)int HostResolver::getaddrinfo(const char* node, 23546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const char* service, 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const struct addrinfo* hints_in, 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct addrinfo** result) { 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *result = NULL; 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct addrinfo* end = NULL; 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 241116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (node == NULL && service == NULL) { 242116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG_TRACE("node and service are NULL."); 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return EAI_NONAME; 244116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Check the service name (port). Currently we only handle numeric 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // services. 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) long port = 0; 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (service != NULL) { 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) char* cp; 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) port = strtol(service, &cp, 10); 2526d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (port >= 0 && port <= UINT16_MAX && *cp == '\0') { 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) port = htons(port); 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 255116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG_TRACE("Service \"%s\" not supported.", service); 2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return EAI_SERVICE; 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct addrinfo default_hints; 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) memset(&default_hints, 0, sizeof(default_hints)); 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const struct addrinfo* hints = hints_in ? hints_in : &default_hints; 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Verify values passed in hints structure 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) switch (hints->ai_family) { 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case AF_INET6: 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case AF_INET: 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case AF_UNSPEC: 269bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch break; 270bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch default: 271116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG_TRACE("Unknown family: %d.", hints->ai_family); 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return EAI_FAMILY; 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct sockaddr_in addr_in; 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) memset(&addr_in, 0, sizeof(addr_in)); 2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) addr_in.sin_family = AF_INET; 2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) addr_in.sin_port = port; 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct sockaddr_in6 addr_in6; 2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) memset(&addr_in6, 0, sizeof(addr_in6)); 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) addr_in6.sin6_family = AF_INET6; 2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) addr_in6.sin6_port = port; 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (node) { 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Handle numeric node name. 2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (hints->ai_family == AF_INET || hints->ai_family == AF_UNSPEC) { 2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) in_addr in; 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (inet_pton(AF_INET, node, &in)) { 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) addr_in.sin_addr = in; 2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateAddrInfo(hints, (sockaddr*)&addr_in, node, result, &end); 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 0; 2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (hints->ai_family == AF_INET6 || hints->ai_family == AF_UNSPEC) { 2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) in6_addr in6; 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (inet_pton(AF_INET6, node, &in6)) { 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) addr_in6.sin6_addr = in6; 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateAddrInfo(hints, (sockaddr*)&addr_in6, node, result, &end); 3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 0; 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Handle AI_PASSIVE (used for listening sockets, e.g. INADDR_ANY) 3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (node == NULL && (hints->ai_flags & AI_PASSIVE)) { 3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (hints->ai_family == AF_INET6 || hints->ai_family == AF_UNSPEC) { 3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const in6_addr in6addr_any = IN6ADDR_ANY_INIT; 3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) memcpy(&addr_in6.sin6_addr.s6_addr, &in6addr_any, sizeof(in6addr_any)); 3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateAddrInfo(hints, (sockaddr*)&addr_in6, NULL, result, &end); 3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (hints->ai_family == AF_INET || hints->ai_family == AF_UNSPEC) { 3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) addr_in.sin_addr.s_addr = INADDR_ANY; 3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateAddrInfo(hints, (sockaddr*)&addr_in, NULL, result, &end); 3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 0; 3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 321116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (NULL == ppapi_) { 322116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG_ERROR("ppapi_ is NULL."); 3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return EAI_SYSTEM; 324116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Use PPAPI interface to resolve nodename 3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) HostResolverInterface* resolver_iface = ppapi_->GetHostResolverInterface(); 328116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch VarInterface* var_iface = ppapi_->GetVarInterface(); 3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NetAddressInterface* netaddr_iface = ppapi_->GetNetAddressInterface(); 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 331116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!(resolver_iface && var_iface && netaddr_iface)) { 332116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG_ERROR("Got NULL interface(s): %s%s%s", 333116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch resolver_iface ? "" : "HostResolver ", 334116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch var_iface ? "" : "Var ", 335116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch netaddr_iface ? "" : "NetAddress"); 3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return EAI_SYSTEM; 337116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedResource scoped_resolver(ppapi_, 3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) resolver_iface->Create(ppapi_->GetInstance())); 3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PP_Resource resolver = scoped_resolver.pp_resource(); 3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct PP_HostResolver_Hint pp_hints; 3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) HintsToPPHints(hints, &pp_hints); 3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int err = resolver_iface->Resolve(resolver, 3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) node, 3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 0, 3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &pp_hints, 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PP_BlockUntilComplete()); 3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (err) { 3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) switch (err) { 3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case PP_ERROR_NOACCESS: 3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return EAI_SYSTEM; 3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case PP_ERROR_NAME_NOT_RESOLVED: 3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return EAI_NONAME; 3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) default: 3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return EAI_SYSTEM; 3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) char* canon_name = NULL; 3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (hints->ai_flags & AI_CANONNAME) { 3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PP_Var name_var = resolver_iface->GetCanonicalName(resolver); 3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (PP_VARTYPE_STRING == name_var.type) { 3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) uint32_t len = 0; 367116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const char* tmp = var_iface->VarToUtf8(name_var, &len); 3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // For some reason GetCanonicalName alway returns an empty 3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // string so this condition is never true. 3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(sbc): investigate this issue with PPAPI team. 3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (len > 0) { 3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Copy and NULL-terminate the UTF8 string var. 37346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) canon_name = static_cast<char*>(malloc(len + 1)); 3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) strncpy(canon_name, tmp, len); 3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) canon_name[len] = '\0'; 3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!canon_name) 3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) canon_name = strdup(node); 380116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch var_iface->Release(name_var); 381bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 382bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int num_addresses = resolver_iface->GetNetAddressCount(resolver); 384bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (0 == num_addresses) 3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return EAI_NODATA; 386bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Convert address to sockaddr struct. 3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (int i = 0; i < num_addresses; i++) { 3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedResource addr(ppapi_, resolver_iface->GetNetAddress(resolver, i)); 3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PP_Resource resource = addr.pp_resource(); 3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert(resource != 0); 3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert(PP_ToBool(netaddr_iface->IsNetAddress(resource))); 3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct sockaddr* sockaddr = NULL; 3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) switch (netaddr_iface->GetFamily(resource)) { 3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case PP_NETADDRESS_FAMILY_IPV4: { 3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct PP_NetAddress_IPv4 pp_addr; 3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!netaddr_iface->DescribeAsIPv4Address(resource, &pp_addr)) { 3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert(false); 3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) memcpy(&addr_in.sin_addr.s_addr, pp_addr.addr, sizeof(in_addr_t)); 4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sockaddr = (struct sockaddr*)&addr_in; 4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 404bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case PP_NETADDRESS_FAMILY_IPV6: { 4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct PP_NetAddress_IPv6 pp_addr; 4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!netaddr_iface->DescribeAsIPv6Address(resource, &pp_addr)) { 4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert(false); 4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 41146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) memcpy(&addr_in6.sin6_addr.s6_addr, pp_addr.addr, sizeof(in6_addr)); 4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sockaddr = (struct sockaddr*)&addr_in6; 4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) default: 4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return EAI_SYSTEM; 4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (sockaddr != NULL) 4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateAddrInfo(hints, sockaddr, canon_name, result, &end); 4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (canon_name) { 4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) free(canon_name); 4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) canon_name = NULL; 425bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 426bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 0; 429bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 430bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 431bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// Frees all of the deep pointers in a hostent struct. Called between uses of 432bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// gethostbyname, and when the kernel_proxy object is destroyed. 433bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochvoid HostResolver::hostent_cleanup() { 434bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (NULL != hostent_.h_name) { 435bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch free(hostent_.h_name); 436bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 437bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (NULL != hostent_.h_aliases) { 43846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) for (int i = 0; NULL != hostent_.h_aliases[i]; i++) { 439bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch free(hostent_.h_aliases[i]); 440bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 441bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch free(hostent_.h_aliases); 442bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 443bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (NULL != hostent_.h_addr_list) { 44446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) for (int i = 0; NULL != hostent_.h_addr_list[i]; i++) { 445bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch free(hostent_.h_addr_list[i]); 446bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 447bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch free(hostent_.h_addr_list); 448bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 449bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch hostent_.h_name = NULL; 450bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch hostent_.h_aliases = NULL; 451bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch hostent_.h_addr_list = NULL; 452cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if !defined(h_addr) 453cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Initialize h_addr separately in the case where it is not a macro. 454cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) hostent_.h_addr = NULL; 455cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif 456bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 457bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 458bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} // namespace nacl_io 459bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 460bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#endif // PROVIDES_SOCKET_API 461