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