• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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