| Index: remoting/protocol/jingle_session.cc
|
| diff --git a/remoting/protocol/jingle_session.cc b/remoting/protocol/jingle_session.cc
|
| index 2aecd4c25d6856d86a4f8f0ab1645219edad48a1..57883cb4a7300995fc8265cb2f8808a0958559c4 100644
|
| --- a/remoting/protocol/jingle_session.cc
|
| +++ b/remoting/protocol/jingle_session.cc
|
| @@ -6,8 +6,10 @@
|
|
|
| #include "base/bind.h"
|
| #include "base/rand_util.h"
|
| +#include "base/single_thread_task_runner.h"
|
| #include "base/stl_util.h"
|
| #include "base/strings/string_number_conversions.h"
|
| +#include "base/thread_task_runner_handle.h"
|
| #include "base/time/time.h"
|
| #include "remoting/base/constants.h"
|
| #include "remoting/jingle_glue/iq_sender.h"
|
| @@ -63,7 +65,8 @@ JingleSession::JingleSession(JingleSessionManager* session_manager)
|
| event_handler_(NULL),
|
| state_(INITIALIZING),
|
| error_(OK),
|
| - config_is_set_(false) {
|
| + config_is_set_(false),
|
| + weak_factory_(this) {
|
| }
|
|
|
| JingleSession::~JingleSession() {
|
| @@ -181,9 +184,10 @@ void JingleSession::ContinueAcceptIncomingConnection() {
|
| SetState(AUTHENTICATED);
|
| } else {
|
| DCHECK_EQ(authenticator_->state(), Authenticator::WAITING_MESSAGE);
|
| + if (authenticator_->started()) {
|
| + SetState(AUTHENTICATING);
|
| + }
|
| }
|
| -
|
| - return;
|
| }
|
|
|
| const std::string& JingleSession::jid() {
|
| @@ -485,7 +489,7 @@ void JingleSession::OnSessionInfo(const JingleMessage& message,
|
| return;
|
| }
|
|
|
| - if (state_ != CONNECTED ||
|
| + if ((state_ != CONNECTED && state_ != AUTHENTICATING) ||
|
| authenticator_->state() != Authenticator::WAITING_MESSAGE) {
|
| LOG(WARNING) << "Received unexpected authenticator message "
|
| << message.info->Str();
|
| @@ -517,8 +521,7 @@ void JingleSession::ProcessTransportInfo(const JingleMessage& message) {
|
|
|
| void JingleSession::OnTerminate(const JingleMessage& message,
|
| const ReplyCallback& reply_callback) {
|
| - if (state_ != CONNECTING && state_ != ACCEPTING && state_ != CONNECTED &&
|
| - state_ != AUTHENTICATED) {
|
| + if (!is_session_active()) {
|
| LOG(WARNING) << "Received unexpected session-terminate message.";
|
| reply_callback.Run(JingleMessageReply::UNEXPECTED_REQUEST);
|
| return;
|
| @@ -577,7 +580,7 @@ void JingleSession::ProcessAuthenticationStep() {
|
| DCHECK(CalledOnValidThread());
|
| DCHECK_NE(authenticator_->state(), Authenticator::PROCESSING_MESSAGE);
|
|
|
| - if (state_ != CONNECTED) {
|
| + if (state_ != CONNECTED && state_ != AUTHENTICATING) {
|
| DCHECK(state_ == FAILED || state_ == CLOSED);
|
| // The remote host closed the connection while the authentication was being
|
| // processed asynchronously, nothing to do.
|
| @@ -592,6 +595,21 @@ void JingleSession::ProcessAuthenticationStep() {
|
| }
|
| DCHECK_NE(authenticator_->state(), Authenticator::MESSAGE_READY);
|
|
|
| + // The current JingleSession object can be destroyed by event_handler of
|
| + // SetState(AUTHENTICATING) and cause subsequent dereferencing of the this
|
| + // pointer to crash. To protect against it, we run ContinueAuthenticationStep
|
| + // asychronously using a weak pointer.
|
| + base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&JingleSession::ContinueAuthenticationStep,
|
| + weak_factory_.GetWeakPtr()));
|
| +
|
| + if (authenticator_->started()) {
|
| + SetState(AUTHENTICATING);
|
| + }
|
| +}
|
| +
|
| +void JingleSession::ContinueAuthenticationStep() {
|
| if (authenticator_->state() == Authenticator::ACCEPTED) {
|
| SetState(AUTHENTICATED);
|
| } else if (authenticator_->state() == Authenticator::REJECTED) {
|
| @@ -603,8 +621,7 @@ void JingleSession::ProcessAuthenticationStep() {
|
| void JingleSession::CloseInternal(ErrorCode error) {
|
| DCHECK(CalledOnValidThread());
|
|
|
| - if (state_ == CONNECTING || state_ == ACCEPTING || state_ == CONNECTED ||
|
| - state_ == AUTHENTICATED) {
|
| + if (is_session_active()) {
|
| // Send session-terminate message with the appropriate error code.
|
| JingleMessage::Reason reason;
|
| switch (error) {
|
| @@ -655,5 +672,10 @@ void JingleSession::SetState(State new_state) {
|
| }
|
| }
|
|
|
| +bool JingleSession::is_session_active() {
|
| + return state_ == CONNECTING || state_ == ACCEPTING || state_ == CONNECTED ||
|
| + state_ == AUTHENTICATING || state_ == AUTHENTICATED;
|
| +}
|
| +
|
| } // namespace protocol
|
| } // namespace remoting
|
|
|