diff options
author | viettrungluu@chromium.org <viettrungluu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-08 20:29:46 +0000 |
---|---|---|
committer | viettrungluu@chromium.org <viettrungluu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-08 20:29:46 +0000 |
commit | 7a2d96a5c7776d4811eb6a8a38e3d24fcf688e05 (patch) | |
tree | 5aac2872b0d97446acba4f436ee152e5e8a64419 /ppapi/shared_impl | |
parent | 1b645f3a76c8bcafb679124126551e689f8fba7a (diff) | |
download | chromium_src-7a2d96a5c7776d4811eb6a8a38e3d24fcf688e05.zip chromium_src-7a2d96a5c7776d4811eb6a8a38e3d24fcf688e05.tar.gz chromium_src-7a2d96a5c7776d4811eb6a8a38e3d24fcf688e05.tar.bz2 |
Add private Pepper API for dealing with PP_Flash_NetAddress.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/8357030
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@109086 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/shared_impl')
-rw-r--r-- | ppapi/shared_impl/private/DEPS | 3 | ||||
-rw-r--r-- | ppapi/shared_impl/private/flash_net_address_impl.cc | 175 | ||||
-rw-r--r-- | ppapi/shared_impl/private/flash_net_address_impl.h | 25 |
3 files changed, 203 insertions, 0 deletions
diff --git a/ppapi/shared_impl/private/DEPS b/ppapi/shared_impl/private/DEPS new file mode 100644 index 0000000..6a2f02e --- /dev/null +++ b/ppapi/shared_impl/private/DEPS @@ -0,0 +1,3 @@ +include_rules = [ + "+net/base", +] diff --git a/ppapi/shared_impl/private/flash_net_address_impl.cc b/ppapi/shared_impl/private/flash_net_address_impl.cc new file mode 100644 index 0000000..0fd0d0fb --- /dev/null +++ b/ppapi/shared_impl/private/flash_net_address_impl.cc @@ -0,0 +1,175 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ppapi/shared_impl/private/flash_net_address_impl.h" + +#include <string.h> + +#include <string> + +#include "base/basictypes.h" +#include "build/build_config.h" +#include "net/base/net_util.h" +#include "net/base/sys_addrinfo.h" +#include "net/base/sys_byteorder.h" +#include "ppapi/c/pp_var.h" +#include "ppapi/c/private/ppb_flash_net_address.h" +#include "ppapi/shared_impl/var.h" +#include "ppapi/thunk/thunk.h" + +// The Flash net address interface doesn't have a normal C -> C++ thunk since it +// doesn't actually have any proxy wrapping or associated objects; it's just a +// call into base. So we implement the entire interface here, using the thunk +// namespace so it magically gets hooked up in the proper places. + +namespace ppapi { + +namespace { + +#if defined(OS_WIN) +// The type of |sockaddr::sa_family|. +typedef ADDRESS_FAMILY sa_family_t; +#endif + +inline sa_family_t GetFamily(const PP_Flash_NetAddress& addr) { + return reinterpret_cast<const sockaddr*>(addr.data)->sa_family; +} + +PP_Bool AreHostsEqual(const PP_Flash_NetAddress* addr1, + const PP_Flash_NetAddress* addr2) { + if (!FlashNetAddressImpl::ValidateNetAddress(*addr1) || + !FlashNetAddressImpl::ValidateNetAddress(*addr2)) + return PP_FALSE; + + if (GetFamily(*addr1) != GetFamily(*addr2)) + return PP_FALSE; + + if (GetFamily(*addr1) == AF_INET) { + const sockaddr_in* a1 = reinterpret_cast<const sockaddr_in*>(addr1->data); + const sockaddr_in* a2 = reinterpret_cast<const sockaddr_in*>(addr2->data); + return PP_FromBool(a1->sin_addr.s_addr == a2->sin_addr.s_addr); + } + + if (GetFamily(*addr1) == AF_INET6) { + const sockaddr_in6* a1 = reinterpret_cast<const sockaddr_in6*>(addr1->data); + const sockaddr_in6* a2 = reinterpret_cast<const sockaddr_in6*>(addr2->data); + return PP_FromBool(a1->sin6_flowinfo == a2->sin6_flowinfo && + memcmp(&a1->sin6_addr, &a2->sin6_addr, + sizeof(a1->sin6_addr)) == 0 && + a1->sin6_scope_id == a2->sin6_scope_id); + } + + return PP_FALSE; +} + +PP_Bool AreEqual(const PP_Flash_NetAddress* addr1, + const PP_Flash_NetAddress* addr2) { + // |AreHostsEqual()| will also validate the addresses and return false if + // either is invalid. + if (!AreHostsEqual(addr1, addr2)) + return PP_FALSE; + + // Note: Here, we know that |addr1| and |addr2| have the same family. + if (GetFamily(*addr1) == AF_INET) { + const sockaddr_in* a1 = reinterpret_cast<const sockaddr_in*>(addr1->data); + const sockaddr_in* a2 = reinterpret_cast<const sockaddr_in*>(addr2->data); + return PP_FromBool(a1->sin_port == a2->sin_port); + } + + if (GetFamily(*addr1) == AF_INET6) { + const sockaddr_in6* a1 = reinterpret_cast<const sockaddr_in6*>(addr1->data); + const sockaddr_in6* a2 = reinterpret_cast<const sockaddr_in6*>(addr2->data); + return PP_FromBool(a1->sin6_port == a2->sin6_port); + } + + return PP_FALSE; +} + +PP_Var Describe(PP_Module module, + const struct PP_Flash_NetAddress* addr, + PP_Bool include_port) { + if (!FlashNetAddressImpl::ValidateNetAddress(*addr)) + return PP_MakeUndefined(); + + const sockaddr* a = reinterpret_cast<const sockaddr*>(addr->data); + socklen_t l = addr->size; + std::string description = + include_port ? net::NetAddressToStringWithPort(a, l) : + net::NetAddressToString(a, l); + return StringVar::StringToPPVar(module, description); +} + +PP_Bool ReplacePort(const struct PP_Flash_NetAddress* src_addr, + uint16_t port, + struct PP_Flash_NetAddress* dest_addr) { + if (!FlashNetAddressImpl::ValidateNetAddress(*src_addr)) + return PP_FALSE; + + if (GetFamily(*src_addr) == AF_INET) { + memmove(dest_addr, src_addr, sizeof(*src_addr)); + reinterpret_cast<sockaddr_in*>(dest_addr->data)->sin_port = htons(port); + return PP_TRUE; + } + + if (GetFamily(*src_addr) == AF_INET6) { + memmove(dest_addr, src_addr, sizeof(*src_addr)); + reinterpret_cast<sockaddr_in6*>(dest_addr->data)->sin6_port = htons(port); + return PP_TRUE; + } + + return PP_FALSE; +} + +void GetAnyAddress(PP_Bool is_ipv6, struct PP_Flash_NetAddress* addr) { + memset(addr->data, 0, arraysize(addr->data) * sizeof(addr->data[0])); + if (is_ipv6) { + sockaddr_in6* a = reinterpret_cast<sockaddr_in6*>(addr->data); + addr->size = sizeof(*a); + a->sin6_family = AF_INET6; + a->sin6_addr = in6addr_any; + } else { + sockaddr_in* a = reinterpret_cast<sockaddr_in*>(addr->data); + addr->size = sizeof(*a); + a->sin_family = AF_INET; + a->sin_addr.s_addr = INADDR_ANY; + } +} + +const PPB_Flash_NetAddress flash_net_address_interface = { + &AreEqual, + &AreHostsEqual, + &Describe, + &ReplacePort, + &GetAnyAddress +}; + +} // namespace + +namespace thunk { + +PPAPI_THUNK_EXPORT const PPB_Flash_NetAddress* GetPPB_Flash_NetAddress_Thunk() { + return &flash_net_address_interface; +} + +} // namespace thunk + +// static +bool FlashNetAddressImpl::ValidateNetAddress(const PP_Flash_NetAddress& addr) { + if (addr.size < sizeof(reinterpret_cast<sockaddr*>(0)->sa_family)) + return false; + + // TODO(viettrungluu): more careful validation? + // Just do a size check for AF_INET. + if (GetFamily(addr) == AF_INET && addr.size >= sizeof(sockaddr_in)) + return true; + + // Ditto for AF_INET6. + if (GetFamily(addr) == AF_INET6 && addr.size >= sizeof(sockaddr_in6)) + return true; + + // Reject everything else. + return false; +} + +} // namespace ppapi diff --git a/ppapi/shared_impl/private/flash_net_address_impl.h b/ppapi/shared_impl/private/flash_net_address_impl.h new file mode 100644 index 0000000..6c070af --- /dev/null +++ b/ppapi/shared_impl/private/flash_net_address_impl.h @@ -0,0 +1,25 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PPAPI_SHARED_IMPL_PRIVATE_FLASH_NET_ADDRESS_IMPL_H_ +#define PPAPI_SHARED_IMPL_PRIVATE_FLASH_NET_ADDRESS_IMPL_H_ + +#include "base/basictypes.h" +#include "ppapi/shared_impl/ppapi_shared_export.h" + +struct PP_Flash_NetAddress; + +namespace ppapi { + +class PPAPI_SHARED_EXPORT FlashNetAddressImpl { + public: + static bool ValidateNetAddress(const PP_Flash_NetAddress& addr); + + private: + DISALLOW_IMPLICIT_CONSTRUCTORS(FlashNetAddressImpl); +}; + +} // namespace ppapi + +#endif // PPAPI_SHARED_IMPL_PRIVATE_FLASH_NET_ADDRESS_IMPL_H_ |