| 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/stl_util.h" | 9 #include "base/stl_util.h" |
| 10 #include "base/string_number_conversions.h" | 10 #include "base/string_number_conversions.h" |
| 11 #include "base/time.h" | 11 #include "base/time.h" |
| 12 #include "remoting/base/constants.h" | 12 #include "remoting/base/constants.h" |
| 13 #include "remoting/jingle_glue/iq_sender.h" | 13 #include "remoting/jingle_glue/iq_sender.h" |
| 14 #include "remoting/protocol/authenticator.h" | 14 #include "remoting/protocol/authenticator.h" |
| 15 #include "remoting/protocol/channel_authenticator.h" | 15 #include "remoting/protocol/channel_authenticator.h" |
| 16 #include "remoting/protocol/channel_multiplexer.h" |
| 16 #include "remoting/protocol/content_description.h" | 17 #include "remoting/protocol/content_description.h" |
| 17 #include "remoting/protocol/jingle_messages.h" | 18 #include "remoting/protocol/jingle_messages.h" |
| 18 #include "remoting/protocol/jingle_session_manager.h" | 19 #include "remoting/protocol/jingle_session_manager.h" |
| 19 #include "remoting/protocol/session_config.h" | 20 #include "remoting/protocol/session_config.h" |
| 20 #include "third_party/libjingle/source/talk/p2p/base/candidate.h" | 21 #include "third_party/libjingle/source/talk/p2p/base/candidate.h" |
| 21 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" | 22 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" |
| 22 | 23 |
| 23 using buzz::XmlElement; | 24 using buzz::XmlElement; |
| 24 | 25 |
| 25 namespace remoting { | 26 namespace remoting { |
| 26 namespace protocol { | 27 namespace protocol { |
| 27 | 28 |
| 28 namespace { | 29 namespace { |
| 29 // Delay after candidate creation before sending transport-info | 30 // Delay after candidate creation before sending transport-info |
| 30 // message. This is neccessary to be able to pack multiple candidates | 31 // message. This is neccessary to be able to pack multiple candidates |
| 31 // into one transport-info messages. The value needs to be greater | 32 // into one transport-info messages. The value needs to be greater |
| 32 // than zero because ports are opened asynchronously in the browser | 33 // than zero because ports are opened asynchronously in the browser |
| 33 // process. | 34 // process. |
| 34 const int kTransportInfoSendDelayMs = 2; | 35 const int kTransportInfoSendDelayMs = 2; |
| 35 | 36 |
| 36 // How long we should wait for a response from the other end. This | 37 // How long we should wait for a response from the other end. This |
| 37 // value is used for all requests include |session-initiate| and | 38 // value is used for all requests include |session-initiate| and |
| 38 // |transport-info|. | 39 // |transport-info|. |
| 39 const int kMessageResponseTimeoutSeconds = 10; | 40 const int kMessageResponseTimeoutSeconds = 10; |
| 40 | 41 |
| 42 // Name of the multiplexed channel. |
| 43 const char kMuxChannelName[] = "mux"; |
| 44 |
| 41 ErrorCode AuthRejectionReasonToErrorCode( | 45 ErrorCode AuthRejectionReasonToErrorCode( |
| 42 Authenticator::RejectionReason reason) { | 46 Authenticator::RejectionReason reason) { |
| 43 switch (reason) { | 47 switch (reason) { |
| 44 case Authenticator::INVALID_CREDENTIALS: | 48 case Authenticator::INVALID_CREDENTIALS: |
| 45 return AUTHENTICATION_FAILED; | 49 return AUTHENTICATION_FAILED; |
| 46 case Authenticator::PROTOCOL_ERROR: | 50 case Authenticator::PROTOCOL_ERROR: |
| 47 return INCOMPATIBLE_PROTOCOL; | 51 return INCOMPATIBLE_PROTOCOL; |
| 48 } | 52 } |
| 49 NOTREACHED(); | 53 NOTREACHED(); |
| 50 return UNKNOWN_ERROR; | 54 return UNKNOWN_ERROR; |
| 51 } | 55 } |
| 52 | 56 |
| 53 } // namespace | 57 } // namespace |
| 54 | 58 |
| 55 JingleSession::JingleSession(JingleSessionManager* session_manager) | 59 JingleSession::JingleSession(JingleSessionManager* session_manager) |
| 56 : session_manager_(session_manager), | 60 : session_manager_(session_manager), |
| 57 event_handler_(NULL), | 61 event_handler_(NULL), |
| 58 state_(INITIALIZING), | 62 state_(INITIALIZING), |
| 59 error_(OK), | 63 error_(OK), |
| 60 config_is_set_(false) { | 64 config_is_set_(false) { |
| 61 } | 65 } |
| 62 | 66 |
| 63 JingleSession::~JingleSession() { | 67 JingleSession::~JingleSession() { |
| 68 channel_multiplexer_.reset(); |
| 64 STLDeleteContainerPointers(pending_requests_.begin(), | 69 STLDeleteContainerPointers(pending_requests_.begin(), |
| 65 pending_requests_.end()); | 70 pending_requests_.end()); |
| 66 STLDeleteContainerPairSecondPointers(channels_.begin(), channels_.end()); | 71 STLDeleteContainerPairSecondPointers(channels_.begin(), channels_.end()); |
| 67 session_manager_->SessionDestroyed(this); | 72 session_manager_->SessionDestroyed(this); |
| 68 } | 73 } |
| 69 | 74 |
| 70 void JingleSession::SetEventHandler(Session::EventHandler* event_handler) { | 75 void JingleSession::SetEventHandler(Session::EventHandler* event_handler) { |
| 71 DCHECK(CalledOnValidThread()); | 76 DCHECK(CalledOnValidThread()); |
| 72 DCHECK(event_handler); | 77 DCHECK(event_handler); |
| 73 event_handler_ = event_handler; | 78 event_handler_ = event_handler; |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 | 168 |
| 164 if (authenticator_->state() == Authenticator::ACCEPTED) { | 169 if (authenticator_->state() == Authenticator::ACCEPTED) { |
| 165 SetState(AUTHENTICATED); | 170 SetState(AUTHENTICATED); |
| 166 } else { | 171 } else { |
| 167 DCHECK_EQ(authenticator_->state(), Authenticator::WAITING_MESSAGE); | 172 DCHECK_EQ(authenticator_->state(), Authenticator::WAITING_MESSAGE); |
| 168 } | 173 } |
| 169 | 174 |
| 170 return; | 175 return; |
| 171 } | 176 } |
| 172 | 177 |
| 178 const std::string& JingleSession::jid() { |
| 179 DCHECK(CalledOnValidThread()); |
| 180 return peer_jid_; |
| 181 } |
| 182 |
| 183 const CandidateSessionConfig* JingleSession::candidate_config() { |
| 184 DCHECK(CalledOnValidThread()); |
| 185 return candidate_config_.get(); |
| 186 } |
| 187 |
| 188 const SessionConfig& JingleSession::config() { |
| 189 DCHECK(CalledOnValidThread()); |
| 190 return config_; |
| 191 } |
| 192 |
| 193 void JingleSession::set_config(const SessionConfig& config) { |
| 194 DCHECK(CalledOnValidThread()); |
| 195 DCHECK(!config_is_set_); |
| 196 config_ = config; |
| 197 config_is_set_ = true; |
| 198 } |
| 199 |
| 200 ChannelFactory* JingleSession::GetTransportChannelFactory() { |
| 201 DCHECK(CalledOnValidThread()); |
| 202 return this; |
| 203 } |
| 204 |
| 205 ChannelFactory* JingleSession::GetMultiplexedChannelFactory() { |
| 206 DCHECK(CalledOnValidThread()); |
| 207 if (!channel_multiplexer_.get()) |
| 208 channel_multiplexer_.reset(new ChannelMultiplexer(this, kMuxChannelName)); |
| 209 return channel_multiplexer_.get(); |
| 210 } |
| 211 |
| 212 void JingleSession::Close() { |
| 213 DCHECK(CalledOnValidThread()); |
| 214 |
| 215 CloseInternal(OK); |
| 216 } |
| 217 |
| 173 void JingleSession::CreateStreamChannel( | 218 void JingleSession::CreateStreamChannel( |
| 174 const std::string& name, | 219 const std::string& name, |
| 175 const StreamChannelCallback& callback) { | 220 const StreamChannelCallback& callback) { |
| 176 DCHECK(!channels_[name]); | 221 DCHECK(!channels_[name]); |
| 177 | 222 |
| 178 scoped_ptr<ChannelAuthenticator> channel_authenticator = | 223 scoped_ptr<ChannelAuthenticator> channel_authenticator = |
| 179 authenticator_->CreateChannelAuthenticator(); | 224 authenticator_->CreateChannelAuthenticator(); |
| 180 scoped_ptr<StreamTransport> channel = | 225 scoped_ptr<StreamTransport> channel = |
| 181 session_manager_->transport_factory_->CreateStreamTransport(); | 226 session_manager_->transport_factory_->CreateStreamTransport(); |
| 182 channel->Initialize(name, this, channel_authenticator.Pass()); | 227 channel->Initialize(name, this, channel_authenticator.Pass()); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 199 } | 244 } |
| 200 | 245 |
| 201 void JingleSession::CancelChannelCreation(const std::string& name) { | 246 void JingleSession::CancelChannelCreation(const std::string& name) { |
| 202 ChannelsMap::iterator it = channels_.find(name); | 247 ChannelsMap::iterator it = channels_.find(name); |
| 203 if (it != channels_.end() && !it->second->is_connected()) { | 248 if (it != channels_.end() && !it->second->is_connected()) { |
| 204 delete it->second; | 249 delete it->second; |
| 205 DCHECK(!channels_[name]); | 250 DCHECK(!channels_[name]); |
| 206 } | 251 } |
| 207 } | 252 } |
| 208 | 253 |
| 209 const std::string& JingleSession::jid() { | |
| 210 DCHECK(CalledOnValidThread()); | |
| 211 return peer_jid_; | |
| 212 } | |
| 213 | |
| 214 const CandidateSessionConfig* JingleSession::candidate_config() { | |
| 215 DCHECK(CalledOnValidThread()); | |
| 216 return candidate_config_.get(); | |
| 217 } | |
| 218 | |
| 219 const SessionConfig& JingleSession::config() { | |
| 220 DCHECK(CalledOnValidThread()); | |
| 221 return config_; | |
| 222 } | |
| 223 | |
| 224 void JingleSession::set_config(const SessionConfig& config) { | |
| 225 DCHECK(CalledOnValidThread()); | |
| 226 DCHECK(!config_is_set_); | |
| 227 config_ = config; | |
| 228 config_is_set_ = true; | |
| 229 } | |
| 230 | |
| 231 void JingleSession::Close() { | |
| 232 DCHECK(CalledOnValidThread()); | |
| 233 | |
| 234 CloseInternal(OK); | |
| 235 } | |
| 236 | |
| 237 void JingleSession::OnTransportCandidate(Transport* transport, | 254 void JingleSession::OnTransportCandidate(Transport* transport, |
| 238 const cricket::Candidate& candidate) { | 255 const cricket::Candidate& candidate) { |
| 239 pending_candidates_.push_back(JingleMessage::NamedCandidate( | 256 pending_candidates_.push_back(JingleMessage::NamedCandidate( |
| 240 transport->name(), candidate)); | 257 transport->name(), candidate)); |
| 241 | 258 |
| 242 if (!transport_infos_timer_.IsRunning()) { | 259 if (!transport_infos_timer_.IsRunning()) { |
| 243 // Delay sending the new candidates in case we get more candidates | 260 // Delay sending the new candidates in case we get more candidates |
| 244 // that we can send in one message. | 261 // that we can send in one message. |
| 245 transport_infos_timer_.Start( | 262 transport_infos_timer_.Start( |
| 246 FROM_HERE, base::TimeDelta::FromMilliseconds(kTransportInfoSendDelayMs), | 263 FROM_HERE, base::TimeDelta::FromMilliseconds(kTransportInfoSendDelayMs), |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 577 DCHECK_NE(state_, FAILED); | 594 DCHECK_NE(state_, FAILED); |
| 578 | 595 |
| 579 state_ = new_state; | 596 state_ = new_state; |
| 580 if (event_handler_) | 597 if (event_handler_) |
| 581 event_handler_->OnSessionStateChange(new_state); | 598 event_handler_->OnSessionStateChange(new_state); |
| 582 } | 599 } |
| 583 } | 600 } |
| 584 | 601 |
| 585 } // namespace protocol | 602 } // namespace protocol |
| 586 } // namespace remoting | 603 } // namespace remoting |
| OLD | NEW |