Line data Source code
1 : // Copyright (c) 2012-2022 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/eventdispatcher
4 : // contact@m2osw.com
5 : //
6 : // This program is free software; you can redistribute it and/or modify
7 : // it under the terms of the GNU General Public License as published by
8 : // the Free Software Foundation; either version 2 of the License, or
9 : // (at your option) any later version.
10 : //
11 : // This program is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 : //
16 : // You should have received a copy of the GNU General Public License along
17 : // with this program; if not, write to the Free Software Foundation, Inc.,
18 : // 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 :
20 : /** \file
21 : * \brief TCP server definition.
22 : *
23 : * Class used to handle events.
24 : */
25 :
26 : // to get the POLLRDHUP definition
27 : #ifndef _GNU_SOURCE
28 : #define _GNU_SOURCE
29 : #endif
30 :
31 :
32 : // self
33 : //
34 : #include "eventdispatcher/tcp_server.h"
35 :
36 : #include "eventdispatcher/exception.h"
37 :
38 :
39 : // snaplogger lib
40 : //
41 : #include <snaplogger/message.h>
42 :
43 :
44 : // snapdev lib
45 : //
46 : #include <snapdev/not_reached.h>
47 :
48 :
49 : // C++ lib
50 : //
51 : #include <cstring>
52 :
53 :
54 : // C lib
55 : //
56 : #include <poll.h>
57 :
58 :
59 : // last include
60 : //
61 : #include <snapdev/poison.h>
62 :
63 :
64 :
65 : namespace ed
66 : {
67 :
68 :
69 :
70 : /** \brief Initialize the server and start listening for connections.
71 : *
72 : * The server constructor creates a socket, binds it, and then listen to it.
73 : *
74 : * By default the server accepts a maximum of \p max_connections (set to
75 : * 0 or less to get the default tcp_server::MAX_CONNECTIONS) in its waiting queue.
76 : * If you use the server and expect a low connection rate, you may want to
77 : * reduce the count to 5. Although some very busy servers use larger numbers.
78 : * This value gets clamped to a minimum of 5 and a maximum of 1,000.
79 : *
80 : * Note that the maximum number of connections is actually limited to
81 : * /proc/sys/net/core/somaxconn connections. This number is generally 128
82 : * in 2016. So the super high limit of 1,000 is anyway going to be ignored
83 : * by the OS.
84 : *
85 : * The address is made non-reusable (which is the default for TCP sockets.)
86 : * It is possible to mark the server address as immediately reusable by
87 : * setting the \p reuse_addr to true.
88 : *
89 : * By default the server is marked as "keepalive". You can turn it off
90 : * using the keepalive() function with false.
91 : *
92 : * \exception tcp_client_server_parameter_error
93 : * This exception is raised if the address parameter is an empty string or
94 : * otherwise an invalid IP address, or if the port is out of range.
95 : *
96 : * \exception tcp_client_server_runtime_error
97 : * This exception is raised if the socket cannot be created, bound to
98 : * the specified IP address and port, or listen() fails on the socket.
99 : *
100 : * \param[in] address The address to listen on. It may be set to "0.0.0.0".
101 : * \param[in] max_connections The number of connections to keep in the listen queue.
102 : * \param[in] reuse_addr Whether to mark the socket with the SO_REUSEADDR flag.
103 : * \param[in] auto_close Automatically close the client socket in accept and the destructor.
104 : */
105 0 : tcp_server::tcp_server(
106 : addr::addr const & address
107 : , int max_connections
108 : , bool reuse_addr
109 0 : , bool auto_close)
110 0 : : f_max_connections(max_connections <= 0 ? MAX_CONNECTIONS : max_connections)
111 : , f_address(address)
112 0 : , f_auto_close(auto_close)
113 : {
114 0 : if(f_max_connections < 5)
115 : {
116 0 : f_max_connections = 5;
117 : }
118 0 : else if(f_max_connections > 1000)
119 : {
120 0 : f_max_connections = 1000;
121 : }
122 :
123 0 : f_socket = f_address.create_socket(
124 : (reuse_addr
125 : ? addr::addr::SOCKET_FLAG_REUSE
126 : : 0));
127 0 : if(f_socket < 0)
128 : {
129 0 : int const e(errno);
130 0 : SNAP_LOG_ERROR
131 : << "addr::create_socket() failed to create a socket descriptor (errno: "
132 0 : << std::to_string(e)
133 : << " -- "
134 0 : << strerror(e)
135 : << ")"
136 : << SNAP_LOG_SEND;
137 0 : throw runtime_error("could not create socket for client");
138 : }
139 :
140 0 : if(f_address.bind(f_socket) != 0)
141 : {
142 0 : close(f_socket);
143 0 : std::stringstream ss;
144 : ss << "could not bind the socket to \""
145 0 : << f_address.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_PORT)
146 0 : << "\"\n";
147 0 : SNAP_LOG_ERROR
148 : << ss
149 : << SNAP_LOG_SEND;
150 0 : throw runtime_error(ss.str());
151 : }
152 :
153 : // start listening, we expect the caller to then call accept() to
154 : // acquire connections
155 : //
156 0 : if(listen(f_socket, f_max_connections) < 0)
157 : {
158 0 : close(f_socket);
159 : throw runtime_error(
160 : "could not listen to the socket bound to \""
161 0 : + f_address.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_PORT)
162 0 : + "\"");
163 : }
164 0 : }
165 :
166 :
167 : /** \brief Clean up the server sockets.
168 : *
169 : * This function ensures that the server sockets get cleaned up.
170 : *
171 : * If the \p auto_close parameter was set to true in the constructor, then
172 : * the last accepter socket gets closed by this function.
173 : *
174 : * \note
175 : * DO NOT use the shutdown() call since we may end up forking and using
176 : * that connection in the child.
177 : */
178 0 : tcp_server::~tcp_server()
179 : {
180 0 : close(f_socket);
181 0 : if(f_auto_close && f_accepted_socket != -1)
182 : {
183 0 : close(f_accepted_socket);
184 : }
185 0 : }
186 :
187 :
188 : /** \brief Retrieve the socket descriptor.
189 : *
190 : * This function returns the socket descriptor. It can be used to
191 : * tweak things on the socket such as making it non-blocking or
192 : * directly accessing the data.
193 : *
194 : * \return The socket descriptor.
195 : */
196 0 : int tcp_server::get_socket() const
197 : {
198 0 : return f_socket;
199 : }
200 :
201 :
202 : /** \brief Retrieve the maximum number of connections.
203 : *
204 : * This function returns the maximum number of connections that can
205 : * be accepted by the socket. This was set by the constructor and
206 : * it cannot be changed later.
207 : *
208 : * \return The maximum number of incoming connections.
209 : */
210 0 : int tcp_server::get_max_connections() const
211 : {
212 0 : return f_max_connections;
213 : }
214 :
215 :
216 : /** \brief Retrieve the server IP address and port.
217 : *
218 : * This function returns the IP address used to bind the socket. This
219 : * is the address clients have to use to connect to the server unless
220 : * the address was set to all zeroes (0.0.0.0) in which case any user
221 : * can connect.
222 : *
223 : * The IP address cannot be changed.
224 : *
225 : * \return The server IP address.
226 : */
227 0 : addr::addr tcp_server::get_address() const
228 : {
229 0 : return f_address;
230 : }
231 :
232 :
233 : /** \brief Return the current status of the keepalive flag.
234 : *
235 : * This function returns the current status of the keepalive flag. This
236 : * flag is set to true by default (in the constructor.) It can be
237 : * changed with the set_keepalive() function.
238 : *
239 : * The flag is used to mark new connections with the SO_KEEPALIVE flag.
240 : * This is used whenever a service may take a little to long to answer
241 : * and avoid losing the TCP connection before the answer is sent to
242 : * the client.
243 : *
244 : * \return The current status of the keepalive flag.
245 : */
246 0 : bool tcp_server::get_keepalive() const
247 : {
248 0 : return f_keepalive;
249 : }
250 :
251 :
252 : /** \brief Set the keepalive flag.
253 : *
254 : * This function sets the keepalive flag to either true (i.e. mark connection
255 : * sockets with the SO_KEEPALIVE flag) or false. The default is true (as set
256 : * in the constructor,) because in most cases this is a feature people want.
257 : *
258 : * \param[in] yes Whether to keep new connections alive even when no traffic
259 : * goes through.
260 : */
261 0 : void tcp_server::set_keepalive(bool yes)
262 : {
263 0 : f_keepalive = yes;
264 0 : }
265 :
266 :
267 : /** \brief Return the current status of the close_on_exec flag.
268 : *
269 : * This function returns the current status of the close_on_exec flag. This
270 : * flag is set to false by default (in the constructor.) It can be
271 : * changed with the set_close_on_exec() function.
272 : *
273 : * The flag is used to atomically mark new connections with the FD_CLOEXEC
274 : * flag. This prevents child processes from inheriting the socket (i.e. if
275 : * you use the system() function, for example, that process would inherit
276 : * your socket).
277 : *
278 : * \return The current status of the close_on_exec flag.
279 : */
280 0 : bool tcp_server::get_close_on_exec() const
281 : {
282 0 : return f_close_on_exec;
283 : }
284 :
285 :
286 : /** \brief Set the close_on_exec flag.
287 : *
288 : * This function sets the close_on_exec flag to either true (i.e. mark connection
289 : * sockets with the FD_CLOEXEC flag) or false. The default is false (as set
290 : * in the constructor,) because in our legacy code, the flag is not expected
291 : * to be set.
292 : *
293 : * \param[in] yes Whether to close on exec() or not.
294 : */
295 0 : void tcp_server::set_close_on_exec(bool yes)
296 : {
297 0 : f_close_on_exec = yes;
298 0 : }
299 :
300 :
301 : /** \brief Accept a connection.
302 : *
303 : * A TCP server accepts incoming connections. This call is a blocking call.
304 : * If no connections are available on the line, then the call blocks until
305 : * a connection becomes available.
306 : *
307 : * To prevent being blocked by this call you can either check the status of
308 : * the file descriptor (use the get_socket() function to retrieve the
309 : * descriptor and use an appropriate wait with 0 as a timeout,) or transform
310 : * the socket in a non-blocking socket (not tested, though.)
311 : *
312 : * This TCP socket implementation is expected to be used in one of two ways:
313 : *
314 : * (1) the main server accepts connections and then fork()'s to handle the
315 : * transaction with the client, in that case we want to set the \p auto_close
316 : * parameter of the constructor to true so the accept() function automatically
317 : * closes the last accepted socket.
318 : *
319 : * (2) the main server keeps a set of connections and handles them alongside
320 : * the main server connection. Although there are limits to what you can do
321 : * in this way, it is very efficient, but this also means the accept() call
322 : * cannot close the last accepted socket since the rest of the software may
323 : * still be working on it.
324 : *
325 : * The function returns a client/server socket. This is the socket one can
326 : * use to communicate with the client that just connected to the server. This
327 : * descriptor can be written to or read from.
328 : *
329 : * This function is the one that applies the keepalive flag to the
330 : * newly accepted socket.
331 : *
332 : * \note
333 : * If you prevent SIGCHLD from stopping your code, you may want to allow it
334 : * when calling this function (that is, if you're interested in getting that
335 : * information immediately, otherwise it is cleaner to always block those
336 : * signals).
337 : * \note
338 : * For SIGCHLD, you may want to consider using the signal_child class which
339 : * takes care of the `waitpid()` and calls your callback at the time your
340 : * child process dies.
341 : *
342 : * \note
343 : * DO NOT use the shutdown() call since we may end up forking and using
344 : * that connection in the child.
345 : *
346 : * \note
347 : * If you want to have the FD_CLOEXEC flag set, make sure to call the
348 : * set_close_on_exec() function before you call the accept() function.
349 : *
350 : * \param[in] max_wait_ms The maximum number of milliseconds to wait for
351 : * a message. If set to -1 (the default), accept() will block
352 : * indefinitely.
353 : *
354 : * \return A client socket descriptor, -1 if an error occurred, or
355 : * -2 if it times out and max_wait is set.
356 : */
357 0 : int tcp_server::accept(int const max_wait_ms)
358 : {
359 : // auto-close?
360 0 : if(f_auto_close
361 0 : && f_accepted_socket != -1)
362 : {
363 : // if the close is interrupted, make sure we try again otherwise
364 : // we could lose that stream until next restart (this could happen
365 : // if you have SIGCHLD)
366 : //
367 0 : if(close(f_accepted_socket) == -1)
368 : {
369 0 : if(errno == EINTR)
370 : {
371 0 : close(f_accepted_socket);
372 : }
373 : }
374 : }
375 0 : f_accepted_socket = -1;
376 :
377 0 : if( max_wait_ms > -1 )
378 : {
379 0 : pollfd fd;
380 0 : fd.events = POLLIN | POLLPRI | POLLRDHUP;
381 0 : fd.fd = f_socket;
382 0 : int const retval(poll(&fd, 1, max_wait_ms));
383 :
384 : // on newer system each input of select() must be a distinct fd_set...
385 : // fd_set s;
386 : //
387 : // FD_ZERO(&s);
388 : //#pragma GCC diagnostic push
389 : //#pragma GCC diagnostic ignored "-Wold-style-cast"
390 : // FD_SET(f_socket, &s);
391 : //#pragma GCC diagnostic pop
392 : //
393 : // struct timeval timeout;
394 : // timeout.tv_sec = max_wait_ms / 1000;
395 : // timeout.tv_usec = (max_wait_ms % 1000) * 1000;
396 : // int const retval = select(f_socket + 1, &s, nullptr, &s, &timeout);
397 :
398 0 : if( retval == -1 )
399 : {
400 : // error
401 : //
402 0 : return -1;
403 : }
404 0 : else if( retval == 0 )
405 : {
406 : // timeout
407 : //
408 0 : return -2;
409 : }
410 : }
411 :
412 : // accept the next connection
413 : //
414 0 : struct sockaddr_in accepted_addr = {};
415 0 : socklen_t addr_len(sizeof(accepted_addr));
416 0 : f_accepted_socket = ::accept4(
417 : f_socket
418 : , reinterpret_cast<struct sockaddr *>(&accepted_addr)
419 : , &addr_len
420 0 : , f_close_on_exec ? SOCK_CLOEXEC : 0);
421 :
422 : // mark the new connection with the SO_KEEPALIVE flag
423 : //
424 0 : if(f_accepted_socket != -1 && f_keepalive)
425 : {
426 : // if this fails, we ignore the error, but still log the event
427 : //
428 0 : int optval(1);
429 0 : socklen_t const optlen(sizeof(optval));
430 0 : if(setsockopt(f_accepted_socket, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) != 0)
431 : {
432 0 : SNAP_LOG_WARNING
433 : << "tcp_server::accept(): an error occurred trying to mark"
434 : " accepted socket with SO_KEEPALIVE."
435 : << SNAP_LOG_SEND;
436 : }
437 : }
438 :
439 0 : return f_accepted_socket;
440 : }
441 :
442 :
443 : /** \brief Retrieve the last accepted socket descriptor.
444 : *
445 : * This function returns the last accepted socket descriptor as retrieved by
446 : * accept(). If accept() was never called or failed, then this returns -1.
447 : *
448 : * Note that it is possible that the socket was closed in between in which
449 : * case this value is going to be an invalid socket.
450 : *
451 : * \return The last accepted socket descriptor.
452 : */
453 0 : int tcp_server::get_last_accepted_socket() const
454 : {
455 0 : return f_accepted_socket;
456 : }
457 :
458 :
459 :
460 6 : } // namespace ed
461 : // vim: ts=4 sw=4 et
|