Home | History | Annotate | Download | only in udp
      1 // Copyright (c) 2011 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 #ifndef NET_UDP_UDP_SOCKET_WIN_H_
      6 #define NET_UDP_UDP_SOCKET_WIN_H_
      7 #pragma once
      8 
      9 #include <winsock2.h>
     10 
     11 #include "base/memory/ref_counted.h"
     12 #include "base/memory/scoped_ptr.h"
     13 #include "base/threading/non_thread_safe.h"
     14 #include "base/win/object_watcher.h"
     15 #include "net/base/completion_callback.h"
     16 #include "net/base/ip_endpoint.h"
     17 #include "net/base/io_buffer.h"
     18 #include "net/base/net_log.h"
     19 
     20 namespace net {
     21 
     22 class BoundNetLog;
     23 
     24 class UDPSocketWin : public base::NonThreadSafe {
     25  public:
     26   UDPSocketWin(net::NetLog* net_log,
     27                const net::NetLog::Source& source);
     28   virtual ~UDPSocketWin();
     29 
     30   // Connect the socket to connect with a certain |address|.
     31   // Returns a net error code.
     32   int Connect(const IPEndPoint& address);
     33 
     34   // Bind the address/port for this socket to |address|.  This is generally
     35   // only used on a server.
     36   // Returns a net error code.
     37   int Bind(const IPEndPoint& address);
     38 
     39   // Close the socket.
     40   void Close();
     41 
     42   // Copy the remote udp address into |address| and return a network error code.
     43   int GetPeerAddress(IPEndPoint* address) const;
     44 
     45   // Copy the local udp address into |address| and return a network error code.
     46   // (similar to getsockname)
     47   int GetLocalAddress(IPEndPoint* address) const;
     48 
     49   // IO:
     50   // Multiple outstanding read requests are not supported.
     51   // Full duplex mode (reading and writing at the same time) is supported
     52 
     53   // Read from the socket.
     54   // Only usable from the client-side of a UDP socket, after the socket
     55   // has been connected.
     56   int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback);
     57 
     58   // Write to the socket.
     59   // Only usable from the client-side of a UDP socket, after the socket
     60   // has been connected.
     61   int Write(IOBuffer* buf, int buf_len, CompletionCallback* callback);
     62 
     63   // Read from a socket and receive sender address information.
     64   // |buf| is the buffer to read data into.
     65   // |buf_len| is the maximum amount of data to read.
     66   // |address| is a buffer provided by the caller for receiving the sender
     67   //   address information about the received data.  This buffer must be kept
     68   //   alive by the caller until the callback is placed.
     69   // |address_length| is a ptr to the length of the |address| buffer.  This
     70   //   is an input parameter containing the maximum size |address| can hold
     71   //   and also an output parameter for the size of |address| upon completion.
     72   // |callback| the callback on completion of the Recv.
     73   // Returns a net error code, or ERR_IO_PENDING if the IO is in progress.
     74   // If ERR_IO_PENDING is returned, the caller must keep |buf|, |address|,
     75   // and |address_length| alive until the callback is called.
     76   int RecvFrom(IOBuffer* buf,
     77                int buf_len,
     78                IPEndPoint* address,
     79                CompletionCallback* callback);
     80 
     81   // Send to a socket with a particular destination.
     82   // |buf| is the buffer to send
     83   // |buf_len| is the number of bytes to send
     84   // |address| is the recipient address.
     85   // |address_length| is the size of the recipient address
     86   // |callback| is the user callback function to call on complete.
     87   // Returns a net error code, or ERR_IO_PENDING if the IO is in progress.
     88   // If ERR_IO_PENDING is returned, the caller must keep |buf| and |address|
     89   // alive until the callback is called.
     90   int SendTo(IOBuffer* buf,
     91              int buf_len,
     92              const IPEndPoint& address,
     93              CompletionCallback* callback);
     94 
     95   // Returns true if the socket is already connected or bound.
     96   bool is_connected() const { return socket_ != INVALID_SOCKET; }
     97 
     98  private:
     99   class ReadDelegate : public base::win::ObjectWatcher::Delegate {
    100    public:
    101     explicit ReadDelegate(UDPSocketWin* socket) : socket_(socket) {}
    102     virtual ~ReadDelegate() {}
    103 
    104     // base::ObjectWatcher::Delegate methods:
    105     virtual void OnObjectSignaled(HANDLE object);
    106 
    107    private:
    108     UDPSocketWin* const socket_;
    109   };
    110 
    111   class WriteDelegate : public base::win::ObjectWatcher::Delegate {
    112    public:
    113     explicit WriteDelegate(UDPSocketWin* socket) : socket_(socket) {}
    114     virtual ~WriteDelegate() {}
    115 
    116     // base::ObjectWatcher::Delegate methods:
    117     virtual void OnObjectSignaled(HANDLE object);
    118 
    119    private:
    120     UDPSocketWin* const socket_;
    121   };
    122 
    123   void DoReadCallback(int rv);
    124   void DoWriteCallback(int rv);
    125   void DidCompleteRead();
    126   void DidCompleteWrite();
    127   bool ProcessSuccessfulRead(int num_bytes, IPEndPoint* address);
    128   void ProcessSuccessfulWrite(int num_bytes);
    129 
    130   // Returns the OS error code (or 0 on success).
    131   int CreateSocket(const IPEndPoint& address);
    132 
    133   // Same as SendTo(), except that address is passed by pointer
    134   // instead of by reference. It is called from Write() with |address|
    135   // set to NULL.
    136   int SendToOrWrite(IOBuffer* buf,
    137                     int buf_len,
    138                     const IPEndPoint* address,
    139                     CompletionCallback* callback);
    140 
    141   int InternalRecvFrom(IOBuffer* buf, int buf_len, IPEndPoint* address);
    142   int InternalSendTo(IOBuffer* buf, int buf_len, const IPEndPoint* address);
    143 
    144   SOCKET socket_;
    145 
    146   // These are mutable since they're just cached copies to make
    147   // GetPeerAddress/GetLocalAddress smarter.
    148   mutable scoped_ptr<IPEndPoint> local_address_;
    149   mutable scoped_ptr<IPEndPoint> remote_address_;
    150 
    151   // The socket's win wrappers
    152   ReadDelegate read_delegate_;
    153   WriteDelegate write_delegate_;
    154 
    155   // Watchers to watch for events from Read() and Write().
    156   base::win::ObjectWatcher read_watcher_;
    157   base::win::ObjectWatcher write_watcher_;
    158 
    159   // OVERLAPPED for pending read and write operations.
    160   OVERLAPPED read_overlapped_;
    161   OVERLAPPED write_overlapped_;
    162 
    163   // The buffer used by InternalRead() to retry Read requests
    164   scoped_refptr<IOBuffer> read_iobuffer_;
    165   struct sockaddr_storage recv_addr_storage_;
    166   socklen_t recv_addr_len_;
    167   IPEndPoint* recv_from_address_;
    168 
    169   // The buffer used by InternalWrite() to retry Write requests
    170   scoped_refptr<IOBuffer> write_iobuffer_;
    171 
    172   // External callback; called when read is complete.
    173   CompletionCallback* read_callback_;
    174 
    175   // External callback; called when write is complete.
    176   CompletionCallback* write_callback_;
    177 
    178   BoundNetLog net_log_;
    179 
    180   DISALLOW_COPY_AND_ASSIGN(UDPSocketWin);
    181 };
    182 
    183 }  // namespace net
    184 
    185 #endif  // NET_UDP_UDP_SOCKET_WIN_H_
    186