Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(56)

Unified Diff: ppapi/shared_impl/private/flash_net_address_impl.cc

Issue 8357030: Add private Pepper API for dealing with PP_Flash_NetAddress. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: oops Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ppapi/shared_impl/private/flash_net_address_impl.h ('k') | ppapi/thunk/interfaces_ppb_private.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ppapi/shared_impl/private/flash_net_address_impl.cc
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 0000000000000000000000000000000000000000..0fd0d0fb9e4b6db9b6924d9610d81f384168f699
--- /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
« no previous file with comments | « ppapi/shared_impl/private/flash_net_address_impl.h ('k') | ppapi/thunk/interfaces_ppb_private.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698