Chromium Code Reviews| 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..04693371f28d80bc353b184d85bc582247cea42f 100644 |
| --- a/extensions/browser/api/socket/socket_api.cc |
| +++ b/extensions/browser/api/socket/socket_api.cc |
| @@ -29,6 +29,11 @@ |
| #include "net/url_request/url_request_context.h" |
| #include "net/url_request/url_request_context_getter.h" |
| +#if defined(OS_CHROMEOS) |
| +#include "chromeos/network/firewall_hole.h" |
| +#include "content/public/browser/browser_thread.h" |
| +#endif // OS_CHROMEOS |
| + |
| namespace extensions { |
| using content::SocketPermissionRequest; |
| @@ -52,6 +57,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 +99,74 @@ 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 (!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::PortType::TCP; |
| + } else { |
| + port_type = chromeos::FirewallHole::PortType::UDP; |
| + } |
| + |
| + content::BrowserThread::PostTask( |
| + content::BrowserThread::UI, FROM_HERE, |
| + base::Bind( |
| + &chromeos::FirewallHole::Open, port_type, local_address.port(), "", |
|
pneubeck (no reviews)
2015/03/10 08:49:22
please add a comment /* all interfaces */ after ""
Reilly Grant (use Gerrit)
2015/03/10 20:15:17
Done.
|
| + 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()); |
| + AsyncWorkCompleted(); |
| +} |
| + |
| +#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, ¶m)) { |
| - 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, ¶m)) { |
| + 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, ¶m)) { |
| - 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, ¶m)) { |
| + 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() {} |