| Index: net/udp/udp_socket_unittest.cc
|
| diff --git a/net/udp/udp_socket_unittest.cc b/net/udp/udp_socket_unittest.cc
|
| deleted file mode 100644
|
| index 4f902a3f0ba139c2a95f83434e3286a95f3549dc..0000000000000000000000000000000000000000
|
| --- a/net/udp/udp_socket_unittest.cc
|
| +++ /dev/null
|
| @@ -1,805 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "net/udp/udp_socket.h"
|
| -
|
| -#include "net/udp/udp_client_socket.h"
|
| -#include "net/udp/udp_server_socket.h"
|
| -
|
| -#include "base/basictypes.h"
|
| -#include "base/bind.h"
|
| -#include "base/memory/weak_ptr.h"
|
| -#include "base/message_loop/message_loop.h"
|
| -#include "base/metrics/histogram.h"
|
| -#include "base/run_loop.h"
|
| -#include "base/stl_util.h"
|
| -#include "net/base/io_buffer.h"
|
| -#include "net/base/ip_endpoint.h"
|
| -#include "net/base/net_errors.h"
|
| -#include "net/base/net_log_unittest.h"
|
| -#include "net/base/net_util.h"
|
| -#include "net/base/test_completion_callback.h"
|
| -#include "net/test/net_test_suite.h"
|
| -#include "testing/gtest/include/gtest/gtest.h"
|
| -#include "testing/platform_test.h"
|
| -
|
| -namespace net {
|
| -
|
| -namespace {
|
| -
|
| -class UDPSocketTest : public PlatformTest {
|
| - public:
|
| - UDPSocketTest() : buffer_(new IOBufferWithSize(kMaxRead)) {}
|
| -
|
| - // Blocks until data is read from the socket.
|
| - std::string RecvFromSocket(UDPServerSocket* socket) {
|
| - TestCompletionCallback callback;
|
| -
|
| - int rv = socket->RecvFrom(
|
| - buffer_.get(), kMaxRead, &recv_from_address_, callback.callback());
|
| - if (rv == ERR_IO_PENDING)
|
| - rv = callback.WaitForResult();
|
| - if (rv < 0)
|
| - return std::string(); // error!
|
| - return std::string(buffer_->data(), rv);
|
| - }
|
| -
|
| - // Loop until |msg| has been written to the socket or until an
|
| - // error occurs.
|
| - // If |address| is specified, then it is used for the destination
|
| - // to send to. Otherwise, will send to the last socket this server
|
| - // received from.
|
| - int SendToSocket(UDPServerSocket* socket, std::string msg) {
|
| - return SendToSocket(socket, msg, recv_from_address_);
|
| - }
|
| -
|
| - int SendToSocket(UDPServerSocket* socket,
|
| - std::string msg,
|
| - const IPEndPoint& address) {
|
| - TestCompletionCallback callback;
|
| -
|
| - int length = msg.length();
|
| - scoped_refptr<StringIOBuffer> io_buffer(new StringIOBuffer(msg));
|
| - scoped_refptr<DrainableIOBuffer> buffer(
|
| - new DrainableIOBuffer(io_buffer.get(), length));
|
| -
|
| - int bytes_sent = 0;
|
| - while (buffer->BytesRemaining()) {
|
| - int rv = socket->SendTo(
|
| - buffer.get(), buffer->BytesRemaining(), address, callback.callback());
|
| - if (rv == ERR_IO_PENDING)
|
| - rv = callback.WaitForResult();
|
| - if (rv <= 0)
|
| - return bytes_sent > 0 ? bytes_sent : rv;
|
| - bytes_sent += rv;
|
| - buffer->DidConsume(rv);
|
| - }
|
| - return bytes_sent;
|
| - }
|
| -
|
| - std::string ReadSocket(UDPClientSocket* socket) {
|
| - TestCompletionCallback callback;
|
| -
|
| - int rv = socket->Read(buffer_.get(), kMaxRead, callback.callback());
|
| - if (rv == ERR_IO_PENDING)
|
| - rv = callback.WaitForResult();
|
| - if (rv < 0)
|
| - return std::string(); // error!
|
| - return std::string(buffer_->data(), rv);
|
| - }
|
| -
|
| - // Loop until |msg| has been written to the socket or until an
|
| - // error occurs.
|
| - int WriteSocket(UDPClientSocket* socket, std::string msg) {
|
| - TestCompletionCallback callback;
|
| -
|
| - int length = msg.length();
|
| - scoped_refptr<StringIOBuffer> io_buffer(new StringIOBuffer(msg));
|
| - scoped_refptr<DrainableIOBuffer> buffer(
|
| - new DrainableIOBuffer(io_buffer.get(), length));
|
| -
|
| - int bytes_sent = 0;
|
| - while (buffer->BytesRemaining()) {
|
| - int rv = socket->Write(
|
| - buffer.get(), buffer->BytesRemaining(), callback.callback());
|
| - if (rv == ERR_IO_PENDING)
|
| - rv = callback.WaitForResult();
|
| - if (rv <= 0)
|
| - return bytes_sent > 0 ? bytes_sent : rv;
|
| - bytes_sent += rv;
|
| - buffer->DidConsume(rv);
|
| - }
|
| - return bytes_sent;
|
| - }
|
| -
|
| - void WriteSocketIgnoreResult(UDPClientSocket* socket, std::string msg) {
|
| - WriteSocket(socket, msg);
|
| - }
|
| -
|
| - // Creates an address from ip address and port and writes it to |*address|.
|
| - void CreateUDPAddress(std::string ip_str, uint16 port, IPEndPoint* address) {
|
| - IPAddressNumber ip_number;
|
| - bool rv = ParseIPLiteralToNumber(ip_str, &ip_number);
|
| - if (!rv)
|
| - return;
|
| - *address = IPEndPoint(ip_number, port);
|
| - }
|
| -
|
| - // Run unit test for a connection test.
|
| - // |use_nonblocking_io| is used to switch between overlapped and non-blocking
|
| - // IO on Windows. It has no effect in other ports.
|
| - void ConnectTest(bool use_nonblocking_io);
|
| -
|
| - protected:
|
| - static const int kMaxRead = 1024;
|
| - scoped_refptr<IOBufferWithSize> buffer_;
|
| - IPEndPoint recv_from_address_;
|
| -};
|
| -
|
| -void ReadCompleteCallback(int* result_out, base::Closure callback, int result) {
|
| - *result_out = result;
|
| - callback.Run();
|
| -}
|
| -
|
| -void UDPSocketTest::ConnectTest(bool use_nonblocking_io) {
|
| - const uint16 kPort = 9999;
|
| - std::string simple_message("hello world!");
|
| -
|
| - // Setup the server to listen.
|
| - IPEndPoint bind_address;
|
| - CreateUDPAddress("127.0.0.1", kPort, &bind_address);
|
| - CapturingNetLog server_log;
|
| - scoped_ptr<UDPServerSocket> server(
|
| - new UDPServerSocket(&server_log, NetLog::Source()));
|
| -#if defined(OS_WIN)
|
| - if (use_nonblocking_io)
|
| - server->UseNonBlockingIO();
|
| -#endif
|
| - server->AllowAddressReuse();
|
| - int rv = server->Listen(bind_address);
|
| - ASSERT_EQ(OK, rv);
|
| -
|
| - // Setup the client.
|
| - IPEndPoint server_address;
|
| - CreateUDPAddress("127.0.0.1", kPort, &server_address);
|
| - CapturingNetLog client_log;
|
| - scoped_ptr<UDPClientSocket> client(
|
| - new UDPClientSocket(DatagramSocket::DEFAULT_BIND, RandIntCallback(),
|
| - &client_log, NetLog::Source()));
|
| -#if defined(OS_WIN)
|
| - if (use_nonblocking_io)
|
| - client->UseNonBlockingIO();
|
| -#endif
|
| -
|
| - rv = client->Connect(server_address);
|
| - EXPECT_EQ(OK, rv);
|
| -
|
| - // Client sends to the server.
|
| - rv = WriteSocket(client.get(), simple_message);
|
| - EXPECT_EQ(simple_message.length(), static_cast<size_t>(rv));
|
| -
|
| - // Server waits for message.
|
| - std::string str = RecvFromSocket(server.get());
|
| - DCHECK(simple_message == str);
|
| -
|
| - // Server echoes reply.
|
| - rv = SendToSocket(server.get(), simple_message);
|
| - EXPECT_EQ(simple_message.length(), static_cast<size_t>(rv));
|
| -
|
| - // Client waits for response.
|
| - str = ReadSocket(client.get());
|
| - DCHECK(simple_message == str);
|
| -
|
| - // Test asynchronous read. Server waits for message.
|
| - base::RunLoop run_loop;
|
| - int read_result = 0;
|
| - rv = server->RecvFrom(
|
| - buffer_.get(), kMaxRead, &recv_from_address_,
|
| - base::Bind(&ReadCompleteCallback, &read_result, run_loop.QuitClosure()));
|
| - EXPECT_EQ(ERR_IO_PENDING, rv);
|
| -
|
| - // Client sends to the server.
|
| - base::MessageLoop::current()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&UDPSocketTest::WriteSocketIgnoreResult,
|
| - base::Unretained(this), client.get(), simple_message));
|
| - run_loop.Run();
|
| - EXPECT_EQ(simple_message.length(), static_cast<size_t>(read_result));
|
| - EXPECT_EQ(simple_message, std::string(buffer_->data(), read_result));
|
| -
|
| - // Delete sockets so they log their final events.
|
| - server.reset();
|
| - client.reset();
|
| -
|
| - // Check the server's log.
|
| - CapturingNetLog::CapturedEntryList server_entries;
|
| - server_log.GetEntries(&server_entries);
|
| - EXPECT_EQ(5u, server_entries.size());
|
| - EXPECT_TRUE(
|
| - LogContainsBeginEvent(server_entries, 0, NetLog::TYPE_SOCKET_ALIVE));
|
| - EXPECT_TRUE(LogContainsEvent(
|
| - server_entries, 1, NetLog::TYPE_UDP_BYTES_RECEIVED, NetLog::PHASE_NONE));
|
| - EXPECT_TRUE(LogContainsEvent(server_entries, 2, NetLog::TYPE_UDP_BYTES_SENT,
|
| - NetLog::PHASE_NONE));
|
| - EXPECT_TRUE(LogContainsEvent(
|
| - server_entries, 3, NetLog::TYPE_UDP_BYTES_RECEIVED, NetLog::PHASE_NONE));
|
| - EXPECT_TRUE(
|
| - LogContainsEndEvent(server_entries, 4, NetLog::TYPE_SOCKET_ALIVE));
|
| -
|
| - // Check the client's log.
|
| - CapturingNetLog::CapturedEntryList client_entries;
|
| - client_log.GetEntries(&client_entries);
|
| - EXPECT_EQ(7u, client_entries.size());
|
| - EXPECT_TRUE(
|
| - LogContainsBeginEvent(client_entries, 0, NetLog::TYPE_SOCKET_ALIVE));
|
| - EXPECT_TRUE(
|
| - LogContainsBeginEvent(client_entries, 1, NetLog::TYPE_UDP_CONNECT));
|
| - EXPECT_TRUE(LogContainsEndEvent(client_entries, 2, NetLog::TYPE_UDP_CONNECT));
|
| - EXPECT_TRUE(LogContainsEvent(client_entries, 3, NetLog::TYPE_UDP_BYTES_SENT,
|
| - NetLog::PHASE_NONE));
|
| - EXPECT_TRUE(LogContainsEvent(
|
| - client_entries, 4, NetLog::TYPE_UDP_BYTES_RECEIVED, NetLog::PHASE_NONE));
|
| - EXPECT_TRUE(LogContainsEvent(client_entries, 5, NetLog::TYPE_UDP_BYTES_SENT,
|
| - NetLog::PHASE_NONE));
|
| - EXPECT_TRUE(
|
| - LogContainsEndEvent(client_entries, 6, NetLog::TYPE_SOCKET_ALIVE));
|
| -}
|
| -
|
| -TEST_F(UDPSocketTest, Connect) {
|
| - // The variable |use_nonblocking_io| has no effect in non-Windows ports.
|
| - ConnectTest(false);
|
| -}
|
| -
|
| -#if defined(OS_WIN)
|
| -TEST_F(UDPSocketTest, ConnectNonBlocking) {
|
| - ConnectTest(true);
|
| -}
|
| -#endif
|
| -
|
| -#if defined(OS_MACOSX)
|
| -// UDPSocketPrivate_Broadcast is disabled for OSX because it requires
|
| -// root permissions on OSX 10.7+.
|
| -TEST_F(UDPSocketTest, DISABLED_Broadcast) {
|
| -#elif defined(OS_ANDROID)
|
| -// It is also disabled for Android because it is extremely flaky.
|
| -// The first call to SendToSocket returns -109 (Address not reachable)
|
| -// in some unpredictable cases. crbug.com/139144.
|
| -TEST_F(UDPSocketTest, DISABLED_Broadcast) {
|
| -#else
|
| -TEST_F(UDPSocketTest, Broadcast) {
|
| -#endif
|
| - const uint16 kPort = 9999;
|
| - std::string first_message("first message"), second_message("second message");
|
| -
|
| - IPEndPoint broadcast_address;
|
| - CreateUDPAddress("255.255.255.255", kPort, &broadcast_address);
|
| - IPEndPoint listen_address;
|
| - CreateUDPAddress("0.0.0.0", kPort, &listen_address);
|
| -
|
| - CapturingNetLog server1_log, server2_log;
|
| - scoped_ptr<UDPServerSocket> server1(
|
| - new UDPServerSocket(&server1_log, NetLog::Source()));
|
| - scoped_ptr<UDPServerSocket> server2(
|
| - new UDPServerSocket(&server2_log, NetLog::Source()));
|
| - server1->AllowAddressReuse();
|
| - server1->AllowBroadcast();
|
| - server2->AllowAddressReuse();
|
| - server2->AllowBroadcast();
|
| -
|
| - int rv = server1->Listen(listen_address);
|
| - EXPECT_EQ(OK, rv);
|
| - rv = server2->Listen(listen_address);
|
| - EXPECT_EQ(OK, rv);
|
| -
|
| - rv = SendToSocket(server1.get(), first_message, broadcast_address);
|
| - ASSERT_EQ(static_cast<int>(first_message.size()), rv);
|
| - std::string str = RecvFromSocket(server1.get());
|
| - ASSERT_EQ(first_message, str);
|
| - str = RecvFromSocket(server2.get());
|
| - ASSERT_EQ(first_message, str);
|
| -
|
| - rv = SendToSocket(server2.get(), second_message, broadcast_address);
|
| - ASSERT_EQ(static_cast<int>(second_message.size()), rv);
|
| - str = RecvFromSocket(server1.get());
|
| - ASSERT_EQ(second_message, str);
|
| - str = RecvFromSocket(server2.get());
|
| - ASSERT_EQ(second_message, str);
|
| -}
|
| -
|
| -// In this test, we verify that random binding logic works, which attempts
|
| -// to bind to a random port and returns if succeeds, otherwise retries for
|
| -// |kBindRetries| number of times.
|
| -
|
| -// To generate the scenario, we first create |kBindRetries| number of
|
| -// UDPClientSockets with default binding policy and connect to the same
|
| -// peer and save the used port numbers. Then we get rid of the last
|
| -// socket, making sure that the local port it was bound to is available.
|
| -// Finally, we create a socket with random binding policy, passing it a
|
| -// test PRNG that would serve used port numbers in the array, one after
|
| -// another. At the end, we make sure that the test socket was bound to the
|
| -// port that became available after deleting the last socket with default
|
| -// binding policy.
|
| -
|
| -// We do not test the randomness of bound ports, but that we are using
|
| -// passed in PRNG correctly, thus, it's the duty of PRNG to produce strong
|
| -// random numbers.
|
| -static const int kBindRetries = 10;
|
| -
|
| -class TestPrng {
|
| - public:
|
| - explicit TestPrng(const std::deque<int>& numbers) : numbers_(numbers) {}
|
| - int GetNext(int /* min */, int /* max */) {
|
| - DCHECK(!numbers_.empty());
|
| - int rv = numbers_.front();
|
| - numbers_.pop_front();
|
| - return rv;
|
| - }
|
| - private:
|
| - std::deque<int> numbers_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(TestPrng);
|
| -};
|
| -
|
| -#if defined(OS_ANDROID)
|
| -// Disabled on Android for lack of 192.168.1.13. crbug.com/161245
|
| -TEST_F(UDPSocketTest, DISABLED_ConnectRandomBind) {
|
| -#else
|
| -TEST_F(UDPSocketTest, ConnectRandomBind) {
|
| -#endif
|
| - std::vector<UDPClientSocket*> sockets;
|
| - IPEndPoint peer_address;
|
| - CreateUDPAddress("192.168.1.13", 53, &peer_address);
|
| -
|
| - // Create and connect sockets and save port numbers.
|
| - std::deque<int> used_ports;
|
| - for (int i = 0; i < kBindRetries; ++i) {
|
| - UDPClientSocket* socket =
|
| - new UDPClientSocket(DatagramSocket::DEFAULT_BIND,
|
| - RandIntCallback(),
|
| - NULL,
|
| - NetLog::Source());
|
| - sockets.push_back(socket);
|
| - EXPECT_EQ(OK, socket->Connect(peer_address));
|
| -
|
| - IPEndPoint client_address;
|
| - EXPECT_EQ(OK, socket->GetLocalAddress(&client_address));
|
| - used_ports.push_back(client_address.port());
|
| - }
|
| -
|
| - // Free the last socket, its local port is still in |used_ports|.
|
| - delete sockets.back();
|
| - sockets.pop_back();
|
| -
|
| - TestPrng test_prng(used_ports);
|
| - RandIntCallback rand_int_cb =
|
| - base::Bind(&TestPrng::GetNext, base::Unretained(&test_prng));
|
| -
|
| - // Create a socket with random binding policy and connect.
|
| - scoped_ptr<UDPClientSocket> test_socket(
|
| - new UDPClientSocket(DatagramSocket::RANDOM_BIND,
|
| - rand_int_cb,
|
| - NULL,
|
| - NetLog::Source()));
|
| - EXPECT_EQ(OK, test_socket->Connect(peer_address));
|
| -
|
| - // Make sure that the last port number in the |used_ports| was used.
|
| - IPEndPoint client_address;
|
| - EXPECT_EQ(OK, test_socket->GetLocalAddress(&client_address));
|
| - EXPECT_EQ(used_ports.back(), client_address.port());
|
| -
|
| - STLDeleteElements(&sockets);
|
| -}
|
| -
|
| -// Return a privileged port (under 1024) so binding will fail.
|
| -int PrivilegedRand(int min, int max) {
|
| - // Chosen by fair dice roll. Guaranteed to be random.
|
| - return 4;
|
| -}
|
| -
|
| -TEST_F(UDPSocketTest, ConnectFail) {
|
| - IPEndPoint peer_address;
|
| - CreateUDPAddress("0.0.0.0", 53, &peer_address);
|
| -
|
| - scoped_ptr<UDPSocket> socket(
|
| - new UDPSocket(DatagramSocket::RANDOM_BIND,
|
| - base::Bind(&PrivilegedRand),
|
| - NULL,
|
| - NetLog::Source()));
|
| - int rv = socket->Open(peer_address.GetFamily());
|
| - EXPECT_EQ(OK, rv);
|
| - rv = socket->Connect(peer_address);
|
| - // Connect should have failed since we couldn't bind to that port,
|
| - EXPECT_NE(OK, rv);
|
| - // Make sure that UDPSocket actually closed the socket.
|
| - EXPECT_FALSE(socket->is_connected());
|
| -}
|
| -
|
| -// In this test, we verify that connect() on a socket will have the effect
|
| -// of filtering reads on this socket only to data read from the destination
|
| -// we connected to.
|
| -//
|
| -// The purpose of this test is that some documentation indicates that connect
|
| -// binds the client's sends to send to a particular server endpoint, but does
|
| -// not bind the client's reads to only be from that endpoint, and that we need
|
| -// to always use recvfrom() to disambiguate.
|
| -TEST_F(UDPSocketTest, VerifyConnectBindsAddr) {
|
| - const uint16 kPort1 = 9999;
|
| - const uint16 kPort2 = 10000;
|
| - std::string simple_message("hello world!");
|
| - std::string foreign_message("BAD MESSAGE TO GET!!");
|
| -
|
| - // Setup the first server to listen.
|
| - IPEndPoint bind_address;
|
| - CreateUDPAddress("127.0.0.1", kPort1, &bind_address);
|
| - UDPServerSocket server1(NULL, NetLog::Source());
|
| - server1.AllowAddressReuse();
|
| - int rv = server1.Listen(bind_address);
|
| - ASSERT_EQ(OK, rv);
|
| -
|
| - // Setup the second server to listen.
|
| - CreateUDPAddress("127.0.0.1", kPort2, &bind_address);
|
| - UDPServerSocket server2(NULL, NetLog::Source());
|
| - server2.AllowAddressReuse();
|
| - rv = server2.Listen(bind_address);
|
| - ASSERT_EQ(OK, rv);
|
| -
|
| - // Setup the client, connected to server 1.
|
| - IPEndPoint server_address;
|
| - CreateUDPAddress("127.0.0.1", kPort1, &server_address);
|
| - UDPClientSocket client(DatagramSocket::DEFAULT_BIND,
|
| - RandIntCallback(),
|
| - NULL,
|
| - NetLog::Source());
|
| - rv = client.Connect(server_address);
|
| - EXPECT_EQ(OK, rv);
|
| -
|
| - // Client sends to server1.
|
| - rv = WriteSocket(&client, simple_message);
|
| - EXPECT_EQ(simple_message.length(), static_cast<size_t>(rv));
|
| -
|
| - // Server1 waits for message.
|
| - std::string str = RecvFromSocket(&server1);
|
| - DCHECK(simple_message == str);
|
| -
|
| - // Get the client's address.
|
| - IPEndPoint client_address;
|
| - rv = client.GetLocalAddress(&client_address);
|
| - EXPECT_EQ(OK, rv);
|
| -
|
| - // Server2 sends reply.
|
| - rv = SendToSocket(&server2, foreign_message,
|
| - client_address);
|
| - EXPECT_EQ(foreign_message.length(), static_cast<size_t>(rv));
|
| -
|
| - // Server1 sends reply.
|
| - rv = SendToSocket(&server1, simple_message,
|
| - client_address);
|
| - EXPECT_EQ(simple_message.length(), static_cast<size_t>(rv));
|
| -
|
| - // Client waits for response.
|
| - str = ReadSocket(&client);
|
| - DCHECK(simple_message == str);
|
| -}
|
| -
|
| -TEST_F(UDPSocketTest, ClientGetLocalPeerAddresses) {
|
| - struct TestData {
|
| - std::string remote_address;
|
| - std::string local_address;
|
| - bool may_fail;
|
| - } tests[] = {
|
| - { "127.0.00.1", "127.0.0.1", false },
|
| - { "::1", "::1", true },
|
| -#if !defined(OS_ANDROID)
|
| - // Addresses below are disabled on Android. See crbug.com/161248
|
| - { "192.168.1.1", "127.0.0.1", false },
|
| - { "2001:db8:0::42", "::1", true },
|
| -#endif
|
| - };
|
| - for (size_t i = 0; i < arraysize(tests); i++) {
|
| - SCOPED_TRACE(std::string("Connecting from ") + tests[i].local_address +
|
| - std::string(" to ") + tests[i].remote_address);
|
| -
|
| - IPAddressNumber ip_number;
|
| - ParseIPLiteralToNumber(tests[i].remote_address, &ip_number);
|
| - IPEndPoint remote_address(ip_number, 80);
|
| - ParseIPLiteralToNumber(tests[i].local_address, &ip_number);
|
| - IPEndPoint local_address(ip_number, 80);
|
| -
|
| - UDPClientSocket client(DatagramSocket::DEFAULT_BIND,
|
| - RandIntCallback(),
|
| - NULL,
|
| - NetLog::Source());
|
| - int rv = client.Connect(remote_address);
|
| - if (tests[i].may_fail && rv == ERR_ADDRESS_UNREACHABLE) {
|
| - // Connect() may return ERR_ADDRESS_UNREACHABLE for IPv6
|
| - // addresses if IPv6 is not configured.
|
| - continue;
|
| - }
|
| -
|
| - EXPECT_LE(ERR_IO_PENDING, rv);
|
| -
|
| - IPEndPoint fetched_local_address;
|
| - rv = client.GetLocalAddress(&fetched_local_address);
|
| - EXPECT_EQ(OK, rv);
|
| -
|
| - // TODO(mbelshe): figure out how to verify the IP and port.
|
| - // The port is dynamically generated by the udp stack.
|
| - // The IP is the real IP of the client, not necessarily
|
| - // loopback.
|
| - //EXPECT_EQ(local_address.address(), fetched_local_address.address());
|
| -
|
| - IPEndPoint fetched_remote_address;
|
| - rv = client.GetPeerAddress(&fetched_remote_address);
|
| - EXPECT_EQ(OK, rv);
|
| -
|
| - EXPECT_EQ(remote_address, fetched_remote_address);
|
| - }
|
| -}
|
| -
|
| -TEST_F(UDPSocketTest, ServerGetLocalAddress) {
|
| - IPEndPoint bind_address;
|
| - CreateUDPAddress("127.0.0.1", 0, &bind_address);
|
| - UDPServerSocket server(NULL, NetLog::Source());
|
| - int rv = server.Listen(bind_address);
|
| - EXPECT_EQ(OK, rv);
|
| -
|
| - IPEndPoint local_address;
|
| - rv = server.GetLocalAddress(&local_address);
|
| - EXPECT_EQ(rv, 0);
|
| -
|
| - // Verify that port was allocated.
|
| - EXPECT_GT(local_address.port(), 0);
|
| - EXPECT_EQ(local_address.address(), bind_address.address());
|
| -}
|
| -
|
| -TEST_F(UDPSocketTest, ServerGetPeerAddress) {
|
| - IPEndPoint bind_address;
|
| - CreateUDPAddress("127.0.0.1", 0, &bind_address);
|
| - UDPServerSocket server(NULL, NetLog::Source());
|
| - int rv = server.Listen(bind_address);
|
| - EXPECT_EQ(OK, rv);
|
| -
|
| - IPEndPoint peer_address;
|
| - rv = server.GetPeerAddress(&peer_address);
|
| - EXPECT_EQ(rv, ERR_SOCKET_NOT_CONNECTED);
|
| -}
|
| -
|
| -// Close the socket while read is pending.
|
| -TEST_F(UDPSocketTest, CloseWithPendingRead) {
|
| - IPEndPoint bind_address;
|
| - CreateUDPAddress("127.0.0.1", 0, &bind_address);
|
| - UDPServerSocket server(NULL, NetLog::Source());
|
| - int rv = server.Listen(bind_address);
|
| - EXPECT_EQ(OK, rv);
|
| -
|
| - TestCompletionCallback callback;
|
| - IPEndPoint from;
|
| - rv = server.RecvFrom(buffer_.get(), kMaxRead, &from, callback.callback());
|
| - EXPECT_EQ(rv, ERR_IO_PENDING);
|
| -
|
| - server.Close();
|
| -
|
| - EXPECT_FALSE(callback.have_result());
|
| -}
|
| -
|
| -#if defined(OS_ANDROID)
|
| -// Some Android devices do not support multicast socket.
|
| -// The ones supporting multicast need WifiManager.MulitcastLock to enable it.
|
| -// http://goo.gl/jjAk9
|
| -#define MAYBE_JoinMulticastGroup DISABLED_JoinMulticastGroup
|
| -#else
|
| -#define MAYBE_JoinMulticastGroup JoinMulticastGroup
|
| -#endif // defined(OS_ANDROID)
|
| -
|
| -TEST_F(UDPSocketTest, MAYBE_JoinMulticastGroup) {
|
| - const uint16 kPort = 9999;
|
| - const char kGroup[] = "237.132.100.17";
|
| -
|
| - IPEndPoint bind_address;
|
| - CreateUDPAddress("0.0.0.0", kPort, &bind_address);
|
| - IPAddressNumber group_ip;
|
| - EXPECT_TRUE(ParseIPLiteralToNumber(kGroup, &group_ip));
|
| -
|
| - UDPSocket socket(DatagramSocket::DEFAULT_BIND,
|
| - RandIntCallback(),
|
| - NULL,
|
| - NetLog::Source());
|
| - EXPECT_EQ(OK, socket.Open(bind_address.GetFamily()));
|
| - EXPECT_EQ(OK, socket.Bind(bind_address));
|
| - EXPECT_EQ(OK, socket.JoinGroup(group_ip));
|
| - // Joining group multiple times.
|
| - EXPECT_NE(OK, socket.JoinGroup(group_ip));
|
| - EXPECT_EQ(OK, socket.LeaveGroup(group_ip));
|
| - // Leaving group multiple times.
|
| - EXPECT_NE(OK, socket.LeaveGroup(group_ip));
|
| -
|
| - socket.Close();
|
| -}
|
| -
|
| -TEST_F(UDPSocketTest, MulticastOptions) {
|
| - const uint16 kPort = 9999;
|
| - IPEndPoint bind_address;
|
| - CreateUDPAddress("0.0.0.0", kPort, &bind_address);
|
| -
|
| - UDPSocket socket(DatagramSocket::DEFAULT_BIND,
|
| - RandIntCallback(),
|
| - NULL,
|
| - NetLog::Source());
|
| - // Before binding.
|
| - EXPECT_EQ(OK, socket.SetMulticastLoopbackMode(false));
|
| - EXPECT_EQ(OK, socket.SetMulticastLoopbackMode(true));
|
| - EXPECT_EQ(OK, socket.SetMulticastTimeToLive(0));
|
| - EXPECT_EQ(OK, socket.SetMulticastTimeToLive(3));
|
| - EXPECT_NE(OK, socket.SetMulticastTimeToLive(-1));
|
| - EXPECT_EQ(OK, socket.SetMulticastInterface(0));
|
| -
|
| - EXPECT_EQ(OK, socket.Open(bind_address.GetFamily()));
|
| - EXPECT_EQ(OK, socket.Bind(bind_address));
|
| -
|
| - EXPECT_NE(OK, socket.SetMulticastLoopbackMode(false));
|
| - EXPECT_NE(OK, socket.SetMulticastTimeToLive(0));
|
| - EXPECT_NE(OK, socket.SetMulticastInterface(0));
|
| -
|
| - socket.Close();
|
| -}
|
| -
|
| -// Checking that DSCP bits are set correctly is difficult,
|
| -// but let's check that the code doesn't crash at least.
|
| -TEST_F(UDPSocketTest, SetDSCP) {
|
| - // Setup the server to listen.
|
| - IPEndPoint bind_address;
|
| - UDPSocket client(DatagramSocket::DEFAULT_BIND,
|
| - RandIntCallback(),
|
| - NULL,
|
| - NetLog::Source());
|
| - // We need a real IP, but we won't actually send anything to it.
|
| - CreateUDPAddress("8.8.8.8", 9999, &bind_address);
|
| - int rv = client.Open(bind_address.GetFamily());
|
| - EXPECT_EQ(OK, rv);
|
| -
|
| - rv = client.Connect(bind_address);
|
| - if (rv != OK) {
|
| - // Let's try localhost then..
|
| - CreateUDPAddress("127.0.0.1", 9999, &bind_address);
|
| - rv = client.Connect(bind_address);
|
| - }
|
| - EXPECT_EQ(OK, rv);
|
| -
|
| - client.SetDiffServCodePoint(DSCP_NO_CHANGE);
|
| - client.SetDiffServCodePoint(DSCP_AF41);
|
| - client.SetDiffServCodePoint(DSCP_DEFAULT);
|
| - client.SetDiffServCodePoint(DSCP_CS2);
|
| - client.SetDiffServCodePoint(DSCP_NO_CHANGE);
|
| - client.SetDiffServCodePoint(DSCP_DEFAULT);
|
| - client.Close();
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -#if defined(OS_WIN)
|
| -
|
| -namespace {
|
| -
|
| -const HANDLE kFakeHandle = (HANDLE)19;
|
| -const QOS_FLOWID kFakeFlowId = (QOS_FLOWID)27;
|
| -
|
| -BOOL WINAPI FakeQOSCreateHandleFAIL(PQOS_VERSION version, PHANDLE handle) {
|
| - EXPECT_EQ(0, version->MinorVersion);
|
| - EXPECT_EQ(1, version->MajorVersion);
|
| - SetLastError(ERROR_OPEN_FAILED);
|
| - return false;
|
| -}
|
| -
|
| -BOOL WINAPI FakeQOSCreateHandle(PQOS_VERSION version, PHANDLE handle) {
|
| - EXPECT_EQ(0, version->MinorVersion);
|
| - EXPECT_EQ(1, version->MajorVersion);
|
| - *handle = kFakeHandle;
|
| - return true;
|
| -}
|
| -
|
| -BOOL WINAPI FakeQOSCloseHandle(HANDLE handle) {
|
| - EXPECT_EQ(kFakeHandle, handle);
|
| - return true;
|
| -}
|
| -
|
| -QOS_TRAFFIC_TYPE g_expected_traffic_type;
|
| -
|
| -BOOL WINAPI FakeQOSAddSocketToFlow(HANDLE handle,
|
| - SOCKET socket,
|
| - PSOCKADDR addr,
|
| - QOS_TRAFFIC_TYPE traffic_type,
|
| - DWORD flags,
|
| - PQOS_FLOWID flow_id) {
|
| - EXPECT_EQ(kFakeHandle, handle);
|
| - EXPECT_EQ(NULL, addr);
|
| - EXPECT_EQ(QOS_NON_ADAPTIVE_FLOW, flags);
|
| - EXPECT_EQ(0, *flow_id);
|
| - *flow_id = kFakeFlowId;
|
| - return true;
|
| -}
|
| -
|
| -BOOL WINAPI FakeQOSRemoveSocketFromFlow(HANDLE handle,
|
| - SOCKET socket,
|
| - QOS_FLOWID flowid,
|
| - DWORD reserved) {
|
| - EXPECT_EQ(kFakeHandle, handle);
|
| - EXPECT_EQ(NULL, socket);
|
| - EXPECT_EQ(kFakeFlowId, flowid);
|
| - EXPECT_EQ(0, reserved);
|
| - return true;
|
| -}
|
| -
|
| -DWORD g_expected_dscp;
|
| -
|
| -BOOL WINAPI FakeQOSSetFlow(HANDLE handle,
|
| - QOS_FLOWID flow_id,
|
| - QOS_SET_FLOW op,
|
| - ULONG size,
|
| - PVOID data,
|
| - DWORD reserved,
|
| - LPOVERLAPPED overlapped) {
|
| - EXPECT_EQ(kFakeHandle, handle);
|
| - EXPECT_EQ(QOSSetOutgoingDSCPValue, op);
|
| - EXPECT_EQ(sizeof(DWORD), size);
|
| - EXPECT_EQ(g_expected_dscp, *reinterpret_cast<DWORD*>(data));
|
| - EXPECT_EQ(kFakeFlowId, flow_id);
|
| - EXPECT_EQ(0, reserved);
|
| - EXPECT_EQ(NULL, overlapped);
|
| - return true;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -// Mock out the Qwave functions and make sure they are
|
| -// called correctly. Must be in net namespace for friendship
|
| -// reasons.
|
| -TEST_F(UDPSocketTest, SetDSCPFake) {
|
| - // Setup the server to listen.
|
| - IPEndPoint bind_address;
|
| - // We need a real IP, but we won't actually send anything to it.
|
| - CreateUDPAddress("8.8.8.8", 9999, &bind_address);
|
| - UDPSocket client(DatagramSocket::DEFAULT_BIND,
|
| - RandIntCallback(),
|
| - NULL,
|
| - NetLog::Source());
|
| - int rv = client.SetDiffServCodePoint(DSCP_AF41);
|
| - EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, rv);
|
| -
|
| - rv = client.Open(bind_address.GetFamily());
|
| - EXPECT_EQ(OK, rv);
|
| -
|
| - rv = client.Connect(bind_address);
|
| - EXPECT_EQ(OK, rv);
|
| -
|
| - QwaveAPI& qos(QwaveAPI::Get());
|
| - qos.create_handle_func_ = FakeQOSCreateHandleFAIL;
|
| - qos.close_handle_func_ = FakeQOSCloseHandle;
|
| - qos.add_socket_to_flow_func_ = FakeQOSAddSocketToFlow;
|
| - qos.remove_socket_from_flow_func_ = FakeQOSRemoveSocketFromFlow;
|
| - qos.set_flow_func_ = FakeQOSSetFlow;
|
| - qos.qwave_supported_ = true;
|
| -
|
| - EXPECT_EQ(OK, client.SetDiffServCodePoint(DSCP_NO_CHANGE));
|
| - EXPECT_EQ(ERROR_NOT_SUPPORTED, client.SetDiffServCodePoint(DSCP_AF41));
|
| - qos.create_handle_func_ = FakeQOSCreateHandle;
|
| - g_expected_dscp = DSCP_AF41;
|
| - g_expected_traffic_type = QOSTrafficTypeAudioVideo;
|
| - EXPECT_EQ(OK, client.SetDiffServCodePoint(DSCP_AF41));
|
| - g_expected_dscp = DSCP_DEFAULT;
|
| - g_expected_traffic_type = QOSTrafficTypeBestEffort;
|
| - EXPECT_EQ(OK, client.SetDiffServCodePoint(DSCP_DEFAULT));
|
| - g_expected_dscp = DSCP_CS2;
|
| - g_expected_traffic_type = QOSTrafficTypeExcellentEffort;
|
| - EXPECT_EQ(OK, client.SetDiffServCodePoint(DSCP_CS2));
|
| - g_expected_dscp = DSCP_CS3;
|
| - g_expected_traffic_type = QOSTrafficTypeExcellentEffort;
|
| - EXPECT_EQ(OK, client.SetDiffServCodePoint(DSCP_NO_CHANGE));
|
| - g_expected_dscp = DSCP_DEFAULT;
|
| - g_expected_traffic_type = QOSTrafficTypeBestEffort;
|
| - EXPECT_EQ(OK, client.SetDiffServCodePoint(DSCP_DEFAULT));
|
| - client.Close();
|
| -}
|
| -#endif
|
| -
|
| -} // namespace net
|
|
|