// Copyright (c) 2011 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/socket/udp_client_socket.h"

#include "net/base/net_errors.h"
#include "net/traffic_annotation/network_traffic_annotation.h"

namespace net {

UDPClientSocket::UDPClientSocket(DatagramSocket::BindType bind_type,
                                 const RandIntCallback& rand_int_cb,
                                 net::NetLog* net_log,
                                 const net::NetLogSource& source)
    : socket_(bind_type, rand_int_cb, net_log, source),
      network_(NetworkChangeNotifier::kInvalidNetworkHandle) {}

UDPClientSocket::~UDPClientSocket() = default;

int UDPClientSocket::Connect(const IPEndPoint& address) {
  int rv = socket_.Open(address.GetFamily());
  if (rv != OK)
    return rv;
  return socket_.Connect(address);
}

int UDPClientSocket::ConnectUsingNetwork(
    NetworkChangeNotifier::NetworkHandle network,
    const IPEndPoint& address) {
  if (!NetworkChangeNotifier::AreNetworkHandlesSupported())
    return ERR_NOT_IMPLEMENTED;
  int rv = socket_.Open(address.GetFamily());
  if (rv != OK)
    return rv;
  rv = socket_.BindToNetwork(network);
  if (rv != OK)
    return rv;
  network_ = network;
  return socket_.Connect(address);
}

int UDPClientSocket::ConnectUsingDefaultNetwork(const IPEndPoint& address) {
  if (!NetworkChangeNotifier::AreNetworkHandlesSupported())
    return ERR_NOT_IMPLEMENTED;
  int rv;
  rv = socket_.Open(address.GetFamily());
  if (rv != OK)
    return rv;
  // Calling connect() will bind a socket to the default network, however there
  // is no way to determine what network the socket got bound to.  The
  // alternative is to query what the default network is and bind the socket to
  // that network explicitly, however this is racy because the default network
  // can change in between when we query it and when we bind to it.  This is
  // rare but should be accounted for.  Since changes of the default network
  // should not come in quick succession, we can simply try again.
  NetworkChangeNotifier::NetworkHandle network;
  for (int attempt = 0; attempt < 2; attempt++) {
    network = NetworkChangeNotifier::GetDefaultNetwork();
    if (network == NetworkChangeNotifier::kInvalidNetworkHandle)
      return ERR_INTERNET_DISCONNECTED;
    rv = socket_.BindToNetwork(network);
    // |network| may have disconnected between the call to GetDefaultNetwork()
    // and the call to BindToNetwork(). Loop only if this is the case (|rv| will
    // be ERR_NETWORK_CHANGED).
    if (rv != ERR_NETWORK_CHANGED)
      break;
  }
  if (rv != OK)
    return rv;
  network_ = network;
  return socket_.Connect(address);
}

NetworkChangeNotifier::NetworkHandle UDPClientSocket::GetBoundNetwork() const {
  return network_;
}

void UDPClientSocket::ApplySocketTag(const SocketTag& tag) {
  socket_.ApplySocketTag(tag);
}

int UDPClientSocket::Read(IOBuffer* buf,
                          int buf_len,
                          const CompletionCallback& callback) {
  return socket_.Read(buf, buf_len, callback);
}

int UDPClientSocket::Write(
    IOBuffer* buf,
    int buf_len,
    const CompletionCallback& callback,
    const NetworkTrafficAnnotationTag& traffic_annotation) {
  return socket_.Write(buf, buf_len, callback, traffic_annotation);
}

void UDPClientSocket::Close() {
  socket_.Close();
}

int UDPClientSocket::GetPeerAddress(IPEndPoint* address) const {
  return socket_.GetPeerAddress(address);
}

int UDPClientSocket::GetLocalAddress(IPEndPoint* address) const {
  return socket_.GetLocalAddress(address);
}

int UDPClientSocket::SetReceiveBufferSize(int32_t size) {
  return socket_.SetReceiveBufferSize(size);
}

int UDPClientSocket::SetSendBufferSize(int32_t size) {
  return socket_.SetSendBufferSize(size);
}

int UDPClientSocket::SetDoNotFragment() {
  return socket_.SetDoNotFragment();
}

const NetLogWithSource& UDPClientSocket::NetLog() const {
  return socket_.NetLog();
}

void UDPClientSocket::UseNonBlockingIO() {
#if defined(OS_WIN)
  socket_.UseNonBlockingIO();
#endif
}

}  // namespace net
