Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/pepper_session.h" | 5 #include "remoting/protocol/pepper_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" |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 31 const int kTransportInfoSendDelayMs = 2; | 31 const int kTransportInfoSendDelayMs = 2; |
| 32 } // namespace | 32 } // namespace |
| 33 | 33 |
| 34 PepperSession::PepperSession(PepperSessionManager* session_manager) | 34 PepperSession::PepperSession(PepperSessionManager* session_manager) |
| 35 : session_manager_(session_manager), | 35 : session_manager_(session_manager), |
| 36 state_(INITIALIZING), | 36 state_(INITIALIZING), |
| 37 error_(OK) { | 37 error_(OK) { |
| 38 } | 38 } |
| 39 | 39 |
| 40 PepperSession::~PepperSession() { | 40 PepperSession::~PepperSession() { |
| 41 control_channel_socket_.reset(); | |
| 42 event_channel_socket_.reset(); | |
| 43 STLDeleteContainerPairSecondPointers(channels_.begin(), channels_.end()); | 41 STLDeleteContainerPairSecondPointers(channels_.begin(), channels_.end()); |
| 44 session_manager_->SessionDestroyed(this); | 42 session_manager_->SessionDestroyed(this); |
| 45 } | 43 } |
| 46 | 44 |
| 47 void PepperSession::SetStateChangeCallback( | 45 void PepperSession::SetStateChangeCallback( |
| 48 const StateChangeCallback& callback) { | 46 const StateChangeCallback& callback) { |
| 49 DCHECK(CalledOnValidThread()); | 47 DCHECK(CalledOnValidThread()); |
| 50 state_change_callback_ = callback; | 48 state_change_callback_ = callback; |
| 51 } | 49 } |
| 52 | 50 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 127 } | 125 } |
| 128 | 126 |
| 129 void PepperSession::CancelChannelCreation(const std::string& name) { | 127 void PepperSession::CancelChannelCreation(const std::string& name) { |
| 130 ChannelsMap::iterator it = channels_.find(name); | 128 ChannelsMap::iterator it = channels_.find(name); |
| 131 if (it != channels_.end() && !it->second->is_connected()) { | 129 if (it != channels_.end() && !it->second->is_connected()) { |
| 132 delete it->second; | 130 delete it->second; |
| 133 DCHECK(!channels_[name]); | 131 DCHECK(!channels_[name]); |
| 134 } | 132 } |
| 135 } | 133 } |
| 136 | 134 |
| 137 net::Socket* PepperSession::control_channel() { | |
| 138 DCHECK(CalledOnValidThread()); | |
| 139 return control_channel_socket_.get(); | |
| 140 } | |
| 141 | |
| 142 net::Socket* PepperSession::event_channel() { | |
| 143 DCHECK(CalledOnValidThread()); | |
| 144 return event_channel_socket_.get(); | |
| 145 } | |
| 146 | |
| 147 const std::string& PepperSession::jid() { | 135 const std::string& PepperSession::jid() { |
| 148 DCHECK(CalledOnValidThread()); | 136 DCHECK(CalledOnValidThread()); |
| 149 return peer_jid_; | 137 return peer_jid_; |
| 150 } | 138 } |
| 151 | 139 |
| 152 const CandidateSessionConfig* PepperSession::candidate_config() { | 140 const CandidateSessionConfig* PepperSession::candidate_config() { |
| 153 DCHECK(CalledOnValidThread()); | 141 DCHECK(CalledOnValidThread()); |
| 154 return candidate_config_.get(); | 142 return candidate_config_.get(); |
| 155 } | 143 } |
| 156 | 144 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 192 } | 180 } |
| 193 | 181 |
| 194 const std::string& PepperSession::shared_secret() { | 182 const std::string& PepperSession::shared_secret() { |
| 195 DCHECK(CalledOnValidThread()); | 183 DCHECK(CalledOnValidThread()); |
| 196 return shared_secret_; | 184 return shared_secret_; |
| 197 } | 185 } |
| 198 | 186 |
| 199 void PepperSession::Close() { | 187 void PepperSession::Close() { |
| 200 DCHECK(CalledOnValidThread()); | 188 DCHECK(CalledOnValidThread()); |
| 201 | 189 |
| 202 if (state_ == CONNECTING || state_ == CONNECTED || | 190 if (state_ == CONNECTING || state_ == CONNECTED) { |
| 203 state_ == CONNECTED_CHANNELS) { | |
| 204 // Send session-terminate message. | 191 // Send session-terminate message. |
| 205 JingleMessage message(peer_jid_, JingleMessage::SESSION_TERMINATE, | 192 JingleMessage message(peer_jid_, JingleMessage::SESSION_TERMINATE, |
| 206 session_id_); | 193 session_id_); |
| 207 scoped_ptr<IqRequest> terminate_request( | 194 scoped_ptr<IqRequest> terminate_request( |
| 208 session_manager_->iq_sender()->SendIq( | 195 session_manager_->iq_sender()->SendIq( |
| 209 message.ToXml(), IqSender::ReplyCallback())); | 196 message.ToXml(), IqSender::ReplyCallback())); |
| 210 } | 197 } |
| 211 | 198 |
| 212 CloseInternal(false); | 199 CloseInternal(false); |
| 213 } | 200 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 245 if (state_ != CONNECTING) { | 232 if (state_ != CONNECTING) { |
| 246 *reply = JingleMessageReply(JingleMessageReply::UNEXPECTED_REQUEST); | 233 *reply = JingleMessageReply(JingleMessageReply::UNEXPECTED_REQUEST); |
| 247 return; | 234 return; |
| 248 } | 235 } |
| 249 | 236 |
| 250 if (!InitializeConfigFromDescription(message.description.get())) { | 237 if (!InitializeConfigFromDescription(message.description.get())) { |
| 251 OnError(INCOMPATIBLE_PROTOCOL); | 238 OnError(INCOMPATIBLE_PROTOCOL); |
| 252 return; | 239 return; |
| 253 } | 240 } |
| 254 | 241 |
| 255 CreateChannels(); | |
| 256 SetState(CONNECTED); | 242 SetState(CONNECTED); |
| 257 | 243 |
| 258 // In case there is transport information in the accept message. | 244 // In case there is transport information in the accept message. |
| 259 ProcessTransportInfo(message); | 245 ProcessTransportInfo(message); |
| 260 } | 246 } |
| 261 | 247 |
| 262 void PepperSession::ProcessTransportInfo(const JingleMessage& message) { | 248 void PepperSession::ProcessTransportInfo(const JingleMessage& message) { |
| 263 for (std::list<cricket::Candidate>::const_iterator it = | 249 for (std::list<cricket::Candidate>::const_iterator it = |
| 264 message.candidates.begin(); | 250 message.candidates.begin(); |
| 265 it != message.candidates.end(); ++it) { | 251 it != message.candidates.end(); ++it) { |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 285 break; | 271 break; |
| 286 | 272 |
| 287 default: | 273 default: |
| 288 LOG(WARNING) << "Received session-terminate message " | 274 LOG(WARNING) << "Received session-terminate message " |
| 289 "with an unexpected reason."; | 275 "with an unexpected reason."; |
| 290 OnError(SESSION_REJECTED); | 276 OnError(SESSION_REJECTED); |
| 291 } | 277 } |
| 292 return; | 278 return; |
| 293 } | 279 } |
| 294 | 280 |
| 295 // TODO(sergeyu): We should return CHANNEL_CONNECTION_ERROR only in | |
| 296 // case when |message.reason| is set GENERAL_ERROR, but some legacy | |
| 297 // hosts may sent terminate messages with reason set to SUCCESS. | |
| 298 if (state_ == CONNECTED) { | 281 if (state_ == CONNECTED) { |
| 299 // Session was connected, but we failed to connect channels. | 282 if (message.reason == JingleMessage::GENERAL_ERROR) { |
| 300 OnError(CHANNEL_CONNECTION_ERROR); | 283 OnError(CHANNEL_CONNECTION_ERROR); |
| 284 } else { | |
| 285 CloseInternal(false); | |
| 286 } | |
| 301 return; | 287 return; |
| 302 } | 288 } |
| 303 | 289 |
| 304 CloseInternal(false); | 290 LOG(ERROR) << "Received unexpected session-terminate message."; |
|
Wez
2011/11/21 02:39:04
Is that really an error?
Sergey Ulanov
2011/11/21 22:14:22
Changed to WARNING.
| |
| 305 } | 291 } |
| 306 | 292 |
| 307 bool PepperSession::InitializeConfigFromDescription( | 293 bool PepperSession::InitializeConfigFromDescription( |
| 308 const ContentDescription* description) { | 294 const ContentDescription* description) { |
| 309 DCHECK(description); | 295 DCHECK(description); |
| 310 | 296 |
| 311 remote_cert_ = description->certificate(); | 297 remote_cert_ = description->certificate(); |
| 312 if (remote_cert_.empty()) { | 298 if (remote_cert_.empty()) { |
| 313 LOG(ERROR) << "session-accept does not specify certificate"; | 299 LOG(ERROR) << "session-accept does not specify certificate"; |
| 314 return false; | 300 return false; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 362 | 348 |
| 363 void PepperSession::SendTransportInfo() { | 349 void PepperSession::SendTransportInfo() { |
| 364 JingleMessage message(peer_jid_, JingleMessage::TRANSPORT_INFO, session_id_); | 350 JingleMessage message(peer_jid_, JingleMessage::TRANSPORT_INFO, session_id_); |
| 365 message.candidates.swap(pending_candidates_); | 351 message.candidates.swap(pending_candidates_); |
| 366 transport_info_request_.reset(session_manager_->iq_sender()->SendIq( | 352 transport_info_request_.reset(session_manager_->iq_sender()->SendIq( |
| 367 message.ToXml(), base::Bind( | 353 message.ToXml(), base::Bind( |
| 368 &PepperSession::OnTransportInfoResponse, | 354 &PepperSession::OnTransportInfoResponse, |
| 369 base::Unretained(this)))); | 355 base::Unretained(this)))); |
| 370 } | 356 } |
| 371 | 357 |
| 372 void PepperSession::CreateChannels() { | |
| 373 CreateStreamChannel( | |
| 374 kControlChannelName, | |
| 375 base::Bind(&PepperSession::OnChannelConnected, | |
| 376 base::Unretained(this), &control_channel_socket_)); | |
| 377 CreateStreamChannel( | |
| 378 kEventChannelName, | |
| 379 base::Bind(&PepperSession::OnChannelConnected, | |
| 380 base::Unretained(this), &event_channel_socket_)); | |
| 381 } | |
| 382 | |
| 383 void PepperSession::OnChannelConnected( | |
| 384 scoped_ptr<net::Socket>* socket_container, | |
| 385 net::StreamSocket* socket) { | |
| 386 if (!socket) { | |
| 387 LOG(ERROR) << "Failed to connect control or events channel. " | |
| 388 << "Terminating connection"; | |
| 389 OnError(CHANNEL_CONNECTION_ERROR); | |
| 390 return; | |
| 391 } | |
| 392 | |
| 393 socket_container->reset(socket); | |
| 394 | |
| 395 if (control_channel_socket_.get() && event_channel_socket_.get()) | |
| 396 SetState(CONNECTED_CHANNELS); | |
| 397 } | |
| 398 | 358 |
| 399 void PepperSession::CloseInternal(bool failed) { | 359 void PepperSession::CloseInternal(bool failed) { |
| 400 DCHECK(CalledOnValidThread()); | 360 DCHECK(CalledOnValidThread()); |
| 401 | 361 |
| 402 if (state_ != FAILED && state_ != CLOSED) { | 362 if (state_ != FAILED && state_ != CLOSED) { |
| 403 control_channel_socket_.reset(); | |
| 404 event_channel_socket_.reset(); | |
| 405 | |
| 406 if (failed) | 363 if (failed) |
| 407 SetState(FAILED); | 364 SetState(FAILED); |
| 408 else | 365 else |
| 409 SetState(CLOSED); | 366 SetState(CLOSED); |
| 410 } | 367 } |
| 411 } | 368 } |
| 412 | 369 |
| 413 void PepperSession::SetState(State new_state) { | 370 void PepperSession::SetState(State new_state) { |
| 414 DCHECK(CalledOnValidThread()); | 371 DCHECK(CalledOnValidThread()); |
| 415 | 372 |
| 416 if (new_state != state_) { | 373 if (new_state != state_) { |
| 417 DCHECK_NE(state_, CLOSED); | 374 DCHECK_NE(state_, CLOSED); |
| 418 DCHECK_NE(state_, FAILED); | 375 DCHECK_NE(state_, FAILED); |
| 419 | 376 |
| 420 state_ = new_state; | 377 state_ = new_state; |
| 421 if (!state_change_callback_.is_null()) | 378 if (!state_change_callback_.is_null()) |
| 422 state_change_callback_.Run(new_state); | 379 state_change_callback_.Run(new_state); |
| 423 } | 380 } |
| 424 } | 381 } |
| 425 | 382 |
| 426 } // namespace protocol | 383 } // namespace protocol |
| 427 } // namespace remoting | 384 } // namespace remoting |
| OLD | NEW |