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