Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(39)

Side by Side Diff: remoting/client/plugin/pepper_port_allocator.cc

Issue 10384171: Fix PepperPortAllocator to resolve STUN addresses using HostResolverPrivate. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "remoting/client/plugin/pepper_port_allocator.h" 5 #include "remoting/client/plugin/pepper_port_allocator.h"
6 6
7 #include "base/string_number_conversions.h" 7 #include "base/string_number_conversions.h"
8 #include "net/base/net_util.h"
8 #include "ppapi/c/pp_errors.h" 9 #include "ppapi/c/pp_errors.h"
9 #include "ppapi/cpp/completion_callback.h" 10 #include "ppapi/cpp/completion_callback.h"
11 #include "ppapi/cpp/private/host_resolver_private.h"
10 #include "ppapi/cpp/url_loader.h" 12 #include "ppapi/cpp/url_loader.h"
11 #include "ppapi/cpp/url_request_info.h" 13 #include "ppapi/cpp/url_request_info.h"
12 #include "ppapi/cpp/url_response_info.h" 14 #include "ppapi/cpp/url_response_info.h"
13 #include "remoting/client/plugin/pepper_network_manager.h" 15 #include "remoting/client/plugin/pepper_network_manager.h"
14 #include "remoting/client/plugin/pepper_packet_socket_factory.h" 16 #include "remoting/client/plugin/pepper_packet_socket_factory.h"
17 #include "remoting/client/plugin/pepper_util.h"
15 18
16 namespace remoting { 19 namespace remoting {
17 20
18 namespace { 21 namespace {
19 22
23 // URL used to create a relay session.
24 const char kCreateRelaySessionURL[] = "/create_session";
25
20 // Read buffer we allocate per read when reading response from 26 // Read buffer we allocate per read when reading response from
21 // URLLoader. Normally the response from URL loader is smaller than 1kB. 27 // URLLoader. Normally the response from URL loader is smaller than 1kB.
22 const int kReadSize = 1024; 28 const int kReadSize = 1024;
23 29
24 class PepperPortAllocatorSession 30 class PepperPortAllocatorSession
25 : public cricket::HttpPortAllocatorSessionBase { 31 : public cricket::HttpPortAllocatorSessionBase {
26 public: 32 public:
27 PepperPortAllocatorSession( 33 PepperPortAllocatorSession(
28 cricket::HttpPortAllocatorBase* allocator, 34 cricket::HttpPortAllocatorBase* allocator,
29 const std::string& channel_name, 35 const std::string& channel_name,
30 int component, 36 int component,
31 const std::vector<talk_base::SocketAddress>& stun_hosts, 37 const std::vector<talk_base::SocketAddress>& stun_hosts,
32 const std::vector<std::string>& relay_hosts, 38 const std::vector<std::string>& relay_hosts,
33 const std::string& relay, 39 const std::string& relay_token,
34 const pp::InstanceHandle& instance); 40 const pp::InstanceHandle& instance);
35 virtual ~PepperPortAllocatorSession(); 41 virtual ~PepperPortAllocatorSession();
36 42
37 // cricket::HttpPortAllocatorBase overrides. 43 // cricket::HttpPortAllocatorBase overrides.
38 virtual void ConfigReady(cricket::PortConfiguration* config) OVERRIDE; 44 virtual void ConfigReady(cricket::PortConfiguration* config) OVERRIDE;
45 virtual void GetPortConfigurations() OVERRIDE;
39 virtual void SendSessionRequest(const std::string& host, int port) OVERRIDE; 46 virtual void SendSessionRequest(const std::string& host, int port) OVERRIDE;
40 47
41 private: 48 private:
42 // Callback handlers for pp::URLLoader. 49 // Callback handlers for Pepper APIs.
50 static void HostResolverCallback(void* user_data, int32_t result);
43 static void UrlLoaderOpenCallback(void* user_data, int32_t result); 51 static void UrlLoaderOpenCallback(void* user_data, int32_t result);
44 static void UrlLoaderReadCallback(void* user_data, int32_t result); 52 static void UrlLoaderReadCallback(void* user_data, int32_t result);
45 53
54 void ResolveStunServerAddress();
55 void OnStunAddressResolved(int32_t result);
56 void OnStunResolutionFinished();
57
46 void OnUrlOpened(int32_t result); 58 void OnUrlOpened(int32_t result);
47 void ReadResponseBody(); 59 void ReadResponseBody();
48 void OnResponseBodyRead(int32_t result); 60 void OnResponseBodyRead(int32_t result);
49 61
50 pp::InstanceHandle instance_; 62 pp::InstanceHandle instance_;
51 63
52 scoped_ptr<pp::URLLoader> url_loader_; 64 pp::HostResolverPrivate stun_address_resolver_;
53 std::vector<char> body_; 65 talk_base::SocketAddress unresolved_stun_address_;
66 talk_base::SocketAddress stun_address_;
67 bool stun_address_resolved_;
Wez 2012/05/15 23:11:29 Why do you need |unresolved_stun_address_| and |st
Sergey Ulanov 2012/05/16 00:22:30 Removed both unresolved_stun_address_ and stun_add
68 int stun_port_;
69
70 scoped_ptr<pp::URLLoader> relay_url_loader_;
71 std::vector<char> relay_response_body_;
72 bool relay_response_received_;
54 73
55 DISALLOW_COPY_AND_ASSIGN(PepperPortAllocatorSession); 74 DISALLOW_COPY_AND_ASSIGN(PepperPortAllocatorSession);
56 }; 75 };
57 76
58 PepperPortAllocatorSession::PepperPortAllocatorSession( 77 PepperPortAllocatorSession::PepperPortAllocatorSession(
59 cricket::HttpPortAllocatorBase* allocator, 78 cricket::HttpPortAllocatorBase* allocator,
60 const std::string& channel_name, 79 const std::string& channel_name,
61 int component, 80 int component,
62 const std::vector<talk_base::SocketAddress>& stun_hosts, 81 const std::vector<talk_base::SocketAddress>& stun_hosts,
63 const std::vector<std::string>& relay_hosts, 82 const std::vector<std::string>& relay_hosts,
64 const std::string& relay, 83 const std::string& relay_token,
65 const pp::InstanceHandle& instance) 84 const pp::InstanceHandle& instance)
66 : HttpPortAllocatorSessionBase( 85 : cricket::HttpPortAllocatorSessionBase(
67 allocator, channel_name, component, stun_hosts, relay_hosts, relay, ""), 86 allocator, channel_name, component, stun_hosts,
68 instance_(instance) { 87 relay_hosts, relay_token, ""),
88 instance_(instance),
89 stun_address_resolver_(instance_),
90 stun_address_resolved_(false),
91 stun_port_(0),
92 relay_response_received_(false) {
93 set_flags(cricket::PORTALLOCATOR_DISABLE_TCP);
Wez 2012/05/15 23:11:29 This doesn't look related to this CL's description
Sergey Ulanov 2012/05/16 00:22:30 Updated the description.
94 if (stun_hosts.size() > 0)
95 unresolved_stun_address_ = stun_hosts[0];
69 } 96 }
70 97
71 PepperPortAllocatorSession::~PepperPortAllocatorSession() { 98 PepperPortAllocatorSession::~PepperPortAllocatorSession() {
72 } 99 }
73 100
74 void PepperPortAllocatorSession::ConfigReady( 101 void PepperPortAllocatorSession::ConfigReady(
75 cricket::PortConfiguration* config) { 102 cricket::PortConfiguration* config) {
103 if (config->stun_address.IsUnresolved()) {
104 // Replace stun address with the resolved IP address.
105 config->stun_address = stun_address_;
106 }
107
76 // Filter out non-UDP relay ports, so that we don't try using TCP. 108 // Filter out non-UDP relay ports, so that we don't try using TCP.
77 for (cricket::PortConfiguration::RelayList::iterator relay = 109 for (cricket::PortConfiguration::RelayList::iterator relay =
78 config->relays.begin(); relay != config->relays.end(); ++relay) { 110 config->relays.begin(); relay != config->relays.end(); ++relay) {
79 cricket::PortConfiguration::PortList filtered_ports; 111 cricket::PortConfiguration::PortList filtered_ports;
80 for (cricket::PortConfiguration::PortList::iterator port = 112 for (cricket::PortConfiguration::PortList::iterator port =
81 relay->ports.begin(); port != relay->ports.end(); ++port) { 113 relay->ports.begin(); port != relay->ports.end(); ++port) {
82 if (port->proto == cricket::PROTO_UDP) { 114 if (port->proto == cricket::PROTO_UDP) {
83 filtered_ports.push_back(*port); 115 filtered_ports.push_back(*port);
84 } 116 }
85 } 117 }
86 relay->ports = filtered_ports; 118 relay->ports = filtered_ports;
87 } 119 }
88 cricket::BasicPortAllocatorSession::ConfigReady(config); 120 cricket::BasicPortAllocatorSession::ConfigReady(config);
89 } 121 }
90 122
123 void PepperPortAllocatorSession::GetPortConfigurations() {
124 // Add an empty configuration synchronously, so a local connection
125 // can be started immediately.
126 ConfigReady(new cricket::PortConfiguration(talk_base::SocketAddress()));
127
128 ResolveStunServerAddress();
129 TryCreateRelaySession();
130 }
131
132 void PepperPortAllocatorSession::ResolveStunServerAddress() {
133 if (unresolved_stun_address_.IsNil()) {
134 OnStunResolutionFinished();
135 return;
136 }
137
138 if (!unresolved_stun_address_.IsUnresolved()) {
139 stun_address_ = unresolved_stun_address_;
140 OnStunResolutionFinished();
141 return;
142 }
143
144 std::string hostname = unresolved_stun_address_.hostname();
145 uint16 port = unresolved_stun_address_.port();
146
147 PP_HostResolver_Private_Hint hint;
148 hint.flags = 0;
149 hint.family = PP_NETADDRESSFAMILY_IPV4;
150 int result = stun_address_resolver_.Resolve(
151 hostname, port, hint, pp::CompletionCallback(
152 &PepperPortAllocatorSession::HostResolverCallback, this));
153 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING);
154 }
155
156 void PepperPortAllocatorSession::OnStunAddressResolved(int32_t result) {
157 if (result < 0) {
158 LOG(ERROR) << "Failed to resolve stun address "
159 << unresolved_stun_address_.hostname() << ": " << result;
160 OnStunResolutionFinished();
161 return;
162 }
163
164 if (!stun_address_resolver_.GetSize()) {
165 LOG(WARNING) << "Received 0 addresses for stun server "
166 << unresolved_stun_address_.hostname();
167 OnStunResolutionFinished();
168 return;
169 }
170
171 PP_NetAddress_Private address;
172 if (!stun_address_resolver_.GetNetAddress(0, &address) ||
173 !PpAddressToSocketAddress(address, &stun_address_)) {
174 LOG(ERROR) << "Failed to get address for STUN server "
175 << unresolved_stun_address_.hostname();
176 OnStunResolutionFinished();
177 return;
178 }
179
180 OnStunResolutionFinished();
181 }
182
183 void PepperPortAllocatorSession::OnStunResolutionFinished() {
184 stun_address_resolved_ = true;
185 if (!stun_address_.IsNil())
Wez 2012/05/15 23:11:29 |!stun_address_.IsUnresolved()|?
Wez 2012/05/15 23:11:29 Use { } consistently with the other if(), below.
Sergey Ulanov 2012/05/16 00:22:30 STUN address may not be set. IsUnresolved returns
Sergey Ulanov 2012/05/16 00:22:30 Done.
Wez 2012/05/16 00:51:53 OK; consider adding a DCHECK() or even CHECK() for
Sergey Ulanov 2012/05/16 01:02:16 Done. Actually we don't need this method anymore,
186 ConfigReady(new cricket::PortConfiguration(stun_address_));
187
188 if (relay_response_received_) {
Wez 2012/05/15 23:11:29 This never gets set anywhere. Do you actually nee
Sergey Ulanov 2012/05/16 00:22:30 It should be set in OnResponseBodyRead(). Fixed no
189 ReceiveSessionResponse(std::string(relay_response_body_.begin(),
190 relay_response_body_.end()));
191 }
192 }
193
91 void PepperPortAllocatorSession::SendSessionRequest( 194 void PepperPortAllocatorSession::SendSessionRequest(
92 const std::string& host, 195 const std::string& host,
93 int port) { 196 int port) {
94 url_loader_.reset(new pp::URLLoader(instance_)); 197 relay_url_loader_.reset(new pp::URLLoader(instance_));
95 pp::URLRequestInfo request_info(instance_); 198 pp::URLRequestInfo request_info(instance_);
96 std::string url = "https://" + host + ":" + base::IntToString(port) + 199 std::string url = "https://" + host + ":" + base::IntToString(port) +
97 GetSessionRequestUrl() + "&sn=1"; 200 GetSessionRequestUrl() + "&sn=1";
98 request_info.SetURL(url); 201 request_info.SetURL(url);
99 request_info.SetMethod("GET"); 202 request_info.SetMethod("GET");
100 std::stringstream headers; 203 std::stringstream headers;
101 headers << "X-Talk-Google-Relay-Auth: " << relay_token() << "\n\r"; 204 headers << "X-Talk-Google-Relay-Auth: " << relay_token() << "\n\r";
102 headers << "X-Google-Relay-Auth: " << relay_token() << "\n\r"; 205 headers << "X-Google-Relay-Auth: " << relay_token() << "\n\r";
103 headers << "X-StreamType: " << channel_name() << "\n\r"; 206 headers << "X-StreamType: " << channel_name() << "\n\r";
104 request_info.SetHeaders(headers.str()); 207 request_info.SetHeaders(headers.str());
105 208
106 int result = url_loader_->Open(request_info, pp::CompletionCallback( 209 int result = relay_url_loader_->Open(request_info, pp::CompletionCallback(
107 &PepperPortAllocatorSession::UrlLoaderOpenCallback, this)); 210 &PepperPortAllocatorSession::UrlLoaderOpenCallback, this));
108 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING); 211 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING);
109 } 212 }
110 213
111 void PepperPortAllocatorSession::OnUrlOpened(int32_t result) { 214 void PepperPortAllocatorSession::OnUrlOpened(int32_t result) {
112 if (result == PP_ERROR_ABORTED) 215 if (result == PP_ERROR_ABORTED)
113 return; 216 return;
114 217
115 if (result < 0) { 218 if (result < 0) {
116 LOG(WARNING) << "URLLoader failed: " << result; 219 LOG(WARNING) << "URLLoader failed: " << result;
117 // Retry creating session. 220 // Retry creating session.
118 TryCreateRelaySession(); 221 TryCreateRelaySession();
119 return; 222 return;
120 } 223 }
121 224
122 pp::URLResponseInfo response = url_loader_->GetResponseInfo(); 225 pp::URLResponseInfo response = relay_url_loader_->GetResponseInfo();
123 DCHECK(!response.is_null()); 226 DCHECK(!response.is_null());
124 if (response.GetStatusCode() != 200) { 227 if (response.GetStatusCode() != 200) {
125 LOG(WARNING) << "Received HTTP status code " << response.GetStatusCode(); 228 LOG(WARNING) << "Received HTTP status code " << response.GetStatusCode();
126 // Retry creating session. 229 // Retry creating session.
127 TryCreateRelaySession(); 230 TryCreateRelaySession();
128 return; 231 return;
129 } 232 }
130 233
131 body_.clear(); 234 relay_response_body_.clear();
132 ReadResponseBody(); 235 ReadResponseBody();
133 } 236 }
134 237
135 void PepperPortAllocatorSession::ReadResponseBody() { 238 void PepperPortAllocatorSession::ReadResponseBody() {
136 int pos = body_.size(); 239 int pos = relay_response_body_.size();
137 body_.resize(pos + kReadSize); 240 relay_response_body_.resize(pos + kReadSize);
138 int result = url_loader_->ReadResponseBody( 241 int result = relay_url_loader_->ReadResponseBody(
139 &body_[pos], kReadSize, pp::CompletionCallback( 242 &relay_response_body_[pos], kReadSize, pp::CompletionCallback(
140 &PepperPortAllocatorSession::UrlLoaderReadCallback, this)); 243 &PepperPortAllocatorSession::UrlLoaderReadCallback, this));
141 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING); 244 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING);
142 } 245 }
143 246
144 void PepperPortAllocatorSession::OnResponseBodyRead(int32_t result) { 247 void PepperPortAllocatorSession::OnResponseBodyRead(int32_t result) {
145 if (result == PP_ERROR_ABORTED) 248 if (result == PP_ERROR_ABORTED)
146 return; 249 return;
147 250
148 if (result < 0) { 251 if (result < 0) {
149 LOG(WARNING) << "Failed to read HTTP response body when " 252 LOG(WARNING) << "Failed to read HTTP response body when "
150 "creating relay session: " << result; 253 "creating relay session: " << result;
151 // Retry creating session. 254 // Retry creating session.
152 TryCreateRelaySession(); 255 TryCreateRelaySession();
153 return; 256 return;
154 } 257 }
155 258
156 // Resize the buffer in case we've read less than was requested. 259 // Resize the buffer in case we've read less than was requested.
157 CHECK_LE(result, kReadSize); 260 CHECK_LE(result, kReadSize);
158 CHECK_GE(static_cast<int>(body_.size()), kReadSize); 261 CHECK_GE(static_cast<int>(relay_response_body_.size()), kReadSize);
159 body_.resize(body_.size() - kReadSize + result); 262 relay_response_body_.resize(relay_response_body_.size() - kReadSize + result);
160 263
161 if (result == 0) { 264 if (result == 0) {
162 // Finished reading the response. 265 // Finished reading the response. Submit it to
163 ReceiveSessionResponse(std::string(body_.begin(), body_.end())); 266 // HttpPortAllocatorSessionBase only after we've resolved STUN
267 // address. This is necessary because STUN and Relay parameters
268 // are stored together in PortConfiguration and
269 // ReceiveSessionResponse() doesn't save relay session
270 // configuration for the case we resolve STUN address later.
271 //
272 // TODO(sergeyu): Refactor HttpPortAllocatorSessionBase to fix this.
273 if (stun_address_resolved_) {
274 ReceiveSessionResponse(std::string(relay_response_body_.begin(),
275 relay_response_body_.end()));
276 }
164 return; 277 return;
165 } 278 }
166 279
167 ReadResponseBody(); 280 ReadResponseBody();
168 } 281 }
169 282
170 // static 283 // static
284 void PepperPortAllocatorSession::HostResolverCallback(
285 void* user_data,
286 int32_t result) {
287 PepperPortAllocatorSession* object =
288 static_cast<PepperPortAllocatorSession*>(user_data);
289 object->OnStunAddressResolved(result);
290 }
291
292 // static
171 void PepperPortAllocatorSession::UrlLoaderOpenCallback( 293 void PepperPortAllocatorSession::UrlLoaderOpenCallback(
172 void* user_data, 294 void* user_data,
173 int32_t result) { 295 int32_t result) {
174 PepperPortAllocatorSession* object = 296 PepperPortAllocatorSession* object =
175 static_cast<PepperPortAllocatorSession*>(user_data); 297 static_cast<PepperPortAllocatorSession*>(user_data);
176 object->OnUrlOpened(result); 298 object->OnUrlOpened(result);
177 } 299 }
178 300
179 // static 301 // static
180 void PepperPortAllocatorSession::UrlLoaderReadCallback( 302 void PepperPortAllocatorSession::UrlLoaderReadCallback(
(...skipping 27 matching lines...) Expand all
208 network_manager_(network_manager.Pass()), 330 network_manager_(network_manager.Pass()),
209 socket_factory_(socket_factory.Pass()) { 331 socket_factory_(socket_factory.Pass()) {
210 } 332 }
211 333
212 PepperPortAllocator::~PepperPortAllocator() { 334 PepperPortAllocator::~PepperPortAllocator() {
213 } 335 }
214 336
215 cricket::PortAllocatorSession* PepperPortAllocator::CreateSession( 337 cricket::PortAllocatorSession* PepperPortAllocator::CreateSession(
216 const std::string& channel_name, 338 const std::string& channel_name,
217 int component) { 339 int component) {
218 return new PepperPortAllocatorSession( 340 return new PepperPortAllocatorSession(
219 this, channel_name, component, stun_hosts(), 341 this, channel_name, component, stun_hosts(),
220 relay_hosts(), relay_token(), instance_); 342 relay_hosts(), relay_token(), instance_);
221 } 343 }
222 344
223 } // namespace remoting 345 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698