| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/protocol/port_allocator_base.h" | 5 #include "remoting/protocol/port_allocator_base.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <map> | 8 #include <map> |
| 9 | 9 |
| 10 #include "base/bind.h" |
| 10 #include "base/logging.h" | 11 #include "base/logging.h" |
| 11 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
| 12 #include "base/strings/string_split.h" | 13 #include "base/strings/string_split.h" |
| 13 #include "net/base/escape.h" | 14 #include "net/base/escape.h" |
| 15 #include "remoting/protocol/network_settings.h" |
| 16 #include "remoting/protocol/transport_context.h" |
| 14 | 17 |
| 15 namespace { | 18 namespace { |
| 16 | 19 |
| 17 typedef std::map<std::string, std::string> StringMap; | 20 typedef std::map<std::string, std::string> StringMap; |
| 18 | 21 |
| 19 // Parses the lines in the result of the HTTP request that are of the form | 22 // Parses the lines in the result of the HTTP request that are of the form |
| 20 // 'a=b' and returns them in a map. | 23 // 'a=b' and returns them in a map. |
| 21 StringMap ParseMap(const std::string& string) { | 24 StringMap ParseMap(const std::string& string) { |
| 22 StringMap map; | 25 StringMap map; |
| 23 base::StringPairs pairs; | 26 base::StringPairs pairs; |
| 24 base::SplitStringIntoKeyValuePairs(string, '\r', '=', &pairs); | 27 base::SplitStringIntoKeyValuePairs(string, '\r', '=', &pairs); |
| 25 | 28 |
| 26 for (auto& pair : pairs) { | 29 for (auto& pair : pairs) { |
| 27 map[pair.first] = pair.second; | 30 map[pair.first] = pair.second; |
| 28 } | 31 } |
| 29 return map; | 32 return map; |
| 30 } | 33 } |
| 31 | 34 |
| 32 } // namespace | 35 } // namespace |
| 33 | 36 |
| 34 namespace remoting { | 37 namespace remoting { |
| 35 namespace protocol { | 38 namespace protocol { |
| 36 | 39 |
| 37 const int PortAllocatorBase::kNumRetries = 5; | 40 const int PortAllocatorBase::kNumRetries = 5; |
| 38 | 41 |
| 39 PortAllocatorBase::PortAllocatorBase(rtc::NetworkManager* network_manager, | 42 PortAllocatorBase::PortAllocatorBase( |
| 40 rtc::PacketSocketFactory* socket_factory) | 43 scoped_ptr<rtc::NetworkManager> network_manager, |
| 41 : BasicPortAllocator(network_manager, socket_factory) {} | 44 scoped_ptr<rtc::PacketSocketFactory> socket_factory, |
| 45 scoped_refptr<TransportContext> transport_context) |
| 46 : BasicPortAllocator(network_manager.get(), socket_factory.get()), |
| 47 network_manager_(std::move(network_manager)), |
| 48 socket_factory_(std::move(socket_factory)), |
| 49 transport_context_(transport_context) { |
| 50 // We always use PseudoTcp to provide a reliable channel. It provides poor |
| 51 // performance when combined with TCP-based transport, so we have to disable |
| 52 // TCP ports. ENABLE_SHARED_UFRAG flag is specified so that the same username |
| 53 // fragment is shared between all candidates. |
| 54 int flags = cricket::PORTALLOCATOR_DISABLE_TCP | |
| 55 cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG | |
| 56 cricket::PORTALLOCATOR_ENABLE_IPV6; |
| 57 |
| 58 NetworkSettings network_settings = transport_context_->network_settings(); |
| 59 |
| 60 if (!(network_settings.flags & NetworkSettings::NAT_TRAVERSAL_STUN)) |
| 61 flags |= cricket::PORTALLOCATOR_DISABLE_STUN; |
| 62 |
| 63 if (!(network_settings.flags & NetworkSettings::NAT_TRAVERSAL_RELAY)) |
| 64 flags |= cricket::PORTALLOCATOR_DISABLE_RELAY; |
| 65 |
| 66 set_flags(flags); |
| 67 SetPortRange(network_settings.port_range.min_port, |
| 68 network_settings.port_range.max_port); |
| 69 } |
| 42 | 70 |
| 43 PortAllocatorBase::~PortAllocatorBase() {} | 71 PortAllocatorBase::~PortAllocatorBase() {} |
| 44 | 72 |
| 45 void PortAllocatorBase::SetStunHosts( | |
| 46 const std::vector<rtc::SocketAddress>& hosts) { | |
| 47 stun_hosts_ = hosts; | |
| 48 } | |
| 49 | |
| 50 void PortAllocatorBase::SetRelayHosts(const std::vector<std::string>& hosts) { | |
| 51 relay_hosts_ = hosts; | |
| 52 } | |
| 53 | |
| 54 void PortAllocatorBase::SetRelayToken(const std::string& relay) { | |
| 55 relay_token_ = relay; | |
| 56 } | |
| 57 | |
| 58 PortAllocatorSessionBase::PortAllocatorSessionBase( | 73 PortAllocatorSessionBase::PortAllocatorSessionBase( |
| 59 PortAllocatorBase* allocator, | 74 PortAllocatorBase* allocator, |
| 60 const std::string& content_name, | 75 const std::string& content_name, |
| 61 int component, | 76 int component, |
| 62 const std::string& ice_ufrag, | 77 const std::string& ice_ufrag, |
| 63 const std::string& ice_pwd, | 78 const std::string& ice_pwd) |
| 64 const std::vector<rtc::SocketAddress>& stun_hosts, | |
| 65 const std::vector<std::string>& relay_hosts, | |
| 66 const std::string& relay_token) | |
| 67 : BasicPortAllocatorSession(allocator, | 79 : BasicPortAllocatorSession(allocator, |
| 68 content_name, | 80 content_name, |
| 69 component, | 81 component, |
| 70 ice_ufrag, | 82 ice_ufrag, |
| 71 ice_pwd), | 83 ice_pwd), |
| 72 relay_hosts_(relay_hosts), | 84 transport_context_(allocator->transport_context()), |
| 73 stun_hosts_(stun_hosts), | 85 weak_factory_(this) {} |
| 74 relay_token_(relay_token), | |
| 75 attempts_(0) {} | |
| 76 | 86 |
| 77 PortAllocatorSessionBase::~PortAllocatorSessionBase() {} | 87 PortAllocatorSessionBase::~PortAllocatorSessionBase() {} |
| 78 | 88 |
| 79 void PortAllocatorSessionBase::GetPortConfigurations() { | 89 void PortAllocatorSessionBase::GetPortConfigurations() { |
| 90 transport_context_->GetJingleInfo(base::Bind( |
| 91 &PortAllocatorSessionBase::OnJingleInfo, weak_factory_.GetWeakPtr())); |
| 92 } |
| 93 |
| 94 void PortAllocatorSessionBase::OnJingleInfo( |
| 95 std::vector<rtc::SocketAddress> stun_hosts, |
| 96 std::vector<std::string> relay_hosts, |
| 97 std::string relay_token) { |
| 98 stun_hosts_ = stun_hosts; |
| 99 relay_hosts_ = relay_hosts; |
| 100 relay_token_ = relay_token; |
| 101 |
| 80 // Creating relay sessions can take time and is done asynchronously. | 102 // Creating relay sessions can take time and is done asynchronously. |
| 81 // Creating stun sessions could also take time and could be done aysnc also, | 103 // Creating stun sessions could also take time and could be done aysnc also, |
| 82 // but for now is done here and added to the initial config. Note any later | 104 // but for now is done here and added to the initial config. Note any later |
| 83 // configs will have unresolved stun ips and will be discarded by the | 105 // configs will have unresolved stun ips and will be discarded by the |
| 84 // AllocationSequence. | 106 // AllocationSequence. |
| 85 cricket::ServerAddresses hosts; | 107 cricket::ServerAddresses hosts; |
| 86 for (const auto& host : stun_hosts_) { | 108 for (const auto& host : stun_hosts_) { |
| 87 hosts.insert(host); | 109 hosts.insert(host); |
| 88 } | 110 } |
| 89 | 111 |
| 90 cricket::PortConfiguration* config = | 112 cricket::PortConfiguration* config = |
| 91 new cricket::PortConfiguration(hosts, username(), password()); | 113 new cricket::PortConfiguration(hosts, username(), password()); |
| 92 ConfigReady(config); | 114 ConfigReady(config); |
| 93 TryCreateRelaySession(); | 115 TryCreateRelaySession(); |
| 94 } | 116 } |
| 95 | 117 |
| 96 void PortAllocatorSessionBase::TryCreateRelaySession() { | 118 void PortAllocatorSessionBase::TryCreateRelaySession() { |
| 97 if (allocator()->flags() & cricket::PORTALLOCATOR_DISABLE_RELAY) | 119 if (flags() & cricket::PORTALLOCATOR_DISABLE_RELAY) |
| 98 return; | 120 return; |
| 99 | 121 |
| 100 if (attempts_ == PortAllocatorBase::kNumRetries) { | 122 if (attempts_ == PortAllocatorBase::kNumRetries) { |
| 101 LOG(ERROR) << "PortAllocator: maximum number of requests reached; " | 123 LOG(ERROR) << "PortAllocator: maximum number of requests reached; " |
| 102 << "giving up on relay."; | 124 << "giving up on relay."; |
| 103 return; | 125 return; |
| 104 } | 126 } |
| 105 | 127 |
| 106 if (relay_hosts_.empty()) { | 128 if (relay_hosts_.empty()) { |
| 107 LOG(ERROR) << "PortAllocator: no relay hosts configured."; | 129 LOG(ERROR) << "PortAllocator: no relay hosts configured."; |
| 108 return; | 130 return; |
| 109 } | 131 } |
| 110 | 132 |
| 111 if (relay_token_.empty()){ | 133 if (relay_token_.empty()){ |
| 112 LOG(WARNING) << "No relay auth token found."; | 134 LOG(WARNING) << "No relay auth token found."; |
| 113 return; | 135 return; |
| 114 } | 136 } |
| 115 | 137 |
| 116 // Choose the next host to try. | 138 // Choose the next host to try. |
| 117 std::string host = relay_hosts_[attempts_ % relay_hosts_.size()]; | 139 std::string host = relay_hosts_[attempts_ % relay_hosts_.size()]; |
| 118 attempts_++; | 140 attempts_++; |
| 119 SendSessionRequest(host); | 141 SendSessionRequest(host); |
| 120 } | 142 } |
| 121 | 143 |
| 122 PortAllocatorBase* PortAllocatorSessionBase::allocator() { | |
| 123 return static_cast<PortAllocatorBase*>( | |
| 124 BasicPortAllocatorSession::allocator()); | |
| 125 } | |
| 126 | |
| 127 std::string PortAllocatorSessionBase::GetSessionRequestUrl() { | 144 std::string PortAllocatorSessionBase::GetSessionRequestUrl() { |
| 128 ASSERT(!username().empty()); | 145 ASSERT(!username().empty()); |
| 129 ASSERT(!password().empty()); | 146 ASSERT(!password().empty()); |
| 130 return "/create_session?username=" + | 147 return "/create_session?username=" + |
| 131 net::EscapeUrlEncodedData(username(), false) + "&password=" + | 148 net::EscapeUrlEncodedData(username(), false) + "&password=" + |
| 132 net::EscapeUrlEncodedData(password(), false); | 149 net::EscapeUrlEncodedData(password(), false); |
| 133 } | 150 } |
| 134 | 151 |
| 135 void PortAllocatorSessionBase::ReceiveSessionResponse( | 152 void PortAllocatorSessionBase::ReceiveSessionResponse( |
| 136 const std::string& response) { | 153 const std::string& response) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 162 relay_config.ports.push_back( | 179 relay_config.ports.push_back( |
| 163 cricket::ProtocolAddress(address, cricket::PROTO_UDP)); | 180 cricket::ProtocolAddress(address, cricket::PROTO_UDP)); |
| 164 config->AddRelay(relay_config); | 181 config->AddRelay(relay_config); |
| 165 } | 182 } |
| 166 | 183 |
| 167 ConfigReady(config); | 184 ConfigReady(config); |
| 168 } | 185 } |
| 169 | 186 |
| 170 } // namespace protocol | 187 } // namespace protocol |
| 171 } // namespace remoting | 188 } // namespace remoting |
| OLD | NEW |