net_address_private_impl.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/private/net_address_private_impl.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <winsock2.h> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <ws2tcpip.h> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX) && !defined(OS_NACL) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <arpa/inet.h> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/socket.h> 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h> 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stringprintf.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_var.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/private/ppb_net_address_private.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/shared_impl/proxy_lock.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/var.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/thunk/thunk.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is a bit evil, but it's standard operating procedure for |s6_addr|.... 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define s6_addr16 __u6_addr.__u6_addr16 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The type of |sockaddr::sa_family|. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef ADDRESS_FAMILY sa_family_t; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define s6_addr16 u.Word 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ntohs(x) _byteswap_ushort(x) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define htons(x) _byteswap_ushort(x) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // defined(OS_WIN) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The net address interface doesn't have a normal C -> C++ thunk since it 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// doesn't actually have any proxy wrapping or associated objects; it's just a 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// call into base. So we implement the entire interface here, using the thunk 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// namespace so it magically gets hooked up in the proper places. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ppapi { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Define our own net-host-net conversion, rather than reuse the one in 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// base/sys_byteorder.h, to simplify the NaCl port. NaCl has no byte swap 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// primitives. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint16 ConvertNetEndian16(uint16 x) { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(ARCH_CPU_LITTLE_ENDIAN) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (x << 8) | (x >> 8); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return x; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const size_t kIPv4AddressSize = 4; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const size_t kIPv6AddressSize = 16; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This structure is a platform-independent representation of a network address. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It is a private format that we embed in PP_NetAddress_Private and is NOT part 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of the stable Pepper API. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct NetAddress { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_valid; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_ipv6; // if true, IPv6, otherwise IPv4. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16_t port; // host order, not network order. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t flow_info; // 0 for IPv4 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t scope_id; // 0 for IPv4 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IPv4 addresses are 4 bytes. IPv6 are 16 bytes. Addresses are stored in net 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // order (big-endian), which only affects IPv6 addresses, which consist of 8 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 16-bit components. These will be byte-swapped on small-endian hosts. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8_t address[kIPv6AddressSize]; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that sizeof(NetAddress) is the same for all compilers. This ensures 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that the alignment is the same on both sides of the NaCl proxy, which is 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// important because we serialize and deserialize PP_NetAddress_Private by 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// simply copying the raw bytes. 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPILE_ASSERT(sizeof(NetAddress) == 28, 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetAddress_different_for_compiler); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure the storage in |PP_NetAddress_Private| is big enough. (Do it here 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// since the data is opaque elsewhere.) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPILE_ASSERT(sizeof(reinterpret_cast<PP_NetAddress_Private*>(0)->data) >= 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(NetAddress), 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_NetAddress_Private_data_too_small); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t GetAddressSize(const NetAddress* net_addr) { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net_addr->is_ipv6 ? kIPv6AddressSize : kIPv4AddressSize; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Convert to embedded struct if it has been initialized. 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NetAddress* ToNetAddress(PP_NetAddress_Private* addr) { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!addr || addr->size != sizeof(NetAddress)) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return reinterpret_cast<NetAddress*>(addr->data); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const NetAddress* ToNetAddress(const PP_NetAddress_Private* addr) { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ToNetAddress(const_cast<PP_NetAddress_Private*>(addr)); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Initializes the NetAddress struct embedded in a PP_NetAddress_Private struct. 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Zeroes the memory, so net_addr->is_valid == false. 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NetAddress* InitNetAddress(PP_NetAddress_Private* addr) { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr->size = sizeof(NetAddress); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetAddress* net_addr = ToNetAddress(addr); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(net_addr); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(net_addr, 0, sizeof(NetAddress)); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net_addr; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsValid(const NetAddress* net_addr) { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net_addr && net_addr->is_valid; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_NetAddressFamily_Private GetFamily(const PP_NetAddress_Private* addr) { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* net_addr = ToNetAddress(addr); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsValid(net_addr)) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_NETADDRESSFAMILY_UNSPECIFIED; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net_addr->is_ipv6 ? 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_NETADDRESSFAMILY_IPV6 : PP_NETADDRESSFAMILY_IPV4; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint16_t GetPort(const PP_NetAddress_Private* addr) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* net_addr = ToNetAddress(addr); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsValid(net_addr)) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net_addr->port; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Bool GetAddress(const PP_NetAddress_Private* addr, 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* address, 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16_t address_size) { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* net_addr = ToNetAddress(addr); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsValid(net_addr)) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_FALSE; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t net_addr_size = GetAddressSize(net_addr); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // address_size must be big enough. 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (net_addr_size > address_size) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_FALSE; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(address, net_addr->address, net_addr_size); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_TRUE; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32_t GetScopeID(const PP_NetAddress_Private* addr) { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* net_addr = ToNetAddress(addr); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsValid(net_addr)) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net_addr->scope_id; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Bool AreHostsEqual(const PP_NetAddress_Private* addr1, 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PP_NetAddress_Private* addr2) { 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* net_addr1 = ToNetAddress(addr1); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* net_addr2 = ToNetAddress(addr2); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsValid(net_addr1) || !IsValid(net_addr2)) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_FALSE; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((net_addr1->is_ipv6 != net_addr2->is_ipv6) || 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (net_addr1->flow_info != net_addr2->flow_info) || 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (net_addr1->scope_id != net_addr2->scope_id)) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_FALSE; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t net_addr_size = GetAddressSize(net_addr1); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < net_addr_size; i++) { 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (net_addr1->address[i] != net_addr2->address[i]) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_FALSE; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_TRUE; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Bool AreEqual(const PP_NetAddress_Private* addr1, 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PP_NetAddress_Private* addr2) { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |AreHostsEqual()| will also validate the addresses and return false if 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // either is invalid. 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!AreHostsEqual(addr1, addr2)) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_FALSE; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // AreHostsEqual has validated these net addresses. 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* net_addr1 = ToNetAddress(addr1); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* net_addr2 = ToNetAddress(addr2); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_FromBool(net_addr1->port == net_addr2->port); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ConvertIPv4AddressToString(const NetAddress* net_addr, 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool include_port) { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string description = base::StringPrintf( 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "%u.%u.%u.%u", 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->address[0], net_addr->address[1], 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->address[2], net_addr->address[3]); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (include_port) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF(&description, ":%u", net_addr->port); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return description; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Format an IPv6 address for human consumption, basically according to RFC 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 5952. 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - If the scope is nonzero, it is appended to the address as "%<scope>" (this 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is not in RFC 5952, but consistent with |getnameinfo()| on Linux and 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Windows). 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - If |include_port| is true, the address (possibly including the scope) is 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// enclosed in square brackets and ":<port>" is appended, i.e., the overall 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// format is "[<address>]:<port>". 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - If the address is an IPv4 address embedded IPv6 (per RFC 4291), then the 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// mixed format is used, e.g., "::ffff:192.168.1.2". This is optional per RFC 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 5952, but consistent with |getnameinfo()|. 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ConvertIPv6AddressToString(const NetAddress* net_addr, 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool include_port) { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string description(include_port ? "[" : ""); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint16_t* address16 = 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<const uint16_t*>(net_addr->address); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IPv4 address embedded in IPv6. 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (address16[0] == 0 && address16[1] == 0 && 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) address16[2] == 0 && address16[3] == 0 && 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) address16[4] == 0 && 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (address16[5] == 0 || address16[5] == 0xffff)) { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF( 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &description, 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) address16[5] == 0 ? "::%u.%u.%u.%u" : "::ffff:%u.%u.%u.%u", 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->address[12], 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->address[13], 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->address[14], 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->address[15]); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "Real" IPv6 addresses. 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find the first longest run of 0s (of length > 1), to collapse to "::". 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int longest_start = 0; 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int longest_length = 0; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int curr_start = 0; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int curr_length = 0; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 8; i++) { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (address16[i] != 0) { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_length = 0; 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!curr_length) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_start = i; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_length++; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (curr_length > longest_length) { 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) longest_start = curr_start; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) longest_length = curr_length; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool need_sep = false; // Whether the next item needs a ':' to separate. 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 8;) { 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (longest_length > 1 && i == longest_start) { 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) description.append("::"); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) need_sep = false; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i += longest_length; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16_t v = ConvertNetEndian16(address16[i]); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF(&description, need_sep ? ":%x" : "%x", v); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) need_sep = true; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i++; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Nonzero scopes, e.g., 123, are indicated by appending, e.g., "%123". 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (net_addr->scope_id != 0) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF(&description, "%%%u", net_addr->scope_id); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (include_port) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF(&description, "]:%u", net_addr->port); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return description; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Var Describe(PP_Module /*module*/, 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct PP_NetAddress_Private* addr, 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Bool include_port) { 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string str = NetAddressPrivateImpl::DescribeNetAddress( 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *addr, PP_ToBool(include_port)); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (str.empty()) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_MakeUndefined(); 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We must acquire the lock while accessing the VarTracker, which is part of 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the critical section of the proxy which may be accessed by other threads. 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProxyAutoLock lock; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return StringVar::StringToPPVar(str); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Bool ReplacePort(const struct PP_NetAddress_Private* src_addr, 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16_t port, 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct PP_NetAddress_Private* dest_addr) { 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* src_net_addr = ToNetAddress(src_addr); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsValid(src_net_addr) || !dest_addr) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_FALSE; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dest_addr->size = sizeof(NetAddress); // make sure 'size' is valid. 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetAddress* dest_net_addr = ToNetAddress(dest_addr); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dest_net_addr = *src_net_addr; 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dest_net_addr->port = port; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_TRUE; 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetAnyAddress(PP_Bool is_ipv6, PP_NetAddress_Private* addr) { 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (addr) { 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetAddress* net_addr = InitNetAddress(addr); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_valid = true; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_ipv6 = (is_ipv6 == PP_TRUE); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreateFromIPv4Address(const uint8_t ip[4], 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16_t port, 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct PP_NetAddress_Private* addr) { 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (addr) { 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetAddress* net_addr = InitNetAddress(addr); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_valid = true; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_ipv6 = false; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->port = port; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(net_addr->address, ip, kIPv4AddressSize); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreateFromIPv6Address(const uint8_t ip[16], 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t scope_id, 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16_t port, 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct PP_NetAddress_Private* addr) { 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (addr) { 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetAddress* net_addr = InitNetAddress(addr); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_valid = true; 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_ipv6 = true; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->port = port; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->scope_id = scope_id; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(net_addr->address, ip, kIPv6AddressSize); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const PPB_NetAddress_Private_0_1 net_address_private_interface_0_1 = { 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &AreEqual, 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &AreHostsEqual, 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &Describe, 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &ReplacePort, 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetAnyAddress 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const PPB_NetAddress_Private_1_0 net_address_private_interface_1_0 = { 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &AreEqual, 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &AreHostsEqual, 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &Describe, 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &ReplacePort, 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetAnyAddress, 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetFamily, 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetPort, 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetAddress 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const PPB_NetAddress_Private_1_1 net_address_private_interface_1_1 = { 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &AreEqual, 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &AreHostsEqual, 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &Describe, 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &ReplacePort, 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetAnyAddress, 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetFamily, 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetPort, 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetAddress, 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetScopeID, 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &CreateFromIPv4Address, 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &CreateFromIPv6Address 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace thunk { 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPAPI_THUNK_EXPORT const PPB_NetAddress_Private_0_1* 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GetPPB_NetAddress_Private_0_1_Thunk() { 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &net_address_private_interface_0_1; 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPAPI_THUNK_EXPORT const PPB_NetAddress_Private_1_0* 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GetPPB_NetAddress_Private_1_0_Thunk() { 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &net_address_private_interface_1_0; 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPAPI_THUNK_EXPORT const PPB_NetAddress_Private_1_1* 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GetPPB_NetAddress_Private_1_1_Thunk() { 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &net_address_private_interface_1_1; 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace thunk 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For the NaCl target, all we need are the API functions and the thunk. 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_NACL) 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const PP_NetAddress_Private NetAddressPrivateImpl::kInvalidNetAddress = { 0 }; 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NetAddressPrivateImpl::ValidateNetAddress( 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PP_NetAddress_Private& addr) { 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IsValid(ToNetAddress(&addr)); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NetAddressPrivateImpl::SockaddrToNetAddress( 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const sockaddr* sa, 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t sa_length, 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_NetAddress_Private* addr) { 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!sa || sa_length == 0 || !addr) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Our platform neutral format stores ports in host order, not net order, 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so convert them here. 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetAddress* net_addr = InitNetAddress(addr); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (sa->sa_family) { 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case AF_INET: { 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct sockaddr_in* addr4 = 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<const struct sockaddr_in*>(sa); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_valid = true; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_ipv6 = false; 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->port = ConvertNetEndian16(addr4->sin_port); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(net_addr->address, &addr4->sin_addr.s_addr, kIPv4AddressSize); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case AF_INET6: { 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct sockaddr_in6* addr6 = 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<const struct sockaddr_in6*>(sa); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_valid = true; 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_ipv6 = true; 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->port = ConvertNetEndian16(addr6->sin6_port); 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->flow_info = addr6->sin6_flowinfo; 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->scope_id = addr6->sin6_scope_id; 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(net_addr->address, addr6->sin6_addr.s6_addr, kIPv6AddressSize); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // InitNetAddress sets net_addr->is_valid to false. 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true;} 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NetAddressPrivateImpl::IPEndPointToNetAddress( 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<unsigned char>& address, 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int port, 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_NetAddress_Private* addr) { 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!addr) 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetAddress* net_addr = InitNetAddress(addr); 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (address.size()) { 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kIPv4AddressSize: { 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_valid = true; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_ipv6 = false; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->port = static_cast<uint16_t>(port); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::copy(address.begin(), address.end(), net_addr->address); 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kIPv6AddressSize: { 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_valid = true; 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_ipv6 = true; 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->port = static_cast<uint16_t>(port); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::copy(address.begin(), address.end(), net_addr->address); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // InitNetAddress sets net_addr->is_valid to false. 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NetAddressPrivateImpl::NetAddressToIPEndPoint( 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PP_NetAddress_Private& addr, 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<unsigned char>* address, 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* port) { 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!address || !port) 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* net_addr = ToNetAddress(&addr); 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsValid(net_addr)) 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *port = net_addr->port; 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t address_size = GetAddressSize(net_addr); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) address->assign(&net_addr->address[0], &net_addr->address[address_size]); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // !defined(OS_NACL) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string NetAddressPrivateImpl::DescribeNetAddress( 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PP_NetAddress_Private& addr, 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool include_port) { 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* net_addr = ToNetAddress(&addr); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsValid(net_addr)) 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::string(); 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On Windows, |NetAddressToString()| doesn't work in the sandbox. On Mac, 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the output isn't consistent with RFC 5952, at least on Mac OS 10.6: 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |getnameinfo()| collapses length-one runs of zeros (and also doesn't 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // display the scope). 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (net_addr->is_ipv6) 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ConvertIPv6AddressToString(net_addr, include_port); 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ConvertIPv4AddressToString(net_addr, include_port); 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ppapi 515