// 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
