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