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