Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/stl_util.h" | 8 #include "base/stl_util.h" |
| 8 #include "content/browser/renderer_host/p2p/socket_host.h" | 9 #include "content/browser/renderer_host/p2p/socket_host.h" |
| 10 #include "content/browser/resource_context.h" | |
| 9 #include "content/common/p2p_messages.h" | 11 #include "content/common/p2p_messages.h" |
| 12 #include "net/base/address_list.h" | |
| 13 #include "net/base/completion_callback.h" | |
| 14 #include "net/base/net_errors.h" | |
| 15 #include "net/base/net_log.h" | |
| 16 #include "net/base/single_request_host_resolver.h" | |
| 17 #include "net/base/sys_addrinfo.h" | |
| 10 | 18 |
| 11 P2PSocketDispatcherHost::P2PSocketDispatcherHost() | 19 class P2PSocketDispatcherHost::DnsRequest { |
| 12 : monitoring_networks_(false) { | 20 public: |
| 21 typedef base::Callback<void(const net::IPAddressNumber&)> DoneCallback; | |
| 22 | |
| 23 DnsRequest(int32 routing_id, int32 request_id, | |
| 24 net::HostResolver* host_resolver) | |
| 25 : routing_id_(routing_id), | |
| 26 request_id_(request_id), | |
| 27 resolver_(host_resolver), | |
| 28 ALLOW_THIS_IN_INITIALIZER_LIST(completion_callback_( | |
| 29 this, &P2PSocketDispatcherHost::DnsRequest::OnDone)) { | |
| 30 } | |
| 31 | |
| 32 void Resolve(const std::string& host_name, | |
| 33 const DoneCallback& done_callback) { | |
|
awong
2011/08/09 00:25:56
DCHECK here that done_callback is initialized?
Sergey Ulanov
2011/08/09 00:41:35
Done.
| |
| 34 host_name_ = host_name; | |
| 35 done_callback_ = done_callback; | |
| 36 | |
| 37 // Return an error if it's an empty string. | |
| 38 if (host_name_.empty()) { | |
| 39 done_callback_.Run(net::IPAddressNumber()); | |
| 40 return; | |
| 41 } | |
| 42 | |
| 43 // Add period at the end to make sure that we only resolve | |
| 44 // fully-qualified names. | |
| 45 if (host_name_.at(host_name_.size() - 1) != '.') | |
| 46 host_name_ = host_name_ + '.'; | |
| 47 | |
| 48 net::HostResolver::RequestInfo info(net::HostPortPair(host_name_, 0)); | |
| 49 resolver_.Resolve(info, &addresses_, &completion_callback_, | |
| 50 net::BoundNetLog()); | |
| 51 } | |
| 52 | |
| 53 int32 routing_id() { return routing_id_; } | |
| 54 int32 request_id() { return request_id_; } | |
| 55 | |
| 56 private: | |
| 57 void OnDone(int result) { | |
| 58 if (result != net::OK) { | |
| 59 LOG(ERROR) << "Failed to resolve address for " << host_name_ | |
| 60 << ", errorcode: " << result; | |
| 61 done_callback_.Run(net::IPAddressNumber()); | |
|
awong
2011/08/09 00:25:56
I'd prefer a return here, and then move the whole
Sergey Ulanov
2011/08/09 00:41:35
Done.
| |
| 62 } else { | |
| 63 if (addresses_.head() == NULL) { | |
| 64 LOG(ERROR) << "Received 0 addresses when trying to resolve address for " | |
| 65 << host_name_; | |
| 66 done_callback_.Run(net::IPAddressNumber()); | |
| 67 return; | |
| 68 } | |
| 69 | |
| 70 net::IPEndPoint end_point; | |
| 71 if (!end_point.FromSockAddr(addresses_.head()->ai_addr, | |
| 72 addresses_.head()->ai_addrlen)) { | |
| 73 LOG(ERROR) << "Received invalid address for " << host_name_; | |
| 74 done_callback_.Run(net::IPAddressNumber()); | |
| 75 return; | |
| 76 } | |
| 77 | |
| 78 done_callback_.Run(end_point.address()); | |
| 79 } | |
| 80 } | |
| 81 | |
| 82 int32 routing_id_; | |
| 83 int32 request_id_; | |
| 84 net::AddressList addresses_; | |
| 85 | |
| 86 std::string host_name_; | |
| 87 net::SingleRequestHostResolver resolver_; | |
| 88 | |
| 89 DoneCallback done_callback_; | |
| 90 | |
| 91 net::CompletionCallbackImpl<DnsRequest> completion_callback_; | |
| 92 }; | |
| 93 | |
| 94 P2PSocketDispatcherHost::P2PSocketDispatcherHost( | |
| 95 const content::ResourceContext* resource_context) | |
| 96 : resource_context_(resource_context), | |
| 97 monitoring_networks_(false) { | |
| 13 } | 98 } |
| 14 | 99 |
| 15 P2PSocketDispatcherHost::~P2PSocketDispatcherHost() { | 100 P2PSocketDispatcherHost::~P2PSocketDispatcherHost() { |
| 16 DCHECK(sockets_.empty()); | 101 DCHECK(sockets_.empty()); |
|
Wez
2011/08/08 21:47:18
Check |dns_requests_| here, or clean it up?
Sergey Ulanov
2011/08/09 00:41:35
Done.
| |
| 17 | 102 |
| 18 if (monitoring_networks_) | 103 if (monitoring_networks_) |
| 19 net::NetworkChangeNotifier::RemoveIPAddressObserver(this); | 104 net::NetworkChangeNotifier::RemoveIPAddressObserver(this); |
| 20 } | 105 } |
| 21 | 106 |
| 22 void P2PSocketDispatcherHost::OnChannelClosing() { | 107 void P2PSocketDispatcherHost::OnChannelClosing() { |
| 23 BrowserMessageFilter::OnChannelClosing(); | 108 BrowserMessageFilter::OnChannelClosing(); |
| 24 | 109 |
| 25 // Since the IPC channel is gone, close pending connections. | 110 // Since the IPC channel is gone, close pending connections. |
| 26 STLDeleteContainerPairSecondPointers(sockets_.begin(), sockets_.end()); | 111 STLDeleteContainerPairSecondPointers(sockets_.begin(), sockets_.end()); |
| 27 sockets_.clear(); | 112 sockets_.clear(); |
| 113 | |
| 114 STLDeleteContainerPointers(dns_requests_.begin(), dns_requests_.end()); | |
| 115 dns_requests_.clear(); | |
| 28 } | 116 } |
| 29 | 117 |
| 30 void P2PSocketDispatcherHost::OnDestruct() const { | 118 void P2PSocketDispatcherHost::OnDestruct() const { |
| 31 BrowserThread::DeleteOnIOThread::Destruct(this); | 119 BrowserThread::DeleteOnIOThread::Destruct(this); |
| 32 } | 120 } |
| 33 | 121 |
| 34 bool P2PSocketDispatcherHost::OnMessageReceived(const IPC::Message& message, | 122 bool P2PSocketDispatcherHost::OnMessageReceived(const IPC::Message& message, |
| 35 bool* message_was_ok) { | 123 bool* message_was_ok) { |
| 36 bool handled = true; | 124 bool handled = true; |
| 37 IPC_BEGIN_MESSAGE_MAP_EX(P2PSocketDispatcherHost, message, *message_was_ok) | 125 IPC_BEGIN_MESSAGE_MAP_EX(P2PSocketDispatcherHost, message, *message_was_ok) |
| 38 IPC_MESSAGE_HANDLER(P2PHostMsg_StartNetworkNotifications, | 126 IPC_MESSAGE_HANDLER(P2PHostMsg_StartNetworkNotifications, |
| 39 OnStartNetworkNotifications) | 127 OnStartNetworkNotifications) |
| 40 IPC_MESSAGE_HANDLER(P2PHostMsg_StopNetworkNotifications, | 128 IPC_MESSAGE_HANDLER(P2PHostMsg_StopNetworkNotifications, |
| 41 OnStopNetworkNotifications) | 129 OnStopNetworkNotifications) |
| 130 IPC_MESSAGE_HANDLER(P2PHostMsg_GetHostAddress, OnGetHostAddress) | |
| 42 IPC_MESSAGE_HANDLER(P2PHostMsg_CreateSocket, OnCreateSocket) | 131 IPC_MESSAGE_HANDLER(P2PHostMsg_CreateSocket, OnCreateSocket) |
| 43 IPC_MESSAGE_HANDLER(P2PHostMsg_AcceptIncomingTcpConnection, | 132 IPC_MESSAGE_HANDLER(P2PHostMsg_AcceptIncomingTcpConnection, |
| 44 OnAcceptIncomingTcpConnection) | 133 OnAcceptIncomingTcpConnection) |
| 45 IPC_MESSAGE_HANDLER(P2PHostMsg_Send, OnSend) | 134 IPC_MESSAGE_HANDLER(P2PHostMsg_Send, OnSend) |
| 46 IPC_MESSAGE_HANDLER(P2PHostMsg_DestroySocket, OnDestroySocket) | 135 IPC_MESSAGE_HANDLER(P2PHostMsg_DestroySocket, OnDestroySocket) |
| 47 IPC_MESSAGE_UNHANDLED(handled = false) | 136 IPC_MESSAGE_UNHANDLED(handled = false) |
| 48 IPC_END_MESSAGE_MAP_EX() | 137 IPC_END_MESSAGE_MAP_EX() |
| 49 return handled; | 138 return handled; |
| 50 } | 139 } |
| 51 | 140 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 94 } | 183 } |
| 95 | 184 |
| 96 void P2PSocketDispatcherHost::SendNetworkList( | 185 void P2PSocketDispatcherHost::SendNetworkList( |
| 97 const net::NetworkInterfaceList& list) { | 186 const net::NetworkInterfaceList& list) { |
| 98 for (std::set<int>::iterator it = notifications_routing_ids_.begin(); | 187 for (std::set<int>::iterator it = notifications_routing_ids_.begin(); |
| 99 it != notifications_routing_ids_.end(); ++it) { | 188 it != notifications_routing_ids_.end(); ++it) { |
| 100 Send(new P2PMsg_NetworkListChanged(*it, list)); | 189 Send(new P2PMsg_NetworkListChanged(*it, list)); |
| 101 } | 190 } |
| 102 } | 191 } |
| 103 | 192 |
| 193 void P2PSocketDispatcherHost::OnGetHostAddress(const IPC::Message& msg, | |
| 194 const std::string& host_name, | |
| 195 int32 request_id) { | |
| 196 DnsRequest* request = new DnsRequest( | |
| 197 msg.routing_id(), request_id, resource_context_->host_resolver()); | |
| 198 request->Resolve(host_name, base::Bind( | |
| 199 &P2PSocketDispatcherHost::OnAddressResolved, | |
| 200 base::Unretained(this), request)); | |
|
awong
2011/08/09 00:25:56
Can the P2PSocketDispatcherHost be deleted before
Sergey Ulanov
2011/08/09 00:41:35
Yes, but all pending requests will be deleted befo
| |
| 201 dns_requests_.insert(request); | |
| 202 } | |
| 203 | |
| 204 void P2PSocketDispatcherHost::OnAddressResolved( | |
| 205 DnsRequest* request, | |
| 206 const net::IPAddressNumber& result) { | |
| 207 Send(new P2PMsg_GetHostAddressResult( | |
|
Wez
2011/08/08 21:47:18
Can we bubble the net error-code back across the I
Sergey Ulanov
2011/08/09 00:41:35
We currently don't do it for any other P2P IPC, an
| |
| 208 request->routing_id(), request->request_id(), result)); | |
| 209 | |
| 210 dns_requests_.erase(request); | |
| 211 delete request; | |
| 212 } | |
| 213 | |
| 104 void P2PSocketDispatcherHost::OnCreateSocket( | 214 void P2PSocketDispatcherHost::OnCreateSocket( |
| 105 const IPC::Message& msg, P2PSocketType type, int socket_id, | 215 const IPC::Message& msg, P2PSocketType type, int socket_id, |
| 106 const net::IPEndPoint& local_address, | 216 const net::IPEndPoint& local_address, |
| 107 const net::IPEndPoint& remote_address) { | 217 const net::IPEndPoint& remote_address) { |
| 108 if (LookupSocket(msg.routing_id(), socket_id)) { | 218 if (LookupSocket(msg.routing_id(), socket_id)) { |
| 109 LOG(ERROR) << "Received P2PHostMsg_CreateSocket for socket " | 219 LOG(ERROR) << "Received P2PHostMsg_CreateSocket for socket " |
| 110 "that already exists."; | 220 "that already exists."; |
| 111 return; | 221 return; |
| 112 } | 222 } |
| 113 | 223 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 158 int socket_id) { | 268 int socket_id) { |
| 159 SocketsMap::iterator it = sockets_.find( | 269 SocketsMap::iterator it = sockets_.find( |
| 160 ExtendedSocketId(msg.routing_id(), socket_id)); | 270 ExtendedSocketId(msg.routing_id(), socket_id)); |
| 161 if (it != sockets_.end()) { | 271 if (it != sockets_.end()) { |
| 162 delete it->second; | 272 delete it->second; |
| 163 sockets_.erase(it); | 273 sockets_.erase(it); |
| 164 } else { | 274 } else { |
| 165 LOG(ERROR) << "Received P2PHostMsg_DestroySocket for invalid socket_id."; | 275 LOG(ERROR) << "Received P2PHostMsg_DestroySocket for invalid socket_id."; |
| 166 } | 276 } |
| 167 } | 277 } |
| OLD | NEW |