| 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/jingle_session.h" | 5 #include "remoting/protocol/jingle_session.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/rand_util.h" | 8 #include "base/rand_util.h" |
| 9 #include "base/single_thread_task_runner.h" | 9 #include "base/single_thread_task_runner.h" |
| 10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
| 11 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
| 12 #include "base/thread_task_runner_handle.h" | 12 #include "base/thread_task_runner_handle.h" |
| 13 #include "base/time/time.h" | 13 #include "base/time/time.h" |
| 14 #include "remoting/base/constants.h" | 14 #include "remoting/base/constants.h" |
| 15 #include "remoting/protocol/authenticator.h" | 15 #include "remoting/protocol/authenticator.h" |
| 16 #include "remoting/protocol/content_description.h" | 16 #include "remoting/protocol/content_description.h" |
| 17 #include "remoting/protocol/jingle_messages.h" | 17 #include "remoting/protocol/jingle_messages.h" |
| 18 #include "remoting/protocol/jingle_session_manager.h" | 18 #include "remoting/protocol/jingle_session_manager.h" |
| 19 #include "remoting/protocol/quic_channel_factory.h" | |
| 20 #include "remoting/protocol/session_config.h" | 19 #include "remoting/protocol/session_config.h" |
| 21 #include "remoting/signaling/iq_sender.h" | 20 #include "remoting/signaling/iq_sender.h" |
| 22 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h" | 21 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h" |
| 23 #include "third_party/webrtc/p2p/base/candidate.h" | 22 #include "third_party/webrtc/p2p/base/candidate.h" |
| 24 | 23 |
| 25 using buzz::XmlElement; | 24 using buzz::XmlElement; |
| 26 | 25 |
| 27 namespace remoting { | 26 namespace remoting { |
| 28 namespace protocol { | 27 namespace protocol { |
| 29 | 28 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 58 | 57 |
| 59 JingleSession::JingleSession(JingleSessionManager* session_manager) | 58 JingleSession::JingleSession(JingleSessionManager* session_manager) |
| 60 : session_manager_(session_manager), | 59 : session_manager_(session_manager), |
| 61 event_handler_(nullptr), | 60 event_handler_(nullptr), |
| 62 state_(INITIALIZING), | 61 state_(INITIALIZING), |
| 63 error_(OK), | 62 error_(OK), |
| 64 weak_factory_(this) { | 63 weak_factory_(this) { |
| 65 } | 64 } |
| 66 | 65 |
| 67 JingleSession::~JingleSession() { | 66 JingleSession::~JingleSession() { |
| 68 quic_channel_factory_.reset(); | |
| 69 transport_.reset(); | 67 transport_.reset(); |
| 70 | 68 |
| 71 STLDeleteContainerPointers(pending_requests_.begin(), | 69 STLDeleteContainerPointers(pending_requests_.begin(), |
| 72 pending_requests_.end()); | 70 pending_requests_.end()); |
| 73 STLDeleteContainerPointers(transport_info_requests_.begin(), | 71 STLDeleteContainerPointers(transport_info_requests_.begin(), |
| 74 transport_info_requests_.end()); | 72 transport_info_requests_.end()); |
| 75 | 73 |
| 76 session_manager_->SessionDestroyed(this); | 74 session_manager_->SessionDestroyed(this); |
| 77 } | 75 } |
| 78 | 76 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 96 peer_jid_ = peer_jid; | 94 peer_jid_ = peer_jid; |
| 97 authenticator_ = authenticator.Pass(); | 95 authenticator_ = authenticator.Pass(); |
| 98 | 96 |
| 99 // Generate random session ID. There are usually not more than 1 | 97 // Generate random session ID. There are usually not more than 1 |
| 100 // concurrent session per host, so a random 64-bit integer provides | 98 // concurrent session per host, so a random 64-bit integer provides |
| 101 // enough entropy. In the worst case connection will fail when two | 99 // enough entropy. In the worst case connection will fail when two |
| 102 // clients generate the same session ID concurrently. | 100 // clients generate the same session ID concurrently. |
| 103 session_id_ = base::Uint64ToString(base::RandGenerator(kuint64max)); | 101 session_id_ = base::Uint64ToString(base::RandGenerator(kuint64max)); |
| 104 | 102 |
| 105 transport_ = session_manager_->transport_factory_->CreateTransport(); | 103 transport_ = session_manager_->transport_factory_->CreateTransport(); |
| 106 quic_channel_factory_.reset(new QuicChannelFactory(session_id_, false)); | |
| 107 | 104 |
| 108 // Send session-initiate message. | 105 // Send session-initiate message. |
| 109 JingleMessage message(peer_jid_, JingleMessage::SESSION_INITIATE, | 106 JingleMessage message(peer_jid_, JingleMessage::SESSION_INITIATE, |
| 110 session_id_); | 107 session_id_); |
| 111 message.initiator = session_manager_->signal_strategy_->GetLocalJid(); | 108 message.initiator = session_manager_->signal_strategy_->GetLocalJid(); |
| 112 message.description.reset(new ContentDescription( | 109 message.description.reset(new ContentDescription( |
| 113 session_manager_->protocol_config_->Clone(), | 110 session_manager_->protocol_config_->Clone(), |
| 114 authenticator_->GetNextMessage(), | 111 authenticator_->GetNextMessage())); |
| 115 quic_channel_factory_->CreateSessionInitiateConfigMessage())); | |
| 116 SendMessage(message); | 112 SendMessage(message); |
| 117 | 113 |
| 118 SetState(CONNECTING); | 114 SetState(CONNECTING); |
| 119 } | 115 } |
| 120 | 116 |
| 121 void JingleSession::InitializeIncomingConnection( | 117 void JingleSession::InitializeIncomingConnection( |
| 122 const JingleMessage& initiate_message, | 118 const JingleMessage& initiate_message, |
| 123 scoped_ptr<Authenticator> authenticator) { | 119 scoped_ptr<Authenticator> authenticator) { |
| 124 DCHECK(CalledOnValidThread()); | 120 DCHECK(CalledOnValidThread()); |
| 125 DCHECK(initiate_message.description.get()); | 121 DCHECK(initiate_message.description.get()); |
| 126 DCHECK(authenticator.get()); | 122 DCHECK(authenticator.get()); |
| 127 DCHECK_EQ(authenticator->state(), Authenticator::WAITING_MESSAGE); | 123 DCHECK_EQ(authenticator->state(), Authenticator::WAITING_MESSAGE); |
| 128 | 124 |
| 129 peer_jid_ = initiate_message.from; | 125 peer_jid_ = initiate_message.from; |
| 130 authenticator_ = authenticator.Pass(); | 126 authenticator_ = authenticator.Pass(); |
| 131 session_id_ = initiate_message.sid; | 127 session_id_ = initiate_message.sid; |
| 132 | 128 |
| 133 SetState(ACCEPTING); | 129 SetState(ACCEPTING); |
| 134 | 130 |
| 135 config_ = | 131 config_ = |
| 136 SessionConfig::SelectCommon(initiate_message.description->config(), | 132 SessionConfig::SelectCommon(initiate_message.description->config(), |
| 137 session_manager_->protocol_config_.get()); | 133 session_manager_->protocol_config_.get()); |
| 138 if (!config_) { | 134 if (!config_) { |
| 139 LOG(WARNING) << "Rejecting connection from " << peer_jid_ | 135 LOG(WARNING) << "Rejecting connection from " << peer_jid_ |
| 140 << " because no compatible configuration has been found."; | 136 << " because no compatible configuration has been found."; |
| 141 Close(INCOMPATIBLE_PROTOCOL); | 137 Close(INCOMPATIBLE_PROTOCOL); |
| 142 return; | 138 return; |
| 143 } | 139 } |
| 144 | 140 |
| 145 if (config_->is_using_quic()) { | |
| 146 quic_channel_factory_.reset(new QuicChannelFactory(session_id_, true)); | |
| 147 if (!quic_channel_factory_->ProcessSessionInitiateConfigMessage( | |
| 148 initiate_message.description->quic_config_message())) { | |
| 149 Close(INCOMPATIBLE_PROTOCOL); | |
| 150 } | |
| 151 } | |
| 152 | |
| 153 transport_ = session_manager_->transport_factory_->CreateTransport(); | 141 transport_ = session_manager_->transport_factory_->CreateTransport(); |
| 154 } | 142 } |
| 155 | 143 |
| 156 void JingleSession::AcceptIncomingConnection( | 144 void JingleSession::AcceptIncomingConnection( |
| 157 const JingleMessage& initiate_message) { | 145 const JingleMessage& initiate_message) { |
| 158 DCHECK(config_); | 146 DCHECK(config_); |
| 159 | 147 |
| 160 // Process the first authentication message. | 148 // Process the first authentication message. |
| 161 const buzz::XmlElement* first_auth_message = | 149 const buzz::XmlElement* first_auth_message = |
| 162 initiate_message.description->authenticator_message(); | 150 initiate_message.description->authenticator_message(); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 181 } | 169 } |
| 182 | 170 |
| 183 // Send the session-accept message. | 171 // Send the session-accept message. |
| 184 JingleMessage message(peer_jid_, JingleMessage::SESSION_ACCEPT, | 172 JingleMessage message(peer_jid_, JingleMessage::SESSION_ACCEPT, |
| 185 session_id_); | 173 session_id_); |
| 186 | 174 |
| 187 scoped_ptr<buzz::XmlElement> auth_message; | 175 scoped_ptr<buzz::XmlElement> auth_message; |
| 188 if (authenticator_->state() == Authenticator::MESSAGE_READY) | 176 if (authenticator_->state() == Authenticator::MESSAGE_READY) |
| 189 auth_message = authenticator_->GetNextMessage(); | 177 auth_message = authenticator_->GetNextMessage(); |
| 190 | 178 |
| 191 std::string quic_config; | 179 message.description.reset(new ContentDescription( |
| 192 if (config_->is_using_quic()) | 180 CandidateSessionConfig::CreateFrom(*config_), auth_message.Pass())); |
| 193 quic_config = quic_channel_factory_->CreateSessionAcceptConfigMessage(); | |
| 194 message.description.reset( | |
| 195 new ContentDescription(CandidateSessionConfig::CreateFrom(*config_), | |
| 196 auth_message.Pass(), quic_config)); | |
| 197 SendMessage(message); | 181 SendMessage(message); |
| 198 | 182 |
| 199 // Update state. | 183 // Update state. |
| 200 SetState(ACCEPTED); | 184 SetState(ACCEPTED); |
| 201 | 185 |
| 202 if (authenticator_->state() == Authenticator::ACCEPTED) { | 186 if (authenticator_->state() == Authenticator::ACCEPTED) { |
| 203 OnAuthenticated(); | 187 OnAuthenticated(); |
| 204 } else { | 188 } else { |
| 205 DCHECK_EQ(authenticator_->state(), Authenticator::WAITING_MESSAGE); | 189 DCHECK_EQ(authenticator_->state(), Authenticator::WAITING_MESSAGE); |
| 206 if (authenticator_->started()) { | 190 if (authenticator_->started()) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 217 const SessionConfig& JingleSession::config() { | 201 const SessionConfig& JingleSession::config() { |
| 218 DCHECK(CalledOnValidThread()); | 202 DCHECK(CalledOnValidThread()); |
| 219 return *config_; | 203 return *config_; |
| 220 } | 204 } |
| 221 | 205 |
| 222 Transport* JingleSession::GetTransport() { | 206 Transport* JingleSession::GetTransport() { |
| 223 DCHECK(CalledOnValidThread()); | 207 DCHECK(CalledOnValidThread()); |
| 224 return transport_.get(); | 208 return transport_.get(); |
| 225 } | 209 } |
| 226 | 210 |
| 227 StreamChannelFactory* JingleSession::GetQuicChannelFactory() { | |
| 228 DCHECK(CalledOnValidThread()); | |
| 229 return quic_channel_factory_.get(); | |
| 230 } | |
| 231 | |
| 232 void JingleSession::Close(protocol::ErrorCode error) { | 211 void JingleSession::Close(protocol::ErrorCode error) { |
| 233 DCHECK(CalledOnValidThread()); | 212 DCHECK(CalledOnValidThread()); |
| 234 | 213 |
| 235 transport_.reset(); | 214 transport_.reset(); |
| 236 | 215 |
| 237 if (is_session_active()) { | 216 if (is_session_active()) { |
| 238 // Send session-terminate message with the appropriate error code. | 217 // Send session-terminate message with the appropriate error code. |
| 239 JingleMessage::Reason reason; | 218 JingleMessage::Reason reason; |
| 240 switch (error) { | 219 switch (error) { |
| 241 case OK: | 220 case OK: |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 DLOG(WARNING) << "Received session-accept without authentication message "; | 435 DLOG(WARNING) << "Received session-accept without authentication message "; |
| 457 Close(INCOMPATIBLE_PROTOCOL); | 436 Close(INCOMPATIBLE_PROTOCOL); |
| 458 return; | 437 return; |
| 459 } | 438 } |
| 460 | 439 |
| 461 if (!InitializeConfigFromDescription(message.description.get())) { | 440 if (!InitializeConfigFromDescription(message.description.get())) { |
| 462 Close(INCOMPATIBLE_PROTOCOL); | 441 Close(INCOMPATIBLE_PROTOCOL); |
| 463 return; | 442 return; |
| 464 } | 443 } |
| 465 | 444 |
| 466 if (config_->is_using_quic()) { | |
| 467 if (!quic_channel_factory_->ProcessSessionAcceptConfigMessage( | |
| 468 message.description->quic_config_message())) { | |
| 469 Close(INCOMPATIBLE_PROTOCOL); | |
| 470 return; | |
| 471 } | |
| 472 } else { | |
| 473 quic_channel_factory_.reset(); | |
| 474 } | |
| 475 | |
| 476 SetState(ACCEPTED); | 445 SetState(ACCEPTED); |
| 477 | 446 |
| 478 DCHECK(authenticator_->state() == Authenticator::WAITING_MESSAGE); | 447 DCHECK(authenticator_->state() == Authenticator::WAITING_MESSAGE); |
| 479 authenticator_->ProcessMessage(auth_message, base::Bind( | 448 authenticator_->ProcessMessage(auth_message, base::Bind( |
| 480 &JingleSession::ProcessAuthenticationStep,base::Unretained(this))); | 449 &JingleSession::ProcessAuthenticationStep,base::Unretained(this))); |
| 481 } | 450 } |
| 482 | 451 |
| 483 void JingleSession::OnSessionInfo(const JingleMessage& message, | 452 void JingleSession::OnSessionInfo(const JingleMessage& message, |
| 484 const ReplyCallback& reply_callback) { | 453 const ReplyCallback& reply_callback) { |
| 485 if (!message.info.get() || | 454 if (!message.info.get() || |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 604 OnAuthenticated(); | 573 OnAuthenticated(); |
| 605 } else if (authenticator_->state() == Authenticator::REJECTED) { | 574 } else if (authenticator_->state() == Authenticator::REJECTED) { |
| 606 Close(AuthRejectionReasonToErrorCode( | 575 Close(AuthRejectionReasonToErrorCode( |
| 607 authenticator_->rejection_reason())); | 576 authenticator_->rejection_reason())); |
| 608 } | 577 } |
| 609 } | 578 } |
| 610 | 579 |
| 611 void JingleSession::OnAuthenticated() { | 580 void JingleSession::OnAuthenticated() { |
| 612 transport_->Start(this, authenticator_.get()); | 581 transport_->Start(this, authenticator_.get()); |
| 613 | 582 |
| 614 if (quic_channel_factory_) { | |
| 615 quic_channel_factory_->Start(transport_->GetDatagramChannelFactory(), | |
| 616 authenticator_->GetAuthKey()); | |
| 617 } | |
| 618 | |
| 619 SetState(AUTHENTICATED); | 583 SetState(AUTHENTICATED); |
| 620 } | 584 } |
| 621 | 585 |
| 622 void JingleSession::SetState(State new_state) { | 586 void JingleSession::SetState(State new_state) { |
| 623 DCHECK(CalledOnValidThread()); | 587 DCHECK(CalledOnValidThread()); |
| 624 | 588 |
| 625 if (new_state != state_) { | 589 if (new_state != state_) { |
| 626 DCHECK_NE(state_, CLOSED); | 590 DCHECK_NE(state_, CLOSED); |
| 627 DCHECK_NE(state_, FAILED); | 591 DCHECK_NE(state_, FAILED); |
| 628 | 592 |
| 629 state_ = new_state; | 593 state_ = new_state; |
| 630 if (event_handler_) | 594 if (event_handler_) |
| 631 event_handler_->OnSessionStateChange(new_state); | 595 event_handler_->OnSessionStateChange(new_state); |
| 632 } | 596 } |
| 633 } | 597 } |
| 634 | 598 |
| 635 bool JingleSession::is_session_active() { | 599 bool JingleSession::is_session_active() { |
| 636 return state_ == CONNECTING || state_ == ACCEPTING || state_ == ACCEPTED || | 600 return state_ == CONNECTING || state_ == ACCEPTING || state_ == ACCEPTED || |
| 637 state_ == AUTHENTICATING || state_ == AUTHENTICATED; | 601 state_ == AUTHENTICATING || state_ == AUTHENTICATED; |
| 638 } | 602 } |
| 639 | 603 |
| 640 } // namespace protocol | 604 } // namespace protocol |
| 641 } // namespace remoting | 605 } // namespace remoting |
| OLD | NEW |