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