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. is_connected()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: ReadWatcher(UDPSocketLibevent * socket)101 explicit ReadWatcher(UDPSocketLibevent* socket) : socket_(socket) {} 102 103 // MessageLoopForIO::Watcher methods 104 OnFileCanReadWithoutBlocking(int)105 virtual void OnFileCanReadWithoutBlocking(int /* fd */) { 106 if (socket_->read_callback_) 107 socket_->DidCompleteRead(); 108 } 109 OnFileCanWriteWithoutBlocking(int)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: WriteWatcher(UDPSocketLibevent * socket)120 explicit WriteWatcher(UDPSocketLibevent* socket) : socket_(socket) {} 121 122 // MessageLoopForIO::Watcher methods 123 OnFileCanReadWithoutBlocking(int)124 virtual void OnFileCanReadWithoutBlocking(int /* fd */) {} 125 OnFileCanWriteWithoutBlocking(int)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