1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "remoting/protocol/chromium_socket_factory.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 79ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/run_loop.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "third_party/webrtc/base/asyncpacketsocket.h" 125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "third_party/webrtc/base/socketaddress.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace remoting { 15116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace protocol { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ChromiumSocketFactoryTest : public testing::Test, 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public sigslot::has_slots<> { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() OVERRIDE { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_factory_.reset(new ChromiumPacketSocketFactory()); 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_.reset(socket_factory_->CreateUdpSocket( 245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rtc::SocketAddress("127.0.0.1", 0), 0, 0)); 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(socket_.get() != NULL); 265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(socket_->GetState(), rtc::AsyncPacketSocket::STATE_BOUND); 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_->SignalReadPacket.connect( 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, &ChromiumSocketFactoryTest::OnPacket); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void OnPacket(rtc::AsyncPacketSocket* socket, 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* data, size_t size, 335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const rtc::SocketAddress& address, 345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const rtc::PacketTime& packet_time) { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(socket, socket_.get()); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_packet_.assign(data, data + size); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_address_ = address; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) run_loop_.Quit(); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void VerifyCanSendAndReceive(rtc::AsyncPacketSocket* sender) { 42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // UDP packets may be lost, so we have to retry sending it more than once. 43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const int kMaxAttempts = 3; 44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const base::TimeDelta kAttemptPeriod = base::TimeDelta::FromSeconds(1); 45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::string test_packet("TEST PACKET"); 46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int attempts = 0; 475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rtc::PacketOptions options; 48f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) while (last_packet_.empty() && attempts++ < kMaxAttempts) { 49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sender->SendTo(test_packet.data(), test_packet.size(), 50f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) socket_->GetLocalAddress(), options); 51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) message_loop_.PostDelayedTask(FROM_HERE, run_loop_.QuitClosure(), 52f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) kAttemptPeriod); 53f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) run_loop_.Run(); 54f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 55f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_EQ(test_packet, last_packet_); 56f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_EQ(sender->GetLocalAddress(), last_address_); 57f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoopForIO message_loop_; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::RunLoop run_loop_; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<rtc::PacketSocketFactory> socket_factory_; 645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<rtc::AsyncPacketSocket> socket_; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string last_packet_; 675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rtc::SocketAddress last_address_; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ChromiumSocketFactoryTest, SendAndReceive) { 715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<rtc::AsyncPacketSocket> sending_socket( 72f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) socket_factory_->CreateUdpSocket( 735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rtc::SocketAddress("127.0.0.1", 0), 0, 0)); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(sending_socket.get() != NULL); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(sending_socket->GetState(), 765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rtc::AsyncPacketSocket::STATE_BOUND); 77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 78f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) VerifyCanSendAndReceive(sending_socket.get()); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ChromiumSocketFactoryTest, SetOptions) { 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(0, socket_->SetOption(rtc::Socket::OPT_SNDBUF, 4096)); 835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(0, socket_->SetOption(rtc::Socket::OPT_RCVBUF, 4096)); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ChromiumSocketFactoryTest, PortRange) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kMinPort = 12400; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kMaxPort = 12410; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_.reset(socket_factory_->CreateUdpSocket( 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rtc::SocketAddress("127.0.0.1", 0), kMaxPort, kMaxPort)); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(socket_.get() != NULL); 925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(socket_->GetState(), rtc::AsyncPacketSocket::STATE_BOUND); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GE(socket_->GetLocalAddress().port(), kMinPort); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_LE(socket_->GetLocalAddress().port(), kMaxPort); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(ChromiumSocketFactoryTest, TransientError) { 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<rtc::AsyncPacketSocket> sending_socket( 99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) socket_factory_->CreateUdpSocket( 1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rtc::SocketAddress("127.0.0.1", 0), 0, 0)); 101f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::string test_packet("TEST"); 102f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 103f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Try sending a packet to an IPv6 address from a socket that's bound to an 104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // IPv4 address. This send is expected to fail, but the socket should still be 105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // functional. 106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sending_socket->SendTo(test_packet.data(), test_packet.size(), 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rtc::SocketAddress("::1", 0), 1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rtc::PacketOptions()); 109f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 110f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Verify that socket is still usable. 111f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) VerifyCanSendAndReceive(sending_socket.get()); 112f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 113f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} // namespace protocol 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace remoting 116