socket_api.cc revision effb81e5f8246d0db0270817048dc992db66e9fb
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. 4 5#include "extensions/browser/api/socket/socket_api.h" 6 7#include <vector> 8 9#include "base/bind.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" 27 28namespace extensions { 29 30using content::SocketPermissionRequest; 31 32const char kAddressKey[] = "address"; 33const char kPortKey[] = "port"; 34const char kBytesWrittenKey[] = "bytesWritten"; 35const char kDataKey[] = "data"; 36const char kResultCodeKey[] = "resultCode"; 37const char kSocketIdKey[] = "socketId"; 38 39const char kSocketNotFoundError[] = "Socket not found"; 40const char kDnsLookupFailedError[] = "DNS resolution failed"; 41const char kPermissionError[] = "App does not have permission"; 42const char kNetworkListError[] = "Network lookup failed or unsupported"; 43const char kTCPSocketBindError[] = 44 "TCP socket does not support bind. For TCP server please use listen."; 45const char kMulticastSocketTypeError[] = "Only UDP socket supports multicast."; 46const char kWildcardAddress[] = "*"; 47const int kWildcardPort = 0; 48 49SocketAsyncApiFunction::SocketAsyncApiFunction() {} 50 51SocketAsyncApiFunction::~SocketAsyncApiFunction() {} 52 53bool SocketAsyncApiFunction::PrePrepare() { 54 manager_ = CreateSocketResourceManager(); 55 return manager_->SetBrowserContext(browser_context()); 56} 57 58bool SocketAsyncApiFunction::Respond() { return error_.empty(); } 59 60scoped_ptr<SocketResourceManagerInterface> 61SocketAsyncApiFunction::CreateSocketResourceManager() { 62 return scoped_ptr<SocketResourceManagerInterface>( 63 new SocketResourceManager<Socket>()).Pass(); 64} 65 66int SocketAsyncApiFunction::AddSocket(Socket* socket) { 67 return manager_->Add(socket); 68} 69 70Socket* SocketAsyncApiFunction::GetSocket(int api_resource_id) { 71 return manager_->Get(extension_->id(), api_resource_id); 72} 73 74base::hash_set<int>* SocketAsyncApiFunction::GetSocketIds() { 75 return manager_->GetResourceIds(extension_->id()); 76} 77 78void SocketAsyncApiFunction::RemoveSocket(int api_resource_id) { 79 manager_->Remove(extension_->id(), api_resource_id); 80} 81 82SocketExtensionWithDnsLookupFunction::SocketExtensionWithDnsLookupFunction() 83 : resource_context_(NULL), 84 request_handle_(new net::HostResolver::RequestHandle), 85 addresses_(new net::AddressList) {} 86 87SocketExtensionWithDnsLookupFunction::~SocketExtensionWithDnsLookupFunction() {} 88 89bool SocketExtensionWithDnsLookupFunction::PrePrepare() { 90 if (!SocketAsyncApiFunction::PrePrepare()) 91 return false; 92 resource_context_ = browser_context()->GetResourceContext(); 93 return resource_context_ != NULL; 94} 95 96void 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); 102 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); 108 109 net::HostResolver::RequestInfo request_info(host_port_pair); 110 int resolve_result = host_resolver->Resolve( 111 request_info, 112 net::DEFAULT_PRIORITY, 113 addresses_.get(), 114 base::Bind(&SocketExtensionWithDnsLookupFunction::OnDnsLookup, this), 115 request_handle_.get(), 116 net::BoundNetLog()); 117 118 if (resolve_result != net::ERR_IO_PENDING) 119 OnDnsLookup(resolve_result); 120} 121 122void SocketExtensionWithDnsLookupFunction::OnDnsLookup(int resolve_result) { 123 if (resolve_result == net::OK) { 124 DCHECK(!addresses_->empty()); 125 resolved_address_ = addresses_->front().ToStringWithoutPort(); 126 } else { 127 error_ = kDnsLookupFailedError; 128 } 129 AfterDnsLookup(resolve_result); 130} 131 132SocketCreateFunction::SocketCreateFunction() 133 : socket_type_(kSocketTypeInvalid) {} 134 135SocketCreateFunction::~SocketCreateFunction() {} 136 137bool SocketCreateFunction::Prepare() { 138 params_ = core_api::socket::Create::Params::Create(*args_); 139 EXTENSION_FUNCTION_VALIDATE(params_.get()); 140 141 switch (params_->type) { 142 case extensions::core_api::socket::SOCKET_TYPE_TCP: 143 socket_type_ = kSocketTypeTCP; 144 break; 145 case extensions::core_api::socket::SOCKET_TYPE_UDP: 146 socket_type_ = kSocketTypeUDP; 147 break; 148 case extensions::core_api::socket::SOCKET_TYPE_NONE: 149 NOTREACHED(); 150 break; 151 } 152 153 return true; 154} 155 156void 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()); 162 } 163 DCHECK(socket); 164 165 base::DictionaryValue* result = new base::DictionaryValue(); 166 result->SetInteger(kSocketIdKey, AddSocket(socket)); 167 SetResult(result); 168} 169 170bool SocketDestroyFunction::Prepare() { 171 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); 172 return true; 173} 174 175void SocketDestroyFunction::Work() { RemoveSocket(socket_id_); } 176 177SocketConnectFunction::SocketConnectFunction() 178 : socket_id_(0), hostname_(), port_(0), socket_(NULL) {} 179 180SocketConnectFunction::~SocketConnectFunction() {} 181 182bool 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_)); 186 return true; 187} 188 189void SocketConnectFunction::AsyncWorkStart() { 190 socket_ = GetSocket(socket_id_); 191 if (!socket_) { 192 error_ = kSocketNotFoundError; 193 SetResult(new base::FundamentalValue(-1)); 194 AsyncWorkCompleted(); 195 return; 196 } 197 198 SocketPermissionRequest::OperationType operation_type; 199 switch (socket_->GetSocketType()) { 200 case Socket::TYPE_TCP: 201 operation_type = SocketPermissionRequest::TCP_CONNECT; 202 break; 203 case Socket::TYPE_UDP: 204 operation_type = SocketPermissionRequest::UDP_SEND_TO; 205 break; 206 default: 207 NOTREACHED() << "Unknown socket type."; 208 operation_type = SocketPermissionRequest::NONE; 209 break; 210 } 211 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(); 218 return; 219 } 220 221 StartDnsLookup(hostname_); 222} 223 224void SocketConnectFunction::AfterDnsLookup(int lookup_result) { 225 if (lookup_result == net::OK) { 226 StartConnect(); 227 } else { 228 SetResult(new base::FundamentalValue(lookup_result)); 229 AsyncWorkCompleted(); 230 } 231} 232 233void SocketConnectFunction::StartConnect() { 234 socket_->Connect(resolved_address_, 235 port_, 236 base::Bind(&SocketConnectFunction::OnConnect, this)); 237} 238 239void SocketConnectFunction::OnConnect(int result) { 240 SetResult(new base::FundamentalValue(result)); 241 AsyncWorkCompleted(); 242} 243 244bool SocketDisconnectFunction::Prepare() { 245 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); 246 return true; 247} 248 249void SocketDisconnectFunction::Work() { 250 Socket* socket = GetSocket(socket_id_); 251 if (socket) 252 socket->Disconnect(); 253 else 254 error_ = kSocketNotFoundError; 255 SetResult(base::Value::CreateNullValue()); 256} 257 258bool 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_)); 262 return true; 263} 264 265void SocketBindFunction::Work() { 266 int result = -1; 267 Socket* socket = GetSocket(socket_id_); 268 269 if (!socket) { 270 error_ = kSocketNotFoundError; 271 SetResult(new base::FundamentalValue(result)); 272 return; 273 } 274 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)); 282 return; 283 } 284 } else if (socket->GetSocketType() == Socket::TYPE_TCP) { 285 error_ = kTCPSocketBindError; 286 SetResult(new base::FundamentalValue(result)); 287 return; 288 } 289 290 result = socket->Bind(address_, port_); 291 SetResult(new base::FundamentalValue(result)); 292} 293 294SocketListenFunction::SocketListenFunction() {} 295 296SocketListenFunction::~SocketListenFunction() {} 297 298bool SocketListenFunction::Prepare() { 299 params_ = core_api::socket::Listen::Params::Create(*args_); 300 EXTENSION_FUNCTION_VALIDATE(params_.get()); 301 return true; 302} 303 304void SocketListenFunction::Work() { 305 int result = -1; 306 307 Socket* socket = GetSocket(params_->socket_id); 308 if (socket) { 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)); 315 return; 316 } 317 318 result = 319 socket->Listen(params_->address, 320 params_->port, 321 params_->backlog.get() ? *params_->backlog.get() : 5, 322 &error_); 323 } else { 324 error_ = kSocketNotFoundError; 325 } 326 327 SetResult(new base::FundamentalValue(result)); 328} 329 330SocketAcceptFunction::SocketAcceptFunction() {} 331 332SocketAcceptFunction::~SocketAcceptFunction() {} 333 334bool SocketAcceptFunction::Prepare() { 335 params_ = core_api::socket::Accept::Params::Create(*args_); 336 EXTENSION_FUNCTION_VALIDATE(params_.get()); 337 return true; 338} 339 340void SocketAcceptFunction::AsyncWorkStart() { 341 Socket* socket = GetSocket(params_->socket_id); 342 if (socket) { 343 socket->Accept(base::Bind(&SocketAcceptFunction::OnAccept, this)); 344 } else { 345 error_ = kSocketNotFoundError; 346 OnAccept(-1, NULL); 347 } 348} 349 350void SocketAcceptFunction::OnAccept(int result_code, 351 net::TCPClientSocket* socket) { 352 base::DictionaryValue* result = new base::DictionaryValue(); 353 result->SetInteger(kResultCodeKey, result_code); 354 if (socket) { 355 Socket* client_socket = new TCPSocket(socket, extension_id(), true); 356 result->SetInteger(kSocketIdKey, AddSocket(client_socket)); 357 } 358 SetResult(result); 359 360 AsyncWorkCompleted(); 361} 362 363SocketReadFunction::SocketReadFunction() {} 364 365SocketReadFunction::~SocketReadFunction() {} 366 367bool SocketReadFunction::Prepare() { 368 params_ = core_api::socket::Read::Params::Create(*args_); 369 EXTENSION_FUNCTION_VALIDATE(params_.get()); 370 return true; 371} 372 373void SocketReadFunction::AsyncWorkStart() { 374 Socket* socket = GetSocket(params_->socket_id); 375 if (!socket) { 376 error_ = kSocketNotFoundError; 377 OnCompleted(-1, NULL); 378 return; 379 } 380 381 socket->Read(params_->buffer_size.get() ? *params_->buffer_size.get() : 4096, 382 base::Bind(&SocketReadFunction::OnCompleted, this)); 383} 384 385void 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(), 392 bytes_read)); 393 } else { 394 result->Set(kDataKey, new base::BinaryValue()); 395 } 396 SetResult(result); 397 398 AsyncWorkCompleted(); 399} 400 401SocketWriteFunction::SocketWriteFunction() 402 : socket_id_(0), io_buffer_(NULL), io_buffer_size_(0) {} 403 404SocketWriteFunction::~SocketWriteFunction() {} 405 406bool SocketWriteFunction::Prepare() { 407 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); 408 base::BinaryValue* data = NULL; 409 EXTENSION_FUNCTION_VALIDATE(args_->GetBinary(1, &data)); 410 411 io_buffer_size_ = data->GetSize(); 412 io_buffer_ = new net::WrappedIOBuffer(data->GetBuffer()); 413 return true; 414} 415 416void SocketWriteFunction::AsyncWorkStart() { 417 Socket* socket = GetSocket(socket_id_); 418 419 if (!socket) { 420 error_ = kSocketNotFoundError; 421 OnCompleted(-1); 422 return; 423 } 424 425 socket->Write(io_buffer_, 426 io_buffer_size_, 427 base::Bind(&SocketWriteFunction::OnCompleted, this)); 428} 429 430void SocketWriteFunction::OnCompleted(int bytes_written) { 431 base::DictionaryValue* result = new base::DictionaryValue(); 432 result->SetInteger(kBytesWrittenKey, bytes_written); 433 SetResult(result); 434 435 AsyncWorkCompleted(); 436} 437 438SocketRecvFromFunction::SocketRecvFromFunction() {} 439 440SocketRecvFromFunction::~SocketRecvFromFunction() {} 441 442bool SocketRecvFromFunction::Prepare() { 443 params_ = core_api::socket::RecvFrom::Params::Create(*args_); 444 EXTENSION_FUNCTION_VALIDATE(params_.get()); 445 return true; 446} 447 448void SocketRecvFromFunction::AsyncWorkStart() { 449 Socket* socket = GetSocket(params_->socket_id); 450 if (!socket) { 451 error_ = kSocketNotFoundError; 452 OnCompleted(-1, NULL, std::string(), 0); 453 return; 454 } 455 456 socket->RecvFrom(params_->buffer_size.get() ? *params_->buffer_size : 4096, 457 base::Bind(&SocketRecvFromFunction::OnCompleted, this)); 458} 459 460void SocketRecvFromFunction::OnCompleted(int bytes_read, 461 scoped_refptr<net::IOBuffer> io_buffer, 462 const std::string& address, 463 int port) { 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(), 469 bytes_read)); 470 } else { 471 result->Set(kDataKey, new base::BinaryValue()); 472 } 473 result->SetString(kAddressKey, address); 474 result->SetInteger(kPortKey, port); 475 SetResult(result); 476 477 AsyncWorkCompleted(); 478} 479 480SocketSendToFunction::SocketSendToFunction() 481 : socket_id_(0), 482 io_buffer_(NULL), 483 io_buffer_size_(0), 484 port_(0), 485 socket_(NULL) {} 486 487SocketSendToFunction::~SocketSendToFunction() {} 488 489bool 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_)); 495 496 io_buffer_size_ = data->GetSize(); 497 io_buffer_ = new net::WrappedIOBuffer(data->GetBuffer()); 498 return true; 499} 500 501void SocketSendToFunction::AsyncWorkStart() { 502 socket_ = GetSocket(socket_id_); 503 if (!socket_) { 504 error_ = kSocketNotFoundError; 505 SetResult(new base::FundamentalValue(-1)); 506 AsyncWorkCompleted(); 507 return; 508 } 509 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(); 518 return; 519 } 520 } 521 522 StartDnsLookup(hostname_); 523} 524 525void SocketSendToFunction::AfterDnsLookup(int lookup_result) { 526 if (lookup_result == net::OK) { 527 StartSendTo(); 528 } else { 529 SetResult(new base::FundamentalValue(lookup_result)); 530 AsyncWorkCompleted(); 531 } 532} 533 534void SocketSendToFunction::StartSendTo() { 535 socket_->SendTo(io_buffer_, 536 io_buffer_size_, 537 resolved_address_, 538 port_, 539 base::Bind(&SocketSendToFunction::OnCompleted, this)); 540} 541 542void SocketSendToFunction::OnCompleted(int bytes_written) { 543 base::DictionaryValue* result = new base::DictionaryValue(); 544 result->SetInteger(kBytesWrittenKey, bytes_written); 545 SetResult(result); 546 547 AsyncWorkCompleted(); 548} 549 550SocketSetKeepAliveFunction::SocketSetKeepAliveFunction() {} 551 552SocketSetKeepAliveFunction::~SocketSetKeepAliveFunction() {} 553 554bool SocketSetKeepAliveFunction::Prepare() { 555 params_ = core_api::socket::SetKeepAlive::Params::Create(*args_); 556 EXTENSION_FUNCTION_VALIDATE(params_.get()); 557 return true; 558} 559 560void SocketSetKeepAliveFunction::Work() { 561 bool result = false; 562 Socket* socket = GetSocket(params_->socket_id); 563 if (socket) { 564 int delay = 0; 565 if (params_->delay.get()) 566 delay = *params_->delay; 567 result = socket->SetKeepAlive(params_->enable, delay); 568 } else { 569 error_ = kSocketNotFoundError; 570 } 571 SetResult(new base::FundamentalValue(result)); 572} 573 574SocketSetNoDelayFunction::SocketSetNoDelayFunction() {} 575 576SocketSetNoDelayFunction::~SocketSetNoDelayFunction() {} 577 578bool SocketSetNoDelayFunction::Prepare() { 579 params_ = core_api::socket::SetNoDelay::Params::Create(*args_); 580 EXTENSION_FUNCTION_VALIDATE(params_.get()); 581 return true; 582} 583 584void SocketSetNoDelayFunction::Work() { 585 bool result = false; 586 Socket* socket = GetSocket(params_->socket_id); 587 if (socket) 588 result = socket->SetNoDelay(params_->no_delay); 589 else 590 error_ = kSocketNotFoundError; 591 SetResult(new base::FundamentalValue(result)); 592} 593 594SocketGetInfoFunction::SocketGetInfoFunction() {} 595 596SocketGetInfoFunction::~SocketGetInfoFunction() {} 597 598bool SocketGetInfoFunction::Prepare() { 599 params_ = core_api::socket::GetInfo::Params::Create(*args_); 600 EXTENSION_FUNCTION_VALIDATE(params_.get()); 601 return true; 602} 603 604void SocketGetInfoFunction::Work() { 605 Socket* socket = GetSocket(params_->socket_id); 606 if (!socket) { 607 error_ = kSocketNotFoundError; 608 return; 609 } 610 611 core_api::socket::SocketInfo info; 612 // This represents what we know about the socket, and does not call through 613 // to the system. 614 if (socket->GetSocketType() == Socket::TYPE_TCP) 615 info.socket_type = extensions::core_api::socket::SOCKET_TYPE_TCP; 616 else 617 info.socket_type = extensions::core_api::socket::SOCKET_TYPE_UDP; 618 info.connected = socket->IsConnected(); 619 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())); 628 } 629 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())); 636 } 637 638 SetResult(info.ToValue().release()); 639} 640 641bool SocketGetNetworkListFunction::RunImpl() { 642 content::BrowserThread::PostTask( 643 content::BrowserThread::FILE, 644 FROM_HERE, 645 base::Bind(&SocketGetNetworkListFunction::GetNetworkListOnFileThread, 646 this)); 647 return true; 648} 649 650void 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, 656 FROM_HERE, 657 base::Bind(&SocketGetNetworkListFunction::SendResponseOnUIThread, 658 this, 659 interface_list)); 660 return; 661 } 662 663 content::BrowserThread::PostTask( 664 content::BrowserThread::UI, 665 FROM_HERE, 666 base::Bind(&SocketGetNetworkListFunction::HandleGetNetworkListError, 667 this)); 668} 669 670void SocketGetNetworkListFunction::HandleGetNetworkListError() { 671 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 672 error_ = kNetworkListError; 673 SendResponse(false); 674} 675 676void SocketGetNetworkListFunction::SendResponseOnUIThread( 677 const net::NetworkInterfaceList& interface_list) { 678 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 679 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(); 684 ++i) { 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); 691 } 692 693 results_ = core_api::socket::GetNetworkList::Results::Create(create_arg); 694 SendResponse(true); 695} 696 697SocketJoinGroupFunction::SocketJoinGroupFunction() {} 698 699SocketJoinGroupFunction::~SocketJoinGroupFunction() {} 700 701bool SocketJoinGroupFunction::Prepare() { 702 params_ = core_api::socket::JoinGroup::Params::Create(*args_); 703 EXTENSION_FUNCTION_VALIDATE(params_.get()); 704 return true; 705} 706 707void SocketJoinGroupFunction::Work() { 708 int result = -1; 709 Socket* socket = GetSocket(params_->socket_id); 710 if (!socket) { 711 error_ = kSocketNotFoundError; 712 SetResult(new base::FundamentalValue(result)); 713 return; 714 } 715 716 if (socket->GetSocketType() != Socket::TYPE_UDP) { 717 error_ = kMulticastSocketTypeError; 718 SetResult(new base::FundamentalValue(result)); 719 return; 720 } 721 722 SocketPermission::CheckParam param( 723 SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP, 724 kWildcardAddress, 725 kWildcardPort); 726 727 if (!PermissionsData::CheckAPIPermissionWithParam( 728 GetExtension(), APIPermission::kSocket, ¶m)) { 729 error_ = kPermissionError; 730 SetResult(new base::FundamentalValue(result)); 731 return; 732 } 733 734 result = static_cast<UDPSocket*>(socket)->JoinGroup(params_->address); 735 if (result != 0) { 736 error_ = net::ErrorToString(result); 737 } 738 SetResult(new base::FundamentalValue(result)); 739} 740 741SocketLeaveGroupFunction::SocketLeaveGroupFunction() {} 742 743SocketLeaveGroupFunction::~SocketLeaveGroupFunction() {} 744 745bool SocketLeaveGroupFunction::Prepare() { 746 params_ = core_api::socket::LeaveGroup::Params::Create(*args_); 747 EXTENSION_FUNCTION_VALIDATE(params_.get()); 748 return true; 749} 750 751void SocketLeaveGroupFunction::Work() { 752 int result = -1; 753 Socket* socket = GetSocket(params_->socket_id); 754 755 if (!socket) { 756 error_ = kSocketNotFoundError; 757 SetResult(new base::FundamentalValue(result)); 758 return; 759 } 760 761 if (socket->GetSocketType() != Socket::TYPE_UDP) { 762 error_ = kMulticastSocketTypeError; 763 SetResult(new base::FundamentalValue(result)); 764 return; 765 } 766 767 SocketPermission::CheckParam param( 768 SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP, 769 kWildcardAddress, 770 kWildcardPort); 771 if (!PermissionsData::CheckAPIPermissionWithParam( 772 GetExtension(), APIPermission::kSocket, ¶m)) { 773 error_ = kPermissionError; 774 SetResult(new base::FundamentalValue(result)); 775 return; 776 } 777 778 result = static_cast<UDPSocket*>(socket)->LeaveGroup(params_->address); 779 if (result != 0) 780 error_ = net::ErrorToString(result); 781 SetResult(new base::FundamentalValue(result)); 782} 783 784SocketSetMulticastTimeToLiveFunction::SocketSetMulticastTimeToLiveFunction() {} 785 786SocketSetMulticastTimeToLiveFunction::~SocketSetMulticastTimeToLiveFunction() {} 787 788bool SocketSetMulticastTimeToLiveFunction::Prepare() { 789 params_ = core_api::socket::SetMulticastTimeToLive::Params::Create(*args_); 790 EXTENSION_FUNCTION_VALIDATE(params_.get()); 791 return true; 792} 793void SocketSetMulticastTimeToLiveFunction::Work() { 794 int result = -1; 795 Socket* socket = GetSocket(params_->socket_id); 796 if (!socket) { 797 error_ = kSocketNotFoundError; 798 SetResult(new base::FundamentalValue(result)); 799 return; 800 } 801 802 if (socket->GetSocketType() != Socket::TYPE_UDP) { 803 error_ = kMulticastSocketTypeError; 804 SetResult(new base::FundamentalValue(result)); 805 return; 806 } 807 808 result = 809 static_cast<UDPSocket*>(socket)->SetMulticastTimeToLive(params_->ttl); 810 if (result != 0) 811 error_ = net::ErrorToString(result); 812 SetResult(new base::FundamentalValue(result)); 813} 814 815SocketSetMulticastLoopbackModeFunction:: 816 SocketSetMulticastLoopbackModeFunction() {} 817 818SocketSetMulticastLoopbackModeFunction:: 819 ~SocketSetMulticastLoopbackModeFunction() {} 820 821bool SocketSetMulticastLoopbackModeFunction::Prepare() { 822 params_ = core_api::socket::SetMulticastLoopbackMode::Params::Create(*args_); 823 EXTENSION_FUNCTION_VALIDATE(params_.get()); 824 return true; 825} 826 827void SocketSetMulticastLoopbackModeFunction::Work() { 828 int result = -1; 829 Socket* socket = GetSocket(params_->socket_id); 830 if (!socket) { 831 error_ = kSocketNotFoundError; 832 SetResult(new base::FundamentalValue(result)); 833 return; 834 } 835 836 if (socket->GetSocketType() != Socket::TYPE_UDP) { 837 error_ = kMulticastSocketTypeError; 838 SetResult(new base::FundamentalValue(result)); 839 return; 840 } 841 842 result = static_cast<UDPSocket*>(socket) 843 ->SetMulticastLoopbackMode(params_->enabled); 844 if (result != 0) 845 error_ = net::ErrorToString(result); 846 SetResult(new base::FundamentalValue(result)); 847} 848 849SocketGetJoinedGroupsFunction::SocketGetJoinedGroupsFunction() {} 850 851SocketGetJoinedGroupsFunction::~SocketGetJoinedGroupsFunction() {} 852 853bool SocketGetJoinedGroupsFunction::Prepare() { 854 params_ = core_api::socket::GetJoinedGroups::Params::Create(*args_); 855 EXTENSION_FUNCTION_VALIDATE(params_.get()); 856 return true; 857} 858 859void SocketGetJoinedGroupsFunction::Work() { 860 int result = -1; 861 Socket* socket = GetSocket(params_->socket_id); 862 if (!socket) { 863 error_ = kSocketNotFoundError; 864 SetResult(new base::FundamentalValue(result)); 865 return; 866 } 867 868 if (socket->GetSocketType() != Socket::TYPE_UDP) { 869 error_ = kMulticastSocketTypeError; 870 SetResult(new base::FundamentalValue(result)); 871 return; 872 } 873 874 SocketPermission::CheckParam param( 875 SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP, 876 kWildcardAddress, 877 kWildcardPort); 878 if (!PermissionsData::CheckAPIPermissionWithParam( 879 GetExtension(), APIPermission::kSocket, ¶m)) { 880 error_ = kPermissionError; 881 SetResult(new base::FundamentalValue(result)); 882 return; 883 } 884 885 base::ListValue* values = new base::ListValue(); 886 values->AppendStrings((std::vector<std::string>&)static_cast<UDPSocket*>( 887 socket)->GetJoinedGroups()); 888 SetResult(values); 889} 890 891} // namespace extensions 892