| 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/channel_authenticator.h" | |
| 17 #include "remoting/protocol/channel_multiplexer.h" | |
| 18 #include "remoting/protocol/content_description.h" | 16 #include "remoting/protocol/content_description.h" |
| 19 #include "remoting/protocol/jingle_messages.h" | 17 #include "remoting/protocol/jingle_messages.h" |
| 20 #include "remoting/protocol/jingle_session_manager.h" | 18 #include "remoting/protocol/jingle_session_manager.h" |
| 21 #include "remoting/protocol/pseudotcp_channel_factory.h" | |
| 22 #include "remoting/protocol/quic_channel_factory.h" | 19 #include "remoting/protocol/quic_channel_factory.h" |
| 23 #include "remoting/protocol/secure_channel_factory.h" | |
| 24 #include "remoting/protocol/session_config.h" | 20 #include "remoting/protocol/session_config.h" |
| 25 #include "remoting/protocol/stream_channel_factory.h" | |
| 26 #include "remoting/signaling/iq_sender.h" | 21 #include "remoting/signaling/iq_sender.h" |
| 27 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h" | 22 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h" |
| 28 #include "third_party/webrtc/p2p/base/candidate.h" | 23 #include "third_party/webrtc/p2p/base/candidate.h" |
| 29 | 24 |
| 30 using buzz::XmlElement; | 25 using buzz::XmlElement; |
| 31 | 26 |
| 32 namespace remoting { | 27 namespace remoting { |
| 33 namespace protocol { | 28 namespace protocol { |
| 34 | 29 |
| 35 namespace { | 30 namespace { |
| 36 | 31 |
| 37 // Delay after candidate creation before sending transport-info message to | |
| 38 // accumulate multiple candidates. This is an optimization to reduce number of | |
| 39 // transport-info messages. | |
| 40 const int kTransportInfoSendDelayMs = 20; | |
| 41 | |
| 42 // How long we should wait for a response from the other end. This value is used | 32 // How long we should wait for a response from the other end. This value is used |
| 43 // for all requests except |transport-info|. | 33 // for all requests except |transport-info|. |
| 44 const int kDefaultMessageTimeout = 10; | 34 const int kDefaultMessageTimeout = 10; |
| 45 | 35 |
| 46 // During a reconnection, it usually takes longer for the peer to respond due to | 36 // During a reconnection, it usually takes longer for the peer to respond due to |
| 47 // pending messages in the channel from the previous session. From experiment, | 37 // pending messages in the channel from the previous session. From experiment, |
| 48 // it can take up to 20s for the session to reconnect. To make it safe, setting | 38 // it can take up to 20s for the session to reconnect. To make it safe, setting |
| 49 // the timeout to 30s. | 39 // the timeout to 30s. |
| 50 const int kSessionInitiateAndAcceptTimeout = kDefaultMessageTimeout * 3; | 40 const int kSessionInitiateAndAcceptTimeout = kDefaultMessageTimeout * 3; |
| 51 | 41 |
| 52 // Timeout for the transport-info messages. | 42 // Timeout for the transport-info messages. |
| 53 const int kTransportInfoTimeout = 10 * 60; | 43 const int kTransportInfoTimeout = 10 * 60; |
| 54 | 44 |
| 55 // Name of the multiplexed channel. | |
| 56 const char kMuxChannelName[] = "mux"; | |
| 57 | |
| 58 ErrorCode AuthRejectionReasonToErrorCode( | 45 ErrorCode AuthRejectionReasonToErrorCode( |
| 59 Authenticator::RejectionReason reason) { | 46 Authenticator::RejectionReason reason) { |
| 60 switch (reason) { | 47 switch (reason) { |
| 61 case Authenticator::INVALID_CREDENTIALS: | 48 case Authenticator::INVALID_CREDENTIALS: |
| 62 return AUTHENTICATION_FAILED; | 49 return AUTHENTICATION_FAILED; |
| 63 case Authenticator::PROTOCOL_ERROR: | 50 case Authenticator::PROTOCOL_ERROR: |
| 64 return INCOMPATIBLE_PROTOCOL; | 51 return INCOMPATIBLE_PROTOCOL; |
| 65 } | 52 } |
| 66 NOTREACHED(); | 53 NOTREACHED(); |
| 67 return UNKNOWN_ERROR; | 54 return UNKNOWN_ERROR; |
| 68 } | 55 } |
| 69 | 56 |
| 70 } // namespace | 57 } // namespace |
| 71 | 58 |
| 72 JingleSession::JingleSession(JingleSessionManager* session_manager) | 59 JingleSession::JingleSession(JingleSessionManager* session_manager) |
| 73 : session_manager_(session_manager), | 60 : session_manager_(session_manager), |
| 74 event_handler_(nullptr), | 61 event_handler_(nullptr), |
| 75 state_(INITIALIZING), | 62 state_(INITIALIZING), |
| 76 error_(OK), | 63 error_(OK), |
| 77 weak_factory_(this) { | 64 weak_factory_(this) { |
| 78 } | 65 } |
| 79 | 66 |
| 80 JingleSession::~JingleSession() { | 67 JingleSession::~JingleSession() { |
| 81 channel_multiplexer_.reset(); | |
| 82 quic_channel_factory_.reset(); | 68 quic_channel_factory_.reset(); |
| 69 transport_session_.reset(); |
| 70 |
| 83 STLDeleteContainerPointers(pending_requests_.begin(), | 71 STLDeleteContainerPointers(pending_requests_.begin(), |
| 84 pending_requests_.end()); | 72 pending_requests_.end()); |
| 85 STLDeleteContainerPointers(transport_info_requests_.begin(), | 73 STLDeleteContainerPointers(transport_info_requests_.begin(), |
| 86 transport_info_requests_.end()); | 74 transport_info_requests_.end()); |
| 87 | 75 |
| 88 DCHECK(channels_.empty()); | |
| 89 | |
| 90 session_manager_->SessionDestroyed(this); | 76 session_manager_->SessionDestroyed(this); |
| 91 } | 77 } |
| 92 | 78 |
| 93 void JingleSession::SetEventHandler(Session::EventHandler* event_handler) { | 79 void JingleSession::SetEventHandler(Session::EventHandler* event_handler) { |
| 94 DCHECK(CalledOnValidThread()); | 80 DCHECK(CalledOnValidThread()); |
| 95 DCHECK(event_handler); | 81 DCHECK(event_handler); |
| 96 event_handler_ = event_handler; | 82 event_handler_ = event_handler; |
| 97 } | 83 } |
| 98 | 84 |
| 99 ErrorCode JingleSession::error() { | 85 ErrorCode JingleSession::error() { |
| 100 DCHECK(CalledOnValidThread()); | 86 DCHECK(CalledOnValidThread()); |
| 101 return error_; | 87 return error_; |
| 102 } | 88 } |
| 103 | 89 |
| 104 void JingleSession::StartConnection(const std::string& peer_jid, | 90 void JingleSession::StartConnection(const std::string& peer_jid, |
| 105 scoped_ptr<Authenticator> authenticator) { | 91 scoped_ptr<Authenticator> authenticator) { |
| 106 DCHECK(CalledOnValidThread()); | 92 DCHECK(CalledOnValidThread()); |
| 107 DCHECK(authenticator.get()); | 93 DCHECK(authenticator.get()); |
| 108 DCHECK_EQ(authenticator->state(), Authenticator::MESSAGE_READY); | 94 DCHECK_EQ(authenticator->state(), Authenticator::MESSAGE_READY); |
| 109 | 95 |
| 110 peer_jid_ = peer_jid; | 96 peer_jid_ = peer_jid; |
| 111 authenticator_ = authenticator.Pass(); | 97 authenticator_ = authenticator.Pass(); |
| 112 | 98 |
| 113 // Generate random session ID. There are usually not more than 1 | 99 // Generate random session ID. There are usually not more than 1 |
| 114 // concurrent session per host, so a random 64-bit integer provides | 100 // concurrent session per host, so a random 64-bit integer provides |
| 115 // enough entropy. In the worst case connection will fail when two | 101 // enough entropy. In the worst case connection will fail when two |
| 116 // clients generate the same session ID concurrently. | 102 // clients generate the same session ID concurrently. |
| 117 session_id_ = base::Uint64ToString(base::RandGenerator(kuint64max)); | 103 session_id_ = base::Uint64ToString(base::RandGenerator(kuint64max)); |
| 118 | 104 |
| 105 transport_session_ = |
| 106 session_manager_->transport_factory_->CreateTransportSession(); |
| 119 quic_channel_factory_.reset(new QuicChannelFactory(session_id_, false)); | 107 quic_channel_factory_.reset(new QuicChannelFactory(session_id_, false)); |
| 120 | 108 |
| 121 // Send session-initiate message. | 109 // Send session-initiate message. |
| 122 JingleMessage message(peer_jid_, JingleMessage::SESSION_INITIATE, | 110 JingleMessage message(peer_jid_, JingleMessage::SESSION_INITIATE, |
| 123 session_id_); | 111 session_id_); |
| 124 message.initiator = session_manager_->signal_strategy_->GetLocalJid(); | 112 message.initiator = session_manager_->signal_strategy_->GetLocalJid(); |
| 125 message.description.reset(new ContentDescription( | 113 message.description.reset(new ContentDescription( |
| 126 session_manager_->protocol_config_->Clone(), | 114 session_manager_->protocol_config_->Clone(), |
| 127 authenticator_->GetNextMessage(), | 115 authenticator_->GetNextMessage(), |
| 128 quic_channel_factory_->CreateSessionInitiateConfigMessage())); | 116 quic_channel_factory_->CreateSessionInitiateConfigMessage())); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 155 return; | 143 return; |
| 156 } | 144 } |
| 157 | 145 |
| 158 if (config_->is_using_quic()) { | 146 if (config_->is_using_quic()) { |
| 159 quic_channel_factory_.reset(new QuicChannelFactory(session_id_, true)); | 147 quic_channel_factory_.reset(new QuicChannelFactory(session_id_, true)); |
| 160 if (!quic_channel_factory_->ProcessSessionInitiateConfigMessage( | 148 if (!quic_channel_factory_->ProcessSessionInitiateConfigMessage( |
| 161 initiate_message.description->quic_config_message())) { | 149 initiate_message.description->quic_config_message())) { |
| 162 CloseInternal(INCOMPATIBLE_PROTOCOL); | 150 CloseInternal(INCOMPATIBLE_PROTOCOL); |
| 163 } | 151 } |
| 164 } | 152 } |
| 153 |
| 154 transport_session_ = |
| 155 session_manager_->transport_factory_->CreateTransportSession(); |
| 165 } | 156 } |
| 166 | 157 |
| 167 void JingleSession::AcceptIncomingConnection( | 158 void JingleSession::AcceptIncomingConnection( |
| 168 const JingleMessage& initiate_message) { | 159 const JingleMessage& initiate_message) { |
| 169 DCHECK(config_); | 160 DCHECK(config_); |
| 170 | 161 |
| 171 // Process the first authentication message. | 162 // Process the first authentication message. |
| 172 const buzz::XmlElement* first_auth_message = | 163 const buzz::XmlElement* first_auth_message = |
| 173 initiate_message.description->authenticator_message(); | 164 initiate_message.description->authenticator_message(); |
| 174 | 165 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 const std::string& JingleSession::jid() { | 215 const std::string& JingleSession::jid() { |
| 225 DCHECK(CalledOnValidThread()); | 216 DCHECK(CalledOnValidThread()); |
| 226 return peer_jid_; | 217 return peer_jid_; |
| 227 } | 218 } |
| 228 | 219 |
| 229 const SessionConfig& JingleSession::config() { | 220 const SessionConfig& JingleSession::config() { |
| 230 DCHECK(CalledOnValidThread()); | 221 DCHECK(CalledOnValidThread()); |
| 231 return *config_; | 222 return *config_; |
| 232 } | 223 } |
| 233 | 224 |
| 234 StreamChannelFactory* JingleSession::GetTransportChannelFactory() { | 225 TransportSession* JingleSession::GetTransportSession() { |
| 235 DCHECK(CalledOnValidThread()); | 226 DCHECK(CalledOnValidThread()); |
| 236 return secure_channel_factory_.get(); | 227 return transport_session_.get(); |
| 237 } | |
| 238 | |
| 239 StreamChannelFactory* JingleSession::GetMultiplexedChannelFactory() { | |
| 240 DCHECK(CalledOnValidThread()); | |
| 241 if (!channel_multiplexer_.get()) { | |
| 242 channel_multiplexer_.reset( | |
| 243 new ChannelMultiplexer(GetTransportChannelFactory(), kMuxChannelName)); | |
| 244 } | |
| 245 return channel_multiplexer_.get(); | |
| 246 } | 228 } |
| 247 | 229 |
| 248 StreamChannelFactory* JingleSession::GetQuicChannelFactory() { | 230 StreamChannelFactory* JingleSession::GetQuicChannelFactory() { |
| 249 DCHECK(CalledOnValidThread()); | 231 DCHECK(CalledOnValidThread()); |
| 250 return quic_channel_factory_.get(); | 232 return quic_channel_factory_.get(); |
| 251 } | 233 } |
| 252 | 234 |
| 253 void JingleSession::Close() { | 235 void JingleSession::Close() { |
| 254 DCHECK(CalledOnValidThread()); | 236 DCHECK(CalledOnValidThread()); |
| 255 | 237 |
| 256 CloseInternal(OK); | 238 CloseInternal(OK); |
| 257 } | 239 } |
| 258 | 240 |
| 259 void JingleSession::AddPendingRemoteTransportInfo(Transport* channel) { | |
| 260 std::list<JingleMessage::IceCredentials>::iterator credentials = | |
| 261 pending_remote_ice_credentials_.begin(); | |
| 262 while (credentials != pending_remote_ice_credentials_.end()) { | |
| 263 if (credentials->channel == channel->name()) { | |
| 264 channel->SetRemoteCredentials(credentials->ufrag, credentials->password); | |
| 265 credentials = pending_remote_ice_credentials_.erase(credentials); | |
| 266 } else { | |
| 267 ++credentials; | |
| 268 } | |
| 269 } | |
| 270 | |
| 271 std::list<JingleMessage::NamedCandidate>::iterator candidate = | |
| 272 pending_remote_candidates_.begin(); | |
| 273 while (candidate != pending_remote_candidates_.end()) { | |
| 274 if (candidate->name == channel->name()) { | |
| 275 channel->AddRemoteCandidate(candidate->candidate); | |
| 276 candidate = pending_remote_candidates_.erase(candidate); | |
| 277 } else { | |
| 278 ++candidate; | |
| 279 } | |
| 280 } | |
| 281 } | |
| 282 | |
| 283 void JingleSession::CreateChannel(const std::string& name, | |
| 284 const ChannelCreatedCallback& callback) { | |
| 285 DCHECK(!channels_[name]); | |
| 286 | |
| 287 scoped_ptr<Transport> channel = | |
| 288 session_manager_->transport_factory_->CreateTransport(); | |
| 289 channel->Connect(name, this, callback); | |
| 290 AddPendingRemoteTransportInfo(channel.get()); | |
| 291 channels_[name] = channel.release(); | |
| 292 } | |
| 293 | |
| 294 void JingleSession::CancelChannelCreation(const std::string& name) { | |
| 295 ChannelsMap::iterator it = channels_.find(name); | |
| 296 if (it != channels_.end()) { | |
| 297 DCHECK(!it->second->is_connected()); | |
| 298 delete it->second; | |
| 299 DCHECK(channels_.find(name) == channels_.end()); | |
| 300 } | |
| 301 } | |
| 302 | |
| 303 void JingleSession::OnTransportIceCredentials(Transport* transport, | |
| 304 const std::string& ufrag, | |
| 305 const std::string& password) { | |
| 306 EnsurePendingTransportInfoMessage(); | |
| 307 pending_transport_info_message_->ice_credentials.push_back( | |
| 308 JingleMessage::IceCredentials(transport->name(), ufrag, password)); | |
| 309 } | |
| 310 | |
| 311 void JingleSession::OnTransportCandidate(Transport* transport, | |
| 312 const cricket::Candidate& candidate) { | |
| 313 EnsurePendingTransportInfoMessage(); | |
| 314 pending_transport_info_message_->candidates.push_back( | |
| 315 JingleMessage::NamedCandidate(transport->name(), candidate)); | |
| 316 } | |
| 317 | |
| 318 void JingleSession::OnTransportRouteChange(Transport* transport, | |
| 319 const TransportRoute& route) { | |
| 320 if (event_handler_) | |
| 321 event_handler_->OnSessionRouteChange(transport->name(), route); | |
| 322 } | |
| 323 | |
| 324 void JingleSession::OnTransportFailed(Transport* transport) { | |
| 325 CloseInternal(CHANNEL_CONNECTION_ERROR); | |
| 326 } | |
| 327 | |
| 328 void JingleSession::OnTransportDeleted(Transport* transport) { | |
| 329 ChannelsMap::iterator it = channels_.find(transport->name()); | |
| 330 DCHECK_EQ(it->second, transport); | |
| 331 channels_.erase(it); | |
| 332 } | |
| 333 | |
| 334 void JingleSession::SendMessage(const JingleMessage& message) { | 241 void JingleSession::SendMessage(const JingleMessage& message) { |
| 335 scoped_ptr<IqRequest> request = session_manager_->iq_sender()->SendIq( | 242 scoped_ptr<IqRequest> request = session_manager_->iq_sender()->SendIq( |
| 336 message.ToXml(), | 243 message.ToXml(), |
| 337 base::Bind(&JingleSession::OnMessageResponse, | 244 base::Bind(&JingleSession::OnMessageResponse, |
| 338 base::Unretained(this), | 245 base::Unretained(this), |
| 339 message.action)); | 246 message.action)); |
| 340 | 247 |
| 341 int timeout = kDefaultMessageTimeout; | 248 int timeout = kDefaultMessageTimeout; |
| 342 if (message.action == JingleMessage::SESSION_INITIATE || | 249 if (message.action == JingleMessage::SESSION_INITIATE || |
| 343 message.action == JingleMessage::SESSION_ACCEPT) { | 250 message.action == JingleMessage::SESSION_ACCEPT) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 379 << " message: \"" << response->Str() | 286 << " message: \"" << response->Str() |
| 380 << "\". Terminating the session."; | 287 << "\". Terminating the session."; |
| 381 | 288 |
| 382 // TODO(sergeyu): There may be different reasons for error | 289 // TODO(sergeyu): There may be different reasons for error |
| 383 // here. Parse the response stanza to find failure reason. | 290 // here. Parse the response stanza to find failure reason. |
| 384 CloseInternal(PEER_IS_OFFLINE); | 291 CloseInternal(PEER_IS_OFFLINE); |
| 385 } | 292 } |
| 386 } | 293 } |
| 387 } | 294 } |
| 388 | 295 |
| 389 void JingleSession::EnsurePendingTransportInfoMessage() { | 296 void JingleSession::OnOutgoingTransportInfo( |
| 390 // |transport_info_timer_| must be running iff | 297 scoped_ptr<XmlElement> transport_info) { |
| 391 // |pending_transport_info_message_| exists. | 298 JingleMessage message(peer_jid_, JingleMessage::TRANSPORT_INFO, session_id_); |
| 392 DCHECK_EQ(pending_transport_info_message_ != nullptr, | 299 message.transport_info = transport_info.Pass(); |
| 393 transport_info_timer_.IsRunning()); | |
| 394 | |
| 395 if (!pending_transport_info_message_) { | |
| 396 pending_transport_info_message_.reset(new JingleMessage( | |
| 397 peer_jid_, JingleMessage::TRANSPORT_INFO, session_id_)); | |
| 398 // Delay sending the new candidates in case we get more candidates | |
| 399 // that we can send in one message. | |
| 400 transport_info_timer_.Start( | |
| 401 FROM_HERE, base::TimeDelta::FromMilliseconds(kTransportInfoSendDelayMs), | |
| 402 this, &JingleSession::SendTransportInfo); | |
| 403 } | |
| 404 } | |
| 405 | |
| 406 void JingleSession::SendTransportInfo() { | |
| 407 DCHECK(pending_transport_info_message_); | |
| 408 | 300 |
| 409 scoped_ptr<IqRequest> request = session_manager_->iq_sender()->SendIq( | 301 scoped_ptr<IqRequest> request = session_manager_->iq_sender()->SendIq( |
| 410 pending_transport_info_message_->ToXml(), | 302 message.ToXml(), base::Bind(&JingleSession::OnTransportInfoResponse, |
| 411 base::Bind(&JingleSession::OnTransportInfoResponse, | 303 base::Unretained(this))); |
| 412 base::Unretained(this))); | |
| 413 pending_transport_info_message_.reset(); | |
| 414 if (request) { | 304 if (request) { |
| 415 request->SetTimeout(base::TimeDelta::FromSeconds(kTransportInfoTimeout)); | 305 request->SetTimeout(base::TimeDelta::FromSeconds(kTransportInfoTimeout)); |
| 416 transport_info_requests_.push_back(request.release()); | 306 transport_info_requests_.push_back(request.release()); |
| 417 } else { | 307 } else { |
| 418 LOG(ERROR) << "Failed to send a transport-info message"; | 308 LOG(ERROR) << "Failed to send a transport-info message"; |
| 419 } | 309 } |
| 420 } | 310 } |
| 421 | 311 |
| 312 void JingleSession::OnTransportRouteChange(const std::string& channel_name, |
| 313 const TransportRoute& route) { |
| 314 event_handler_->OnSessionRouteChange(channel_name, route); |
| 315 } |
| 316 |
| 317 void JingleSession::OnTransportError(ErrorCode error) { |
| 318 CloseInternal(error); |
| 319 } |
| 320 |
| 422 void JingleSession::OnTransportInfoResponse(IqRequest* request, | 321 void JingleSession::OnTransportInfoResponse(IqRequest* request, |
| 423 const buzz::XmlElement* response) { | 322 const buzz::XmlElement* response) { |
| 424 DCHECK(!transport_info_requests_.empty()); | 323 DCHECK(!transport_info_requests_.empty()); |
| 425 | 324 |
| 426 // Consider transport-info requests sent before this one lost and delete | 325 // Consider transport-info requests sent before this one lost and delete |
| 427 // corresponding IqRequest objects. | 326 // corresponding IqRequest objects. |
| 428 while (transport_info_requests_.front() != request) { | 327 while (transport_info_requests_.front() != request) { |
| 429 delete transport_info_requests_.front(); | 328 delete transport_info_requests_.front(); |
| 430 transport_info_requests_.pop_front(); | 329 transport_info_requests_.pop_front(); |
| 431 } | 330 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 462 switch (message.action) { | 361 switch (message.action) { |
| 463 case JingleMessage::SESSION_ACCEPT: | 362 case JingleMessage::SESSION_ACCEPT: |
| 464 OnAccept(message, reply_callback); | 363 OnAccept(message, reply_callback); |
| 465 break; | 364 break; |
| 466 | 365 |
| 467 case JingleMessage::SESSION_INFO: | 366 case JingleMessage::SESSION_INFO: |
| 468 OnSessionInfo(message, reply_callback); | 367 OnSessionInfo(message, reply_callback); |
| 469 break; | 368 break; |
| 470 | 369 |
| 471 case JingleMessage::TRANSPORT_INFO: | 370 case JingleMessage::TRANSPORT_INFO: |
| 472 reply_callback.Run(JingleMessageReply::NONE); | 371 if (transport_session_->ProcessTransportInfo( |
| 473 ProcessTransportInfo(message); | 372 message.transport_info.get())) { |
| 373 reply_callback.Run(JingleMessageReply::NONE); |
| 374 } else { |
| 375 reply_callback.Run(JingleMessageReply::BAD_REQUEST); |
| 376 } |
| 474 break; | 377 break; |
| 475 | 378 |
| 476 case JingleMessage::SESSION_TERMINATE: | 379 case JingleMessage::SESSION_TERMINATE: |
| 477 OnTerminate(message, reply_callback); | 380 OnTerminate(message, reply_callback); |
| 478 break; | 381 break; |
| 479 | 382 |
| 480 default: | 383 default: |
| 481 reply_callback.Run(JingleMessageReply::UNEXPECTED_REQUEST); | 384 reply_callback.Run(JingleMessageReply::UNEXPECTED_REQUEST); |
| 482 } | 385 } |
| 483 } | 386 } |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 537 CloseInternal(INCOMPATIBLE_PROTOCOL); | 440 CloseInternal(INCOMPATIBLE_PROTOCOL); |
| 538 return; | 441 return; |
| 539 } | 442 } |
| 540 | 443 |
| 541 reply_callback.Run(JingleMessageReply::NONE); | 444 reply_callback.Run(JingleMessageReply::NONE); |
| 542 | 445 |
| 543 authenticator_->ProcessMessage(message.info.get(), base::Bind( | 446 authenticator_->ProcessMessage(message.info.get(), base::Bind( |
| 544 &JingleSession::ProcessAuthenticationStep, base::Unretained(this))); | 447 &JingleSession::ProcessAuthenticationStep, base::Unretained(this))); |
| 545 } | 448 } |
| 546 | 449 |
| 547 void JingleSession::ProcessTransportInfo(const JingleMessage& message) { | |
| 548 for (std::list<JingleMessage::IceCredentials>::const_iterator it = | |
| 549 message.ice_credentials.begin(); | |
| 550 it != message.ice_credentials.end(); ++it) { | |
| 551 ChannelsMap::iterator channel = channels_.find(it->channel); | |
| 552 if (channel != channels_.end()) { | |
| 553 channel->second->SetRemoteCredentials(it->ufrag, it->password); | |
| 554 } else { | |
| 555 // Transport info was received before the channel was created. | |
| 556 // This could happen due to messages being reordered on the wire. | |
| 557 pending_remote_ice_credentials_.push_back(*it); | |
| 558 } | |
| 559 } | |
| 560 | |
| 561 for (std::list<JingleMessage::NamedCandidate>::const_iterator it = | |
| 562 message.candidates.begin(); | |
| 563 it != message.candidates.end(); ++it) { | |
| 564 ChannelsMap::iterator channel = channels_.find(it->name); | |
| 565 if (channel != channels_.end()) { | |
| 566 channel->second->AddRemoteCandidate(it->candidate); | |
| 567 } else { | |
| 568 // Transport info was received before the channel was created. | |
| 569 // This could happen due to messages being reordered on the wire. | |
| 570 pending_remote_candidates_.push_back(*it); | |
| 571 } | |
| 572 } | |
| 573 } | |
| 574 | |
| 575 void JingleSession::OnTerminate(const JingleMessage& message, | 450 void JingleSession::OnTerminate(const JingleMessage& message, |
| 576 const ReplyCallback& reply_callback) { | 451 const ReplyCallback& reply_callback) { |
| 577 if (!is_session_active()) { | 452 if (!is_session_active()) { |
| 578 LOG(WARNING) << "Received unexpected session-terminate message."; | 453 LOG(WARNING) << "Received unexpected session-terminate message."; |
| 579 reply_callback.Run(JingleMessageReply::UNEXPECTED_REQUEST); | 454 reply_callback.Run(JingleMessageReply::UNEXPECTED_REQUEST); |
| 580 return; | 455 return; |
| 581 } | 456 } |
| 582 | 457 |
| 583 reply_callback.Run(JingleMessageReply::NONE); | 458 reply_callback.Run(JingleMessageReply::NONE); |
| 584 | 459 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 665 void JingleSession::ContinueAuthenticationStep() { | 540 void JingleSession::ContinueAuthenticationStep() { |
| 666 if (authenticator_->state() == Authenticator::ACCEPTED) { | 541 if (authenticator_->state() == Authenticator::ACCEPTED) { |
| 667 OnAuthenticated(); | 542 OnAuthenticated(); |
| 668 } else if (authenticator_->state() == Authenticator::REJECTED) { | 543 } else if (authenticator_->state() == Authenticator::REJECTED) { |
| 669 CloseInternal(AuthRejectionReasonToErrorCode( | 544 CloseInternal(AuthRejectionReasonToErrorCode( |
| 670 authenticator_->rejection_reason())); | 545 authenticator_->rejection_reason())); |
| 671 } | 546 } |
| 672 } | 547 } |
| 673 | 548 |
| 674 void JingleSession::OnAuthenticated() { | 549 void JingleSession::OnAuthenticated() { |
| 675 pseudotcp_channel_factory_.reset(new PseudoTcpChannelFactory(this)); | 550 transport_session_->Start(this, authenticator_.get()); |
| 676 secure_channel_factory_.reset( | |
| 677 new SecureChannelFactory(pseudotcp_channel_factory_.get(), | |
| 678 authenticator_.get())); | |
| 679 | 551 |
| 680 if (quic_channel_factory_) | 552 if (quic_channel_factory_) { |
| 681 quic_channel_factory_->Start(this, authenticator_->GetAuthKey()); | 553 quic_channel_factory_->Start( |
| 554 transport_session_->GetDatagramChannelFactory(), |
| 555 authenticator_->GetAuthKey()); |
| 556 } |
| 682 | 557 |
| 683 SetState(AUTHENTICATED); | 558 SetState(AUTHENTICATED); |
| 684 } | 559 } |
| 685 | 560 |
| 686 void JingleSession::CloseInternal(ErrorCode error) { | 561 void JingleSession::CloseInternal(ErrorCode error) { |
| 687 DCHECK(CalledOnValidThread()); | 562 DCHECK(CalledOnValidThread()); |
| 688 | 563 |
| 689 if (is_session_active()) { | 564 if (is_session_active()) { |
| 690 // Send session-terminate message with the appropriate error code. | 565 // Send session-terminate message with the appropriate error code. |
| 691 JingleMessage::Reason reason; | 566 JingleMessage::Reason reason; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 737 } | 612 } |
| 738 } | 613 } |
| 739 | 614 |
| 740 bool JingleSession::is_session_active() { | 615 bool JingleSession::is_session_active() { |
| 741 return state_ == CONNECTING || state_ == ACCEPTING || state_ == CONNECTED || | 616 return state_ == CONNECTING || state_ == ACCEPTING || state_ == CONNECTED || |
| 742 state_ == AUTHENTICATING || state_ == AUTHENTICATED; | 617 state_ == AUTHENTICATING || state_ == AUTHENTICATED; |
| 743 } | 618 } |
| 744 | 619 |
| 745 } // namespace protocol | 620 } // namespace protocol |
| 746 } // namespace remoting | 621 } // namespace remoting |
| OLD | NEW |