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 "remoting/client/plugin/pepper_port_allocator.h" | 5 #include "remoting/client/plugin/pepper_port_allocator.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
9 #include "net/base/net_util.h" | 9 #include "net/base/net_util.h" |
10 #include "ppapi/c/pp_errors.h" | 10 #include "ppapi/c/pp_errors.h" |
11 #include "ppapi/cpp/host_resolver.h" | |
12 #include "ppapi/cpp/net_address.h" | |
13 #include "ppapi/cpp/url_loader.h" | 11 #include "ppapi/cpp/url_loader.h" |
14 #include "ppapi/cpp/url_request_info.h" | 12 #include "ppapi/cpp/url_request_info.h" |
15 #include "ppapi/cpp/url_response_info.h" | 13 #include "ppapi/cpp/url_response_info.h" |
16 #include "ppapi/utility/completion_callback_factory.h" | 14 #include "ppapi/utility/completion_callback_factory.h" |
17 #include "remoting/client/plugin/pepper_network_manager.h" | 15 #include "remoting/client/plugin/pepper_network_manager.h" |
18 #include "remoting/client/plugin/pepper_packet_socket_factory.h" | 16 #include "remoting/client/plugin/pepper_packet_socket_factory.h" |
19 #include "remoting/client/plugin/pepper_util.h" | 17 #include "remoting/client/plugin/pepper_util.h" |
20 | 18 |
21 namespace remoting { | 19 namespace remoting { |
22 | 20 |
(...skipping 17 matching lines...) Expand all Loading... |
40 const std::string& relay_token, | 38 const std::string& relay_token, |
41 const pp::InstanceHandle& instance); | 39 const pp::InstanceHandle& instance); |
42 virtual ~PepperPortAllocatorSession(); | 40 virtual ~PepperPortAllocatorSession(); |
43 | 41 |
44 // cricket::HttpPortAllocatorBase overrides. | 42 // cricket::HttpPortAllocatorBase overrides. |
45 virtual void ConfigReady(cricket::PortConfiguration* config) OVERRIDE; | 43 virtual void ConfigReady(cricket::PortConfiguration* config) OVERRIDE; |
46 virtual void GetPortConfigurations() OVERRIDE; | 44 virtual void GetPortConfigurations() OVERRIDE; |
47 virtual void SendSessionRequest(const std::string& host, int port) OVERRIDE; | 45 virtual void SendSessionRequest(const std::string& host, int port) OVERRIDE; |
48 | 46 |
49 private: | 47 private: |
50 void ResolveStunServerAddress(); | |
51 void OnStunAddressResolved(int32_t result); | |
52 | |
53 void OnUrlOpened(int32_t result); | 48 void OnUrlOpened(int32_t result); |
54 void ReadResponseBody(); | 49 void ReadResponseBody(); |
55 void OnResponseBodyRead(int32_t result); | 50 void OnResponseBodyRead(int32_t result); |
56 | 51 |
57 pp::InstanceHandle instance_; | 52 pp::InstanceHandle instance_; |
58 | 53 |
59 pp::HostResolver stun_address_resolver_; | |
60 rtc::SocketAddress stun_address_; | 54 rtc::SocketAddress stun_address_; |
61 int stun_port_; | 55 int stun_port_; |
62 | 56 |
63 scoped_ptr<pp::URLLoader> relay_url_loader_; | 57 scoped_ptr<pp::URLLoader> relay_url_loader_; |
64 std::vector<char> relay_response_body_; | 58 std::vector<char> relay_response_body_; |
65 bool relay_response_received_; | 59 bool relay_response_received_; |
66 | 60 |
67 pp::CompletionCallbackFactory<PepperPortAllocatorSession> callback_factory_; | 61 pp::CompletionCallbackFactory<PepperPortAllocatorSession> callback_factory_; |
68 | 62 |
69 DISALLOW_COPY_AND_ASSIGN(PepperPortAllocatorSession); | 63 DISALLOW_COPY_AND_ASSIGN(PepperPortAllocatorSession); |
(...skipping 12 matching lines...) Expand all Loading... |
82 : HttpPortAllocatorSessionBase(allocator, | 76 : HttpPortAllocatorSessionBase(allocator, |
83 content_name, | 77 content_name, |
84 component, | 78 component, |
85 ice_username_fragment, | 79 ice_username_fragment, |
86 ice_password, | 80 ice_password, |
87 stun_hosts, | 81 stun_hosts, |
88 relay_hosts, | 82 relay_hosts, |
89 relay_token, | 83 relay_token, |
90 std::string()), | 84 std::string()), |
91 instance_(instance), | 85 instance_(instance), |
92 stun_address_resolver_(instance_), | |
93 stun_port_(0), | 86 stun_port_(0), |
94 relay_response_received_(false), | 87 relay_response_received_(false), |
95 callback_factory_(this) { | 88 callback_factory_(this) { |
96 if (stun_hosts.size() > 0) { | 89 if (stun_hosts.size() > 0) { |
97 stun_address_ = stun_hosts[0]; | 90 stun_address_ = stun_hosts[0]; |
98 } | 91 } |
99 } | 92 } |
100 | 93 |
101 PepperPortAllocatorSession::~PepperPortAllocatorSession() { | 94 PepperPortAllocatorSession::~PepperPortAllocatorSession() { |
102 } | 95 } |
103 | 96 |
104 void PepperPortAllocatorSession::ConfigReady( | 97 void PepperPortAllocatorSession::ConfigReady( |
105 cricket::PortConfiguration* config) { | 98 cricket::PortConfiguration* config) { |
106 if (config->stun_address.IsUnresolved()) { | |
107 // Make sure that the address that we pass to ConfigReady() is | |
108 // always resolved. | |
109 if (stun_address_.IsUnresolved()) { | |
110 config->stun_address.Clear(); | |
111 } else { | |
112 config->stun_address = stun_address_; | |
113 } | |
114 } | |
115 | |
116 // Filter out non-UDP relay ports, so that we don't try using TCP. | 99 // Filter out non-UDP relay ports, so that we don't try using TCP. |
117 for (cricket::PortConfiguration::RelayList::iterator relay = | 100 for (cricket::PortConfiguration::RelayList::iterator relay = |
118 config->relays.begin(); relay != config->relays.end(); ++relay) { | 101 config->relays.begin(); relay != config->relays.end(); ++relay) { |
119 cricket::PortList filtered_ports; | 102 cricket::PortList filtered_ports; |
120 for (cricket::PortList::iterator port = | 103 for (cricket::PortList::iterator port = |
121 relay->ports.begin(); port != relay->ports.end(); ++port) { | 104 relay->ports.begin(); port != relay->ports.end(); ++port) { |
122 if (port->proto == cricket::PROTO_UDP) { | 105 if (port->proto == cricket::PROTO_UDP) { |
123 filtered_ports.push_back(*port); | 106 filtered_ports.push_back(*port); |
124 } | 107 } |
125 } | 108 } |
126 relay->ports = filtered_ports; | 109 relay->ports = filtered_ports; |
127 } | 110 } |
128 cricket::BasicPortAllocatorSession::ConfigReady(config); | 111 cricket::BasicPortAllocatorSession::ConfigReady(config); |
129 } | 112 } |
130 | 113 |
131 void PepperPortAllocatorSession::GetPortConfigurations() { | 114 void PepperPortAllocatorSession::GetPortConfigurations() { |
132 // Add an empty configuration synchronously, so a local connection | 115 // Add a configuration without relay response first so local and STUN |
133 // can be started immediately. | 116 // candidates can be allocated without waiting for the relay response. |
134 ConfigReady(new cricket::PortConfiguration( | 117 ConfigReady(new cricket::PortConfiguration( |
135 rtc::SocketAddress(), std::string(), std::string())); | 118 stun_address_, std::string(), std::string())); |
136 | 119 |
137 ResolveStunServerAddress(); | |
138 TryCreateRelaySession(); | 120 TryCreateRelaySession(); |
139 } | 121 } |
140 | 122 |
141 void PepperPortAllocatorSession::ResolveStunServerAddress() { | |
142 if (stun_address_.IsNil()) { | |
143 return; | |
144 } | |
145 | |
146 if (!stun_address_.IsUnresolved()) { | |
147 return; | |
148 } | |
149 | |
150 std::string hostname = stun_address_.hostname(); | |
151 uint16 port = stun_address_.port(); | |
152 | |
153 PP_HostResolver_Hint hint; | |
154 hint.flags = 0; | |
155 hint.family = PP_NETADDRESS_FAMILY_IPV4; | |
156 pp::CompletionCallback callback = callback_factory_.NewCallback( | |
157 &PepperPortAllocatorSession::OnStunAddressResolved); | |
158 int result = stun_address_resolver_.Resolve(hostname.c_str(), | |
159 port, | |
160 hint, | |
161 callback); | |
162 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING); | |
163 } | |
164 | |
165 void PepperPortAllocatorSession::OnStunAddressResolved(int32_t result) { | |
166 if (result < 0) { | |
167 LOG(ERROR) << "Failed to resolve stun address " | |
168 << stun_address_.hostname() << ": " << result; | |
169 return; | |
170 } | |
171 | |
172 if (!stun_address_resolver_.GetNetAddressCount()) { | |
173 LOG(WARNING) << "Received 0 addresses for stun server " | |
174 << stun_address_.hostname(); | |
175 return; | |
176 } | |
177 | |
178 pp::NetAddress address = stun_address_resolver_.GetNetAddress(0); | |
179 if (address.is_null()) { | |
180 LOG(ERROR) << "Failed to get address for STUN server " | |
181 << stun_address_.hostname(); | |
182 return; | |
183 } | |
184 | |
185 PpNetAddressToSocketAddress(address, &stun_address_); | |
186 DCHECK(!stun_address_.IsUnresolved()); | |
187 | |
188 if (relay_response_received_) { | |
189 // If we've finished reading the response, then resubmit it to | |
190 // HttpPortAllocatorSessionBase. This is necessary because STUN | |
191 // and Relay parameters are stored together in PortConfiguration | |
192 // and ReceiveSessionResponse() doesn't save relay session | |
193 // configuration for the case we resolve STUN address later. This | |
194 // method invokes overriden ConfigReady() which then submits | |
195 // resolved |stun_address_|. | |
196 // | |
197 // TODO(sergeyu): Refactor HttpPortAllocatorSessionBase to fix this. | |
198 ReceiveSessionResponse(std::string(relay_response_body_.begin(), | |
199 relay_response_body_.end())); | |
200 } else { | |
201 ConfigReady(new cricket::PortConfiguration( | |
202 stun_address_, std::string(), std::string())); | |
203 } | |
204 } | |
205 | |
206 void PepperPortAllocatorSession::SendSessionRequest( | 123 void PepperPortAllocatorSession::SendSessionRequest( |
207 const std::string& host, | 124 const std::string& host, |
208 int port) { | 125 int port) { |
209 relay_url_loader_.reset(new pp::URLLoader(instance_)); | 126 relay_url_loader_.reset(new pp::URLLoader(instance_)); |
210 pp::URLRequestInfo request_info(instance_); | 127 pp::URLRequestInfo request_info(instance_); |
211 std::string url = "https://" + host + ":" + base::IntToString(port) + | 128 std::string url = "https://" + host + ":" + base::IntToString(port) + |
212 GetSessionRequestUrl() + "&sn=1"; | 129 GetSessionRequestUrl() + "&sn=1"; |
213 request_info.SetURL(url); | 130 request_info.SetURL(url); |
214 request_info.SetMethod("GET"); | 131 request_info.SetMethod("GET"); |
215 std::stringstream headers; | 132 std::stringstream headers; |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 const std::string& content_name, | 245 const std::string& content_name, |
329 int component, | 246 int component, |
330 const std::string& ice_username_fragment, | 247 const std::string& ice_username_fragment, |
331 const std::string& ice_password) { | 248 const std::string& ice_password) { |
332 return new PepperPortAllocatorSession( | 249 return new PepperPortAllocatorSession( |
333 this, content_name, component, ice_username_fragment, ice_password, | 250 this, content_name, component, ice_username_fragment, ice_password, |
334 stun_hosts(), relay_hosts(), relay_token(), instance_); | 251 stun_hosts(), relay_hosts(), relay_token(), instance_); |
335 } | 252 } |
336 | 253 |
337 } // namespace remoting | 254 } // namespace remoting |
OLD | NEW |