| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/renderer_host/p2p/socket_dispatcher_host.h" | 5 #include "content/browser/renderer_host/p2p/socket_dispatcher_host.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
| 9 #include "content/browser/renderer_host/p2p/socket_host.h" | 9 #include "content/browser/renderer_host/p2p/socket_host.h" |
| 10 #include "content/public/browser/resource_context.h" | 10 #include "content/public/browser/resource_context.h" |
| 11 #include "content/common/p2p_messages.h" | 11 #include "content/common/p2p_messages.h" |
| 12 #include "net/base/address_list.h" | 12 #include "net/base/address_list.h" |
| 13 #include "net/base/completion_callback.h" | 13 #include "net/base/completion_callback.h" |
| 14 #include "net/base/net_errors.h" | 14 #include "net/base/net_errors.h" |
| 15 #include "net/base/net_log.h" | 15 #include "net/base/net_log.h" |
| 16 #include "net/base/single_request_host_resolver.h" | 16 #include "net/base/single_request_host_resolver.h" |
| 17 #include "net/base/sys_addrinfo.h" | 17 #include "net/base/sys_addrinfo.h" |
| 18 | 18 |
| 19 using content::BrowserMessageFilter; | 19 using content::BrowserMessageFilter; |
| 20 using content::BrowserThread; | 20 using content::BrowserThread; |
| 21 | 21 |
| 22 namespace content { | 22 namespace content { |
| 23 | 23 |
| 24 class P2PSocketDispatcherHost::DnsRequest { | 24 class P2PSocketDispatcherHost::DnsRequest { |
| 25 public: | 25 public: |
| 26 typedef base::Callback<void(const net::IPAddressNumber&)> DoneCallback; | 26 typedef base::Callback<void(const net::IPAddressNumber&)> DoneCallback; |
| 27 | 27 |
| 28 DnsRequest(int32 routing_id, int32 request_id, | 28 DnsRequest(int32 request_id, net::HostResolver* host_resolver) |
| 29 net::HostResolver* host_resolver) | 29 : request_id_(request_id), |
| 30 : routing_id_(routing_id), | |
| 31 request_id_(request_id), | |
| 32 resolver_(host_resolver) { | 30 resolver_(host_resolver) { |
| 33 } | 31 } |
| 34 | 32 |
| 35 void Resolve(const std::string& host_name, | 33 void Resolve(const std::string& host_name, |
| 36 const DoneCallback& done_callback) { | 34 const DoneCallback& done_callback) { |
| 37 DCHECK(!done_callback.is_null()); | 35 DCHECK(!done_callback.is_null()); |
| 38 | 36 |
| 39 host_name_ = host_name; | 37 host_name_ = host_name; |
| 40 done_callback_ = done_callback; | 38 done_callback_ = done_callback; |
| 41 | 39 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 53 net::HostResolver::RequestInfo info(net::HostPortPair(host_name_, 0)); | 51 net::HostResolver::RequestInfo info(net::HostPortPair(host_name_, 0)); |
| 54 int result = resolver_.Resolve( | 52 int result = resolver_.Resolve( |
| 55 info, &addresses_, | 53 info, &addresses_, |
| 56 base::Bind(&P2PSocketDispatcherHost::DnsRequest::OnDone, | 54 base::Bind(&P2PSocketDispatcherHost::DnsRequest::OnDone, |
| 57 base::Unretained(this)), | 55 base::Unretained(this)), |
| 58 net::BoundNetLog()); | 56 net::BoundNetLog()); |
| 59 if (result != net::ERR_IO_PENDING) | 57 if (result != net::ERR_IO_PENDING) |
| 60 OnDone(result); | 58 OnDone(result); |
| 61 } | 59 } |
| 62 | 60 |
| 63 int32 routing_id() { return routing_id_; } | |
| 64 int32 request_id() { return request_id_; } | 61 int32 request_id() { return request_id_; } |
| 65 | 62 |
| 66 private: | 63 private: |
| 67 void OnDone(int result) { | 64 void OnDone(int result) { |
| 68 if (result != net::OK) { | 65 if (result != net::OK) { |
| 69 LOG(ERROR) << "Failed to resolve address for " << host_name_ | 66 LOG(ERROR) << "Failed to resolve address for " << host_name_ |
| 70 << ", errorcode: " << result; | 67 << ", errorcode: " << result; |
| 71 done_callback_.Run(net::IPAddressNumber()); | 68 done_callback_.Run(net::IPAddressNumber()); |
| 72 return; | 69 return; |
| 73 } | 70 } |
| 74 | 71 |
| 75 // TODO(szym): Redundant check. http://crbug.com/126211 | 72 // TODO(szym): Redundant check. http://crbug.com/126211 |
| 76 if (addresses_.empty()) { | 73 if (addresses_.empty()) { |
| 77 LOG(ERROR) << "Received 0 addresses when trying to resolve address for " | 74 LOG(ERROR) << "Received 0 addresses when trying to resolve address for " |
| 78 << host_name_; | 75 << host_name_; |
| 79 done_callback_.Run(net::IPAddressNumber()); | 76 done_callback_.Run(net::IPAddressNumber()); |
| 80 return; | 77 return; |
| 81 } | 78 } |
| 82 | 79 |
| 83 done_callback_.Run(addresses_.front().address()); | 80 done_callback_.Run(addresses_.front().address()); |
| 84 } | 81 } |
| 85 | 82 |
| 86 int32 routing_id_; | |
| 87 int32 request_id_; | 83 int32 request_id_; |
| 88 net::AddressList addresses_; | 84 net::AddressList addresses_; |
| 89 | 85 |
| 90 std::string host_name_; | 86 std::string host_name_; |
| 91 net::SingleRequestHostResolver resolver_; | 87 net::SingleRequestHostResolver resolver_; |
| 92 | 88 |
| 93 DoneCallback done_callback_; | 89 DoneCallback done_callback_; |
| 94 }; | 90 }; |
| 95 | 91 |
| 96 P2PSocketDispatcherHost::P2PSocketDispatcherHost( | 92 P2PSocketDispatcherHost::P2PSocketDispatcherHost( |
| 97 content::ResourceContext* resource_context) | 93 content::ResourceContext* resource_context) |
| 98 : resource_context_(resource_context), | 94 : resource_context_(resource_context), |
| 99 monitoring_networks_(false) { | 95 monitoring_networks_(false) { |
| 100 } | 96 } |
| 101 | 97 |
| 102 void P2PSocketDispatcherHost::OnChannelClosing() { | 98 void P2PSocketDispatcherHost::OnChannelClosing() { |
| 103 BrowserMessageFilter::OnChannelClosing(); | 99 BrowserMessageFilter::OnChannelClosing(); |
| 104 | 100 |
| 105 // Since the IPC channel is gone, close pending connections. | 101 // Since the IPC channel is gone, close pending connections. |
| 106 STLDeleteContainerPairSecondPointers(sockets_.begin(), sockets_.end()); | 102 STLDeleteContainerPairSecondPointers(sockets_.begin(), sockets_.end()); |
| 107 sockets_.clear(); | 103 sockets_.clear(); |
| 108 | 104 |
| 109 STLDeleteContainerPointers(dns_requests_.begin(), dns_requests_.end()); | 105 STLDeleteContainerPointers(dns_requests_.begin(), dns_requests_.end()); |
| 110 dns_requests_.clear(); | 106 dns_requests_.clear(); |
| 107 |
| 108 if (monitoring_networks_) { |
| 109 net::NetworkChangeNotifier::RemoveIPAddressObserver(this); |
| 110 monitoring_networks_ = false; |
| 111 } |
| 111 } | 112 } |
| 112 | 113 |
| 113 void P2PSocketDispatcherHost::OnDestruct() const { | 114 void P2PSocketDispatcherHost::OnDestruct() const { |
| 114 BrowserThread::DeleteOnIOThread::Destruct(this); | 115 BrowserThread::DeleteOnIOThread::Destruct(this); |
| 115 } | 116 } |
| 116 | 117 |
| 117 bool P2PSocketDispatcherHost::OnMessageReceived(const IPC::Message& message, | 118 bool P2PSocketDispatcherHost::OnMessageReceived(const IPC::Message& message, |
| 118 bool* message_was_ok) { | 119 bool* message_was_ok) { |
| 119 bool handled = true; | 120 bool handled = true; |
| 120 IPC_BEGIN_MESSAGE_MAP_EX(P2PSocketDispatcherHost, message, *message_was_ok) | 121 IPC_BEGIN_MESSAGE_MAP_EX(P2PSocketDispatcherHost, message, *message_was_ok) |
| (...skipping 20 matching lines...) Expand all Loading... |
| 141 } | 142 } |
| 142 | 143 |
| 143 P2PSocketDispatcherHost::~P2PSocketDispatcherHost() { | 144 P2PSocketDispatcherHost::~P2PSocketDispatcherHost() { |
| 144 DCHECK(sockets_.empty()); | 145 DCHECK(sockets_.empty()); |
| 145 DCHECK(dns_requests_.empty()); | 146 DCHECK(dns_requests_.empty()); |
| 146 | 147 |
| 147 if (monitoring_networks_) | 148 if (monitoring_networks_) |
| 148 net::NetworkChangeNotifier::RemoveIPAddressObserver(this); | 149 net::NetworkChangeNotifier::RemoveIPAddressObserver(this); |
| 149 } | 150 } |
| 150 | 151 |
| 151 P2PSocketHost* P2PSocketDispatcherHost::LookupSocket( | 152 P2PSocketHost* P2PSocketDispatcherHost::LookupSocket(int socket_id) { |
| 152 int32 routing_id, int socket_id) { | 153 SocketsMap::iterator it = sockets_.find(socket_id); |
| 153 SocketsMap::iterator it = sockets_.find( | 154 return (it == sockets_.end()) ? NULL : it->second; |
| 154 ExtendedSocketId(routing_id, socket_id)); | |
| 155 if (it == sockets_.end()) | |
| 156 return NULL; | |
| 157 else | |
| 158 return it->second; | |
| 159 } | 155 } |
| 160 | 156 |
| 161 void P2PSocketDispatcherHost::OnStartNetworkNotifications( | 157 void P2PSocketDispatcherHost::OnStartNetworkNotifications( |
| 162 const IPC::Message& msg) { | 158 const IPC::Message& msg) { |
| 163 if (!monitoring_networks_) { | 159 if (!monitoring_networks_) { |
| 164 net::NetworkChangeNotifier::AddIPAddressObserver(this); | 160 net::NetworkChangeNotifier::AddIPAddressObserver(this); |
| 165 monitoring_networks_ = true; | 161 monitoring_networks_ = true; |
| 166 } | 162 } |
| 167 | 163 |
| 168 notifications_routing_ids_.insert(msg.routing_id()); | |
| 169 | |
| 170 BrowserThread::PostTask( | 164 BrowserThread::PostTask( |
| 171 BrowserThread::FILE, FROM_HERE, base::Bind( | 165 BrowserThread::FILE, FROM_HERE, base::Bind( |
| 172 &P2PSocketDispatcherHost::DoGetNetworkList, this)); | 166 &P2PSocketDispatcherHost::DoGetNetworkList, this)); |
| 173 } | 167 } |
| 174 | 168 |
| 175 void P2PSocketDispatcherHost::OnStopNetworkNotifications( | 169 void P2PSocketDispatcherHost::OnStopNetworkNotifications( |
| 176 const IPC::Message& msg) { | 170 const IPC::Message& msg) { |
| 177 notifications_routing_ids_.erase(msg.routing_id()); | 171 if (monitoring_networks_) { |
| 172 net::NetworkChangeNotifier::RemoveIPAddressObserver(this); |
| 173 monitoring_networks_ = false; |
| 174 } |
| 178 } | 175 } |
| 179 | 176 |
| 180 void P2PSocketDispatcherHost::OnGetHostAddress(const IPC::Message& msg, | 177 void P2PSocketDispatcherHost::OnGetHostAddress(const std::string& host_name, |
| 181 const std::string& host_name, | |
| 182 int32 request_id) { | 178 int32 request_id) { |
| 183 DnsRequest* request = new DnsRequest( | 179 DnsRequest* request = new DnsRequest(request_id, |
| 184 msg.routing_id(), request_id, resource_context_->GetHostResolver()); | 180 resource_context_->GetHostResolver()); |
| 185 dns_requests_.insert(request); | 181 dns_requests_.insert(request); |
| 186 request->Resolve(host_name, base::Bind( | 182 request->Resolve(host_name, base::Bind( |
| 187 &P2PSocketDispatcherHost::OnAddressResolved, | 183 &P2PSocketDispatcherHost::OnAddressResolved, |
| 188 base::Unretained(this), request)); | 184 base::Unretained(this), request)); |
| 189 } | 185 } |
| 190 | 186 |
| 191 void P2PSocketDispatcherHost::OnCreateSocket( | 187 void P2PSocketDispatcherHost::OnCreateSocket( |
| 192 const IPC::Message& msg, P2PSocketType type, int socket_id, | 188 P2PSocketType type, int socket_id, |
| 193 const net::IPEndPoint& local_address, | 189 const net::IPEndPoint& local_address, |
| 194 const net::IPEndPoint& remote_address) { | 190 const net::IPEndPoint& remote_address) { |
| 195 if (LookupSocket(msg.routing_id(), socket_id)) { | 191 if (LookupSocket(socket_id)) { |
| 196 LOG(ERROR) << "Received P2PHostMsg_CreateSocket for socket " | 192 LOG(ERROR) << "Received P2PHostMsg_CreateSocket for socket " |
| 197 "that already exists."; | 193 "that already exists."; |
| 198 return; | 194 return; |
| 199 } | 195 } |
| 200 | 196 |
| 201 scoped_ptr<P2PSocketHost> socket( | 197 scoped_ptr<P2PSocketHost> socket( |
| 202 P2PSocketHost::Create(this, msg.routing_id(), socket_id, type)); | 198 P2PSocketHost::Create(this, socket_id, type)); |
| 203 | 199 |
| 204 if (!socket.get()) { | 200 if (!socket.get()) { |
| 205 Send(new P2PMsg_OnError(msg.routing_id(), socket_id)); | 201 Send(new P2PMsg_OnError(socket_id)); |
| 206 return; | 202 return; |
| 207 } | 203 } |
| 208 | 204 |
| 209 if (socket->Init(local_address, remote_address)) { | 205 if (socket->Init(local_address, remote_address)) { |
| 210 sockets_.insert(std::pair<ExtendedSocketId, P2PSocketHost*>( | 206 sockets_[socket_id] = socket.release(); |
| 211 ExtendedSocketId(msg.routing_id(), socket_id), socket.release())); | |
| 212 } | 207 } |
| 213 } | 208 } |
| 214 | 209 |
| 215 void P2PSocketDispatcherHost::OnAcceptIncomingTcpConnection( | 210 void P2PSocketDispatcherHost::OnAcceptIncomingTcpConnection( |
| 216 const IPC::Message& msg, int listen_socket_id, | 211 int listen_socket_id, const net::IPEndPoint& remote_address, |
| 217 const net::IPEndPoint& remote_address, int connected_socket_id) { | 212 int connected_socket_id) { |
| 218 P2PSocketHost* socket = LookupSocket(msg.routing_id(), listen_socket_id); | 213 P2PSocketHost* socket = LookupSocket(listen_socket_id); |
| 219 if (!socket) { | 214 if (!socket) { |
| 220 LOG(ERROR) << "Received P2PHostMsg_AcceptIncomingTcpConnection " | 215 LOG(ERROR) << "Received P2PHostMsg_AcceptIncomingTcpConnection " |
| 221 "for invalid socket_id."; | 216 "for invalid socket_id."; |
| 222 return; | 217 return; |
| 223 } | 218 } |
| 224 P2PSocketHost* accepted_connection = | 219 P2PSocketHost* accepted_connection = |
| 225 socket->AcceptIncomingTcpConnection(remote_address, connected_socket_id); | 220 socket->AcceptIncomingTcpConnection(remote_address, connected_socket_id); |
| 226 if (accepted_connection) { | 221 if (accepted_connection) { |
| 227 sockets_.insert(std::pair<ExtendedSocketId, P2PSocketHost*>( | 222 sockets_[connected_socket_id] = accepted_connection; |
| 228 ExtendedSocketId(msg.routing_id(), connected_socket_id), | |
| 229 accepted_connection)); | |
| 230 } | 223 } |
| 231 } | 224 } |
| 232 | 225 |
| 233 void P2PSocketDispatcherHost::OnSend(const IPC::Message& msg, int socket_id, | 226 void P2PSocketDispatcherHost::OnSend(int socket_id, |
| 234 const net::IPEndPoint& socket_address, | 227 const net::IPEndPoint& socket_address, |
| 235 const std::vector<char>& data) { | 228 const std::vector<char>& data) { |
| 236 P2PSocketHost* socket = LookupSocket(msg.routing_id(), socket_id); | 229 P2PSocketHost* socket = LookupSocket(socket_id); |
| 237 if (!socket) { | 230 if (!socket) { |
| 238 LOG(ERROR) << "Received P2PHostMsg_Send for invalid socket_id."; | 231 LOG(ERROR) << "Received P2PHostMsg_Send for invalid socket_id."; |
| 239 return; | 232 return; |
| 240 } | 233 } |
| 241 socket->Send(socket_address, data); | 234 socket->Send(socket_address, data); |
| 242 } | 235 } |
| 243 | 236 |
| 244 void P2PSocketDispatcherHost::OnDestroySocket(const IPC::Message& msg, | 237 void P2PSocketDispatcherHost::OnDestroySocket(int socket_id) { |
| 245 int socket_id) { | 238 SocketsMap::iterator it = sockets_.find(socket_id); |
| 246 SocketsMap::iterator it = sockets_.find( | |
| 247 ExtendedSocketId(msg.routing_id(), socket_id)); | |
| 248 if (it != sockets_.end()) { | 239 if (it != sockets_.end()) { |
| 249 delete it->second; | 240 delete it->second; |
| 250 sockets_.erase(it); | 241 sockets_.erase(it); |
| 251 } else { | 242 } else { |
| 252 LOG(ERROR) << "Received P2PHostMsg_DestroySocket for invalid socket_id."; | 243 LOG(ERROR) << "Received P2PHostMsg_DestroySocket for invalid socket_id."; |
| 253 } | 244 } |
| 254 } | 245 } |
| 255 | 246 |
| 256 void P2PSocketDispatcherHost::DoGetNetworkList() { | 247 void P2PSocketDispatcherHost::DoGetNetworkList() { |
| 257 net::NetworkInterfaceList list; | 248 net::NetworkInterfaceList list; |
| 258 net::GetNetworkList(&list); | 249 net::GetNetworkList(&list); |
| 259 BrowserThread::PostTask( | 250 BrowserThread::PostTask( |
| 260 BrowserThread::IO, FROM_HERE, base::Bind( | 251 BrowserThread::IO, FROM_HERE, base::Bind( |
| 261 &P2PSocketDispatcherHost::SendNetworkList, this, list)); | 252 &P2PSocketDispatcherHost::SendNetworkList, this, list)); |
| 262 } | 253 } |
| 263 | 254 |
| 264 void P2PSocketDispatcherHost::SendNetworkList( | 255 void P2PSocketDispatcherHost::SendNetworkList( |
| 265 const net::NetworkInterfaceList& list) { | 256 const net::NetworkInterfaceList& list) { |
| 266 for (std::set<int>::iterator it = notifications_routing_ids_.begin(); | 257 Send(new P2PMsg_NetworkListChanged(list)); |
| 267 it != notifications_routing_ids_.end(); ++it) { | |
| 268 Send(new P2PMsg_NetworkListChanged(*it, list)); | |
| 269 } | |
| 270 } | 258 } |
| 271 | 259 |
| 272 void P2PSocketDispatcherHost::OnAddressResolved( | 260 void P2PSocketDispatcherHost::OnAddressResolved( |
| 273 DnsRequest* request, | 261 DnsRequest* request, |
| 274 const net::IPAddressNumber& result) { | 262 const net::IPAddressNumber& result) { |
| 275 Send(new P2PMsg_GetHostAddressResult( | 263 Send(new P2PMsg_GetHostAddressResult(request->request_id(), result)); |
| 276 request->routing_id(), request->request_id(), result)); | |
| 277 | 264 |
| 278 dns_requests_.erase(request); | 265 dns_requests_.erase(request); |
| 279 delete request; | 266 delete request; |
| 280 } | 267 } |
| 281 | 268 |
| 282 } // namespace content | 269 } // namespace content |
| OLD | NEW |