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