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

Side by Side Diff: remoting/host/chromoting_host.cc

Issue 6711033: A new authenticated connection evicts an old one. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 9 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/host/chromoting_host.h" 5 #include "remoting/host/chromoting_host.h"
6 6
7 #include "base/stl_util-inl.h" 7 #include "base/stl_util-inl.h"
8 #include "base/task.h" 8 #include "base/task.h"
9 #include "build/build_config.h" 9 #include "build/build_config.h"
10 #include "remoting/base/constants.h" 10 #include "remoting/base/constants.h"
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 return; 133 return;
134 } 134 }
135 state_ = kStopped; 135 state_ = kStopped;
136 } 136 }
137 137
138 // Make sure ScreenRecorder doesn't write to the connection. 138 // Make sure ScreenRecorder doesn't write to the connection.
139 if (recorder_.get()) { 139 if (recorder_.get()) {
140 recorder_->RemoveAllConnections(); 140 recorder_->RemoveAllConnections();
141 } 141 }
142 142
143 // Disconnect the client. 143 // Disconnect the clients.
144 if (connection_) { 144 for (size_t i = 0; i < connections_.size(); i++) {
145 connection_->Disconnect(); 145 connections_[i]->Disconnect();
146 } 146 }
147 147
148 // Stop the heartbeat sender. 148 // Stop the heartbeat sender.
149 if (heartbeat_sender_) { 149 if (heartbeat_sender_) {
150 heartbeat_sender_->Stop(); 150 heartbeat_sender_->Stop();
151 } 151 }
152 152
153 // Stop chromotocol session manager. 153 // Stop chromotocol session manager.
154 if (session_manager_) { 154 if (session_manager_) {
155 session_manager_->Close( 155 session_manager_->Close(
156 NewRunnableMethod(this, &ChromotingHost::OnServerClosed)); 156 NewRunnableMethod(this, &ChromotingHost::OnServerClosed));
157 } 157 }
158 158
159 // Disconnect from the talk network. 159 // Disconnect from the talk network.
160 if (jingle_client_) { 160 if (jingle_client_) {
161 jingle_client_->Close(); 161 jingle_client_->Close();
162 } 162 }
163 163
164 if (recorder_.get()) { 164 if (recorder_.get()) {
165 recorder_->Stop(shutdown_task_.release()); 165 recorder_->Stop(shutdown_task_.release());
166 } else { 166 } else {
167 shutdown_task_->Run(); 167 shutdown_task_->Run();
168 shutdown_task_.reset(); 168 shutdown_task_.reset();
169 } 169 }
170 } 170 }
171 171
172 // This method is called when a client connects. 172 // This method is called when a client connects.
173 void ChromotingHost::OnClientConnected(ConnectionToClient* connection) { 173 void ChromotingHost::OnClientConnected(ConnectionToClient* connection) {
174 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current()); 174 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current());
175
176 // Create a new RecordSession if there was none.
177 if (!recorder_.get()) {
178 // Then we create a ScreenRecorder passing the message loops that
179 // it should run on.
180 DCHECK(desktop_environment_->capturer());
181
182 Encoder* encoder = CreateEncoder(connection->session()->config());
183
184 recorder_ = new ScreenRecorder(context_->main_message_loop(),
185 context_->encode_message_loop(),
186 context_->network_message_loop(),
187 desktop_environment_->capturer(),
188 encoder);
189 }
190
191 // Immediately add the connection and start the session.
192 recorder_->AddConnection(connection);
193 } 175 }
194 176
195 void ChromotingHost::OnClientDisconnected(ConnectionToClient* connection) { 177 void ChromotingHost::OnClientDisconnected(ConnectionToClient* connection) {
196 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current()); 178 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current());
197 179
198 // Remove the connection from the session manager and stop the session. 180 // Remove the connection from the session manager and stop the session.
199 // TODO(hclam): Stop only if the last connection disconnected.
200 if (recorder_.get()) { 181 if (recorder_.get()) {
201 recorder_->RemoveConnection(connection); 182 recorder_->RemoveConnection(connection);
202 recorder_->Stop(NULL); 183 // If the client is authenticated, then it was the only reason for running
203 recorder_ = NULL; 184 // the recorder.
185 if (connection->client_authenticated()) {
186 recorder_->Stop(NULL);
187 recorder_ = NULL;
188 }
204 } 189 }
205 190
206 // Close the connection to connection just to be safe. 191 // Close the connection to connection just to be safe.
207 connection->Disconnect(); 192 connection->Disconnect();
208 193
209 // Also remove reference to ConnectionToClient from this object. 194 // Also remove reference to ConnectionToClient from this object.
210 connection_ = NULL; 195 std::vector<scoped_refptr<protocol::ConnectionToClient>>::iterator it =
196 std::find(connections_.begin(), connections_.end(), connection);
197 if (it != connections_.end())
198 connections_.erase(it);
211 } 199 }
212 200
213 //////////////////////////////////////////////////////////////////////////// 201 ////////////////////////////////////////////////////////////////////////////
214 // protocol::ConnectionToClient::EventHandler implementations 202 // protocol::ConnectionToClient::EventHandler implementations
215 void ChromotingHost::OnConnectionOpened(ConnectionToClient* connection) { 203 void ChromotingHost::OnConnectionOpened(ConnectionToClient* connection) {
216 DCHECK_EQ(context_->network_message_loop(), MessageLoop::current()); 204 DCHECK_EQ(context_->network_message_loop(), MessageLoop::current());
217 205
218 // Completes the connection to the client. 206 // Completes the connection to the client.
219 VLOG(1) << "Connection to client established."; 207 VLOG(1) << "Connection to client established.";
220 context_->main_message_loop()->PostTask( 208 context_->main_message_loop()->PostTask(
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 // TODO(sergeyu): We should try reconnecting here instead of terminating 268 // TODO(sergeyu): We should try reconnecting here instead of terminating
281 // the host. 269 // the host.
282 Shutdown(); 270 Shutdown();
283 } 271 }
284 } 272 }
285 273
286 void ChromotingHost::OnNewClientSession( 274 void ChromotingHost::OnNewClientSession(
287 protocol::Session* session, 275 protocol::Session* session,
288 protocol::SessionManager::IncomingSessionResponse* response) { 276 protocol::SessionManager::IncomingSessionResponse* response) {
289 base::AutoLock auto_lock(lock_); 277 base::AutoLock auto_lock(lock_);
290 // TODO(hclam): Allow multiple clients to connect to the host. 278 if (state_ != kStarted) {
291 if (connection_.get() || state_ != kStarted) {
292 *response = protocol::SessionManager::DECLINE; 279 *response = protocol::SessionManager::DECLINE;
293 return; 280 return;
294 } 281 }
295 282
296 // Check that the client has access to the host. 283 // Check that the client has access to the host.
297 if (!access_verifier_.VerifyPermissions(session->jid(), 284 if (!access_verifier_.VerifyPermissions(session->jid(),
298 session->initiator_token())) { 285 session->initiator_token())) {
299 *response = protocol::SessionManager::DECLINE; 286 *response = protocol::SessionManager::DECLINE;
300 return; 287 return;
301 } 288 }
(...skipping 15 matching lines...) Expand all
317 304
318 session->set_config(config); 305 session->set_config(config);
319 session->set_receiver_token( 306 session->set_receiver_token(
320 GenerateHostAuthToken(session->initiator_token())); 307 GenerateHostAuthToken(session->initiator_token()));
321 308
322 *response = protocol::SessionManager::ACCEPT; 309 *response = protocol::SessionManager::ACCEPT;
323 310
324 VLOG(1) << "Client connected: " << session->jid(); 311 VLOG(1) << "Client connected: " << session->jid();
325 312
326 // If we accept the connected then create a connection object. 313 // If we accept the connected then create a connection object.
327 connection_ = new ConnectionToClient(context_->network_message_loop(), 314 ConnectionToClient* connection = new ConnectionToClient(
328 this, 315 context_->network_message_loop(),
329 desktop_environment_.get(), 316 this,
330 desktop_environment_->input_stub()); 317 desktop_environment_.get(),
331 connection_->Init(session); 318 desktop_environment_->input_stub());
319
320 connection->Init(session);
321
322 connections_.push_back(connection);
332 } 323 }
333 324
334 void ChromotingHost::set_protocol_config( 325 void ChromotingHost::set_protocol_config(
335 protocol::CandidateSessionConfig* config) { 326 protocol::CandidateSessionConfig* config) {
336 DCHECK(config_.get()); 327 DCHECK(config_.get());
337 DCHECK_EQ(state_, kInitial); 328 DCHECK_EQ(state_, kInitial);
338 protocol_config_.reset(config); 329 protocol_config_.reset(config);
339 } 330 }
340 331
341 protocol::HostStub* ChromotingHost::host_stub() const { 332 protocol::HostStub* ChromotingHost::host_stub() const {
(...skipping 22 matching lines...) Expand all
364 355
365 return NULL; 356 return NULL;
366 } 357 }
367 358
368 std::string ChromotingHost::GenerateHostAuthToken( 359 std::string ChromotingHost::GenerateHostAuthToken(
369 const std::string& encoded_client_token) { 360 const std::string& encoded_client_token) {
370 // TODO(ajwong): Return the signature of this instead. 361 // TODO(ajwong): Return the signature of this instead.
371 return encoded_client_token; 362 return encoded_client_token;
372 } 363 }
373 364
374 void ChromotingHost::LocalLoginSucceeded() { 365 void ChromotingHost::LocalLoginSucceeded(ConnectionToClient* connection) {
375 if (MessageLoop::current() != context_->main_message_loop()) { 366 if (MessageLoop::current() != context_->main_message_loop()) {
376 context_->main_message_loop()->PostTask( 367 context_->main_message_loop()->PostTask(
377 FROM_HERE, 368 FROM_HERE,
378 NewRunnableMethod(this, &ChromotingHost::LocalLoginSucceeded)); 369 NewRunnableMethod(this,
370 &ChromotingHost::LocalLoginSucceeded,
371 connection));
379 return; 372 return;
380 } 373 }
381 374
382 protocol::LocalLoginStatus* status = new protocol::LocalLoginStatus(); 375 protocol::LocalLoginStatus* status = new protocol::LocalLoginStatus();
383 status->set_success(true); 376 status->set_success(true);
384 connection_->client_stub()->BeginSessionResponse( 377 connection->client_stub()->BeginSessionResponse(
385 status, new DeleteTask<protocol::LocalLoginStatus>(status)); 378 status, new DeleteTask<protocol::LocalLoginStatus>(status));
386 379
387 connection_->OnClientAuthenticated(); 380 connection->OnClientAuthenticated();
381
382 // Disconnect all other clients.
383 std::vector<scoped_refptr<protocol::ConnectionToClient>> conns_copy(
384 connections_);
385 std::vector<scoped_refptr<protocol::ConnectionToClient>>::const_iterator conn;
386 for (conn = conns_copy.begin(); conn != conns_copy.end(); conn++) {
387 if (conn->get() != connection) {
388 OnClientDisconnected(conn->get());
389 }
390 }
391 // Those disconnections should have killed the screen recorder.
392 DCHECK(recorder_.get() == NULL);
393
394 // Create a new RecordSession if there was none.
395 if (!recorder_.get()) {
396 // Then we create a ScreenRecorder passing the message loops that
397 // it should run on.
398 DCHECK(desktop_environment_->capturer());
399
400 Encoder* encoder = CreateEncoder(connection->session()->config());
401
402 recorder_ = new ScreenRecorder(context_->main_message_loop(),
403 context_->encode_message_loop(),
404 context_->network_message_loop(),
405 desktop_environment_->capturer(),
406 encoder);
407 }
408
409 // Immediately add the connection and start the session.
410 recorder_->AddConnection(connection);
388 recorder_->Start(); 411 recorder_->Start();
389 } 412 }
390 413
391 void ChromotingHost::LocalLoginFailed() { 414 void ChromotingHost::LocalLoginFailed(ConnectionToClient* connection) {
392 if (MessageLoop::current() != context_->main_message_loop()) { 415 if (MessageLoop::current() != context_->main_message_loop()) {
393 context_->main_message_loop()->PostTask( 416 context_->main_message_loop()->PostTask(
394 FROM_HERE, 417 FROM_HERE,
395 NewRunnableMethod(this, &ChromotingHost::LocalLoginFailed)); 418 NewRunnableMethod(this, &ChromotingHost::LocalLoginFailed, connection));
396 return; 419 return;
397 } 420 }
398 421
399 protocol::LocalLoginStatus* status = new protocol::LocalLoginStatus(); 422 protocol::LocalLoginStatus* status = new protocol::LocalLoginStatus();
400 status->set_success(false); 423 status->set_success(false);
401 connection_->client_stub()->BeginSessionResponse( 424 connection->client_stub()->BeginSessionResponse(
402 status, new DeleteTask<protocol::LocalLoginStatus>(status)); 425 status, new DeleteTask<protocol::LocalLoginStatus>(status));
403 } 426 }
404 427
405 } // namespace remoting 428 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698