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/protocol/libjingle_transport_factory.h" | 5 #include "remoting/protocol/libjingle_transport_factory.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/callback.h" | 9 #include "base/callback.h" |
10 #include "base/single_thread_task_runner.h" | 10 #include "base/single_thread_task_runner.h" |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 void OnCandidateReady(cricket::TransportChannelImpl* channel, | 79 void OnCandidateReady(cricket::TransportChannelImpl* channel, |
80 const cricket::Candidate& candidate); | 80 const cricket::Candidate& candidate); |
81 void OnRouteChange(cricket::TransportChannel* channel, | 81 void OnRouteChange(cricket::TransportChannel* channel, |
82 const cricket::Candidate& candidate); | 82 const cricket::Candidate& candidate); |
83 void OnWritableState(cricket::TransportChannel* channel); | 83 void OnWritableState(cricket::TransportChannel* channel); |
84 | 84 |
85 // Callback for jingle_glue::TransportChannelSocketAdapter to notify when the | 85 // Callback for jingle_glue::TransportChannelSocketAdapter to notify when the |
86 // socket is destroyed. | 86 // socket is destroyed. |
87 void OnChannelDestroyed(); | 87 void OnChannelDestroyed(); |
88 | 88 |
| 89 void NotifyRouteChanged(); |
| 90 |
89 // Tries to connect by restarting ICE. Called by |reconnect_timer_|. | 91 // Tries to connect by restarting ICE. Called by |reconnect_timer_|. |
90 void TryReconnect(); | 92 void TryReconnect(); |
91 | 93 |
92 cricket::PortAllocator* port_allocator_; | 94 cricket::PortAllocator* port_allocator_; |
93 NetworkSettings network_settings_; | 95 NetworkSettings network_settings_; |
94 | 96 |
95 std::string name_; | 97 std::string name_; |
96 EventHandler* event_handler_; | 98 EventHandler* event_handler_; |
97 Transport::ConnectedCallback callback_; | 99 Transport::ConnectedCallback callback_; |
98 std::string ice_username_fragment_; | 100 std::string ice_username_fragment_; |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 void LibjingleTransport::OnCandidateReady( | 253 void LibjingleTransport::OnCandidateReady( |
252 cricket::TransportChannelImpl* channel, | 254 cricket::TransportChannelImpl* channel, |
253 const cricket::Candidate& candidate) { | 255 const cricket::Candidate& candidate) { |
254 DCHECK(CalledOnValidThread()); | 256 DCHECK(CalledOnValidThread()); |
255 event_handler_->OnTransportCandidate(this, candidate); | 257 event_handler_->OnTransportCandidate(this, candidate); |
256 } | 258 } |
257 | 259 |
258 void LibjingleTransport::OnRouteChange( | 260 void LibjingleTransport::OnRouteChange( |
259 cricket::TransportChannel* channel, | 261 cricket::TransportChannel* channel, |
260 const cricket::Candidate& candidate) { | 262 const cricket::Candidate& candidate) { |
| 263 // Ignore notifications if the channel is not writable. |
| 264 if (channel_->writable()) |
| 265 NotifyRouteChanged(); |
| 266 } |
| 267 |
| 268 void LibjingleTransport::OnWritableState( |
| 269 cricket::TransportChannel* channel) { |
| 270 DCHECK_EQ(channel, channel_.get()); |
| 271 |
| 272 if (channel->writable()) { |
| 273 if (!channel_was_writable_) { |
| 274 channel_was_writable_ = true; |
| 275 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 276 FROM_HERE, |
| 277 base::Bind(&LibjingleTransport::NotifyConnected, |
| 278 weak_factory_.GetWeakPtr())); |
| 279 } |
| 280 connect_attempts_left_ = kMaxReconnectAttempts; |
| 281 reconnect_timer_.Stop(); |
| 282 |
| 283 // Route change notifications are ignored when the |channel_| is not |
| 284 // writable. Notify the event handler about the current route once the |
| 285 // channel is writable. |
| 286 NotifyRouteChanged(); |
| 287 } else if (!channel->writable() && channel_was_writable_) { |
| 288 reconnect_timer_.Reset(); |
| 289 TryReconnect(); |
| 290 } |
| 291 } |
| 292 |
| 293 void LibjingleTransport::OnChannelDestroyed() { |
| 294 if (is_connected()) { |
| 295 // The connection socket is being deleted, so delete the transport too. |
| 296 delete this; |
| 297 } |
| 298 } |
| 299 |
| 300 void LibjingleTransport::NotifyRouteChanged() { |
261 TransportRoute route; | 301 TransportRoute route; |
262 | 302 |
263 DCHECK(channel_->best_connection()); | 303 DCHECK(channel_->best_connection()); |
264 const cricket::Connection* connection = channel_->best_connection(); | 304 const cricket::Connection* connection = channel_->best_connection(); |
265 | 305 |
266 // A connection has both a local and a remote candidate. For our purposes, the | 306 // A connection has both a local and a remote candidate. For our purposes, the |
267 // route type is determined by the most indirect candidate type. For example: | 307 // route type is determined by the most indirect candidate type. For example: |
268 // it's possible for the local candidate be a "relay" type, while the remote | 308 // it's possible for the local candidate be a "relay" type, while the remote |
269 // candidate is "local". In this case, we still want to report a RELAY route | 309 // candidate is "local". In this case, we still want to report a RELAY route |
270 // type. | 310 // type. |
271 static_assert(TransportRoute::DIRECT < TransportRoute::STUN && | 311 static_assert(TransportRoute::DIRECT < TransportRoute::STUN && |
272 TransportRoute::STUN < TransportRoute::RELAY, | 312 TransportRoute::STUN < TransportRoute::RELAY, |
273 "Route type enum values are ordered by 'indirectness'"); | 313 "Route type enum values are ordered by 'indirectness'"); |
274 route.type = std::max( | 314 route.type = std::max( |
275 CandidateTypeToTransportRouteType(connection->local_candidate().type()), | 315 CandidateTypeToTransportRouteType(connection->local_candidate().type()), |
276 CandidateTypeToTransportRouteType(connection->remote_candidate().type())); | 316 CandidateTypeToTransportRouteType(connection->remote_candidate().type())); |
277 | 317 |
278 if (!jingle_glue::SocketAddressToIPEndPoint( | 318 if (!jingle_glue::SocketAddressToIPEndPoint( |
279 candidate.address(), &route.remote_address)) { | 319 connection->remote_candidate().address(), &route.remote_address)) { |
280 LOG(FATAL) << "Failed to convert peer IP address."; | 320 LOG(FATAL) << "Failed to convert peer IP address."; |
281 } | 321 } |
282 | 322 |
283 const cricket::Candidate& local_candidate = | 323 const cricket::Candidate& local_candidate = |
284 channel_->best_connection()->local_candidate(); | 324 channel_->best_connection()->local_candidate(); |
285 if (!jingle_glue::SocketAddressToIPEndPoint( | 325 if (!jingle_glue::SocketAddressToIPEndPoint( |
286 local_candidate.address(), &route.local_address)) { | 326 local_candidate.address(), &route.local_address)) { |
287 LOG(FATAL) << "Failed to convert local IP address."; | 327 LOG(FATAL) << "Failed to convert local IP address."; |
288 } | 328 } |
289 | 329 |
290 event_handler_->OnTransportRouteChange(this, route); | 330 event_handler_->OnTransportRouteChange(this, route); |
291 } | 331 } |
292 | 332 |
293 void LibjingleTransport::OnWritableState( | |
294 cricket::TransportChannel* channel) { | |
295 DCHECK_EQ(channel, channel_.get()); | |
296 | |
297 if (channel->writable()) { | |
298 if (!channel_was_writable_) { | |
299 channel_was_writable_ = true; | |
300 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
301 FROM_HERE, | |
302 base::Bind(&LibjingleTransport::NotifyConnected, | |
303 weak_factory_.GetWeakPtr())); | |
304 } | |
305 connect_attempts_left_ = kMaxReconnectAttempts; | |
306 reconnect_timer_.Stop(); | |
307 } else if (!channel->writable() && channel_was_writable_) { | |
308 reconnect_timer_.Reset(); | |
309 TryReconnect(); | |
310 } | |
311 } | |
312 | |
313 void LibjingleTransport::OnChannelDestroyed() { | |
314 if (is_connected()) { | |
315 // The connection socket is being deleted, so delete the transport too. | |
316 delete this; | |
317 } | |
318 } | |
319 | |
320 void LibjingleTransport::TryReconnect() { | 333 void LibjingleTransport::TryReconnect() { |
321 DCHECK(!channel_->writable()); | 334 DCHECK(!channel_->writable()); |
322 | 335 |
323 if (connect_attempts_left_ <= 0) { | 336 if (connect_attempts_left_ <= 0) { |
324 reconnect_timer_.Stop(); | 337 reconnect_timer_.Stop(); |
325 | 338 |
326 // Notify the caller that ICE connection has failed - normally that will | 339 // Notify the caller that ICE connection has failed - normally that will |
327 // terminate Jingle connection (i.e. the transport will be destroyed). | 340 // terminate Jingle connection (i.e. the transport will be destroyed). |
328 event_handler_->OnTransportFailed(this); | 341 event_handler_->OnTransportFailed(this); |
329 return; | 342 return; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
410 last_jingle_info_update_time_ = base::TimeTicks::Now(); | 423 last_jingle_info_update_time_ = base::TimeTicks::Now(); |
411 | 424 |
412 while (!on_jingle_info_callbacks_.empty()) { | 425 while (!on_jingle_info_callbacks_.empty()) { |
413 on_jingle_info_callbacks_.begin()->Run(); | 426 on_jingle_info_callbacks_.begin()->Run(); |
414 on_jingle_info_callbacks_.pop_front(); | 427 on_jingle_info_callbacks_.pop_front(); |
415 } | 428 } |
416 } | 429 } |
417 | 430 |
418 } // namespace protocol | 431 } // namespace protocol |
419 } // namespace remoting | 432 } // namespace remoting |
OLD | NEW |