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

Unified Diff: extensions/browser/api/socket/socket_api.cc

Issue 965613002: Open a firewall hole when a TCP server or UDP socket is bound. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Actually use the thread_checker_ in FirewallHole. Created 5 years, 10 months 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
Index: extensions/browser/api/socket/socket_api.cc
diff --git a/extensions/browser/api/socket/socket_api.cc b/extensions/browser/api/socket/socket_api.cc
index dca379ab144f381e4f4db4720eeeb230ac7b914a..20f9c62bbfb04affd948e58ac5c9e2916ce89a8a 100644
--- a/extensions/browser/api/socket/socket_api.cc
+++ b/extensions/browser/api/socket/socket_api.cc
@@ -29,6 +29,12 @@
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
+#if defined(OS_CHROMEOS)
+#include "base/sys_info.h"
+#include "chromeos/network/firewall_hole.h"
+#include "content/public/browser/browser_thread.h"
+#endif // OS_CHROMEOS
+
namespace extensions {
using content::SocketPermissionRequest;
@@ -52,6 +58,10 @@ const char kSocketNotConnectedError[] = "Socket not connected";
const char kWildcardAddress[] = "*";
const uint16 kWildcardPort = 0;
+#if defined(OS_CHROMEOS)
+const char kFirewallFailure[] = "Failed to open firewall port";
+#endif // OS_CHROMEOS
+
SocketAsyncApiFunction::SocketAsyncApiFunction() {}
SocketAsyncApiFunction::~SocketAsyncApiFunction() {}
@@ -90,6 +100,73 @@ void SocketAsyncApiFunction::RemoveSocket(int api_resource_id) {
manager_->Remove(extension_->id(), api_resource_id);
}
+void SocketAsyncApiFunction::OpenFirewallHole(const std::string& address,
+ int socket_id,
+ Socket* socket) {
+#if defined(OS_CHROMEOS)
+ if (base::SysInfo::IsRunningOnChromeOS() && !net::IsLocalhost(address)) {
+ net::IPEndPoint local_address;
+ if (!socket->GetLocalAddress(&local_address)) {
+ NOTREACHED() << "Cannot get address of recently bound socket.";
+ error_ = kFirewallFailure;
+ SetResult(new base::FundamentalValue(-1));
+ AsyncWorkCompleted();
+ return;
+ }
+
+ chromeos::FirewallHole::PortType port_type;
+ if (socket->GetSocketType() == Socket::TYPE_TCP) {
+ port_type = chromeos::FirewallHole::TCP;
+ } else {
+ port_type = chromeos::FirewallHole::UDP;
+ }
+
+ content::BrowserThread::PostTask(
+ content::BrowserThread::UI, FROM_HERE,
+ base::Bind(
+ &chromeos::FirewallHole::Open, port_type, local_address.port(), "",
+ base::Bind(&SocketAsyncApiFunction::OnFirewallHoleOpenedOnUIThread,
+ this, socket_id)));
+ return;
+ }
+#endif
+ AsyncWorkCompleted();
+}
+
+#if defined(OS_CHROMEOS)
+
+void SocketAsyncApiFunction::OnFirewallHoleOpenedOnUIThread(
+ int socket_id,
+ scoped_ptr<chromeos::FirewallHole> hole) {
+ content::BrowserThread::PostTask(
+ content::BrowserThread::IO, FROM_HERE,
+ base::Bind(&SocketAsyncApiFunction::OnFirewallHoleOpened, this, socket_id,
+ base::Passed(&hole)));
+}
+
+void SocketAsyncApiFunction::OnFirewallHoleOpened(
+ int socket_id,
+ scoped_ptr<chromeos::FirewallHole> hole) {
+ if (!hole) {
+ error_ = kFirewallFailure;
+ SetResult(new base::FundamentalValue(-1));
+ AsyncWorkCompleted();
+ return;
+ }
+
+ Socket* socket = GetSocket(socket_id);
+ if (!socket) {
+ error_ = kSocketNotFoundError;
+ SetResult(new base::FundamentalValue(-1));
+ AsyncWorkCompleted();
+ return;
+ }
+
+ socket->set_firewall_hole(hole.Pass());
+}
+
+#endif // OS_CHROMEOS
+
SocketExtensionWithDnsLookupFunction::SocketExtensionWithDnsLookupFunction()
: resource_context_(NULL),
request_handle_(new net::HostResolver::RequestHandle),
@@ -294,33 +371,41 @@ bool SocketBindFunction::Prepare() {
return true;
}
-void SocketBindFunction::Work() {
- int result = -1;
+void SocketBindFunction::AsyncWorkStart() {
Socket* socket = GetSocket(socket_id_);
-
if (!socket) {
error_ = kSocketNotFoundError;
- SetResult(new base::FundamentalValue(result));
+ SetResult(new base::FundamentalValue(-1));
+ AsyncWorkCompleted();
return;
}
- if (socket->GetSocketType() == Socket::TYPE_UDP) {
- SocketPermission::CheckParam param(
- SocketPermissionRequest::UDP_BIND, address_, port_);
- if (!extension()->permissions_data()->CheckAPIPermissionWithParam(
- APIPermission::kSocket, &param)) {
- error_ = kPermissionError;
- SetResult(new base::FundamentalValue(result));
- return;
- }
- } else if (socket->GetSocketType() == Socket::TYPE_TCP) {
+ if (socket->GetSocketType() == Socket::TYPE_TCP) {
error_ = kTCPSocketBindError;
- SetResult(new base::FundamentalValue(result));
+ SetResult(new base::FundamentalValue(-1));
+ AsyncWorkCompleted();
+ return;
+ }
+
+ CHECK(socket->GetSocketType() == Socket::TYPE_UDP);
+ SocketPermission::CheckParam param(SocketPermissionRequest::UDP_BIND,
+ address_, port_);
+ if (!extension()->permissions_data()->CheckAPIPermissionWithParam(
+ APIPermission::kSocket, &param)) {
+ error_ = kPermissionError;
+ SetResult(new base::FundamentalValue(-1));
+ AsyncWorkCompleted();
return;
}
- result = socket->Bind(address_, port_);
+ int result = socket->Bind(address_, port_);
SetResult(new base::FundamentalValue(result));
+ if (result != net::OK) {
+ AsyncWorkCompleted();
+ return;
+ }
+
+ OpenFirewallHole(address_, socket_id_, socket);
}
SocketListenFunction::SocketListenFunction() {}
@@ -333,30 +418,35 @@ bool SocketListenFunction::Prepare() {
return true;
}
-void SocketListenFunction::Work() {
- int result = -1;
-
+void SocketListenFunction::AsyncWorkStart() {
Socket* socket = GetSocket(params_->socket_id);
- if (socket) {
- SocketPermission::CheckParam param(
- SocketPermissionRequest::TCP_LISTEN, params_->address, params_->port);
- if (!extension()->permissions_data()->CheckAPIPermissionWithParam(
- APIPermission::kSocket, &param)) {
- error_ = kPermissionError;
- SetResult(new base::FundamentalValue(result));
- return;
- }
-
- result =
- socket->Listen(params_->address,
- params_->port,
- params_->backlog.get() ? *params_->backlog.get() : 5,
- &error_);
- } else {
+ if (!socket) {
error_ = kSocketNotFoundError;
+ SetResult(new base::FundamentalValue(-1));
+ AsyncWorkCompleted();
+ return;
+ }
+
+ SocketPermission::CheckParam param(SocketPermissionRequest::TCP_LISTEN,
+ params_->address, params_->port);
+ if (!extension()->permissions_data()->CheckAPIPermissionWithParam(
+ APIPermission::kSocket, &param)) {
+ error_ = kPermissionError;
+ SetResult(new base::FundamentalValue(-1));
+ AsyncWorkCompleted();
+ return;
}
+ int result = socket->Listen(
+ params_->address, params_->port,
+ params_->backlog.get() ? *params_->backlog.get() : 5, &error_);
SetResult(new base::FundamentalValue(result));
+ if (result != net::OK) {
+ AsyncWorkCompleted();
+ return;
+ }
+
+ OpenFirewallHole(params_->address, params_->socket_id, socket);
}
SocketAcceptFunction::SocketAcceptFunction() {}

Powered by Google App Engine
This is Rietveld 408576698