net_address_private_impl.cc revision 7d4cd473f85ac64c3747c96c277f9e506a0d2246
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" 237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/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. 57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)uint16 ConvertFromNetEndian16(uint16 x) { 58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(ARCH_CPU_LITTLE_ENDIAN) 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return (x << 8) | (x >> 8); 60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#else 61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return x; 62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif 63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)uint16 ConvertToNetEndian16(uint16 x) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(ARCH_CPU_LITTLE_ENDIAN) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (x << 8) | (x >> 8); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return x; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const size_t kIPv4AddressSize = 4; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const size_t kIPv6AddressSize = 16; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This structure is a platform-independent representation of a network address. 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It is a private format that we embed in PP_NetAddress_Private and is NOT part 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of the stable Pepper API. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct NetAddress { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_valid; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_ipv6; // if true, IPv6, otherwise IPv4. 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16_t port; // host order, not network order. 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t flow_info; // 0 for IPv4 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t scope_id; // 0 for IPv4 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IPv4 addresses are 4 bytes. IPv6 are 16 bytes. Addresses are stored in net 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // order (big-endian), which only affects IPv6 addresses, which consist of 8 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 16-bit components. These will be byte-swapped on small-endian hosts. 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8_t address[kIPv6AddressSize]; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that sizeof(NetAddress) is the same for all compilers. This ensures 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that the alignment is the same on both sides of the NaCl proxy, which is 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// important because we serialize and deserialize PP_NetAddress_Private by 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// simply copying the raw bytes. 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPILE_ASSERT(sizeof(NetAddress) == 28, 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetAddress_different_for_compiler); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure the storage in |PP_NetAddress_Private| is big enough. (Do it here 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// since the data is opaque elsewhere.) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPILE_ASSERT(sizeof(reinterpret_cast<PP_NetAddress_Private*>(0)->data) >= 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(NetAddress), 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_NetAddress_Private_data_too_small); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t GetAddressSize(const NetAddress* net_addr) { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net_addr->is_ipv6 ? kIPv6AddressSize : kIPv4AddressSize; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Convert to embedded struct if it has been initialized. 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NetAddress* ToNetAddress(PP_NetAddress_Private* addr) { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!addr || addr->size != sizeof(NetAddress)) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return reinterpret_cast<NetAddress*>(addr->data); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const NetAddress* ToNetAddress(const PP_NetAddress_Private* addr) { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ToNetAddress(const_cast<PP_NetAddress_Private*>(addr)); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Initializes the NetAddress struct embedded in a PP_NetAddress_Private struct. 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Zeroes the memory, so net_addr->is_valid == false. 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NetAddress* InitNetAddress(PP_NetAddress_Private* addr) { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr->size = sizeof(NetAddress); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetAddress* net_addr = ToNetAddress(addr); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(net_addr); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(net_addr, 0, sizeof(NetAddress)); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net_addr; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsValid(const NetAddress* net_addr) { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net_addr && net_addr->is_valid; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_NetAddressFamily_Private GetFamily(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 PP_NETADDRESSFAMILY_UNSPECIFIED; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net_addr->is_ipv6 ? 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_NETADDRESSFAMILY_IPV6 : PP_NETADDRESSFAMILY_IPV4; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint16_t GetPort(const PP_NetAddress_Private* addr) { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* net_addr = ToNetAddress(addr); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsValid(net_addr)) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net_addr->port; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Bool GetAddress(const PP_NetAddress_Private* addr, 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* address, 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16_t address_size) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* net_addr = ToNetAddress(addr); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsValid(net_addr)) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_FALSE; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t net_addr_size = GetAddressSize(net_addr); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // address_size must be big enough. 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (net_addr_size > address_size) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_FALSE; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(address, net_addr->address, net_addr_size); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_TRUE; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32_t GetScopeID(const PP_NetAddress_Private* addr) { 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* net_addr = ToNetAddress(addr); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsValid(net_addr)) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net_addr->scope_id; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Bool AreHostsEqual(const PP_NetAddress_Private* addr1, 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PP_NetAddress_Private* addr2) { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* net_addr1 = ToNetAddress(addr1); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* net_addr2 = ToNetAddress(addr2); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsValid(net_addr1) || !IsValid(net_addr2)) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_FALSE; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((net_addr1->is_ipv6 != net_addr2->is_ipv6) || 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (net_addr1->flow_info != net_addr2->flow_info) || 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (net_addr1->scope_id != net_addr2->scope_id)) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_FALSE; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t net_addr_size = GetAddressSize(net_addr1); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < net_addr_size; i++) { 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (net_addr1->address[i] != net_addr2->address[i]) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_FALSE; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_TRUE; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Bool AreEqual(const PP_NetAddress_Private* addr1, 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PP_NetAddress_Private* addr2) { 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |AreHostsEqual()| will also validate the addresses and return false if 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // either is invalid. 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!AreHostsEqual(addr1, addr2)) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_FALSE; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // AreHostsEqual has validated these net addresses. 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* net_addr1 = ToNetAddress(addr1); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* net_addr2 = ToNetAddress(addr2); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_FromBool(net_addr1->port == net_addr2->port); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ConvertIPv4AddressToString(const NetAddress* net_addr, 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool include_port) { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string description = base::StringPrintf( 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "%u.%u.%u.%u", 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->address[0], net_addr->address[1], 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->address[2], net_addr->address[3]); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (include_port) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF(&description, ":%u", net_addr->port); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return description; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Format an IPv6 address for human consumption, basically according to RFC 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 5952. 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - If the scope is nonzero, it is appended to the address as "%<scope>" (this 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is not in RFC 5952, but consistent with |getnameinfo()| on Linux and 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Windows). 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - If |include_port| is true, the address (possibly including the scope) is 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// enclosed in square brackets and ":<port>" is appended, i.e., the overall 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// format is "[<address>]:<port>". 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - If the address is an IPv4 address embedded IPv6 (per RFC 4291), then the 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// mixed format is used, e.g., "::ffff:192.168.1.2". This is optional per RFC 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 5952, but consistent with |getnameinfo()|. 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ConvertIPv6AddressToString(const NetAddress* net_addr, 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool include_port) { 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string description(include_port ? "[" : ""); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint16_t* address16 = 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<const uint16_t*>(net_addr->address); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IPv4 address embedded in IPv6. 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (address16[0] == 0 && address16[1] == 0 && 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) address16[2] == 0 && address16[3] == 0 && 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) address16[4] == 0 && 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (address16[5] == 0 || address16[5] == 0xffff)) { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF( 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &description, 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) address16[5] == 0 ? "::%u.%u.%u.%u" : "::ffff:%u.%u.%u.%u", 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->address[12], 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->address[13], 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->address[14], 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->address[15]); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "Real" IPv6 addresses. 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find the first longest run of 0s (of length > 1), to collapse to "::". 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int longest_start = 0; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int longest_length = 0; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int curr_start = 0; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int curr_length = 0; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 8; i++) { 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (address16[i] != 0) { 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_length = 0; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!curr_length) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_start = i; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_length++; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (curr_length > longest_length) { 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) longest_start = curr_start; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) longest_length = curr_length; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool need_sep = false; // Whether the next item needs a ':' to separate. 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 8;) { 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (longest_length > 1 && i == longest_start) { 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) description.append("::"); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) need_sep = false; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i += longest_length; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) uint16_t v = ConvertFromNetEndian16(address16[i]); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF(&description, need_sep ? ":%x" : "%x", v); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) need_sep = true; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i++; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Nonzero scopes, e.g., 123, are indicated by appending, e.g., "%123". 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (net_addr->scope_id != 0) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF(&description, "%%%u", net_addr->scope_id); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (include_port) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF(&description, "]:%u", net_addr->port); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return description; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Var Describe(PP_Module /*module*/, 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct PP_NetAddress_Private* addr, 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Bool include_port) { 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string str = NetAddressPrivateImpl::DescribeNetAddress( 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *addr, PP_ToBool(include_port)); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (str.empty()) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_MakeUndefined(); 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We must acquire the lock while accessing the VarTracker, which is part of 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the critical section of the proxy which may be accessed by other threads. 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProxyAutoLock lock; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return StringVar::StringToPPVar(str); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Bool ReplacePort(const struct PP_NetAddress_Private* src_addr, 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16_t port, 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct PP_NetAddress_Private* dest_addr) { 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* src_net_addr = ToNetAddress(src_addr); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsValid(src_net_addr) || !dest_addr) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_FALSE; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dest_addr->size = sizeof(NetAddress); // make sure 'size' is valid. 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetAddress* dest_net_addr = ToNetAddress(dest_addr); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dest_net_addr = *src_net_addr; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dest_net_addr->port = port; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_TRUE; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetAnyAddress(PP_Bool is_ipv6, PP_NetAddress_Private* addr) { 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (addr) { 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetAddress* net_addr = InitNetAddress(addr); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_valid = true; 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_ipv6 = (is_ipv6 == PP_TRUE); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreateFromIPv4Address(const uint8_t ip[4], 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16_t port, 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct PP_NetAddress_Private* addr) { 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (addr) { 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetAddress* net_addr = InitNetAddress(addr); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_valid = true; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_ipv6 = false; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->port = port; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(net_addr->address, ip, kIPv4AddressSize); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreateFromIPv6Address(const uint8_t ip[16], 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t scope_id, 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16_t port, 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct PP_NetAddress_Private* addr) { 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (addr) { 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetAddress* net_addr = InitNetAddress(addr); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_valid = true; 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_ipv6 = true; 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->port = port; 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->scope_id = scope_id; 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(net_addr->address, ip, kIPv6AddressSize); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const PPB_NetAddress_Private_0_1 net_address_private_interface_0_1 = { 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &AreEqual, 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &AreHostsEqual, 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &Describe, 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &ReplacePort, 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetAnyAddress 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const PPB_NetAddress_Private_1_0 net_address_private_interface_1_0 = { 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &AreEqual, 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &AreHostsEqual, 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &Describe, 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &ReplacePort, 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetAnyAddress, 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetFamily, 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetPort, 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetAddress 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const PPB_NetAddress_Private_1_1 net_address_private_interface_1_1 = { 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &AreEqual, 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &AreHostsEqual, 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &Describe, 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &ReplacePort, 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetAnyAddress, 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetFamily, 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetPort, 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetAddress, 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetScopeID, 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &CreateFromIPv4Address, 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &CreateFromIPv6Address 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace thunk { 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPAPI_THUNK_EXPORT const PPB_NetAddress_Private_0_1* 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GetPPB_NetAddress_Private_0_1_Thunk() { 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &net_address_private_interface_0_1; 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPAPI_THUNK_EXPORT const PPB_NetAddress_Private_1_0* 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GetPPB_NetAddress_Private_1_0_Thunk() { 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &net_address_private_interface_1_0; 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPAPI_THUNK_EXPORT const PPB_NetAddress_Private_1_1* 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GetPPB_NetAddress_Private_1_1_Thunk() { 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &net_address_private_interface_1_1; 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace thunk 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For the NaCl target, all we need are the API functions and the thunk. 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_NACL) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NetAddressPrivateImpl::ValidateNetAddress( 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PP_NetAddress_Private& addr) { 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IsValid(ToNetAddress(&addr)); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NetAddressPrivateImpl::SockaddrToNetAddress( 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const sockaddr* sa, 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t sa_length, 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_NetAddress_Private* addr) { 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!sa || sa_length == 0 || !addr) 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Our platform neutral format stores ports in host order, not net order, 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so convert them here. 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetAddress* net_addr = InitNetAddress(addr); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (sa->sa_family) { 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case AF_INET: { 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct sockaddr_in* addr4 = 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<const struct sockaddr_in*>(sa); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_valid = true; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_ipv6 = false; 430868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) net_addr->port = ConvertFromNetEndian16(addr4->sin_port); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(net_addr->address, &addr4->sin_addr.s_addr, kIPv4AddressSize); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case AF_INET6: { 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct sockaddr_in6* addr6 = 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<const struct sockaddr_in6*>(sa); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_valid = true; 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_ipv6 = true; 439868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) net_addr->port = ConvertFromNetEndian16(addr6->sin6_port); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->flow_info = addr6->sin6_flowinfo; 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->scope_id = addr6->sin6_scope_id; 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(net_addr->address, addr6->sin6_addr.s6_addr, kIPv6AddressSize); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // InitNetAddress sets net_addr->is_valid to false. 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true;} 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NetAddressPrivateImpl::IPEndPointToNetAddress( 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<unsigned char>& address, 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int port, 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_NetAddress_Private* addr) { 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!addr) 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetAddress* net_addr = InitNetAddress(addr); 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (address.size()) { 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kIPv4AddressSize: { 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_valid = true; 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_ipv6 = false; 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->port = static_cast<uint16_t>(port); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::copy(address.begin(), address.end(), net_addr->address); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kIPv6AddressSize: { 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_valid = true; 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_ipv6 = true; 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->port = static_cast<uint16_t>(port); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::copy(address.begin(), address.end(), net_addr->address); 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // InitNetAddress sets net_addr->is_valid to false. 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NetAddressPrivateImpl::NetAddressToIPEndPoint( 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PP_NetAddress_Private& addr, 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<unsigned char>* address, 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* port) { 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!address || !port) 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* net_addr = ToNetAddress(&addr); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsValid(net_addr)) 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *port = net_addr->port; 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t address_size = GetAddressSize(net_addr); 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) address->assign(&net_addr->address[0], &net_addr->address[address_size]); 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // !defined(OS_NACL) 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string NetAddressPrivateImpl::DescribeNetAddress( 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PP_NetAddress_Private& addr, 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool include_port) { 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* net_addr = ToNetAddress(&addr); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsValid(net_addr)) 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::string(); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On Windows, |NetAddressToString()| doesn't work in the sandbox. On Mac, 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the output isn't consistent with RFC 5952, at least on Mac OS 10.6: 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |getnameinfo()| collapses length-one runs of zeros (and also doesn't 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // display the scope). 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (net_addr->is_ipv6) 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ConvertIPv6AddressToString(net_addr, include_port); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ConvertIPv4AddressToString(net_addr, include_port); 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 520868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// static 521868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void NetAddressPrivateImpl::CreateNetAddressPrivateFromIPv4Address( 522868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const PP_NetAddress_IPv4_Dev& ipv4_addr, 523868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PP_NetAddress_Private* addr) { 524868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CreateFromIPv4Address(ipv4_addr.addr, ConvertFromNetEndian16(ipv4_addr.port), 525868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) addr); 526868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 527868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 528868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// static 529868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void NetAddressPrivateImpl::CreateNetAddressPrivateFromIPv6Address( 530868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const PP_NetAddress_IPv6_Dev& ipv6_addr, 531868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PP_NetAddress_Private* addr) { 532868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CreateFromIPv6Address(ipv6_addr.addr, 0, 533868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ConvertFromNetEndian16(ipv6_addr.port), addr); 534868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 535868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 536868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// static 537868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)PP_NetAddress_Family_Dev NetAddressPrivateImpl::GetFamilyFromNetAddressPrivate( 538868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const PP_NetAddress_Private& addr) { 539868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const NetAddress* net_addr = ToNetAddress(&addr); 540868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!IsValid(net_addr)) 541868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return PP_NETADDRESS_FAMILY_UNSPECIFIED; 542868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return net_addr->is_ipv6 ? PP_NETADDRESS_FAMILY_IPV6 : 543868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PP_NETADDRESS_FAMILY_IPV4; 544868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 545868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 546868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// static 547868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool NetAddressPrivateImpl::DescribeNetAddressPrivateAsIPv4Address( 548868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const PP_NetAddress_Private& addr, 549868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PP_NetAddress_IPv4_Dev* ipv4_addr) { 550868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!ipv4_addr) 551868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return false; 552868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 553868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const NetAddress* net_addr = ToNetAddress(&addr); 554868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!IsValid(net_addr) || net_addr->is_ipv6) 555868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return false; 556868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 557868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ipv4_addr->port = ConvertToNetEndian16(net_addr->port); 558868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 559868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) COMPILE_ASSERT(sizeof(ipv4_addr->addr) == kIPv4AddressSize, 560868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) mismatched_IPv4_address_size); 561868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) memcpy(ipv4_addr->addr, net_addr->address, kIPv4AddressSize); 562868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 563868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return true; 564868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 565868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 566868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// static 567868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool NetAddressPrivateImpl::DescribeNetAddressPrivateAsIPv6Address( 568868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const PP_NetAddress_Private& addr, 569868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PP_NetAddress_IPv6_Dev* ipv6_addr) { 570868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!ipv6_addr) 571868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return false; 572868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 573868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const NetAddress* net_addr = ToNetAddress(&addr); 574868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!IsValid(net_addr) || !net_addr->is_ipv6) 575868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return false; 576868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 577868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ipv6_addr->port = ConvertToNetEndian16(net_addr->port); 578868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 579868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) COMPILE_ASSERT(sizeof(ipv6_addr->addr) == kIPv6AddressSize, 580868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) mismatched_IPv6_address_size); 581868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) memcpy(ipv6_addr->addr, net_addr->address, kIPv6AddressSize); 582868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 583868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return true; 584868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 585868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ppapi 587