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 <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <limits> | 9 #include <limits> |
10 #include <memory> | |
10 #include <utility> | 11 #include <utility> |
11 | 12 |
12 #include "base/bind.h" | 13 #include "base/bind.h" |
14 #include "base/callback.h" | |
13 #include "base/single_thread_task_runner.h" | 15 #include "base/single_thread_task_runner.h" |
14 #include "base/stl_util.h" | 16 #include "base/stl_util.h" |
15 #include "base/strings/string_split.h" | 17 #include "base/strings/string_split.h" |
16 #include "base/threading/thread_task_runner_handle.h" | 18 #include "base/threading/thread_task_runner_handle.h" |
17 #include "base/time/time.h" | 19 #include "base/time/time.h" |
18 #include "remoting/base/constants.h" | 20 #include "remoting/base/constants.h" |
19 #include "remoting/protocol/authenticator.h" | 21 #include "remoting/protocol/authenticator.h" |
20 #include "remoting/protocol/content_description.h" | 22 #include "remoting/protocol/content_description.h" |
21 #include "remoting/protocol/jingle_messages.h" | 23 #include "remoting/protocol/jingle_messages.h" |
22 #include "remoting/protocol/jingle_session_manager.h" | 24 #include "remoting/protocol/jingle_session_manager.h" |
23 #include "remoting/protocol/session_config.h" | 25 #include "remoting/protocol/session_config.h" |
26 #include "remoting/protocol/session_plugin.h" | |
24 #include "remoting/protocol/transport.h" | 27 #include "remoting/protocol/transport.h" |
25 #include "remoting/signaling/iq_sender.h" | 28 #include "remoting/signaling/iq_sender.h" |
26 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h" | 29 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h" |
27 #include "third_party/webrtc/libjingle/xmpp/constants.h" | 30 #include "third_party/webrtc/libjingle/xmpp/constants.h" |
28 #include "third_party/webrtc/p2p/base/candidate.h" | 31 #include "third_party/webrtc/p2p/base/candidate.h" |
29 | 32 |
30 using buzz::XmlElement; | 33 using buzz::XmlElement; |
31 | 34 |
32 namespace remoting { | 35 namespace remoting { |
33 namespace protocol { | 36 namespace protocol { |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
201 peer_address_ = SignalingAddress(peer_jid); | 204 peer_address_ = SignalingAddress(peer_jid); |
202 authenticator_ = std::move(authenticator); | 205 authenticator_ = std::move(authenticator); |
203 | 206 |
204 // Generate random session ID. There are usually not more than 1 | 207 // Generate random session ID. There are usually not more than 1 |
205 // concurrent session per host, so a random 64-bit integer provides | 208 // concurrent session per host, so a random 64-bit integer provides |
206 // enough entropy. In the worst case connection will fail when two | 209 // enough entropy. In the worst case connection will fail when two |
207 // clients generate the same session ID concurrently. | 210 // clients generate the same session ID concurrently. |
208 session_id_ = base::Uint64ToString( | 211 session_id_ = base::Uint64ToString( |
209 base::RandGenerator(std::numeric_limits<uint64_t>::max())); | 212 base::RandGenerator(std::numeric_limits<uint64_t>::max())); |
210 | 213 |
211 // Send session-initiate message. | 214 // Delay sending session-initiate message to ensure SessionPlugin can be |
212 std::unique_ptr<JingleMessage> message(new JingleMessage( | 215 // attached before the message. |
213 peer_address_, JingleMessage::SESSION_INITIATE, session_id_)); | 216 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, |
214 message->initiator = session_manager_->signal_strategy_->GetLocalJid(); | 217 base::Bind(&JingleSession::SendSessionInitiateMessage, |
215 message->description.reset(new ContentDescription( | 218 weak_factory_.GetWeakPtr())); |
216 session_manager_->protocol_config_->Clone(), | |
217 authenticator_->GetNextMessage())); | |
218 SendMessage(std::move(message)); | |
219 | 219 |
220 SetState(CONNECTING); | 220 SetState(CONNECTING); |
221 } | 221 } |
222 | 222 |
223 void JingleSession::InitializeIncomingConnection( | 223 void JingleSession::InitializeIncomingConnection( |
224 const JingleMessage& initiate_message, | 224 const JingleMessage& initiate_message, |
225 std::unique_ptr<Authenticator> authenticator) { | 225 std::unique_ptr<Authenticator> authenticator) { |
226 DCHECK(thread_checker_.CalledOnValidThread()); | 226 DCHECK(thread_checker_.CalledOnValidThread()); |
227 DCHECK(initiate_message.description.get()); | 227 DCHECK(initiate_message.description.get()); |
228 DCHECK(authenticator.get()); | 228 DCHECK(authenticator.get()); |
(...skipping 13 matching lines...) Expand all Loading... | |
242 << " because no compatible configuration has been found."; | 242 << " because no compatible configuration has been found."; |
243 Close(INCOMPATIBLE_PROTOCOL); | 243 Close(INCOMPATIBLE_PROTOCOL); |
244 return; | 244 return; |
245 } | 245 } |
246 } | 246 } |
247 | 247 |
248 void JingleSession::AcceptIncomingConnection( | 248 void JingleSession::AcceptIncomingConnection( |
249 const JingleMessage& initiate_message) { | 249 const JingleMessage& initiate_message) { |
250 DCHECK(config_); | 250 DCHECK(config_); |
251 | 251 |
252 ExecutePluginsOnIncomingMessage(initiate_message); | |
252 // Process the first authentication message. | 253 // Process the first authentication message. |
253 const buzz::XmlElement* first_auth_message = | 254 const buzz::XmlElement* first_auth_message = |
254 initiate_message.description->authenticator_message(); | 255 initiate_message.description->authenticator_message(); |
255 | 256 |
256 if (!first_auth_message) { | 257 if (!first_auth_message) { |
257 Close(INCOMPATIBLE_PROTOCOL); | 258 Close(INCOMPATIBLE_PROTOCOL); |
258 return; | 259 return; |
259 } | 260 } |
260 | 261 |
261 DCHECK_EQ(authenticator_->state(), Authenticator::WAITING_MESSAGE); | 262 DCHECK_EQ(authenticator_->state(), Authenticator::WAITING_MESSAGE); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
315 } | 316 } |
316 | 317 |
317 void JingleSession::SendTransportInfo( | 318 void JingleSession::SendTransportInfo( |
318 std::unique_ptr<buzz::XmlElement> transport_info) { | 319 std::unique_ptr<buzz::XmlElement> transport_info) { |
319 DCHECK(thread_checker_.CalledOnValidThread()); | 320 DCHECK(thread_checker_.CalledOnValidThread()); |
320 DCHECK_EQ(state_, AUTHENTICATED); | 321 DCHECK_EQ(state_, AUTHENTICATED); |
321 | 322 |
322 std::unique_ptr<JingleMessage> message(new JingleMessage( | 323 std::unique_ptr<JingleMessage> message(new JingleMessage( |
323 peer_address_, JingleMessage::TRANSPORT_INFO, session_id_)); | 324 peer_address_, JingleMessage::TRANSPORT_INFO, session_id_)); |
324 message->transport_info = std::move(transport_info); | 325 message->transport_info = std::move(transport_info); |
326 ExecutePluginsOnOutgoingMessage(message.get()); | |
325 | 327 |
326 std::unique_ptr<buzz::XmlElement> stanza = message->ToXml(); | 328 std::unique_ptr<buzz::XmlElement> stanza = message->ToXml(); |
327 stanza->AddAttr(buzz::QN_ID, GetNextOutgoingId()); | 329 stanza->AddAttr(buzz::QN_ID, GetNextOutgoingId()); |
328 | 330 |
329 auto request = session_manager_->iq_sender()->SendIq( | 331 auto request = session_manager_->iq_sender()->SendIq( |
330 std::move(stanza), base::Bind(&JingleSession::OnTransportInfoResponse, | 332 std::move(stanza), base::Bind(&JingleSession::OnTransportInfoResponse, |
331 base::Unretained(this))); | 333 base::Unretained(this))); |
332 if (request) { | 334 if (request) { |
333 request->SetTimeout(base::TimeDelta::FromSeconds(kTransportInfoTimeout)); | 335 request->SetTimeout(base::TimeDelta::FromSeconds(kTransportInfoTimeout)); |
334 transport_info_requests_.push_back(std::move(request)); | 336 transport_info_requests_.push_back(std::move(request)); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
379 | 381 |
380 if (state_ != FAILED && state_ != CLOSED) { | 382 if (state_ != FAILED && state_ != CLOSED) { |
381 if (error != OK) { | 383 if (error != OK) { |
382 SetState(FAILED); | 384 SetState(FAILED); |
383 } else { | 385 } else { |
384 SetState(CLOSED); | 386 SetState(CLOSED); |
385 } | 387 } |
386 } | 388 } |
387 } | 389 } |
388 | 390 |
391 void JingleSession::AddPlugin(SessionPlugin* plugin) { | |
392 DCHECK(plugin); | |
393 plugins_.push_back(plugin); | |
394 } | |
395 | |
389 void JingleSession::SendMessage(std::unique_ptr<JingleMessage> message) { | 396 void JingleSession::SendMessage(std::unique_ptr<JingleMessage> message) { |
390 DCHECK(thread_checker_.CalledOnValidThread()); | 397 DCHECK(thread_checker_.CalledOnValidThread()); |
391 | 398 |
399 ExecutePluginsOnOutgoingMessage(message.get()); | |
Sergey Ulanov
2016/12/27 22:05:18
When the host accepts session-initiate message fro
Hzj_jie
2016/12/27 23:21:08
I see. Thank you for the explanation. I exclude pl
| |
392 std::unique_ptr<buzz::XmlElement> stanza = message->ToXml(); | 400 std::unique_ptr<buzz::XmlElement> stanza = message->ToXml(); |
393 stanza->AddAttr(buzz::QN_ID, GetNextOutgoingId()); | 401 stanza->AddAttr(buzz::QN_ID, GetNextOutgoingId()); |
394 | 402 |
395 auto request = session_manager_->iq_sender()->SendIq( | 403 auto request = session_manager_->iq_sender()->SendIq( |
396 std::move(stanza), base::Bind(&JingleSession::OnMessageResponse, | 404 std::move(stanza), base::Bind(&JingleSession::OnMessageResponse, |
397 base::Unretained(this), message->action)); | 405 base::Unretained(this), message->action)); |
398 | 406 |
399 int timeout = kDefaultMessageTimeout; | 407 int timeout = kDefaultMessageTimeout; |
400 if (message->action == JingleMessage::SESSION_INITIATE || | 408 if (message->action == JingleMessage::SESSION_INITIATE || |
401 message->action == JingleMessage::SESSION_ACCEPT) { | 409 message->action == JingleMessage::SESSION_ACCEPT) { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
475 if (type != "result") { | 483 if (type != "result") { |
476 LOG(ERROR) << "Received error in response to transport-info message: \"" | 484 LOG(ERROR) << "Received error in response to transport-info message: \"" |
477 << response->Str() << "\". Terminating the session."; | 485 << response->Str() << "\". Terminating the session."; |
478 Close(PEER_IS_OFFLINE); | 486 Close(PEER_IS_OFFLINE); |
479 } | 487 } |
480 } | 488 } |
481 | 489 |
482 void JingleSession::OnIncomingMessage(const std::string& id, | 490 void JingleSession::OnIncomingMessage(const std::string& id, |
483 std::unique_ptr<JingleMessage> message, | 491 std::unique_ptr<JingleMessage> message, |
484 const ReplyCallback& reply_callback) { | 492 const ReplyCallback& reply_callback) { |
493 ExecutePluginsOnIncomingMessage(*message); | |
485 std::vector<PendingMessage> ordered = message_queue_->OnIncomingMessage( | 494 std::vector<PendingMessage> ordered = message_queue_->OnIncomingMessage( |
486 id, PendingMessage{std::move(message), reply_callback}); | 495 id, PendingMessage{std::move(message), reply_callback}); |
487 base::WeakPtr<JingleSession> self = weak_factory_.GetWeakPtr(); | 496 base::WeakPtr<JingleSession> self = weak_factory_.GetWeakPtr(); |
488 for (auto& message : ordered) { | 497 for (auto& message : ordered) { |
489 ProcessIncomingMessage(std::move(message.message), message.reply_callback); | 498 ProcessIncomingMessage(std::move(message.message), message.reply_callback); |
490 if (!self) | 499 if (!self) |
491 return; | 500 return; |
492 } | 501 } |
493 } | 502 } |
494 | 503 |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
740 if (event_handler_) | 749 if (event_handler_) |
741 event_handler_->OnSessionStateChange(new_state); | 750 event_handler_->OnSessionStateChange(new_state); |
742 } | 751 } |
743 } | 752 } |
744 | 753 |
745 bool JingleSession::is_session_active() { | 754 bool JingleSession::is_session_active() { |
746 return state_ == CONNECTING || state_ == ACCEPTING || state_ == ACCEPTED || | 755 return state_ == CONNECTING || state_ == ACCEPTING || state_ == ACCEPTED || |
747 state_ == AUTHENTICATING || state_ == AUTHENTICATED; | 756 state_ == AUTHENTICATING || state_ == AUTHENTICATED; |
748 } | 757 } |
749 | 758 |
759 void JingleSession::ExecutePluginsOnIncomingMessage( | |
760 const JingleMessage& message) { | |
761 if (message.attachments) { | |
762 for (const auto& plugin : plugins_) { | |
763 plugin->OnIncomingMessage(state_, *(message.attachments)); | |
764 } | |
765 } | |
766 } | |
767 | |
768 void JingleSession::ExecutePluginsOnOutgoingMessage(JingleMessage* message) { | |
769 DCHECK(message); | |
770 for (const auto& plugin : plugins_) { | |
771 std::unique_ptr<XmlElement> attachment = plugin->GetNextMessage(state_); | |
772 if (attachment) { | |
773 message->AddAttachment(std::move(attachment)); | |
774 } | |
775 } | |
776 } | |
777 | |
778 void JingleSession::SendSessionInitiateMessage() { | |
779 std::unique_ptr<JingleMessage> message(new JingleMessage( | |
780 peer_address_, JingleMessage::SESSION_INITIATE, session_id_)); | |
781 message->initiator = session_manager_->signal_strategy_->GetLocalJid(); | |
782 message->description.reset(new ContentDescription( | |
783 session_manager_->protocol_config_->Clone(), | |
784 authenticator_->GetNextMessage())); | |
785 SendMessage(std::move(message)); | |
786 } | |
787 | |
750 std::string JingleSession::GetNextOutgoingId() { | 788 std::string JingleSession::GetNextOutgoingId() { |
751 return outgoing_id_prefix_ + "_" + base::IntToString(++next_outgoing_id_); | 789 return outgoing_id_prefix_ + "_" + base::IntToString(++next_outgoing_id_); |
752 } | 790 } |
753 | 791 |
754 } // namespace protocol | 792 } // namespace protocol |
755 } // namespace remoting | 793 } // namespace remoting |
OLD | NEW |