1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "extensions/browser/api/socket/socket_api.h"
10 #include "base/containers/hash_tables.h"
11 #include "content/public/browser/browser_context.h"
12 #include "content/public/browser/resource_context.h"
13 #include "extensions/browser/api/dns/host_resolver_wrapper.h"
14 #include "extensions/browser/api/socket/socket.h"
15 #include "extensions/browser/api/socket/tcp_socket.h"
16 #include "extensions/browser/api/socket/udp_socket.h"
17 #include "extensions/browser/extension_system.h"
18 #include "extensions/common/extension.h"
19 #include "extensions/common/permissions/permissions_data.h"
20 #include "extensions/common/permissions/socket_permission.h"
21 #include "net/base/host_port_pair.h"
22 #include "net/base/io_buffer.h"
23 #include "net/base/ip_endpoint.h"
24 #include "net/base/net_errors.h"
25 #include "net/base/net_log.h"
26 #include "net/base/net_util.h"
28 namespace extensions
{
30 using content::SocketPermissionRequest
;
32 const char kAddressKey
[] = "address";
33 const char kPortKey
[] = "port";
34 const char kBytesWrittenKey
[] = "bytesWritten";
35 const char kDataKey
[] = "data";
36 const char kResultCodeKey
[] = "resultCode";
37 const char kSocketIdKey
[] = "socketId";
39 const char kSocketNotFoundError
[] = "Socket not found";
40 const char kDnsLookupFailedError
[] = "DNS resolution failed";
41 const char kPermissionError
[] = "App does not have permission";
42 const char kNetworkListError
[] = "Network lookup failed or unsupported";
43 const char kTCPSocketBindError
[] =
44 "TCP socket does not support bind. For TCP server please use listen.";
45 const char kMulticastSocketTypeError
[] = "Only UDP socket supports multicast.";
46 const char kWildcardAddress
[] = "*";
47 const int kWildcardPort
= 0;
49 SocketAsyncApiFunction::SocketAsyncApiFunction() {}
51 SocketAsyncApiFunction::~SocketAsyncApiFunction() {}
53 bool SocketAsyncApiFunction::PrePrepare() {
54 manager_
= CreateSocketResourceManager();
55 return manager_
->SetBrowserContext(browser_context());
58 bool SocketAsyncApiFunction::Respond() { return error_
.empty(); }
60 scoped_ptr
<SocketResourceManagerInterface
>
61 SocketAsyncApiFunction::CreateSocketResourceManager() {
62 return scoped_ptr
<SocketResourceManagerInterface
>(
63 new SocketResourceManager
<Socket
>()).Pass();
66 int SocketAsyncApiFunction::AddSocket(Socket
* socket
) {
67 return manager_
->Add(socket
);
70 Socket
* SocketAsyncApiFunction::GetSocket(int api_resource_id
) {
71 return manager_
->Get(extension_
->id(), api_resource_id
);
74 base::hash_set
<int>* SocketAsyncApiFunction::GetSocketIds() {
75 return manager_
->GetResourceIds(extension_
->id());
78 void SocketAsyncApiFunction::RemoveSocket(int api_resource_id
) {
79 manager_
->Remove(extension_
->id(), api_resource_id
);
82 SocketExtensionWithDnsLookupFunction::SocketExtensionWithDnsLookupFunction()
83 : resource_context_(NULL
),
84 request_handle_(new net::HostResolver::RequestHandle
),
85 addresses_(new net::AddressList
) {}
87 SocketExtensionWithDnsLookupFunction::~SocketExtensionWithDnsLookupFunction() {}
89 bool SocketExtensionWithDnsLookupFunction::PrePrepare() {
90 if (!SocketAsyncApiFunction::PrePrepare())
92 resource_context_
= browser_context()->GetResourceContext();
93 return resource_context_
!= NULL
;
96 void SocketExtensionWithDnsLookupFunction::StartDnsLookup(
97 const std::string
& hostname
) {
98 net::HostResolver
* host_resolver
=
99 extensions::HostResolverWrapper::GetInstance()->GetHostResolver(
100 resource_context_
->GetHostResolver());
101 DCHECK(host_resolver
);
103 // Yes, we are passing zero as the port. There are some interesting but not
104 // presently relevant reasons why HostResolver asks for the port of the
105 // hostname you'd like to resolve, even though it doesn't use that value in
106 // determining its answer.
107 net::HostPortPair
host_port_pair(hostname
, 0);
109 net::HostResolver::RequestInfo
request_info(host_port_pair
);
110 int resolve_result
= host_resolver
->Resolve(
112 net::DEFAULT_PRIORITY
,
114 base::Bind(&SocketExtensionWithDnsLookupFunction::OnDnsLookup
, this),
115 request_handle_
.get(),
118 if (resolve_result
!= net::ERR_IO_PENDING
)
119 OnDnsLookup(resolve_result
);
122 void SocketExtensionWithDnsLookupFunction::OnDnsLookup(int resolve_result
) {
123 if (resolve_result
== net::OK
) {
124 DCHECK(!addresses_
->empty());
125 resolved_address_
= addresses_
->front().ToStringWithoutPort();
127 error_
= kDnsLookupFailedError
;
129 AfterDnsLookup(resolve_result
);
132 SocketCreateFunction::SocketCreateFunction()
133 : socket_type_(kSocketTypeInvalid
) {}
135 SocketCreateFunction::~SocketCreateFunction() {}
137 bool SocketCreateFunction::Prepare() {
138 params_
= core_api::socket::Create::Params::Create(*args_
);
139 EXTENSION_FUNCTION_VALIDATE(params_
.get());
141 switch (params_
->type
) {
142 case extensions::core_api::socket::SOCKET_TYPE_TCP
:
143 socket_type_
= kSocketTypeTCP
;
145 case extensions::core_api::socket::SOCKET_TYPE_UDP
:
146 socket_type_
= kSocketTypeUDP
;
148 case extensions::core_api::socket::SOCKET_TYPE_NONE
:
156 void SocketCreateFunction::Work() {
157 Socket
* socket
= NULL
;
158 if (socket_type_
== kSocketTypeTCP
) {
159 socket
= new TCPSocket(extension_
->id());
160 } else if (socket_type_
== kSocketTypeUDP
) {
161 socket
= new UDPSocket(extension_
->id());
165 base::DictionaryValue
* result
= new base::DictionaryValue();
166 result
->SetInteger(kSocketIdKey
, AddSocket(socket
));
170 bool SocketDestroyFunction::Prepare() {
171 EXTENSION_FUNCTION_VALIDATE(args_
->GetInteger(0, &socket_id_
));
175 void SocketDestroyFunction::Work() { RemoveSocket(socket_id_
); }
177 SocketConnectFunction::SocketConnectFunction()
178 : socket_id_(0), hostname_(), port_(0), socket_(NULL
) {}
180 SocketConnectFunction::~SocketConnectFunction() {}
182 bool SocketConnectFunction::Prepare() {
183 EXTENSION_FUNCTION_VALIDATE(args_
->GetInteger(0, &socket_id_
));
184 EXTENSION_FUNCTION_VALIDATE(args_
->GetString(1, &hostname_
));
185 EXTENSION_FUNCTION_VALIDATE(args_
->GetInteger(2, &port_
));
189 void SocketConnectFunction::AsyncWorkStart() {
190 socket_
= GetSocket(socket_id_
);
192 error_
= kSocketNotFoundError
;
193 SetResult(new base::FundamentalValue(-1));
194 AsyncWorkCompleted();
198 SocketPermissionRequest::OperationType operation_type
;
199 switch (socket_
->GetSocketType()) {
200 case Socket::TYPE_TCP
:
201 operation_type
= SocketPermissionRequest::TCP_CONNECT
;
203 case Socket::TYPE_UDP
:
204 operation_type
= SocketPermissionRequest::UDP_SEND_TO
;
207 NOTREACHED() << "Unknown socket type.";
208 operation_type
= SocketPermissionRequest::NONE
;
212 SocketPermission::CheckParam
param(operation_type
, hostname_
, port_
);
213 if (!PermissionsData::CheckAPIPermissionWithParam(
214 GetExtension(), APIPermission::kSocket
, ¶m
)) {
215 error_
= kPermissionError
;
216 SetResult(new base::FundamentalValue(-1));
217 AsyncWorkCompleted();
221 StartDnsLookup(hostname_
);
224 void SocketConnectFunction::AfterDnsLookup(int lookup_result
) {
225 if (lookup_result
== net::OK
) {
228 SetResult(new base::FundamentalValue(lookup_result
));
229 AsyncWorkCompleted();
233 void SocketConnectFunction::StartConnect() {
234 socket_
->Connect(resolved_address_
,
236 base::Bind(&SocketConnectFunction::OnConnect
, this));
239 void SocketConnectFunction::OnConnect(int result
) {
240 SetResult(new base::FundamentalValue(result
));
241 AsyncWorkCompleted();
244 bool SocketDisconnectFunction::Prepare() {
245 EXTENSION_FUNCTION_VALIDATE(args_
->GetInteger(0, &socket_id_
));
249 void SocketDisconnectFunction::Work() {
250 Socket
* socket
= GetSocket(socket_id_
);
252 socket
->Disconnect();
254 error_
= kSocketNotFoundError
;
255 SetResult(base::Value::CreateNullValue());
258 bool SocketBindFunction::Prepare() {
259 EXTENSION_FUNCTION_VALIDATE(args_
->GetInteger(0, &socket_id_
));
260 EXTENSION_FUNCTION_VALIDATE(args_
->GetString(1, &address_
));
261 EXTENSION_FUNCTION_VALIDATE(args_
->GetInteger(2, &port_
));
265 void SocketBindFunction::Work() {
267 Socket
* socket
= GetSocket(socket_id_
);
270 error_
= kSocketNotFoundError
;
271 SetResult(new base::FundamentalValue(result
));
275 if (socket
->GetSocketType() == Socket::TYPE_UDP
) {
276 SocketPermission::CheckParam
param(
277 SocketPermissionRequest::UDP_BIND
, address_
, port_
);
278 if (!PermissionsData::CheckAPIPermissionWithParam(
279 GetExtension(), APIPermission::kSocket
, ¶m
)) {
280 error_
= kPermissionError
;
281 SetResult(new base::FundamentalValue(result
));
284 } else if (socket
->GetSocketType() == Socket::TYPE_TCP
) {
285 error_
= kTCPSocketBindError
;
286 SetResult(new base::FundamentalValue(result
));
290 result
= socket
->Bind(address_
, port_
);
291 SetResult(new base::FundamentalValue(result
));
294 SocketListenFunction::SocketListenFunction() {}
296 SocketListenFunction::~SocketListenFunction() {}
298 bool SocketListenFunction::Prepare() {
299 params_
= core_api::socket::Listen::Params::Create(*args_
);
300 EXTENSION_FUNCTION_VALIDATE(params_
.get());
304 void SocketListenFunction::Work() {
307 Socket
* socket
= GetSocket(params_
->socket_id
);
309 SocketPermission::CheckParam
param(
310 SocketPermissionRequest::TCP_LISTEN
, params_
->address
, params_
->port
);
311 if (!PermissionsData::CheckAPIPermissionWithParam(
312 GetExtension(), APIPermission::kSocket
, ¶m
)) {
313 error_
= kPermissionError
;
314 SetResult(new base::FundamentalValue(result
));
319 socket
->Listen(params_
->address
,
321 params_
->backlog
.get() ? *params_
->backlog
.get() : 5,
324 error_
= kSocketNotFoundError
;
327 SetResult(new base::FundamentalValue(result
));
330 SocketAcceptFunction::SocketAcceptFunction() {}
332 SocketAcceptFunction::~SocketAcceptFunction() {}
334 bool SocketAcceptFunction::Prepare() {
335 params_
= core_api::socket::Accept::Params::Create(*args_
);
336 EXTENSION_FUNCTION_VALIDATE(params_
.get());
340 void SocketAcceptFunction::AsyncWorkStart() {
341 Socket
* socket
= GetSocket(params_
->socket_id
);
343 socket
->Accept(base::Bind(&SocketAcceptFunction::OnAccept
, this));
345 error_
= kSocketNotFoundError
;
350 void SocketAcceptFunction::OnAccept(int result_code
,
351 net::TCPClientSocket
* socket
) {
352 base::DictionaryValue
* result
= new base::DictionaryValue();
353 result
->SetInteger(kResultCodeKey
, result_code
);
355 Socket
* client_socket
= new TCPSocket(socket
, extension_id(), true);
356 result
->SetInteger(kSocketIdKey
, AddSocket(client_socket
));
360 AsyncWorkCompleted();
363 SocketReadFunction::SocketReadFunction() {}
365 SocketReadFunction::~SocketReadFunction() {}
367 bool SocketReadFunction::Prepare() {
368 params_
= core_api::socket::Read::Params::Create(*args_
);
369 EXTENSION_FUNCTION_VALIDATE(params_
.get());
373 void SocketReadFunction::AsyncWorkStart() {
374 Socket
* socket
= GetSocket(params_
->socket_id
);
376 error_
= kSocketNotFoundError
;
377 OnCompleted(-1, NULL
);
381 socket
->Read(params_
->buffer_size
.get() ? *params_
->buffer_size
.get() : 4096,
382 base::Bind(&SocketReadFunction::OnCompleted
, this));
385 void SocketReadFunction::OnCompleted(int bytes_read
,
386 scoped_refptr
<net::IOBuffer
> io_buffer
) {
387 base::DictionaryValue
* result
= new base::DictionaryValue();
388 result
->SetInteger(kResultCodeKey
, bytes_read
);
389 if (bytes_read
> 0) {
390 result
->Set(kDataKey
,
391 base::BinaryValue::CreateWithCopiedBuffer(io_buffer
->data(),
394 result
->Set(kDataKey
, new base::BinaryValue());
398 AsyncWorkCompleted();
401 SocketWriteFunction::SocketWriteFunction()
402 : socket_id_(0), io_buffer_(NULL
), io_buffer_size_(0) {}
404 SocketWriteFunction::~SocketWriteFunction() {}
406 bool SocketWriteFunction::Prepare() {
407 EXTENSION_FUNCTION_VALIDATE(args_
->GetInteger(0, &socket_id_
));
408 base::BinaryValue
* data
= NULL
;
409 EXTENSION_FUNCTION_VALIDATE(args_
->GetBinary(1, &data
));
411 io_buffer_size_
= data
->GetSize();
412 io_buffer_
= new net::WrappedIOBuffer(data
->GetBuffer());
416 void SocketWriteFunction::AsyncWorkStart() {
417 Socket
* socket
= GetSocket(socket_id_
);
420 error_
= kSocketNotFoundError
;
425 socket
->Write(io_buffer_
,
427 base::Bind(&SocketWriteFunction::OnCompleted
, this));
430 void SocketWriteFunction::OnCompleted(int bytes_written
) {
431 base::DictionaryValue
* result
= new base::DictionaryValue();
432 result
->SetInteger(kBytesWrittenKey
, bytes_written
);
435 AsyncWorkCompleted();
438 SocketRecvFromFunction::SocketRecvFromFunction() {}
440 SocketRecvFromFunction::~SocketRecvFromFunction() {}
442 bool SocketRecvFromFunction::Prepare() {
443 params_
= core_api::socket::RecvFrom::Params::Create(*args_
);
444 EXTENSION_FUNCTION_VALIDATE(params_
.get());
448 void SocketRecvFromFunction::AsyncWorkStart() {
449 Socket
* socket
= GetSocket(params_
->socket_id
);
451 error_
= kSocketNotFoundError
;
452 OnCompleted(-1, NULL
, std::string(), 0);
456 socket
->RecvFrom(params_
->buffer_size
.get() ? *params_
->buffer_size
: 4096,
457 base::Bind(&SocketRecvFromFunction::OnCompleted
, this));
460 void SocketRecvFromFunction::OnCompleted(int bytes_read
,
461 scoped_refptr
<net::IOBuffer
> io_buffer
,
462 const std::string
& address
,
464 base::DictionaryValue
* result
= new base::DictionaryValue();
465 result
->SetInteger(kResultCodeKey
, bytes_read
);
466 if (bytes_read
> 0) {
467 result
->Set(kDataKey
,
468 base::BinaryValue::CreateWithCopiedBuffer(io_buffer
->data(),
471 result
->Set(kDataKey
, new base::BinaryValue());
473 result
->SetString(kAddressKey
, address
);
474 result
->SetInteger(kPortKey
, port
);
477 AsyncWorkCompleted();
480 SocketSendToFunction::SocketSendToFunction()
487 SocketSendToFunction::~SocketSendToFunction() {}
489 bool SocketSendToFunction::Prepare() {
490 EXTENSION_FUNCTION_VALIDATE(args_
->GetInteger(0, &socket_id_
));
491 base::BinaryValue
* data
= NULL
;
492 EXTENSION_FUNCTION_VALIDATE(args_
->GetBinary(1, &data
));
493 EXTENSION_FUNCTION_VALIDATE(args_
->GetString(2, &hostname_
));
494 EXTENSION_FUNCTION_VALIDATE(args_
->GetInteger(3, &port_
));
496 io_buffer_size_
= data
->GetSize();
497 io_buffer_
= new net::WrappedIOBuffer(data
->GetBuffer());
501 void SocketSendToFunction::AsyncWorkStart() {
502 socket_
= GetSocket(socket_id_
);
504 error_
= kSocketNotFoundError
;
505 SetResult(new base::FundamentalValue(-1));
506 AsyncWorkCompleted();
510 if (socket_
->GetSocketType() == Socket::TYPE_UDP
) {
511 SocketPermission::CheckParam
param(
512 SocketPermissionRequest::UDP_SEND_TO
, hostname_
, port_
);
513 if (!PermissionsData::CheckAPIPermissionWithParam(
514 GetExtension(), APIPermission::kSocket
, ¶m
)) {
515 error_
= kPermissionError
;
516 SetResult(new base::FundamentalValue(-1));
517 AsyncWorkCompleted();
522 StartDnsLookup(hostname_
);
525 void SocketSendToFunction::AfterDnsLookup(int lookup_result
) {
526 if (lookup_result
== net::OK
) {
529 SetResult(new base::FundamentalValue(lookup_result
));
530 AsyncWorkCompleted();
534 void SocketSendToFunction::StartSendTo() {
535 socket_
->SendTo(io_buffer_
,
539 base::Bind(&SocketSendToFunction::OnCompleted
, this));
542 void SocketSendToFunction::OnCompleted(int bytes_written
) {
543 base::DictionaryValue
* result
= new base::DictionaryValue();
544 result
->SetInteger(kBytesWrittenKey
, bytes_written
);
547 AsyncWorkCompleted();
550 SocketSetKeepAliveFunction::SocketSetKeepAliveFunction() {}
552 SocketSetKeepAliveFunction::~SocketSetKeepAliveFunction() {}
554 bool SocketSetKeepAliveFunction::Prepare() {
555 params_
= core_api::socket::SetKeepAlive::Params::Create(*args_
);
556 EXTENSION_FUNCTION_VALIDATE(params_
.get());
560 void SocketSetKeepAliveFunction::Work() {
562 Socket
* socket
= GetSocket(params_
->socket_id
);
565 if (params_
->delay
.get())
566 delay
= *params_
->delay
;
567 result
= socket
->SetKeepAlive(params_
->enable
, delay
);
569 error_
= kSocketNotFoundError
;
571 SetResult(new base::FundamentalValue(result
));
574 SocketSetNoDelayFunction::SocketSetNoDelayFunction() {}
576 SocketSetNoDelayFunction::~SocketSetNoDelayFunction() {}
578 bool SocketSetNoDelayFunction::Prepare() {
579 params_
= core_api::socket::SetNoDelay::Params::Create(*args_
);
580 EXTENSION_FUNCTION_VALIDATE(params_
.get());
584 void SocketSetNoDelayFunction::Work() {
586 Socket
* socket
= GetSocket(params_
->socket_id
);
588 result
= socket
->SetNoDelay(params_
->no_delay
);
590 error_
= kSocketNotFoundError
;
591 SetResult(new base::FundamentalValue(result
));
594 SocketGetInfoFunction::SocketGetInfoFunction() {}
596 SocketGetInfoFunction::~SocketGetInfoFunction() {}
598 bool SocketGetInfoFunction::Prepare() {
599 params_
= core_api::socket::GetInfo::Params::Create(*args_
);
600 EXTENSION_FUNCTION_VALIDATE(params_
.get());
604 void SocketGetInfoFunction::Work() {
605 Socket
* socket
= GetSocket(params_
->socket_id
);
607 error_
= kSocketNotFoundError
;
611 core_api::socket::SocketInfo info
;
612 // This represents what we know about the socket, and does not call through
614 if (socket
->GetSocketType() == Socket::TYPE_TCP
)
615 info
.socket_type
= extensions::core_api::socket::SOCKET_TYPE_TCP
;
617 info
.socket_type
= extensions::core_api::socket::SOCKET_TYPE_UDP
;
618 info
.connected
= socket
->IsConnected();
620 // Grab the peer address as known by the OS. This and the call below will
621 // always succeed while the socket is connected, even if the socket has
622 // been remotely closed by the peer; only reading the socket will reveal
623 // that it should be closed locally.
624 net::IPEndPoint peerAddress
;
625 if (socket
->GetPeerAddress(&peerAddress
)) {
626 info
.peer_address
.reset(new std::string(peerAddress
.ToStringWithoutPort()));
627 info
.peer_port
.reset(new int(peerAddress
.port()));
630 // Grab the local address as known by the OS.
631 net::IPEndPoint localAddress
;
632 if (socket
->GetLocalAddress(&localAddress
)) {
633 info
.local_address
.reset(
634 new std::string(localAddress
.ToStringWithoutPort()));
635 info
.local_port
.reset(new int(localAddress
.port()));
638 SetResult(info
.ToValue().release());
641 bool SocketGetNetworkListFunction::RunAsync() {
642 content::BrowserThread::PostTask(
643 content::BrowserThread::FILE,
645 base::Bind(&SocketGetNetworkListFunction::GetNetworkListOnFileThread
,
650 void SocketGetNetworkListFunction::GetNetworkListOnFileThread() {
651 net::NetworkInterfaceList interface_list
;
652 if (GetNetworkList(&interface_list
,
653 net::INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES
)) {
654 content::BrowserThread::PostTask(
655 content::BrowserThread::UI
,
657 base::Bind(&SocketGetNetworkListFunction::SendResponseOnUIThread
,
663 content::BrowserThread::PostTask(
664 content::BrowserThread::UI
,
666 base::Bind(&SocketGetNetworkListFunction::HandleGetNetworkListError
,
670 void SocketGetNetworkListFunction::HandleGetNetworkListError() {
671 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
672 error_
= kNetworkListError
;
676 void SocketGetNetworkListFunction::SendResponseOnUIThread(
677 const net::NetworkInterfaceList
& interface_list
) {
678 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
680 std::vector
<linked_ptr
<core_api::socket::NetworkInterface
> > create_arg
;
681 create_arg
.reserve(interface_list
.size());
682 for (net::NetworkInterfaceList::const_iterator i
= interface_list
.begin();
683 i
!= interface_list
.end();
685 linked_ptr
<core_api::socket::NetworkInterface
> info
=
686 make_linked_ptr(new core_api::socket::NetworkInterface
);
687 info
->name
= i
->name
;
688 info
->address
= net::IPAddressToString(i
->address
);
689 info
->prefix_length
= i
->network_prefix
;
690 create_arg
.push_back(info
);
693 results_
= core_api::socket::GetNetworkList::Results::Create(create_arg
);
697 SocketJoinGroupFunction::SocketJoinGroupFunction() {}
699 SocketJoinGroupFunction::~SocketJoinGroupFunction() {}
701 bool SocketJoinGroupFunction::Prepare() {
702 params_
= core_api::socket::JoinGroup::Params::Create(*args_
);
703 EXTENSION_FUNCTION_VALIDATE(params_
.get());
707 void SocketJoinGroupFunction::Work() {
709 Socket
* socket
= GetSocket(params_
->socket_id
);
711 error_
= kSocketNotFoundError
;
712 SetResult(new base::FundamentalValue(result
));
716 if (socket
->GetSocketType() != Socket::TYPE_UDP
) {
717 error_
= kMulticastSocketTypeError
;
718 SetResult(new base::FundamentalValue(result
));
722 SocketPermission::CheckParam
param(
723 SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP
,
727 if (!PermissionsData::CheckAPIPermissionWithParam(
728 GetExtension(), APIPermission::kSocket
, ¶m
)) {
729 error_
= kPermissionError
;
730 SetResult(new base::FundamentalValue(result
));
734 result
= static_cast<UDPSocket
*>(socket
)->JoinGroup(params_
->address
);
736 error_
= net::ErrorToString(result
);
738 SetResult(new base::FundamentalValue(result
));
741 SocketLeaveGroupFunction::SocketLeaveGroupFunction() {}
743 SocketLeaveGroupFunction::~SocketLeaveGroupFunction() {}
745 bool SocketLeaveGroupFunction::Prepare() {
746 params_
= core_api::socket::LeaveGroup::Params::Create(*args_
);
747 EXTENSION_FUNCTION_VALIDATE(params_
.get());
751 void SocketLeaveGroupFunction::Work() {
753 Socket
* socket
= GetSocket(params_
->socket_id
);
756 error_
= kSocketNotFoundError
;
757 SetResult(new base::FundamentalValue(result
));
761 if (socket
->GetSocketType() != Socket::TYPE_UDP
) {
762 error_
= kMulticastSocketTypeError
;
763 SetResult(new base::FundamentalValue(result
));
767 SocketPermission::CheckParam
param(
768 SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP
,
771 if (!PermissionsData::CheckAPIPermissionWithParam(
772 GetExtension(), APIPermission::kSocket
, ¶m
)) {
773 error_
= kPermissionError
;
774 SetResult(new base::FundamentalValue(result
));
778 result
= static_cast<UDPSocket
*>(socket
)->LeaveGroup(params_
->address
);
780 error_
= net::ErrorToString(result
);
781 SetResult(new base::FundamentalValue(result
));
784 SocketSetMulticastTimeToLiveFunction::SocketSetMulticastTimeToLiveFunction() {}
786 SocketSetMulticastTimeToLiveFunction::~SocketSetMulticastTimeToLiveFunction() {}
788 bool SocketSetMulticastTimeToLiveFunction::Prepare() {
789 params_
= core_api::socket::SetMulticastTimeToLive::Params::Create(*args_
);
790 EXTENSION_FUNCTION_VALIDATE(params_
.get());
793 void SocketSetMulticastTimeToLiveFunction::Work() {
795 Socket
* socket
= GetSocket(params_
->socket_id
);
797 error_
= kSocketNotFoundError
;
798 SetResult(new base::FundamentalValue(result
));
802 if (socket
->GetSocketType() != Socket::TYPE_UDP
) {
803 error_
= kMulticastSocketTypeError
;
804 SetResult(new base::FundamentalValue(result
));
809 static_cast<UDPSocket
*>(socket
)->SetMulticastTimeToLive(params_
->ttl
);
811 error_
= net::ErrorToString(result
);
812 SetResult(new base::FundamentalValue(result
));
815 SocketSetMulticastLoopbackModeFunction::
816 SocketSetMulticastLoopbackModeFunction() {}
818 SocketSetMulticastLoopbackModeFunction::
819 ~SocketSetMulticastLoopbackModeFunction() {}
821 bool SocketSetMulticastLoopbackModeFunction::Prepare() {
822 params_
= core_api::socket::SetMulticastLoopbackMode::Params::Create(*args_
);
823 EXTENSION_FUNCTION_VALIDATE(params_
.get());
827 void SocketSetMulticastLoopbackModeFunction::Work() {
829 Socket
* socket
= GetSocket(params_
->socket_id
);
831 error_
= kSocketNotFoundError
;
832 SetResult(new base::FundamentalValue(result
));
836 if (socket
->GetSocketType() != Socket::TYPE_UDP
) {
837 error_
= kMulticastSocketTypeError
;
838 SetResult(new base::FundamentalValue(result
));
842 result
= static_cast<UDPSocket
*>(socket
)
843 ->SetMulticastLoopbackMode(params_
->enabled
);
845 error_
= net::ErrorToString(result
);
846 SetResult(new base::FundamentalValue(result
));
849 SocketGetJoinedGroupsFunction::SocketGetJoinedGroupsFunction() {}
851 SocketGetJoinedGroupsFunction::~SocketGetJoinedGroupsFunction() {}
853 bool SocketGetJoinedGroupsFunction::Prepare() {
854 params_
= core_api::socket::GetJoinedGroups::Params::Create(*args_
);
855 EXTENSION_FUNCTION_VALIDATE(params_
.get());
859 void SocketGetJoinedGroupsFunction::Work() {
861 Socket
* socket
= GetSocket(params_
->socket_id
);
863 error_
= kSocketNotFoundError
;
864 SetResult(new base::FundamentalValue(result
));
868 if (socket
->GetSocketType() != Socket::TYPE_UDP
) {
869 error_
= kMulticastSocketTypeError
;
870 SetResult(new base::FundamentalValue(result
));
874 SocketPermission::CheckParam
param(
875 SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP
,
878 if (!PermissionsData::CheckAPIPermissionWithParam(
879 GetExtension(), APIPermission::kSocket
, ¶m
)) {
880 error_
= kPermissionError
;
881 SetResult(new base::FundamentalValue(result
));
885 base::ListValue
* values
= new base::ListValue();
886 values
->AppendStrings((std::vector
<std::string
>&)static_cast<UDPSocket
*>(
887 socket
)->GetJoinedGroups());
891 } // namespace extensions