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 |