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

Side by Side Diff: remoting/protocol/ice_transport_channel.cc

Issue 1412313006: Remove remoting::protocol::Transport interface. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@transport_session.h
Patch Set: Created 5 years, 1 month 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
« no previous file with comments | « remoting/protocol/ice_transport_channel.h ('k') | remoting/protocol/ice_transport_factory.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 2015 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/libjingle_transport_factory.h" 5 #include "remoting/protocol/ice_transport_channel.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/callback.h" 9 #include "base/callback.h"
10 #include "base/callback_helpers.h" 10 #include "base/callback_helpers.h"
11 #include "base/single_thread_task_runner.h" 11 #include "base/single_thread_task_runner.h"
12 #include "base/thread_task_runner_handle.h" 12 #include "base/thread_task_runner_handle.h"
13 #include "base/timer/timer.h"
14 #include "jingle/glue/utils.h" 13 #include "jingle/glue/utils.h"
15 #include "net/base/net_errors.h" 14 #include "net/base/net_errors.h"
16 #include "remoting/protocol/channel_socket_adapter.h" 15 #include "remoting/protocol/channel_socket_adapter.h"
17 #include "remoting/protocol/network_settings.h"
18 #include "remoting/signaling/jingle_info_request.h"
19 #include "third_party/webrtc/base/network.h" 16 #include "third_party/webrtc/base/network.h"
20 #include "third_party/webrtc/p2p/base/constants.h" 17 #include "third_party/webrtc/p2p/base/constants.h"
21 #include "third_party/webrtc/p2p/base/p2ptransportchannel.h" 18 #include "third_party/webrtc/p2p/base/p2ptransportchannel.h"
22 #include "third_party/webrtc/p2p/base/port.h" 19 #include "third_party/webrtc/p2p/base/port.h"
23 #include "third_party/webrtc/p2p/client/httpportallocator.h" 20 #include "third_party/webrtc/p2p/client/httpportallocator.h"
24 21
25 namespace remoting { 22 namespace remoting {
26 namespace protocol { 23 namespace protocol {
27 24
28 namespace { 25 namespace {
29 26
30 // Try connecting ICE twice with timeout of 15 seconds for each attempt. 27 // Try connecting ICE twice with timeout of 15 seconds for each attempt.
31 const int kMaxReconnectAttempts = 2; 28 const int kMaxReconnectAttempts = 2;
32 const int kReconnectDelaySeconds = 15; 29 const int kReconnectDelaySeconds = 15;
33 30
34 // Get fresh STUN/Relay configuration every hour.
35 const int kJingleInfoUpdatePeriodSeconds = 3600;
36
37 // Utility function to map a cricket::Candidate string type to a 31 // Utility function to map a cricket::Candidate string type to a
38 // TransportRoute::RouteType enum value. 32 // TransportRoute::RouteType enum value.
39 TransportRoute::RouteType CandidateTypeToTransportRouteType( 33 TransportRoute::RouteType CandidateTypeToTransportRouteType(
40 const std::string& candidate_type) { 34 const std::string& candidate_type) {
41 if (candidate_type == "local") { 35 if (candidate_type == "local") {
42 return TransportRoute::DIRECT; 36 return TransportRoute::DIRECT;
43 } else if (candidate_type == "stun" || candidate_type == "prflx") { 37 } else if (candidate_type == "stun" || candidate_type == "prflx") {
44 return TransportRoute::STUN; 38 return TransportRoute::STUN;
45 } else if (candidate_type == "relay") { 39 } else if (candidate_type == "relay") {
46 return TransportRoute::RELAY; 40 return TransportRoute::RELAY;
47 } else { 41 } else {
48 LOG(FATAL) << "Unknown candidate type: " << candidate_type; 42 LOG(FATAL) << "Unknown candidate type: " << candidate_type;
49 return TransportRoute::DIRECT; 43 return TransportRoute::DIRECT;
50 } 44 }
51 } 45 }
52 46
53 class LibjingleTransport 47 } // namespace
54 : public Transport,
55 public base::SupportsWeakPtr<LibjingleTransport>,
56 public sigslot::has_slots<> {
57 public:
58 LibjingleTransport(cricket::PortAllocator* port_allocator,
59 const NetworkSettings& network_settings,
60 TransportRole role);
61 ~LibjingleTransport() override;
62 48
63 // Called by JingleTransportFactory when it has fresh Jingle info. 49 IceTransportChannel::IceTransportChannel(cricket::PortAllocator* port_allocator,
64 void OnCanStart();
65
66 // Transport interface.
67 void Connect(const std::string& name,
68 Transport::EventHandler* event_handler,
69 const Transport::ConnectedCallback& callback) override;
70 void SetRemoteCredentials(const std::string& ufrag,
71 const std::string& password) override;
72 void AddRemoteCandidate(const cricket::Candidate& candidate) override;
73 const std::string& name() const override;
74 bool is_connected() const override;
75
76 private:
77 void DoStart();
78 void NotifyConnected();
79
80 // Signal handlers for cricket::TransportChannel.
81 void OnCandidateGathered(cricket::TransportChannelImpl* channel,
82 const cricket::Candidate& candidate);
83 void OnRouteChange(cricket::TransportChannel* channel,
84 const cricket::Candidate& candidate);
85 void OnReceivingState(cricket::TransportChannel* channel);
86 void OnWritableState(cricket::TransportChannel* channel);
87
88 // Callback for TransportChannelSocketAdapter to notify when the socket is
89 // destroyed.
90 void OnChannelDestroyed();
91
92 void NotifyRouteChanged();
93
94 // Tries to connect by restarting ICE. Called by |reconnect_timer_|.
95 void TryReconnect();
96
97 cricket::PortAllocator* port_allocator_;
98 NetworkSettings network_settings_;
99 TransportRole role_;
100
101 std::string name_;
102 EventHandler* event_handler_;
103 Transport::ConnectedCallback callback_;
104 std::string ice_username_fragment_;
105
106 bool can_start_;
107
108 std::string remote_ice_username_fragment_;
109 std::string remote_ice_password_;
110 std::list<cricket::Candidate> pending_candidates_;
111 scoped_ptr<cricket::P2PTransportChannel> channel_;
112 int connect_attempts_left_;
113 base::RepeatingTimer reconnect_timer_;
114
115 base::WeakPtrFactory<LibjingleTransport> weak_factory_;
116
117 DISALLOW_COPY_AND_ASSIGN(LibjingleTransport);
118 };
119
120 LibjingleTransport::LibjingleTransport(cricket::PortAllocator* port_allocator,
121 const NetworkSettings& network_settings, 50 const NetworkSettings& network_settings,
122 TransportRole role) 51 TransportRole role)
123 : port_allocator_(port_allocator), 52 : port_allocator_(port_allocator),
124 network_settings_(network_settings), 53 network_settings_(network_settings),
125 role_(role), 54 role_(role),
126 event_handler_(nullptr), 55 delegate_(nullptr),
127 ice_username_fragment_( 56 ice_username_fragment_(
128 rtc::CreateRandomString(cricket::ICE_UFRAG_LENGTH)), 57 rtc::CreateRandomString(cricket::ICE_UFRAG_LENGTH)),
129 can_start_(false), 58 can_start_(false),
130 connect_attempts_left_(kMaxReconnectAttempts), 59 connect_attempts_left_(kMaxReconnectAttempts),
131 weak_factory_(this) { 60 weak_factory_(this) {
132 DCHECK(!ice_username_fragment_.empty()); 61 DCHECK(!ice_username_fragment_.empty());
133 } 62 }
134 63
135 LibjingleTransport::~LibjingleTransport() { 64 IceTransportChannel::~IceTransportChannel() {
136 DCHECK(event_handler_); 65 DCHECK(delegate_);
137 66
138 event_handler_->OnTransportDeleted(this); 67 delegate_->OnTransportDeleted(this);
139 68
140 if (channel_.get()) { 69 if (channel_.get()) {
141 base::ThreadTaskRunnerHandle::Get()->DeleteSoon( 70 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(
142 FROM_HERE, channel_.release()); 71 FROM_HERE, channel_.release());
143 } 72 }
144 } 73 }
145 74
146 void LibjingleTransport::OnCanStart() { 75 void IceTransportChannel::OnCanStart() {
147 DCHECK(CalledOnValidThread()); 76 DCHECK(thread_checker_.CalledOnValidThread());
148 77
149 DCHECK(!can_start_); 78 DCHECK(!can_start_);
150 can_start_ = true; 79 can_start_ = true;
151 80
152 // If Connect() has been called then start connection. 81 // If Connect() has been called then start connection.
153 if (!callback_.is_null()) 82 if (!callback_.is_null())
154 DoStart(); 83 DoStart();
155 84
156 // Pass pending ICE credentials and candidates to the channel. 85 // Pass pending ICE credentials and candidates to the channel.
157 if (!remote_ice_username_fragment_.empty()) { 86 if (!remote_ice_username_fragment_.empty()) {
158 channel_->SetRemoteIceCredentials(remote_ice_username_fragment_, 87 channel_->SetRemoteIceCredentials(remote_ice_username_fragment_,
159 remote_ice_password_); 88 remote_ice_password_);
160 } 89 }
161 90
162 while (!pending_candidates_.empty()) { 91 while (!pending_candidates_.empty()) {
163 channel_->AddRemoteCandidate(pending_candidates_.front()); 92 channel_->AddRemoteCandidate(pending_candidates_.front());
164 pending_candidates_.pop_front(); 93 pending_candidates_.pop_front();
165 } 94 }
166 } 95 }
167 96
168 void LibjingleTransport::Connect( 97 void IceTransportChannel::Connect(const std::string& name,
169 const std::string& name, 98 Delegate* delegate,
170 Transport::EventHandler* event_handler, 99 const ConnectedCallback& callback) {
171 const Transport::ConnectedCallback& callback) { 100 DCHECK(thread_checker_.CalledOnValidThread());
172 DCHECK(CalledOnValidThread());
173 DCHECK(!name.empty()); 101 DCHECK(!name.empty());
174 DCHECK(event_handler); 102 DCHECK(delegate);
175 DCHECK(!callback.is_null()); 103 DCHECK(!callback.is_null());
176 104
177 DCHECK(name_.empty()); 105 DCHECK(name_.empty());
178 name_ = name; 106 name_ = name;
179 event_handler_ = event_handler; 107 delegate_ = delegate;
180 callback_ = callback; 108 callback_ = callback;
181 109
182 if (can_start_) 110 if (can_start_)
183 DoStart(); 111 DoStart();
184 } 112 }
185 113
186 void LibjingleTransport::DoStart() { 114 void IceTransportChannel::DoStart() {
187 DCHECK(!channel_.get()); 115 DCHECK(!channel_.get());
188 116
189 // Create P2PTransportChannel, attach signal handlers and connect it. 117 // Create P2PTransportChannel, attach signal handlers and connect it.
190 // TODO(sergeyu): Specify correct component ID for the channel. 118 // TODO(sergeyu): Specify correct component ID for the channel.
191 channel_.reset(new cricket::P2PTransportChannel( 119 channel_.reset(new cricket::P2PTransportChannel(
192 std::string(), 0, nullptr, port_allocator_)); 120 std::string(), 0, nullptr, port_allocator_));
193 std::string ice_password = rtc::CreateRandomString(cricket::ICE_PWD_LENGTH); 121 std::string ice_password = rtc::CreateRandomString(cricket::ICE_PWD_LENGTH);
194 channel_->SetIceProtocolType(cricket::ICEPROTO_RFC5245); 122 channel_->SetIceProtocolType(cricket::ICEPROTO_RFC5245);
195 channel_->SetIceRole((role_ == TransportRole::CLIENT) 123 channel_->SetIceRole((role_ == TransportRole::CLIENT)
196 ? cricket::ICEROLE_CONTROLLING 124 ? cricket::ICEROLE_CONTROLLING
197 : cricket::ICEROLE_CONTROLLED); 125 : cricket::ICEROLE_CONTROLLED);
198 event_handler_->OnTransportIceCredentials(this, ice_username_fragment_, 126 delegate_->OnTransportIceCredentials(this, ice_username_fragment_,
199 ice_password); 127 ice_password);
200 channel_->SetIceCredentials(ice_username_fragment_, ice_password); 128 channel_->SetIceCredentials(ice_username_fragment_, ice_password);
201 channel_->SignalCandidateGathered.connect( 129 channel_->SignalCandidateGathered.connect(
202 this, &LibjingleTransport::OnCandidateGathered); 130 this, &IceTransportChannel::OnCandidateGathered);
203 channel_->SignalRouteChange.connect( 131 channel_->SignalRouteChange.connect(
204 this, &LibjingleTransport::OnRouteChange); 132 this, &IceTransportChannel::OnRouteChange);
205 channel_->SignalReceivingState.connect( 133 channel_->SignalReceivingState.connect(
206 this, &LibjingleTransport::OnReceivingState); 134 this, &IceTransportChannel::OnReceivingState);
207 channel_->SignalWritableState.connect( 135 channel_->SignalWritableState.connect(
208 this, &LibjingleTransport::OnWritableState); 136 this, &IceTransportChannel::OnWritableState);
209 channel_->set_incoming_only( 137 channel_->set_incoming_only(
210 !(network_settings_.flags & NetworkSettings::NAT_TRAVERSAL_OUTGOING)); 138 !(network_settings_.flags & NetworkSettings::NAT_TRAVERSAL_OUTGOING));
211 139
212 channel_->Connect(); 140 channel_->Connect();
213 channel_->MaybeStartGathering(); 141 channel_->MaybeStartGathering();
214 142
215 --connect_attempts_left_; 143 --connect_attempts_left_;
216 144
217 // Start reconnection timer. 145 // Start reconnection timer.
218 reconnect_timer_.Start( 146 reconnect_timer_.Start(
219 FROM_HERE, base::TimeDelta::FromSeconds(kReconnectDelaySeconds), 147 FROM_HERE, base::TimeDelta::FromSeconds(kReconnectDelaySeconds),
220 this, &LibjingleTransport::TryReconnect); 148 this, &IceTransportChannel::TryReconnect);
221 } 149 }
222 150
223 void LibjingleTransport::NotifyConnected() { 151 void IceTransportChannel::NotifyConnected() {
224 // Create P2PDatagramSocket adapter for the P2PTransportChannel. 152 // Create P2PDatagramSocket adapter for the P2PTransportChannel.
225 scoped_ptr<TransportChannelSocketAdapter> socket( 153 scoped_ptr<TransportChannelSocketAdapter> socket(
226 new TransportChannelSocketAdapter(channel_.get())); 154 new TransportChannelSocketAdapter(channel_.get()));
227 socket->SetOnDestroyedCallback(base::Bind( 155 socket->SetOnDestroyedCallback(base::Bind(
228 &LibjingleTransport::OnChannelDestroyed, base::Unretained(this))); 156 &IceTransportChannel::OnChannelDestroyed, base::Unretained(this)));
229 base::ResetAndReturn(&callback_).Run(socket.Pass()); 157 base::ResetAndReturn(&callback_).Run(socket.Pass());
230 } 158 }
231 159
232 void LibjingleTransport::SetRemoteCredentials(const std::string& ufrag, 160 void IceTransportChannel::SetRemoteCredentials(const std::string& ufrag,
233 const std::string& password) { 161 const std::string& password) {
234 DCHECK(CalledOnValidThread()); 162 DCHECK(thread_checker_.CalledOnValidThread());
235 163
236 remote_ice_username_fragment_ = ufrag; 164 remote_ice_username_fragment_ = ufrag;
237 remote_ice_password_ = password; 165 remote_ice_password_ = password;
238 166
239 if (channel_) 167 if (channel_)
240 channel_->SetRemoteIceCredentials(ufrag, password); 168 channel_->SetRemoteIceCredentials(ufrag, password);
241 } 169 }
242 170
243 void LibjingleTransport::AddRemoteCandidate( 171 void IceTransportChannel::AddRemoteCandidate(
244 const cricket::Candidate& candidate) { 172 const cricket::Candidate& candidate) {
245 DCHECK(CalledOnValidThread()); 173 DCHECK(thread_checker_.CalledOnValidThread());
246 174
247 // To enforce the no-relay setting, it's not enough to not produce relay 175 // To enforce the no-relay setting, it's not enough to not produce relay
248 // candidates. It's also necessary to discard remote relay candidates. 176 // candidates. It's also necessary to discard remote relay candidates.
249 bool relay_allowed = (network_settings_.flags & 177 bool relay_allowed = (network_settings_.flags &
250 NetworkSettings::NAT_TRAVERSAL_RELAY) != 0; 178 NetworkSettings::NAT_TRAVERSAL_RELAY) != 0;
251 if (!relay_allowed && candidate.type() == cricket::RELAY_PORT_TYPE) 179 if (!relay_allowed && candidate.type() == cricket::RELAY_PORT_TYPE)
252 return; 180 return;
253 181
254 if (channel_) { 182 if (channel_) {
255 channel_->AddRemoteCandidate(candidate); 183 channel_->AddRemoteCandidate(candidate);
256 } else { 184 } else {
257 pending_candidates_.push_back(candidate); 185 pending_candidates_.push_back(candidate);
258 } 186 }
259 } 187 }
260 188
261 const std::string& LibjingleTransport::name() const { 189 const std::string& IceTransportChannel::name() const {
262 DCHECK(CalledOnValidThread()); 190 DCHECK(thread_checker_.CalledOnValidThread());
263 return name_; 191 return name_;
264 } 192 }
265 193
266 bool LibjingleTransport::is_connected() const { 194 bool IceTransportChannel::is_connected() const {
267 DCHECK(CalledOnValidThread()); 195 DCHECK(thread_checker_.CalledOnValidThread());
268 return callback_.is_null(); 196 return callback_.is_null();
269 } 197 }
270 198
271 void LibjingleTransport::OnCandidateGathered( 199 void IceTransportChannel::OnCandidateGathered(
272 cricket::TransportChannelImpl* channel, 200 cricket::TransportChannelImpl* channel,
273 const cricket::Candidate& candidate) { 201 const cricket::Candidate& candidate) {
274 DCHECK(CalledOnValidThread()); 202 DCHECK(thread_checker_.CalledOnValidThread());
275 event_handler_->OnTransportCandidate(this, candidate); 203 delegate_->OnTransportCandidate(this, candidate);
276 } 204 }
277 205
278 void LibjingleTransport::OnRouteChange( 206 void IceTransportChannel::OnRouteChange(
279 cricket::TransportChannel* channel, 207 cricket::TransportChannel* channel,
280 const cricket::Candidate& candidate) { 208 const cricket::Candidate& candidate) {
281 // Ignore notifications if the channel is not writable. 209 // Ignore notifications if the channel is not writable.
282 if (channel_->writable()) 210 if (channel_->writable())
283 NotifyRouteChanged(); 211 NotifyRouteChanged();
284 } 212 }
285 213
286 void LibjingleTransport::OnReceivingState(cricket::TransportChannel* channel) { 214 void IceTransportChannel::OnReceivingState(cricket::TransportChannel* channel) {
287 DCHECK_EQ(channel, static_cast<cricket::TransportChannel*>(channel_.get())); 215 DCHECK_EQ(channel, static_cast<cricket::TransportChannel*>(channel_.get()));
288 216
289 if (channel->receiving() && !callback_.is_null()) 217 if (channel->receiving() && !callback_.is_null())
290 NotifyConnected(); 218 NotifyConnected();
291 } 219 }
292 220
293 void LibjingleTransport::OnWritableState(cricket::TransportChannel* channel) { 221 void IceTransportChannel::OnWritableState(cricket::TransportChannel* channel) {
294 DCHECK_EQ(channel, static_cast<cricket::TransportChannel*>(channel_.get())); 222 DCHECK_EQ(channel, static_cast<cricket::TransportChannel*>(channel_.get()));
295 223
296 if (channel->writable()) { 224 if (channel->writable()) {
297 connect_attempts_left_ = kMaxReconnectAttempts; 225 connect_attempts_left_ = kMaxReconnectAttempts;
298 reconnect_timer_.Stop(); 226 reconnect_timer_.Stop();
299 227
300 // Route change notifications are ignored when the |channel_| is not 228 // Route change notifications are ignored when the |channel_| is not
301 // writable. Notify the event handler about the current route once the 229 // writable. Notify the event handler about the current route once the
302 // channel is writable. 230 // channel is writable.
303 NotifyRouteChanged(); 231 NotifyRouteChanged();
304 } else { 232 } else {
305 reconnect_timer_.Reset(); 233 reconnect_timer_.Reset();
306 TryReconnect(); 234 TryReconnect();
307 } 235 }
308 } 236 }
309 237
310 void LibjingleTransport::OnChannelDestroyed() { 238 void IceTransportChannel::OnChannelDestroyed() {
311 // The connection socket is being deleted, so delete the transport too. 239 // The connection socket is being deleted, so delete the transport too.
312 delete this; 240 delete this;
313 } 241 }
314 242
315 void LibjingleTransport::NotifyRouteChanged() { 243 void IceTransportChannel::NotifyRouteChanged() {
316 TransportRoute route; 244 TransportRoute route;
317 245
318 DCHECK(channel_->best_connection()); 246 DCHECK(channel_->best_connection());
319 const cricket::Connection* connection = channel_->best_connection(); 247 const cricket::Connection* connection = channel_->best_connection();
320 248
321 // A connection has both a local and a remote candidate. For our purposes, the 249 // A connection has both a local and a remote candidate. For our purposes, the
322 // route type is determined by the most indirect candidate type. For example: 250 // route type is determined by the most indirect candidate type. For example:
323 // it's possible for the local candidate be a "relay" type, while the remote 251 // it's possible for the local candidate be a "relay" type, while the remote
324 // candidate is "local". In this case, we still want to report a RELAY route 252 // candidate is "local". In this case, we still want to report a RELAY route
325 // type. 253 // type.
326 static_assert(TransportRoute::DIRECT < TransportRoute::STUN && 254 static_assert(TransportRoute::DIRECT < TransportRoute::STUN &&
327 TransportRoute::STUN < TransportRoute::RELAY, 255 TransportRoute::STUN < TransportRoute::RELAY,
328 "Route type enum values are ordered by 'indirectness'"); 256 "Route type enum values are ordered by 'indirectness'");
329 route.type = std::max( 257 route.type = std::max(
330 CandidateTypeToTransportRouteType(connection->local_candidate().type()), 258 CandidateTypeToTransportRouteType(connection->local_candidate().type()),
331 CandidateTypeToTransportRouteType(connection->remote_candidate().type())); 259 CandidateTypeToTransportRouteType(connection->remote_candidate().type()));
332 260
333 if (!jingle_glue::SocketAddressToIPEndPoint( 261 if (!jingle_glue::SocketAddressToIPEndPoint(
334 connection->remote_candidate().address(), &route.remote_address)) { 262 connection->remote_candidate().address(), &route.remote_address)) {
335 LOG(FATAL) << "Failed to convert peer IP address."; 263 LOG(FATAL) << "Failed to convert peer IP address.";
336 } 264 }
337 265
338 const cricket::Candidate& local_candidate = 266 const cricket::Candidate& local_candidate =
339 channel_->best_connection()->local_candidate(); 267 channel_->best_connection()->local_candidate();
340 if (!jingle_glue::SocketAddressToIPEndPoint( 268 if (!jingle_glue::SocketAddressToIPEndPoint(
341 local_candidate.address(), &route.local_address)) { 269 local_candidate.address(), &route.local_address)) {
342 LOG(FATAL) << "Failed to convert local IP address."; 270 LOG(FATAL) << "Failed to convert local IP address.";
343 } 271 }
344 272
345 event_handler_->OnTransportRouteChange(this, route); 273 delegate_->OnTransportRouteChange(this, route);
346 } 274 }
347 275
348 void LibjingleTransport::TryReconnect() { 276 void IceTransportChannel::TryReconnect() {
349 DCHECK(!channel_->writable()); 277 DCHECK(!channel_->writable());
350 278
351 if (connect_attempts_left_ <= 0) { 279 if (connect_attempts_left_ <= 0) {
352 reconnect_timer_.Stop(); 280 reconnect_timer_.Stop();
353 281
354 // Notify the caller that ICE connection has failed - normally that will 282 // Notify the caller that ICE connection has failed - normally that will
355 // terminate Jingle connection (i.e. the transport will be destroyed). 283 // terminate Jingle connection (i.e. the transport will be destroyed).
356 event_handler_->OnTransportFailed(this); 284 delegate_->OnTransportFailed(this);
357 return; 285 return;
358 } 286 }
359 --connect_attempts_left_; 287 --connect_attempts_left_;
360 288
361 // Restart ICE by resetting ICE password. 289 // Restart ICE by resetting ICE password.
362 std::string ice_password = rtc::CreateRandomString(cricket::ICE_PWD_LENGTH); 290 std::string ice_password = rtc::CreateRandomString(cricket::ICE_PWD_LENGTH);
363 event_handler_->OnTransportIceCredentials(this, ice_username_fragment_, 291 delegate_->OnTransportIceCredentials(this, ice_username_fragment_,
364 ice_password); 292 ice_password);
365 channel_->SetIceCredentials(ice_username_fragment_, ice_password); 293 channel_->SetIceCredentials(ice_username_fragment_, ice_password);
366 } 294 }
367 295
368 } // namespace
369
370 LibjingleTransportFactory::LibjingleTransportFactory(
371 SignalStrategy* signal_strategy,
372 scoped_ptr<cricket::HttpPortAllocatorBase> port_allocator,
373 const NetworkSettings& network_settings,
374 TransportRole role)
375 : signal_strategy_(signal_strategy),
376 port_allocator_(port_allocator.Pass()),
377 network_settings_(network_settings),
378 role_(role) {
379 }
380
381 LibjingleTransportFactory::~LibjingleTransportFactory() {
382 // This method may be called in response to a libjingle signal, so
383 // libjingle objects must be deleted asynchronously.
384 scoped_refptr<base::SingleThreadTaskRunner> task_runner =
385 base::ThreadTaskRunnerHandle::Get();
386 task_runner->DeleteSoon(FROM_HERE, port_allocator_.release());
387 }
388
389 void LibjingleTransportFactory::PrepareTokens() {
390 EnsureFreshJingleInfo();
391 }
392
393 scoped_ptr<Transport> LibjingleTransportFactory::CreateTransport() {
394 scoped_ptr<LibjingleTransport> result(
395 new LibjingleTransport(port_allocator_.get(), network_settings_, role_));
396
397 EnsureFreshJingleInfo();
398
399 // If there is a pending |jingle_info_request_| delay starting the new
400 // transport until the request is finished.
401 if (jingle_info_request_) {
402 on_jingle_info_callbacks_.push_back(
403 base::Bind(&LibjingleTransport::OnCanStart,
404 result->AsWeakPtr()));
405 } else {
406 result->OnCanStart();
407 }
408
409 return result.Pass();
410 }
411
412 void LibjingleTransportFactory::EnsureFreshJingleInfo() {
413 uint32 stun_or_relay_flags = NetworkSettings::NAT_TRAVERSAL_STUN |
414 NetworkSettings::NAT_TRAVERSAL_RELAY;
415 if (!(network_settings_.flags & stun_or_relay_flags) ||
416 jingle_info_request_) {
417 return;
418 }
419
420 if (last_jingle_info_update_time_.is_null() ||
421 base::TimeTicks::Now() - last_jingle_info_update_time_ >
422 base::TimeDelta::FromSeconds(kJingleInfoUpdatePeriodSeconds)) {
423 jingle_info_request_.reset(new JingleInfoRequest(signal_strategy_));
424 jingle_info_request_->Send(base::Bind(
425 &LibjingleTransportFactory::OnJingleInfo, base::Unretained(this)));
426 }
427 }
428
429 void LibjingleTransportFactory::OnJingleInfo(
430 const std::string& relay_token,
431 const std::vector<std::string>& relay_hosts,
432 const std::vector<rtc::SocketAddress>& stun_hosts) {
433 if (!relay_token.empty() && !relay_hosts.empty()) {
434 port_allocator_->SetRelayHosts(relay_hosts);
435 port_allocator_->SetRelayToken(relay_token);
436 }
437 if (!stun_hosts.empty()) {
438 port_allocator_->SetStunHosts(stun_hosts);
439 }
440
441 jingle_info_request_.reset();
442 if ((!relay_token.empty() && !relay_hosts.empty()) || !stun_hosts.empty())
443 last_jingle_info_update_time_ = base::TimeTicks::Now();
444
445 while (!on_jingle_info_callbacks_.empty()) {
446 on_jingle_info_callbacks_.begin()->Run();
447 on_jingle_info_callbacks_.pop_front();
448 }
449 }
450
451 } // namespace protocol 296 } // namespace protocol
452 } // namespace remoting 297 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/protocol/ice_transport_channel.h ('k') | remoting/protocol/ice_transport_factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698