1 // Copyright (c) 2012 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 "chrome/browser/extensions/api/socket/socket_api.h" 6 7 #include <vector> 8 9 #include "base/bind.h" 10 #include "base/containers/hash_tables.h" 11 #include "chrome/browser/browser_process.h" 12 #include "chrome/browser/extensions/api/dns/host_resolver_wrapper.h" 13 #include "chrome/browser/extensions/api/socket/socket.h" 14 #include "chrome/browser/extensions/api/socket/tcp_socket.h" 15 #include "chrome/browser/extensions/api/socket/udp_socket.h" 16 #include "chrome/browser/extensions/extension_system.h" 17 #include "chrome/browser/io_thread.h" 18 #include "chrome/common/extensions/permissions/socket_permission.h" 19 #include "extensions/common/extension.h" 20 #include "extensions/common/permissions/permissions_data.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 28 namespace extensions { 29 30 using content::SocketPermissionRequest; 31 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"; 38 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[] = 46 "Only UDP socket supports multicast."; 47 const char kWildcardAddress[] = "*"; 48 const int kWildcardPort = 0; 49 50 SocketAsyncApiFunction::SocketAsyncApiFunction() { 51 } 52 53 SocketAsyncApiFunction::~SocketAsyncApiFunction() { 54 } 55 56 bool SocketAsyncApiFunction::PrePrepare() { 57 manager_ = CreateSocketResourceManager(); 58 return manager_->SetProfile(GetProfile()); 59 } 60 61 bool SocketAsyncApiFunction::Respond() { 62 return error_.empty(); 63 } 64 65 scoped_ptr<SocketResourceManagerInterface> 66 SocketAsyncApiFunction::CreateSocketResourceManager() { 67 return scoped_ptr<SocketResourceManagerInterface>( 68 new SocketResourceManager<Socket>()).Pass(); 69 } 70 71 int SocketAsyncApiFunction::AddSocket(Socket* socket) { 72 return manager_->Add(socket); 73 } 74 75 Socket* SocketAsyncApiFunction::GetSocket(int api_resource_id) { 76 return manager_->Get(extension_->id(), api_resource_id); 77 } 78 79 base::hash_set<int>* SocketAsyncApiFunction::GetSocketIds() { 80 return manager_->GetResourceIds(extension_->id()); 81 } 82 83 void SocketAsyncApiFunction::RemoveSocket(int api_resource_id) { 84 manager_->Remove(extension_->id(), api_resource_id); 85 } 86 87 SocketExtensionWithDnsLookupFunction::SocketExtensionWithDnsLookupFunction() 88 : io_thread_(g_browser_process->io_thread()), 89 request_handle_(new net::HostResolver::RequestHandle), 90 addresses_(new net::AddressList) { 91 } 92 93 SocketExtensionWithDnsLookupFunction::~SocketExtensionWithDnsLookupFunction() { 94 } 95 96 void SocketExtensionWithDnsLookupFunction::StartDnsLookup( 97 const std::string& hostname) { 98 net::HostResolver* host_resolver = 99 HostResolverWrapper::GetInstance()->GetHostResolver( 100 io_thread_->globals()->host_resolver.get()); 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 122 void 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 132 SocketCreateFunction::SocketCreateFunction() 133 : socket_type_(kSocketTypeInvalid) { 134 } 135 136 SocketCreateFunction::~SocketCreateFunction() {} 137 138 bool SocketCreateFunction::Prepare() { 139 params_ = api::socket::Create::Params::Create(*args_); 140 EXTENSION_FUNCTION_VALIDATE(params_.get()); 141 142 switch (params_->type) { 143 case extensions::api::socket::SOCKET_TYPE_TCP: 144 socket_type_ = kSocketTypeTCP; 145 break; 146 case extensions::api::socket::SOCKET_TYPE_UDP: 147 socket_type_ = kSocketTypeUDP; 148 break; 149 case extensions::api::socket::SOCKET_TYPE_NONE: 150 NOTREACHED(); 151 break; 152 } 153 154 return true; 155 } 156 157 void SocketCreateFunction::Work() { 158 Socket* socket = NULL; 159 if (socket_type_ == kSocketTypeTCP) { 160 socket = new TCPSocket(extension_->id()); 161 } else if (socket_type_== kSocketTypeUDP) { 162 socket = new UDPSocket(extension_->id()); 163 } 164 DCHECK(socket); 165 166 base::DictionaryValue* result = new base::DictionaryValue(); 167 result->SetInteger(kSocketIdKey, AddSocket(socket)); 168 SetResult(result); 169 } 170 171 bool SocketDestroyFunction::Prepare() { 172 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); 173 return true; 174 } 175 176 void SocketDestroyFunction::Work() { 177 RemoveSocket(socket_id_); 178 } 179 180 SocketConnectFunction::SocketConnectFunction() 181 : socket_id_(0), 182 hostname_(), 183 port_(0), 184 socket_(NULL) { 185 } 186 187 SocketConnectFunction::~SocketConnectFunction() { 188 } 189 190 bool SocketConnectFunction::Prepare() { 191 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); 192 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &hostname_)); 193 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(2, &port_)); 194 return true; 195 } 196 197 void SocketConnectFunction::AsyncWorkStart() { 198 socket_ = GetSocket(socket_id_); 199 if (!socket_) { 200 error_ = kSocketNotFoundError; 201 SetResult(new base::FundamentalValue(-1)); 202 AsyncWorkCompleted(); 203 return; 204 } 205 206 SocketPermissionRequest::OperationType operation_type; 207 switch (socket_->GetSocketType()) { 208 case Socket::TYPE_TCP: 209 operation_type = SocketPermissionRequest::TCP_CONNECT; 210 break; 211 case Socket::TYPE_UDP: 212 operation_type = SocketPermissionRequest::UDP_SEND_TO; 213 break; 214 default: 215 NOTREACHED() << "Unknown socket type."; 216 operation_type = SocketPermissionRequest::NONE; 217 break; 218 } 219 220 SocketPermission::CheckParam param(operation_type, hostname_, port_); 221 if (!PermissionsData::CheckAPIPermissionWithParam( 222 GetExtension(), APIPermission::kSocket, ¶m)) { 223 error_ = kPermissionError; 224 SetResult(new base::FundamentalValue(-1)); 225 AsyncWorkCompleted(); 226 return; 227 } 228 229 StartDnsLookup(hostname_); 230 } 231 232 void SocketConnectFunction::AfterDnsLookup(int lookup_result) { 233 if (lookup_result == net::OK) { 234 StartConnect(); 235 } else { 236 SetResult(new base::FundamentalValue(lookup_result)); 237 AsyncWorkCompleted(); 238 } 239 } 240 241 void SocketConnectFunction::StartConnect() { 242 socket_->Connect(resolved_address_, port_, 243 base::Bind(&SocketConnectFunction::OnConnect, this)); 244 } 245 246 void SocketConnectFunction::OnConnect(int result) { 247 SetResult(new base::FundamentalValue(result)); 248 AsyncWorkCompleted(); 249 } 250 251 bool SocketDisconnectFunction::Prepare() { 252 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); 253 return true; 254 } 255 256 void SocketDisconnectFunction::Work() { 257 Socket* socket = GetSocket(socket_id_); 258 if (socket) 259 socket->Disconnect(); 260 else 261 error_ = kSocketNotFoundError; 262 SetResult(Value::CreateNullValue()); 263 } 264 265 bool SocketBindFunction::Prepare() { 266 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); 267 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &address_)); 268 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(2, &port_)); 269 return true; 270 } 271 272 void SocketBindFunction::Work() { 273 int result = -1; 274 Socket* socket = GetSocket(socket_id_); 275 276 if (!socket) { 277 error_ = kSocketNotFoundError; 278 SetResult(new base::FundamentalValue(result)); 279 return; 280 } 281 282 if (socket->GetSocketType() == Socket::TYPE_UDP) { 283 SocketPermission::CheckParam param( 284 SocketPermissionRequest::UDP_BIND, address_, port_); 285 if (!PermissionsData::CheckAPIPermissionWithParam( 286 GetExtension(), 287 APIPermission::kSocket, 288 ¶m)) { 289 error_ = kPermissionError; 290 SetResult(new base::FundamentalValue(result)); 291 return; 292 } 293 } else if (socket->GetSocketType() == Socket::TYPE_TCP) { 294 error_ = kTCPSocketBindError; 295 SetResult(new base::FundamentalValue(result)); 296 return; 297 } 298 299 result = socket->Bind(address_, port_); 300 SetResult(new base::FundamentalValue(result)); 301 } 302 303 SocketListenFunction::SocketListenFunction() {} 304 305 SocketListenFunction::~SocketListenFunction() {} 306 307 bool SocketListenFunction::Prepare() { 308 params_ = api::socket::Listen::Params::Create(*args_); 309 EXTENSION_FUNCTION_VALIDATE(params_.get()); 310 return true; 311 } 312 313 void SocketListenFunction::Work() { 314 int result = -1; 315 316 Socket* socket = GetSocket(params_->socket_id); 317 if (socket) { 318 SocketPermission::CheckParam param( 319 SocketPermissionRequest::TCP_LISTEN, params_->address, params_->port); 320 if (!PermissionsData::CheckAPIPermissionWithParam( 321 GetExtension(), 322 APIPermission::kSocket, 323 ¶m)) { 324 error_ = kPermissionError; 325 SetResult(new base::FundamentalValue(result)); 326 return; 327 } 328 329 result = socket->Listen( 330 params_->address, 331 params_->port, 332 params_->backlog.get() ? *params_->backlog.get() : 5, 333 &error_); 334 } else { 335 error_ = kSocketNotFoundError; 336 } 337 338 SetResult(new base::FundamentalValue(result)); 339 } 340 341 SocketAcceptFunction::SocketAcceptFunction() {} 342 343 SocketAcceptFunction::~SocketAcceptFunction() {} 344 345 bool SocketAcceptFunction::Prepare() { 346 params_ = api::socket::Accept::Params::Create(*args_); 347 EXTENSION_FUNCTION_VALIDATE(params_.get()); 348 return true; 349 } 350 351 void SocketAcceptFunction::AsyncWorkStart() { 352 Socket* socket = GetSocket(params_->socket_id); 353 if (socket) { 354 socket->Accept(base::Bind(&SocketAcceptFunction::OnAccept, this)); 355 } else { 356 error_ = kSocketNotFoundError; 357 OnAccept(-1, NULL); 358 } 359 } 360 361 void SocketAcceptFunction::OnAccept(int result_code, 362 net::TCPClientSocket *socket) { 363 base::DictionaryValue* result = new base::DictionaryValue(); 364 result->SetInteger(kResultCodeKey, result_code); 365 if (socket) { 366 Socket *client_socket = new TCPSocket(socket, extension_id(), true); 367 result->SetInteger(kSocketIdKey, AddSocket(client_socket)); 368 } 369 SetResult(result); 370 371 AsyncWorkCompleted(); 372 } 373 374 SocketReadFunction::SocketReadFunction() {} 375 376 SocketReadFunction::~SocketReadFunction() {} 377 378 bool SocketReadFunction::Prepare() { 379 params_ = api::socket::Read::Params::Create(*args_); 380 EXTENSION_FUNCTION_VALIDATE(params_.get()); 381 return true; 382 } 383 384 void SocketReadFunction::AsyncWorkStart() { 385 Socket* socket = GetSocket(params_->socket_id); 386 if (!socket) { 387 error_ = kSocketNotFoundError; 388 OnCompleted(-1, NULL); 389 return; 390 } 391 392 socket->Read(params_->buffer_size.get() ? *params_->buffer_size.get() : 4096, 393 base::Bind(&SocketReadFunction::OnCompleted, this)); 394 } 395 396 void SocketReadFunction::OnCompleted(int bytes_read, 397 scoped_refptr<net::IOBuffer> io_buffer) { 398 base::DictionaryValue* result = new base::DictionaryValue(); 399 result->SetInteger(kResultCodeKey, bytes_read); 400 if (bytes_read > 0) { 401 result->Set(kDataKey, 402 base::BinaryValue::CreateWithCopiedBuffer(io_buffer->data(), 403 bytes_read)); 404 } else { 405 result->Set(kDataKey, new base::BinaryValue()); 406 } 407 SetResult(result); 408 409 AsyncWorkCompleted(); 410 } 411 412 SocketWriteFunction::SocketWriteFunction() 413 : socket_id_(0), 414 io_buffer_(NULL), 415 io_buffer_size_(0) { 416 } 417 418 SocketWriteFunction::~SocketWriteFunction() {} 419 420 bool SocketWriteFunction::Prepare() { 421 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); 422 base::BinaryValue *data = NULL; 423 EXTENSION_FUNCTION_VALIDATE(args_->GetBinary(1, &data)); 424 425 io_buffer_size_ = data->GetSize(); 426 io_buffer_ = new net::WrappedIOBuffer(data->GetBuffer()); 427 return true; 428 } 429 430 void SocketWriteFunction::AsyncWorkStart() { 431 Socket* socket = GetSocket(socket_id_); 432 433 if (!socket) { 434 error_ = kSocketNotFoundError; 435 OnCompleted(-1); 436 return; 437 } 438 439 socket->Write(io_buffer_, io_buffer_size_, 440 base::Bind(&SocketWriteFunction::OnCompleted, this)); 441 } 442 443 void SocketWriteFunction::OnCompleted(int bytes_written) { 444 base::DictionaryValue* result = new base::DictionaryValue(); 445 result->SetInteger(kBytesWrittenKey, bytes_written); 446 SetResult(result); 447 448 AsyncWorkCompleted(); 449 } 450 451 SocketRecvFromFunction::SocketRecvFromFunction() {} 452 453 SocketRecvFromFunction::~SocketRecvFromFunction() {} 454 455 bool SocketRecvFromFunction::Prepare() { 456 params_ = api::socket::RecvFrom::Params::Create(*args_); 457 EXTENSION_FUNCTION_VALIDATE(params_.get()); 458 return true; 459 } 460 461 void SocketRecvFromFunction::AsyncWorkStart() { 462 Socket* socket = GetSocket(params_->socket_id); 463 if (!socket) { 464 error_ = kSocketNotFoundError; 465 OnCompleted(-1, NULL, std::string(), 0); 466 return; 467 } 468 469 socket->RecvFrom(params_->buffer_size.get() ? *params_->buffer_size : 4096, 470 base::Bind(&SocketRecvFromFunction::OnCompleted, this)); 471 } 472 473 void SocketRecvFromFunction::OnCompleted(int bytes_read, 474 scoped_refptr<net::IOBuffer> io_buffer, 475 const std::string& address, 476 int port) { 477 base::DictionaryValue* result = new base::DictionaryValue(); 478 result->SetInteger(kResultCodeKey, bytes_read); 479 if (bytes_read > 0) { 480 result->Set(kDataKey, 481 base::BinaryValue::CreateWithCopiedBuffer(io_buffer->data(), 482 bytes_read)); 483 } else { 484 result->Set(kDataKey, new base::BinaryValue()); 485 } 486 result->SetString(kAddressKey, address); 487 result->SetInteger(kPortKey, port); 488 SetResult(result); 489 490 AsyncWorkCompleted(); 491 } 492 493 SocketSendToFunction::SocketSendToFunction() 494 : socket_id_(0), 495 io_buffer_(NULL), 496 io_buffer_size_(0), 497 port_(0), 498 socket_(NULL) { 499 } 500 501 SocketSendToFunction::~SocketSendToFunction() {} 502 503 bool SocketSendToFunction::Prepare() { 504 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); 505 base::BinaryValue *data = NULL; 506 EXTENSION_FUNCTION_VALIDATE(args_->GetBinary(1, &data)); 507 EXTENSION_FUNCTION_VALIDATE(args_->GetString(2, &hostname_)); 508 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(3, &port_)); 509 510 io_buffer_size_ = data->GetSize(); 511 io_buffer_ = new net::WrappedIOBuffer(data->GetBuffer()); 512 return true; 513 } 514 515 void SocketSendToFunction::AsyncWorkStart() { 516 socket_ = GetSocket(socket_id_); 517 if (!socket_) { 518 error_ = kSocketNotFoundError; 519 SetResult(new base::FundamentalValue(-1)); 520 AsyncWorkCompleted(); 521 return; 522 } 523 524 if (socket_->GetSocketType() == Socket::TYPE_UDP) { 525 SocketPermission::CheckParam param(SocketPermissionRequest::UDP_SEND_TO, 526 hostname_, port_); 527 if (!PermissionsData::CheckAPIPermissionWithParam( 528 GetExtension(), 529 APIPermission::kSocket, 530 ¶m)) { 531 error_ = kPermissionError; 532 SetResult(new base::FundamentalValue(-1)); 533 AsyncWorkCompleted(); 534 return; 535 } 536 } 537 538 StartDnsLookup(hostname_); 539 } 540 541 void SocketSendToFunction::AfterDnsLookup(int lookup_result) { 542 if (lookup_result == net::OK) { 543 StartSendTo(); 544 } else { 545 SetResult(new base::FundamentalValue(lookup_result)); 546 AsyncWorkCompleted(); 547 } 548 } 549 550 void SocketSendToFunction::StartSendTo() { 551 socket_->SendTo(io_buffer_, io_buffer_size_, resolved_address_, port_, 552 base::Bind(&SocketSendToFunction::OnCompleted, this)); 553 } 554 555 void SocketSendToFunction::OnCompleted(int bytes_written) { 556 base::DictionaryValue* result = new base::DictionaryValue(); 557 result->SetInteger(kBytesWrittenKey, bytes_written); 558 SetResult(result); 559 560 AsyncWorkCompleted(); 561 } 562 563 SocketSetKeepAliveFunction::SocketSetKeepAliveFunction() {} 564 565 SocketSetKeepAliveFunction::~SocketSetKeepAliveFunction() {} 566 567 bool SocketSetKeepAliveFunction::Prepare() { 568 params_ = api::socket::SetKeepAlive::Params::Create(*args_); 569 EXTENSION_FUNCTION_VALIDATE(params_.get()); 570 return true; 571 } 572 573 void SocketSetKeepAliveFunction::Work() { 574 bool result = false; 575 Socket* socket = GetSocket(params_->socket_id); 576 if (socket) { 577 int delay = 0; 578 if (params_->delay.get()) 579 delay = *params_->delay; 580 result = socket->SetKeepAlive(params_->enable, delay); 581 } else { 582 error_ = kSocketNotFoundError; 583 } 584 SetResult(new base::FundamentalValue(result)); 585 } 586 587 SocketSetNoDelayFunction::SocketSetNoDelayFunction() {} 588 589 SocketSetNoDelayFunction::~SocketSetNoDelayFunction() {} 590 591 bool SocketSetNoDelayFunction::Prepare() { 592 params_ = api::socket::SetNoDelay::Params::Create(*args_); 593 EXTENSION_FUNCTION_VALIDATE(params_.get()); 594 return true; 595 } 596 597 void SocketSetNoDelayFunction::Work() { 598 bool result = false; 599 Socket* socket = GetSocket(params_->socket_id); 600 if (socket) 601 result = socket->SetNoDelay(params_->no_delay); 602 else 603 error_ = kSocketNotFoundError; 604 SetResult(new base::FundamentalValue(result)); 605 } 606 607 SocketGetInfoFunction::SocketGetInfoFunction() {} 608 609 SocketGetInfoFunction::~SocketGetInfoFunction() {} 610 611 bool SocketGetInfoFunction::Prepare() { 612 params_ = api::socket::GetInfo::Params::Create(*args_); 613 EXTENSION_FUNCTION_VALIDATE(params_.get()); 614 return true; 615 } 616 617 void SocketGetInfoFunction::Work() { 618 Socket* socket = GetSocket(params_->socket_id); 619 if (!socket) { 620 error_ = kSocketNotFoundError; 621 return; 622 } 623 624 api::socket::SocketInfo info; 625 // This represents what we know about the socket, and does not call through 626 // to the system. 627 if (socket->GetSocketType() == Socket::TYPE_TCP) 628 info.socket_type = extensions::api::socket::SOCKET_TYPE_TCP; 629 else 630 info.socket_type = extensions::api::socket::SOCKET_TYPE_UDP; 631 info.connected = socket->IsConnected(); 632 633 // Grab the peer address as known by the OS. This and the call below will 634 // always succeed while the socket is connected, even if the socket has 635 // been remotely closed by the peer; only reading the socket will reveal 636 // that it should be closed locally. 637 net::IPEndPoint peerAddress; 638 if (socket->GetPeerAddress(&peerAddress)) { 639 info.peer_address.reset( 640 new std::string(peerAddress.ToStringWithoutPort())); 641 info.peer_port.reset(new int(peerAddress.port())); 642 } 643 644 // Grab the local address as known by the OS. 645 net::IPEndPoint localAddress; 646 if (socket->GetLocalAddress(&localAddress)) { 647 info.local_address.reset( 648 new std::string(localAddress.ToStringWithoutPort())); 649 info.local_port.reset(new int(localAddress.port())); 650 } 651 652 SetResult(info.ToValue().release()); 653 } 654 655 bool SocketGetNetworkListFunction::RunImpl() { 656 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE, 657 base::Bind(&SocketGetNetworkListFunction::GetNetworkListOnFileThread, 658 this)); 659 return true; 660 } 661 662 void SocketGetNetworkListFunction::GetNetworkListOnFileThread() { 663 net::NetworkInterfaceList interface_list; 664 if (GetNetworkList(&interface_list)) { 665 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, 666 base::Bind(&SocketGetNetworkListFunction::SendResponseOnUIThread, 667 this, interface_list)); 668 return; 669 } 670 671 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, 672 base::Bind(&SocketGetNetworkListFunction::HandleGetNetworkListError, 673 this)); 674 } 675 676 void SocketGetNetworkListFunction::HandleGetNetworkListError() { 677 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 678 error_ = kNetworkListError; 679 SendResponse(false); 680 } 681 682 void SocketGetNetworkListFunction::SendResponseOnUIThread( 683 const net::NetworkInterfaceList& interface_list) { 684 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 685 686 std::vector<linked_ptr<api::socket::NetworkInterface> > create_arg; 687 create_arg.reserve(interface_list.size()); 688 for (net::NetworkInterfaceList::const_iterator i = interface_list.begin(); 689 i != interface_list.end(); ++i) { 690 linked_ptr<api::socket::NetworkInterface> info = 691 make_linked_ptr(new api::socket::NetworkInterface); 692 info->name = i->name; 693 info->address = net::IPAddressToString(i->address); 694 info->prefix_length = i->network_prefix; 695 create_arg.push_back(info); 696 } 697 698 results_ = api::socket::GetNetworkList::Results::Create(create_arg); 699 SendResponse(true); 700 } 701 702 SocketJoinGroupFunction::SocketJoinGroupFunction() {} 703 704 SocketJoinGroupFunction::~SocketJoinGroupFunction() {} 705 706 bool SocketJoinGroupFunction::Prepare() { 707 params_ = api::socket::JoinGroup::Params::Create(*args_); 708 EXTENSION_FUNCTION_VALIDATE(params_.get()); 709 return true; 710 } 711 712 void SocketJoinGroupFunction::Work() { 713 int result = -1; 714 Socket* socket = GetSocket(params_->socket_id); 715 if (!socket) { 716 error_ = kSocketNotFoundError; 717 SetResult(new base::FundamentalValue(result)); 718 return; 719 } 720 721 if (socket->GetSocketType() != Socket::TYPE_UDP) { 722 error_ = kMulticastSocketTypeError; 723 SetResult(new base::FundamentalValue(result)); 724 return; 725 } 726 727 SocketPermission::CheckParam param( 728 SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP, 729 kWildcardAddress, 730 kWildcardPort); 731 732 if (!PermissionsData::CheckAPIPermissionWithParam( 733 GetExtension(), APIPermission::kSocket, ¶m)) { 734 error_ = kPermissionError; 735 SetResult(new base::FundamentalValue(result)); 736 return; 737 } 738 739 result = static_cast<UDPSocket*>(socket)->JoinGroup(params_->address); 740 if (result != 0) { 741 error_ = net::ErrorToString(result); 742 } 743 SetResult(new base::FundamentalValue(result)); 744 } 745 746 SocketLeaveGroupFunction::SocketLeaveGroupFunction() {} 747 748 SocketLeaveGroupFunction::~SocketLeaveGroupFunction() {} 749 750 bool SocketLeaveGroupFunction::Prepare() { 751 params_ = api::socket::LeaveGroup::Params::Create(*args_); 752 EXTENSION_FUNCTION_VALIDATE(params_.get()); 753 return true; 754 } 755 756 void SocketLeaveGroupFunction::Work() { 757 int result = -1; 758 Socket* socket = GetSocket(params_->socket_id); 759 760 if (!socket) { 761 error_ = kSocketNotFoundError; 762 SetResult(new base::FundamentalValue(result)); 763 return; 764 } 765 766 if (socket->GetSocketType() != Socket::TYPE_UDP) { 767 error_ = kMulticastSocketTypeError; 768 SetResult(new base::FundamentalValue(result)); 769 return; 770 } 771 772 SocketPermission::CheckParam param( 773 SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP, 774 kWildcardAddress, 775 kWildcardPort); 776 if (!PermissionsData::CheckAPIPermissionWithParam(GetExtension(), 777 APIPermission::kSocket, 778 ¶m)) { 779 error_ = kPermissionError; 780 SetResult(new base::FundamentalValue(result)); 781 return; 782 } 783 784 result = static_cast<UDPSocket*>(socket)->LeaveGroup(params_->address); 785 if (result != 0) 786 error_ = net::ErrorToString(result); 787 SetResult(new base::FundamentalValue(result)); 788 } 789 790 SocketSetMulticastTimeToLiveFunction::SocketSetMulticastTimeToLiveFunction() {} 791 792 SocketSetMulticastTimeToLiveFunction::~SocketSetMulticastTimeToLiveFunction() {} 793 794 bool SocketSetMulticastTimeToLiveFunction::Prepare() { 795 params_ = api::socket::SetMulticastTimeToLive::Params::Create(*args_); 796 EXTENSION_FUNCTION_VALIDATE(params_.get()); 797 return true; 798 } 799 void SocketSetMulticastTimeToLiveFunction::Work() { 800 int result = -1; 801 Socket* socket = GetSocket(params_->socket_id); 802 if (!socket) { 803 error_ = kSocketNotFoundError; 804 SetResult(new base::FundamentalValue(result)); 805 return; 806 } 807 808 if (socket->GetSocketType() != Socket::TYPE_UDP) { 809 error_ = kMulticastSocketTypeError; 810 SetResult(new base::FundamentalValue(result)); 811 return; 812 } 813 814 result = static_cast<UDPSocket*>(socket)->SetMulticastTimeToLive( 815 params_->ttl); 816 if (result != 0) 817 error_ = net::ErrorToString(result); 818 SetResult(new base::FundamentalValue(result)); 819 } 820 821 SocketSetMulticastLoopbackModeFunction:: 822 SocketSetMulticastLoopbackModeFunction() {} 823 824 SocketSetMulticastLoopbackModeFunction:: 825 ~SocketSetMulticastLoopbackModeFunction() {} 826 827 bool SocketSetMulticastLoopbackModeFunction::Prepare() { 828 params_ = api::socket::SetMulticastLoopbackMode::Params::Create(*args_); 829 EXTENSION_FUNCTION_VALIDATE(params_.get()); 830 return true; 831 } 832 833 void SocketSetMulticastLoopbackModeFunction::Work() { 834 int result = -1; 835 Socket* socket = GetSocket(params_->socket_id); 836 if (!socket) { 837 error_ = kSocketNotFoundError; 838 SetResult(new base::FundamentalValue(result)); 839 return; 840 } 841 842 if (socket->GetSocketType() != Socket::TYPE_UDP) { 843 error_ = kMulticastSocketTypeError; 844 SetResult(new base::FundamentalValue(result)); 845 return; 846 } 847 848 result = static_cast<UDPSocket*>(socket)-> 849 SetMulticastLoopbackMode(params_->enabled); 850 if (result != 0) 851 error_ = net::ErrorToString(result); 852 SetResult(new base::FundamentalValue(result)); 853 } 854 855 SocketGetJoinedGroupsFunction::SocketGetJoinedGroupsFunction() {} 856 857 SocketGetJoinedGroupsFunction::~SocketGetJoinedGroupsFunction() {} 858 859 bool SocketGetJoinedGroupsFunction::Prepare() { 860 params_ = api::socket::GetJoinedGroups::Params::Create(*args_); 861 EXTENSION_FUNCTION_VALIDATE(params_.get()); 862 return true; 863 } 864 865 void SocketGetJoinedGroupsFunction::Work() { 866 int result = -1; 867 Socket* socket = GetSocket(params_->socket_id); 868 if (!socket) { 869 error_ = kSocketNotFoundError; 870 SetResult(new base::FundamentalValue(result)); 871 return; 872 } 873 874 if (socket->GetSocketType() != Socket::TYPE_UDP) { 875 error_ = kMulticastSocketTypeError; 876 SetResult(new base::FundamentalValue(result)); 877 return; 878 } 879 880 SocketPermission::CheckParam param( 881 SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP, 882 kWildcardAddress, 883 kWildcardPort); 884 if (!PermissionsData::CheckAPIPermissionWithParam( 885 GetExtension(), 886 APIPermission::kSocket, 887 ¶m)) { 888 error_ = kPermissionError; 889 SetResult(new base::FundamentalValue(result)); 890 return; 891 } 892 893 base::ListValue* values = new base::ListValue(); 894 values->AppendStrings((std::vector<std::string>&) 895 static_cast<UDPSocket*>(socket)->GetJoinedGroups()); 896 SetResult(values); 897 } 898 899 } // namespace extensions 900