summaryrefslogtreecommitdiff
path: root/chromium/extensions/browser/api/socket/socket_api.h
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/extensions/browser/api/socket/socket_api.h')
-rw-r--r--chromium/extensions/browser/api/socket/socket_api.h560
1 files changed, 560 insertions, 0 deletions
diff --git a/chromium/extensions/browser/api/socket/socket_api.h b/chromium/extensions/browser/api/socket/socket_api.h
new file mode 100644
index 00000000000..9094f6097d6
--- /dev/null
+++ b/chromium/extensions/browser/api/socket/socket_api.h
@@ -0,0 +1,560 @@
+// Copyright 2014 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 EXTENSIONS_BROWSER_API_SOCKET_SOCKET_API_H_
+#define EXTENSIONS_BROWSER_API_SOCKET_SOCKET_API_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <string>
+
+#include "base/gtest_prod_util.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "build/build_config.h"
+#include "extensions/browser/api/api_resource_manager.h"
+#include "extensions/browser/api/async_api_function.h"
+#include "extensions/browser/extension_function.h"
+#include "extensions/common/api/socket.h"
+#include "net/base/address_list.h"
+#include "net/base/network_change_notifier.h"
+#include "net/dns/host_resolver.h"
+#include "net/socket/tcp_client_socket.h"
+
+#if defined(OS_CHROMEOS)
+#include "extensions/browser/api/socket/app_firewall_hole_manager.h"
+#endif // OS_CHROMEOS
+
+namespace content {
+class BrowserContext;
+class ResourceContext;
+}
+
+namespace net {
+class IOBuffer;
+class URLRequestContextGetter;
+class SSLClientSocket;
+}
+
+namespace extensions {
+class Socket;
+class TLSSocket;
+
+// A simple interface to ApiResourceManager<Socket> or derived class. The goal
+// of this interface is to allow Socket API functions to use distinct instances
+// of ApiResourceManager<> depending on the type of socket (old version in
+// "socket" namespace vs new version in "socket.xxx" namespaces).
+class SocketResourceManagerInterface {
+ public:
+ virtual ~SocketResourceManagerInterface() {}
+
+ virtual bool SetBrowserContext(content::BrowserContext* context) = 0;
+ virtual int Add(Socket* socket) = 0;
+ virtual Socket* Get(const std::string& extension_id, int api_resource_id) = 0;
+ virtual void Remove(const std::string& extension_id, int api_resource_id) = 0;
+ virtual void Replace(const std::string& extension_id,
+ int api_resource_id,
+ Socket* socket) = 0;
+ virtual base::hash_set<int>* GetResourceIds(
+ const std::string& extension_id) = 0;
+};
+
+// Implementation of SocketResourceManagerInterface using an
+// ApiResourceManager<T> instance (where T derives from Socket).
+template <typename T>
+class SocketResourceManager : public SocketResourceManagerInterface {
+ public:
+ SocketResourceManager() : manager_(NULL) {}
+
+ bool SetBrowserContext(content::BrowserContext* context) override {
+ manager_ = ApiResourceManager<T>::Get(context);
+ DCHECK(manager_)
+ << "There is no socket manager. "
+ "If this assertion is failing during a test, then it is likely that "
+ "TestExtensionSystem is failing to provide an instance of "
+ "ApiResourceManager<Socket>.";
+ return manager_ != NULL;
+ }
+
+ int Add(Socket* socket) override {
+ // Note: Cast needed here, because "T" may be a subclass of "Socket".
+ return manager_->Add(static_cast<T*>(socket));
+ }
+
+ Socket* Get(const std::string& extension_id, int api_resource_id) override {
+ return manager_->Get(extension_id, api_resource_id);
+ }
+
+ void Replace(const std::string& extension_id,
+ int api_resource_id,
+ Socket* socket) override {
+ manager_->Replace(extension_id, api_resource_id, static_cast<T*>(socket));
+ }
+
+ void Remove(const std::string& extension_id, int api_resource_id) override {
+ manager_->Remove(extension_id, api_resource_id);
+ }
+
+ base::hash_set<int>* GetResourceIds(
+ const std::string& extension_id) override {
+ return manager_->GetResourceIds(extension_id);
+ }
+
+ private:
+ ApiResourceManager<T>* manager_;
+};
+
+class SocketAsyncApiFunction : public AsyncApiFunction {
+ public:
+ SocketAsyncApiFunction();
+
+ protected:
+ ~SocketAsyncApiFunction() override;
+
+ // AsyncApiFunction:
+ bool PrePrepare() override;
+ bool Respond() override;
+
+ virtual scoped_ptr<SocketResourceManagerInterface>
+ CreateSocketResourceManager();
+
+ int AddSocket(Socket* socket);
+ Socket* GetSocket(int api_resource_id);
+ void ReplaceSocket(int api_resource_id, Socket* socket);
+ void RemoveSocket(int api_resource_id);
+ base::hash_set<int>* GetSocketIds();
+
+ // A no-op outside of Chrome OS.
+ void OpenFirewallHole(const std::string& address,
+ int socket_id,
+ Socket* socket);
+
+ private:
+#if defined(OS_CHROMEOS)
+ void OpenFirewallHoleOnUIThread(AppFirewallHole::PortType type,
+ uint16_t port,
+ int socket_id);
+ void OnFirewallHoleOpened(
+ int socket_id,
+ scoped_ptr<AppFirewallHole, content::BrowserThread::DeleteOnUIThread>
+ hole);
+#endif // OS_CHROMEOS
+
+ scoped_ptr<SocketResourceManagerInterface> manager_;
+};
+
+class SocketExtensionWithDnsLookupFunction : public SocketAsyncApiFunction {
+ protected:
+ SocketExtensionWithDnsLookupFunction();
+ ~SocketExtensionWithDnsLookupFunction() override;
+
+ // AsyncApiFunction:
+ bool PrePrepare() override;
+
+ void StartDnsLookup(const net::HostPortPair& host_port_pair);
+ virtual void AfterDnsLookup(int lookup_result) = 0;
+
+ net::AddressList addresses_;
+
+ private:
+ void OnDnsLookup(int resolve_result);
+
+ // Weak pointer to the resource context.
+ content::ResourceContext* resource_context_;
+};
+
+class SocketCreateFunction : public SocketAsyncApiFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("socket.create", SOCKET_CREATE)
+
+ SocketCreateFunction();
+
+ protected:
+ ~SocketCreateFunction() override;
+
+ // AsyncApiFunction:
+ bool Prepare() override;
+ void Work() override;
+
+ private:
+ FRIEND_TEST_ALL_PREFIXES(SocketUnitTest, Create);
+ enum SocketType { kSocketTypeInvalid = -1, kSocketTypeTCP, kSocketTypeUDP };
+
+ scoped_ptr<api::socket::Create::Params> params_;
+ SocketType socket_type_;
+};
+
+class SocketDestroyFunction : public SocketAsyncApiFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("socket.destroy", SOCKET_DESTROY)
+
+ protected:
+ ~SocketDestroyFunction() override {}
+
+ // AsyncApiFunction:
+ bool Prepare() override;
+ void Work() override;
+
+ private:
+ int socket_id_;
+};
+
+class SocketConnectFunction : public SocketExtensionWithDnsLookupFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("socket.connect", SOCKET_CONNECT)
+
+ SocketConnectFunction();
+
+ protected:
+ ~SocketConnectFunction() override;
+
+ // AsyncApiFunction:
+ bool Prepare() override;
+ void AsyncWorkStart() override;
+
+ // SocketExtensionWithDnsLookupFunction:
+ void AfterDnsLookup(int lookup_result) override;
+
+ private:
+ void StartConnect();
+ void OnConnect(int result);
+
+ int socket_id_;
+ std::string hostname_;
+ uint16_t port_;
+};
+
+class SocketDisconnectFunction : public SocketAsyncApiFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("socket.disconnect", SOCKET_DISCONNECT)
+
+ protected:
+ ~SocketDisconnectFunction() override {}
+
+ // AsyncApiFunction:
+ bool Prepare() override;
+ void Work() override;
+
+ private:
+ int socket_id_;
+};
+
+class SocketBindFunction : public SocketAsyncApiFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("socket.bind", SOCKET_BIND)
+
+ protected:
+ ~SocketBindFunction() override {}
+
+ // AsyncApiFunction:
+ bool Prepare() override;
+ void AsyncWorkStart() override;
+
+ private:
+ int socket_id_;
+ std::string address_;
+ uint16_t port_;
+};
+
+class SocketListenFunction : public SocketAsyncApiFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("socket.listen", SOCKET_LISTEN)
+
+ SocketListenFunction();
+
+ protected:
+ ~SocketListenFunction() override;
+
+ // AsyncApiFunction:
+ bool Prepare() override;
+ void AsyncWorkStart() override;
+
+ private:
+ scoped_ptr<api::socket::Listen::Params> params_;
+};
+
+class SocketAcceptFunction : public SocketAsyncApiFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("socket.accept", SOCKET_ACCEPT)
+
+ SocketAcceptFunction();
+
+ protected:
+ ~SocketAcceptFunction() override;
+
+ // AsyncApiFunction:
+ bool Prepare() override;
+ void AsyncWorkStart() override;
+
+ private:
+ void OnAccept(int result_code, scoped_ptr<net::TCPClientSocket> socket);
+
+ scoped_ptr<api::socket::Accept::Params> params_;
+};
+
+class SocketReadFunction : public SocketAsyncApiFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("socket.read", SOCKET_READ)
+
+ SocketReadFunction();
+
+ protected:
+ ~SocketReadFunction() override;
+
+ // AsyncApiFunction:
+ bool Prepare() override;
+ void AsyncWorkStart() override;
+ void OnCompleted(int result, scoped_refptr<net::IOBuffer> io_buffer);
+
+ private:
+ scoped_ptr<api::socket::Read::Params> params_;
+};
+
+class SocketWriteFunction : public SocketAsyncApiFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("socket.write", SOCKET_WRITE)
+
+ SocketWriteFunction();
+
+ protected:
+ ~SocketWriteFunction() override;
+
+ // AsyncApiFunction:
+ bool Prepare() override;
+ void AsyncWorkStart() override;
+ void OnCompleted(int result);
+
+ private:
+ int socket_id_;
+ scoped_refptr<net::IOBuffer> io_buffer_;
+ size_t io_buffer_size_;
+};
+
+class SocketRecvFromFunction : public SocketAsyncApiFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("socket.recvFrom", SOCKET_RECVFROM)
+
+ SocketRecvFromFunction();
+
+ protected:
+ ~SocketRecvFromFunction() override;
+
+ // AsyncApiFunction
+ bool Prepare() override;
+ void AsyncWorkStart() override;
+ void OnCompleted(int result,
+ scoped_refptr<net::IOBuffer> io_buffer,
+ const std::string& address,
+ uint16_t port);
+
+ private:
+ scoped_ptr<api::socket::RecvFrom::Params> params_;
+};
+
+class SocketSendToFunction : public SocketExtensionWithDnsLookupFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("socket.sendTo", SOCKET_SENDTO)
+
+ SocketSendToFunction();
+
+ protected:
+ ~SocketSendToFunction() override;
+
+ // AsyncApiFunction:
+ bool Prepare() override;
+ void AsyncWorkStart() override;
+ void OnCompleted(int result);
+
+ // SocketExtensionWithDnsLookupFunction:
+ void AfterDnsLookup(int lookup_result) override;
+
+ private:
+ void StartSendTo();
+
+ int socket_id_;
+ scoped_refptr<net::IOBuffer> io_buffer_;
+ size_t io_buffer_size_;
+ std::string hostname_;
+ uint16_t port_;
+};
+
+class SocketSetKeepAliveFunction : public SocketAsyncApiFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("socket.setKeepAlive", SOCKET_SETKEEPALIVE)
+
+ SocketSetKeepAliveFunction();
+
+ protected:
+ ~SocketSetKeepAliveFunction() override;
+
+ // AsyncApiFunction:
+ bool Prepare() override;
+ void Work() override;
+
+ private:
+ scoped_ptr<api::socket::SetKeepAlive::Params> params_;
+};
+
+class SocketSetNoDelayFunction : public SocketAsyncApiFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("socket.setNoDelay", SOCKET_SETNODELAY)
+
+ SocketSetNoDelayFunction();
+
+ protected:
+ ~SocketSetNoDelayFunction() override;
+
+ // AsyncApiFunction:
+ bool Prepare() override;
+ void Work() override;
+
+ private:
+ scoped_ptr<api::socket::SetNoDelay::Params> params_;
+};
+
+class SocketGetInfoFunction : public SocketAsyncApiFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("socket.getInfo", SOCKET_GETINFO)
+
+ SocketGetInfoFunction();
+
+ protected:
+ ~SocketGetInfoFunction() override;
+
+ // AsyncApiFunction:
+ bool Prepare() override;
+ void Work() override;
+
+ private:
+ scoped_ptr<api::socket::GetInfo::Params> params_;
+};
+
+class SocketGetNetworkListFunction : public AsyncExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("socket.getNetworkList", SOCKET_GETNETWORKLIST)
+
+ protected:
+ ~SocketGetNetworkListFunction() override {}
+ bool RunAsync() override;
+
+ private:
+ void GetNetworkListOnFileThread();
+ void HandleGetNetworkListError();
+ void SendResponseOnUIThread(const net::NetworkInterfaceList& interface_list);
+};
+
+class SocketJoinGroupFunction : public SocketAsyncApiFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("socket.joinGroup", SOCKET_MULTICAST_JOIN_GROUP)
+
+ SocketJoinGroupFunction();
+
+ protected:
+ ~SocketJoinGroupFunction() override;
+
+ // AsyncApiFunction
+ bool Prepare() override;
+ void Work() override;
+
+ private:
+ scoped_ptr<api::socket::JoinGroup::Params> params_;
+};
+
+class SocketLeaveGroupFunction : public SocketAsyncApiFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("socket.leaveGroup", SOCKET_MULTICAST_LEAVE_GROUP)
+
+ SocketLeaveGroupFunction();
+
+ protected:
+ ~SocketLeaveGroupFunction() override;
+
+ // AsyncApiFunction
+ bool Prepare() override;
+ void Work() override;
+
+ private:
+ scoped_ptr<api::socket::LeaveGroup::Params> params_;
+};
+
+class SocketSetMulticastTimeToLiveFunction : public SocketAsyncApiFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("socket.setMulticastTimeToLive",
+ SOCKET_MULTICAST_SET_TIME_TO_LIVE)
+
+ SocketSetMulticastTimeToLiveFunction();
+
+ protected:
+ ~SocketSetMulticastTimeToLiveFunction() override;
+
+ // AsyncApiFunction
+ bool Prepare() override;
+ void Work() override;
+
+ private:
+ scoped_ptr<api::socket::SetMulticastTimeToLive::Params> params_;
+};
+
+class SocketSetMulticastLoopbackModeFunction : public SocketAsyncApiFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("socket.setMulticastLoopbackMode",
+ SOCKET_MULTICAST_SET_LOOPBACK_MODE)
+
+ SocketSetMulticastLoopbackModeFunction();
+
+ protected:
+ ~SocketSetMulticastLoopbackModeFunction() override;
+
+ // AsyncApiFunction
+ bool Prepare() override;
+ void Work() override;
+
+ private:
+ scoped_ptr<api::socket::SetMulticastLoopbackMode::Params> params_;
+};
+
+class SocketGetJoinedGroupsFunction : public SocketAsyncApiFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("socket.getJoinedGroups",
+ SOCKET_MULTICAST_GET_JOINED_GROUPS)
+
+ SocketGetJoinedGroupsFunction();
+
+ protected:
+ ~SocketGetJoinedGroupsFunction() override;
+
+ // AsyncApiFunction
+ bool Prepare() override;
+ void Work() override;
+
+ private:
+ scoped_ptr<api::socket::GetJoinedGroups::Params> params_;
+};
+
+class SocketSecureFunction : public SocketAsyncApiFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("socket.secure", SOCKET_SECURE);
+ SocketSecureFunction();
+
+ protected:
+ ~SocketSecureFunction() override;
+
+ // AsyncApiFunction
+ bool Prepare() override;
+ void AsyncWorkStart() override;
+
+ private:
+ // Callback from TLSSocket::UpgradeSocketToTLS().
+ void TlsConnectDone(scoped_ptr<TLSSocket> socket, int result);
+
+ scoped_ptr<api::socket::Secure::Params> params_;
+ scoped_refptr<net::URLRequestContextGetter> url_request_getter_;
+
+ DISALLOW_COPY_AND_ASSIGN(SocketSecureFunction);
+};
+
+} // namespace extensions
+
+#endif // EXTENSIONS_BROWSER_API_SOCKET_SOCKET_API_H_