| 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 |