Line data Source code
1 : // Copyright (c) 2012-2019 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // This program is free software; you can redistribute it and/or modify
4 : // it under the terms of the GNU General Public License as published by
5 : // the Free Software Foundation; either version 2 of the License, or
6 : // (at your option) any later version.
7 : //
8 : // This program is distributed in the hope that it will be useful,
9 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 : // GNU General Public License for more details.
12 : //
13 : // You should have received a copy of the GNU General Public License
14 : // along with this program; if not, write to the Free Software
15 : // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 :
17 : /** \file
18 : * \brief Implementation of the Snap Communicator class.
19 : *
20 : * This class wraps the C poll() interface in a C++ object with many types
21 : * of objects:
22 : *
23 : * \li Server Connections; for software that want to offer a port to
24 : * which clients can connect to; the server will call accept()
25 : * once a new client connection is ready; this results in a
26 : * Server/Client connection object
27 : * \li Client Connections; for software that want to connect to
28 : * a server; these expect the IP address and port to connect to
29 : * \li Server/Client Connections; for the server when it accepts a new
30 : * connection; in this case the server gets a socket from accept()
31 : * and creates one of these objects to handle the connection
32 : *
33 : * Using the poll() function is the easiest and allows us to listen
34 : * on pretty much any number of sockets (on my server it is limited
35 : * at 16,768 and frankly over 1,000 we probably will start to have
36 : * real slowness issues on small VPN servers.)
37 : */
38 :
39 : // to get the POLLRDHUP definition
40 : #ifndef _GNU_SOURCE
41 : #define _GNU_SOURCE
42 : #endif
43 :
44 :
45 : // self
46 : //
47 : #include "eventdispatcher/fd_connection.h"
48 :
49 : //#include "eventdispatcher/snap_communicator_dispatcher.h"
50 : //
51 : //
52 : //// snaplogger lib
53 : ////
54 : //#include "snaplogger/message.h"
55 : //
56 : //
57 : //// snapdev lib
58 : ////
59 : //#include "snapdev/not_reached.h"
60 : //#include "snapdev/not_used.h"
61 : //#include "snapdev/string_replace_many.h"
62 : //
63 : //
64 : //// libaddr lib
65 : ////
66 : //#include "libaddr/addr_parser.h"
67 : //
68 : //
69 : //// C++ lib
70 : ////
71 : //#include <sstream>
72 : //#include <limits>
73 : //#include <atomic>
74 :
75 :
76 : // C lib
77 : //
78 : //#include <fcntl.h>
79 : //#include <poll.h>
80 : #include <unistd.h>
81 : //#include <sys/eventfd.h>
82 : //#include <sys/inotify.h>
83 : //#include <sys/ioctl.h>
84 : //#include <sys/resource.h>
85 : //#include <sys/syscall.h>
86 : //#include <sys/time.h>
87 :
88 :
89 : // last include
90 : //
91 : #include <snapdev/poison.h>
92 :
93 :
94 :
95 :
96 : namespace ed
97 : {
98 :
99 :
100 :
101 : /** \brief Initializes the file descriptor connection.
102 : *
103 : * This function creates a connection based on an existing file descriptor.
104 : * This is a class used to handle existing pipes or socket (opposed to other
105 : * implementations which create a pipe, open a socket, etc.) It is especially
106 : * useful if you want to listen to stdin and stdout. Use the `fileno()`
107 : * function to get the file descriptor and create a `snap_fd_connection`
108 : * object what that descriptor.
109 : *
110 : * The mode parameter defines how you are to use the file descriptor. In
111 : * other words, a socket that is read/write could be added to two different
112 : * `snap_fd_connection` objects: one to read and one to write, instead of
113 : * a single read/write object.
114 : *
115 : * Note that although you can say it's only going to be used in READ or
116 : * in WRITE mode, in all cases, make sure that the file is readable before
117 : * specifying READ or RW, and make sure that the file is writable before
118 : * specifying WRITE or RW.
119 : *
120 : * \note
121 : * It is important to note that the lifetime of the file desriptor is
122 : * not managed by this object. You are responsible for the descriptor to
123 : * stay valid as long as the connection is added to the snap_communicator
124 : * list of connections. If you want to close the connection, please first
125 : * remove the connection from the snap_communicator, destroy the connection,
126 : * then close the file descriptor.
127 : *
128 : * \note
129 : * It is possible to pass -1 (or any negative number) as the file
130 : * descriptor. In that case it is interpreted as "not a valid
131 : * file descriptor."
132 : *
133 : * \warning
134 : * If you are to use a read() or a write() that may block, make sure to
135 : * first set your file descriptor in non-blocking mode. If that's not
136 : * possible, then make sure to read or write only one byte at a time.
137 : * The loop will be slower, but you will avoid blocks which would
138 : * prevent the rest of the software from getting their own events.
139 : *
140 : * \param[in] fd The file descriptor to handle.
141 : * \param[in] mode The mode this descriptor is to be used by the connection.
142 : */
143 0 : fd_connection::fd_connection(int fd, mode_t mode)
144 : : f_fd(fd)
145 0 : , f_mode(mode)
146 : {
147 0 : }
148 :
149 :
150 : /** \brief Used to close the file descriptor.
151 : *
152 : * This function closes the file descript of this connection.
153 : *
154 : * The function is not called automatically as we mention in the
155 : * constructor, the function cannot just close the file descriptor
156 : * on its own so it is up to you to call this function or not.
157 : * It is not mandatory.
158 : *
159 : * The function does not verify to know whether the file descriptor
160 : * was already closed outside of this function. Although it is safe
161 : * to call this function multiple times, if you close the file
162 : * descriptor with other means, then calling this function may
163 : * end up closing another file...
164 : */
165 0 : void fd_connection::close()
166 : {
167 0 : if(f_fd != -1)
168 : {
169 0 : ::close(f_fd);
170 0 : f_fd = -1;
171 : }
172 0 : }
173 :
174 :
175 : /** \brief Used to mark the file descriptor as closed.
176 : *
177 : * This function marks the file descriptor as closed. Whether it is,
178 : * is your own concern. This is used to avoid a double close in
179 : * case some other function ends up calling close() and yet you
180 : * somehow closed the file descriptor (i.e. fclose(f) will do that
181 : * on you...)
182 : *
183 : * \code
184 : * ...
185 : * fclose(f);
186 : * // tell connection that we've close the connection fd
187 : * c->mark_closed();
188 : * ...
189 : * \endcode
190 : *
191 : * Note that if you do not have any other copy of the file descriptor
192 : * and you call mark_closed() instead of close(), you will leak that
193 : * file descriptor.
194 : */
195 0 : void fd_connection::mark_closed()
196 : {
197 0 : f_fd = -1;
198 0 : }
199 :
200 :
201 : /** \brief Check whether this connection is a reader.
202 : *
203 : * If you created this file descriptor connection as a reader, then this
204 : * function returns true.
205 : *
206 : * A reader has a mode of FD_MODE_READ or FD_MODE_RW.
207 : *
208 : * \return true if the connection is considered to be a reader.
209 : */
210 0 : bool fd_connection::is_reader() const
211 : {
212 0 : return f_mode != mode_t::FD_MODE_WRITE && get_socket() != -1;
213 : }
214 :
215 :
216 : /** \brief Check whether this connection is a writer.
217 : *
218 : * If you created this file descriptor connection as a writer, then this
219 : * function returns true.
220 : *
221 : * A writer has a mode of FD_MODE_WRITE or FD_MODE_RW.
222 : *
223 : * \return true if the connection is considered to be a writer.
224 : */
225 0 : bool fd_connection::is_writer() const
226 : {
227 0 : return f_mode != mode_t::FD_MODE_READ && get_socket() != -1;
228 : }
229 :
230 :
231 : /** \brief Return the file descriptor ("socket").
232 : *
233 : * This function returns the file descriptor specified in the constructor.
234 : *
235 : * The current naming convention comes from the fact that the library
236 : * was first created for sockets.
237 : *
238 : * \return The connection file descriptor.
239 : */
240 0 : int fd_connection::get_socket() const
241 : {
242 0 : return f_fd;
243 : }
244 :
245 :
246 : /** \brief Read up data from the file descriptor.
247 : *
248 : * This function attempts to read up to \p count bytes of data from
249 : * this file descriptor. If that works to some extend, then the
250 : * data read will be saved in \p buf and the function returns
251 : * the number of bytes read.
252 : *
253 : * If no data can be read, the function may return -1 or 0.
254 : *
255 : * The file descriptor must be a reader or the function will always fail.
256 : *
257 : * \param[in] buf The buffer where the data read is saved.
258 : * \param[in] count The maximum number of bytes to read at once.
259 : */
260 0 : ssize_t fd_connection::read(void * buf, size_t count)
261 : {
262 : // WARNING: We MUST call the fd_connection version of the is_writer(),
263 : // because the fd_buffer_connection::is_writer() also checks
264 : // the f_output buffer which has unwanted side effects
265 : //
266 0 : if(!fd_connection::is_reader())
267 : {
268 0 : errno = EBADF;
269 0 : return -1;
270 : }
271 :
272 0 : return ::read(f_fd, buf, count);
273 : }
274 :
275 :
276 : /** \brief Write buffer data to the file descriptor.
277 : *
278 : * This function writes \p count bytes of data from \p buf to
279 : * the file descriptor attached to this connection.
280 : *
281 : * If the file descriptor is closed, then an error occurs and
282 : * the function returns -1.
283 : *
284 : * \note
285 : * If you setup the file descriptor in non-blocking mode, then the
286 : * function will return early if it cannot cache or immediately
287 : * send the specified data.
288 : *
289 : * \param[in] buf A pointer to a buffer of data to write to the file.
290 : * \param[in] count The number of bytes to write to the file.
291 : *
292 : * \return The number of bytes written to the file.
293 : */
294 0 : ssize_t fd_connection::write(void const * buf, size_t count)
295 : {
296 : // WARNING: We MUST call the fd_connection version of the is_writer(),
297 : // because the fd_buffer_connection::is_writer() also checks
298 : // the f_output buffer which has unwanted side effects
299 : //
300 0 : if(!fd_connection::is_writer())
301 : {
302 0 : errno = EBADF;
303 0 : return -1;
304 : }
305 :
306 0 : return ::write(f_fd, buf, count);
307 : }
308 :
309 :
310 :
311 : } // namespace ed
312 : // vim: ts=4 sw=4 et
|