Home | History | Annotate | Download | only in udp
      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.
      4 
      5 #include "net/udp/udp_socket_win.h"
      6 
      7 #include <mstcpip.h>
      8 
      9 #include "base/callback.h"
     10 #include "base/lazy_instance.h"
     11 #include "base/logging.h"
     12 #include "base/message_loop/message_loop.h"
     13 #include "base/metrics/histogram.h"
     14 #include "base/metrics/sparse_histogram.h"
     15 #include "base/metrics/stats_counters.h"
     16 #include "base/rand_util.h"
     17 #include "net/base/io_buffer.h"
     18 #include "net/base/ip_endpoint.h"
     19 #include "net/base/net_errors.h"
     20 #include "net/base/net_log.h"
     21 #include "net/base/net_util.h"
     22 #include "net/base/winsock_init.h"
     23 #include "net/base/winsock_util.h"
     24 #include "net/socket/socket_descriptor.h"
     25 #include "net/udp/udp_net_log_parameters.h"
     26 
     27 namespace {
     28 
     29 const int kBindRetries = 10;
     30 const int kPortStart = 1024;
     31 const int kPortEnd = 65535;
     32 
     33 }  // namespace
     34 
     35 namespace net {
     36 
     37 // This class encapsulates all the state that has to be preserved as long as
     38 // there is a network IO operation in progress. If the owner UDPSocketWin
     39 // is destroyed while an operation is in progress, the Core is detached and it
     40 // lives until the operation completes and the OS doesn't reference any resource
     41 // declared on this class anymore.
     42 class UDPSocketWin::Core : public base::RefCounted<Core> {
     43  public:
     44   explicit Core(UDPSocketWin* socket);
     45 
     46   // Start watching for the end of a read or write operation.
     47   void WatchForRead();
     48   void WatchForWrite();
     49 
     50   // The UDPSocketWin is going away.
     51   void Detach() { socket_ = NULL; }
     52 
     53   // The separate OVERLAPPED variables for asynchronous operation.
     54   OVERLAPPED read_overlapped_;
     55   OVERLAPPED write_overlapped_;
     56 
     57   // The buffers used in Read() and Write().
     58   scoped_refptr<IOBuffer> read_iobuffer_;
     59   scoped_refptr<IOBuffer> write_iobuffer_;
     60 
     61   // The address storage passed to WSARecvFrom().
     62   SockaddrStorage recv_addr_storage_;
     63 
     64  private:
     65   friend class base::RefCounted<Core>;
     66 
     67   class ReadDelegate : public base::win::ObjectWatcher::Delegate {
     68    public:
     69     explicit ReadDelegate(Core* core) : core_(core) {}
     70     virtual ~ReadDelegate() {}
     71 
     72     // base::ObjectWatcher::Delegate methods:
     73     virtual void OnObjectSignaled(HANDLE object);
     74 
     75    private:
     76     Core* const core_;
     77   };
     78 
     79   class WriteDelegate : public base::win::ObjectWatcher::Delegate {
     80    public:
     81     explicit WriteDelegate(Core* core) : core_(core) {}
     82     virtual ~WriteDelegate() {}
     83 
     84     // base::ObjectWatcher::Delegate methods:
     85     virtual void OnObjectSignaled(HANDLE object);
     86 
     87    private:
     88     Core* const core_;
     89   };
     90 
     91   ~Core();
     92 
     93   // The socket that created this object.
     94   UDPSocketWin* socket_;
     95 
     96   // |reader_| handles the signals from |read_watcher_|.
     97   ReadDelegate reader_;
     98   // |writer_| handles the signals from |write_watcher_|.
     99   WriteDelegate writer_;
    100 
    101   // |read_watcher_| watches for events from Read().
    102   base::win::ObjectWatcher read_watcher_;
    103   // |write_watcher_| watches for events from Write();
    104   base::win::ObjectWatcher write_watcher_;
    105 
    106   DISALLOW_COPY_AND_ASSIGN(Core);
    107 };
    108 
    109 UDPSocketWin::Core::Core(UDPSocketWin* socket)
    110     : socket_(socket),
    111       reader_(this),
    112       writer_(this) {
    113   memset(&read_overlapped_, 0, sizeof(read_overlapped_));
    114   memset(&write_overlapped_, 0, sizeof(write_overlapped_));
    115 
    116   read_overlapped_.hEvent = WSACreateEvent();
    117   write_overlapped_.hEvent = WSACreateEvent();
    118 }
    119 
    120 UDPSocketWin::Core::~Core() {
    121   // Make sure the message loop is not watching this object anymore.
    122   read_watcher_.StopWatching();
    123   write_watcher_.StopWatching();
    124 
    125   WSACloseEvent(read_overlapped_.hEvent);
    126   memset(&read_overlapped_, 0xaf, sizeof(read_overlapped_));
    127   WSACloseEvent(write_overlapped_.hEvent);
    128   memset(&write_overlapped_, 0xaf, sizeof(write_overlapped_));
    129 }
    130 
    131 void UDPSocketWin::Core::WatchForRead() {
    132   // We grab an extra reference because there is an IO operation in progress.
    133   // Balanced in ReadDelegate::OnObjectSignaled().
    134   AddRef();
    135   read_watcher_.StartWatching(read_overlapped_.hEvent, &reader_);
    136 }
    137 
    138 void UDPSocketWin::Core::WatchForWrite() {
    139   // We grab an extra reference because there is an IO operation in progress.
    140   // Balanced in WriteDelegate::OnObjectSignaled().
    141   AddRef();
    142   write_watcher_.StartWatching(write_overlapped_.hEvent, &writer_);
    143 }
    144 
    145 void UDPSocketWin::Core::ReadDelegate::OnObjectSignaled(HANDLE object) {
    146   DCHECK_EQ(object, core_->read_overlapped_.hEvent);
    147   if (core_->socket_)
    148     core_->socket_->DidCompleteRead();
    149 
    150   core_->Release();
    151 }
    152 
    153 void UDPSocketWin::Core::WriteDelegate::OnObjectSignaled(HANDLE object) {
    154   DCHECK_EQ(object, core_->write_overlapped_.hEvent);
    155   if (core_->socket_)
    156     core_->socket_->DidCompleteWrite();
    157 
    158   core_->Release();
    159 }
    160 //-----------------------------------------------------------------------------
    161 
    162 QwaveAPI::QwaveAPI() : qwave_supported_(false) {
    163   HMODULE qwave = LoadLibrary(L"qwave.dll");
    164   if (!qwave)
    165     return;
    166   create_handle_func_ =
    167       (CreateHandleFn)GetProcAddress(qwave, "QOSCreateHandle");
    168   close_handle_func_ =
    169       (CloseHandleFn)GetProcAddress(qwave, "QOSCloseHandle");
    170   add_socket_to_flow_func_ =
    171       (AddSocketToFlowFn)GetProcAddress(qwave, "QOSAddSocketToFlow");
    172   remove_socket_from_flow_func_ =
    173       (RemoveSocketFromFlowFn)GetProcAddress(qwave, "QOSRemoveSocketFromFlow");
    174   set_flow_func_ = (SetFlowFn)GetProcAddress(qwave, "QOSSetFlow");
    175 
    176   if (create_handle_func_ && close_handle_func_ &&
    177       add_socket_to_flow_func_ && remove_socket_from_flow_func_ &&
    178       set_flow_func_) {
    179     qwave_supported_ = true;
    180   }
    181 }
    182 
    183 QwaveAPI& QwaveAPI::Get() {
    184   static base::LazyInstance<QwaveAPI>::Leaky lazy_qwave =
    185     LAZY_INSTANCE_INITIALIZER;
    186   return lazy_qwave.Get();
    187 }
    188 
    189 bool QwaveAPI::qwave_supported() const {
    190   return qwave_supported_;
    191 }
    192 BOOL QwaveAPI::CreateHandle(PQOS_VERSION version, PHANDLE handle) {
    193   return create_handle_func_(version, handle);
    194 }
    195 BOOL QwaveAPI::CloseHandle(HANDLE handle) {
    196   return close_handle_func_(handle);
    197 }
    198 
    199 BOOL QwaveAPI::AddSocketToFlow(HANDLE handle,
    200                                SOCKET socket,
    201                                PSOCKADDR addr,
    202                                QOS_TRAFFIC_TYPE traffic_type,
    203                                DWORD flags,
    204                                PQOS_FLOWID flow_id) {
    205   return add_socket_to_flow_func_(handle,
    206                                   socket,
    207                                   addr,
    208                                   traffic_type,
    209                                   flags,
    210                                   flow_id);
    211 }
    212 
    213 BOOL QwaveAPI::RemoveSocketFromFlow(HANDLE handle,
    214                                     SOCKET socket,
    215                                     QOS_FLOWID flow_id,
    216                                     DWORD reserved) {
    217   return remove_socket_from_flow_func_(handle, socket, flow_id, reserved);
    218 }
    219 
    220 BOOL QwaveAPI::SetFlow(HANDLE handle,
    221                        QOS_FLOWID flow_id,
    222                        QOS_SET_FLOW op,
    223                        ULONG size,
    224                        PVOID data,
    225                        DWORD reserved,
    226                        LPOVERLAPPED overlapped) {
    227   return set_flow_func_(handle,
    228                         flow_id,
    229                         op,
    230                         size,
    231                         data,
    232                         reserved,
    233                         overlapped);
    234 }
    235 
    236 
    237 //-----------------------------------------------------------------------------
    238 
    239 UDPSocketWin::UDPSocketWin(DatagramSocket::BindType bind_type,
    240                            const RandIntCallback& rand_int_cb,
    241                            net::NetLog* net_log,
    242                            const net::NetLog::Source& source)
    243     : socket_(INVALID_SOCKET),
    244       addr_family_(0),
    245       socket_options_(SOCKET_OPTION_MULTICAST_LOOP),
    246       multicast_interface_(0),
    247       multicast_time_to_live_(1),
    248       bind_type_(bind_type),
    249       rand_int_cb_(rand_int_cb),
    250       recv_from_address_(NULL),
    251       net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)),
    252       qos_handle_(NULL),
    253       qos_flow_id_(0) {
    254   EnsureWinsockInit();
    255   net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE,
    256                       source.ToEventParametersCallback());
    257   if (bind_type == DatagramSocket::RANDOM_BIND)
    258     DCHECK(!rand_int_cb.is_null());
    259 }
    260 
    261 UDPSocketWin::~UDPSocketWin() {
    262   Close();
    263   net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE);
    264 }
    265 
    266 void UDPSocketWin::Close() {
    267   DCHECK(CalledOnValidThread());
    268 
    269   if (!is_connected())
    270     return;
    271 
    272   if (qos_handle_) {
    273     QwaveAPI::Get().CloseHandle(qos_handle_);
    274   }
    275 
    276   // Zero out any pending read/write callback state.
    277   read_callback_.Reset();
    278   recv_from_address_ = NULL;
    279   write_callback_.Reset();
    280 
    281   base::TimeTicks start_time = base::TimeTicks::Now();
    282   closesocket(socket_);
    283   UMA_HISTOGRAM_TIMES("Net.UDPSocketWinClose",
    284                       base::TimeTicks::Now() - start_time);
    285   socket_ = INVALID_SOCKET;
    286   addr_family_ = 0;
    287 
    288   core_->Detach();
    289   core_ = NULL;
    290 }
    291 
    292 int UDPSocketWin::GetPeerAddress(IPEndPoint* address) const {
    293   DCHECK(CalledOnValidThread());
    294   DCHECK(address);
    295   if (!is_connected())
    296     return ERR_SOCKET_NOT_CONNECTED;
    297 
    298   // TODO(szym): Simplify. http://crbug.com/126152
    299   if (!remote_address_.get()) {
    300     SockaddrStorage storage;
    301     if (getpeername(socket_, storage.addr, &storage.addr_len))
    302       return MapSystemError(WSAGetLastError());
    303     scoped_ptr<IPEndPoint> address(new IPEndPoint());
    304     if (!address->FromSockAddr(storage.addr, storage.addr_len))
    305       return ERR_ADDRESS_INVALID;
    306     remote_address_.reset(address.release());
    307   }
    308 
    309   *address = *remote_address_;
    310   return OK;
    311 }
    312 
    313 int UDPSocketWin::GetLocalAddress(IPEndPoint* address) const {
    314   DCHECK(CalledOnValidThread());
    315   DCHECK(address);
    316   if (!is_connected())
    317     return ERR_SOCKET_NOT_CONNECTED;
    318 
    319   // TODO(szym): Simplify. http://crbug.com/126152
    320   if (!local_address_.get()) {
    321     SockaddrStorage storage;
    322     if (getsockname(socket_, storage.addr, &storage.addr_len))
    323       return MapSystemError(WSAGetLastError());
    324     scoped_ptr<IPEndPoint> address(new IPEndPoint());
    325     if (!address->FromSockAddr(storage.addr, storage.addr_len))
    326       return ERR_ADDRESS_INVALID;
    327     local_address_.reset(address.release());
    328     net_log_.AddEvent(NetLog::TYPE_UDP_LOCAL_ADDRESS,
    329                       CreateNetLogUDPConnectCallback(local_address_.get()));
    330   }
    331 
    332   *address = *local_address_;
    333   return OK;
    334 }
    335 
    336 int UDPSocketWin::Read(IOBuffer* buf,
    337                        int buf_len,
    338                        const CompletionCallback& callback) {
    339   return RecvFrom(buf, buf_len, NULL, callback);
    340 }
    341 
    342 int UDPSocketWin::RecvFrom(IOBuffer* buf,
    343                            int buf_len,
    344                            IPEndPoint* address,
    345                            const CompletionCallback& callback) {
    346   DCHECK(CalledOnValidThread());
    347   DCHECK_NE(INVALID_SOCKET, socket_);
    348   CHECK(read_callback_.is_null());
    349   DCHECK(!recv_from_address_);
    350   DCHECK(!callback.is_null());  // Synchronous operation not supported.
    351   DCHECK_GT(buf_len, 0);
    352 
    353   int nread = InternalRecvFrom(buf, buf_len, address);
    354   if (nread != ERR_IO_PENDING)
    355     return nread;
    356 
    357   read_callback_ = callback;
    358   recv_from_address_ = address;
    359   return ERR_IO_PENDING;
    360 }
    361 
    362 int UDPSocketWin::Write(IOBuffer* buf,
    363                         int buf_len,
    364                         const CompletionCallback& callback) {
    365   return SendToOrWrite(buf, buf_len, NULL, callback);
    366 }
    367 
    368 int UDPSocketWin::SendTo(IOBuffer* buf,
    369                          int buf_len,
    370                          const IPEndPoint& address,
    371                          const CompletionCallback& callback) {
    372   return SendToOrWrite(buf, buf_len, &address, callback);
    373 }
    374 
    375 int UDPSocketWin::SendToOrWrite(IOBuffer* buf,
    376                                 int buf_len,
    377                                 const IPEndPoint* address,
    378                                 const CompletionCallback& callback) {
    379   DCHECK(CalledOnValidThread());
    380   DCHECK_NE(INVALID_SOCKET, socket_);
    381   CHECK(write_callback_.is_null());
    382   DCHECK(!callback.is_null());  // Synchronous operation not supported.
    383   DCHECK_GT(buf_len, 0);
    384   DCHECK(!send_to_address_.get());
    385 
    386   int nwrite = InternalSendTo(buf, buf_len, address);
    387   if (nwrite != ERR_IO_PENDING)
    388     return nwrite;
    389 
    390   if (address)
    391     send_to_address_.reset(new IPEndPoint(*address));
    392   write_callback_ = callback;
    393   return ERR_IO_PENDING;
    394 }
    395 
    396 int UDPSocketWin::Connect(const IPEndPoint& address) {
    397   net_log_.BeginEvent(NetLog::TYPE_UDP_CONNECT,
    398                       CreateNetLogUDPConnectCallback(&address));
    399   int rv = InternalConnect(address);
    400   if (rv != OK)
    401     Close();
    402   net_log_.EndEventWithNetErrorCode(NetLog::TYPE_UDP_CONNECT, rv);
    403   return rv;
    404 }
    405 
    406 int UDPSocketWin::InternalConnect(const IPEndPoint& address) {
    407   DCHECK(!is_connected());
    408   DCHECK(!remote_address_.get());
    409   int addr_family = address.GetSockAddrFamily();
    410   int rv = CreateSocket(addr_family);
    411   if (rv < 0)
    412     return rv;
    413 
    414   if (bind_type_ == DatagramSocket::RANDOM_BIND) {
    415     // Construct IPAddressNumber of appropriate size (IPv4 or IPv6) of 0s,
    416     // representing INADDR_ANY or in6addr_any.
    417     size_t addr_size =
    418         addr_family == AF_INET ? kIPv4AddressSize : kIPv6AddressSize;
    419     IPAddressNumber addr_any(addr_size);
    420     rv = RandomBind(addr_any);
    421   }
    422   // else connect() does the DatagramSocket::DEFAULT_BIND
    423 
    424   if (rv < 0) {
    425     UMA_HISTOGRAM_SPARSE_SLOWLY("Net.UdpSocketRandomBindErrorCode", -rv);
    426     Close();
    427     return rv;
    428   }
    429 
    430   SockaddrStorage storage;
    431   if (!address.ToSockAddr(storage.addr, &storage.addr_len))
    432     return ERR_ADDRESS_INVALID;
    433 
    434   rv = connect(socket_, storage.addr, storage.addr_len);
    435   if (rv < 0) {
    436     // Close() may change the last error. Map it beforehand.
    437     int result = MapSystemError(WSAGetLastError());
    438     Close();
    439     return result;
    440   }
    441 
    442   remote_address_.reset(new IPEndPoint(address));
    443   return rv;
    444 }
    445 
    446 int UDPSocketWin::Bind(const IPEndPoint& address) {
    447   DCHECK(!is_connected());
    448   int rv = CreateSocket(address.GetSockAddrFamily());
    449   if (rv < 0)
    450     return rv;
    451   rv = SetSocketOptions();
    452   if (rv < 0) {
    453     Close();
    454     return rv;
    455   }
    456   rv = DoBind(address);
    457   if (rv < 0) {
    458     Close();
    459     return rv;
    460   }
    461   local_address_.reset();
    462   return rv;
    463 }
    464 
    465 int UDPSocketWin::CreateSocket(int addr_family) {
    466   addr_family_ = addr_family;
    467   socket_ = CreatePlatformSocket(addr_family_, SOCK_DGRAM, IPPROTO_UDP);
    468   if (socket_ == INVALID_SOCKET)
    469     return MapSystemError(WSAGetLastError());
    470   core_ = new Core(this);
    471   return OK;
    472 }
    473 
    474 int UDPSocketWin::SetReceiveBufferSize(int32 size) {
    475   DCHECK(CalledOnValidThread());
    476   int rv = setsockopt(socket_, SOL_SOCKET, SO_RCVBUF,
    477                       reinterpret_cast<const char*>(&size), sizeof(size));
    478   if (rv != 0)
    479     return MapSystemError(WSAGetLastError());
    480 
    481   // According to documentation, setsockopt may succeed, but we need to check
    482   // the results via getsockopt to be sure it works on Windows.
    483   int32 actual_size = 0;
    484   int option_size = sizeof(actual_size);
    485   rv = getsockopt(socket_, SOL_SOCKET, SO_RCVBUF,
    486                   reinterpret_cast<char*>(&actual_size), &option_size);
    487   if (rv != 0)
    488     return MapSystemError(WSAGetLastError());
    489   if (actual_size >= size)
    490     return OK;
    491   UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SocketUnchangeableReceiveBuffer",
    492                               actual_size, 1000, 1000000, 50);
    493   return ERR_SOCKET_RECEIVE_BUFFER_SIZE_UNCHANGEABLE;
    494 }
    495 
    496 int UDPSocketWin::SetSendBufferSize(int32 size) {
    497   DCHECK(CalledOnValidThread());
    498   int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF,
    499                       reinterpret_cast<const char*>(&size), sizeof(size));
    500   if (rv != 0)
    501     return MapSystemError(WSAGetLastError());
    502   // According to documentation, setsockopt may succeed, but we need to check
    503   // the results via getsockopt to be sure it works on Windows.
    504   int32 actual_size = 0;
    505   int option_size = sizeof(actual_size);
    506   rv = getsockopt(socket_, SOL_SOCKET, SO_SNDBUF,
    507                   reinterpret_cast<char*>(&actual_size), &option_size);
    508   if (rv != 0)
    509     return MapSystemError(WSAGetLastError());
    510   if (actual_size >= size)
    511     return OK;
    512   UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SocketUnchangeableSendBuffer",
    513                               actual_size, 1000, 1000000, 50);
    514   return ERR_SOCKET_SEND_BUFFER_SIZE_UNCHANGEABLE;
    515 }
    516 
    517 void UDPSocketWin::AllowAddressReuse() {
    518   DCHECK(CalledOnValidThread());
    519   DCHECK(!is_connected());
    520 
    521   socket_options_ |= SOCKET_OPTION_REUSE_ADDRESS;
    522 }
    523 
    524 void UDPSocketWin::AllowBroadcast() {
    525   DCHECK(CalledOnValidThread());
    526   DCHECK(!is_connected());
    527 
    528   socket_options_ |= SOCKET_OPTION_BROADCAST;
    529 }
    530 
    531 void UDPSocketWin::DoReadCallback(int rv) {
    532   DCHECK_NE(rv, ERR_IO_PENDING);
    533   DCHECK(!read_callback_.is_null());
    534 
    535   // since Run may result in Read being called, clear read_callback_ up front.
    536   CompletionCallback c = read_callback_;
    537   read_callback_.Reset();
    538   c.Run(rv);
    539 }
    540 
    541 void UDPSocketWin::DoWriteCallback(int rv) {
    542   DCHECK_NE(rv, ERR_IO_PENDING);
    543   DCHECK(!write_callback_.is_null());
    544 
    545   // since Run may result in Write being called, clear write_callback_ up front.
    546   CompletionCallback c = write_callback_;
    547   write_callback_.Reset();
    548   c.Run(rv);
    549 }
    550 
    551 void UDPSocketWin::DidCompleteRead() {
    552   DWORD num_bytes, flags;
    553   BOOL ok = WSAGetOverlappedResult(socket_, &core_->read_overlapped_,
    554                                    &num_bytes, FALSE, &flags);
    555   WSAResetEvent(core_->read_overlapped_.hEvent);
    556   int result = ok ? num_bytes : MapSystemError(WSAGetLastError());
    557   // Convert address.
    558   if (recv_from_address_ && result >= 0) {
    559     if (!ReceiveAddressToIPEndpoint(recv_from_address_))
    560       result = ERR_ADDRESS_INVALID;
    561   }
    562   LogRead(result, core_->read_iobuffer_->data());
    563   core_->read_iobuffer_ = NULL;
    564   recv_from_address_ = NULL;
    565   DoReadCallback(result);
    566 }
    567 
    568 void UDPSocketWin::LogRead(int result, const char* bytes) const {
    569   if (result < 0) {
    570     net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_RECEIVE_ERROR, result);
    571     return;
    572   }
    573 
    574   if (net_log_.IsLogging()) {
    575     // Get address for logging, if |address| is NULL.
    576     IPEndPoint address;
    577     bool is_address_valid = ReceiveAddressToIPEndpoint(&address);
    578     net_log_.AddEvent(
    579         NetLog::TYPE_UDP_BYTES_RECEIVED,
    580         CreateNetLogUDPDataTranferCallback(
    581             result, bytes,
    582             is_address_valid ? &address : NULL));
    583   }
    584 
    585   base::StatsCounter read_bytes("udp.read_bytes");
    586   read_bytes.Add(result);
    587 }
    588 
    589 void UDPSocketWin::DidCompleteWrite() {
    590   DWORD num_bytes, flags;
    591   BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_,
    592                                    &num_bytes, FALSE, &flags);
    593   WSAResetEvent(core_->write_overlapped_.hEvent);
    594   int result = ok ? num_bytes : MapSystemError(WSAGetLastError());
    595   LogWrite(result, core_->write_iobuffer_->data(), send_to_address_.get());
    596 
    597   send_to_address_.reset();
    598   core_->write_iobuffer_ = NULL;
    599   DoWriteCallback(result);
    600 }
    601 
    602 void UDPSocketWin::LogWrite(int result,
    603                             const char* bytes,
    604                             const IPEndPoint* address) const {
    605   if (result < 0) {
    606     net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_SEND_ERROR, result);
    607     return;
    608   }
    609 
    610   if (net_log_.IsLogging()) {
    611     net_log_.AddEvent(
    612         NetLog::TYPE_UDP_BYTES_SENT,
    613         CreateNetLogUDPDataTranferCallback(result, bytes, address));
    614   }
    615 
    616   base::StatsCounter write_bytes("udp.write_bytes");
    617   write_bytes.Add(result);
    618 }
    619 
    620 int UDPSocketWin::InternalRecvFrom(IOBuffer* buf, int buf_len,
    621                                    IPEndPoint* address) {
    622   DCHECK(!core_->read_iobuffer_);
    623   SockaddrStorage& storage = core_->recv_addr_storage_;
    624   storage.addr_len = sizeof(storage.addr_storage);
    625 
    626   WSABUF read_buffer;
    627   read_buffer.buf = buf->data();
    628   read_buffer.len = buf_len;
    629 
    630   DWORD flags = 0;
    631   DWORD num;
    632   CHECK_NE(INVALID_SOCKET, socket_);
    633   AssertEventNotSignaled(core_->read_overlapped_.hEvent);
    634   int rv = WSARecvFrom(socket_, &read_buffer, 1, &num, &flags, storage.addr,
    635                        &storage.addr_len, &core_->read_overlapped_, NULL);
    636   if (rv == 0) {
    637     if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) {
    638       int result = num;
    639       // Convert address.
    640       if (address && result >= 0) {
    641         if (!ReceiveAddressToIPEndpoint(address))
    642           result = ERR_ADDRESS_INVALID;
    643       }
    644       LogRead(result, buf->data());
    645       return result;
    646     }
    647   } else {
    648     int os_error = WSAGetLastError();
    649     if (os_error != WSA_IO_PENDING) {
    650       int result = MapSystemError(os_error);
    651       LogRead(result, NULL);
    652       return result;
    653     }
    654   }
    655   core_->WatchForRead();
    656   core_->read_iobuffer_ = buf;
    657   return ERR_IO_PENDING;
    658 }
    659 
    660 int UDPSocketWin::InternalSendTo(IOBuffer* buf, int buf_len,
    661                                  const IPEndPoint* address) {
    662   DCHECK(!core_->write_iobuffer_);
    663   SockaddrStorage storage;
    664   struct sockaddr* addr = storage.addr;
    665   // Convert address.
    666   if (!address) {
    667     addr = NULL;
    668     storage.addr_len = 0;
    669   } else {
    670     if (!address->ToSockAddr(addr, &storage.addr_len)) {
    671       int result = ERR_ADDRESS_INVALID;
    672       LogWrite(result, NULL, NULL);
    673       return result;
    674     }
    675   }
    676 
    677   WSABUF write_buffer;
    678   write_buffer.buf = buf->data();
    679   write_buffer.len = buf_len;
    680 
    681   DWORD flags = 0;
    682   DWORD num;
    683   AssertEventNotSignaled(core_->write_overlapped_.hEvent);
    684   int rv = WSASendTo(socket_, &write_buffer, 1, &num, flags,
    685                      addr, storage.addr_len, &core_->write_overlapped_, NULL);
    686   if (rv == 0) {
    687     if (ResetEventIfSignaled(core_->write_overlapped_.hEvent)) {
    688       int result = num;
    689       LogWrite(result, buf->data(), address);
    690       return result;
    691     }
    692   } else {
    693     int os_error = WSAGetLastError();
    694     if (os_error != WSA_IO_PENDING) {
    695       int result = MapSystemError(os_error);
    696       LogWrite(result, NULL, NULL);
    697       return result;
    698     }
    699   }
    700 
    701   core_->WatchForWrite();
    702   core_->write_iobuffer_ = buf;
    703   return ERR_IO_PENDING;
    704 }
    705 
    706 int UDPSocketWin::SetSocketOptions() {
    707   BOOL true_value = 1;
    708   if (socket_options_ & SOCKET_OPTION_REUSE_ADDRESS) {
    709     int rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR,
    710                         reinterpret_cast<const char*>(&true_value),
    711                         sizeof(true_value));
    712     if (rv < 0)
    713       return MapSystemError(WSAGetLastError());
    714   }
    715   if (socket_options_ & SOCKET_OPTION_BROADCAST) {
    716     int rv = setsockopt(socket_, SOL_SOCKET, SO_BROADCAST,
    717                         reinterpret_cast<const char*>(&true_value),
    718                         sizeof(true_value));
    719     if (rv < 0)
    720       return MapSystemError(WSAGetLastError());
    721   }
    722   if (!(socket_options_ & SOCKET_OPTION_MULTICAST_LOOP)) {
    723     DWORD loop = 0;
    724     int protocol_level =
    725         addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
    726     int option =
    727         addr_family_ == AF_INET ? IP_MULTICAST_LOOP: IPV6_MULTICAST_LOOP;
    728     int rv = setsockopt(socket_, protocol_level, option,
    729                         reinterpret_cast<const char*>(&loop), sizeof(loop));
    730     if (rv < 0)
    731       return MapSystemError(WSAGetLastError());
    732   }
    733   if (multicast_time_to_live_ != 1) {
    734     DWORD hops = multicast_time_to_live_;
    735     int protocol_level =
    736         addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
    737     int option =
    738         addr_family_ == AF_INET ? IP_MULTICAST_TTL: IPV6_MULTICAST_HOPS;
    739     int rv = setsockopt(socket_, protocol_level, option,
    740                         reinterpret_cast<const char*>(&hops), sizeof(hops));
    741     if (rv < 0)
    742       return MapSystemError(WSAGetLastError());
    743   }
    744   if (multicast_interface_ != 0) {
    745     switch (addr_family_) {
    746       case AF_INET: {
    747         in_addr address;
    748         address.s_addr = htonl(multicast_interface_);
    749         int rv = setsockopt(socket_, IPPROTO_IP, IP_MULTICAST_IF,
    750                             reinterpret_cast<const char*>(&address),
    751                             sizeof(address));
    752         if (rv)
    753           return MapSystemError(WSAGetLastError());
    754         break;
    755       }
    756       case AF_INET6: {
    757         uint32 interface_index = multicast_interface_;
    758         int rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_MULTICAST_IF,
    759                             reinterpret_cast<const char*>(&interface_index),
    760                             sizeof(interface_index));
    761         if (rv)
    762           return MapSystemError(WSAGetLastError());
    763         break;
    764       }
    765       default:
    766         NOTREACHED() << "Invalid address family";
    767         return ERR_ADDRESS_INVALID;
    768     }
    769   }
    770   return OK;
    771 }
    772 
    773 int UDPSocketWin::DoBind(const IPEndPoint& address) {
    774   SockaddrStorage storage;
    775   if (!address.ToSockAddr(storage.addr, &storage.addr_len))
    776     return ERR_ADDRESS_INVALID;
    777   int rv = bind(socket_, storage.addr, storage.addr_len);
    778   if (rv == 0)
    779     return OK;
    780   int last_error = WSAGetLastError();
    781   UMA_HISTOGRAM_SPARSE_SLOWLY("Net.UdpSocketBindErrorFromWinOS", last_error);
    782   // Map some codes that are special to bind() separately.
    783   // * WSAEACCES: If a port is already bound to a socket, WSAEACCES may be
    784   //   returned instead of WSAEADDRINUSE, depending on whether the socket
    785   //   option SO_REUSEADDR or SO_EXCLUSIVEADDRUSE is set and whether the
    786   //   conflicting socket is owned by a different user account. See the MSDN
    787   //   page "Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE" for the gory details.
    788   if (last_error == WSAEACCES || last_error == WSAEADDRNOTAVAIL)
    789     return ERR_ADDRESS_IN_USE;
    790   return MapSystemError(last_error);
    791 }
    792 
    793 int UDPSocketWin::RandomBind(const IPAddressNumber& address) {
    794   DCHECK(bind_type_ == DatagramSocket::RANDOM_BIND && !rand_int_cb_.is_null());
    795 
    796   for (int i = 0; i < kBindRetries; ++i) {
    797     int rv = DoBind(IPEndPoint(address,
    798                                rand_int_cb_.Run(kPortStart, kPortEnd)));
    799     if (rv == OK || rv != ERR_ADDRESS_IN_USE)
    800       return rv;
    801   }
    802   return DoBind(IPEndPoint(address, 0));
    803 }
    804 
    805 bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const {
    806   SockaddrStorage& storage = core_->recv_addr_storage_;
    807   return address->FromSockAddr(storage.addr, storage.addr_len);
    808 }
    809 
    810 int UDPSocketWin::JoinGroup(
    811     const IPAddressNumber& group_address) const {
    812   DCHECK(CalledOnValidThread());
    813   if (!is_connected())
    814     return ERR_SOCKET_NOT_CONNECTED;
    815 
    816   switch (group_address.size()) {
    817     case kIPv4AddressSize: {
    818       if (addr_family_ != AF_INET)
    819         return ERR_ADDRESS_INVALID;
    820       ip_mreq mreq;
    821       mreq.imr_interface.s_addr = htonl(multicast_interface_);
    822       memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize);
    823       int rv = setsockopt(socket_, IPPROTO_IP, IP_ADD_MEMBERSHIP,
    824                           reinterpret_cast<const char*>(&mreq),
    825                           sizeof(mreq));
    826       if (rv)
    827         return MapSystemError(WSAGetLastError());
    828       return OK;
    829     }
    830     case kIPv6AddressSize: {
    831       if (addr_family_ != AF_INET6)
    832         return ERR_ADDRESS_INVALID;
    833       ipv6_mreq mreq;
    834       mreq.ipv6mr_interface = multicast_interface_;
    835       memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize);
    836       int rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP,
    837                           reinterpret_cast<const char*>(&mreq),
    838                           sizeof(mreq));
    839       if (rv)
    840         return MapSystemError(WSAGetLastError());
    841       return OK;
    842     }
    843     default:
    844       NOTREACHED() << "Invalid address family";
    845       return ERR_ADDRESS_INVALID;
    846   }
    847 }
    848 
    849 int UDPSocketWin::LeaveGroup(
    850     const IPAddressNumber& group_address) const {
    851   DCHECK(CalledOnValidThread());
    852   if (!is_connected())
    853     return ERR_SOCKET_NOT_CONNECTED;
    854 
    855   switch (group_address.size()) {
    856     case kIPv4AddressSize: {
    857       if (addr_family_ != AF_INET)
    858         return ERR_ADDRESS_INVALID;
    859       ip_mreq mreq;
    860       mreq.imr_interface.s_addr = htonl(multicast_interface_);
    861       memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize);
    862       int rv = setsockopt(socket_, IPPROTO_IP, IP_DROP_MEMBERSHIP,
    863                           reinterpret_cast<const char*>(&mreq), sizeof(mreq));
    864       if (rv)
    865         return MapSystemError(WSAGetLastError());
    866       return OK;
    867     }
    868     case kIPv6AddressSize: {
    869       if (addr_family_ != AF_INET6)
    870         return ERR_ADDRESS_INVALID;
    871       ipv6_mreq mreq;
    872       mreq.ipv6mr_interface = multicast_interface_;
    873       memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize);
    874       int rv = setsockopt(socket_, IPPROTO_IPV6, IP_DROP_MEMBERSHIP,
    875                           reinterpret_cast<const char*>(&mreq), sizeof(mreq));
    876       if (rv)
    877         return MapSystemError(WSAGetLastError());
    878       return OK;
    879     }
    880     default:
    881       NOTREACHED() << "Invalid address family";
    882       return ERR_ADDRESS_INVALID;
    883   }
    884 }
    885 
    886 int UDPSocketWin::SetMulticastInterface(uint32 interface_index) {
    887   DCHECK(CalledOnValidThread());
    888   if (is_connected())
    889     return ERR_SOCKET_IS_CONNECTED;
    890   multicast_interface_ = interface_index;
    891   return OK;
    892 }
    893 
    894 int UDPSocketWin::SetMulticastTimeToLive(int time_to_live) {
    895   DCHECK(CalledOnValidThread());
    896   if (is_connected())
    897     return ERR_SOCKET_IS_CONNECTED;
    898 
    899   if (time_to_live < 0 || time_to_live > 255)
    900     return ERR_INVALID_ARGUMENT;
    901   multicast_time_to_live_ = time_to_live;
    902   return OK;
    903 }
    904 
    905 int UDPSocketWin::SetMulticastLoopbackMode(bool loopback) {
    906   DCHECK(CalledOnValidThread());
    907   if (is_connected())
    908     return ERR_SOCKET_IS_CONNECTED;
    909 
    910   if (loopback)
    911     socket_options_ |= SOCKET_OPTION_MULTICAST_LOOP;
    912   else
    913     socket_options_ &= ~SOCKET_OPTION_MULTICAST_LOOP;
    914   return OK;
    915 }
    916 
    917 int UDPSocketWin::SetDiffServCodePoint(DiffServCodePoint dscp) {
    918   if (dscp == DSCP_NO_CHANGE) {
    919     return OK;
    920   }
    921 
    922   if (!is_connected())
    923     return ERR_SOCKET_NOT_CONNECTED;
    924 
    925   QwaveAPI& qos(QwaveAPI::Get());
    926 
    927   if (!qos.qwave_supported())
    928     return ERROR_NOT_SUPPORTED;
    929 
    930   if (qos_handle_ == NULL) {
    931     QOS_VERSION version;
    932     version.MajorVersion = 1;
    933     version.MinorVersion = 0;
    934     qos.CreateHandle(&version, &qos_handle_);
    935     if (qos_handle_ == NULL)
    936       return ERROR_NOT_SUPPORTED;
    937   }
    938 
    939   QOS_TRAFFIC_TYPE traffic_type = QOSTrafficTypeBestEffort;
    940   switch (dscp) {
    941     case DSCP_CS0:
    942       traffic_type = QOSTrafficTypeBestEffort;
    943       break;
    944     case DSCP_CS1:
    945       traffic_type = QOSTrafficTypeBackground;
    946       break;
    947     case DSCP_AF11:
    948     case DSCP_AF12:
    949     case DSCP_AF13:
    950     case DSCP_CS2:
    951     case DSCP_AF21:
    952     case DSCP_AF22:
    953     case DSCP_AF23:
    954     case DSCP_CS3:
    955     case DSCP_AF31:
    956     case DSCP_AF32:
    957     case DSCP_AF33:
    958     case DSCP_CS4:
    959       traffic_type = QOSTrafficTypeExcellentEffort;
    960       break;
    961     case DSCP_AF41:
    962     case DSCP_AF42:
    963     case DSCP_AF43:
    964     case DSCP_CS5:
    965       traffic_type = QOSTrafficTypeAudioVideo;
    966       break;
    967     case DSCP_EF:
    968     case DSCP_CS6:
    969       traffic_type = QOSTrafficTypeVoice;
    970       break;
    971     case DSCP_CS7:
    972       traffic_type = QOSTrafficTypeControl;
    973       break;
    974     case DSCP_NO_CHANGE:
    975       NOTREACHED();
    976       break;
    977   }
    978   if (qos_flow_id_ != 0) {
    979     qos.RemoveSocketFromFlow(qos_handle_, NULL, qos_flow_id_, 0);
    980     qos_flow_id_ = 0;
    981   }
    982   if (!qos.AddSocketToFlow(qos_handle_,
    983                            socket_,
    984                            NULL,
    985                            traffic_type,
    986                            QOS_NON_ADAPTIVE_FLOW,
    987                            &qos_flow_id_)) {
    988     DWORD err = GetLastError();
    989     if (err == ERROR_DEVICE_REINITIALIZATION_NEEDED) {
    990       qos.CloseHandle(qos_handle_);
    991       qos_flow_id_ = 0;
    992       qos_handle_ = 0;
    993     }
    994     return MapSystemError(err);
    995   }
    996   // This requires admin rights, and may fail, if so we ignore it
    997   // as AddSocketToFlow should still do *approximately* the right thing.
    998   DWORD buf = dscp;
    999   qos.SetFlow(qos_handle_,
   1000               qos_flow_id_,
   1001               QOSSetOutgoingDSCPValue,
   1002               sizeof(buf),
   1003               &buf,
   1004               0,
   1005               NULL);
   1006 
   1007   return OK;
   1008 }
   1009 
   1010 void UDPSocketWin::DetachFromThread() {
   1011   base::NonThreadSafe::DetachFromThread();
   1012 }
   1013 
   1014 }  // namespace net
   1015