Home | History | Annotate | Download | only in p2p
      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 "content/renderer/p2p/socket_dispatcher.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/memory/ref_counted.h"
      9 #include "base/message_loop/message_loop_proxy.h"
     10 #include "content/child/child_process.h"
     11 #include "content/common/p2p_messages.h"
     12 #include "content/renderer/p2p/host_address_request.h"
     13 #include "content/renderer/p2p/network_list_observer.h"
     14 #include "content/renderer/p2p/socket_client_impl.h"
     15 #include "content/renderer/render_view_impl.h"
     16 #include "ipc/ipc_sender.h"
     17 
     18 namespace content {
     19 
     20 P2PSocketDispatcher::P2PSocketDispatcher(
     21     base::MessageLoopProxy* ipc_message_loop)
     22     : message_loop_(ipc_message_loop),
     23       network_notifications_started_(false),
     24       network_list_observers_(
     25           new ObserverListThreadSafe<NetworkListObserver>()),
     26       sender_(NULL) {
     27 }
     28 
     29 P2PSocketDispatcher::~P2PSocketDispatcher() {
     30   network_list_observers_->AssertEmpty();
     31   for (IDMap<P2PSocketClientImpl>::iterator i(&clients_); !i.IsAtEnd();
     32        i.Advance()) {
     33     i.GetCurrentValue()->Detach();
     34   }
     35 }
     36 
     37 void P2PSocketDispatcher::AddNetworkListObserver(
     38     NetworkListObserver* network_list_observer) {
     39   network_list_observers_->AddObserver(network_list_observer);
     40   network_notifications_started_ = true;
     41   SendP2PMessage(new P2PHostMsg_StartNetworkNotifications());
     42 }
     43 
     44 void P2PSocketDispatcher::RemoveNetworkListObserver(
     45     NetworkListObserver* network_list_observer) {
     46   network_list_observers_->RemoveObserver(network_list_observer);
     47 }
     48 
     49 void P2PSocketDispatcher::Send(IPC::Message* message) {
     50   DCHECK(message_loop_->BelongsToCurrentThread());
     51   if (!sender_) {
     52     DLOG(WARNING) << "P2PSocketDispatcher::Send() - Sender closed.";
     53     delete message;
     54     return;
     55   }
     56 
     57   sender_->Send(message);
     58 }
     59 
     60 bool P2PSocketDispatcher::OnMessageReceived(const IPC::Message& message) {
     61   bool handled = true;
     62   IPC_BEGIN_MESSAGE_MAP(P2PSocketDispatcher, message)
     63     IPC_MESSAGE_HANDLER(P2PMsg_NetworkListChanged, OnNetworkListChanged)
     64     IPC_MESSAGE_HANDLER(P2PMsg_GetHostAddressResult, OnGetHostAddressResult)
     65     IPC_MESSAGE_HANDLER(P2PMsg_OnSocketCreated, OnSocketCreated)
     66     IPC_MESSAGE_HANDLER(P2PMsg_OnIncomingTcpConnection, OnIncomingTcpConnection)
     67     IPC_MESSAGE_HANDLER(P2PMsg_OnSendComplete, OnSendComplete)
     68     IPC_MESSAGE_HANDLER(P2PMsg_OnError, OnError)
     69     IPC_MESSAGE_HANDLER(P2PMsg_OnDataReceived, OnDataReceived)
     70     IPC_MESSAGE_UNHANDLED(handled = false)
     71   IPC_END_MESSAGE_MAP()
     72   return handled;
     73 }
     74 
     75 void P2PSocketDispatcher::OnFilterAdded(IPC::Sender* sender) {
     76   DVLOG(1) << "P2PSocketDispatcher::OnFilterAdded()";
     77   sender_ = sender;
     78 }
     79 
     80 void P2PSocketDispatcher::OnFilterRemoved() {
     81   sender_ = NULL;
     82 }
     83 
     84 void P2PSocketDispatcher::OnChannelClosing() {
     85   sender_ = NULL;
     86 }
     87 
     88 base::MessageLoopProxy* P2PSocketDispatcher::message_loop() {
     89   return message_loop_.get();
     90 }
     91 
     92 int P2PSocketDispatcher::RegisterClient(P2PSocketClientImpl* client) {
     93   DCHECK(message_loop_->BelongsToCurrentThread());
     94   return clients_.Add(client);
     95 }
     96 
     97 void P2PSocketDispatcher::UnregisterClient(int id) {
     98   DCHECK(message_loop_->BelongsToCurrentThread());
     99   clients_.Remove(id);
    100 }
    101 
    102 void P2PSocketDispatcher::SendP2PMessage(IPC::Message* msg) {
    103   if (!message_loop_->BelongsToCurrentThread()) {
    104     message_loop_->PostTask(FROM_HERE,
    105                             base::Bind(&P2PSocketDispatcher::Send,
    106                                        this, msg));
    107     return;
    108   }
    109   Send(msg);
    110 }
    111 
    112 int P2PSocketDispatcher::RegisterHostAddressRequest(
    113     P2PAsyncAddressResolver* request) {
    114   DCHECK(message_loop_->BelongsToCurrentThread());
    115   return host_address_requests_.Add(request);
    116 }
    117 
    118 void P2PSocketDispatcher::UnregisterHostAddressRequest(int id) {
    119   DCHECK(message_loop_->BelongsToCurrentThread());
    120   host_address_requests_.Remove(id);
    121 }
    122 
    123 void P2PSocketDispatcher::OnNetworkListChanged(
    124     const net::NetworkInterfaceList& networks) {
    125   network_list_observers_->Notify(
    126       &NetworkListObserver::OnNetworkListChanged, networks);
    127 }
    128 
    129 void P2PSocketDispatcher::OnGetHostAddressResult(
    130     int32 request_id,
    131     const net::IPAddressList& addresses) {
    132   P2PAsyncAddressResolver* request = host_address_requests_.Lookup(request_id);
    133   if (!request) {
    134     VLOG(1) << "Received P2P message for socket that doesn't exist.";
    135     return;
    136   }
    137 
    138   request->OnResponse(addresses);
    139 }
    140 
    141 void P2PSocketDispatcher::OnSocketCreated(
    142     int socket_id,
    143     const net::IPEndPoint& local_address,
    144     const net::IPEndPoint& remote_address) {
    145   P2PSocketClientImpl* client = GetClient(socket_id);
    146   if (client) {
    147     client->OnSocketCreated(local_address, remote_address);
    148   }
    149 }
    150 
    151 void P2PSocketDispatcher::OnIncomingTcpConnection(
    152     int socket_id, const net::IPEndPoint& address) {
    153   P2PSocketClientImpl* client = GetClient(socket_id);
    154   if (client) {
    155     client->OnIncomingTcpConnection(address);
    156   }
    157 }
    158 
    159 void P2PSocketDispatcher::OnSendComplete(int socket_id) {
    160   P2PSocketClientImpl* client = GetClient(socket_id);
    161   if (client) {
    162     client->OnSendComplete();
    163   }
    164 }
    165 
    166 void P2PSocketDispatcher::OnError(int socket_id) {
    167   P2PSocketClientImpl* client = GetClient(socket_id);
    168   if (client) {
    169     client->OnError();
    170   }
    171 }
    172 
    173 void P2PSocketDispatcher::OnDataReceived(
    174     int socket_id, const net::IPEndPoint& address,
    175     const std::vector<char>& data,
    176     const base::TimeTicks& timestamp) {
    177   P2PSocketClientImpl* client = GetClient(socket_id);
    178   if (client) {
    179     client->OnDataReceived(address, data, timestamp);
    180   }
    181 }
    182 
    183 P2PSocketClientImpl* P2PSocketDispatcher::GetClient(int socket_id) {
    184   P2PSocketClientImpl* client = clients_.Lookup(socket_id);
    185   if (client == NULL) {
    186     // This may happen if the socket was closed, but the browser side
    187     // hasn't processed the close message by the time it sends the
    188     // message to the renderer.
    189     VLOG(1) << "Received P2P message for socket that doesn't exist.";
    190     return NULL;
    191   }
    192 
    193   return client;
    194 }
    195 
    196 }  // namespace content
    197