Home | History | Annotate | Download | only in socket
      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, &param)) {
    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             &param)) {
    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             &param)) {
    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             &param)) {
    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, &param)) {
    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                                                     &param)) {
    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           &param)) {
    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