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
3 // found in the LICENSE file.
5 #include "remoting/protocol/jingle_session.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/run_loop.h"
10 #include "base/test/test_timeouts.h"
11 #include "base/time/time.h"
12 #include "jingle/glue/thread_wrapper.h"
13 #include "net/socket/socket.h"
14 #include "net/socket/stream_socket.h"
15 #include "net/url_request/url_request_context_getter.h"
16 #include "remoting/base/constants.h"
17 #include "remoting/protocol/authenticator.h"
18 #include "remoting/protocol/channel_authenticator.h"
19 #include "remoting/protocol/chromium_port_allocator.h"
20 #include "remoting/protocol/connection_tester.h"
21 #include "remoting/protocol/fake_authenticator.h"
22 #include "remoting/protocol/jingle_session_manager.h"
23 #include "remoting/protocol/libjingle_transport_factory.h"
24 #include "remoting/protocol/network_settings.h"
25 #include "remoting/protocol/p2p_stream_socket.h"
26 #include "remoting/protocol/stream_channel_factory.h"
27 #include "remoting/signaling/fake_signal_strategy.h"
28 #include "testing/gmock/include/gmock/gmock.h"
29 #include "testing/gtest/include/gtest/gtest.h"
32 using testing::AtLeast
;
33 using testing::AtMost
;
34 using testing::DeleteArg
;
36 using testing::InSequence
;
37 using testing::Invoke
;
38 using testing::InvokeWithoutArgs
;
39 using testing::Return
;
40 using testing::SaveArg
;
41 using testing::SetArgumentPointee
;
42 using testing::WithArg
;
49 const char kHostJid
[] = "host1@gmail.com/123";
50 const char kClientJid
[] = "host2@gmail.com/321";
52 // Send 100 messages 1024 bytes each. UDP messages are sent with 10ms delay
53 // between messages (about 1 second for 100 messages).
54 const int kMessageSize
= 1024;
55 const int kMessages
= 100;
56 const char kChannelName
[] = "test_channel";
58 void QuitCurrentThread() {
59 base::MessageLoop::current()->PostTask(FROM_HERE
,
60 base::MessageLoop::QuitClosure());
67 ACTION_P(QuitThreadOnCounter
, counter
) {
69 EXPECT_GE(*counter
, 0);
74 class MockSessionManagerListener
: public SessionManager::Listener
{
76 MOCK_METHOD0(OnSessionManagerReady
, void());
77 MOCK_METHOD2(OnIncomingSession
,
79 SessionManager::IncomingSessionResponse
*));
82 class MockSessionEventHandler
: public Session::EventHandler
{
84 MOCK_METHOD1(OnSessionStateChange
, void(Session::State
));
85 MOCK_METHOD2(OnSessionRouteChange
, void(const std::string
& channel_name
,
86 const TransportRoute
& route
));
89 class MockChannelCreatedCallback
{
91 MOCK_METHOD1(OnDone
, void(P2PStreamSocket
* socket
));
96 class JingleSessionTest
: public testing::Test
{
99 message_loop_
.reset(new base::MessageLoopForIO());
100 jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop();
103 // Helper method that handles OnIncomingSession().
104 void SetHostSession(Session
* session
) {
106 host_session_
.reset(session
);
107 host_session_
->SetEventHandler(&host_session_event_handler_
);
109 session
->set_config(standard_ice_
? SessionConfig::ForTest()
110 : SessionConfig::WithLegacyIceForTest());
113 void DeleteSession() {
114 host_session_
.reset();
117 void OnClientChannelCreated(scoped_ptr
<P2PStreamSocket
> socket
) {
118 client_channel_callback_
.OnDone(socket
.get());
119 client_socket_
= socket
.Pass();
122 void OnHostChannelCreated(scoped_ptr
<P2PStreamSocket
> socket
) {
123 host_channel_callback_
.OnDone(socket
.get());
124 host_socket_
= socket
.Pass();
128 void SetUp() override
{}
130 void TearDown() override
{
132 CloseSessionManager();
133 base::RunLoop().RunUntilIdle();
136 void CloseSessions() {
137 host_socket_
.reset();
138 host_session_
.reset();
139 client_socket_
.reset();
140 client_session_
.reset();
143 void CreateSessionManagers(int auth_round_trips
, int messages_till_start
,
144 FakeAuthenticator::Action auth_action
) {
145 host_signal_strategy_
.reset(new FakeSignalStrategy(kHostJid
));
146 client_signal_strategy_
.reset(new FakeSignalStrategy(kClientJid
));
147 FakeSignalStrategy::Connect(host_signal_strategy_
.get(),
148 client_signal_strategy_
.get());
150 EXPECT_CALL(host_server_listener_
, OnSessionManagerReady())
153 NetworkSettings
network_settings(NetworkSettings::NAT_TRAVERSAL_OUTGOING
);
155 scoped_ptr
<TransportFactory
> host_transport(new LibjingleTransportFactory(
157 ChromiumPortAllocator::Create(nullptr, network_settings
).Pass(),
158 network_settings
, TransportRole::SERVER
));
159 host_server_
.reset(new JingleSessionManager(host_transport
.Pass()));
160 host_server_
->Init(host_signal_strategy_
.get(), &host_server_listener_
);
162 scoped_ptr
<AuthenticatorFactory
> factory(
163 new FakeHostAuthenticatorFactory(auth_round_trips
,
164 messages_till_start
, auth_action
, true));
165 host_server_
->set_authenticator_factory(factory
.Pass());
167 EXPECT_CALL(client_server_listener_
, OnSessionManagerReady())
169 scoped_ptr
<TransportFactory
> client_transport(new LibjingleTransportFactory(
171 ChromiumPortAllocator::Create(nullptr, network_settings
).Pass(),
172 network_settings
, TransportRole::CLIENT
));
173 client_server_
.reset(
174 new JingleSessionManager(client_transport
.Pass()));
175 client_server_
->Init(client_signal_strategy_
.get(),
176 &client_server_listener_
);
179 void CreateSessionManagers(int auth_round_trips
,
180 FakeAuthenticator::Action auth_action
) {
181 CreateSessionManagers(auth_round_trips
, 0, auth_action
);
184 void CloseSessionManager() {
185 if (host_server_
.get()) {
186 host_server_
->Close();
187 host_server_
.reset();
189 if (client_server_
.get()) {
190 client_server_
->Close();
191 client_server_
.reset();
193 host_signal_strategy_
.reset();
194 client_signal_strategy_
.reset();
197 void InitiateConnection(int auth_round_trips
,
198 FakeAuthenticator::Action auth_action
,
200 EXPECT_CALL(host_server_listener_
, OnIncomingSession(_
, _
))
202 WithArg
<0>(Invoke(this, &JingleSessionTest::SetHostSession
)),
203 SetArgumentPointee
<1>(protocol::SessionManager::ACCEPT
)));
208 EXPECT_CALL(host_session_event_handler_
,
209 OnSessionStateChange(Session::CONNECTED
))
211 EXPECT_CALL(host_session_event_handler_
,
212 OnSessionStateChange(Session::AUTHENTICATING
))
215 EXPECT_CALL(host_session_event_handler_
,
216 OnSessionStateChange(Session::FAILED
))
219 EXPECT_CALL(host_session_event_handler_
,
220 OnSessionStateChange(Session::AUTHENTICATED
))
222 // Expect that the connection will be closed eventually.
223 EXPECT_CALL(host_session_event_handler_
,
224 OnSessionStateChange(Session::CLOSED
))
232 EXPECT_CALL(client_session_event_handler_
,
233 OnSessionStateChange(Session::CONNECTED
))
235 EXPECT_CALL(client_session_event_handler_
,
236 OnSessionStateChange(Session::AUTHENTICATING
))
239 EXPECT_CALL(client_session_event_handler_
,
240 OnSessionStateChange(Session::FAILED
))
243 EXPECT_CALL(client_session_event_handler_
,
244 OnSessionStateChange(Session::AUTHENTICATED
))
246 // Expect that the connection will be closed eventually.
247 EXPECT_CALL(client_session_event_handler_
,
248 OnSessionStateChange(Session::CLOSED
))
253 scoped_ptr
<Authenticator
> authenticator(new FakeAuthenticator(
254 FakeAuthenticator::CLIENT
, auth_round_trips
, auth_action
, true));
256 client_session_
= client_server_
->Connect(
257 kHostJid
, authenticator
.Pass(),
258 CandidateSessionConfig::CreateDefault());
259 client_session_
->SetEventHandler(&client_session_event_handler_
);
261 base::RunLoop().RunUntilIdle();
264 void CreateChannel() {
265 client_session_
->GetTransportChannelFactory()->CreateChannel(
266 kChannelName
, base::Bind(&JingleSessionTest::OnClientChannelCreated
,
267 base::Unretained(this)));
268 host_session_
->GetTransportChannelFactory()->CreateChannel(
269 kChannelName
, base::Bind(&JingleSessionTest::OnHostChannelCreated
,
270 base::Unretained(this)));
273 ExpectRouteChange(kChannelName
);
274 EXPECT_CALL(client_channel_callback_
, OnDone(_
))
275 .WillOnce(QuitThreadOnCounter(&counter
));
276 EXPECT_CALL(host_channel_callback_
, OnDone(_
))
277 .WillOnce(QuitThreadOnCounter(&counter
));
278 message_loop_
->Run();
280 EXPECT_TRUE(client_socket_
.get());
281 EXPECT_TRUE(host_socket_
.get());
284 void ExpectRouteChange(const std::string
& channel_name
) {
285 EXPECT_CALL(host_session_event_handler_
,
286 OnSessionRouteChange(channel_name
, _
))
288 EXPECT_CALL(client_session_event_handler_
,
289 OnSessionRouteChange(channel_name
, _
))
293 scoped_ptr
<base::MessageLoopForIO
> message_loop_
;
295 bool standard_ice_
= true;
297 scoped_ptr
<FakeSignalStrategy
> host_signal_strategy_
;
298 scoped_ptr
<FakeSignalStrategy
> client_signal_strategy_
;
300 scoped_ptr
<JingleSessionManager
> host_server_
;
301 MockSessionManagerListener host_server_listener_
;
302 scoped_ptr
<JingleSessionManager
> client_server_
;
303 MockSessionManagerListener client_server_listener_
;
305 scoped_ptr
<Session
> host_session_
;
306 MockSessionEventHandler host_session_event_handler_
;
307 scoped_ptr
<Session
> client_session_
;
308 MockSessionEventHandler client_session_event_handler_
;
310 MockChannelCreatedCallback client_channel_callback_
;
311 MockChannelCreatedCallback host_channel_callback_
;
313 scoped_ptr
<P2PStreamSocket
> client_socket_
;
314 scoped_ptr
<P2PStreamSocket
> host_socket_
;
318 // Verify that we can create and destroy session managers without a
320 TEST_F(JingleSessionTest
, CreateAndDestoy
) {
321 CreateSessionManagers(1, FakeAuthenticator::ACCEPT
);
324 // Verify that an incoming session can be rejected, and that the
325 // status of the connection is set to FAILED in this case.
326 TEST_F(JingleSessionTest
, RejectConnection
) {
327 CreateSessionManagers(1, FakeAuthenticator::ACCEPT
);
329 // Reject incoming session.
330 EXPECT_CALL(host_server_listener_
, OnIncomingSession(_
, _
))
331 .WillOnce(SetArgumentPointee
<1>(protocol::SessionManager::DECLINE
));
335 EXPECT_CALL(client_session_event_handler_
,
336 OnSessionStateChange(Session::FAILED
))
340 scoped_ptr
<Authenticator
> authenticator(new FakeAuthenticator(
341 FakeAuthenticator::CLIENT
, 1, FakeAuthenticator::ACCEPT
, true));
342 client_session_
= client_server_
->Connect(
343 kHostJid
, authenticator
.Pass(), CandidateSessionConfig::CreateDefault());
344 client_session_
->SetEventHandler(&client_session_event_handler_
);
346 base::RunLoop().RunUntilIdle();
349 // Verify that we can connect two endpoints with single-step authentication.
350 TEST_F(JingleSessionTest
, Connect
) {
351 CreateSessionManagers(1, FakeAuthenticator::ACCEPT
);
352 InitiateConnection(1, FakeAuthenticator::ACCEPT
, false);
354 // Verify that the client specified correct initiator value.
355 ASSERT_GT(host_signal_strategy_
->received_messages().size(), 0U);
356 const buzz::XmlElement
* initiate_xml
=
357 host_signal_strategy_
->received_messages().front();
358 const buzz::XmlElement
* jingle_element
=
359 initiate_xml
->FirstNamed(buzz::QName("urn:xmpp:jingle:1", "jingle"));
360 ASSERT_TRUE(jingle_element
);
361 ASSERT_EQ(kClientJid
,
362 jingle_element
->Attr(buzz::QName(std::string(), "initiator")));
365 // Verify that we can connect two endpoints with multi-step authentication.
366 TEST_F(JingleSessionTest
, ConnectWithMultistep
) {
367 CreateSessionManagers(3, FakeAuthenticator::ACCEPT
);
368 InitiateConnection(3, FakeAuthenticator::ACCEPT
, false);
371 // Verify that connection is terminated when single-step auth fails.
372 TEST_F(JingleSessionTest
, ConnectWithBadAuth
) {
373 CreateSessionManagers(1, FakeAuthenticator::REJECT
);
374 InitiateConnection(1, FakeAuthenticator::ACCEPT
, true);
377 // Verify that connection is terminated when multi-step auth fails.
378 TEST_F(JingleSessionTest
, ConnectWithBadMultistepAuth
) {
379 CreateSessionManagers(3, FakeAuthenticator::REJECT
);
380 InitiateConnection(3, FakeAuthenticator::ACCEPT
, true);
383 // Verify that data can be sent over stream channel.
384 TEST_F(JingleSessionTest
, TestStreamChannel
) {
385 CreateSessionManagers(1, FakeAuthenticator::ACCEPT
);
386 ASSERT_NO_FATAL_FAILURE(
387 InitiateConnection(1, FakeAuthenticator::ACCEPT
, false));
389 ASSERT_NO_FATAL_FAILURE(CreateChannel());
391 StreamConnectionTester
tester(host_socket_
.get(), client_socket_
.get(),
392 kMessageSize
, kMessages
);
394 message_loop_
->Run();
395 tester
.CheckResults();
398 // Verify that we can still connect using legacy GICE transport.
399 TEST_F(JingleSessionTest
, TestLegacyIceConnection
) {
400 standard_ice_
= false;
402 CreateSessionManagers(1, FakeAuthenticator::ACCEPT
);
403 ASSERT_NO_FATAL_FAILURE(
404 InitiateConnection(1, FakeAuthenticator::ACCEPT
, false));
406 ASSERT_NO_FATAL_FAILURE(CreateChannel());
408 StreamConnectionTester
tester(host_socket_
.get(), client_socket_
.get(),
409 kMessageSize
, kMessages
);
411 message_loop_
->Run();
412 tester
.CheckResults();
415 TEST_F(JingleSessionTest
, DeleteSessionOnIncomingConnection
) {
416 CreateSessionManagers(3, FakeAuthenticator::ACCEPT
);
418 EXPECT_CALL(host_server_listener_
, OnIncomingSession(_
, _
))
420 WithArg
<0>(Invoke(this, &JingleSessionTest::SetHostSession
)),
421 SetArgumentPointee
<1>(protocol::SessionManager::ACCEPT
)));
423 EXPECT_CALL(host_session_event_handler_
,
424 OnSessionStateChange(Session::CONNECTED
))
427 EXPECT_CALL(host_session_event_handler_
,
428 OnSessionStateChange(Session::AUTHENTICATING
))
429 .WillOnce(InvokeWithoutArgs(this, &JingleSessionTest::DeleteSession
));
431 scoped_ptr
<Authenticator
> authenticator(new FakeAuthenticator(
432 FakeAuthenticator::CLIENT
, 3, FakeAuthenticator::ACCEPT
, true));
434 client_session_
= client_server_
->Connect(
435 kHostJid
, authenticator
.Pass(),
436 CandidateSessionConfig::CreateDefault());
438 base::RunLoop().RunUntilIdle();
441 TEST_F(JingleSessionTest
, DeleteSessionOnAuth
) {
442 // Same as the previous test, but set messages_till_started to 2 in
443 // CreateSessionManagers so that the session will goes into the
444 // AUTHENTICATING state after two message exchanges.
445 CreateSessionManagers(3, 2, FakeAuthenticator::ACCEPT
);
447 EXPECT_CALL(host_server_listener_
, OnIncomingSession(_
, _
))
449 WithArg
<0>(Invoke(this, &JingleSessionTest::SetHostSession
)),
450 SetArgumentPointee
<1>(protocol::SessionManager::ACCEPT
)));
452 EXPECT_CALL(host_session_event_handler_
,
453 OnSessionStateChange(Session::CONNECTED
))
456 EXPECT_CALL(host_session_event_handler_
,
457 OnSessionStateChange(Session::AUTHENTICATING
))
458 .WillOnce(InvokeWithoutArgs(this, &JingleSessionTest::DeleteSession
));
460 scoped_ptr
<Authenticator
> authenticator(new FakeAuthenticator(
461 FakeAuthenticator::CLIENT
, 3, FakeAuthenticator::ACCEPT
, true));
463 client_session_
= client_server_
->Connect(
464 kHostJid
, authenticator
.Pass(),
465 CandidateSessionConfig::CreateDefault());
466 base::RunLoop().RunUntilIdle();
469 // Verify that data can be sent over a multiplexed channel.
470 TEST_F(JingleSessionTest
, TestMuxStreamChannel
) {
471 CreateSessionManagers(1, FakeAuthenticator::ACCEPT
);
472 ASSERT_NO_FATAL_FAILURE(
473 InitiateConnection(1, FakeAuthenticator::ACCEPT
, false));
475 client_session_
->GetMultiplexedChannelFactory()->CreateChannel(
476 kChannelName
, base::Bind(&JingleSessionTest::OnClientChannelCreated
,
477 base::Unretained(this)));
478 host_session_
->GetMultiplexedChannelFactory()->CreateChannel(
479 kChannelName
, base::Bind(&JingleSessionTest::OnHostChannelCreated
,
480 base::Unretained(this)));
483 ExpectRouteChange("mux");
484 EXPECT_CALL(client_channel_callback_
, OnDone(_
))
485 .WillOnce(QuitThreadOnCounter(&counter
));
486 EXPECT_CALL(host_channel_callback_
, OnDone(_
))
487 .WillOnce(QuitThreadOnCounter(&counter
));
488 message_loop_
->Run();
490 EXPECT_TRUE(client_socket_
.get());
491 EXPECT_TRUE(host_socket_
.get());
493 StreamConnectionTester
tester(host_socket_
.get(), client_socket_
.get(),
494 kMessageSize
, kMessages
);
496 message_loop_
->Run();
497 tester
.CheckResults();
500 // Verify that we can connect channels with multistep auth.
501 TEST_F(JingleSessionTest
, TestMultistepAuthStreamChannel
) {
502 CreateSessionManagers(3, FakeAuthenticator::ACCEPT
);
503 ASSERT_NO_FATAL_FAILURE(
504 InitiateConnection(3, FakeAuthenticator::ACCEPT
, false));
506 ASSERT_NO_FATAL_FAILURE(CreateChannel());
508 StreamConnectionTester
tester(host_socket_
.get(), client_socket_
.get(),
509 kMessageSize
, kMessages
);
511 message_loop_
->Run();
512 tester
.CheckResults();
515 // Verify that we shutdown properly when channel authentication fails.
516 TEST_F(JingleSessionTest
, TestFailedChannelAuth
) {
517 CreateSessionManagers(1, FakeAuthenticator::REJECT_CHANNEL
);
518 ASSERT_NO_FATAL_FAILURE(
519 InitiateConnection(1, FakeAuthenticator::ACCEPT
, false));
521 client_session_
->GetTransportChannelFactory()->CreateChannel(
522 kChannelName
, base::Bind(&JingleSessionTest::OnClientChannelCreated
,
523 base::Unretained(this)));
524 host_session_
->GetTransportChannelFactory()->CreateChannel(
525 kChannelName
, base::Bind(&JingleSessionTest::OnHostChannelCreated
,
526 base::Unretained(this)));
528 // Terminate the message loop when we get rejection notification
530 EXPECT_CALL(host_channel_callback_
, OnDone(nullptr))
531 .WillOnce(QuitThread());
532 ExpectRouteChange(kChannelName
);
534 message_loop_
->Run();
536 client_session_
->GetTransportChannelFactory()->CancelChannelCreation(
539 EXPECT_TRUE(!host_socket_
.get());
542 TEST_F(JingleSessionTest
, TestCancelChannelCreation
) {
543 CreateSessionManagers(1, FakeAuthenticator::REJECT_CHANNEL
);
544 ASSERT_NO_FATAL_FAILURE(
545 InitiateConnection(1, FakeAuthenticator::ACCEPT
, false));
547 client_session_
->GetTransportChannelFactory()->CreateChannel(
548 kChannelName
, base::Bind(&JingleSessionTest::OnClientChannelCreated
,
549 base::Unretained(this)));
550 client_session_
->GetTransportChannelFactory()->CancelChannelCreation(
553 EXPECT_TRUE(!client_socket_
.get());
556 // Verify that we can still connect even when there is a delay in signaling
557 // messages delivery.
558 TEST_F(JingleSessionTest
, TestDelayedSignaling
) {
559 CreateSessionManagers(1, FakeAuthenticator::ACCEPT
);
560 ASSERT_NO_FATAL_FAILURE(
561 InitiateConnection(1, FakeAuthenticator::ACCEPT
, false));
563 host_signal_strategy_
->set_send_delay(
564 base::TimeDelta::FromMilliseconds(100));
566 ASSERT_NO_FATAL_FAILURE(CreateChannel());
568 StreamConnectionTester
tester(host_socket_
.get(), client_socket_
.get(),
571 message_loop_
->Run();
572 tester
.CheckResults();
575 } // namespace protocol
576 } // namespace remoting