| 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 <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <limits> | 9 #include <limits> |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 return error_; | 89 return error_; |
| 90 } | 90 } |
| 91 | 91 |
| 92 void JingleSession::StartConnection( | 92 void JingleSession::StartConnection( |
| 93 const std::string& peer_jid, | 93 const std::string& peer_jid, |
| 94 std::unique_ptr<Authenticator> authenticator) { | 94 std::unique_ptr<Authenticator> authenticator) { |
| 95 DCHECK(thread_checker_.CalledOnValidThread()); | 95 DCHECK(thread_checker_.CalledOnValidThread()); |
| 96 DCHECK(authenticator.get()); | 96 DCHECK(authenticator.get()); |
| 97 DCHECK_EQ(authenticator->state(), Authenticator::MESSAGE_READY); | 97 DCHECK_EQ(authenticator->state(), Authenticator::MESSAGE_READY); |
| 98 | 98 |
| 99 peer_jid_ = peer_jid; | 99 peer_ = Address(peer_jid); |
| 100 authenticator_ = std::move(authenticator); | 100 authenticator_ = std::move(authenticator); |
| 101 | 101 |
| 102 // Generate random session ID. There are usually not more than 1 | 102 // Generate random session ID. There are usually not more than 1 |
| 103 // concurrent session per host, so a random 64-bit integer provides | 103 // concurrent session per host, so a random 64-bit integer provides |
| 104 // enough entropy. In the worst case connection will fail when two | 104 // enough entropy. In the worst case connection will fail when two |
| 105 // clients generate the same session ID concurrently. | 105 // clients generate the same session ID concurrently. |
| 106 session_id_ = base::Uint64ToString( | 106 session_id_ = base::Uint64ToString( |
| 107 base::RandGenerator(std::numeric_limits<uint64_t>::max())); | 107 base::RandGenerator(std::numeric_limits<uint64_t>::max())); |
| 108 | 108 |
| 109 // Send session-initiate message. | 109 // Send session-initiate message. |
| 110 JingleMessage message(peer_jid_, JingleMessage::SESSION_INITIATE, | 110 JingleMessage message(peer_, JingleMessage::SESSION_INITIATE, |
| 111 session_id_); | 111 session_id_); |
| 112 message.initiator = session_manager_->signal_strategy_->GetLocalJid(); | 112 message.initiator = session_manager_->signal_strategy_->GetLocalJid(); |
| 113 message.description.reset(new ContentDescription( | 113 message.description.reset(new ContentDescription( |
| 114 session_manager_->protocol_config_->Clone(), | 114 session_manager_->protocol_config_->Clone(), |
| 115 authenticator_->GetNextMessage())); | 115 authenticator_->GetNextMessage())); |
| 116 SendMessage(message); | 116 SendMessage(message); |
| 117 | 117 |
| 118 SetState(CONNECTING); | 118 SetState(CONNECTING); |
| 119 } | 119 } |
| 120 | 120 |
| 121 void JingleSession::InitializeIncomingConnection( | 121 void JingleSession::InitializeIncomingConnection( |
| 122 const JingleMessage& initiate_message, | 122 const JingleMessage& initiate_message, |
| 123 std::unique_ptr<Authenticator> authenticator) { | 123 std::unique_ptr<Authenticator> authenticator) { |
| 124 DCHECK(thread_checker_.CalledOnValidThread()); | 124 DCHECK(thread_checker_.CalledOnValidThread()); |
| 125 DCHECK(initiate_message.description.get()); | 125 DCHECK(initiate_message.description.get()); |
| 126 DCHECK(authenticator.get()); | 126 DCHECK(authenticator.get()); |
| 127 DCHECK_EQ(authenticator->state(), Authenticator::WAITING_MESSAGE); | 127 DCHECK_EQ(authenticator->state(), Authenticator::WAITING_MESSAGE); |
| 128 | 128 |
| 129 peer_jid_ = initiate_message.from; | 129 peer_ = initiate_message.from; |
| 130 authenticator_ = std::move(authenticator); | 130 authenticator_ = std::move(authenticator); |
| 131 session_id_ = initiate_message.sid; | 131 session_id_ = initiate_message.sid; |
| 132 | 132 |
| 133 SetState(ACCEPTING); | 133 SetState(ACCEPTING); |
| 134 | 134 |
| 135 config_ = | 135 config_ = |
| 136 SessionConfig::SelectCommon(initiate_message.description->config(), | 136 SessionConfig::SelectCommon(initiate_message.description->config(), |
| 137 session_manager_->protocol_config_.get()); | 137 session_manager_->protocol_config_.get()); |
| 138 if (!config_) { | 138 if (!config_) { |
| 139 LOG(WARNING) << "Rejecting connection from " << peer_jid_ | 139 LOG(WARNING) << "Rejecting connection from " << peer_.endpoint_id |
| 140 << " because no compatible configuration has been found."; | 140 << " because no compatible configuration has been found."; |
| 141 Close(INCOMPATIBLE_PROTOCOL); | 141 Close(INCOMPATIBLE_PROTOCOL); |
| 142 return; | 142 return; |
| 143 } | 143 } |
| 144 } | 144 } |
| 145 | 145 |
| 146 void JingleSession::AcceptIncomingConnection( | 146 void JingleSession::AcceptIncomingConnection( |
| 147 const JingleMessage& initiate_message) { | 147 const JingleMessage& initiate_message) { |
| 148 DCHECK(config_); | 148 DCHECK(config_); |
| 149 | 149 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 164 } | 164 } |
| 165 | 165 |
| 166 void JingleSession::ContinueAcceptIncomingConnection() { | 166 void JingleSession::ContinueAcceptIncomingConnection() { |
| 167 DCHECK_NE(authenticator_->state(), Authenticator::PROCESSING_MESSAGE); | 167 DCHECK_NE(authenticator_->state(), Authenticator::PROCESSING_MESSAGE); |
| 168 if (authenticator_->state() == Authenticator::REJECTED) { | 168 if (authenticator_->state() == Authenticator::REJECTED) { |
| 169 Close(AuthRejectionReasonToErrorCode(authenticator_->rejection_reason())); | 169 Close(AuthRejectionReasonToErrorCode(authenticator_->rejection_reason())); |
| 170 return; | 170 return; |
| 171 } | 171 } |
| 172 | 172 |
| 173 // Send the session-accept message. | 173 // Send the session-accept message. |
| 174 JingleMessage message(peer_jid_, JingleMessage::SESSION_ACCEPT, | 174 JingleMessage message(peer_, JingleMessage::SESSION_ACCEPT, |
| 175 session_id_); | 175 session_id_); |
| 176 | 176 |
| 177 std::unique_ptr<buzz::XmlElement> auth_message; | 177 std::unique_ptr<buzz::XmlElement> auth_message; |
| 178 if (authenticator_->state() == Authenticator::MESSAGE_READY) | 178 if (authenticator_->state() == Authenticator::MESSAGE_READY) |
| 179 auth_message = authenticator_->GetNextMessage(); | 179 auth_message = authenticator_->GetNextMessage(); |
| 180 | 180 |
| 181 message.description.reset(new ContentDescription( | 181 message.description.reset(new ContentDescription( |
| 182 CandidateSessionConfig::CreateFrom(*config_), std::move(auth_message))); | 182 CandidateSessionConfig::CreateFrom(*config_), std::move(auth_message))); |
| 183 SendMessage(message); | 183 SendMessage(message); |
| 184 | 184 |
| 185 // Update state. | 185 // Update state. |
| 186 SetState(ACCEPTED); | 186 SetState(ACCEPTED); |
| 187 | 187 |
| 188 if (authenticator_->state() == Authenticator::ACCEPTED) { | 188 if (authenticator_->state() == Authenticator::ACCEPTED) { |
| 189 OnAuthenticated(); | 189 OnAuthenticated(); |
| 190 } else { | 190 } else { |
| 191 DCHECK_EQ(authenticator_->state(), Authenticator::WAITING_MESSAGE); | 191 DCHECK_EQ(authenticator_->state(), Authenticator::WAITING_MESSAGE); |
| 192 if (authenticator_->started()) { | 192 if (authenticator_->started()) { |
| 193 SetState(AUTHENTICATING); | 193 SetState(AUTHENTICATING); |
| 194 } | 194 } |
| 195 } | 195 } |
| 196 } | 196 } |
| 197 | 197 |
| 198 const std::string& JingleSession::jid() { | 198 const std::string& JingleSession::jid() { |
| 199 DCHECK(thread_checker_.CalledOnValidThread()); | 199 DCHECK(thread_checker_.CalledOnValidThread()); |
| 200 return peer_jid_; | 200 // Returns the |endpoint_id| instead of the |jid| it uniquely identifies the |
| 201 // peer. |
| 202 return peer_.endpoint_id; |
| 201 } | 203 } |
| 202 | 204 |
| 203 const SessionConfig& JingleSession::config() { | 205 const SessionConfig& JingleSession::config() { |
| 204 DCHECK(thread_checker_.CalledOnValidThread()); | 206 DCHECK(thread_checker_.CalledOnValidThread()); |
| 205 return *config_; | 207 return *config_; |
| 206 } | 208 } |
| 207 | 209 |
| 208 void JingleSession::SetTransport(Transport* transport) { | 210 void JingleSession::SetTransport(Transport* transport) { |
| 209 DCHECK(thread_checker_.CalledOnValidThread()); | 211 DCHECK(thread_checker_.CalledOnValidThread()); |
| 210 DCHECK(!transport_); | 212 DCHECK(!transport_); |
| 211 DCHECK(transport); | 213 DCHECK(transport); |
| 212 transport_ = transport; | 214 transport_ = transport; |
| 213 } | 215 } |
| 214 | 216 |
| 215 void JingleSession::SendTransportInfo( | 217 void JingleSession::SendTransportInfo( |
| 216 std::unique_ptr<buzz::XmlElement> transport_info) { | 218 std::unique_ptr<buzz::XmlElement> transport_info) { |
| 217 DCHECK(thread_checker_.CalledOnValidThread()); | 219 DCHECK(thread_checker_.CalledOnValidThread()); |
| 218 DCHECK_EQ(state_, AUTHENTICATED); | 220 DCHECK_EQ(state_, AUTHENTICATED); |
| 219 | 221 |
| 220 JingleMessage message(peer_jid_, JingleMessage::TRANSPORT_INFO, session_id_); | 222 JingleMessage message(peer_, JingleMessage::TRANSPORT_INFO, session_id_); |
| 221 message.transport_info = std::move(transport_info); | 223 message.transport_info = std::move(transport_info); |
| 222 | 224 |
| 223 std::unique_ptr<IqRequest> request = session_manager_->iq_sender()->SendIq( | 225 std::unique_ptr<IqRequest> request = session_manager_->iq_sender()->SendIq( |
| 224 message.ToXml(), base::Bind(&JingleSession::OnTransportInfoResponse, | 226 message.ToXml(), base::Bind(&JingleSession::OnTransportInfoResponse, |
| 225 base::Unretained(this))); | 227 base::Unretained(this))); |
| 226 if (request) { | 228 if (request) { |
| 227 request->SetTimeout(base::TimeDelta::FromSeconds(kTransportInfoTimeout)); | 229 request->SetTimeout(base::TimeDelta::FromSeconds(kTransportInfoTimeout)); |
| 228 transport_info_requests_.push_back(request.release()); | 230 transport_info_requests_.push_back(request.release()); |
| 229 } else { | 231 } else { |
| 230 LOG(ERROR) << "Failed to send a transport-info message"; | 232 LOG(ERROR) << "Failed to send a transport-info message"; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 254 case MAX_SESSION_LENGTH: | 256 case MAX_SESSION_LENGTH: |
| 255 reason = JingleMessage::EXPIRED; | 257 reason = JingleMessage::EXPIRED; |
| 256 break; | 258 break; |
| 257 case HOST_CONFIGURATION_ERROR: | 259 case HOST_CONFIGURATION_ERROR: |
| 258 reason = JingleMessage::FAILED_APPLICATION; | 260 reason = JingleMessage::FAILED_APPLICATION; |
| 259 break; | 261 break; |
| 260 default: | 262 default: |
| 261 reason = JingleMessage::GENERAL_ERROR; | 263 reason = JingleMessage::GENERAL_ERROR; |
| 262 } | 264 } |
| 263 | 265 |
| 264 JingleMessage message(peer_jid_, JingleMessage::SESSION_TERMINATE, | 266 JingleMessage message(peer_, JingleMessage::SESSION_TERMINATE, session_id_); |
| 265 session_id_); | |
| 266 message.reason = reason; | 267 message.reason = reason; |
| 267 SendMessage(message); | 268 SendMessage(message); |
| 268 } | 269 } |
| 269 | 270 |
| 270 error_ = error; | 271 error_ = error; |
| 271 | 272 |
| 272 if (state_ != FAILED && state_ != CLOSED) { | 273 if (state_ != FAILED && state_ != CLOSED) { |
| 273 if (error != OK) { | 274 if (error != OK) { |
| 274 SetState(FAILED); | 275 SetState(FAILED); |
| 275 } else { | 276 } else { |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 LOG(ERROR) << "Received error in response to transport-info message: \"" | 364 LOG(ERROR) << "Received error in response to transport-info message: \"" |
| 364 << response->Str() << "\". Terminating the session."; | 365 << response->Str() << "\". Terminating the session."; |
| 365 Close(PEER_IS_OFFLINE); | 366 Close(PEER_IS_OFFLINE); |
| 366 } | 367 } |
| 367 } | 368 } |
| 368 | 369 |
| 369 void JingleSession::OnIncomingMessage(const JingleMessage& message, | 370 void JingleSession::OnIncomingMessage(const JingleMessage& message, |
| 370 const ReplyCallback& reply_callback) { | 371 const ReplyCallback& reply_callback) { |
| 371 DCHECK(thread_checker_.CalledOnValidThread()); | 372 DCHECK(thread_checker_.CalledOnValidThread()); |
| 372 | 373 |
| 373 if (message.from != peer_jid_) { | 374 if (peer_ != message.from) { |
| 374 // Ignore messages received from a different Jid. | 375 // Ignore messages received from a different Jid. |
| 375 reply_callback.Run(JingleMessageReply::INVALID_SID); | 376 reply_callback.Run(JingleMessageReply::INVALID_SID); |
| 376 return; | 377 return; |
| 377 } | 378 } |
| 378 | 379 |
| 379 switch (message.action) { | 380 switch (message.action) { |
| 380 case JingleMessage::SESSION_ACCEPT: | 381 case JingleMessage::SESSION_ACCEPT: |
| 381 OnAccept(message, reply_callback); | 382 OnAccept(message, reply_callback); |
| 382 break; | 383 break; |
| 383 | 384 |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 DCHECK_NE(authenticator_->state(), Authenticator::PROCESSING_MESSAGE); | 532 DCHECK_NE(authenticator_->state(), Authenticator::PROCESSING_MESSAGE); |
| 532 | 533 |
| 533 if (state_ != ACCEPTED && state_ != AUTHENTICATING) { | 534 if (state_ != ACCEPTED && state_ != AUTHENTICATING) { |
| 534 DCHECK(state_ == FAILED || state_ == CLOSED); | 535 DCHECK(state_ == FAILED || state_ == CLOSED); |
| 535 // The remote host closed the connection while the authentication was being | 536 // The remote host closed the connection while the authentication was being |
| 536 // processed asynchronously, nothing to do. | 537 // processed asynchronously, nothing to do. |
| 537 return; | 538 return; |
| 538 } | 539 } |
| 539 | 540 |
| 540 if (authenticator_->state() == Authenticator::MESSAGE_READY) { | 541 if (authenticator_->state() == Authenticator::MESSAGE_READY) { |
| 541 JingleMessage message(peer_jid_, JingleMessage::SESSION_INFO, session_id_); | 542 JingleMessage message(peer_, JingleMessage::SESSION_INFO, session_id_); |
| 542 message.info = authenticator_->GetNextMessage(); | 543 message.info = authenticator_->GetNextMessage(); |
| 543 DCHECK(message.info.get()); | 544 DCHECK(message.info.get()); |
| 544 SendMessage(message); | 545 SendMessage(message); |
| 545 } | 546 } |
| 546 DCHECK_NE(authenticator_->state(), Authenticator::MESSAGE_READY); | 547 DCHECK_NE(authenticator_->state(), Authenticator::MESSAGE_READY); |
| 547 | 548 |
| 548 // The current JingleSession object can be destroyed by event_handler of | 549 // The current JingleSession object can be destroyed by event_handler of |
| 549 // SetState(AUTHENTICATING) and cause subsequent dereferencing of the this | 550 // SetState(AUTHENTICATING) and cause subsequent dereferencing of the this |
| 550 // pointer to crash. To protect against it, we run ContinueAuthenticationStep | 551 // pointer to crash. To protect against it, we run ContinueAuthenticationStep |
| 551 // asychronously using a weak pointer. | 552 // asychronously using a weak pointer. |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 589 } | 590 } |
| 590 } | 591 } |
| 591 | 592 |
| 592 bool JingleSession::is_session_active() { | 593 bool JingleSession::is_session_active() { |
| 593 return state_ == CONNECTING || state_ == ACCEPTING || state_ == ACCEPTED || | 594 return state_ == CONNECTING || state_ == ACCEPTING || state_ == ACCEPTED || |
| 594 state_ == AUTHENTICATING || state_ == AUTHENTICATED; | 595 state_ == AUTHENTICATING || state_ == AUTHENTICATED; |
| 595 } | 596 } |
| 596 | 597 |
| 597 } // namespace protocol | 598 } // namespace protocol |
| 598 } // namespace remoting | 599 } // namespace remoting |
| OLD | NEW |