Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(127)

Side by Side Diff: remoting/protocol/jingle_session.cc

Issue 1085703003: Use standard ICE in Chromoting. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix crash on memory bots Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « remoting/protocol/jingle_session.h ('k') | remoting/protocol/jingle_session_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
(...skipping 14 matching lines...) Expand all
25 #include "remoting/signaling/iq_sender.h" 25 #include "remoting/signaling/iq_sender.h"
26 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h" 26 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h"
27 #include "third_party/webrtc/p2p/base/candidate.h" 27 #include "third_party/webrtc/p2p/base/candidate.h"
28 28
29 using buzz::XmlElement; 29 using buzz::XmlElement;
30 30
31 namespace remoting { 31 namespace remoting {
32 namespace protocol { 32 namespace protocol {
33 33
34 namespace { 34 namespace {
35 // Delay after candidate creation before sending transport-info 35
36 // message. This is neccessary to be able to pack multiple candidates 36 // Delay after candidate creation before sending transport-info message to
37 // into one transport-info messages. The value needs to be greater 37 // accumulate multiple candidates. This is an optimization to reduce number of
38 // than zero because ports are opened asynchronously in the browser 38 // transport-info messages.
39 // process. 39 const int kTransportInfoSendDelayMs = 20;
40 const int kTransportInfoSendDelayMs = 2;
41 40
42 // How long we should wait for a response from the other end. This value is used 41 // How long we should wait for a response from the other end. This value is used
43 // for all requests except |transport-info|. 42 // for all requests except |transport-info|.
44 const int kDefaultMessageTimeout = 10; 43 const int kDefaultMessageTimeout = 10;
45 44
46 // During a reconnection, it usually takes longer for the peer to respond due to 45 // 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, 46 // 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 47 // it can take up to 20s for the session to reconnect. To make it safe, setting
49 // the timeout to 30s. 48 // the timeout to 30s.
50 const int kSessionInitiateAndAcceptTimeout = kDefaultMessageTimeout * 3; 49 const int kSessionInitiateAndAcceptTimeout = kDefaultMessageTimeout * 3;
(...skipping 16 matching lines...) Expand all
67 return UNKNOWN_ERROR; 66 return UNKNOWN_ERROR;
68 } 67 }
69 68
70 } // namespace 69 } // namespace
71 70
72 JingleSession::JingleSession(JingleSessionManager* session_manager) 71 JingleSession::JingleSession(JingleSessionManager* session_manager)
73 : session_manager_(session_manager), 72 : session_manager_(session_manager),
74 event_handler_(nullptr), 73 event_handler_(nullptr),
75 state_(INITIALIZING), 74 state_(INITIALIZING),
76 error_(OK), 75 error_(OK),
77 config_is_set_(false),
78 weak_factory_(this) { 76 weak_factory_(this) {
79 } 77 }
80 78
81 JingleSession::~JingleSession() { 79 JingleSession::~JingleSession() {
82 channel_multiplexer_.reset(); 80 channel_multiplexer_.reset();
83 STLDeleteContainerPointers(pending_requests_.begin(), 81 STLDeleteContainerPointers(pending_requests_.begin(),
84 pending_requests_.end()); 82 pending_requests_.end());
85 STLDeleteContainerPointers(transport_info_requests_.begin(), 83 STLDeleteContainerPointers(transport_info_requests_.begin(),
86 transport_info_requests_.end()); 84 transport_info_requests_.end());
87 85
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 peer_jid_ = initiate_message.from; 140 peer_jid_ = initiate_message.from;
143 authenticator_ = authenticator.Pass(); 141 authenticator_ = authenticator.Pass();
144 session_id_ = initiate_message.sid; 142 session_id_ = initiate_message.sid;
145 candidate_config_ = initiate_message.description->config()->Clone(); 143 candidate_config_ = initiate_message.description->config()->Clone();
146 144
147 SetState(ACCEPTING); 145 SetState(ACCEPTING);
148 } 146 }
149 147
150 void JingleSession::AcceptIncomingConnection( 148 void JingleSession::AcceptIncomingConnection(
151 const JingleMessage& initiate_message) { 149 const JingleMessage& initiate_message) {
152 DCHECK(config_is_set_); 150 DCHECK(config_);
153 151
154 // Process the first authentication message. 152 // Process the first authentication message.
155 const buzz::XmlElement* first_auth_message = 153 const buzz::XmlElement* first_auth_message =
156 initiate_message.description->authenticator_message(); 154 initiate_message.description->authenticator_message();
157 155
158 if (!first_auth_message) { 156 if (!first_auth_message) {
159 CloseInternal(INCOMPATIBLE_PROTOCOL); 157 CloseInternal(INCOMPATIBLE_PROTOCOL);
160 return; 158 return;
161 } 159 }
162 160
(...skipping 14 matching lines...) Expand all
177 175
178 // Send the session-accept message. 176 // Send the session-accept message.
179 JingleMessage message(peer_jid_, JingleMessage::SESSION_ACCEPT, 177 JingleMessage message(peer_jid_, JingleMessage::SESSION_ACCEPT,
180 session_id_); 178 session_id_);
181 179
182 scoped_ptr<buzz::XmlElement> auth_message; 180 scoped_ptr<buzz::XmlElement> auth_message;
183 if (authenticator_->state() == Authenticator::MESSAGE_READY) 181 if (authenticator_->state() == Authenticator::MESSAGE_READY)
184 auth_message = authenticator_->GetNextMessage(); 182 auth_message = authenticator_->GetNextMessage();
185 183
186 message.description.reset( 184 message.description.reset(
187 new ContentDescription(CandidateSessionConfig::CreateFrom(config_), 185 new ContentDescription(CandidateSessionConfig::CreateFrom(*config_),
188 auth_message.Pass())); 186 auth_message.Pass()));
189 SendMessage(message); 187 SendMessage(message);
190 188
191 // Update state. 189 // Update state.
192 SetState(CONNECTED); 190 SetState(CONNECTED);
193 191
194 if (authenticator_->state() == Authenticator::ACCEPTED) { 192 if (authenticator_->state() == Authenticator::ACCEPTED) {
195 OnAuthenticated(); 193 OnAuthenticated();
196 } else { 194 } else {
197 DCHECK_EQ(authenticator_->state(), Authenticator::WAITING_MESSAGE); 195 DCHECK_EQ(authenticator_->state(), Authenticator::WAITING_MESSAGE);
198 if (authenticator_->started()) { 196 if (authenticator_->started()) {
199 SetState(AUTHENTICATING); 197 SetState(AUTHENTICATING);
200 } 198 }
201 } 199 }
202 } 200 }
203 201
204 const std::string& JingleSession::jid() { 202 const std::string& JingleSession::jid() {
205 DCHECK(CalledOnValidThread()); 203 DCHECK(CalledOnValidThread());
206 return peer_jid_; 204 return peer_jid_;
207 } 205 }
208 206
209 const CandidateSessionConfig* JingleSession::candidate_config() { 207 const CandidateSessionConfig* JingleSession::candidate_config() {
210 DCHECK(CalledOnValidThread()); 208 DCHECK(CalledOnValidThread());
211 return candidate_config_.get(); 209 return candidate_config_.get();
212 } 210 }
213 211
214 const SessionConfig& JingleSession::config() { 212 const SessionConfig& JingleSession::config() {
215 DCHECK(CalledOnValidThread()); 213 DCHECK(CalledOnValidThread());
216 return config_; 214 return *config_;
217 } 215 }
218 216
219 void JingleSession::set_config(const SessionConfig& config) { 217 void JingleSession::set_config(scoped_ptr<SessionConfig> config) {
220 DCHECK(CalledOnValidThread()); 218 DCHECK(CalledOnValidThread());
221 DCHECK(!config_is_set_); 219 DCHECK(!config_);
222 config_ = config; 220 config_ = config.Pass();
223 config_is_set_ = true;
224 } 221 }
225 222
226 StreamChannelFactory* JingleSession::GetTransportChannelFactory() { 223 StreamChannelFactory* JingleSession::GetTransportChannelFactory() {
227 DCHECK(CalledOnValidThread()); 224 DCHECK(CalledOnValidThread());
228 return secure_channel_factory_.get(); 225 return secure_channel_factory_.get();
229 } 226 }
230 227
231 StreamChannelFactory* JingleSession::GetMultiplexedChannelFactory() { 228 StreamChannelFactory* JingleSession::GetMultiplexedChannelFactory() {
232 DCHECK(CalledOnValidThread()); 229 DCHECK(CalledOnValidThread());
233 if (!channel_multiplexer_.get()) { 230 if (!channel_multiplexer_.get()) {
234 channel_multiplexer_.reset( 231 channel_multiplexer_.reset(
235 new ChannelMultiplexer(GetTransportChannelFactory(), kMuxChannelName)); 232 new ChannelMultiplexer(GetTransportChannelFactory(), kMuxChannelName));
236 } 233 }
237 return channel_multiplexer_.get(); 234 return channel_multiplexer_.get();
238 } 235 }
239 236
240 void JingleSession::Close() { 237 void JingleSession::Close() {
241 DCHECK(CalledOnValidThread()); 238 DCHECK(CalledOnValidThread());
242 239
243 CloseInternal(OK); 240 CloseInternal(OK);
244 } 241 }
245 242
246 void JingleSession::AddPendingRemoteCandidates(Transport* channel, 243 void JingleSession::AddPendingRemoteTransportInfo(Transport* channel) {
247 const std::string& name) { 244 std::list<JingleMessage::IceCredentials>::iterator credentials =
248 std::list<JingleMessage::NamedCandidate>::iterator it = 245 pending_remote_ice_credentials_.begin();
246 while (credentials != pending_remote_ice_credentials_.end()) {
247 if (credentials->channel == channel->name()) {
248 channel->SetRemoteCredentials(credentials->ufrag, credentials->password);
249 credentials = pending_remote_ice_credentials_.erase(credentials);
250 } else {
251 ++credentials;
252 }
253 }
254
255 std::list<JingleMessage::NamedCandidate>::iterator candidate =
249 pending_remote_candidates_.begin(); 256 pending_remote_candidates_.begin();
250 while(it != pending_remote_candidates_.end()) { 257 while (candidate != pending_remote_candidates_.end()) {
251 if (it->name == name) { 258 if (candidate->name == channel->name()) {
252 channel->AddRemoteCandidate(it->candidate); 259 channel->AddRemoteCandidate(candidate->candidate);
253 it = pending_remote_candidates_.erase(it); 260 candidate = pending_remote_candidates_.erase(candidate);
254 } else { 261 } else {
255 ++it; 262 ++candidate;
256 } 263 }
257 } 264 }
258 } 265 }
259 266
260 void JingleSession::CreateChannel(const std::string& name, 267 void JingleSession::CreateChannel(const std::string& name,
261 const ChannelCreatedCallback& callback) { 268 const ChannelCreatedCallback& callback) {
262 DCHECK(!channels_[name]); 269 DCHECK(!channels_[name]);
263 270
264 scoped_ptr<Transport> channel = 271 scoped_ptr<Transport> channel =
265 session_manager_->transport_factory_->CreateTransport(); 272 session_manager_->transport_factory_->CreateTransport();
273 channel->SetUseStandardIce(config_->standard_ice());
266 channel->Connect(name, this, callback); 274 channel->Connect(name, this, callback);
267 AddPendingRemoteCandidates(channel.get(), name); 275 AddPendingRemoteTransportInfo(channel.get());
268 channels_[name] = channel.release(); 276 channels_[name] = channel.release();
269 } 277 }
270 278
271 void JingleSession::CancelChannelCreation(const std::string& name) { 279 void JingleSession::CancelChannelCreation(const std::string& name) {
272 ChannelsMap::iterator it = channels_.find(name); 280 ChannelsMap::iterator it = channels_.find(name);
273 if (it != channels_.end()) { 281 if (it != channels_.end()) {
274 DCHECK(!it->second->is_connected()); 282 DCHECK(!it->second->is_connected());
275 delete it->second; 283 delete it->second;
276 DCHECK(channels_.find(name) == channels_.end()); 284 DCHECK(channels_.find(name) == channels_.end());
277 } 285 }
278 } 286 }
279 287
288 void JingleSession::OnTransportIceCredentials(Transport* transport,
289 const std::string& ufrag,
290 const std::string& password) {
291 EnsurePendingTransportInfoMessage();
292 pending_transport_info_message_->ice_credentials.push_back(
293 JingleMessage::IceCredentials(transport->name(), ufrag, password));
294 }
295
280 void JingleSession::OnTransportCandidate(Transport* transport, 296 void JingleSession::OnTransportCandidate(Transport* transport,
281 const cricket::Candidate& candidate) { 297 const cricket::Candidate& candidate) {
282 pending_candidates_.push_back(JingleMessage::NamedCandidate( 298 EnsurePendingTransportInfoMessage();
283 transport->name(), candidate)); 299 pending_transport_info_message_->candidates.push_back(
284 300 JingleMessage::NamedCandidate(transport->name(), candidate));
285 if (!transport_infos_timer_.IsRunning()) {
286 // Delay sending the new candidates in case we get more candidates
287 // that we can send in one message.
288 transport_infos_timer_.Start(
289 FROM_HERE, base::TimeDelta::FromMilliseconds(kTransportInfoSendDelayMs),
290 this, &JingleSession::SendTransportInfo);
291 }
292 } 301 }
293 302
294 void JingleSession::OnTransportRouteChange(Transport* transport, 303 void JingleSession::OnTransportRouteChange(Transport* transport,
295 const TransportRoute& route) { 304 const TransportRoute& route) {
296 if (event_handler_) 305 if (event_handler_)
297 event_handler_->OnSessionRouteChange(transport->name(), route); 306 event_handler_->OnSessionRouteChange(transport->name(), route);
298 } 307 }
299 308
300 void JingleSession::OnTransportFailed(Transport* transport) { 309 void JingleSession::OnTransportFailed(Transport* transport) {
301 CloseInternal(CHANNEL_CONNECTION_ERROR); 310 CloseInternal(CHANNEL_CONNECTION_ERROR);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 << " message: \"" << response->Str() 364 << " message: \"" << response->Str()
356 << "\". Terminating the session."; 365 << "\". Terminating the session.";
357 366
358 // TODO(sergeyu): There may be different reasons for error 367 // TODO(sergeyu): There may be different reasons for error
359 // here. Parse the response stanza to find failure reason. 368 // here. Parse the response stanza to find failure reason.
360 CloseInternal(PEER_IS_OFFLINE); 369 CloseInternal(PEER_IS_OFFLINE);
361 } 370 }
362 } 371 }
363 } 372 }
364 373
374 void JingleSession::EnsurePendingTransportInfoMessage() {
375 // |transport_info_timer_| must be running iff
376 // |pending_transport_info_message_| exists.
377 DCHECK_EQ(pending_transport_info_message_ != nullptr,
378 transport_info_timer_.IsRunning());
379
380 if (!pending_transport_info_message_) {
381 pending_transport_info_message_.reset(new JingleMessage(
382 peer_jid_, JingleMessage::TRANSPORT_INFO, session_id_));
383 pending_transport_info_message_->standard_ice = config_->standard_ice();
384
385 // Delay sending the new candidates in case we get more candidates
386 // that we can send in one message.
387 transport_info_timer_.Start(
388 FROM_HERE, base::TimeDelta::FromMilliseconds(kTransportInfoSendDelayMs),
389 this, &JingleSession::SendTransportInfo);
390 }
391 }
392
365 void JingleSession::SendTransportInfo() { 393 void JingleSession::SendTransportInfo() {
366 JingleMessage message(peer_jid_, JingleMessage::TRANSPORT_INFO, session_id_); 394 DCHECK(pending_transport_info_message_);
367 message.candidates.swap(pending_candidates_);
368 395
369 scoped_ptr<IqRequest> request = session_manager_->iq_sender()->SendIq( 396 scoped_ptr<IqRequest> request = session_manager_->iq_sender()->SendIq(
370 message.ToXml(), 397 pending_transport_info_message_->ToXml(),
371 base::Bind(&JingleSession::OnTransportInfoResponse, 398 base::Bind(&JingleSession::OnTransportInfoResponse,
372 base::Unretained(this))); 399 base::Unretained(this)));
400 pending_transport_info_message_.reset();
373 if (request) { 401 if (request) {
374 request->SetTimeout(base::TimeDelta::FromSeconds(kTransportInfoTimeout)); 402 request->SetTimeout(base::TimeDelta::FromSeconds(kTransportInfoTimeout));
375 transport_info_requests_.push_back(request.release()); 403 transport_info_requests_.push_back(request.release());
376 } else { 404 } else {
377 LOG(ERROR) << "Failed to send a transport-info message"; 405 LOG(ERROR) << "Failed to send a transport-info message";
378 } 406 }
379 } 407 }
380 408
381 void JingleSession::OnTransportInfoResponse(IqRequest* request, 409 void JingleSession::OnTransportInfoResponse(IqRequest* request,
382 const buzz::XmlElement* response) { 410 const buzz::XmlElement* response) {
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 DLOG(WARNING) << "Received session-accept without authentication message "; 484 DLOG(WARNING) << "Received session-accept without authentication message ";
457 CloseInternal(INCOMPATIBLE_PROTOCOL); 485 CloseInternal(INCOMPATIBLE_PROTOCOL);
458 return; 486 return;
459 } 487 }
460 488
461 if (!InitializeConfigFromDescription(message.description.get())) { 489 if (!InitializeConfigFromDescription(message.description.get())) {
462 CloseInternal(INCOMPATIBLE_PROTOCOL); 490 CloseInternal(INCOMPATIBLE_PROTOCOL);
463 return; 491 return;
464 } 492 }
465 493
466 // In case there is transport information in the accept message.
467 ProcessTransportInfo(message);
468
469 SetState(CONNECTED); 494 SetState(CONNECTED);
470 495
471 DCHECK(authenticator_->state() == Authenticator::WAITING_MESSAGE); 496 DCHECK(authenticator_->state() == Authenticator::WAITING_MESSAGE);
472 authenticator_->ProcessMessage(auth_message, base::Bind( 497 authenticator_->ProcessMessage(auth_message, base::Bind(
473 &JingleSession::ProcessAuthenticationStep,base::Unretained(this))); 498 &JingleSession::ProcessAuthenticationStep,base::Unretained(this)));
474 } 499 }
475 500
476 void JingleSession::OnSessionInfo(const JingleMessage& message, 501 void JingleSession::OnSessionInfo(const JingleMessage& message,
477 const ReplyCallback& reply_callback) { 502 const ReplyCallback& reply_callback) {
478 if (!message.info.get() || 503 if (!message.info.get() ||
(...skipping 11 matching lines...) Expand all
490 return; 515 return;
491 } 516 }
492 517
493 reply_callback.Run(JingleMessageReply::NONE); 518 reply_callback.Run(JingleMessageReply::NONE);
494 519
495 authenticator_->ProcessMessage(message.info.get(), base::Bind( 520 authenticator_->ProcessMessage(message.info.get(), base::Bind(
496 &JingleSession::ProcessAuthenticationStep, base::Unretained(this))); 521 &JingleSession::ProcessAuthenticationStep, base::Unretained(this)));
497 } 522 }
498 523
499 void JingleSession::ProcessTransportInfo(const JingleMessage& message) { 524 void JingleSession::ProcessTransportInfo(const JingleMessage& message) {
525 // Check if the transport information version matches what was negotiated.
526 if (message.standard_ice != config_->standard_ice()) {
527 LOG(ERROR) << "Received transport-info message in format different from "
528 "negotiated.";
529 CloseInternal(INCOMPATIBLE_PROTOCOL);
530 return;
531 }
532
533 for (std::list<JingleMessage::IceCredentials>::const_iterator it =
534 message.ice_credentials.begin();
535 it != message.ice_credentials.end(); ++it) {
536 ChannelsMap::iterator channel = channels_.find(it->channel);
537 if (channel != channels_.end()) {
538 channel->second->SetRemoteCredentials(it->ufrag, it->password);
539 } else {
540 // Transport info was received before the channel was created.
541 // This could happen due to messages being reordered on the wire.
542 pending_remote_ice_credentials_.push_back(*it);
543 }
544 }
545
500 for (std::list<JingleMessage::NamedCandidate>::const_iterator it = 546 for (std::list<JingleMessage::NamedCandidate>::const_iterator it =
501 message.candidates.begin(); 547 message.candidates.begin();
502 it != message.candidates.end(); ++it) { 548 it != message.candidates.end(); ++it) {
503 ChannelsMap::iterator channel = channels_.find(it->name); 549 ChannelsMap::iterator channel = channels_.find(it->name);
504 if (channel != channels_.end()) { 550 if (channel != channels_.end()) {
505 channel->second->AddRemoteCandidate(it->candidate); 551 channel->second->AddRemoteCandidate(it->candidate);
506 } else { 552 } else {
507 // Transport info was received before the channel was created. 553 // Transport info was received before the channel was created.
508 // This could happen due to messages being reordered on the wire. 554 // This could happen due to messages being reordered on the wire.
509 pending_remote_candidates_.push_back(*it); 555 pending_remote_candidates_.push_back(*it);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
548 if (error_ != OK) { 594 if (error_ != OK) {
549 SetState(FAILED); 595 SetState(FAILED);
550 } else { 596 } else {
551 SetState(CLOSED); 597 SetState(CLOSED);
552 } 598 }
553 } 599 }
554 600
555 bool JingleSession::InitializeConfigFromDescription( 601 bool JingleSession::InitializeConfigFromDescription(
556 const ContentDescription* description) { 602 const ContentDescription* description) {
557 DCHECK(description); 603 DCHECK(description);
558 604 config_ = SessionConfig::GetFinalConfig(description->config());
559 if (!description->config()->GetFinalConfig(&config_)) { 605 if (!config_) {
560 LOG(ERROR) << "session-accept does not specify configuration"; 606 LOG(ERROR) << "session-accept does not specify configuration";
561 return false; 607 return false;
562 } 608 }
563 if (!candidate_config()->IsSupported(config_)) { 609 if (!candidate_config()->IsSupported(*config_)) {
564 LOG(ERROR) << "session-accept specifies an invalid configuration"; 610 LOG(ERROR) << "session-accept specifies an invalid configuration";
565 return false; 611 return false;
566 } 612 }
567 613
568 return true; 614 return true;
569 } 615 }
570 616
571 void JingleSession::ProcessAuthenticationStep() { 617 void JingleSession::ProcessAuthenticationStep() {
572 DCHECK(CalledOnValidThread()); 618 DCHECK(CalledOnValidThread());
573 DCHECK_NE(authenticator_->state(), Authenticator::PROCESSING_MESSAGE); 619 DCHECK_NE(authenticator_->state(), Authenticator::PROCESSING_MESSAGE);
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
673 } 719 }
674 } 720 }
675 721
676 bool JingleSession::is_session_active() { 722 bool JingleSession::is_session_active() {
677 return state_ == CONNECTING || state_ == ACCEPTING || state_ == CONNECTED || 723 return state_ == CONNECTING || state_ == ACCEPTING || state_ == CONNECTED ||
678 state_ == AUTHENTICATING || state_ == AUTHENTICATED; 724 state_ == AUTHENTICATING || state_ == AUTHENTICATED;
679 } 725 }
680 726
681 } // namespace protocol 727 } // namespace protocol
682 } // namespace remoting 728 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/protocol/jingle_session.h ('k') | remoting/protocol/jingle_session_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698