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 <utility> | 10 #include <utility> |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 return error_; | 89 return error_; |
90 } | 90 } |
91 | 91 |
92 void JingleSession::StartConnection( | 92 void JingleSession::StartConnection( |
93 const std::string& peer_jid, | 93 const std::string& peer_jid, |
94 std::unique_ptr<Authenticator> authenticator) { | 94 std::unique_ptr<Authenticator> authenticator) { |
95 DCHECK(thread_checker_.CalledOnValidThread()); | 95 DCHECK(thread_checker_.CalledOnValidThread()); |
96 DCHECK(authenticator.get()); | 96 DCHECK(authenticator.get()); |
97 DCHECK_EQ(authenticator->state(), Authenticator::MESSAGE_READY); | 97 DCHECK_EQ(authenticator->state(), Authenticator::MESSAGE_READY); |
98 | 98 |
99 peer_jid_ = peer_jid; | 99 peer_ = Address(peer_jid); |
100 authenticator_ = std::move(authenticator); | 100 authenticator_ = std::move(authenticator); |
101 | 101 |
102 // Generate random session ID. There are usually not more than 1 | 102 // Generate random session ID. There are usually not more than 1 |
103 // concurrent session per host, so a random 64-bit integer provides | 103 // concurrent session per host, so a random 64-bit integer provides |
104 // enough entropy. In the worst case connection will fail when two | 104 // enough entropy. In the worst case connection will fail when two |
105 // clients generate the same session ID concurrently. | 105 // clients generate the same session ID concurrently. |
106 session_id_ = base::Uint64ToString( | 106 session_id_ = base::Uint64ToString( |
107 base::RandGenerator(std::numeric_limits<uint64_t>::max())); | 107 base::RandGenerator(std::numeric_limits<uint64_t>::max())); |
108 | 108 |
109 // Send session-initiate message. | 109 // Send session-initiate message. |
110 JingleMessage message(peer_jid_, JingleMessage::SESSION_INITIATE, | 110 JingleMessage message(peer_, JingleMessage::SESSION_INITIATE, |
111 session_id_); | 111 session_id_); |
112 message.initiator = session_manager_->signal_strategy_->GetLocalJid(); | 112 message.initiator = session_manager_->signal_strategy_->GetLocalJid(); |
113 message.description.reset(new ContentDescription( | 113 message.description.reset(new ContentDescription( |
114 session_manager_->protocol_config_->Clone(), | 114 session_manager_->protocol_config_->Clone(), |
115 authenticator_->GetNextMessage())); | 115 authenticator_->GetNextMessage())); |
116 SendMessage(message); | 116 SendMessage(message); |
117 | 117 |
118 SetState(CONNECTING); | 118 SetState(CONNECTING); |
119 } | 119 } |
120 | 120 |
121 void JingleSession::InitializeIncomingConnection( | 121 void JingleSession::InitializeIncomingConnection( |
122 const JingleMessage& initiate_message, | 122 const JingleMessage& initiate_message, |
123 std::unique_ptr<Authenticator> authenticator) { | 123 std::unique_ptr<Authenticator> authenticator) { |
124 DCHECK(thread_checker_.CalledOnValidThread()); | 124 DCHECK(thread_checker_.CalledOnValidThread()); |
125 DCHECK(initiate_message.description.get()); | 125 DCHECK(initiate_message.description.get()); |
126 DCHECK(authenticator.get()); | 126 DCHECK(authenticator.get()); |
127 DCHECK_EQ(authenticator->state(), Authenticator::WAITING_MESSAGE); | 127 DCHECK_EQ(authenticator->state(), Authenticator::WAITING_MESSAGE); |
128 | 128 |
129 peer_jid_ = initiate_message.from; | 129 peer_ = initiate_message.from; |
130 authenticator_ = std::move(authenticator); | 130 authenticator_ = std::move(authenticator); |
131 session_id_ = initiate_message.sid; | 131 session_id_ = initiate_message.sid; |
132 | 132 |
133 SetState(ACCEPTING); | 133 SetState(ACCEPTING); |
134 | 134 |
135 config_ = | 135 config_ = |
136 SessionConfig::SelectCommon(initiate_message.description->config(), | 136 SessionConfig::SelectCommon(initiate_message.description->config(), |
137 session_manager_->protocol_config_.get()); | 137 session_manager_->protocol_config_.get()); |
138 if (!config_) { | 138 if (!config_) { |
139 LOG(WARNING) << "Rejecting connection from " << peer_jid_ | 139 LOG(WARNING) << "Rejecting connection from " << peer_.endpoint_id |
140 << " because no compatible configuration has been found."; | 140 << " because no compatible configuration has been found."; |
141 Close(INCOMPATIBLE_PROTOCOL); | 141 Close(INCOMPATIBLE_PROTOCOL); |
142 return; | 142 return; |
143 } | 143 } |
144 } | 144 } |
145 | 145 |
146 void JingleSession::AcceptIncomingConnection( | 146 void JingleSession::AcceptIncomingConnection( |
147 const JingleMessage& initiate_message) { | 147 const JingleMessage& initiate_message) { |
148 DCHECK(config_); | 148 DCHECK(config_); |
149 | 149 |
(...skipping 14 matching lines...) Expand all Loading... |
164 } | 164 } |
165 | 165 |
166 void JingleSession::ContinueAcceptIncomingConnection() { | 166 void JingleSession::ContinueAcceptIncomingConnection() { |
167 DCHECK_NE(authenticator_->state(), Authenticator::PROCESSING_MESSAGE); | 167 DCHECK_NE(authenticator_->state(), Authenticator::PROCESSING_MESSAGE); |
168 if (authenticator_->state() == Authenticator::REJECTED) { | 168 if (authenticator_->state() == Authenticator::REJECTED) { |
169 Close(AuthRejectionReasonToErrorCode(authenticator_->rejection_reason())); | 169 Close(AuthRejectionReasonToErrorCode(authenticator_->rejection_reason())); |
170 return; | 170 return; |
171 } | 171 } |
172 | 172 |
173 // Send the session-accept message. | 173 // Send the session-accept message. |
174 JingleMessage message(peer_jid_, JingleMessage::SESSION_ACCEPT, | 174 JingleMessage message(peer_, JingleMessage::SESSION_ACCEPT, |
175 session_id_); | 175 session_id_); |
176 | 176 |
177 std::unique_ptr<buzz::XmlElement> auth_message; | 177 std::unique_ptr<buzz::XmlElement> auth_message; |
178 if (authenticator_->state() == Authenticator::MESSAGE_READY) | 178 if (authenticator_->state() == Authenticator::MESSAGE_READY) |
179 auth_message = authenticator_->GetNextMessage(); | 179 auth_message = authenticator_->GetNextMessage(); |
180 | 180 |
181 message.description.reset(new ContentDescription( | 181 message.description.reset(new ContentDescription( |
182 CandidateSessionConfig::CreateFrom(*config_), std::move(auth_message))); | 182 CandidateSessionConfig::CreateFrom(*config_), std::move(auth_message))); |
183 SendMessage(message); | 183 SendMessage(message); |
184 | 184 |
185 // Update state. | 185 // Update state. |
186 SetState(ACCEPTED); | 186 SetState(ACCEPTED); |
187 | 187 |
188 if (authenticator_->state() == Authenticator::ACCEPTED) { | 188 if (authenticator_->state() == Authenticator::ACCEPTED) { |
189 OnAuthenticated(); | 189 OnAuthenticated(); |
190 } else { | 190 } else { |
191 DCHECK_EQ(authenticator_->state(), Authenticator::WAITING_MESSAGE); | 191 DCHECK_EQ(authenticator_->state(), Authenticator::WAITING_MESSAGE); |
192 if (authenticator_->started()) { | 192 if (authenticator_->started()) { |
193 SetState(AUTHENTICATING); | 193 SetState(AUTHENTICATING); |
194 } | 194 } |
195 } | 195 } |
196 } | 196 } |
197 | 197 |
198 const std::string& JingleSession::jid() { | 198 const std::string& JingleSession::jid() { |
199 DCHECK(thread_checker_.CalledOnValidThread()); | 199 DCHECK(thread_checker_.CalledOnValidThread()); |
200 return peer_jid_; | 200 // Returns the |endpoint_id| instead of the |jid| it uniquely identifies the |
| 201 // peer. |
| 202 return peer_.endpoint_id; |
201 } | 203 } |
202 | 204 |
203 const SessionConfig& JingleSession::config() { | 205 const SessionConfig& JingleSession::config() { |
204 DCHECK(thread_checker_.CalledOnValidThread()); | 206 DCHECK(thread_checker_.CalledOnValidThread()); |
205 return *config_; | 207 return *config_; |
206 } | 208 } |
207 | 209 |
208 void JingleSession::SetTransport(Transport* transport) { | 210 void JingleSession::SetTransport(Transport* transport) { |
209 DCHECK(thread_checker_.CalledOnValidThread()); | 211 DCHECK(thread_checker_.CalledOnValidThread()); |
210 DCHECK(!transport_); | 212 DCHECK(!transport_); |
211 DCHECK(transport); | 213 DCHECK(transport); |
212 transport_ = transport; | 214 transport_ = transport; |
213 } | 215 } |
214 | 216 |
215 void JingleSession::SendTransportInfo( | 217 void JingleSession::SendTransportInfo( |
216 std::unique_ptr<buzz::XmlElement> transport_info) { | 218 std::unique_ptr<buzz::XmlElement> transport_info) { |
217 DCHECK(thread_checker_.CalledOnValidThread()); | 219 DCHECK(thread_checker_.CalledOnValidThread()); |
218 DCHECK_EQ(state_, AUTHENTICATED); | 220 DCHECK_EQ(state_, AUTHENTICATED); |
219 | 221 |
220 JingleMessage message(peer_jid_, JingleMessage::TRANSPORT_INFO, session_id_); | 222 JingleMessage message(peer_, JingleMessage::TRANSPORT_INFO, session_id_); |
221 message.transport_info = std::move(transport_info); | 223 message.transport_info = std::move(transport_info); |
222 | 224 |
223 std::unique_ptr<IqRequest> request = session_manager_->iq_sender()->SendIq( | 225 std::unique_ptr<IqRequest> request = session_manager_->iq_sender()->SendIq( |
224 message.ToXml(), base::Bind(&JingleSession::OnTransportInfoResponse, | 226 message.ToXml(), base::Bind(&JingleSession::OnTransportInfoResponse, |
225 base::Unretained(this))); | 227 base::Unretained(this))); |
226 if (request) { | 228 if (request) { |
227 request->SetTimeout(base::TimeDelta::FromSeconds(kTransportInfoTimeout)); | 229 request->SetTimeout(base::TimeDelta::FromSeconds(kTransportInfoTimeout)); |
228 transport_info_requests_.push_back(request.release()); | 230 transport_info_requests_.push_back(request.release()); |
229 } else { | 231 } else { |
230 LOG(ERROR) << "Failed to send a transport-info message"; | 232 LOG(ERROR) << "Failed to send a transport-info message"; |
(...skipping 23 matching lines...) Expand all Loading... |
254 case MAX_SESSION_LENGTH: | 256 case MAX_SESSION_LENGTH: |
255 reason = JingleMessage::EXPIRED; | 257 reason = JingleMessage::EXPIRED; |
256 break; | 258 break; |
257 case HOST_CONFIGURATION_ERROR: | 259 case HOST_CONFIGURATION_ERROR: |
258 reason = JingleMessage::FAILED_APPLICATION; | 260 reason = JingleMessage::FAILED_APPLICATION; |
259 break; | 261 break; |
260 default: | 262 default: |
261 reason = JingleMessage::GENERAL_ERROR; | 263 reason = JingleMessage::GENERAL_ERROR; |
262 } | 264 } |
263 | 265 |
264 JingleMessage message(peer_jid_, JingleMessage::SESSION_TERMINATE, | 266 JingleMessage message(peer_, JingleMessage::SESSION_TERMINATE, session_id_); |
265 session_id_); | |
266 message.reason = reason; | 267 message.reason = reason; |
267 SendMessage(message); | 268 SendMessage(message); |
268 } | 269 } |
269 | 270 |
270 error_ = error; | 271 error_ = error; |
271 | 272 |
272 if (state_ != FAILED && state_ != CLOSED) { | 273 if (state_ != FAILED && state_ != CLOSED) { |
273 if (error != OK) { | 274 if (error != OK) { |
274 SetState(FAILED); | 275 SetState(FAILED); |
275 } else { | 276 } else { |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 LOG(ERROR) << "Received error in response to transport-info message: \"" | 364 LOG(ERROR) << "Received error in response to transport-info message: \"" |
364 << response->Str() << "\". Terminating the session."; | 365 << response->Str() << "\". Terminating the session."; |
365 Close(PEER_IS_OFFLINE); | 366 Close(PEER_IS_OFFLINE); |
366 } | 367 } |
367 } | 368 } |
368 | 369 |
369 void JingleSession::OnIncomingMessage(const JingleMessage& message, | 370 void JingleSession::OnIncomingMessage(const JingleMessage& message, |
370 const ReplyCallback& reply_callback) { | 371 const ReplyCallback& reply_callback) { |
371 DCHECK(thread_checker_.CalledOnValidThread()); | 372 DCHECK(thread_checker_.CalledOnValidThread()); |
372 | 373 |
373 if (message.from != peer_jid_) { | 374 if (peer_ != message.from) { |
374 // Ignore messages received from a different Jid. | 375 // Ignore messages received from a different Jid. |
375 reply_callback.Run(JingleMessageReply::INVALID_SID); | 376 reply_callback.Run(JingleMessageReply::INVALID_SID); |
376 return; | 377 return; |
377 } | 378 } |
378 | 379 |
379 switch (message.action) { | 380 switch (message.action) { |
380 case JingleMessage::SESSION_ACCEPT: | 381 case JingleMessage::SESSION_ACCEPT: |
381 OnAccept(message, reply_callback); | 382 OnAccept(message, reply_callback); |
382 break; | 383 break; |
383 | 384 |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
531 DCHECK_NE(authenticator_->state(), Authenticator::PROCESSING_MESSAGE); | 532 DCHECK_NE(authenticator_->state(), Authenticator::PROCESSING_MESSAGE); |
532 | 533 |
533 if (state_ != ACCEPTED && state_ != AUTHENTICATING) { | 534 if (state_ != ACCEPTED && state_ != AUTHENTICATING) { |
534 DCHECK(state_ == FAILED || state_ == CLOSED); | 535 DCHECK(state_ == FAILED || state_ == CLOSED); |
535 // The remote host closed the connection while the authentication was being | 536 // The remote host closed the connection while the authentication was being |
536 // processed asynchronously, nothing to do. | 537 // processed asynchronously, nothing to do. |
537 return; | 538 return; |
538 } | 539 } |
539 | 540 |
540 if (authenticator_->state() == Authenticator::MESSAGE_READY) { | 541 if (authenticator_->state() == Authenticator::MESSAGE_READY) { |
541 JingleMessage message(peer_jid_, JingleMessage::SESSION_INFO, session_id_); | 542 JingleMessage message(peer_, JingleMessage::SESSION_INFO, session_id_); |
542 message.info = authenticator_->GetNextMessage(); | 543 message.info = authenticator_->GetNextMessage(); |
543 DCHECK(message.info.get()); | 544 DCHECK(message.info.get()); |
544 SendMessage(message); | 545 SendMessage(message); |
545 } | 546 } |
546 DCHECK_NE(authenticator_->state(), Authenticator::MESSAGE_READY); | 547 DCHECK_NE(authenticator_->state(), Authenticator::MESSAGE_READY); |
547 | 548 |
548 // The current JingleSession object can be destroyed by event_handler of | 549 // The current JingleSession object can be destroyed by event_handler of |
549 // SetState(AUTHENTICATING) and cause subsequent dereferencing of the this | 550 // SetState(AUTHENTICATING) and cause subsequent dereferencing of the this |
550 // pointer to crash. To protect against it, we run ContinueAuthenticationStep | 551 // pointer to crash. To protect against it, we run ContinueAuthenticationStep |
551 // asychronously using a weak pointer. | 552 // asychronously using a weak pointer. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
589 } | 590 } |
590 } | 591 } |
591 | 592 |
592 bool JingleSession::is_session_active() { | 593 bool JingleSession::is_session_active() { |
593 return state_ == CONNECTING || state_ == ACCEPTING || state_ == ACCEPTED || | 594 return state_ == CONNECTING || state_ == ACCEPTING || state_ == ACCEPTED || |
594 state_ == AUTHENTICATING || state_ == AUTHENTICATED; | 595 state_ == AUTHENTICATING || state_ == AUTHENTICATED; |
595 } | 596 } |
596 | 597 |
597 } // namespace protocol | 598 } // namespace protocol |
598 } // namespace remoting | 599 } // namespace remoting |
OLD | NEW |