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

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
« no previous file with comments | « remoting/client/plugin/pepper_port_allocator.h ('k') | remoting/client/plugin/pepper_util.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
46 void OnUrlOpened(int32_t result); 57 void OnUrlOpened(int32_t result);
47 void ReadResponseBody(); 58 void ReadResponseBody();
48 void OnResponseBodyRead(int32_t result); 59 void OnResponseBodyRead(int32_t result);
49 60
50 pp::InstanceHandle instance_; 61 pp::InstanceHandle instance_;
51 62
52 scoped_ptr<pp::URLLoader> url_loader_; 63 pp::HostResolverPrivate stun_address_resolver_;
53 std::vector<char> body_; 64 talk_base::SocketAddress stun_address_;
65 int stun_port_;
66
67 scoped_ptr<pp::URLLoader> relay_url_loader_;
68 std::vector<char> relay_response_body_;
69 bool relay_response_received_;
54 70
55 DISALLOW_COPY_AND_ASSIGN(PepperPortAllocatorSession); 71 DISALLOW_COPY_AND_ASSIGN(PepperPortAllocatorSession);
56 }; 72 };
57 73
58 PepperPortAllocatorSession::PepperPortAllocatorSession( 74 PepperPortAllocatorSession::PepperPortAllocatorSession(
59 cricket::HttpPortAllocatorBase* allocator, 75 cricket::HttpPortAllocatorBase* allocator,
60 const std::string& channel_name, 76 const std::string& channel_name,
61 int component, 77 int component,
62 const std::vector<talk_base::SocketAddress>& stun_hosts, 78 const std::vector<talk_base::SocketAddress>& stun_hosts,
63 const std::vector<std::string>& relay_hosts, 79 const std::vector<std::string>& relay_hosts,
64 const std::string& relay, 80 const std::string& relay_token,
65 const pp::InstanceHandle& instance) 81 const pp::InstanceHandle& instance)
66 : HttpPortAllocatorSessionBase( 82 : cricket::HttpPortAllocatorSessionBase(
67 allocator, channel_name, component, stun_hosts, relay_hosts, relay, ""), 83 allocator, channel_name, component, stun_hosts,
68 instance_(instance) { 84 relay_hosts, relay_token, ""),
85 instance_(instance),
86 stun_address_resolver_(instance_),
87 stun_port_(0),
88 relay_response_received_(false) {
89 set_flags(cricket::PORTALLOCATOR_DISABLE_TCP);
90 if (stun_hosts.size() > 0) {
91 stun_address_ = stun_hosts[0];
92 }
69 } 93 }
70 94
71 PepperPortAllocatorSession::~PepperPortAllocatorSession() { 95 PepperPortAllocatorSession::~PepperPortAllocatorSession() {
72 } 96 }
73 97
74 void PepperPortAllocatorSession::ConfigReady( 98 void PepperPortAllocatorSession::ConfigReady(
75 cricket::PortConfiguration* config) { 99 cricket::PortConfiguration* config) {
100 if (config->stun_address.IsUnresolved()) {
101 // Make sure that the address that we pass to ConfigReady() is
102 // always resolved.
103 if (stun_address_.IsUnresolved()) {
104 config->stun_address.Clear();
105 } else {
106 config->stun_address = stun_address_;
107 }
108 }
109
76 // Filter out non-UDP relay ports, so that we don't try using TCP. 110 // Filter out non-UDP relay ports, so that we don't try using TCP.
77 for (cricket::PortConfiguration::RelayList::iterator relay = 111 for (cricket::PortConfiguration::RelayList::iterator relay =
78 config->relays.begin(); relay != config->relays.end(); ++relay) { 112 config->relays.begin(); relay != config->relays.end(); ++relay) {
79 cricket::PortConfiguration::PortList filtered_ports; 113 cricket::PortConfiguration::PortList filtered_ports;
80 for (cricket::PortConfiguration::PortList::iterator port = 114 for (cricket::PortConfiguration::PortList::iterator port =
81 relay->ports.begin(); port != relay->ports.end(); ++port) { 115 relay->ports.begin(); port != relay->ports.end(); ++port) {
82 if (port->proto == cricket::PROTO_UDP) { 116 if (port->proto == cricket::PROTO_UDP) {
83 filtered_ports.push_back(*port); 117 filtered_ports.push_back(*port);
84 } 118 }
85 } 119 }
86 relay->ports = filtered_ports; 120 relay->ports = filtered_ports;
87 } 121 }
88 cricket::BasicPortAllocatorSession::ConfigReady(config); 122 cricket::BasicPortAllocatorSession::ConfigReady(config);
89 } 123 }
90 124
125 void PepperPortAllocatorSession::GetPortConfigurations() {
126 // Add an empty configuration synchronously, so a local connection
127 // can be started immediately.
128 ConfigReady(new cricket::PortConfiguration(talk_base::SocketAddress()));
129
130 ResolveStunServerAddress();
131 TryCreateRelaySession();
132 }
133
134 void PepperPortAllocatorSession::ResolveStunServerAddress() {
135 if (stun_address_.IsNil()) {
136 return;
137 }
138
139 if (!stun_address_.IsUnresolved()) {
140 return;
141 }
142
143 std::string hostname = stun_address_.hostname();
144 uint16 port = stun_address_.port();
145
146 PP_HostResolver_Private_Hint hint;
147 hint.flags = 0;
148 hint.family = PP_NETADDRESSFAMILY_IPV4;
149 int result = stun_address_resolver_.Resolve(
150 hostname, port, hint, pp::CompletionCallback(
151 &PepperPortAllocatorSession::HostResolverCallback, this));
152 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING);
153 }
154
155 void PepperPortAllocatorSession::OnStunAddressResolved(int32_t result) {
156 if (result < 0) {
157 LOG(ERROR) << "Failed to resolve stun address "
158 << stun_address_.hostname() << ": " << result;
159 return;
160 }
161
162 if (!stun_address_resolver_.GetSize()) {
163 LOG(WARNING) << "Received 0 addresses for stun server "
164 << stun_address_.hostname();
165 return;
166 }
167
168 PP_NetAddress_Private address;
169 if (!stun_address_resolver_.GetNetAddress(0, &address) ||
170 !PpAddressToSocketAddress(address, &stun_address_)) {
171 LOG(ERROR) << "Failed to get address for STUN server "
172 << stun_address_.hostname();
173 return;
174 }
175
176 DCHECK(!stun_address_.IsUnresolved());
177
178 if (relay_response_received_) {
179 // If we've finished reading the response, then resubmit it to
180 // HttpPortAllocatorSessionBase. This is necessary because STUN
181 // and Relay parameters are stored together in PortConfiguration
182 // and ReceiveSessionResponse() doesn't save relay session
183 // configuration for the case we resolve STUN address later. This
184 // method invokes overriden ConfigReady() which then submits
185 // resolved |stun_address_|.
186 //
187 // TODO(sergeyu): Refactor HttpPortAllocatorSessionBase to fix this.
188 ReceiveSessionResponse(std::string(relay_response_body_.begin(),
189 relay_response_body_.end()));
190 } else {
191 ConfigReady(new cricket::PortConfiguration(stun_address_));
192 }
193 }
194
91 void PepperPortAllocatorSession::SendSessionRequest( 195 void PepperPortAllocatorSession::SendSessionRequest(
92 const std::string& host, 196 const std::string& host,
93 int port) { 197 int port) {
94 url_loader_.reset(new pp::URLLoader(instance_)); 198 relay_url_loader_.reset(new pp::URLLoader(instance_));
95 pp::URLRequestInfo request_info(instance_); 199 pp::URLRequestInfo request_info(instance_);
96 std::string url = "https://" + host + ":" + base::IntToString(port) + 200 std::string url = "https://" + host + ":" + base::IntToString(port) +
97 GetSessionRequestUrl() + "&sn=1"; 201 GetSessionRequestUrl() + "&sn=1";
98 request_info.SetURL(url); 202 request_info.SetURL(url);
99 request_info.SetMethod("GET"); 203 request_info.SetMethod("GET");
100 std::stringstream headers; 204 std::stringstream headers;
101 headers << "X-Talk-Google-Relay-Auth: " << relay_token() << "\n\r"; 205 headers << "X-Talk-Google-Relay-Auth: " << relay_token() << "\n\r";
102 headers << "X-Google-Relay-Auth: " << relay_token() << "\n\r"; 206 headers << "X-Google-Relay-Auth: " << relay_token() << "\n\r";
103 headers << "X-StreamType: " << channel_name() << "\n\r"; 207 headers << "X-StreamType: " << channel_name() << "\n\r";
104 request_info.SetHeaders(headers.str()); 208 request_info.SetHeaders(headers.str());
105 209
106 int result = url_loader_->Open(request_info, pp::CompletionCallback( 210 int result = relay_url_loader_->Open(request_info, pp::CompletionCallback(
107 &PepperPortAllocatorSession::UrlLoaderOpenCallback, this)); 211 &PepperPortAllocatorSession::UrlLoaderOpenCallback, this));
108 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING); 212 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING);
109 } 213 }
110 214
111 void PepperPortAllocatorSession::OnUrlOpened(int32_t result) { 215 void PepperPortAllocatorSession::OnUrlOpened(int32_t result) {
112 if (result == PP_ERROR_ABORTED) 216 if (result == PP_ERROR_ABORTED) {
113 return; 217 return;
218 }
114 219
115 if (result < 0) { 220 if (result < 0) {
116 LOG(WARNING) << "URLLoader failed: " << result; 221 LOG(WARNING) << "URLLoader failed: " << result;
117 // Retry creating session. 222 // Retry creating session.
118 TryCreateRelaySession(); 223 TryCreateRelaySession();
119 return; 224 return;
120 } 225 }
121 226
122 pp::URLResponseInfo response = url_loader_->GetResponseInfo(); 227 pp::URLResponseInfo response = relay_url_loader_->GetResponseInfo();
123 DCHECK(!response.is_null()); 228 DCHECK(!response.is_null());
124 if (response.GetStatusCode() != 200) { 229 if (response.GetStatusCode() != 200) {
125 LOG(WARNING) << "Received HTTP status code " << response.GetStatusCode(); 230 LOG(WARNING) << "Received HTTP status code " << response.GetStatusCode();
126 // Retry creating session. 231 // Retry creating session.
127 TryCreateRelaySession(); 232 TryCreateRelaySession();
128 return; 233 return;
129 } 234 }
130 235
131 body_.clear(); 236 relay_response_body_.clear();
132 ReadResponseBody(); 237 ReadResponseBody();
133 } 238 }
134 239
135 void PepperPortAllocatorSession::ReadResponseBody() { 240 void PepperPortAllocatorSession::ReadResponseBody() {
136 int pos = body_.size(); 241 int pos = relay_response_body_.size();
137 body_.resize(pos + kReadSize); 242 relay_response_body_.resize(pos + kReadSize);
138 int result = url_loader_->ReadResponseBody( 243 int result = relay_url_loader_->ReadResponseBody(
139 &body_[pos], kReadSize, pp::CompletionCallback( 244 &relay_response_body_[pos], kReadSize, pp::CompletionCallback(
140 &PepperPortAllocatorSession::UrlLoaderReadCallback, this)); 245 &PepperPortAllocatorSession::UrlLoaderReadCallback, this));
141 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING); 246 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING);
142 } 247 }
143 248
144 void PepperPortAllocatorSession::OnResponseBodyRead(int32_t result) { 249 void PepperPortAllocatorSession::OnResponseBodyRead(int32_t result) {
145 if (result == PP_ERROR_ABORTED) 250 if (result == PP_ERROR_ABORTED) {
146 return; 251 return;
252 }
147 253
148 if (result < 0) { 254 if (result < 0) {
149 LOG(WARNING) << "Failed to read HTTP response body when " 255 LOG(WARNING) << "Failed to read HTTP response body when "
150 "creating relay session: " << result; 256 "creating relay session: " << result;
151 // Retry creating session. 257 // Retry creating session.
152 TryCreateRelaySession(); 258 TryCreateRelaySession();
153 return; 259 return;
154 } 260 }
155 261
156 // Resize the buffer in case we've read less than was requested. 262 // Resize the buffer in case we've read less than was requested.
157 CHECK_LE(result, kReadSize); 263 CHECK_LE(result, kReadSize);
158 CHECK_GE(static_cast<int>(body_.size()), kReadSize); 264 CHECK_GE(static_cast<int>(relay_response_body_.size()), kReadSize);
159 body_.resize(body_.size() - kReadSize + result); 265 relay_response_body_.resize(relay_response_body_.size() - kReadSize + result);
160 266
161 if (result == 0) { 267 if (result == 0) {
162 // Finished reading the response. 268 relay_response_received_ = true;
163 ReceiveSessionResponse(std::string(body_.begin(), body_.end())); 269 ReceiveSessionResponse(std::string(relay_response_body_.begin(),
270 relay_response_body_.end()));
164 return; 271 return;
165 } 272 }
166 273
167 ReadResponseBody(); 274 ReadResponseBody();
168 } 275 }
169 276
170 // static 277 // static
278 void PepperPortAllocatorSession::HostResolverCallback(
279 void* user_data,
280 int32_t result) {
281 PepperPortAllocatorSession* object =
282 static_cast<PepperPortAllocatorSession*>(user_data);
283 object->OnStunAddressResolved(result);
284 }
285
286 // static
171 void PepperPortAllocatorSession::UrlLoaderOpenCallback( 287 void PepperPortAllocatorSession::UrlLoaderOpenCallback(
172 void* user_data, 288 void* user_data,
173 int32_t result) { 289 int32_t result) {
174 PepperPortAllocatorSession* object = 290 PepperPortAllocatorSession* object =
175 static_cast<PepperPortAllocatorSession*>(user_data); 291 static_cast<PepperPortAllocatorSession*>(user_data);
176 object->OnUrlOpened(result); 292 object->OnUrlOpened(result);
177 } 293 }
178 294
179 // static 295 // static
180 void PepperPortAllocatorSession::UrlLoaderReadCallback( 296 void PepperPortAllocatorSession::UrlLoaderReadCallback(
(...skipping 27 matching lines...) Expand all
208 network_manager_(network_manager.Pass()), 324 network_manager_(network_manager.Pass()),
209 socket_factory_(socket_factory.Pass()) { 325 socket_factory_(socket_factory.Pass()) {
210 } 326 }
211 327
212 PepperPortAllocator::~PepperPortAllocator() { 328 PepperPortAllocator::~PepperPortAllocator() {
213 } 329 }
214 330
215 cricket::PortAllocatorSession* PepperPortAllocator::CreateSession( 331 cricket::PortAllocatorSession* PepperPortAllocator::CreateSession(
216 const std::string& channel_name, 332 const std::string& channel_name,
217 int component) { 333 int component) {
218 return new PepperPortAllocatorSession( 334 return new PepperPortAllocatorSession(
219 this, channel_name, component, stun_hosts(), 335 this, channel_name, component, stun_hosts(),
220 relay_hosts(), relay_token(), instance_); 336 relay_hosts(), relay_token(), instance_);
221 } 337 }
222 338
223 } // namespace remoting 339 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/client/plugin/pepper_port_allocator.h ('k') | remoting/client/plugin/pepper_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698