Line data Source code
1 : // Snap Communicator -- classes to ease handling communication between processes
2 : // Copyright (c) 2012-2019 Made to Order Software Corp. All Rights Reserved
3 : //
4 : // This program is free software; you can redistribute it and/or modify
5 : // it under the terms of the GNU General Public License as published by
6 : // the Free Software Foundation; either version 2 of the License, or
7 : // (at your option) any later version.
8 : //
9 : // This program is distributed in the hope that it will be useful,
10 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : // GNU General Public License for more details.
13 : //
14 : // You should have received a copy of the GNU General Public License
15 : // along with this program; if not, write to the Free Software
16 : // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 :
18 : // to get the POLLRDHUP definition
19 : #ifndef _GNU_SOURCE
20 : #define _GNU_SOURCE
21 : #endif
22 :
23 :
24 : // self
25 : //
26 : #include "snapwebsites/snap_communicator.h"
27 :
28 :
29 : // snapwebsites lib
30 : //
31 : #include "snapwebsites/log.h"
32 : #include "snapwebsites/qstring_stream.h"
33 : #include "snapwebsites/snap_communicator_dispatcher.h"
34 :
35 :
36 : // snapdev lib
37 : //
38 : #include <snapdev/not_reached.h>
39 : #include <snapdev/not_used.h>
40 : #include <snapdev/string_replace_many.h>
41 :
42 :
43 : // libaddr lib
44 : //
45 : #include <libaddr/addr_parser.h>
46 :
47 :
48 : // C++ lib
49 : //
50 : #include <sstream>
51 : #include <limits>
52 : #include <atomic>
53 :
54 :
55 : // C lib
56 : //
57 : #include <fcntl.h>
58 : #include <poll.h>
59 : #include <unistd.h>
60 : #include <sys/eventfd.h>
61 : #include <sys/inotify.h>
62 : #include <sys/ioctl.h>
63 : #include <sys/resource.h>
64 : #include <sys/syscall.h>
65 : #include <sys/time.h>
66 :
67 :
68 : // last include
69 : //
70 : #include <snapdev/poison.h>
71 :
72 :
73 :
74 : /** \file
75 : * \brief Implementation of the Snap Communicator class.
76 : *
77 : * This class wraps the C poll() interface in a C++ object with many types
78 : * of objects:
79 : *
80 : * \li Server Connections; for software that want to offer a port to
81 : * which clients can connect to; the server will call accept()
82 : * once a new client connection is ready; this results in a
83 : * Server/Client connection object
84 : * \li Client Connections; for software that want to connect to
85 : * a server; these expect the IP address and port to connect to
86 : * \li Server/Client Connections; for the server when it accepts a new
87 : * connection; in this case the server gets a socket from accept()
88 : * and creates one of these objects to handle the connection
89 : *
90 : * Using the poll() function is the easiest and allows us to listen
91 : * on pretty much any number of sockets (on my server it is limited
92 : * at 16,768 and frankly over 1,000 we probably will start to have
93 : * real slowness issues on small VPN servers.)
94 : */
95 :
96 : namespace snap
97 : {
98 : namespace
99 : {
100 :
101 :
102 : /** \brief The instance of the snap_communicator singleton.
103 : *
104 : * This pointer is the one instance of the snap_communicator
105 : * we create to run an event loop.
106 : */
107 2 : snap_communicator::pointer_t g_instance;
108 :
109 :
110 : /** \brief The array of signals handled by snap_signal objects.
111 : *
112 : * This map holds a list of signal handlers. You cannot register
113 : * the same signal more than once so this map is used to make
114 : * sure that each signal is unique.
115 : *
116 : * \todo
117 : * We may actually want to use a sigset_t object and just set
118 : * bits and remove
119 : *
120 : * \note
121 : * The pointer to the snap_signal object is a bare pointer
122 : * for in part because we cannot use a smart pointer in
123 : * a constructor where we add the signal to this map. Also
124 : * at this time that pointer does not get used so it could
125 : * as well have been a boolean.
126 : */
127 : sigset_t g_signal_handlers = sigset_t();
128 :
129 :
130 : /** \brief Retrieve the identifier of the current thread.
131 : *
132 : * This function returns the pid_t of the current thread.
133 : *
134 : * \return The current thread identifier.
135 : */
136 0 : pid_t gettid()
137 : {
138 0 : return syscall(SYS_gettid);
139 : }
140 :
141 :
142 : /** \brief Close a file descriptor object.
143 : *
144 : * This deleter is used to make sure that any file descriptor gets
145 : * closed as expected even if an exception occurs.
146 : *
147 : * \param[in] fd The file descriptor gets closed.
148 : */
149 0 : void fd_deleter(int * fd)
150 : {
151 0 : close(*fd);
152 0 : }
153 :
154 :
155 : } // no name namespace
156 :
157 :
158 :
159 :
160 : //////////////////////////////////
161 : // Snap Communicator Dispatcher //
162 : //////////////////////////////////
163 :
164 :
165 :
166 : /** \brief The dispatcher base destructor.
167 : *
168 : * This destructor is virtual allowing clean derivation at all levels.
169 : */
170 0 : dispatcher_base::~dispatcher_base()
171 : {
172 0 : }
173 :
174 :
175 :
176 : ///////////////////////////////
177 : // Snap Communicator Message //
178 : ///////////////////////////////
179 :
180 :
181 : /** \brief Parse a message from the specified paremeter.
182 : *
183 : * This function transformed the input string in a set of message
184 : * fields.
185 : *
186 : * The message format supported is:
187 : *
188 : * \code
189 : * ( '<' sent-from-server ':' sent-from-service ' ')? ( ( server ':' )? service '/' )? command ' ' ( parameter_name '=' value ';' )*
190 : * \endcode
191 : *
192 : * The sender "<sent-from-server:sent-from-service" names are added by
193 : * snapcommunicator when it receives a message which is destined for
194 : * another service (i.e. not itself). This can be used by the receiver
195 : * to reply back to the exact same process if it is a requirement for that
196 : * message (i.e. a process that sends a LOCK message, for example,
197 : * expects to receive the LOCKED message back as an answer.) Note that
198 : * it is assumed that there cannot be more than one service named
199 : * 'service' per server. This is enforced by the snapcommunicator
200 : * REGISTER function.
201 : *
202 : * \code
203 : * // to reply to the exact message sender, one can use the
204 : * // following two lines of code:
205 : * //
206 : * reply.set_server(message.get_sent_from_server());
207 : * reply.set_service(message.get_sent_from_service());
208 : *
209 : * // or use the reply_to() helper function
210 : * //
211 : * reply.reply_to(message);
212 : * \endcode
213 : *
214 : * The space after the command cannot be there unless parameters follow.
215 : * Parameters must be separated by semi-colons.
216 : *
217 : * The value of a parameter gets quoted when it includes a ';'. Within
218 : * the quotes, a Double Quote can be escaped inside by adding a backslash
219 : * in front of it (\"). Newline characters (as well as return carriage)
220 : * are also escaped using \n and \r respectively. Finally, we have to
221 : * escape backslashes themselves by doubling them, so \ becomes \\.
222 : *
223 : * Note that only parameter values support absolutely any character.
224 : * All the other parameters are limited to the latin alphabet, digits,
225 : * and underscores ([A-Za-z0-9_]+). Also all commands are limited
226 : * to uppercase letters only.
227 : *
228 : * \note
229 : * The input message is not saved as a cached version of the message
230 : * because we assume it may not be 100% optimized (canonicalized.)
231 : *
232 : * \param[in] message The string to convert into fields in this
233 : * message object.
234 : *
235 : * \return true if the message was succesfully parsed; false when an
236 : * error occurs and in that case no fields get modified.
237 : *
238 : * \sa to_message()
239 : * \sa get_sent_from_server()
240 : * \sa get_sent_from_service()
241 : * \sa reply_to()
242 : */
243 0 : bool snap_communicator_message::from_message(QString const & message)
244 : {
245 0 : QString sent_from_server;
246 0 : QString sent_from_service;
247 0 : QString server;
248 0 : QString service;
249 0 : QString command;
250 0 : parameters_t parameters;
251 :
252 : // someone using telnet to test sending messages will include a '\r'
253 : // so run a trim on the message in case it is there
254 : //
255 0 : QString const msg(message.trimmed());
256 0 : QChar const * m(msg.constData());
257 :
258 : // sent-from indicated?
259 0 : if(!m->isNull() && m->unicode() == '<')
260 : {
261 : // the name of the server and server sending this message
262 : //
263 : // First ++m to skip the '<'
264 0 : for(++m; !m->isNull() && m->unicode() != ':'; ++m)
265 : {
266 0 : if(m->unicode() == ' ')
267 : {
268 : // invalid syntax from input message
269 : //
270 0 : SNAP_LOG_ERROR("a message with sent_from_server must not include a space in the server name (")(message)(").");
271 0 : return false;
272 : }
273 :
274 0 : sent_from_server += m->unicode();
275 : }
276 0 : if(!m->isNull())
277 : {
278 : // First ++m to skip the ':'
279 0 : for(++m; !m->isNull() && m->unicode() != ' '; ++m)
280 : {
281 0 : sent_from_service += m->unicode();
282 : }
283 : }
284 0 : if(m->isNull())
285 : {
286 : // invalid syntax from input message
287 : //
288 0 : SNAP_LOG_ERROR("a message cannot only include a 'sent from service' definition.");
289 0 : return false;
290 : }
291 : // Skip the ' '
292 0 : ++m;
293 : }
294 :
295 0 : bool has_server(false);
296 0 : bool has_service(false);
297 0 : for(; !m->isNull() && m->unicode() != ' '; ++m)
298 : {
299 0 : if(m->unicode() == ':')
300 : {
301 0 : if(has_server
302 0 : || has_service
303 0 : || command.isEmpty())
304 : {
305 : // we cannot have more than one ':'
306 : // and the name cannot be empty if ':' is used
307 : // we also cannot have a ':' after the '/'
308 0 : SNAP_LOG_ERROR("a server name cannot be empty when specified, also it cannot include two server names and a server name after a service name was specified.");
309 0 : return false;
310 : }
311 0 : has_server = true;
312 0 : server = command;
313 0 : command.clear();
314 : }
315 0 : else if(m->unicode() == '/')
316 : {
317 0 : if(has_service
318 0 : || command.isEmpty())
319 : {
320 : // we cannot have more than one '/'
321 : // and the name cannot be empty if '/' is used
322 0 : SNAP_LOG_ERROR("a service name is mandatory when the message includes a slash (/), also it cannot include two service names.");
323 0 : return false;
324 : }
325 0 : has_service = true;
326 0 : service = command;
327 0 : command.clear();
328 : }
329 : else
330 : {
331 0 : command += *m;
332 : }
333 : }
334 :
335 0 : if(command.isEmpty())
336 : {
337 : // command is mandatory
338 0 : SNAP_LOG_ERROR("a command is mandatory in in a message.");
339 0 : return false;
340 : }
341 :
342 : // if we have a space, we expect one or more parameters
343 0 : if(m->unicode() == ' ')
344 : {
345 0 : for(++m; !m->isNull();)
346 : {
347 : // first we have to read the parameter name (up to the '=')
348 0 : QString param_name;
349 0 : for(; !m->isNull() && m->unicode() != '='; ++m)
350 : {
351 0 : param_name += *m;
352 : }
353 0 : if(param_name.isEmpty())
354 : {
355 : // parameters must have a name
356 0 : SNAP_LOG_ERROR("could not accept message because an empty parameter name is not valid.");
357 0 : return false;
358 : }
359 : try
360 : {
361 0 : verify_name(param_name);
362 : }
363 0 : catch(snap_communicator_invalid_message const & e)
364 : {
365 : // name is not empty, but it has invalid characters in it
366 0 : SNAP_LOG_ERROR("could not accept message because parameter name \"")(param_name)("\" is not considered valid: ")(e.what());
367 0 : return false;
368 : }
369 :
370 0 : if(m->isNull()
371 0 : || m->unicode() != '=')
372 : {
373 : // ?!?
374 0 : SNAP_LOG_ERROR("message parameters must be followed by an equal (=) character.");
375 0 : return false;
376 : }
377 0 : ++m;
378 :
379 : // retrieve the parameter name at first
380 0 : QString param_value;
381 0 : if(!m->isNull() && m->unicode() == '"')
382 : {
383 : // quoted parameter
384 0 : for(++m; !m->isNull() && m->unicode() != '"'; ++m)
385 : {
386 : // restored escaped double quotes
387 : // (note that we do not yet restore other backslashed
388 : // characters, that's done below)
389 0 : if(m->unicode() == '\\' && !m[1].isNull() && m[1].unicode() == '"')
390 : {
391 0 : ++m;
392 0 : param_value += *m;
393 : }
394 : else
395 : {
396 : // here the character may be ';'
397 0 : param_value += *m;
398 : }
399 : }
400 0 : if(m->isNull()
401 0 : || m->unicode() != '"')
402 : {
403 : // closing quote (") is missing
404 0 : SNAP_LOG_ERROR("a quoted message parameter must end with a quote (\").");
405 0 : return false;
406 : }
407 : // skip the quote
408 0 : ++m;
409 : }
410 : else
411 : {
412 : // parameter value is found as is
413 0 : for(; !m->isNull() && m->unicode() != ';'; ++m)
414 : {
415 0 : param_value += *m;
416 : }
417 : }
418 :
419 0 : if(!m->isNull())
420 : {
421 0 : if(m->unicode() != ';')
422 : {
423 : // this should never happend
424 0 : SNAP_LOG_ERROR("two parameters must be separated by a semicolon (;).");
425 0 : return false;
426 : }
427 : // skip the ';'
428 0 : ++m;
429 : }
430 :
431 : // also restore new lines and blackslashes if any
432 0 : std::string const str_value(param_value.toUtf8().data());
433 : std::string const unsafe_value(string_replace_many(
434 : str_value,
435 : {
436 : { "\\\\", "\\" },
437 : { "\\n", "\n" },
438 : { "\\r", "\r" }
439 0 : }));
440 : //param_value.replace("\\\\", "\\")
441 : // .replace("\\n", "\n")
442 : // .replace("\\r", "\r");
443 :
444 : // we got a valid parameter, add it
445 0 : parameters[param_name] = QString::fromUtf8(unsafe_value.c_str());
446 : }
447 : }
448 :
449 0 : f_sent_from_server = sent_from_server;
450 0 : f_sent_from_service = sent_from_service;
451 0 : f_server = server;
452 0 : f_service = service;
453 0 : f_command = command;
454 0 : f_parameters.swap(parameters);
455 0 : f_cached_message.clear();
456 :
457 0 : return true;
458 : }
459 :
460 :
461 : /** \brief Transform all the message parameters in a string.
462 : *
463 : * This function transforms all the message parameters in a string
464 : * and returns the result. The string is a message we can send over
465 : * TCP/IP (if you make sure to add a "\n", note that the
466 : * send_message() does that automatically) or over UDP/IP.
467 : *
468 : * \note
469 : * The function caches the result so calling the function many times
470 : * will return the same string and thus the function is very fast
471 : * after the first call (assuming you do not modify the message on
472 : * each call to to_message().)
473 : *
474 : * \note
475 : * The sent-from information gets saved in the message only if both,
476 : * the server name and service name it was sent from are defined.
477 : *
478 : * \exception snap_communicator_invalid_message
479 : * This function raises an exception if the message command was not
480 : * defined since a command is always mandatory.
481 : *
482 : * \return The converted message as a string.
483 : *
484 : * \sa get_sent_from_server()
485 : * \sa get_sent_from_service()
486 : * \sa set_reply_to_server()
487 : * \sa set_reply_to_service()
488 : */
489 0 : QString snap_communicator_message::to_message() const
490 : {
491 0 : if(f_cached_message.isEmpty())
492 : {
493 0 : if(f_command.isEmpty())
494 : {
495 0 : throw snap_communicator_invalid_message("snap_communicator_message::to_message(): cannot build a valid message without at least a command.");
496 : }
497 :
498 : // add info about the sender
499 : // ['<' <sent-from-server> '/' <sent-from-service> ' ']
500 : //
501 0 : if(!f_sent_from_server.isEmpty()
502 0 : || !f_sent_from_service.isEmpty())
503 : {
504 0 : f_cached_message += "<";
505 0 : f_cached_message += f_sent_from_server;
506 0 : f_cached_message += ":";
507 0 : f_cached_message += f_sent_from_service;
508 0 : f_cached_message += " ";
509 : }
510 :
511 : // add server and optionally the destination server name if both are defined
512 : // ['<' <sent-from-server> '/' <sent-from-service> ' '] [[<server> ':'] <name> '/']
513 : //
514 0 : if(!f_service.isEmpty())
515 : {
516 0 : if(!f_server.isEmpty())
517 : {
518 0 : f_cached_message += f_server;
519 0 : f_cached_message += ':';
520 : }
521 0 : f_cached_message += f_service;
522 0 : f_cached_message += "/";
523 : }
524 :
525 : // ['<' <sent-from-server> '/' <sent-from-service> ' '] [[<server> ':'] <name> '/'] <command>
526 0 : f_cached_message += f_command;
527 :
528 : // add parameters if any
529 : // ['<' <sent-from-server> '/' <sent-from-service> ' '] [[<server> ':'] <name> '/'] <command> [' ' <param1> '=' <value1>][';' <param2> '=' <value2>]...
530 : //
531 0 : bool first(true);
532 0 : for(auto p(f_parameters.begin());
533 0 : p != f_parameters.end();
534 0 : ++p, first = false)
535 : {
536 0 : f_cached_message += QString("%1%2=").arg(first ? " " : ";").arg(p.key());
537 0 : std::string const str_value(p.value().toUtf8().data());
538 : std::string const safe_value(string_replace_many(
539 : str_value,
540 : {
541 : { "\\", "\\\\" },
542 : { "\n", "\\n" },
543 : { "\r", "\\r" }
544 0 : }));
545 : //QString param(p.value());
546 : //param.replace("\\", "\\\\") // existing backslashes need to be escaped
547 : // .replace("\n", "\\n") // newline needs to be escaped
548 : // .replace("\r", "\\r"); // this one is not important, but for completeness
549 0 : QString param(QString::fromUtf8(safe_value.c_str()));
550 0 : if(param.indexOf(";") >= 0
551 0 : || (!param.isEmpty() && param[0] == '\"'))
552 : {
553 : // escape the double quotes
554 0 : param.replace("\"", "\\\"");
555 : // quote the resulting parameter and save in f_cached_message
556 0 : f_cached_message += QString("\"%1\"").arg(param);
557 : }
558 : else
559 : {
560 : // no special handling necessary
561 0 : f_cached_message += param;
562 : }
563 : }
564 : }
565 :
566 0 : return f_cached_message;
567 : }
568 :
569 :
570 : /** \brief Where this message came from.
571 : *
572 : * Some services send a message expecting an answer directly sent back
573 : * to them. Yet, those services may have multiple instances in your cluster
574 : * (i.e. snapcommunicator runs on all computers, snapwatchdog, snapfirewall,
575 : * snaplock, snapdbproxy are likely to run on most computers, etc.)
576 : * This parameter defines which computer the message came from. Thus,
577 : * you can use that information to send the message back to that
578 : * specific computer. The snapcommunicator on that computer will
579 : * then forward the message to the specified service instance.
580 : *
581 : * If empty (the default,) then the normal snapcommunicator behavior is
582 : * used (i.e. send to any instance of the service that is available.)
583 : *
584 : * \return The address and port of the specific service this message has to
585 : * be sent to.
586 : *
587 : * \sa set_sent_from_server()
588 : * \sa set_sent_from_service()
589 : * \sa get_sent_from_service()
590 : */
591 0 : QString const & snap_communicator_message::get_sent_from_server() const
592 : {
593 0 : return f_sent_from_server;
594 : }
595 :
596 :
597 : /** \brief Set the name of the server that sent this message.
598 : *
599 : * This function saves the name of the server that was used to
600 : * generate the message. This can be used later to send a reply
601 : * to the service that sent this message.
602 : *
603 : * The snapcommunicator tool is actually in charge of setting this
604 : * parameter and you should never have to do so from your tool.
605 : * The set happens whenever the snapcommunicator receives a
606 : * message from a client. If you are not using the snapcommunicator
607 : * then you are welcome to use this function for your own needs.
608 : *
609 : * \param[in] sent_from_server The name of the source server.
610 : *
611 : * \sa get_sent_from_server()
612 : * \sa get_sent_from_service()
613 : * \sa set_sent_from_service()
614 : */
615 0 : void snap_communicator_message::set_sent_from_server(QString const & sent_from_server)
616 : {
617 0 : if(f_sent_from_server != sent_from_server)
618 : {
619 : // this name can be empty and it supports lowercase
620 : //
621 0 : verify_name(sent_from_server, true);
622 :
623 0 : f_sent_from_server = sent_from_server;
624 0 : f_cached_message.clear();
625 : }
626 0 : }
627 :
628 :
629 : /** \brief Who sent this message.
630 : *
631 : * Some services send messages expecting an answer sent right back to
632 : * them. For example, the snaplock tool sends the message LOCKENTERING
633 : * and expects the LOCKENTERED as a reply. The reply has to be sent
634 : * to the exact same instance t hat sent the LOCKENTERING message.
635 : *
636 : * In order to do so, the system makes use of the server and service
637 : * name the data was sent from. Since the name of each service
638 : * registering with snapcommunicator must be unique, it 100% defines
639 : * the sender of the that message.
640 : *
641 : * If empty (the default,) then the normal snapcommunicator behavior is
642 : * used (i.e. send to any instance of the service that is available locally,
643 : * if not available locally, try to send it to another snapcommunicator
644 : * that knows about it.)
645 : *
646 : * \return The address and port of the specific service this message has to
647 : * be sent to.
648 : *
649 : * \sa get_sent_from_server()
650 : * \sa set_sent_from_server()
651 : * \sa set_sent_from_service()
652 : */
653 0 : QString const & snap_communicator_message::get_sent_from_service() const
654 : {
655 0 : return f_sent_from_service;
656 : }
657 :
658 :
659 : /** \brief Set the name of the server that sent this message.
660 : *
661 : * This function saves the name of the service that sent this message
662 : * to snapcommuncator. It is set by snapcommunicator whenever it receives
663 : * a message from a service it manages so you do not have to specify this
664 : * parameter yourselves.
665 : *
666 : * This can be used to provide the name of the service to reply to. This
667 : * is useful when the receiver does not already know exactly who sends it
668 : * certain messages.
669 : *
670 : * \param[in] sent_from_service The name of the service that sent this message.
671 : *
672 : * \sa get_sent_from_server()
673 : * \sa set_sent_from_server()
674 : * \sa get_sent_from_service()
675 : */
676 0 : void snap_communicator_message::set_sent_from_service(QString const & sent_from_service)
677 : {
678 0 : if(f_sent_from_service != sent_from_service)
679 : {
680 : // this name can be empty and it supports lowercase
681 : //
682 0 : verify_name(sent_from_service, true);
683 :
684 0 : f_sent_from_service = sent_from_service;
685 0 : f_cached_message.clear();
686 : }
687 0 : }
688 :
689 :
690 : /** \brief The server where this message has to be delivered.
691 : *
692 : * Some services need their messages to be delivered to a service
693 : * running on a specific computer. This function returns the name
694 : * of that server.
695 : *
696 : * If the function returns an empty string, then snapcommunicator is
697 : * free to send the message to any server.
698 : *
699 : * \return The name of the server to send this message to or an empty string.
700 : *
701 : * \sa set_server()
702 : * \sa get_service()
703 : * \sa set_service()
704 : */
705 0 : QString const & snap_communicator_message::get_server() const
706 : {
707 0 : return f_server;
708 : }
709 :
710 :
711 : /** \brief Set the name of a specific server where to send this message.
712 : *
713 : * In some cases you may want to send a message to a service running
714 : * on a specific server. This function can be used to specify the exact
715 : * server where the message has to be delivered.
716 : *
717 : * This is particularly useful when you need to send a reply to a
718 : * specific daemon that sent you a message.
719 : *
720 : * The name can be set to ".", which means send to a local service
721 : * only, whether it is available or not. This option can be used
722 : * to avoid/prevent sending a message to other computers.
723 : *
724 : * The name can be set to "*", which is useful to broadcast the message
725 : * to all servers even if the destination service name is
726 : * "snapcommunicator".
727 : *
728 : * \param[in] server The name of the server to send this message to.
729 : *
730 : * \sa get_server()
731 : * \sa get_service()
732 : * \sa set_service()
733 : */
734 0 : void snap_communicator_message::set_server(QString const & server)
735 : {
736 0 : if(f_server != server)
737 : {
738 : // this name can be empty and it supports lowercase
739 : //
740 0 : if(server != "."
741 0 : && server != "*")
742 : {
743 0 : verify_name(server, true);
744 : }
745 :
746 0 : f_server = server;
747 0 : f_cached_message.clear();
748 : }
749 0 : }
750 :
751 :
752 : /** \brief Retrieve the name of the service the message is for.
753 : *
754 : * This function returns the name of the service this message is being
755 : * sent to.
756 : *
757 : * \return Destination service.
758 : *
759 : * \sa get_server()
760 : * \sa set_server()
761 : * \sa set_service()
762 : */
763 0 : QString const & snap_communicator_message::get_service() const
764 : {
765 0 : return f_service;
766 : }
767 :
768 :
769 : /** \brief Set the name of the service this message is being sent to.
770 : *
771 : * This function specifies the name of the server this message is expected
772 : * to be sent to.
773 : *
774 : * When a service wants to send a message to snapcommunicator, no service
775 : * name is required.
776 : *
777 : * \param[in] service The name of the destination service.
778 : *
779 : * \sa get_server()
780 : * \sa set_server()
781 : * \sa get_service()
782 : */
783 0 : void snap_communicator_message::set_service(QString const & service)
784 : {
785 0 : if(f_service != service)
786 : {
787 : // broadcast is a special case that the verify_name() does not
788 : // support
789 : //
790 0 : if(service != "*"
791 0 : && service != "?"
792 0 : && service != ".")
793 : {
794 : // this name can be empty and it supports lowercase
795 : //
796 0 : verify_name(service, true);
797 : }
798 :
799 0 : f_service = service;
800 0 : f_cached_message.clear();
801 : }
802 0 : }
803 :
804 :
805 : /** \brief Copy sent information to this message.
806 : *
807 : * This function copies the sent information found in message
808 : * to this message server and service names.
809 : *
810 : * This is an equivalent to the following two lines of code:
811 : *
812 : * \code
813 : * reply.set_server(message.get_sent_from_server());
814 : * reply.set_service(message.get_sent_from_service());
815 : * \endcode
816 : *
817 : * \param[in] message The source message you want to reply to.
818 : */
819 0 : void snap_communicator_message::reply_to(snap_communicator_message const & message)
820 : {
821 0 : set_server(message.get_sent_from_server());
822 0 : set_service(message.get_sent_from_service());
823 0 : }
824 :
825 :
826 : /** \brief Get the command being sent.
827 : *
828 : * Each message is an equivalent to an RPC command being send between
829 : * services.
830 : *
831 : * The command is a string of text, generally one or more words
832 : * concatenated (no space allowed) such as STOP and LOCKENTERING.
833 : *
834 : * \note
835 : * The command string may still be empty if it was not yet assigned.
836 : *
837 : * \return The command of this message.
838 : */
839 0 : QString const & snap_communicator_message::get_command() const
840 : {
841 0 : return f_command;
842 : }
843 :
844 :
845 : /** \brief Set the message command.
846 : *
847 : * This function is used to define the RPC-like command of this message.
848 : *
849 : * The name of the command gets verified using the verify_name() function.
850 : * It cannot be empty and all letters have to be uppercase.
851 : *
852 : * \param[in] command The command to send to a connection.
853 : *
854 : * \sa verify_name()
855 : */
856 0 : void snap_communicator_message::set_command(QString const & command)
857 : {
858 : // this name cannot be empty and it does not support lowercase
859 : // characters either
860 : //
861 0 : verify_name(command, false, false);
862 :
863 0 : if(f_command != command)
864 : {
865 0 : f_command = command;
866 0 : f_cached_message.clear();
867 : }
868 0 : }
869 :
870 :
871 : /** \brief Add a string parameter to the message.
872 : *
873 : * Messages can include parameters (variables) such as a URI or a word.
874 : *
875 : * The value is not limited, although it probably should be limited to
876 : * standard text as these messages are sent as text.
877 : *
878 : * The name is verified by the verify_name() function.
879 : *
880 : * \param[in] name The name of the parameter.
881 : * \param[in] value The value of this parameter.
882 : *
883 : * \sa verify_name()
884 : */
885 0 : void snap_communicator_message::add_parameter(QString const & name, char const * value)
886 : {
887 0 : verify_name(name);
888 :
889 0 : f_parameters[name] = QString::fromUtf8(value);
890 0 : f_cached_message.clear();
891 0 : }
892 :
893 :
894 : /** \brief Add a string parameter to the message.
895 : *
896 : * Messages can include parameters (variables) such as a URI or a word.
897 : *
898 : * The value is not limited, although it probably should be limited to
899 : * standard text as these messages are sent as text.
900 : *
901 : * The name is verified by the verify_name() function.
902 : *
903 : * \param[in] name The name of the parameter.
904 : * \param[in] value The value of this parameter.
905 : *
906 : * \sa verify_name()
907 : */
908 0 : void snap_communicator_message::add_parameter(QString const & name, std::string const & value)
909 : {
910 0 : verify_name(name);
911 :
912 0 : f_parameters[name] = QString::fromUtf8(value.c_str());
913 0 : f_cached_message.clear();
914 0 : }
915 :
916 :
917 : /** \brief Add a string parameter to the message.
918 : *
919 : * Messages can include parameters (variables) such as a URI or a word.
920 : *
921 : * The value is not limited, although it probably should be limited to
922 : * standard text as these messages are sent as text.
923 : *
924 : * The name is verified by the verify_name() function.
925 : *
926 : * \param[in] name The name of the parameter.
927 : * \param[in] value The value of this parameter.
928 : *
929 : * \sa verify_name()
930 : */
931 0 : void snap_communicator_message::add_parameter(QString const & name, QString const & value)
932 : {
933 0 : verify_name(name);
934 :
935 0 : f_parameters[name] = value;
936 0 : f_cached_message.clear();
937 0 : }
938 :
939 :
940 : /** \brief Add an integer parameter to the message.
941 : *
942 : * Messages can include parameters (variables) such as a URI or a word.
943 : *
944 : * The value is not limited, although it probably should be limited to
945 : * standard text as these messages are sent as text.
946 : *
947 : * The name is verified by the verify_name() function.
948 : *
949 : * \param[in] name The name of the parameter.
950 : * \param[in] value The value of this parameter.
951 : *
952 : * \sa verify_name()
953 : */
954 0 : void snap_communicator_message::add_parameter(QString const & name, int32_t value)
955 : {
956 0 : verify_name(name);
957 :
958 0 : f_parameters[name] = QString("%1").arg(value);
959 0 : f_cached_message.clear();
960 0 : }
961 :
962 :
963 : /** \brief Add an integer parameter to the message.
964 : *
965 : * Messages can include parameters (variables) such as a URI or a word.
966 : *
967 : * The value is not limited, although it probably should be limited to
968 : * standard text as these messages are sent as text.
969 : *
970 : * The name is verified by the verify_name() function.
971 : *
972 : * \param[in] name The name of the parameter.
973 : * \param[in] value The value of this parameter.
974 : *
975 : * \sa verify_name()
976 : */
977 0 : void snap_communicator_message::add_parameter(QString const & name, uint32_t value)
978 : {
979 0 : verify_name(name);
980 :
981 0 : f_parameters[name] = QString("%1").arg(value);
982 0 : f_cached_message.clear();
983 0 : }
984 :
985 :
986 : /** \brief Add an integer parameter to the message.
987 : *
988 : * Messages can include parameters (variables) such as a URI or a word.
989 : *
990 : * The value is not limited, although it probably should be limited to
991 : * standard text as these messages are sent as text.
992 : *
993 : * The name is verified by the verify_name() function.
994 : *
995 : * \param[in] name The name of the parameter.
996 : * \param[in] value The value of this parameter.
997 : *
998 : * \sa verify_name()
999 : */
1000 0 : void snap_communicator_message::add_parameter(QString const & name, int64_t value)
1001 : {
1002 0 : verify_name(name);
1003 :
1004 0 : f_parameters[name] = QString("%1").arg(value);
1005 0 : f_cached_message.clear();
1006 0 : }
1007 :
1008 :
1009 : /** \brief Add an integer parameter to the message.
1010 : *
1011 : * Messages can include parameters (variables) such as a URI or a word.
1012 : *
1013 : * The value is not limited, although it probably should be limited to
1014 : * standard text as these messages are sent as text.
1015 : *
1016 : * The name is verified by the verify_name() function.
1017 : *
1018 : * \param[in] name The name of the parameter.
1019 : * \param[in] value The value of this parameter.
1020 : *
1021 : * \sa verify_name()
1022 : */
1023 0 : void snap_communicator_message::add_parameter(QString const & name, uint64_t value)
1024 : {
1025 0 : verify_name(name);
1026 :
1027 0 : f_parameters[name] = QString("%1").arg(value);
1028 0 : f_cached_message.clear();
1029 0 : }
1030 :
1031 :
1032 : /** \brief Check whether a parameter is defined in this message.
1033 : *
1034 : * This function checks whether a parameter is defined in a message. If
1035 : * so it returns true. This is important because the get_parameter()
1036 : * functions throw if the parameter is not available (i.e. which is
1037 : * what is used for mandatory parameters.)
1038 : *
1039 : * \param[in] name The name of the parameter.
1040 : *
1041 : * \return true if that parameter exists.
1042 : *
1043 : * \sa verify_name()
1044 : */
1045 0 : bool snap_communicator_message::has_parameter(QString const & name) const
1046 : {
1047 0 : verify_name(name);
1048 :
1049 0 : return f_parameters.contains(name);
1050 : }
1051 :
1052 :
1053 : /** \brief Retrieve a parameter as a string from this message.
1054 : *
1055 : * This function retrieves the named parameter from this message as a string,
1056 : * which is the default.
1057 : *
1058 : * The name must be valid as defined by the verify_name() function.
1059 : *
1060 : * \note
1061 : * This function returns a copy of the parameter so if you later change
1062 : * the value of that parameter, what has been returned does not change
1063 : * under your feet.
1064 : *
1065 : * \exception snap_communicator_invalid_message
1066 : * This exception is raised whenever the parameter is not defined or
1067 : * if the parameter \p name is not considered valid.
1068 : *
1069 : * \param[in] name The name of the parameter.
1070 : *
1071 : * \return A copy of the parameter value.
1072 : *
1073 : * \sa verify_name()
1074 : */
1075 0 : QString const snap_communicator_message::get_parameter(QString const & name) const
1076 : {
1077 0 : verify_name(name);
1078 :
1079 0 : if(f_parameters.contains(name))
1080 : {
1081 0 : return f_parameters[name];
1082 : }
1083 :
1084 0 : throw snap_communicator_invalid_message(QString("snap_communicator_message::get_parameter(): parameter \"%1\" of command \"%2\" not defined, try has_parameter() before calling a get_parameter() function.").arg(name).arg(f_command));
1085 : }
1086 :
1087 :
1088 : /** \brief Retrieve a parameter as an integer from this message.
1089 : *
1090 : * This function retrieves the named parameter from this message as a string,
1091 : * which is the default.
1092 : *
1093 : * The name must be valid as defined by the verify_name() function.
1094 : *
1095 : * \exception snap_communicator_invalid_message
1096 : * This exception is raised whenever the parameter is not a valid integer,
1097 : * it is not set, or the parameter name is not considered valid.
1098 : *
1099 : * \param[in] name The name of the parameter.
1100 : *
1101 : * \return The parameter converted to an integer.
1102 : *
1103 : * \sa verify_name()
1104 : */
1105 0 : int64_t snap_communicator_message::get_integer_parameter(QString const & name) const
1106 : {
1107 0 : verify_name(name);
1108 :
1109 0 : if(f_parameters.contains(name))
1110 : {
1111 : bool ok;
1112 0 : int64_t const r(f_parameters[name].toLongLong(&ok, 10));
1113 0 : if(!ok)
1114 : {
1115 0 : throw snap_communicator_invalid_message(QString("snap_communicator_message::get_integer_parameter(): command \"%1\" expected integer for \"%2\" but it could not be converted.").arg(f_command).arg(name));
1116 : }
1117 0 : return r;
1118 : }
1119 :
1120 0 : throw snap_communicator_invalid_message(QString("snap_communicator_message::get_integer_parameter(): parameter \"%1\" of command \"%2\" not defined, try has_parameter() before calling a get_integer_parameter() function.").arg(name).arg(f_command));
1121 : }
1122 :
1123 :
1124 : /** \brief Retrieve the list of parameters from this message.
1125 : *
1126 : * This function returns a constant reference to the list of parameters
1127 : * defined in this message.
1128 : *
1129 : * This can be useful if you allow for variable lists of parameters, but
1130 : * generally the get_parameter() and get_integer_parameter() are prefered.
1131 : *
1132 : * \warning
1133 : * This is a direct reference to the list of parameter. If you call the
1134 : * add_parameter() function, the new parameter will be visible in that
1135 : * new list and an iterator is likely not going to be valid on return
1136 : * from that call.
1137 : *
1138 : * \return A constant reference to the list of message parameters.
1139 : *
1140 : * \sa get_parameter()
1141 : * \sa get_integer_parameter()
1142 : */
1143 0 : snap_communicator_message::parameters_t const & snap_communicator_message::get_all_parameters() const
1144 : {
1145 0 : return f_parameters;
1146 : }
1147 :
1148 :
1149 : /** \brief Verify various names used with messages.
1150 : *
1151 : * The messages use names for:
1152 : *
1153 : * \li commands
1154 : * \li services
1155 : * \li parameters
1156 : *
1157 : * All those names must be valid as per this function. They are checked
1158 : * on read and on write (i.e. add_parameter() and get_paramter() both
1159 : * check the parameter name to make sure you did not mistype it.)
1160 : *
1161 : * A valid name must start with a letter or an underscore (although
1162 : * we suggest you do not start names with underscores; we want to
1163 : * have those reserved for low level system like messages,) and
1164 : * it can only include letters, digits, and underscores.
1165 : *
1166 : * The letters are limited to uppercase for commands. Also certain
1167 : * names may be empty (See concerned functions for details on that one.)
1168 : *
1169 : * \note
1170 : * The allowed letters are 'a' to 'z' and 'A' to 'Z' only. The allowed
1171 : * digits are '0' to '9' only. The underscore is '_' only.
1172 : *
1173 : * A few valid names:
1174 : *
1175 : * \li commands: PING, STOP, LOCK, LOCKED, QUITTING, UNKNOWN, LOCKEXITING
1176 : * \li services: snapcommunicator, snapserver, snaplock, MyOwnService
1177 : * \li parameters: URI, name, IP, TimeOut
1178 : *
1179 : * At this point all our services use lowercase, but this is not enforced.
1180 : * Actually, mixed case or uppercase service names are allowed.
1181 : *
1182 : * \exception snap_communicator_invalid_message
1183 : * This exception is raised if the name includes characters considered
1184 : * invalid.
1185 : *
1186 : * \param[in] name The name of the parameter.
1187 : * \param[in] can_be_empty Whether the name can be empty.
1188 : * \param[in] can_be_lowercase Whether the name can include lowercase letters.
1189 : */
1190 0 : void snap_communicator_message::verify_name(QString const & name, bool can_be_empty, bool can_be_lowercase)
1191 : {
1192 0 : if(!can_be_empty
1193 0 : && name.isEmpty())
1194 : {
1195 0 : SNAP_LOG_FATAL("snap_communicator: a message name cannot be empty.");
1196 0 : throw snap_communicator_invalid_message("snap_communicator: a message name cannot be empty.");
1197 : }
1198 :
1199 0 : for(auto const & c : name)
1200 : {
1201 0 : if((c < 'a' || c > 'z' || !can_be_lowercase)
1202 0 : && (c < 'A' || c > 'Z')
1203 0 : && (c < '0' || c > '9')
1204 0 : && c != '_')
1205 : {
1206 0 : SNAP_LOG_FATAL("snap_communicator: a message name must be composed of ASCII 'a'..'z', 'A'..'Z', '0'..'9', or '_' only (also a command must be uppercase only,) \"")(name)("\" is not valid.");
1207 0 : throw snap_communicator_invalid_message(QString("snap_communicator: a message name must be composed of ASCII 'a'..'z', 'A'..'Z', '0'..'9', or '_' only (also a command must be uppercase only,) \"%1\" is not valid.").arg(name));
1208 : }
1209 : }
1210 :
1211 0 : ushort const fc(name[0].unicode());
1212 0 : if(fc >= '0' && fc <= '9')
1213 : {
1214 0 : SNAP_LOG_FATAL("snap_communicator: parameter name cannot start with a digit, \"")(name)("\" is not valid.");
1215 0 : throw snap_communicator_invalid_message(QString("snap_communicator: parameter name cannot start with a digit, \"%1\" is not valid.").arg(name));
1216 : }
1217 0 : }
1218 :
1219 :
1220 :
1221 :
1222 :
1223 :
1224 :
1225 :
1226 : /////////////////////////////
1227 : // Snap Dispatcher Support //
1228 : /////////////////////////////
1229 :
1230 :
1231 :
1232 : /** \brief The destuctor.
1233 : *
1234 : * This cleans up the dispatcher support object.
1235 : */
1236 0 : snap_communicator::snap_dispatcher_support::~snap_dispatcher_support()
1237 : {
1238 0 : }
1239 :
1240 :
1241 : /** \brief Define a dispatcher to execute your functions.
1242 : *
1243 : * The dispatcher to use to dispatch messages when received. The dispatch
1244 : * happens by matching the command name with the dispatcher_match and
1245 : * calling the corresponding function.
1246 : *
1247 : * If no match is found, then nothing gets executed by the dispatcher and
1248 : * your default process_message() function gets called instead. If you
1249 : * use a "match all" type of entry in your dispatcher, then your
1250 : * process_message() function never gets called.
1251 : *
1252 : * \param[in] d The pointer to your dispatcher object.
1253 : */
1254 0 : void snap_communicator::snap_dispatcher_support::set_dispatcher(dispatcher_base::pointer_t d)
1255 : {
1256 0 : f_dispatcher = d;
1257 0 : }
1258 :
1259 :
1260 : /** \brief Get the dispatcher used to execute your message functions.
1261 : *
1262 : * This function returns the dispatcher one set with the set_dispatcher()
1263 : * function. It may be a nullptr.
1264 : *
1265 : * \warning
1266 : * Note that it may return nullptr because the weak pointer was just
1267 : * set to nullptr as the owner of the dispatcher was deleted.
1268 : *
1269 : * \return The pointer to the dispatcher used to execite messages or nullptr.
1270 : */
1271 0 : dispatcher_base::pointer_t snap_communicator::snap_dispatcher_support::get_dispatcher() const
1272 : {
1273 0 : return f_dispatcher.lock();
1274 : }
1275 :
1276 :
1277 : /** \brief Dispatcher the specified message.
1278 : *
1279 : * This dispatcher function searches for a function that matches the
1280 : * command of the specified \p message.
1281 : *
1282 : * The dispatcher handles a vector of dispatcher_match structures each
1283 : * of which defines a message that this daemon understands. The dispatch
1284 : * is done on a match as determined the the f_match() static function.
1285 : *
1286 : * The function executes the f_execute() function on a match. If none of
1287 : * the dispatcher_match entries match the input message, then the default
1288 : * process resumes, which is to call the process_message() function. This
1289 : * is done as a fallback and it should only be used if you want to be
1290 : * able to handle very complex cases as in the snapcommunicator. In most
1291 : * cases, having a function that handles your command(s) will be more
1292 : * than enough.
1293 : *
1294 : * If you called the add_snap_communicator_commands() function on your
1295 : * dispatcher, it won't be necessary to implement the process_message()
1296 : * since it adds a last entry which is a "catch all" entry. This entry
1297 : * uses the function that replies to the user with the UNKNOWN message.
1298 : * Assuming you do not do anything extraordinary, you just need to
1299 : * implement the ready() and stop() functions. If you have dynamic
1300 : * commands that the default msg_help() wont' understand, then you
1301 : * need to also implement the help() function.
1302 : *
1303 : * \param[in,out] message The message being dispatched.
1304 : *
1305 : * \return true if the dispatcher handled the message, false if the
1306 : * process_message() function was called instead.
1307 : */
1308 0 : bool snap_communicator::snap_dispatcher_support::dispatch_message(snap::snap_communicator_message & message)
1309 : {
1310 0 : auto d(f_dispatcher.lock());
1311 0 : if(d != nullptr)
1312 : {
1313 : // we have a dispatcher installed, try to dispatch that message
1314 : //
1315 0 : if(d->dispatch(message))
1316 : {
1317 0 : return true;
1318 : }
1319 : }
1320 :
1321 : // either there was no dispatcher installed or the message is
1322 : // not in the list of messages handled by this dispatcher
1323 : //
1324 0 : process_message(message);
1325 :
1326 0 : return false;
1327 : }
1328 :
1329 :
1330 : /** \brief A default implementation of the process_message() function.
1331 : *
1332 : * This function is adefault fallback for the process_message()
1333 : * functionality. If you define a dispatcher, then you probably
1334 : * won't need to define a process_message() which in most cases
1335 : * would do the exact same thing but it would be called.
1336 : *
1337 : * This is especially true if you finish your list of matches
1338 : * with the always_match() function and msg_reply_with_unknown()
1339 : * as the function to run when that entry is hit.
1340 : *
1341 : * \code
1342 : * {
1343 : * nullptr
1344 : * , &dispatcher<my_connection>::dispatcher_match::msg_reply_with_unknown
1345 : * , &dispatcher<my_connection>::dispatcher_match::always_match
1346 : * },
1347 : * \endcode
1348 : *
1349 : * \todo
1350 : * Look into fixing this function so it can send the UNKNOWN message itself.
1351 : * That way we'd avoid the last entry in the match array, which would allow
1352 : * us to have binary search (much faster).
1353 : *
1354 : * \param[in] message The message to be processed.
1355 : */
1356 0 : void snap_communicator::snap_dispatcher_support::process_message(snap_communicator_message const & message)
1357 : {
1358 : // We don't currently have access to the send_message() function from
1359 : // here--the snap_inter_thread_message_connection class causes a problem
1360 : // because it has two process_message() functions: process_message_a()
1361 : // and process_message_b().
1362 : //
1363 : //snap::snap_communicator_message unknown;
1364 : //unknown.reply_to(message);
1365 : //unknown.set_command("UNKNOWN");
1366 : //unknown.add_parameter("command", message.get_command());
1367 : //if(!send_message(unknown, false))
1368 : //{
1369 : // SNAP_LOG_WARNING("could not reply with UNKNOWN message to \"")(message.get_command())("\"");
1370 : //}
1371 :
1372 0 : SNAP_LOG_FATAL("process_message() with message \"")
1373 0 : (message.to_message())
1374 0 : ("\" was not reimplemented in your class and the always_match() was not used in your dispatcher matches");
1375 :
1376 : throw snap_communicator_implementation_error("your class is not reimplementing the process_message() virtual function and your dispatcher did not catch mnessage \""
1377 0 : + message.to_message()
1378 0 : + "\".");
1379 : }
1380 :
1381 :
1382 :
1383 :
1384 :
1385 :
1386 :
1387 :
1388 : /////////////////////
1389 : // Snap Connection //
1390 : /////////////////////
1391 :
1392 :
1393 : /** \brief Initializes the connection.
1394 : *
1395 : * This function initializes a base connection object.
1396 : */
1397 0 : snap_communicator::snap_connection::snap_connection()
1398 : //: f_name("")
1399 : //, f_priority(0)
1400 : //, f_timeout(-1)
1401 : {
1402 0 : }
1403 :
1404 :
1405 : /** \brief Proceed with the cleanup of the snap_connection.
1406 : *
1407 : * This function cleans up a snap_connection object.
1408 : */
1409 0 : snap_communicator::snap_connection::~snap_connection()
1410 : {
1411 0 : }
1412 :
1413 :
1414 : /** \brief Remove this connection from the communicator it was added in.
1415 : *
1416 : * This function removes the connection from the communicator that
1417 : * it was created in.
1418 : *
1419 : * This happens in several circumstances:
1420 : *
1421 : * \li When the connection is not necessary anymore
1422 : * \li When the connection receives a message saying it should close
1423 : * \li When the connection receives a Hang Up event
1424 : * \li When the connection looks erroneous
1425 : * \li When the connection looks invalid
1426 : *
1427 : * If the connection is not currently connected to a snap_communicator
1428 : * object, then nothing happens.
1429 : */
1430 0 : void snap_communicator::snap_connection::remove_from_communicator()
1431 : {
1432 0 : snap_communicator::instance()->remove_connection(shared_from_this());
1433 0 : }
1434 :
1435 :
1436 : /** \brief Retrieve the name of the connection.
1437 : *
1438 : * When generating an error or a log the library makes use of this name
1439 : * so we actually know which type of socket generated a problem.
1440 : *
1441 : * \return A constant reference to the connection name.
1442 : */
1443 0 : QString const & snap_communicator::snap_connection::get_name() const
1444 : {
1445 0 : return f_name;
1446 : }
1447 :
1448 :
1449 : /** \brief Change the name of the connection.
1450 : *
1451 : * A connection can be given a name. This is mainly for debug purposes.
1452 : * We will be adding this name in errors and exceptions as they occur.
1453 : *
1454 : * The connection makes a copy of \p name.
1455 : *
1456 : * \param[in] name The name to give this connection.
1457 : */
1458 0 : void snap_communicator::snap_connection::set_name(QString const & name)
1459 : {
1460 0 : f_name = name;
1461 0 : }
1462 :
1463 :
1464 : /** \brief Tell us whether this socket is a listener or not.
1465 : *
1466 : * By default a snap_connection object does not represent a listener
1467 : * object.
1468 : *
1469 : * \return The base implementation returns false. Override this
1470 : * virtual function if your snap_connection is a listener.
1471 : */
1472 0 : bool snap_communicator::snap_connection::is_listener() const
1473 : {
1474 0 : return false;
1475 : }
1476 :
1477 :
1478 : /** \brief Tell us whether this connection is listening on a Unix signal.
1479 : *
1480 : * By default a snap_connection object does not represent a Unix signal.
1481 : * See the snap_signal implementation for further information about
1482 : * Unix signal handling in this library.
1483 : *
1484 : * \return The base implementation returns false.
1485 : */
1486 0 : bool snap_communicator::snap_connection::is_signal() const
1487 : {
1488 0 : return false;
1489 : }
1490 :
1491 :
1492 : /** \brief Tell us whether this socket is used to receive data.
1493 : *
1494 : * If you expect to receive data on this connection, then mark it
1495 : * as a reader by returning true in an overridden version of this
1496 : * function.
1497 : *
1498 : * \return By default this function returns false (nothing to read).
1499 : */
1500 0 : bool snap_communicator::snap_connection::is_reader() const
1501 : {
1502 0 : return false;
1503 : }
1504 :
1505 :
1506 : /** \brief Tell us whether this socket is used to send data.
1507 : *
1508 : * If you expect to send data on this connection, then mark it
1509 : * as a writer by returning true in an overridden version of
1510 : * this function.
1511 : *
1512 : * \return By default this function returns false (nothing to write).
1513 : */
1514 0 : bool snap_communicator::snap_connection::is_writer() const
1515 : {
1516 0 : return false;
1517 : }
1518 :
1519 :
1520 : /** \brief Check whether the socket is valid for this connection.
1521 : *
1522 : * Some connections do not make use of a socket so just checking
1523 : * whether the socket is -1 is not a good way to know whether the
1524 : * socket is valid.
1525 : *
1526 : * The default function assumes that a socket has to be 0 or more
1527 : * to be valid. Other connection implementations may overload this
1528 : * function to allow other values.
1529 : *
1530 : * \return true if the socket is valid.
1531 : */
1532 0 : bool snap_communicator::snap_connection::valid_socket() const
1533 : {
1534 0 : return get_socket() >= 0;
1535 : }
1536 :
1537 :
1538 : /** \brief Check whether this connection is enabled.
1539 : *
1540 : * It is possible to turn a connection ON or OFF using the set_enable()
1541 : * function. This function returns the current value. If true, which
1542 : * is the default, the connection is considered enabled and will get
1543 : * its callbacks called.
1544 : *
1545 : * \return true if the connection is currently enabled.
1546 : */
1547 0 : bool snap_communicator::snap_connection::is_enabled() const
1548 : {
1549 0 : return f_enabled;
1550 : }
1551 :
1552 :
1553 : /** \brief Change the status of a connection.
1554 : *
1555 : * This function let you change the status of a connection from
1556 : * enabled (true) to disabled (false) and vice versa.
1557 : *
1558 : * A disabled connection is not listened on at all. This is similar
1559 : * to returning false in all three functions is_listener(),
1560 : * is_reader(), and is_writer().
1561 : *
1562 : * \param[in] enabled The new status of the connection.
1563 : */
1564 0 : void snap_communicator::snap_connection::set_enable(bool enabled)
1565 : {
1566 0 : f_enabled = enabled;
1567 0 : }
1568 :
1569 :
1570 : /** \brief Define the priority of this connection object.
1571 : *
1572 : * By default snap_connection objets have a priority of 100.
1573 : *
1574 : * You may also use the set_priority() to change the priority of a
1575 : * connection at any time.
1576 : *
1577 : * \return The current priority of this connection.
1578 : *
1579 : * \sa set_priority()
1580 : */
1581 0 : int snap_communicator::snap_connection::get_priority() const
1582 : {
1583 0 : return f_priority;
1584 : }
1585 :
1586 :
1587 : /** \brief Change this event priority.
1588 : *
1589 : * This function can be used to change the default priority (which is
1590 : * 100) to a larger or smaller number. A larger number makes the connection
1591 : * less important and callbacks get called later. A smaller number makes
1592 : * the connection more important and callbacks get called sooner.
1593 : *
1594 : * Note that the priority of a connection can modified at any time.
1595 : * It is not guaranteed to be taken in account immediately, though.
1596 : *
1597 : * \exception snap_communicator_parameter_error
1598 : * The priority of the event is out of range when this exception is raised.
1599 : * The value must between between 0 and EVENT_MAX_PRIORITY. Any
1600 : * other value raises this exception.
1601 : *
1602 : * \param[in] priority Priority of the event.
1603 : */
1604 0 : void snap_communicator::snap_connection::set_priority(priority_t priority)
1605 : {
1606 0 : if(priority < 0 || priority > EVENT_MAX_PRIORITY)
1607 : {
1608 0 : std::stringstream ss;
1609 0 : ss << "snap_communicator::set_priority(): priority out of range, this instance of snap_communicator accepts priorities between 0 and "
1610 : << EVENT_MAX_PRIORITY
1611 0 : << ".";
1612 0 : throw snap_communicator_parameter_error(ss.str());
1613 : }
1614 :
1615 0 : f_priority = priority;
1616 :
1617 : // make sure that the new order is calculated when we execute
1618 : // the next loop
1619 : //
1620 0 : snap_communicator::instance()->f_force_sort = true;
1621 0 : }
1622 :
1623 :
1624 : /** \brief Less than operator to sort connections by priority.
1625 : *
1626 : * This function is used to know whether a connection has a higher or lower
1627 : * priority. This is used when one adds, removes, or changes the priority
1628 : * of a connection. The sorting itself happens in the
1629 : * snap_communicator::run() which knows that something changed whenever
1630 : * it checks the data.
1631 : *
1632 : * The result of the priority mechanism is that callbacks of items with
1633 : * a smaller priorirty will be called first.
1634 : *
1635 : * \param[in] lhs The left hand side snap_connection.
1636 : * \param[in] rhs The right hand side snap_connection.
1637 : *
1638 : * \return true if lhs has a smaller priority than rhs.
1639 : */
1640 0 : bool snap_communicator::snap_connection::compare(pointer_t const & lhs, pointer_t const & rhs)
1641 : {
1642 0 : return lhs->get_priority() < rhs->get_priority();
1643 : }
1644 :
1645 :
1646 : /** \brief Get the number of events a connection will process in a row.
1647 : *
1648 : * Depending on the connection, their events may get processed within
1649 : * a loop. If a new event is received before the current event being
1650 : * processed is done, then the system generally processes that new event
1651 : * before exiting the loop.
1652 : *
1653 : * This count limit specifies that a certain amount of events can be
1654 : * processed in a row. After that many events were processed, the loop
1655 : * exits.
1656 : *
1657 : * Some loops may not allow for us to immediately quit that function. In
1658 : * that case we go on until a breaking point is allowed.
1659 : *
1660 : * \return The total amount of microsecond allowed before a connection
1661 : * processing returns even if additional events are already available
1662 : * in connection.
1663 : *
1664 : * \sa snap_communicator::snap_connection::set_event_limit()
1665 : */
1666 0 : uint16_t snap_communicator::snap_connection::get_event_limit() const
1667 : {
1668 0 : return f_event_limit;
1669 : }
1670 :
1671 :
1672 : /** \brief Set the number of events a connection will process in a row.
1673 : *
1674 : * Depending on the connection, their events may get processed within
1675 : * a loop. If a new event is received before the current event being
1676 : * processed is done, then the system generally processes that new event
1677 : * before exiting the loop.
1678 : *
1679 : * This count limit specifies that a certain amount of events can be
1680 : * processed in a row. After that many events were processed, the loop
1681 : * exits.
1682 : *
1683 : * Some loops may not allow for us to immediately quit that function. In
1684 : * that case we go on until a breaking point is allowed.
1685 : *
1686 : * \param[in] event_limit Number of events to process in a row.
1687 : *
1688 : * \sa snap_communicator::snap_connection::get_event_limit()
1689 : */
1690 0 : void snap_communicator::snap_connection::set_event_limit(uint16_t event_limit)
1691 : {
1692 0 : f_event_limit = event_limit;
1693 0 : }
1694 :
1695 :
1696 : /** \brief Get the processing time limit while processing a connection events.
1697 : *
1698 : * Depending on the connection, their events may get processed within
1699 : * a loop. If a new event is received before the current event being
1700 : * processed is done, then the system generally processes that new event
1701 : * before exiting the loop.
1702 : *
1703 : * This count limit specifies that a certain amount of events can be
1704 : * processed in a row. After that many events were processed, the loop
1705 : * exits.
1706 : *
1707 : * Some loops may not allow for us to immediately quit that function. In
1708 : * that case we go on until a breaking point is allowed.
1709 : *
1710 : * \return The total amount of microsecond allowed before a connection
1711 : * processing returns even if additional events are already available
1712 : * in connection.
1713 : *
1714 : * \sa snap_communicator::snap_connection::set_processing_time_limit()
1715 : */
1716 0 : uint16_t snap_communicator::snap_connection::get_processing_time_limit() const
1717 : {
1718 0 : return f_processing_time_limit;
1719 : }
1720 :
1721 :
1722 : /** \brief Set the processing time limit while processing a connection events.
1723 : *
1724 : * Depending on the connection, their events may get processed within
1725 : * a loop. If a new event is received before the current event being
1726 : * processed is done, then the system generally processes that new event
1727 : * before exiting the loop.
1728 : *
1729 : * This time limit gives a certain amount of time for a set of events
1730 : * to get processed. The default is 0.5 seconds. Note that the system
1731 : * won't stop the current event after 0.5 seconds, however, if it
1732 : * takes that long or more, then it will not try to process another
1733 : * event within that loop before it checks all the connections that
1734 : * exist in your process.
1735 : *
1736 : * Some loops may not allow for us to immediately quit that function. In
1737 : * that case we go on until a breaking point is allowed.
1738 : *
1739 : * \param[in] processing_time_limit The total amount of microsecond
1740 : * allowed before a connection processing returns even if
1741 : * additional events are already available in connection.
1742 : *
1743 : * \sa snap_communicator::snap_connection::get_processing_time_limit()
1744 : */
1745 0 : void snap_communicator::snap_connection::set_processing_time_limit(int32_t processing_time_limit)
1746 : {
1747 : // in mircoseconds.
1748 0 : f_processing_time_limit = processing_time_limit;
1749 0 : }
1750 :
1751 :
1752 : /** \brief Return the delay between ticks when this connection times out.
1753 : *
1754 : * All connections can include a timeout delay in microseconds which is
1755 : * used to know when the wait on that specific connection times out.
1756 : *
1757 : * By default connections do not time out. This function returns -1
1758 : * to indicate that this connection does not ever time out. To
1759 : * change the timeout delay use the set_timeout_delay() function.
1760 : *
1761 : * \return This function returns the current timeout delay.
1762 : */
1763 0 : int64_t snap_communicator::snap_connection::get_timeout_delay() const
1764 : {
1765 0 : return f_timeout_delay;
1766 : }
1767 :
1768 :
1769 : /** \brief Change the timeout of this connection.
1770 : *
1771 : * Each connection can be setup with a timeout in microseconds.
1772 : * When that delay is past, the callback function of the connection
1773 : * is called with the EVENT_TIMEOUT flag set (note that the callback
1774 : * may happen along other events.)
1775 : *
1776 : * The current date when this function gets called is the starting
1777 : * point for each following trigger. Because many other callbacks
1778 : * get called, it is not very likely that you will be called
1779 : * exactly on time, but the ticks are guaranteed to be requested
1780 : * on a non moving schedule defined as:
1781 : *
1782 : * \f[
1783 : * \large tick_i = start-time + k \times delay
1784 : * \f]
1785 : *
1786 : * In other words the time and date when ticks happen does not slip
1787 : * with time. However, this implementation may skip one or more
1788 : * ticks at any time (especially if the delay is very small).
1789 : *
1790 : * When a tick triggers an EVENT_TIMEOUT, the snap_communicator::run()
1791 : * function calls calculate_next_tick() to calculate the time when
1792 : * the next tick will occur which will always be in the function.
1793 : *
1794 : * \exception snap_communicator_parameter_error
1795 : * This exception is raised if the timeout_us parameter is not considered
1796 : * valid. The minimum value is 10 and microseconds. You may use -1 to turn
1797 : * off the timeout delay feature.
1798 : *
1799 : * \param[in] timeout_us The new time out in microseconds.
1800 : */
1801 0 : void snap_communicator::snap_connection::set_timeout_delay(int64_t timeout_us)
1802 : {
1803 0 : if(timeout_us != -1
1804 0 : && timeout_us < 10)
1805 : {
1806 0 : throw snap_communicator_parameter_error("snap_communicator::snap_connection::set_timeout_delay(): timeout_us parameter cannot be less than 10 unless it is exactly -1.");
1807 : }
1808 :
1809 0 : f_timeout_delay = timeout_us;
1810 :
1811 : // immediately calculate the next timeout date
1812 0 : f_timeout_next_date = get_current_date() + f_timeout_delay;
1813 0 : }
1814 :
1815 :
1816 : /** \brief Calculate when the next tick shall occur.
1817 : *
1818 : * This function calculates the date and time when the next tick
1819 : * has to be triggered. This function is called after the
1820 : * last time the EVENT_TIMEOUT callback was called.
1821 : */
1822 0 : void snap_communicator::snap_connection::calculate_next_tick()
1823 : {
1824 0 : if(f_timeout_delay == -1)
1825 : {
1826 : // no delay based timeout so forget about it
1827 0 : return;
1828 : }
1829 :
1830 : // what is now?
1831 0 : int64_t const now(get_current_date());
1832 :
1833 : // gap between now and the last time we triggered this timeout
1834 0 : int64_t const gap(now - f_timeout_next_date);
1835 0 : if(gap < 0)
1836 : {
1837 : // somehow we got called even though now is still larger
1838 : // than f_timeout_next_date
1839 : //
1840 : // This message happens all the time, it is not helpful at the moment
1841 : // so commenting out.
1842 : //SNAP_LOG_DEBUG("snap_communicator::snap_connection::calculate_next_tick() called even though the next date is still larger than 'now'.");
1843 0 : return;
1844 : }
1845 :
1846 : // number of ticks in that gap, rounded up
1847 0 : int64_t const ticks((gap + f_timeout_delay - 1) / f_timeout_delay);
1848 :
1849 : // the next date may be equal to now, however, since it is very
1850 : // unlikely that the tick has happened right on time, and took
1851 : // less than 1ms, this is rather unlikely all around...
1852 : //
1853 0 : f_timeout_next_date += ticks * f_timeout_delay;
1854 : }
1855 :
1856 :
1857 : /** \brief Return when this connection times out.
1858 : *
1859 : * All connections can include a timeout in microseconds which is
1860 : * used to know when the wait on that specific connection times out.
1861 : *
1862 : * By default connections do not time out. This function returns -1
1863 : * to indicate that this connection does not ever time out. You
1864 : * may overload this function to return a different value so your
1865 : * version can time out.
1866 : *
1867 : * \return This function returns the timeout date in microseconds.
1868 : */
1869 0 : int64_t snap_communicator::snap_connection::get_timeout_date() const
1870 : {
1871 0 : return f_timeout_date;
1872 : }
1873 :
1874 :
1875 : /** \brief Change the date at which you want a timeout event.
1876 : *
1877 : * This function can be used to setup one specific date and time
1878 : * at which this connection should timeout. This specific date
1879 : * is used internally to calculate the amount of time the poll()
1880 : * will have to wait, not including the time it will take
1881 : * to execute other callbacks if any needs to be run (i.e. the
1882 : * timeout is executed last, after all other events, and also
1883 : * priority is used to know which other connections are parsed
1884 : * first.)
1885 : *
1886 : * \exception snap_communicator_parameter_error
1887 : * If the date_us is too small (less than -1) then this exception
1888 : * is raised.
1889 : *
1890 : * \param[in] date_us The new time out in micro seconds.
1891 : */
1892 0 : void snap_communicator::snap_connection::set_timeout_date(int64_t date_us)
1893 : {
1894 0 : if(date_us < -1)
1895 : {
1896 0 : throw snap_communicator_parameter_error("snap_communicator::snap_connection::set_timeout_date(): date_us parameter cannot be less than -1.");
1897 : }
1898 :
1899 0 : f_timeout_date = date_us;
1900 0 : }
1901 :
1902 :
1903 : /** \brief Return when this connection expects a timeout.
1904 : *
1905 : * All connections can include a timeout specification which is
1906 : * either a specific day and time set with set_timeout_date()
1907 : * or an repetitive timeout which is defined with the
1908 : * set_timeout_delay().
1909 : *
1910 : * If neither timeout is set the function returns -1. Otherwise
1911 : * the function will calculate when the connection is to time
1912 : * out and return that date.
1913 : *
1914 : * If the date is already in the past then the callback
1915 : * is called immediately with the EVENT_TIMEOUT flag set.
1916 : *
1917 : * \note
1918 : * If the timeout date is triggered, then the loop calls
1919 : * set_timeout_date(-1) because the date timeout is expected
1920 : * to only be triggered once. This resetting is done before
1921 : * calling the user callback which can in turn set a new
1922 : * value back in the connection object.
1923 : *
1924 : * \return This function returns -1 when no timers are set
1925 : * or a timestamp in microseconds when the timer is
1926 : * expected to trigger.
1927 : */
1928 0 : int64_t snap_communicator::snap_connection::get_timeout_timestamp() const
1929 : {
1930 0 : if(f_timeout_date != -1)
1931 : {
1932 : // this one is easy, it is already defined as expected
1933 : //
1934 0 : return f_timeout_date;
1935 : }
1936 :
1937 0 : if(f_timeout_delay != -1)
1938 : {
1939 : // this one makes use of the calculated next date
1940 : //
1941 0 : return f_timeout_next_date;
1942 : }
1943 :
1944 : // no timeout defined
1945 : //
1946 0 : return -1;
1947 : }
1948 :
1949 :
1950 : /** \brief Save the timeout stamp just before calling poll().
1951 : *
1952 : * This function is called by the run() function before the poll()
1953 : * gets called. It makes sure to save the timeout timestamp so
1954 : * when we check the connections again after poll() returns and
1955 : * any number of callbacks were called, the timeout does or does
1956 : * not happen as expected.
1957 : *
1958 : * \return The timeout timestamp as returned by get_timeout_timestamp().
1959 : *
1960 : * \sa get_saved_timeout_timestamp()
1961 : * \sa run()
1962 : */
1963 0 : int64_t snap_communicator::snap_connection::save_timeout_timestamp()
1964 : {
1965 0 : f_saved_timeout_stamp = get_timeout_timestamp();
1966 0 : return f_saved_timeout_stamp;
1967 : }
1968 :
1969 :
1970 : /** \brief Get the saved timeout timestamp.
1971 : *
1972 : * This function returns the timeout as saved by the
1973 : * save_timeout_timestamp() function. The timestamp returned by
1974 : * this funtion was frozen so if the user calls various timeout
1975 : * functions that could completely change the timeout stamp that
1976 : * the get_timeout_timestamp() would return just at the time we
1977 : * want to know whether th timeout callback needs to be called
1978 : * will be ignored by the loop.
1979 : *
1980 : * \return The saved timeout stamp as returned by save_timeout_timestamp().
1981 : *
1982 : * \sa save_timeout_timestamp()
1983 : * \sa run()
1984 : */
1985 0 : int64_t snap_communicator::snap_connection::get_saved_timeout_timestamp() const
1986 : {
1987 0 : return f_saved_timeout_stamp;
1988 : }
1989 :
1990 :
1991 : /** \brief Make this connection socket a non-blocking socket.
1992 : *
1993 : * For the read and write to work as expected we generally need
1994 : * to make those sockets non-blocking.
1995 : *
1996 : * For accept(), you do just one call and return and it will not
1997 : * block on you. It is important to not setup a socket you
1998 : * listen on as non-blocking if you do not want to risk having the
1999 : * accepted sockets non-blocking.
2000 : *
2001 : * \param[in] non_blocking_socket Make socket non-block if true,
2002 : * blocking if false.
2003 : */
2004 0 : void snap_communicator::snap_connection::non_blocking() const
2005 : {
2006 0 : if(valid_socket()
2007 0 : && get_socket() >= 0)
2008 : {
2009 0 : int optval(1);
2010 0 : ioctl(get_socket(), FIONBIO, &optval);
2011 : }
2012 0 : }
2013 :
2014 :
2015 : /** \brief Ask the OS to keep the socket alive.
2016 : *
2017 : * This function marks the socket with the SO_KEEPALIVE flag. This means
2018 : * the OS implementation of the network stack should regularly send
2019 : * small messages over the network to keep the connection alive.
2020 : *
2021 : * The function returns whether the function works or not. If the function
2022 : * fails, it logs a warning and returns.
2023 : */
2024 0 : void snap_communicator::snap_connection::keep_alive() const
2025 : {
2026 0 : if(get_socket() != -1)
2027 : {
2028 0 : int optval(1);
2029 0 : socklen_t const optlen(sizeof(optval));
2030 0 : if(setsockopt(get_socket(), SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) != 0)
2031 : {
2032 0 : SNAP_LOG_WARNING("snap_communicator::snap_connection::keep_alive(): an error occurred trying to mark socket with SO_KEEPALIVE.");
2033 : }
2034 : }
2035 0 : }
2036 :
2037 :
2038 : /** \brief Lets you know whether mark_done() was called.
2039 : *
2040 : * This function returns true if mark_done() was called on this connection.
2041 : */
2042 0 : bool snap_communicator::snap_connection::is_done() const
2043 : {
2044 0 : return f_done;
2045 : }
2046 :
2047 :
2048 : /** \brief Call once you are done with a connection.
2049 : *
2050 : * This function lets the connection know that you are done with it.
2051 : * It is very important to call this function before you send the last
2052 : * message. For example, with its permanent connection the snapbackend
2053 : * tool does this:
2054 : *
2055 : * \code
2056 : * f_messenger->mark_done();
2057 : * f_messenger->send_message(stop_message);
2058 : * \endcode
2059 : *
2060 : * The f_done flag is currently used in two situations by the main
2061 : * system:
2062 : *
2063 : * \li write buffer is empty
2064 : *
2065 : * There are times when you send one or more last messages to a connection.
2066 : * The write is generally buffered and will be processed whenever you
2067 : * next come back in the run() loop.
2068 : *
2069 : * So one knows that the write (output) buffer is empty whenever one gets
2070 : * its process_empty_buffer() callback called. At that point, the connection
2071 : * can be removed from the snap_communicator instance since we are done with
2072 : * it. The default process_empty_buffer() does that for us whenver the
2073 : * mark_done() function was called.
2074 : *
2075 : * \li HUP of a permanent connection
2076 : *
2077 : * When the f_done flag is set, the next HUP error is properly interpreted
2078 : * as "we are done". Otherwise, a HUP is interpreted as a lost connection
2079 : * and since a permanent connection is... permanent, it simply restarts the
2080 : * connect process to reconnect to the server.
2081 : *
2082 : * \todo
2083 : * Since we remove the connection on a process_empty_buffer(), maybe we
2084 : * should have the has_output() as a virtual function and if it returns
2085 : * true (which would be the default,) then we should remove the connection
2086 : * immediately since it is already done? This may require a quick review
2087 : * since in some cases we are not to remove the connection at all. But
2088 : * this function could call the process_empty_buffer(), which can be
2089 : * overridden so the developer can add its own callback to avoid the
2090 : * potential side effect.
2091 : *
2092 : * \sa is_done()
2093 : * \sa mark_not_done()
2094 : */
2095 0 : void snap_communicator::snap_connection::mark_done()
2096 : {
2097 0 : f_done = true;
2098 :
2099 : //if(!has_output())
2100 : //{
2101 : // process_empty_buffer();
2102 : //}
2103 0 : }
2104 :
2105 :
2106 : /** \brief Mark this connection as not done.
2107 : *
2108 : * In some cases you may want to mark a connection as done and later
2109 : * restore it as not done.
2110 : *
2111 : * Specifically, this is used by the
2112 : * snap_tcp_blocking_client_message_connection class. When you call the
2113 : * run() function, this mark_not_done() function gets called so in
2114 : * effect you can re-enter the run() loop multiple times. Each time,
2115 : * you have to call the mark_done() function to exit the loop.
2116 : *
2117 : * \sa is_done()
2118 : * \sa mark_done()
2119 : */
2120 0 : void snap_communicator::snap_connection::mark_not_done()
2121 : {
2122 0 : f_done = false;
2123 0 : }
2124 :
2125 :
2126 : /** \brief This callback gets called whenever the connection times out.
2127 : *
2128 : * This function is called whenever a timeout is detected on this
2129 : * connection. It is expected to be overwritten by your class if
2130 : * you expect to use the timeout feature.
2131 : *
2132 : * The snap_timer class is expected to always have a timer (although
2133 : * the connection can temporarily be disabled) which triggers this
2134 : * callback on a given periodicity.
2135 : */
2136 0 : void snap_communicator::snap_connection::process_timeout()
2137 : {
2138 0 : }
2139 :
2140 :
2141 : /** \brief This callback gets called whenever the signal happened.
2142 : *
2143 : * This function is called whenever a certain signal (as defined in
2144 : * your snap_signal object) was detected while waiting for an
2145 : * event.
2146 : */
2147 0 : void snap_communicator::snap_connection::process_signal()
2148 : {
2149 0 : }
2150 :
2151 :
2152 : /** \brief This callback gets called whenever data can be read.
2153 : *
2154 : * This function is called whenever a socket has data that can be
2155 : * read. For UDP, this means reading one packet. For TCP, it means
2156 : * you can read at least one byte. To avoid blocking in TCP,
2157 : * you must have called the non_blocking() function on that
2158 : * connection, then you can attempt to read as much data as you
2159 : * want.
2160 : */
2161 0 : void snap_communicator::snap_connection::process_read()
2162 : {
2163 0 : }
2164 :
2165 :
2166 : /** \brief This callback gets called whenever data can be written.
2167 : *
2168 : * This function is called whenever a socket has space in its output
2169 : * buffers to write data there.
2170 : *
2171 : * For UDP, this means writing one packet.
2172 : *
2173 : * For TCP, it means you can write at least one byte. To be able to
2174 : * write as many bytes as you want, you must make sure to make the
2175 : * socket non_blocking() first, then you can write as many bytes as
2176 : * you want, although all those bytes may not get written in one
2177 : * go (you may need to wait for the next call to this function to
2178 : * finish up your write.)
2179 : */
2180 0 : void snap_communicator::snap_connection::process_write()
2181 : {
2182 0 : }
2183 :
2184 :
2185 : /** \brief Sent all data to the other end.
2186 : *
2187 : * This function is called whenever a connection bufferized data
2188 : * to be sent to the other end of the connection and that buffer
2189 : * just went empty.
2190 : *
2191 : * Just at the time the function gets called, the buffer is empty.
2192 : * You may refill it at that time.
2193 : *
2194 : * The callback is often used to remove a connection from the
2195 : * snapcommunicator instance (i.e. just after we sent a last
2196 : * message to the other end.)
2197 : *
2198 : * By default this function removes the connection from the
2199 : * snap_communicator instance if the mark_done() function was
2200 : * called. Otherwise, it just ignores the message.
2201 : */
2202 0 : void snap_communicator::snap_connection::process_empty_buffer()
2203 : {
2204 0 : if(f_done)
2205 : {
2206 0 : SNAP_LOG_DEBUG("socket ")(get_socket())(" of connection \"")(f_name)("\" was marked as done, removing in process_empty_buffer().");
2207 :
2208 0 : remove_from_communicator();
2209 : }
2210 0 : }
2211 :
2212 :
2213 : /** \brief This callback gets called whenever a connection is made.
2214 : *
2215 : * A listening server receiving a new connection gets this function
2216 : * called. The function is expected to create a new connection object
2217 : * and add it to the communicator.
2218 : *
2219 : * \code
2220 : * // get the socket from the accept() function
2221 : * int const client_socket(accept());
2222 : * client_impl::pointer_t connection(new client_impl(get_communicator(), client_socket));
2223 : * connection->set_name("connection created by server on accept()");
2224 : * get_communicator()->add_connection(connection);
2225 : * \endcode
2226 : */
2227 0 : void snap_communicator::snap_connection::process_accept()
2228 : {
2229 0 : }
2230 :
2231 :
2232 : /** \brief This callback gets called whenever an error is detected.
2233 : *
2234 : * If an error is detected on a socket, this callback function gets
2235 : * called. By default the function removes the connection from
2236 : * the communicator because such errors are generally non-recoverable.
2237 : *
2238 : * The function also logs an error message.
2239 : */
2240 0 : void snap_communicator::snap_connection::process_error()
2241 : {
2242 : // TBD: should we offer a virtual close() function to handle this
2243 : // case? because the get_socket() function will not return
2244 : // -1 after such errors...
2245 :
2246 0 : if(get_socket() == -1)
2247 : {
2248 0 : SNAP_LOG_DEBUG("socket ")(get_socket())(" of connection \"")(f_name)("\" was marked as erroneous by the kernel or was closed (-1).");
2249 : }
2250 : else
2251 : {
2252 : // this happens all the time, so we changed the WARNING into a
2253 : // DEBUG, too much logs by default otherwise...
2254 : //
2255 0 : SNAP_LOG_DEBUG("socket ")(get_socket())(" of connection \"")(f_name)("\" was marked as erroneous by the kernel.");
2256 : }
2257 :
2258 0 : remove_from_communicator();
2259 0 : }
2260 :
2261 :
2262 : /** \brief This callback gets called whenever a hang up is detected.
2263 : *
2264 : * When the remote connection (client or server) closes a socket
2265 : * on their end, then the other end is signaled by getting this
2266 : * callback called.
2267 : *
2268 : * Note that this callback will be called after the process_read()
2269 : * and process_write() callbacks. The process_write() is unlikely
2270 : * to work at all. However, the process_read() may be able to get
2271 : * a few more bytes from the remove connection and act on it.
2272 : *
2273 : * By default a connection gets removed from the communicator
2274 : * when the hang up even occurs.
2275 : */
2276 0 : void snap_communicator::snap_connection::process_hup()
2277 : {
2278 : // TBD: should we offer a virtual close() function to handle this
2279 : // case? because the get_socket() function will not return
2280 : // -1 after such errors...
2281 :
2282 0 : SNAP_LOG_DEBUG("socket ")(get_socket())(" of connection \"")(f_name)("\" hang up.");
2283 :
2284 0 : remove_from_communicator();
2285 0 : }
2286 :
2287 :
2288 : /** \brief This callback gets called whenever an invalid socket is detected.
2289 : *
2290 : * I am not too sure at the moment when we are expected to really receive
2291 : * this call. How does a socket become invalid (i.e. does it get closed
2292 : * and then the user still attempts to use it)? In most cases, this should
2293 : * probably never happen.
2294 : *
2295 : * By default a connection gets removed from the communicator
2296 : * when the invalid even occurs.
2297 : *
2298 : * This function also logs the error.
2299 : */
2300 0 : void snap_communicator::snap_connection::process_invalid()
2301 : {
2302 : // TBD: should we offer a virtual close() function to handle this
2303 : // case? because the get_socket() function will not return
2304 : // -1 after such errors...
2305 :
2306 0 : SNAP_LOG_ERROR("socket of connection \"")(f_name)("\" was marked as invalid by the kernel.");
2307 :
2308 0 : remove_from_communicator();
2309 0 : }
2310 :
2311 :
2312 : /** \brief Callback called whenever this connection gets added.
2313 : *
2314 : * This function gets called whenever this connection is added to
2315 : * the snap_communicator object. This gives you the opportunity
2316 : * to do additional initialization before the run() loop gets
2317 : * called or re-entered.
2318 : */
2319 0 : void snap_communicator::snap_connection::connection_added()
2320 : {
2321 0 : }
2322 :
2323 :
2324 : /** \brief Callback called whenever this connection gets removed.
2325 : *
2326 : * This callback gets called after it got removed from the
2327 : * snap_communicator object. This gives you the opportunity
2328 : * to do additional clean ups before the run() loop gets
2329 : * re-entered.
2330 : */
2331 0 : void snap_communicator::snap_connection::connection_removed()
2332 : {
2333 0 : }
2334 :
2335 :
2336 :
2337 :
2338 :
2339 :
2340 :
2341 : //////////////////////////////////
2342 : // Connection With Send Message //
2343 : //////////////////////////////////
2344 :
2345 :
2346 : /** \brief Initialize a connection_with_send_message object.
2347 : *
2348 : * This constructor initializes a connectopm which supports a send_message()
2349 : * function. This allows that object to send a certain number of default
2350 : * messages such as the UNKNOWN message automatically.
2351 : */
2352 0 : snap_communicator::connection_with_send_message::~connection_with_send_message()
2353 : {
2354 0 : }
2355 :
2356 :
2357 :
2358 : /** \brief Build the HELP reply and send it.
2359 : *
2360 : * When a daemon registers with the snapcommunicator, it sends a REGISTER
2361 : * command. As a result, the daemon is sent a HELP command which must be
2362 : * answered with a COMMAND and the list of commands that this connection
2363 : * supports.
2364 : *
2365 : * \note
2366 : * If the environment logger is not currently configured, this message
2367 : * gets ignored.
2368 : *
2369 : * \param[in] message The HELP message.
2370 : *
2371 : * \sa msg_ready()
2372 : */
2373 0 : void snap_communicator::connection_with_send_message::msg_help(snap_communicator_message & message)
2374 : {
2375 0 : NOTUSED(message);
2376 :
2377 0 : bool need_user_help(true);
2378 0 : snap_string_list commands;
2379 :
2380 : dispatcher_base * d;
2381 0 : snap_dispatcher_support * dispatcher_support(dynamic_cast<snap_dispatcher_support *>(this));
2382 0 : if(dispatcher_support != nullptr)
2383 : {
2384 : // we extract the bare pointer because in the other case
2385 : // we only get a bare pointer... (which we can't safely
2386 : // put in a shared pointer, although we could attempt to
2387 : // use shared_from_this() but we could have a class without
2388 : // it?)
2389 : //
2390 0 : d = dispatcher_support->get_dispatcher().get();
2391 : }
2392 : else
2393 : {
2394 0 : d = dynamic_cast<dispatcher_base *>(this);
2395 : }
2396 0 : if(d != nullptr)
2397 : {
2398 0 : need_user_help = d->get_commands(commands);
2399 : }
2400 :
2401 : // the user has "unknown" commands (as far as the dispatcher is concerned)
2402 : // in his list of commands so we have to let him enter them "manually"
2403 : //
2404 : // this happens whenever there is an entry which is a regular expression
2405 : // or something similar which we just cannot grab
2406 : //
2407 0 : if(need_user_help)
2408 : {
2409 0 : help(commands);
2410 : }
2411 :
2412 : // the list of commands just cannot be empty
2413 : //
2414 0 : if(commands.empty())
2415 : {
2416 : throw snap_communicator_implementation_error(
2417 : "snap_communicator::connection_with_send_message::msg_help()"
2418 0 : " is not able to determine the commands this messenger supports");
2419 : }
2420 :
2421 : // Now prepare the COMMAND message and send it
2422 : //
2423 : // Note: we turn off the caching on this message, it does not make sense
2424 : // because if snapcommunicator is not running, then caching won't
2425 : // happen work anyway (i.e. snapcommunicator has to send HELP first
2426 : // and then we send the reply, if it has to restart, then just
2427 : // sending COMMANDS will fail.)
2428 : //
2429 0 : snap::snap_communicator_message reply;
2430 0 : reply.set_command("COMMANDS");
2431 0 : reply.add_parameter("list", commands.join(","));
2432 0 : if(!send_message(reply, false))
2433 : {
2434 0 : SNAP_LOG_WARNING("could not reply with COMMANDS message to \"")(message.get_command())("\"");
2435 : }
2436 0 : }
2437 :
2438 :
2439 : /** \brief Reply to the watchdog message ALIVE.
2440 : *
2441 : * To check whether a service is alive, send the ALIVE message. This
2442 : * function builds a ABSOLUTELY reply and attaches the "serial" parameter
2443 : * as is if present. It will also include the original "timestamp" parameter
2444 : * when present.
2445 : *
2446 : * The function also adds one field named "reply_timestamp" with the Unix
2447 : * time when the reply is being sent.
2448 : *
2449 : * \note
2450 : * The "serial" parameter is expected to be used to make sure that no messages
2451 : * are lost, or if loss is expected, to see whether loss is heavy or not.
2452 : *
2453 : * \note
2454 : * The "serial" and "timestamp" parameters do not get checked. If present
2455 : * in the original message, they get copied verbatim to the destination.
2456 : * This allows you to include anything you want in those parameters although
2457 : * we suggest you use the "timestamp" only for a value representing time.
2458 : *
2459 : * \param[in] message The STOP message.
2460 : */
2461 0 : void snap_communicator::connection_with_send_message::msg_alive(snap_communicator_message & message)
2462 : {
2463 0 : snap::snap_communicator_message absolutely;
2464 0 : absolutely.reply_to(message);
2465 0 : absolutely.set_command("ABSOLUTELY");
2466 0 : if(message.has_parameter("serial"))
2467 : {
2468 0 : absolutely.add_parameter("serial", message.get_parameter("serial"));
2469 : }
2470 0 : if(message.has_parameter("timestamp"))
2471 : {
2472 0 : absolutely.add_parameter("timestamp", message.get_parameter("timestamp"));
2473 : }
2474 0 : absolutely.add_parameter("reply_timestamp", time(nullptr));
2475 0 : if(!send_message(absolutely, false))
2476 : {
2477 0 : SNAP_LOG_WARNING("could not reply with ABSOLULTELY message to \"")(message.get_command())("\"");
2478 : }
2479 0 : }
2480 :
2481 :
2482 : /** \brief Reconfigure the logger.
2483 : *
2484 : * Whenever the logrotate runs or some changes are maed to the log
2485 : * definitions, the corresponding daemons need to reconfigure their
2486 : * logger to make use of the new file and settings. This command is
2487 : * used for the purpose.
2488 : *
2489 : * \note
2490 : * If the environment logger is not currently configured, this message
2491 : * gets ignored.
2492 : *
2493 : * \param[in] message The STOP message.
2494 : */
2495 0 : void snap_communicator::connection_with_send_message::msg_log(snap_communicator_message & message)
2496 : {
2497 0 : NOTUSED(message);
2498 :
2499 0 : if(snap::logging::is_configured())
2500 : {
2501 : // send log in the old file and format
2502 : //
2503 0 : SNAP_LOG_INFO("-------------------- Logging reconfiguration request.");
2504 :
2505 : // reconfigure
2506 : //
2507 0 : snap::logging::reconfigure();
2508 :
2509 : // send log to new file and format
2510 : //
2511 0 : SNAP_LOG_INFO("-------------------- Logging reconfiguration done.");
2512 : }
2513 0 : }
2514 :
2515 :
2516 : /** \brief Call you stop() function with true.
2517 : *
2518 : * This command means that someone is asking your daemon to quit as soon as
2519 : * possible because the Snap! environment is being asked to shutdown.
2520 : *
2521 : * The value 'true' means that all the daemons are being asked to stop and
2522 : * not just you.
2523 : *
2524 : * \param[in] message The STOP message.
2525 : *
2526 : * \sa msg_stop()
2527 : */
2528 0 : void snap_communicator::connection_with_send_message::msg_quitting(snap_communicator_message & message)
2529 : {
2530 0 : NOTUSED(message);
2531 :
2532 0 : stop(true);
2533 0 : }
2534 :
2535 :
2536 : /** \brief Call you ready() function with the message.
2537 : *
2538 : * All daemons using the snapcommunicator daemon have to have a ready()
2539 : * function which gets called once the HELP and COMMAND message were
2540 : * handled. This is why your daemon is expected to be ready to start
2541 : * working. Some daemon, though, start working immediately no matter
2542 : * what (i.e. snapwatchdog and snapfirewall do work either way.)
2543 : *
2544 : * \param[in] message The READY message.
2545 : *
2546 : * \sa msg_help()
2547 : */
2548 0 : void snap_communicator::connection_with_send_message::msg_ready(snap_communicator_message & message)
2549 : {
2550 : // pass the message so any additional info can be accessed.
2551 : //
2552 0 : ready(message);
2553 0 : }
2554 :
2555 :
2556 : /** \brief Call you stop() function with false.
2557 : *
2558 : * This command means that someone is asking your daemon to stop.
2559 : *
2560 : * The value 'false' means just your daemon was asked to stop and not the
2561 : * entire system to shutdown (otherwise you would receive a QUITTING command
2562 : * instead.)
2563 : *
2564 : * \param[in] message The STOP message.
2565 : *
2566 : * \sa msg_quitting()
2567 : */
2568 0 : void snap_communicator::connection_with_send_message::msg_stop(snap_communicator_message & message)
2569 : {
2570 0 : NOTUSED(message);
2571 :
2572 0 : stop(false);
2573 0 : }
2574 :
2575 :
2576 : /** \brief Handle the UNKNOWN message.
2577 : *
2578 : * Whenever we send a command to another daemon, that command can be refused
2579 : * by sending an UNKNOWN reply. This function handles the UNKNOWN command
2580 : * by simply recording that as an error in the logs.
2581 : *
2582 : * \param[in] message The UNKNOWN message we just received.
2583 : */
2584 0 : void snap_communicator::connection_with_send_message::msg_log_unknown(snap_communicator_message & message)
2585 : {
2586 : // we sent a command that the other end did not understand
2587 : // and got an UNKNOWN reply
2588 : //
2589 0 : SNAP_LOG_ERROR("we sent unknown command \"")
2590 0 : (message.get_parameter("command"))
2591 0 : ("\" and probably did not get the expected result.");
2592 0 : }
2593 :
2594 :
2595 : /** \brief Send the UNKNOWN message as a reply.
2596 : *
2597 : * This function replies to the \p message with the UNKNOWN message as
2598 : * expected by all our `snap_connection`'s when a service receives a
2599 : * message it does not know how to handle.
2600 : *
2601 : * It is expected to be used in your dispatcher_match array.
2602 : *
2603 : * \note
2604 : * This function is virtual which allows you to add it to your array of
2605 : * of dispatcher_match items. The following shows an example of what that
2606 : * can look like.
2607 : *
2608 : * \code
2609 : * ...
2610 : *
2611 : * // ALWAYS LAST
2612 : * {
2613 : * nullptr
2614 : * , &my_service_connection::msg_reply_with_unknown
2615 : * , &snap::dispatcher<my_service_connection>::dispatcher_match::always_match
2616 : * }
2617 : * };
2618 : * \endcode
2619 : *
2620 : * \param[in] message The messageto reply to.
2621 : */
2622 0 : void snap_communicator::connection_with_send_message::msg_reply_with_unknown(snap_communicator_message & message)
2623 : {
2624 0 : snap::snap_communicator_message unknown;
2625 0 : unknown.reply_to(message);
2626 0 : unknown.set_command("UNKNOWN");
2627 0 : unknown.add_parameter("command", message.get_command());
2628 0 : if(!send_message(unknown, false))
2629 : {
2630 0 : SNAP_LOG_WARNING("could not reply with UNKNOWN message to \"")(message.get_command())("\"");
2631 : }
2632 0 : }
2633 :
2634 :
2635 : /** \brief The default help() function does nothing.
2636 : *
2637 : * This implementation does nothing. It is expected that you reimplement
2638 : * this function depending on your daemon's need.
2639 : *
2640 : * The help() function gets called whenever the list of commands can't be
2641 : * 100% defined automatically.
2642 : *
2643 : * Your function is expected to add commands to the \p commands parameter
2644 : * as in:
2645 : *
2646 : * \code
2647 : * commands << "MSG1";
2648 : * commands << "MSG2";
2649 : * commands << "MSG3";
2650 : * \endcode
2651 : *
2652 : * This allows you to handle those three messages with a single entry in
2653 : * your list of dispatcher_match objects with a regular expression such
2654 : * as "MSG[1-3]".
2655 : *
2656 : * \param[in,out] commands List of commands to update.
2657 : */
2658 0 : void snap_communicator::connection_with_send_message::help(snap_string_list & commands)
2659 : {
2660 0 : NOTUSED(commands);
2661 :
2662 : // do nothing by default -- user is expected to overload this function
2663 0 : }
2664 :
2665 :
2666 : /** \brief The default ready() function does nothing.
2667 : *
2668 : * This implementation does nothing. It is expected that you reimplement
2669 : * this function depending on your daemon's need. Most often this function
2670 : * is the one that really starts your daemons process.
2671 : *
2672 : * \param[in,out] message The READY message.
2673 : */
2674 0 : void snap_communicator::connection_with_send_message::ready(snap_communicator_message & message)
2675 : {
2676 0 : NOTUSED(message);
2677 :
2678 : // do nothing by default -- user is expected to overload this function
2679 : //
2680 0 : SNAP_LOG_WARNING("default ready() function was called.");
2681 0 : }
2682 :
2683 :
2684 : /** \brief The default stop() function does nothing.
2685 : *
2686 : * This implementation does nothing. It is expected that you reimplement
2687 : * this function depending on your daemon's need.
2688 : *
2689 : * \param[in] quitting Whether the QUITTING (true) or STOP (false) command
2690 : * was received.
2691 : */
2692 0 : void snap_communicator::connection_with_send_message::stop(bool quitting)
2693 : {
2694 0 : NOTUSED(quitting);
2695 :
2696 : // do nothing by default -- user is expected to overload this function
2697 : //
2698 0 : SNAP_LOG_WARNING("default stop() function was called.");
2699 0 : }
2700 :
2701 :
2702 :
2703 :
2704 :
2705 :
2706 :
2707 :
2708 :
2709 :
2710 : ////////////////
2711 : // Snap Timer //
2712 : ////////////////
2713 :
2714 :
2715 : /** \brief Initializes the timer object.
2716 : *
2717 : * This function initializes the timer object with the specified \p timeout
2718 : * defined in microseconds.
2719 : *
2720 : * Note that by default all snap_connection objects are marked as persistent
2721 : * since in most cases that is the type of connections you are interested
2722 : * in. Therefore timers are also marked as persistent. This means if you
2723 : * want a one time callback, you want to call the remove_connection()
2724 : * function with your timer from your callback.
2725 : *
2726 : * \note
2727 : * POSIX offers timers (in Linux since kernel version 2.6), only
2728 : * (a) these generate signals, which is generally considered slow
2729 : * in comparison to a timeout assigned to the poll() function, and
2730 : * (b) the kernel posts at most one timer signal at a time across
2731 : * one process, in other words, if 5 timers time out before you are
2732 : * given a chance to process the timer, you only get one single
2733 : * signal.
2734 : *
2735 : * \param[in] communicator The snap communicator controlling this connection.
2736 : * \param[in] timeout_us The timeout in microseconds.
2737 : */
2738 0 : snap_communicator::snap_timer::snap_timer(int64_t timeout_us)
2739 : {
2740 0 : if(timeout_us == 0)
2741 : {
2742 : // if zero, we assume that the timeout is a one time trigger
2743 : // and that it will be set to other dates at other later times
2744 : //
2745 0 : set_timeout_date(get_current_date());
2746 : }
2747 : else
2748 : {
2749 0 : set_timeout_delay(timeout_us);
2750 : }
2751 0 : }
2752 :
2753 :
2754 : /** \brief Retrieve the socket of the timer object.
2755 : *
2756 : * Timer objects are never attached to a socket so this function always
2757 : * returns -1.
2758 : *
2759 : * \note
2760 : * You should not override this function since there is not other
2761 : * value it can return.
2762 : *
2763 : * \return Always -1.
2764 : */
2765 0 : int snap_communicator::snap_timer::get_socket() const
2766 : {
2767 0 : return -1;
2768 : }
2769 :
2770 :
2771 : /** \brief Tell that the socket is always valid.
2772 : *
2773 : * This function always returns true since the timer never uses a socket.
2774 : *
2775 : * \return Always true.
2776 : */
2777 0 : bool snap_communicator::snap_timer::valid_socket() const
2778 : {
2779 0 : return true;
2780 : }
2781 :
2782 :
2783 :
2784 :
2785 :
2786 :
2787 :
2788 : /////////////////
2789 : // Snap Signal //
2790 : /////////////////
2791 :
2792 :
2793 : /** \brief Initializes the signal object.
2794 : *
2795 : * This function initializes the signal object with the specified
2796 : * \p posix_signal which represents a POSIX signal such as SIGHUP,
2797 : * SIGTERM, SIGUSR1, SIGUSR2, etc.
2798 : *
2799 : * The signal automatically gets masked out. This allows us to
2800 : * unmask the signal only when we are ready to call ppoll() and
2801 : * thus not have the signal break any of our normal user code.
2802 : *
2803 : * The ppoll() function unblocks all the signals that you listen
2804 : * to (i.e. for each snap_signal object you created.) The run()
2805 : * loop ends up calling your process_signal() callback function.
2806 : *
2807 : * Note that the snap_signal callback is called from the normal user
2808 : * environment and not directly from the POSIX signal handler.
2809 : * This means you can call any function from your callback.
2810 : *
2811 : * \note
2812 : * IMPORTANT: Remember that POSIX signals stop your code at a 'breakable'
2813 : * point which in many circumstances can create many problems unless
2814 : * you make sure to mask signals while doing work. For example, you
2815 : * could end up with a read() returning an error when the file you
2816 : * are reading has absolutely no error but a dude decided to signal
2817 : * you with a 'kill -HUP 123'...
2818 : *
2819 : * \code
2820 : * {
2821 : * // use an RAII masking mechanism
2822 : * mask_posix_signal mask();
2823 : *
2824 : * // do your work (i.e. read/write/etc.)
2825 : * ...
2826 : * }
2827 : * \endcode
2828 : *
2829 : * \par
2830 : * The best way in our processes will be to block all signals except
2831 : * while poll() is called (using ppoll() for the feat.)
2832 : *
2833 : * \note
2834 : * By default the constructor masks the specified \p posix_signal and
2835 : * it does not restore the signal on destruction. If you want the
2836 : * signal to be unmasked on destruction (say to restore the default
2837 : * functioning of the SIGINT signal,) then make sure to call the
2838 : * unblock_signal() function right after you create your connection.
2839 : *
2840 : * \warning
2841 : * The the signal gets masked by this constructor. If you want to make
2842 : * sure that most of your code does not get affected by said signal,
2843 : * make sure to create your snap_signal object early on or mask those
2844 : * signals beforehand. Otherwise the signal could happen before it
2845 : * gets masked. Initialization of your process may not require
2846 : * protection anyway.
2847 : *
2848 : * \bug
2849 : * You should not use signal() and setup a handler for the same signal.
2850 : * It will not play nice to have both types of signal handlers. That
2851 : * being said, we my current testing (as of Ubuntu 16.04), it seems
2852 : * to work just fine..
2853 : *
2854 : * \exception snap_communicator_initialization_error
2855 : * Create multiple snap_signal() with the same posix_signal parameter
2856 : * is not supported and this exception is raised whenever you attempt
2857 : * to do that. Remember that you can have at most one snap_communicator
2858 : * object (hence the singleton.)
2859 : *
2860 : * \exception snap_communicator_runtime_error
2861 : * The signalfd() function is expected to create a "socket" (file
2862 : * descriptor) listening for incoming signals. If it fails, this
2863 : * exception is raised (which is very similar to other socket
2864 : * based connections which throw whenever a connection cannot
2865 : * be achieved.)
2866 : *
2867 : * \param[in] posix_signal The signal to be managed by this snap_signal.
2868 : */
2869 0 : snap_communicator::snap_signal::snap_signal(int posix_signal)
2870 0 : : f_signal(posix_signal)
2871 : {
2872 0 : int const r(sigismember(&g_signal_handlers, f_signal));
2873 0 : if(r != 0)
2874 : {
2875 0 : if(r == 1)
2876 : {
2877 : // this could be fixed, but probably not worth the trouble...
2878 0 : throw snap_communicator_initialization_error("the same signal cannot be created more than once in your entire process.");
2879 : }
2880 : // f_signal is not considered valid by this OS
2881 0 : throw snap_communicator_initialization_error("posix_signal (f_signal) is not a valid/recognized signal number.");
2882 : }
2883 :
2884 : // create a mask for that signal
2885 : //
2886 : sigset_t set;
2887 0 : sigemptyset(&set);
2888 0 : sigaddset(&set, f_signal); // ignore error, we already know f_signal is valid
2889 :
2890 : // first we block the signal
2891 : //
2892 0 : if(sigprocmask(SIG_BLOCK, &set, nullptr) != 0)
2893 : {
2894 0 : throw snap_communicator_runtime_error("sigprocmask() failed to block signal.");
2895 : }
2896 :
2897 : // second we create a "socket" for the signal (really it is a file
2898 : // descriptor manager by the kernel)
2899 : //
2900 0 : f_socket = signalfd(-1, &set, SFD_NONBLOCK | SFD_CLOEXEC);
2901 0 : if(f_socket == -1)
2902 : {
2903 0 : int const e(errno);
2904 0 : SNAP_LOG_ERROR("signalfd() failed to create a signal listener for signal ")(f_signal)(" (errno: ")(e)(" -- ")(strerror(e))(")");
2905 0 : throw snap_communicator_runtime_error("signalfd() failed to create a signal listener.");
2906 : }
2907 :
2908 : // mark this signal as in use
2909 : //
2910 0 : sigaddset(&g_signal_handlers, f_signal); // ignore error, we already know f_signal is valid
2911 0 : }
2912 :
2913 :
2914 : /** \brief Restore the signal as it was before you created a snap_signal.
2915 : *
2916 : * The destructor is expected to restore the signal to what it was
2917 : * before you create this snap_signal. Of course, if you created
2918 : * other signal handlers in between, it will not work right since
2919 : * this function will destroy your handler pointer.
2920 : *
2921 : * To do it right, it has to be done in order (i.e. set handler 1, set
2922 : * handler 2, set handler 3, remove handler 3, remove handler 2, remove
2923 : * handler 1.) We do not guarantee anything at this level!
2924 : */
2925 0 : snap_communicator::snap_signal::~snap_signal()
2926 : {
2927 0 : close();
2928 0 : }
2929 :
2930 :
2931 : /** \brief Tell that this connection is listening on a Unix signal.
2932 : *
2933 : * The snap_signal implements the signal listening feature. We use
2934 : * a simple flag in the virtual table to avoid a more expansive
2935 : * dynamic_cast<>() is a loop that goes over all the connections
2936 : * you have defined.
2937 : *
2938 : * \return The base implementation returns false.
2939 : */
2940 0 : bool snap_communicator::snap_signal::is_signal() const
2941 : {
2942 0 : return true;
2943 : }
2944 :
2945 :
2946 : /** \brief Retrieve the "socket" of the signal object.
2947 : *
2948 : * Signal objects have a socket (file descriptor) assigned to them
2949 : * using the signalfd() function.
2950 : *
2951 : * \note
2952 : * You should not override this function since there is no other
2953 : * value it can return.
2954 : *
2955 : * \return The signal socket to listen on with poll().
2956 : */
2957 0 : int snap_communicator::snap_signal::get_socket() const
2958 : {
2959 0 : return f_socket;
2960 : }
2961 :
2962 :
2963 : /** \brief Retrieve the PID of the child process that just emitted SIGCHLD.
2964 : *
2965 : * This function returns the process identifier (pid_t) of the child that
2966 : * just sent us a SIGCHLD Unix signal.
2967 : *
2968 : * \exception snap_communicator_runtime_error
2969 : * This exception is raised if the function gets called before any signal
2970 : * ever occurred.
2971 : *
2972 : * \return The process identifier (pid_t) of the child that died.
2973 : */
2974 0 : pid_t snap_communicator::snap_signal::get_child_pid() const
2975 : {
2976 0 : if(f_signal_info.ssi_signo == 0)
2977 : {
2978 0 : throw snap_communicator_runtime_error("snap_signal::get_child_pid() called before any signal ever occurred.");
2979 : }
2980 :
2981 0 : return f_signal_info.ssi_pid;
2982 : }
2983 :
2984 :
2985 : /** \brief Processes this signal.
2986 : *
2987 : * This function reads the signal "socket" for all the signal received
2988 : * so far.
2989 : *
2990 : * For each instance found in the signal queue, the process_signal() gets
2991 : * called.
2992 : */
2993 0 : void snap_communicator::snap_signal::process()
2994 : {
2995 : // loop any number of times as required
2996 : // (or can we receive a maximum of 1 such signal at a time?)
2997 : //
2998 0 : while(f_socket != -1)
2999 : {
3000 0 : int const r(read(f_socket, &f_signal_info, sizeof(f_signal_info)));
3001 0 : if(r == sizeof(f_signal_info))
3002 : {
3003 0 : process_signal();
3004 : }
3005 : else
3006 : {
3007 0 : if(r == -1)
3008 : {
3009 : // if EAGAIN then we are done as expected, any other error
3010 : // is logged
3011 : //
3012 0 : if(errno != EAGAIN)
3013 : {
3014 0 : int const e(errno);
3015 0 : SNAP_LOG_ERROR("an error occurred while reading from the signalfd() file descriptor. (errno: ")(e)(" -- ")(strerror(e));
3016 : }
3017 : }
3018 : else
3019 : {
3020 : // what to do? what to do?
3021 0 : SNAP_LOG_ERROR("reading from the signalfd() file descriptor did not return the expected size. (got ")(r)(", expected ")(sizeof(f_signal_info))(")");
3022 : }
3023 0 : break;
3024 : }
3025 : }
3026 0 : }
3027 :
3028 :
3029 : /** \brief Close the signal file descriptor.
3030 : *
3031 : * This function closes the file descriptor and, if you called the
3032 : * unblock_signal_on_destruction() function, it also restores the
3033 : * signal (unblocks it.)
3034 : *
3035 : * After this call, the connection is pretty much useless (although
3036 : * you could still use it as a timer.) You cannot reopen the signal
3037 : * file descriptor once closed. Instead, you have to create a new
3038 : * connection.
3039 : */
3040 0 : void snap_communicator::snap_signal::close()
3041 : {
3042 0 : if(f_socket != -1)
3043 : {
3044 0 : ::close(f_socket);
3045 0 : f_socket = -1;
3046 :
3047 0 : sigdelset(&g_signal_handlers, f_signal); // ignore error, we already know f_signal is valid
3048 :
3049 0 : if(f_unblock)
3050 : {
3051 : // also unblock the signal
3052 : //
3053 : sigset_t set;
3054 0 : sigemptyset(&set);
3055 0 : sigaddset(&set, f_signal); // ignore error, we already know f_signal is valid
3056 0 : if(sigprocmask(SIG_UNBLOCK, &set, nullptr) != 0)
3057 : {
3058 : // we cannot throw in a destructor and in most cases this
3059 : // happens in the destructor...
3060 : //throw snap_communicator_runtime_error("sigprocmask() failed to block signal.");
3061 :
3062 0 : int const e(errno);
3063 0 : SNAP_LOG_FATAL("an error occurred while unblocking signal ")
3064 0 : (f_signal)
3065 0 : (" with sigprocmask(). (errno: ")
3066 0 : (e)
3067 0 : (" -- ")
3068 0 : (strerror(e));
3069 0 : std::cerr << "sigprocmask() failed to unblock signal." << std::endl;
3070 :
3071 0 : std::terminate();
3072 : }
3073 : }
3074 : }
3075 0 : }
3076 :
3077 :
3078 : /** \brief Unmask a signal that was part of a connection.
3079 : *
3080 : * If you remove a snap_signal connection, you may want to restore
3081 : * the mask functionality. By default the signal gets masked but
3082 : * it does not get unmasked.
3083 : *
3084 : * By calling this function just after creation, the signal gets restored
3085 : * (unblocked) whenever the snap_signal object gets destroyed.
3086 : */
3087 0 : void snap_communicator::snap_signal::unblock_signal_on_destruction()
3088 : {
3089 0 : f_unblock = true;
3090 0 : }
3091 :
3092 :
3093 :
3094 :
3095 :
3096 :
3097 :
3098 :
3099 : /////////////////////////////
3100 : // Snap Thread Done Signal //
3101 : /////////////////////////////
3102 :
3103 :
3104 : /** \brief Initializes the "thread done signal" object.
3105 : *
3106 : * To know that a thread is done, we need some form of signal that the
3107 : * poll() can wake up on. For the purpose we currently use a pipe because
3108 : * a full socket is rather slow to setup compare to a simple pipe.
3109 : *
3110 : * To use this signal, one creates a Thread Done Signal and adds the
3111 : * new connection to the Snap Communicator object. Then when the thread
3112 : * is done, the thread calls the thread_done() function. That will wake
3113 : * up the main process.
3114 : *
3115 : * The same snap_thread_done_signal class can be used multiple times,
3116 : * but only by one thread at a time. Otherwise you cannot know which
3117 : * thread sent the message and by the time you attempt a join, you may
3118 : * be testing the wrong thread (either that or you need another type
3119 : * of synchronization mechanism.)
3120 : *
3121 : * \code
3122 : * class thread_done_impl
3123 : * : snap::snap_communicator::snap_thread_done_signal::snap_thread_done_signal
3124 : * {
3125 : * ...
3126 : * void process_read()
3127 : * {
3128 : * // this function gets called when the thread is about
3129 : * // to exit or has exited; since the write to the pipe
3130 : * // happens before the thread really exited, but should
3131 : * // be near the very end, you should be fine calling the
3132 : * // snap_thread::stop() function to join with it very
3133 : * // quickly.
3134 : * ...
3135 : * }
3136 : * ...
3137 : * };
3138 : *
3139 : * // in the main thread
3140 : * snap::snap_communicator::snap_thread_done_signal::pointer_t s(new thread_done_impl);
3141 : * snap::snap_communicator::instance()->add_connection(s);
3142 : *
3143 : * // create thread... and make sure the thread has access to 's'
3144 : * ...
3145 : *
3146 : * // in the thread, before exiting we do:
3147 : * s->thread_done();
3148 : *
3149 : * // around here, in the timeline, the process_read() function
3150 : * // gets called
3151 : * \endcode
3152 : *
3153 : * \todo
3154 : * Change the implementation to use eventfd() instead of pipe2().
3155 : * Pipes are using more resources and are slower to use than
3156 : * an eventfd.
3157 : */
3158 0 : snap_communicator::snap_thread_done_signal::snap_thread_done_signal()
3159 : {
3160 0 : if(pipe2(f_pipe, O_NONBLOCK | O_CLOEXEC) != 0)
3161 : {
3162 : // pipe could not be created
3163 0 : throw snap_communicator_initialization_error("somehow the pipes used to detect the death of a thread could not be created.");
3164 : }
3165 0 : }
3166 :
3167 :
3168 : /** \brief Close the pipe used to detect the thread death.
3169 : *
3170 : * The destructor is expected to close the pipe opned in the constructor.
3171 : */
3172 0 : snap_communicator::snap_thread_done_signal::~snap_thread_done_signal()
3173 : {
3174 0 : close(f_pipe[0]);
3175 0 : close(f_pipe[1]);
3176 0 : }
3177 :
3178 :
3179 : /** \brief Tell that this connection expects incoming data.
3180 : *
3181 : * The snap_thread_done_signal implements a signal that a secondary
3182 : * thread can trigger before it quits, hence waking up the main
3183 : * thread immediately instead of polling.
3184 : *
3185 : * \return The function returns true.
3186 : */
3187 0 : bool snap_communicator::snap_thread_done_signal::is_reader() const
3188 : {
3189 0 : return true;
3190 : }
3191 :
3192 :
3193 : /** \brief Retrieve the "socket" of the thread done signal object.
3194 : *
3195 : * The Thread Done Signal is implemented using a pair of pipes.
3196 : * One of the pipes is returned as the "socket" and the other is
3197 : * used to "write the signal".
3198 : *
3199 : * \return The signal "socket" to listen on with poll().
3200 : */
3201 0 : int snap_communicator::snap_thread_done_signal::get_socket() const
3202 : {
3203 0 : return f_pipe[0];
3204 : }
3205 :
3206 :
3207 : /** \brief Read the byte that was written in the thread_done().
3208 : *
3209 : * This function implementation reads one byte that was written by
3210 : * thread_done() so the pipes can be reused multiple times.
3211 : */
3212 0 : void snap_communicator::snap_thread_done_signal::process_read()
3213 : {
3214 0 : char c(0);
3215 0 : if(read(f_pipe[0], &c, sizeof(char)) != sizeof(char))
3216 : {
3217 0 : int const e(errno);
3218 0 : SNAP_LOG_ERROR("an error occurred while reading from a pipe used to know whether a thread is done (errno: ")(e)(" -- ")(strerror(e))(").");
3219 : }
3220 0 : }
3221 :
3222 :
3223 : /** \brief Send the signal from the secondary thread.
3224 : *
3225 : * This function writes one byte in the pipe, which has the effect of
3226 : * waking up the poll() of the main thread. This way we avoid having
3227 : * to lock the file.
3228 : *
3229 : * The thread is expected to call this function just before it returns.
3230 : */
3231 0 : void snap_communicator::snap_thread_done_signal::thread_done()
3232 : {
3233 0 : char c(1);
3234 0 : if(write(f_pipe[1], &c, sizeof(char)) != sizeof(char))
3235 : {
3236 0 : int const e(errno);
3237 0 : SNAP_LOG_ERROR("an error occurred while writing to a pipe used to know whether a thread is done (errno: ")(e)(" -- ")(strerror(e))(").");
3238 : }
3239 0 : }
3240 :
3241 :
3242 :
3243 :
3244 :
3245 :
3246 :
3247 : //////////////////////////////////
3248 : // Snap Inter-Thread Connection //
3249 : //////////////////////////////////
3250 :
3251 :
3252 :
3253 : /** \brief Initializes the inter-thread connection.
3254 : *
3255 : * This function creates two queues to communicate between two threads.
3256 : * At this point, we expect such connections to only be used between
3257 : * two threads because we cannot listen on more than one socket.
3258 : *
3259 : * The connection is expected to be created by "thread A". This means
3260 : * the send_message() for "thread A" adds messages to the queue of
3261 : * "thread B" and the process_message() for "thread A" reads
3262 : * messages from the "thread A" queue, and vice versa.
3263 : *
3264 : * In order to know whether a queue has data in it, we use an eventfd().
3265 : * One of them is for "thread A" and the other is for "thread B".
3266 : *
3267 : * \todo
3268 : * To support all the features of a snap_connection on both sides
3269 : * we would have to allocate a sub-connection object for thread B.
3270 : * That sub-connection object would then be used just like a full
3271 : * regular connection with all of its own parameters. Actually the
3272 : * FIFO of messages could then clearly be segregated in each object.
3273 : *
3274 : * \exception snap_communicator_initialization_error
3275 : * This exception is raised if the pipes (socketpair) cannot be created.
3276 : */
3277 0 : snap_communicator::snap_inter_thread_message_connection::snap_inter_thread_message_connection()
3278 : {
3279 0 : f_creator_id = gettid();
3280 :
3281 0 : f_thread_a.reset(new int(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK | EFD_SEMAPHORE)), fd_deleter);
3282 0 : if(*f_thread_a == -1)
3283 : {
3284 : // eventfd could not be created
3285 0 : throw snap_communicator_initialization_error("could not create eventfd for thread A");
3286 : }
3287 :
3288 0 : f_thread_b.reset(new int(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK | EFD_SEMAPHORE)), fd_deleter);
3289 0 : if(*f_thread_b == -1)
3290 : {
3291 : // eventfd could not be created
3292 0 : throw snap_communicator_initialization_error("could not create eventfd for thread B");
3293 : }
3294 0 : }
3295 :
3296 :
3297 : /** \brief Make sure to close the eventfd objects.
3298 : *
3299 : * The destructor ensures that the eventfd objects allocated by the
3300 : * constructor get closed.
3301 : */
3302 0 : snap_communicator::snap_inter_thread_message_connection::~snap_inter_thread_message_connection()
3303 : {
3304 0 : }
3305 :
3306 :
3307 : /** \brief Close the thread communication early.
3308 : *
3309 : * This function closes the pair of eventfd managed by this
3310 : * inter-thread connection object.
3311 : *
3312 : * After this call, the inter-thread connection is closed and cannot be
3313 : * used anymore. The read and write functions will return immediately
3314 : * if called.
3315 : */
3316 0 : void snap_communicator::snap_inter_thread_message_connection::close()
3317 : {
3318 0 : f_thread_a.reset();
3319 0 : f_thread_b.reset();
3320 0 : }
3321 :
3322 :
3323 : /** \brief Poll the connection in the child.
3324 : *
3325 : * There can be only one snap_communicator, therefore, the thread
3326 : * cannot make use of it since it is only for the main application.
3327 : * This poll() function can be used by the child to wait on the
3328 : * connection.
3329 : *
3330 : * You may specify a timeout as usual.
3331 : *
3332 : * \exception snap_communicator_runtime_error
3333 : * If an interrupt happens and stops the poll() then this exception is
3334 : * raised. If not enough memory is available to run the poll() function,
3335 : * this errors is raised.
3336 : *
3337 : * \exception snap_communicator_parameter_error
3338 : * Somehow a buffer was moved out of our client's space (really that one
3339 : * is not likely to happen...). Too many file descriptors in the list of
3340 : * fds (not likely to happen since we just have one!)
3341 : *
3342 : * \exception snap_communicator_parameter_error
3343 : *
3344 : * \param[in] timeout The maximum amount of time to wait in microseconds.
3345 : * Use zero (0) to not block at all.
3346 : *
3347 : * \return -1 if an error occurs, 0 on success
3348 : */
3349 0 : int snap_communicator::snap_inter_thread_message_connection::poll(int timeout)
3350 : {
3351 : for(;;)
3352 : {
3353 : // are we even enabled?
3354 : //
3355 : struct pollfd fd;
3356 0 : fd.events = POLLIN | POLLPRI | POLLRDHUP;
3357 0 : fd.fd = get_socket();
3358 :
3359 0 : if(fd.fd < 0
3360 0 : || !is_enabled())
3361 : {
3362 0 : return -1;
3363 : }
3364 :
3365 : // we cannot use this connection timeout information; it would
3366 : // otherwise be common to both threads; so instead we have
3367 : // a parameter which is used by the caller to tell us how long
3368 : // we have to wait
3369 : //
3370 : // convert microseconds to milliseconds for poll()
3371 : //
3372 0 : if(timeout > 0)
3373 : {
3374 0 : timeout /= 1000;
3375 0 : if(timeout == 0)
3376 : {
3377 : // less than one is a waste of time (CPU intenssive
3378 : // until the time is reached, we can be 1 ms off
3379 : // instead...)
3380 : //
3381 0 : timeout = 1;
3382 : }
3383 : }
3384 : else
3385 : {
3386 : // negative numbers are adjusted to zero.
3387 : //
3388 0 : timeout = 0;
3389 : }
3390 :
3391 0 : int const r(::poll(&fd, 1, timeout));
3392 0 : if(r < 0)
3393 : {
3394 : // r < 0 means an error occurred
3395 : //
3396 0 : int const e(errno);
3397 :
3398 0 : if(e == EINTR)
3399 : {
3400 : // Note: if the user wants to prevent this error, he should
3401 : // use the snap_signal with the Unix signals that may
3402 : // happen while calling poll().
3403 : //
3404 0 : throw snap_communicator_runtime_error("EINTR occurred while in poll() -- interrupts are not supported yet though");
3405 : }
3406 0 : if(e == EFAULT)
3407 : {
3408 0 : throw snap_communicator_parameter_error("buffer was moved out of our address space?");
3409 : }
3410 0 : if(e == EINVAL)
3411 : {
3412 : // if this is really because nfds is too large then it may be
3413 : // a "soft" error that can be fixed; that being said, my
3414 : // current version is 16K files which frankly when we reach
3415 : // that level we have a problem...
3416 : //
3417 : struct rlimit rl;
3418 0 : getrlimit(RLIMIT_NOFILE, &rl);
3419 0 : throw snap_communicator_parameter_error(QString("too many file fds for poll, limit is currently %1, your kernel top limit is %2")
3420 0 : .arg(rl.rlim_cur)
3421 0 : .arg(rl.rlim_max).toStdString());
3422 : }
3423 0 : if(e == ENOMEM)
3424 : {
3425 0 : throw snap_communicator_runtime_error("poll() failed because of memory");
3426 : }
3427 0 : throw snap_communicator_runtime_error(QString("poll() failed with error %1").arg(e).toStdString());
3428 : }
3429 :
3430 0 : if(r == 0)
3431 : {
3432 : // poll() timed out, just return so the thread can do some
3433 : // additional work
3434 : //
3435 0 : return 0;
3436 : }
3437 :
3438 : // we reach here when there is something to read
3439 : //
3440 0 : if((fd.revents & (POLLIN | POLLPRI)) != 0)
3441 : {
3442 0 : process_read();
3443 : }
3444 : // at this point we do not request POLLOUT and assume that the
3445 : // write() function will never fail
3446 : //
3447 : //if((fd.revents & POLLOUT) != 0)
3448 : //{
3449 : // process_write();
3450 : //}
3451 0 : if((fd.revents & POLLERR) != 0)
3452 : {
3453 0 : process_error();
3454 : }
3455 0 : if((fd.revents & (POLLHUP | POLLRDHUP)) != 0)
3456 : {
3457 0 : process_hup();
3458 : }
3459 0 : if((fd.revents & POLLNVAL) != 0)
3460 : {
3461 0 : process_invalid();
3462 : }
3463 0 : }
3464 : NOTREACHED();
3465 : }
3466 :
3467 :
3468 : /** \brief Pipe connections accept reads.
3469 : *
3470 : * This function returns true meaning that the pipe connection can be
3471 : * used to read data.
3472 : *
3473 : * \return true since a pipe connection is a reader.
3474 : */
3475 0 : bool snap_communicator::snap_inter_thread_message_connection::is_reader() const
3476 : {
3477 0 : return true;
3478 : }
3479 :
3480 :
3481 : /** \brief This function returns the pipe we want to listen on.
3482 : *
3483 : * This function returns the file descriptor of one of the two
3484 : * sockets. The parent process returns the descriptor of socket
3485 : * number 0. The child process returns the descriptor of socket
3486 : * number 1.
3487 : *
3488 : * \note
3489 : * If the close() function was called, this function returns -1.
3490 : *
3491 : * \return A pipe descriptor to listen on with poll().
3492 : */
3493 0 : int snap_communicator::snap_inter_thread_message_connection::get_socket() const
3494 : {
3495 0 : if(f_creator_id == gettid())
3496 : {
3497 0 : return *f_thread_a;
3498 : }
3499 :
3500 0 : return *f_thread_b;
3501 : }
3502 :
3503 :
3504 : /** \brief Read one message from the FIFO.
3505 : *
3506 : * This function reads one message from the FIFO specific to this
3507 : * thread. If the FIFO is empty,
3508 : *
3509 : * The function makes sure to use the correct socket for the calling
3510 : * process (i.e. depending on whether this is the parent or child.)
3511 : *
3512 : * Just like the system write(2) function, errno is set to the error
3513 : * that happened when the function returns -1.
3514 : *
3515 : * \warning
3516 : * At the moment this class does not support the dispatcher
3517 : * extension.
3518 : *
3519 : * \return The number of bytes written to this pipe socket, or -1 on errors.
3520 : */
3521 0 : void snap_communicator::snap_inter_thread_message_connection::process_read()
3522 : {
3523 0 : snap_communicator_message message;
3524 :
3525 0 : bool const is_thread_a(f_creator_id == gettid());
3526 :
3527 : // retrieve the message
3528 : //
3529 0 : bool const got_message((is_thread_a ? f_message_a : f_message_b).pop_front(message, 0));
3530 :
3531 : // "remove" that one object from the semaphore counter
3532 : //
3533 0 : uint64_t value(1);
3534 : #pragma GCC diagnostic push
3535 : #pragma GCC diagnostic ignored "-Wunused-result"
3536 0 : if(read(is_thread_a ? *f_thread_a : *f_thread_b, &value, sizeof(value)) != sizeof(value))
3537 : {
3538 0 : throw snap_communicator_runtime_error("an error occurred while reading from inter-thread eventfd description.");
3539 : }
3540 : #pragma GCC diagnostic pop
3541 :
3542 : // send the message for processing
3543 : // got_message should always be true, but just in case...
3544 : //
3545 0 : if(got_message)
3546 : {
3547 0 : if(is_thread_a)
3548 : {
3549 0 : process_message_a(message);
3550 : }
3551 : else
3552 : {
3553 0 : process_message_b(message);
3554 : }
3555 : }
3556 0 : }
3557 :
3558 :
3559 : /** \brief Send a message to the other end of this connection.
3560 : *
3561 : * This function sends the specified \p message to the thread
3562 : * on the other side of the connection.
3563 : *
3564 : * \note
3565 : * We are not a writer. We directly write to the corresponding
3566 : * thread eventfd() so it can wake up and read the message we
3567 : * just sent. There is only one reason for which the write
3568 : * would not be available, we already sent 2^64-2 messages,
3569 : * which is not likely to happen since memory would not support
3570 : * that many messages.
3571 : *
3572 : * \todo
3573 : * One day we probably will want to be able to have support for a
3574 : * process_write() callback... Maybe we should do the write there.
3575 : * Only we need to know where the write() would have to happen...
3576 : * That's a bit complicated right now for a feature that would not
3577 : * get tested well...
3578 : *
3579 : * \param[in] message The message to send to the other side.
3580 : * \param[in] cache These messages are always cached so this is ignored.
3581 : *
3582 : * \return true of the message was sent, false if it was cached or failed.
3583 : */
3584 0 : bool snap_communicator::snap_inter_thread_message_connection::send_message(snap_communicator_message const & message, bool cache)
3585 : {
3586 0 : NOTUSED(cache);
3587 :
3588 0 : if(f_creator_id == gettid())
3589 : {
3590 0 : f_message_b.push_back(message);
3591 0 : uint64_t const value(1);
3592 0 : return write(*f_thread_b, &value, sizeof(value)) == sizeof(value);
3593 : }
3594 : else
3595 : {
3596 0 : f_message_a.push_back(message);
3597 0 : uint64_t const value(1);
3598 0 : return write(*f_thread_a, &value, sizeof(value)) == sizeof(value);
3599 : }
3600 : }
3601 :
3602 :
3603 :
3604 :
3605 : //////////////////////////
3606 : // Snap Pipe Connection //
3607 : //////////////////////////
3608 :
3609 :
3610 :
3611 : /** \brief Initializes the pipe connection.
3612 : *
3613 : * This function creates the pipes that are to be used to connect
3614 : * two processes (these are actually Unix sockets). These are
3615 : * used whenever you fork() so the parent process can very quickly
3616 : * communicate with the child process using complex messages just
3617 : * like you do between services and Snap Communicator.
3618 : *
3619 : * \warning
3620 : * The sockets are opened in a non-blocking state. However, they are
3621 : * not closed when you call fork() since they are to be used across
3622 : * processes.
3623 : *
3624 : * \warning
3625 : * You need to create a new snap_pipe_connection each time you want
3626 : * to create a new child.
3627 : *
3628 : * \exception snap_communicator_initialization_error
3629 : * This exception is raised if the pipes (socketpair) cannot be created.
3630 : */
3631 0 : snap_communicator::snap_pipe_connection::snap_pipe_connection()
3632 : {
3633 0 : if(socketpair(AF_LOCAL, SOCK_STREAM | SOCK_NONBLOCK, 0, f_socket) != 0)
3634 : {
3635 : // pipe could not be created
3636 0 : throw snap_communicator_initialization_error("somehow the pipes used for a two way pipe connection could not be created.");
3637 : }
3638 :
3639 0 : f_parent = getpid();
3640 0 : }
3641 :
3642 :
3643 : /** \brief Make sure to close the pipes.
3644 : *
3645 : * The destructor ensures that the pipes get closed.
3646 : *
3647 : * They may already have been closed if a broken pipe was detected.
3648 : */
3649 0 : snap_communicator::snap_pipe_connection::~snap_pipe_connection()
3650 : {
3651 0 : close();
3652 0 : }
3653 :
3654 :
3655 : /** \brief Read data from this pipe connection.
3656 : *
3657 : * This function reads up to count bytes from this pipe connection.
3658 : *
3659 : * The function makes sure to use the correct socket for the calling
3660 : * process (i.e. depending on whether this is the parent or child.)
3661 : *
3662 : * Just like the system read(2) function, errno is set to the error
3663 : * that happened when the function returns -1.
3664 : *
3665 : * \param[in] buf A pointer to a buffer of data.
3666 : * \param[in] count The number of bytes to read from the pipe connection.
3667 : *
3668 : * \return The number of bytes read from this pipe socket, or -1 on errors.
3669 : */
3670 0 : ssize_t snap_communicator::snap_pipe_connection::read(void * buf, size_t count)
3671 : {
3672 0 : int const s(get_socket());
3673 0 : if(s == -1)
3674 : {
3675 0 : errno = EBADF;
3676 0 : return -1;
3677 : }
3678 0 : return ::read(s, buf, count);
3679 : }
3680 :
3681 :
3682 : /** \brief Write data to this pipe connection.
3683 : *
3684 : * This function writes count bytes to this pipe connection.
3685 : *
3686 : * The function makes sure to use the correct socket for the calling
3687 : * process (i.e. depending on whether this is the parent or child.)
3688 : *
3689 : * Just like the system write(2) function, errno is set to the error
3690 : * that happened when the function returns -1.
3691 : *
3692 : * \param[in] buf A pointer to a buffer of data.
3693 : * \param[in] count The number of bytes to write to the pipe connection.
3694 : *
3695 : * \return The number of bytes written to this pipe socket, or -1 on errors.
3696 : */
3697 0 : ssize_t snap_communicator::snap_pipe_connection::write(void const * buf, size_t count)
3698 : {
3699 0 : int const s(get_socket());
3700 0 : if(s == -1)
3701 : {
3702 0 : errno = EBADF;
3703 0 : return -1;
3704 : }
3705 0 : if(buf != nullptr && count > 0)
3706 : {
3707 0 : return ::write(s, buf, count);
3708 : }
3709 0 : return 0;
3710 : }
3711 :
3712 :
3713 : /** \brief Close the sockets.
3714 : *
3715 : * This function closes the pair of sockets managed by this
3716 : * pipe connection object.
3717 : *
3718 : * After this call, the pipe connection is closed and cannot be
3719 : * used anymore. The read and write functions will return immediately
3720 : * if called.
3721 : */
3722 0 : void snap_communicator::snap_pipe_connection::close()
3723 : {
3724 0 : if(f_socket[0] != -1)
3725 : {
3726 0 : ::close(f_socket[0]);
3727 0 : ::close(f_socket[1]);
3728 0 : f_socket[0] = -1;
3729 0 : f_socket[1] = -1;
3730 : }
3731 0 : }
3732 :
3733 :
3734 : /** \brief Pipe connections accept reads.
3735 : *
3736 : * This function returns true meaning that the pipe connection can be
3737 : * used to read data.
3738 : *
3739 : * \return true since a pipe connection is a reader.
3740 : */
3741 0 : bool snap_communicator::snap_pipe_connection::is_reader() const
3742 : {
3743 0 : return true;
3744 : }
3745 :
3746 :
3747 : /** \brief This function returns the pipe we want to listen on.
3748 : *
3749 : * This function returns the file descriptor of one of the two
3750 : * sockets. The parent process returns the descriptor of socket
3751 : * number 0. The child process returns the descriptor of socket
3752 : * number 1.
3753 : *
3754 : * \note
3755 : * If the close() function was called, this function returns -1.
3756 : *
3757 : * \return A pipe descriptor to listen on with poll().
3758 : */
3759 0 : int snap_communicator::snap_pipe_connection::get_socket() const
3760 : {
3761 0 : if(f_parent == getpid())
3762 : {
3763 0 : return f_socket[0];
3764 : }
3765 :
3766 0 : return f_socket[1];
3767 : }
3768 :
3769 :
3770 :
3771 :
3772 : /////////////////////////////////
3773 : // Snap Pipe Buffer Connection //
3774 : /////////////////////////////////
3775 :
3776 :
3777 :
3778 :
3779 : /** \brief Pipe connections accept writes.
3780 : *
3781 : * This function returns true when there is some data in the pipe
3782 : * connection buffer meaning that the pipe connection needs to
3783 : * send data to the other side of the pipe.
3784 : *
3785 : * \return true if some data has to be written to the pipe.
3786 : */
3787 0 : bool snap_communicator::snap_pipe_buffer_connection::is_writer() const
3788 : {
3789 0 : return get_socket() != -1 && !f_output.empty();
3790 : }
3791 :
3792 :
3793 : /** \brief Write the specified data to the pipe buffer.
3794 : *
3795 : * This function writes the data specified by \p data to the pipe buffer.
3796 : * Note that the data is not sent immediately. This will only happen
3797 : * when the Snap Communicator loop is re-entered.
3798 : *
3799 : * \param[in] data The pointer to the data to write to the pipe.
3800 : * \param[in] length The size of the data buffer.
3801 : *
3802 : * \return The number of bytes written. The function returns 0 when no
3803 : * data can be written to that connection (i.e. it was already
3804 : * closed or data is a null pointer.)
3805 : */
3806 0 : ssize_t snap_communicator::snap_pipe_buffer_connection::write(void const * data, size_t length)
3807 : {
3808 0 : if(get_socket() == -1)
3809 : {
3810 0 : errno = EBADF;
3811 0 : return -1;
3812 : }
3813 :
3814 0 : if(data != nullptr && length > 0)
3815 : {
3816 0 : char const * d(reinterpret_cast<char const *>(data));
3817 0 : f_output.insert(f_output.end(), d, d + length);
3818 0 : return length;
3819 : }
3820 :
3821 0 : return 0;
3822 : }
3823 :
3824 :
3825 : /** \brief Read data that was received on this pipe.
3826 : *
3827 : * This function is used to read data whenever the process on
3828 : * the other side sent us a message.
3829 : */
3830 0 : void snap_communicator::snap_pipe_buffer_connection::process_read()
3831 : {
3832 0 : if(get_socket() != -1)
3833 : {
3834 : // we could read one character at a time until we get a '\n'
3835 : // but since we have a non-blocking socket we can read as
3836 : // much as possible and then check for a '\n' and keep
3837 : // any extra data in a cache.
3838 : //
3839 0 : int count_lines(0);
3840 0 : int64_t const date_limit(snap_communicator::get_current_date() + f_processing_time_limit);
3841 0 : std::vector<char> buffer;
3842 0 : buffer.resize(1024);
3843 : for(;;)
3844 : {
3845 0 : errno = 0;
3846 0 : ssize_t const r(read(&buffer[0], buffer.size()));
3847 0 : if(r > 0)
3848 : {
3849 0 : for(ssize_t position(0); position < r; )
3850 : {
3851 0 : std::vector<char>::const_iterator it(std::find(buffer.begin() + position, buffer.begin() + r, '\n'));
3852 0 : if(it == buffer.begin() + r)
3853 : {
3854 : // no newline, just add the whole thing
3855 0 : f_line += std::string(&buffer[position], r - position);
3856 0 : break; // do not waste time, we know we are done
3857 : }
3858 :
3859 : // retrieve the characters up to the newline
3860 : // character and process the line
3861 : //
3862 0 : f_line += std::string(&buffer[position], it - buffer.begin() - position);
3863 0 : process_line(QString::fromUtf8(f_line.c_str()));
3864 0 : ++count_lines;
3865 :
3866 : // done with that line
3867 : //
3868 0 : f_line.clear();
3869 :
3870 : // we had a newline, we may still have some data
3871 : // in that buffer; (+1 to skip the '\n' itself)
3872 : //
3873 0 : position = it - buffer.begin() + 1;
3874 : }
3875 :
3876 : // when we reach here all the data read in `buffer` is
3877 : // now either fully processed or in f_line
3878 : //
3879 : // TODO: change the way this works so we can test the
3880 : // limit after each process_line() call
3881 : //
3882 0 : if(count_lines >= f_event_limit
3883 0 : || snap_communicator::get_current_date() >= date_limit)
3884 : {
3885 : // we reach one or both limits, stop processing so
3886 : // the other events have a chance to run
3887 : //
3888 0 : break;
3889 : }
3890 : }
3891 0 : else if(r == 0 || errno == 0 || errno == EAGAIN || errno == EWOULDBLOCK)
3892 : {
3893 : // no more data available at this time
3894 : //
3895 : break;
3896 : }
3897 : else //if(r < 0)
3898 : {
3899 : // this happens all the time (i.e. another process quits)
3900 : // so we make it a debug and not a warning or an error...
3901 : //
3902 0 : int const e(errno);
3903 0 : SNAP_LOG_DEBUG("an error occurred while reading from socket (errno: ")(e)(" -- ")(strerror(e))(").");
3904 0 : process_error();
3905 0 : return;
3906 : }
3907 0 : }
3908 : }
3909 : //else -- TBD: should we at least log an error when process_read() is called without a valid socket?
3910 :
3911 : // process the next level
3912 0 : snap_pipe_connection::process_read();
3913 : }
3914 :
3915 :
3916 : /** \brief Write as much data as we can to the pipe.
3917 : *
3918 : * This function writes the data that was cached in our f_output
3919 : * buffer to the pipe, as much as possible, then it returns.
3920 : *
3921 : * The is_writer() function takes care of returning true if more
3922 : * data is present in the f_output buffer and thus the process_write()
3923 : * needs to be called again.
3924 : *
3925 : * Once the write buffer goes empty, this function calls the
3926 : * process_empty_buffer() callback.
3927 : */
3928 0 : void snap_communicator::snap_pipe_buffer_connection::process_write()
3929 : {
3930 0 : if(get_socket() != -1)
3931 : {
3932 0 : errno = 0;
3933 0 : ssize_t const r(snap_pipe_connection::write(&f_output[f_position], f_output.size() - f_position));
3934 0 : if(r > 0)
3935 : {
3936 : // some data was written
3937 0 : f_position += r;
3938 0 : if(f_position >= f_output.size())
3939 : {
3940 0 : f_output.clear();
3941 0 : f_position = 0;
3942 0 : process_empty_buffer();
3943 : }
3944 : }
3945 0 : else if(r != 0 && errno != 0 && errno != EAGAIN && errno != EWOULDBLOCK)
3946 : {
3947 : // connection is considered bad, get rid of it
3948 : //
3949 0 : int const e(errno);
3950 0 : SNAP_LOG_ERROR("an error occurred while writing to socket of \"")(f_name)("\" (errno: ")(e)(" -- ")(strerror(e))(").");
3951 0 : process_error();
3952 0 : return;
3953 : }
3954 : }
3955 : //else -- TBD: should we generate an error when the socket is not valid?
3956 :
3957 : // process next level too
3958 0 : snap_pipe_connection::process_write();
3959 : }
3960 :
3961 :
3962 : /** \brief The process received a hanged up pipe.
3963 : *
3964 : * The pipe on the other end was closed, somehow.
3965 : */
3966 0 : void snap_communicator::snap_pipe_buffer_connection::process_hup()
3967 : {
3968 0 : close();
3969 :
3970 0 : snap_pipe_connection::process_hup();
3971 0 : }
3972 :
3973 :
3974 :
3975 :
3976 :
3977 :
3978 : //////////////////////////////////
3979 : // Snap Pipe Message Connection //
3980 : //////////////////////////////////
3981 :
3982 :
3983 :
3984 : /** \brief Send a message.
3985 : *
3986 : * This function sends a message to the process on the other side
3987 : * of this pipe connection.
3988 : *
3989 : * \exception snap_communicator_runtime_error
3990 : * This function throws this exception if the write() to the pipe
3991 : * fails to write the entire message. This should only happen if
3992 : * the pipe gets severed.
3993 : *
3994 : * \param[in] message The message to be sent.
3995 : * \param[in] cache Whether to cache the message if there is no connection.
3996 : * (Ignore because a pipe has to always be there until
3997 : * closed and then it can't be reopened.)
3998 : *
3999 : * \return Always true, although if an error occurs the function throws.
4000 : */
4001 0 : bool snap_communicator::snap_pipe_message_connection::send_message(snap_communicator_message const & message, bool cache)
4002 : {
4003 0 : NOTUSED(cache);
4004 :
4005 : // transform the message to a string and write to the socket
4006 : // the writing is asynchronous so the message is saved in a cache
4007 : // and transferred only later when the run() loop is hit again
4008 : //
4009 0 : QString const msg(message.to_message());
4010 0 : QByteArray const utf8(msg.toUtf8());
4011 0 : std::string buf(utf8.data(), utf8.size());
4012 0 : buf += "\n";
4013 0 : return write(buf.c_str(), buf.length()) == static_cast<ssize_t>(buf.length());
4014 : }
4015 :
4016 :
4017 : /** \brief Process a line (string) just received.
4018 : *
4019 : * The function parses the line as a message (snap_communicator_message)
4020 : * and then calls the process_message() function if the line was valid.
4021 : *
4022 : * \param[in] line The line of text that was just read.
4023 : */
4024 0 : void snap_communicator::snap_pipe_message_connection::process_line(QString const & line)
4025 : {
4026 0 : if(line.isEmpty())
4027 : {
4028 0 : return;
4029 : }
4030 :
4031 0 : snap_communicator_message message;
4032 0 : if(message.from_message(line))
4033 : {
4034 0 : dispatch_message(message);
4035 : }
4036 : else
4037 : {
4038 : // TODO: what to do here? This could be that the version changed
4039 : // and the messages are not compatible anymore.
4040 : //
4041 0 : SNAP_LOG_ERROR("snap_communicator::snap_pipe_message_connection::process_line() was asked to process an invalid message (")(line)(")");
4042 : }
4043 : }
4044 :
4045 :
4046 :
4047 :
4048 :
4049 :
4050 : //////////////////////////////////
4051 : // Snap File Changed Connection //
4052 : //////////////////////////////////
4053 :
4054 :
4055 :
4056 :
4057 :
4058 0 : snap_communicator::snap_file_changed::event_t::event_t(std::string const & watched_path
4059 : , event_mask_t events
4060 0 : , std::string const & filename)
4061 : : f_watched_path(watched_path)
4062 : , f_events(events)
4063 0 : , f_filename(filename)
4064 : {
4065 0 : if(f_watched_path.empty())
4066 : {
4067 0 : throw snap_communicator_initialization_error("a snap_file_changed watch path cannot be the empty string.");
4068 : }
4069 :
4070 0 : if(f_events == SNAP_FILE_CHANGED_EVENT_NO_EVENTS)
4071 : {
4072 0 : throw snap_communicator_initialization_error("a snap_file_changed events parameter cannot be 0.");
4073 : }
4074 0 : }
4075 :
4076 :
4077 0 : std::string const & snap_communicator::snap_file_changed::event_t::get_watched_path() const
4078 : {
4079 0 : return f_watched_path;
4080 : }
4081 :
4082 :
4083 0 : snap_communicator::snap_file_changed::event_mask_t snap_communicator::snap_file_changed::event_t::get_events() const
4084 : {
4085 0 : return f_events;
4086 : }
4087 :
4088 :
4089 0 : std::string const & snap_communicator::snap_file_changed::event_t::get_filename() const
4090 : {
4091 0 : return f_filename;
4092 : }
4093 :
4094 :
4095 0 : bool snap_communicator::snap_file_changed::event_t::operator < (event_t const & rhs) const
4096 : {
4097 0 : return f_watched_path < rhs.f_watched_path;
4098 : }
4099 :
4100 :
4101 0 : snap_communicator::snap_file_changed::watch_t::watch_t()
4102 : {
4103 0 : }
4104 :
4105 :
4106 0 : snap_communicator::snap_file_changed::watch_t::watch_t(std::string const & watched_path, event_mask_t events, uint32_t add_flags)
4107 : : f_watched_path(watched_path)
4108 : , f_events(events)
4109 0 : , f_mask(events_to_mask(events) | add_flags | IN_EXCL_UNLINK)
4110 : {
4111 0 : }
4112 :
4113 :
4114 0 : void snap_communicator::snap_file_changed::watch_t::add_watch(int inotify)
4115 : {
4116 0 : f_watch = inotify_add_watch(inotify, f_watched_path.c_str(), f_mask);
4117 0 : if(f_watch == -1)
4118 : {
4119 0 : int const e(errno);
4120 0 : SNAP_LOG_WARNING("inotify_add_watch() returned an error (errno: ")(e)(" -- ")(strerror(e))(").");
4121 :
4122 : // it did not work
4123 : //
4124 0 : throw snap_communicator_initialization_error("inotify_add_watch() failed");
4125 : }
4126 0 : }
4127 :
4128 :
4129 0 : void snap_communicator::snap_file_changed::watch_t::merge_watch(int inotify, event_mask_t const events)
4130 : {
4131 0 : f_mask |= events_to_mask(events);
4132 :
4133 : // The documentation is not 100% clear about an update so for now
4134 : // I remove the existing watch and create a new one... it should
4135 : // not happen very often anyway
4136 : //
4137 0 : if(f_watch != -1)
4138 : {
4139 0 : remove_watch(inotify);
4140 : }
4141 :
4142 0 : f_watch = inotify_add_watch(inotify, f_watched_path.c_str(), f_mask);
4143 0 : if(f_watch == -1)
4144 : {
4145 0 : int const e(errno);
4146 0 : SNAP_LOG_WARNING("inotify_raddwatch() returned an error (errno: ")(e)(" -- ")(strerror(e))(").");
4147 :
4148 : // it did not work
4149 : //
4150 0 : throw snap_communicator_initialization_error("inotify_add_watch() failed");
4151 : }
4152 0 : }
4153 :
4154 :
4155 0 : void snap_communicator::snap_file_changed::watch_t::remove_watch(int inotify)
4156 : {
4157 0 : if(f_watch != -1)
4158 : {
4159 0 : int const r(inotify_rm_watch(inotify, f_watch));
4160 0 : if(r != 0)
4161 : {
4162 : // we output the error if one occurs, but go on as if nothing
4163 : // happened
4164 : //
4165 0 : int const e(errno);
4166 0 : SNAP_LOG_WARNING("inotify_rm_watch() returned an error (errno: ")(e)(" -- ")(strerror(e))(").");
4167 : }
4168 :
4169 : // we can remove it just once
4170 : //
4171 0 : f_watch = -1;
4172 : }
4173 0 : }
4174 :
4175 :
4176 0 : snap_communicator::snap_file_changed::snap_file_changed()
4177 0 : : f_inotify(inotify_init1(IN_NONBLOCK | IN_CLOEXEC))
4178 : //, f_watches() -- auto-init
4179 : {
4180 0 : if(f_inotify == -1)
4181 : {
4182 0 : throw snap_communicator_initialization_error("snap_file_changed: inotify_init1() failed.");
4183 : }
4184 0 : }
4185 :
4186 :
4187 0 : snap_communicator::snap_file_changed::~snap_file_changed()
4188 : {
4189 : // watch_t are not RAII because we copy them in maps...
4190 : // so we have to "manually" clean up here, but making them RAII would
4191 : // mean creating an impl and thus hiding the problem at a different
4192 : // level which is less effective...
4193 : //
4194 0 : for(auto & w : f_watches)
4195 : {
4196 0 : w.second.remove_watch(f_inotify);
4197 : }
4198 :
4199 0 : close(f_inotify);
4200 0 : }
4201 :
4202 :
4203 : /** \brief Try to merge a new watch.
4204 : *
4205 : * If you attempt to watch the same path again, instead of adding a new watch,
4206 : * we instead want to merge it. This is important because the system
4207 : * does not generate a new watch when you do that.
4208 : *
4209 : * In this case, the \p events parameter is viewed as parameters being
4210 : * added to the watched. If you want to replace the previous watch instead,
4211 : * make sure to first remove it, then re-add it with new flags as required.
4212 : *
4213 : * \param[in] watched_path The path the user wants to watch.
4214 : * \param[in] events The events being added to the watch.
4215 : */
4216 0 : bool snap_communicator::snap_file_changed::merge_watch(std::string const & watched_path, event_mask_t const events)
4217 : {
4218 : auto const & wevent(std::find_if(
4219 : f_watches.begin()
4220 : , f_watches.end()
4221 0 : , [&watched_path](auto const & w)
4222 0 : {
4223 0 : return w.second.f_watched_path == watched_path;
4224 0 : }));
4225 0 : if(wevent == f_watches.end())
4226 : {
4227 : // not found
4228 : //
4229 0 : return false;
4230 : }
4231 :
4232 0 : wevent->second.merge_watch(f_inotify, events);
4233 :
4234 0 : return true;
4235 : }
4236 :
4237 :
4238 0 : void snap_communicator::snap_file_changed::watch_file(std::string const & watched_path, event_mask_t const events)
4239 : {
4240 0 : if(!merge_watch(watched_path, events))
4241 : {
4242 0 : watch_t watch(watched_path, events, 0);
4243 0 : watch.add_watch(f_inotify);
4244 0 : f_watches[watch.f_watch] = watch;
4245 : }
4246 0 : }
4247 :
4248 :
4249 0 : void snap_communicator::snap_file_changed::watch_symlink(std::string const & watched_path, event_mask_t const events)
4250 : {
4251 0 : if(!merge_watch(watched_path, events))
4252 : {
4253 0 : watch_t watch(watched_path, events, IN_DONT_FOLLOW);
4254 0 : watch.add_watch(f_inotify);
4255 0 : f_watches[watch.f_watch] = watch;
4256 : }
4257 0 : }
4258 :
4259 :
4260 0 : void snap_communicator::snap_file_changed::watch_directory(std::string const & watched_path, event_mask_t const events)
4261 : {
4262 0 : if(!merge_watch(watched_path, events))
4263 : {
4264 0 : watch_t watch(watched_path, events, IN_ONLYDIR);
4265 0 : watch.add_watch(f_inotify);
4266 0 : f_watches[watch.f_watch] = watch;
4267 : }
4268 0 : }
4269 :
4270 :
4271 0 : void snap_communicator::snap_file_changed::stop_watch(std::string const & watched_path)
4272 : {
4273 : // because of the merge, even though the watched_path is not the
4274 : // index of our map, it will be unique so we really only need to
4275 : // find one such entry
4276 : //
4277 : auto wevent(std::find_if(
4278 : f_watches.begin()
4279 : , f_watches.end()
4280 0 : , [&](auto & w)
4281 : {
4282 0 : return w.second.f_watched_path == watched_path;
4283 0 : }));
4284 :
4285 0 : if(wevent != f_watches.end())
4286 : {
4287 0 : wevent->second.remove_watch(f_inotify);
4288 0 : f_watches.erase(wevent);
4289 : }
4290 0 : }
4291 :
4292 :
4293 0 : bool snap_communicator::snap_file_changed::is_reader() const
4294 : {
4295 0 : return true;
4296 : }
4297 :
4298 :
4299 0 : int snap_communicator::snap_file_changed::get_socket() const
4300 : {
4301 : // if we did not add any watches, avoid adding another fd to the poll()
4302 : //
4303 0 : if(f_watches.empty())
4304 : {
4305 0 : return -1;
4306 : }
4307 :
4308 0 : return f_inotify;
4309 : }
4310 :
4311 :
4312 0 : void snap_communicator::snap_file_changed::set_enable(bool enabled)
4313 : {
4314 0 : snap_connection::set_enable(enabled);
4315 :
4316 : // TODO: inotify will continue to send us messages when disabled
4317 : // and that's a total of 16K of messages! That's a lot of
4318 : // memory wasted if the connection gets disabled for a long
4319 : // amount of time; what we want to do instead is disconnect
4320 : // completely on a disable and reconnect on a re-enable
4321 0 : }
4322 :
4323 :
4324 0 : void snap_communicator::snap_file_changed::process_read()
4325 : {
4326 : // were notifications closed in between?
4327 : //
4328 0 : if(f_inotify == -1)
4329 : {
4330 0 : return;
4331 : }
4332 :
4333 : // WARNING: this is about 4Kb of buffer on the stack
4334 : // it is NOT 256 structures because all events with a name
4335 : // have the name included in themselves and that "eats"
4336 : // space in the next structure
4337 : //
4338 : struct inotify_event buffer[256];
4339 :
4340 : for(;;)
4341 : {
4342 : // read a few messages in one call
4343 : //
4344 0 : ssize_t const len(read(f_inotify, buffer, sizeof(buffer)));
4345 0 : if(len <= 0)
4346 : {
4347 0 : if(len == 0
4348 0 : || errno == EAGAIN)
4349 : {
4350 : // reached the end of the current queue
4351 : //
4352 0 : return;
4353 : }
4354 :
4355 : // TODO: close the inotify on errors?
4356 0 : int const e(errno);
4357 0 : SNAP_LOG_ERROR("an error occurred while reading from inotify (errno: ")(e)(" -- ")(strerror(e))(").");
4358 0 : process_error();
4359 0 : return;
4360 : }
4361 : // convert the buffer to a character pointer to make it easier to
4362 : // move the pointer to the next structure
4363 : //
4364 0 : char const * start(reinterpret_cast<char const *>(buffer));
4365 0 : char const * end(start + len);
4366 0 : while(start < end)
4367 : {
4368 : // get the pointer to the current inotify event
4369 : //
4370 0 : struct inotify_event const & ievent(*reinterpret_cast<struct inotify_event const *>(start));
4371 0 : if(start + sizeof(struct inotify_event) + ievent.len > end)
4372 : {
4373 : // unless there is a huge bug in the inotify implementation
4374 : // this exception should never happen
4375 : //
4376 0 : throw snap_communicator_unexpected_data("somehow the size of this ievent does not match what we just read.");
4377 : }
4378 :
4379 : // convert the inotify even in one of our events
4380 : //
4381 0 : auto const & wevent(f_watches.find(ievent.wd));
4382 0 : if(wevent != f_watches.end())
4383 : {
4384 : // XXX: we need to know whether this flag can appear with
4385 : // others (i.e. could we at the same time have a message
4386 : // saying there was a read and a queue overflow?); if
4387 : // so, then we need to run the else part even on
4388 : // overflows
4389 : //
4390 0 : if((ievent.mask & IN_Q_OVERFLOW) != 0)
4391 : {
4392 0 : SNAP_LOG_ERROR("Received an event queue overflow error.");
4393 : }
4394 : else
4395 : {
4396 0 : event_t const watch_event(wevent->second.f_watched_path
4397 0 : , mask_to_events(ievent.mask)
4398 0 : , std::string(ievent.name, ievent.len));
4399 :
4400 0 : process_event(watch_event);
4401 :
4402 : // if the event received included IN_IGNORED then we need
4403 : // to remove that watch
4404 : //
4405 0 : if((ievent.mask & IN_IGNORED) != 0)
4406 : {
4407 : // before losing the wevent, make sure we disconnect
4408 : // from the OS version
4409 : //
4410 0 : const_cast<watch_t &>(wevent->second).remove_watch(f_inotify);
4411 0 : f_watches.erase(ievent.wd);
4412 0 : f_watches.erase(wevent);
4413 : }
4414 : }
4415 : }
4416 : else
4417 : {
4418 : // we do not know about this notifier, close it
4419 : // (this should never happen... unless we read the queue
4420 : // for a watch that had more events and we had not read it
4421 : // yet, in that case the watch was certainly already
4422 : // removed... it should not hurt to re-remove it.)
4423 : //
4424 0 : inotify_rm_watch(f_inotify, ievent.wd);
4425 : }
4426 :
4427 : // move the pointer to the next stucture until we reach 'end'
4428 : //
4429 0 : start += sizeof(struct inotify_event) + ievent.len;
4430 : }
4431 0 : }
4432 : }
4433 :
4434 :
4435 0 : uint32_t snap_communicator::snap_file_changed::events_to_mask(event_mask_t const events)
4436 : {
4437 0 : uint32_t mask(0);
4438 :
4439 0 : if((events & SNAP_FILE_CHANGED_EVENT_ATTRIBUTES) != 0)
4440 : {
4441 0 : mask |= IN_ATTRIB;
4442 : }
4443 :
4444 0 : if((events & SNAP_FILE_CHANGED_EVENT_READ) != 0)
4445 : {
4446 0 : mask |= IN_ACCESS;
4447 : }
4448 :
4449 0 : if((events & SNAP_FILE_CHANGED_EVENT_WRITE) != 0)
4450 : {
4451 0 : mask |= IN_MODIFY;
4452 : }
4453 :
4454 0 : if((events & SNAP_FILE_CHANGED_EVENT_CREATED) != 0)
4455 : {
4456 0 : mask |= IN_CREATE | IN_MOVED_FROM | IN_MOVE_SELF;
4457 : }
4458 :
4459 0 : if((events & SNAP_FILE_CHANGED_EVENT_DELETED) != 0)
4460 : {
4461 0 : mask |= IN_DELETE | IN_DELETE_SELF | IN_MOVED_TO | IN_MOVE_SELF;
4462 : }
4463 :
4464 0 : if((events & SNAP_FILE_CHANGED_EVENT_ACCESS) != 0)
4465 : {
4466 0 : mask |= IN_OPEN | IN_CLOSE_WRITE | IN_CLOSE_NOWRITE;
4467 : }
4468 :
4469 0 : if(mask == 0)
4470 : {
4471 0 : throw snap_communicator_initialization_error("invalid snap_file_changed events parameter, it was not changed to any IN_... flags.");
4472 : }
4473 :
4474 0 : return mask;
4475 : }
4476 :
4477 :
4478 0 : snap_communicator::snap_file_changed::event_mask_t snap_communicator::snap_file_changed::mask_to_events(uint32_t const mask)
4479 : {
4480 0 : event_mask_t events(0);
4481 :
4482 0 : if((mask & IN_ATTRIB) != 0)
4483 : {
4484 0 : events |= SNAP_FILE_CHANGED_EVENT_ATTRIBUTES;
4485 : }
4486 :
4487 0 : if((mask & IN_ACCESS) != 0)
4488 : {
4489 0 : events |= SNAP_FILE_CHANGED_EVENT_READ;
4490 : }
4491 :
4492 0 : if((mask & IN_MODIFY) != 0)
4493 : {
4494 0 : events |= SNAP_FILE_CHANGED_EVENT_WRITE;
4495 : }
4496 :
4497 0 : if((mask & (IN_CREATE | IN_MOVED_FROM)) != 0)
4498 : {
4499 0 : events |= SNAP_FILE_CHANGED_EVENT_CREATED;
4500 : }
4501 :
4502 0 : if((mask & (IN_DELETE | IN_DELETE_SELF | IN_MOVED_TO)) != 0)
4503 : {
4504 0 : events |= SNAP_FILE_CHANGED_EVENT_DELETED;
4505 : }
4506 :
4507 0 : if((mask & (IN_OPEN | IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)) != 0)
4508 : {
4509 0 : events |= SNAP_FILE_CHANGED_EVENT_ACCESS;
4510 : }
4511 :
4512 : // return flags only
4513 : //
4514 0 : if((mask & IN_ISDIR) != 0)
4515 : {
4516 0 : events |= SNAP_FILE_CHANGED_EVENT_DIRECTORY;
4517 : }
4518 :
4519 0 : if((mask & IN_IGNORED) != 0)
4520 : {
4521 0 : events |= SNAP_FILE_CHANGED_EVENT_GONE;
4522 : }
4523 :
4524 0 : if((mask & IN_UNMOUNT) != 0)
4525 : {
4526 0 : events |= SNAP_FILE_CHANGED_EVENT_UNMOUNTED;
4527 : }
4528 :
4529 0 : return events;
4530 : }
4531 :
4532 :
4533 :
4534 :
4535 :
4536 :
4537 :
4538 : /////////////////////////////////////
4539 : // Snap File Descriptor Connection //
4540 : /////////////////////////////////////
4541 :
4542 :
4543 : /** \brief Initializes the file descriptor connection.
4544 : *
4545 : * This function creates a connection based on an existing file descriptor.
4546 : * This is a class used to handle existing pipes or socket (opposed to other
4547 : * implementations which create a pipe, open a socket, etc.) It is especially
4548 : * useful if you want to listen to stdin and stdout. Use the `fileno()`
4549 : * function to get the file descriptor and create a `snap_fd_connection`
4550 : * object what that descriptor.
4551 : *
4552 : * The mode parameter defines how you are to use the file descriptor. In
4553 : * other words, a socket that is read/write could be added to two different
4554 : * `snap_fd_connection` objects: one to read and one to write, instead of
4555 : * a single read/write object.
4556 : *
4557 : * Note that although you can say it's only going to be used in READ or
4558 : * in WRITE mode, in all cases, make sure that the file is readable before
4559 : * specifying READ or RW, and make sure that the file is writable before
4560 : * specifying WRITE or RW.
4561 : *
4562 : * \note
4563 : * It is important to note that the lifetime of the file desriptor is
4564 : * not managed by this object. You are responsible for the descriptor to
4565 : * stay valid as long as the connection is added to the snap_communicator
4566 : * list of connections. If you want to close the connection, please first
4567 : * remove the connection from the snap_communicator, destroy the connection,
4568 : * then close the file descriptor.
4569 : *
4570 : * \note
4571 : * It is possible to pass -1 (or any negative number) as the file
4572 : * descriptor. In that case it is interpreted as "not a valid
4573 : * file descriptor."
4574 : *
4575 : * \warning
4576 : * If you are to use a read() or a write() that may block, make sure to
4577 : * first set your file descriptor in non-blocking mode. If that's not
4578 : * possible, then make sure to read or write only one byte at a time.
4579 : * The loop will be slower, but you will avoid blocks which would
4580 : * prevent the rest of the software from getting their own events.
4581 : *
4582 : * \param[in] fd The file descriptor to handle.
4583 : * \param[in] mode The mode this descriptor is to be used by the connection.
4584 : */
4585 0 : snap_communicator::snap_fd_connection::snap_fd_connection(int fd, mode_t mode)
4586 : : f_fd(fd)
4587 0 : , f_mode(mode)
4588 : {
4589 0 : }
4590 :
4591 :
4592 : /** \brief Used to close the file descriptor.
4593 : *
4594 : * This function closes the file descript of this connection.
4595 : *
4596 : * The function is not called automatically as we mention in the
4597 : * constructor, the function cannot just close the file descriptor
4598 : * on its own so it is up to you to call this function or not.
4599 : * It is not mandatory.
4600 : *
4601 : * The function does not verify to know whether the file descriptor
4602 : * was already closed outside of this function. Although it is safe
4603 : * to call this function multiple times, if you close the file
4604 : * descriptor with other means, then calling this function may
4605 : * end up closing another file...
4606 : */
4607 0 : void snap_communicator::snap_fd_connection::close()
4608 : {
4609 0 : if(f_fd != -1)
4610 : {
4611 0 : ::close(f_fd);
4612 0 : f_fd = -1;
4613 : }
4614 0 : }
4615 :
4616 :
4617 : /** \brief Used to mark the file descriptor as closed.
4618 : *
4619 : * This function marks the file descriptor as closed. Whether it is,
4620 : * is your own concern. This is used to avoid a double close in
4621 : * case some other function ends up calling close() and yet you
4622 : * somehow closed the file descriptor (i.e. fclose(f) will do that
4623 : * on you...)
4624 : *
4625 : * \code
4626 : * ...
4627 : * fclose(f);
4628 : * // tell connection that we've close the connection fd
4629 : * c->mark_closed();
4630 : * ...
4631 : * \endcode
4632 : *
4633 : * Note that if you do not have any other copy of the file descriptor
4634 : * and you call mark_closed() instead of close(), you will leak that
4635 : * file descriptor.
4636 : */
4637 0 : void snap_communicator::snap_fd_connection::mark_closed()
4638 : {
4639 0 : f_fd = -1;
4640 0 : }
4641 :
4642 :
4643 : /** \brief Check whether this connection is a reader.
4644 : *
4645 : * If you created this file descriptor connection as a reader, then this
4646 : * function returns true.
4647 : *
4648 : * A reader has a mode of FD_MODE_READ or FD_MODE_RW.
4649 : *
4650 : * \return true if the connection is considered to be a reader.
4651 : */
4652 0 : bool snap_communicator::snap_fd_connection::is_reader() const
4653 : {
4654 0 : return f_mode != mode_t::FD_MODE_WRITE && get_socket() != -1;
4655 : }
4656 :
4657 :
4658 : /** \brief Check whether this connection is a writer.
4659 : *
4660 : * If you created this file descriptor connection as a writer, then this
4661 : * function returns true.
4662 : *
4663 : * A writer has a mode of FD_MODE_WRITE or FD_MODE_RW.
4664 : *
4665 : * \return true if the connection is considered to be a writer.
4666 : */
4667 0 : bool snap_communicator::snap_fd_connection::is_writer() const
4668 : {
4669 0 : return f_mode != mode_t::FD_MODE_READ && get_socket() != -1;
4670 : }
4671 :
4672 :
4673 : /** \brief Return the file descriptor ("socket").
4674 : *
4675 : * This function returns the file descriptor specified in the constructor.
4676 : *
4677 : * The current naming convention comes from the fact that the library
4678 : * was first created for sockets.
4679 : *
4680 : * \return The connection file descriptor.
4681 : */
4682 0 : int snap_communicator::snap_fd_connection::get_socket() const
4683 : {
4684 0 : return f_fd;
4685 : }
4686 :
4687 :
4688 : /** \brief Read up data from the file descriptor.
4689 : *
4690 : * This function attempts to read up to \p count bytes of data from
4691 : * this file descriptor. If that works to some extend, then the
4692 : * data read will be saved in \p buf and the function returns
4693 : * the number of bytes read.
4694 : *
4695 : * If no data can be read, the function may return -1 or 0.
4696 : *
4697 : * The file descriptor must be a reader or the function will always fail.
4698 : *
4699 : * \param[in] buf The buffer where the data read is saved.
4700 : * \param[in] count The maximum number of bytes to read at once.
4701 : */
4702 0 : ssize_t snap_communicator::snap_fd_connection::read(void * buf, size_t count)
4703 : {
4704 0 : if(!snap_fd_connection::is_reader())
4705 : {
4706 0 : errno = EBADF;
4707 0 : return -1;
4708 : }
4709 :
4710 0 : return ::read(f_fd, buf, count);
4711 : }
4712 :
4713 :
4714 : /** \brief Write buffer data to the file descriptor.
4715 : *
4716 : * This function writes \p count bytes of data from \p buf to
4717 : * the file descriptor attached to this connection.
4718 : *
4719 : * If the file descriptor is closed, then an error occurs and
4720 : * the function returns -1.
4721 : *
4722 : * \note
4723 : * If you setup the file descriptor in non-blocking mode, then the
4724 : * function will return early if it cannot cache or immediately
4725 : * send the specified data.
4726 : *
4727 : * \param[in] buf A pointer to a buffer of data to write to the file.
4728 : * \param[in] count The number of bytes to write to the file.
4729 : *
4730 : * \return The number of bytes written to the file.
4731 : */
4732 0 : ssize_t snap_communicator::snap_fd_connection::write(void const * buf, size_t count)
4733 : {
4734 0 : if(!snap_fd_connection::is_writer())
4735 : {
4736 0 : errno = EBADF;
4737 0 : return -1;
4738 : }
4739 :
4740 0 : return ::write(f_fd, buf, count);
4741 : }
4742 :
4743 :
4744 :
4745 :
4746 :
4747 :
4748 :
4749 :
4750 :
4751 :
4752 :
4753 : ///////////////////////////////
4754 : // Snap FD Buffer Connection //
4755 : ///////////////////////////////
4756 :
4757 : /** \brief Initialize an fd connection with a buffer.
4758 : *
4759 : * The connection is initialized with the specified fd parameter.
4760 : *
4761 : * This initialization, so things work as expected in our environment,
4762 : * marks the file descriptor as non-blocking. This is important for
4763 : * the reader and writer capabilities.
4764 : *
4765 : * \param[in] fd The file descriptor (often a pipe).
4766 : * \param[in] mode The mode describing the file descriptor (i.e. read-only
4767 : * write-only, or read/write.)
4768 : */
4769 0 : snap_communicator::snap_fd_buffer_connection::snap_fd_buffer_connection(int fd, mode_t mode)
4770 0 : : snap_fd_connection(fd, mode)
4771 : {
4772 0 : non_blocking();
4773 0 : }
4774 :
4775 :
4776 : /** \brief Check whether this file descriptor still has some buffered input.
4777 : *
4778 : * This function returns true if there is partial incoming data in this
4779 : * object's buffer.
4780 : *
4781 : * \return true if some buffered input is waiting for completion.
4782 : */
4783 0 : bool snap_communicator::snap_fd_buffer_connection::has_input() const
4784 : {
4785 0 : return !f_line.empty();
4786 : }
4787 :
4788 :
4789 :
4790 : /** \brief Check whether this file descriptor still has some buffered output.
4791 : *
4792 : * This function returns true if there is still some output data in the
4793 : * output cache buffer. Output is added by the write() function, which is
4794 : * called, for example, by the send_message() function.
4795 : *
4796 : * Note that if the fd was already closed, this function may still return
4797 : * true in the event we have some cached data.
4798 : *
4799 : * \return true if some buffered output is waiting to be sent out.
4800 : */
4801 0 : bool snap_communicator::snap_fd_buffer_connection::has_output() const
4802 : {
4803 0 : return !f_output.empty();
4804 : }
4805 :
4806 :
4807 :
4808 : /** \brief Tells that this file descriptor is a writer when we have data.
4809 : *
4810 : * This function checks to know whether there is output data to be writen
4811 : * to this file descriptor. If so then the function returns true. Otherwise
4812 : * it just returns false.
4813 : *
4814 : * This happens whenever you called the write() function and the connection
4815 : * cache is not empty yet.
4816 : *
4817 : * Note that if the connection was closed or it not writable (as per the
4818 : * fd mode specified when creating this connection) then this function
4819 : * returns false.
4820 : *
4821 : * \return true if there is data to write to the fd, false otherwise.
4822 : */
4823 0 : bool snap_communicator::snap_fd_buffer_connection::is_writer() const
4824 : {
4825 0 : return !f_output.empty() && snap_fd_connection::is_writer();
4826 : }
4827 :
4828 :
4829 : /** \brief Write data to the connection.
4830 : *
4831 : * This function can be used to send data to this file descriptor.
4832 : * The data is bufferized and as soon as the connection file descriptor
4833 : * can accept more data it gets written there. In other words, we cannot
4834 : * just sleep and wait for an answer. The transfer of the data is therefore
4835 : * asynchroneous.
4836 : *
4837 : * \todo
4838 : * Determine whether we may end up with really large buffers that
4839 : * grow for a long time. This function only inserts and the
4840 : * process_signal() function only reads some of the bytes but it
4841 : * does not reduce the size of the buffer until all the data was
4842 : * sent.
4843 : *
4844 : * \note
4845 : * The function returns -1 and sets errno to EBADF if the file
4846 : * descriptor was closed (-1) or if it is not marked as a writer.
4847 : *
4848 : * \param[in] data The pointer to the buffer of data to be sent.
4849 : * \param[out] length The number of bytes to send.
4850 : *
4851 : * \return The number of bytes written, either -1, 0, or \p length
4852 : */
4853 0 : ssize_t snap_communicator::snap_fd_buffer_connection::write(void const * data, size_t const length)
4854 : {
4855 0 : if(get_socket() == -1
4856 0 : || !snap_fd_connection::is_writer()) // WARNING: We MUST call the snap_fd_connection version of the is_write(), our version tests the f_output which is an unwanted side effect here
4857 : {
4858 0 : errno = EBADF;
4859 0 : return -1;
4860 : }
4861 :
4862 0 : if(data != nullptr
4863 0 : && length > 0)
4864 : {
4865 0 : char const * d(reinterpret_cast<char const *>(data));
4866 0 : f_output.insert(f_output.end(), d, d + length);
4867 0 : return length;
4868 : }
4869 :
4870 0 : return 0;
4871 : }
4872 :
4873 :
4874 : /** \brief Read and process as much data as possible.
4875 : *
4876 : * This function reads as much incoming data as possible and processes
4877 : * it.
4878 : *
4879 : * If the input includes a newline character ('\n') then this function
4880 : * calls the process_line() callback which can further process that
4881 : * line of data.
4882 : *
4883 : * \todo
4884 : * Look into a way, if possible, to have a single instantiation since
4885 : * as far as I know this code matches the one written in the
4886 : * process_read() of the snap_tcp_client_buffer_connection and
4887 : * the snap_pipe_buffer_connection classes (and now snap_fd_buffer_connection).
4888 : */
4889 0 : void snap_communicator::snap_fd_buffer_connection::process_read()
4890 : {
4891 : // we read one character at a time until we get a '\n'
4892 : // since we have a non-blocking socket we can read as
4893 : // much as possible and then check for a '\n' and keep
4894 : // any extra data in a cache.
4895 : //
4896 0 : if(get_socket() != -1)
4897 : {
4898 0 : int count_lines(0);
4899 0 : int64_t const date_limit(snap_communicator::get_current_date() + f_processing_time_limit);
4900 0 : std::vector<char> buffer;
4901 0 : buffer.resize(1024);
4902 : for(;;)
4903 : {
4904 0 : errno = 0;
4905 0 : ssize_t const r(read(&buffer[0], buffer.size()));
4906 0 : if(r > 0)
4907 : {
4908 0 : for(ssize_t position(0); position < r; )
4909 : {
4910 0 : std::vector<char>::const_iterator it(std::find(buffer.begin() + position, buffer.begin() + r, '\n'));
4911 0 : if(it == buffer.begin() + r)
4912 : {
4913 : // no newline, just add the whole thing
4914 0 : f_line += std::string(&buffer[position], r - position);
4915 0 : break; // do not waste time, we know we are done
4916 : }
4917 :
4918 : // retrieve the characters up to the newline
4919 : // character and process the line
4920 : //
4921 0 : f_line += std::string(&buffer[position], it - buffer.begin() - position);
4922 0 : process_line(QString::fromUtf8(f_line.c_str()));
4923 0 : ++count_lines;
4924 :
4925 : // done with that line
4926 : //
4927 0 : f_line.clear();
4928 :
4929 : // we had a newline, we may still have some data
4930 : // in that buffer; (+1 to skip the '\n' itself)
4931 : //
4932 0 : position = it - buffer.begin() + 1;
4933 : }
4934 :
4935 : // when we reach here all the data read in `buffer` is
4936 : // now either fully processed or in f_line
4937 : //
4938 : // TODO: change the way this works so we can test the
4939 : // limit after each process_line() call
4940 : //
4941 0 : if(count_lines >= f_event_limit
4942 0 : || snap_communicator::get_current_date() >= date_limit)
4943 : {
4944 : // we reach one or both limits, stop processing so
4945 : // the other events have a chance to run
4946 : //
4947 0 : break;
4948 : }
4949 : }
4950 0 : else if(r == 0 || errno == 0 || errno == EAGAIN || errno == EWOULDBLOCK)
4951 : {
4952 : // no more data available at this time
4953 : break;
4954 : }
4955 : else //if(r < 0)
4956 : {
4957 0 : int const e(errno);
4958 0 : SNAP_LOG_WARNING("an error occurred while reading from socket (errno: ")(e)(" -- ")(strerror(e))(").");
4959 0 : process_error();
4960 0 : return;
4961 : }
4962 0 : }
4963 : }
4964 :
4965 : // process next level too
4966 0 : snap_fd_connection::process_read();
4967 : }
4968 :
4969 :
4970 : /** \brief Write to the connection's socket.
4971 : *
4972 : * This function implementation writes as much data as possible to the
4973 : * connection's socket.
4974 : *
4975 : * This function calls the process_empty_buffer() callback whenever the
4976 : * output buffer goes empty.
4977 : */
4978 0 : void snap_communicator::snap_fd_buffer_connection::process_write()
4979 : {
4980 0 : if(get_socket() != -1)
4981 : {
4982 0 : errno = 0;
4983 0 : ssize_t const r(snap_fd_connection::write(&f_output[f_position], f_output.size() - f_position));
4984 0 : if(r > 0)
4985 : {
4986 : // some data was written
4987 0 : f_position += r;
4988 0 : if(f_position >= f_output.size())
4989 : {
4990 0 : f_output.clear();
4991 0 : f_position = 0;
4992 0 : process_empty_buffer();
4993 : }
4994 : }
4995 0 : else if(r != 0 && errno != 0 && errno != EAGAIN && errno != EWOULDBLOCK)
4996 : {
4997 : // connection is considered bad, get rid of it
4998 : //
4999 0 : int const e(errno);
5000 0 : SNAP_LOG_ERROR("an error occurred while writing to socket of \"")(f_name)("\" (errno: ")(e)(" -- ")(strerror(e))(").");
5001 0 : process_error();
5002 0 : return;
5003 : }
5004 : }
5005 :
5006 : // process next level too
5007 0 : snap_fd_connection::process_write();
5008 : }
5009 :
5010 :
5011 : /** \brief The remote used hanged up.
5012 : *
5013 : * This function makes sure that the connection gets closed properly.
5014 : */
5015 0 : void snap_communicator::snap_fd_buffer_connection::process_hup()
5016 : {
5017 : // this connection is dead...
5018 : //
5019 : //close(); -- we are not currently responsible for closing this FD
5020 :
5021 0 : snap_fd_connection::process_hup();
5022 0 : }
5023 :
5024 :
5025 :
5026 :
5027 :
5028 :
5029 :
5030 :
5031 :
5032 :
5033 : ////////////////////////////////
5034 : // Snap TCP Client Connection //
5035 : ////////////////////////////////
5036 :
5037 :
5038 : /** \brief Initializes the client connection.
5039 : *
5040 : * This function creates a connection using the address, port, and mode
5041 : * parameters. This is very similar to using the bio_client class to
5042 : * create a connection, only the resulting connection can be used with
5043 : * the snap_communicator object.
5044 : *
5045 : * \note
5046 : * The function also saves the remote address and port used to open
5047 : * the connection which can later be retrieved using the
5048 : * get_remote_address() function. That address will remain valid
5049 : * even after the socket is closed.
5050 : *
5051 : * \todo
5052 : * If the remote address is an IPv6, we need to put it between [...]
5053 : * (i.e. [::1]:4040) so we can extract the port safely.
5054 : *
5055 : * \param[in] communicator The snap communicator controlling this connection.
5056 : * \param[in] addr The address of the server to connect to.
5057 : * \param[in] port The port to connect to.
5058 : * \param[in] mode Type of connection: plain or secure.
5059 : */
5060 0 : snap_communicator::snap_tcp_client_connection::snap_tcp_client_connection(std::string const & addr, int port, mode_t mode)
5061 : : bio_client(addr, port, mode)
5062 0 : , f_remote_address(QString("%1:%2").arg(get_client_addr().c_str()).arg(get_client_port()))
5063 : {
5064 0 : }
5065 :
5066 :
5067 : /** \brief Retrieve the remote address information.
5068 : *
5069 : * This function can be used to retrieve the remove address and port
5070 : * information as was specified on the constructor. These can be used
5071 : * to find this specific connection at a later time or create another
5072 : * connection.
5073 : *
5074 : * For example, you may get 192.168.2.17:4040.
5075 : *
5076 : * The function works even after the socket gets closed as we save
5077 : * the remote address and port in a string just after the connection
5078 : * was established.
5079 : *
5080 : * \note
5081 : * These parameters are the same as what was passed to the constructor,
5082 : * only both will have been converted to numbers. So for example when
5083 : * you used "localhost", here you get "::1" or "127.0.0.1" for the
5084 : * address.
5085 : *
5086 : * \return The remote host address and connection port.
5087 : */
5088 0 : QString const & snap_communicator::snap_tcp_client_connection::get_remote_address() const
5089 : {
5090 0 : return f_remote_address;
5091 : }
5092 :
5093 :
5094 : /** \brief Read from the client socket.
5095 : *
5096 : * This function reads data from the client socket and copy it in
5097 : * \p buf. A maximum of \p count bytes are read.
5098 : *
5099 : * \param[in,out] buf The buffer where the data is read.
5100 : * \param[in] count The maximum number of bytes to read.
5101 : *
5102 : * \return -1 if an error occurs, zero if no data gets read, a positive
5103 : * number representing the number of bytes read otherwise.
5104 : */
5105 0 : ssize_t snap_communicator::snap_tcp_client_connection::read(void * buf, size_t count)
5106 : {
5107 0 : if(get_socket() == -1)
5108 : {
5109 0 : errno = EBADF;
5110 0 : return -1;
5111 : }
5112 0 : return bio_client::read(reinterpret_cast<char *>(buf), count);
5113 : }
5114 :
5115 :
5116 : /** \brief Write to the client socket.
5117 : *
5118 : * This function writes \p count bytes from \p buf to this
5119 : * client socket.
5120 : *
5121 : * The function can safely be called after the socket was closed, although
5122 : * it will return -1 and set errno to EBADF in tha case.
5123 : *
5124 : * \param[in] buf The buffer to write to the client connection socket.
5125 : * \param[in] count The maximum number of bytes to write on this connection.
5126 : *
5127 : * \return -1 if an error occurs, zero if nothing was written, a positive
5128 : * number representing the number of bytes successfully written.
5129 : */
5130 0 : ssize_t snap_communicator::snap_tcp_client_connection::write(void const * buf, size_t count)
5131 : {
5132 0 : if(get_socket() == -1)
5133 : {
5134 0 : errno = EBADF;
5135 0 : return -1;
5136 : }
5137 0 : return bio_client::write(reinterpret_cast<char const *>(buf), count);
5138 : }
5139 :
5140 :
5141 : /** \brief Check whether this connection is a reader.
5142 : *
5143 : * We change the default to true since TCP sockets are generally
5144 : * always readers. You can still overload this function and
5145 : * return false if necessary.
5146 : *
5147 : * However, we do not overload the is_writer() because that is
5148 : * much more dynamic (i.e. you do not want to advertise as
5149 : * being a writer unless you have data to write to the
5150 : * socket.)
5151 : *
5152 : * \return The events to listen to for this connection.
5153 : */
5154 0 : bool snap_communicator::snap_tcp_client_connection::is_reader() const
5155 : {
5156 0 : return true;
5157 : }
5158 :
5159 :
5160 : /** \brief Retrieve the socket of this client connection.
5161 : *
5162 : * This function retrieves the socket this client connection. In this case
5163 : * the socket is defined in the bio_client class.
5164 : *
5165 : * \return The socket of this client connection.
5166 : */
5167 0 : int snap_communicator::snap_tcp_client_connection::get_socket() const
5168 : {
5169 0 : return bio_client::get_socket();
5170 : }
5171 :
5172 :
5173 :
5174 :
5175 :
5176 :
5177 : ////////////////////////////////
5178 : // Snap TCP Buffer Connection //
5179 : ////////////////////////////////
5180 :
5181 : /** \brief Initialize a client socket.
5182 : *
5183 : * The client socket gets initialized with the specified 'socket'
5184 : * parameter.
5185 : *
5186 : * This constructor creates a writer connection too. This gives you
5187 : * a read/write connection. You can get the writer with the writer()
5188 : * function. So you may write data with:
5189 : *
5190 : * \code
5191 : * my_reader.writer().write(buf, buf_size);
5192 : * \endcode
5193 : *
5194 : * \param[in] addr The address to connect to.
5195 : * \param[in] port The port to connect to.
5196 : * \param[in] mode The mode to connect as (PLAIN or SECURE).
5197 : * \param[in] blocking If true, keep a blocking socket, other non-blocking.
5198 : */
5199 0 : snap_communicator::snap_tcp_client_buffer_connection::snap_tcp_client_buffer_connection(std::string const & addr, int const port, mode_t const mode, bool const blocking)
5200 0 : : snap_tcp_client_connection(addr, port, mode)
5201 : {
5202 0 : if(!blocking)
5203 : {
5204 0 : non_blocking();
5205 : }
5206 0 : }
5207 :
5208 :
5209 : /** \brief Check whether this connection still has some input in its buffer.
5210 : *
5211 : * This function returns true if there is partial incoming data in this
5212 : * object's buffer.
5213 : *
5214 : * \return true if some buffered input is waiting for completion.
5215 : */
5216 0 : bool snap_communicator::snap_tcp_client_buffer_connection::has_input() const
5217 : {
5218 0 : return !f_line.empty();
5219 : }
5220 :
5221 :
5222 :
5223 : /** \brief Check whether this connection still has some output in its buffer.
5224 : *
5225 : * This function returns true if there is still some output in the client
5226 : * buffer. Output is added by the write() function, which is called by
5227 : * the send_message() function.
5228 : *
5229 : * \return true if some buffered output is waiting to be sent out.
5230 : */
5231 0 : bool snap_communicator::snap_tcp_client_buffer_connection::has_output() const
5232 : {
5233 0 : return !f_output.empty();
5234 : }
5235 :
5236 :
5237 :
5238 : /** \brief Write data to the connection.
5239 : *
5240 : * This function can be used to send data to this TCP/IP connection.
5241 : * The data is bufferized and as soon as the connection can WRITE
5242 : * to the socket, it will wake up and send the data. In other words,
5243 : * we cannot just sleep and wait for an answer. The transfer will
5244 : * be asynchroneous.
5245 : *
5246 : * \todo
5247 : * Optimization: look into writing the \p data buffer directly in
5248 : * the socket if the f_output cache is empty. If that works then
5249 : * we can completely bypass our intermediate cache. This works only
5250 : * if we make sure that the socket is non-blocking, though.
5251 : *
5252 : * \todo
5253 : * Determine whether we may end up with really large buffers that
5254 : * grow for a long time. This function only inserts and the
5255 : * process_signal() function only reads some of the bytes but it
5256 : * does not reduce the size of the buffer until all the data was
5257 : * sent.
5258 : *
5259 : * \param[in] data The pointer to the buffer of data to be sent.
5260 : * \param[out] length The number of bytes to send.
5261 : *
5262 : * \return The number of bytes that were saved in our buffer, 0 if
5263 : * no data was written to the buffer (i.e. the socket is
5264 : * closed, length is zero, or data is a null pointer.)
5265 : */
5266 0 : ssize_t snap_communicator::snap_tcp_client_buffer_connection::write(void const * data, size_t length)
5267 : {
5268 0 : if(get_socket() == -1)
5269 : {
5270 0 : errno = EBADF;
5271 0 : return -1;
5272 : }
5273 :
5274 0 : if(data != nullptr && length > 0)
5275 : {
5276 0 : char const * d(reinterpret_cast<char const *>(data));
5277 0 : f_output.insert(f_output.end(), d, d + length);
5278 0 : return length;
5279 : }
5280 :
5281 0 : return 0;
5282 : }
5283 :
5284 :
5285 : /** \brief The buffer is a writer when the output buffer is not empty.
5286 : *
5287 : * This function returns true as long as the output buffer of this
5288 : * client connection is not empty.
5289 : *
5290 : * \return true if the output buffer is not empty, false otherwise.
5291 : */
5292 0 : bool snap_communicator::snap_tcp_client_buffer_connection::is_writer() const
5293 : {
5294 0 : return get_socket() != -1 && !f_output.empty();
5295 : }
5296 :
5297 :
5298 : /** \brief Instantiation of process_read().
5299 : *
5300 : * This function reads incoming data from a socket.
5301 : *
5302 : * The function is what manages our low level TCP/IP connection protocol
5303 : * which is to read one line of data (i.e. bytes up to the next '\n'
5304 : * character; note that '\r' are not understood.)
5305 : *
5306 : * Once a complete line of data was read, it is converted to UTF-8 and
5307 : * sent to the next layer using the process_line() function passing
5308 : * the line it just read (without the '\n') to that callback.
5309 : *
5310 : * \sa process_write()
5311 : * \sa process_line()
5312 : */
5313 0 : void snap_communicator::snap_tcp_client_buffer_connection::process_read()
5314 : {
5315 : // we read one character at a time until we get a '\n'
5316 : // since we have a non-blocking socket we can read as
5317 : // much as possible and then check for a '\n' and keep
5318 : // any extra data in a cache.
5319 : //
5320 0 : if(get_socket() != -1)
5321 : {
5322 0 : int count_lines(0);
5323 0 : int64_t const date_limit(snap_communicator::get_current_date() + f_processing_time_limit);
5324 0 : std::vector<char> buffer;
5325 0 : buffer.resize(1024);
5326 : for(;;)
5327 : {
5328 0 : errno = 0;
5329 0 : ssize_t const r(read(&buffer[0], buffer.size()));
5330 0 : if(r > 0)
5331 : {
5332 0 : for(ssize_t position(0); position < r; )
5333 : {
5334 0 : std::vector<char>::const_iterator it(std::find(buffer.begin() + position, buffer.begin() + r, '\n'));
5335 0 : if(it == buffer.begin() + r)
5336 : {
5337 : // no newline, just add the whole thing
5338 0 : f_line += std::string(&buffer[position], r - position);
5339 0 : break; // do not waste time, we know we are done
5340 : }
5341 :
5342 : // retrieve the characters up to the newline
5343 : // character and process the line
5344 : //
5345 0 : f_line += std::string(&buffer[position], it - buffer.begin() - position);
5346 0 : process_line(QString::fromUtf8(f_line.c_str()));
5347 0 : ++count_lines;
5348 :
5349 : // done with that line
5350 : //
5351 0 : f_line.clear();
5352 :
5353 : // we had a newline, we may still have some data
5354 : // in that buffer; (+1 to skip the '\n' itself)
5355 : //
5356 0 : position = it - buffer.begin() + 1;
5357 : }
5358 :
5359 : // when we reach here all the data read in `buffer` is
5360 : // now either fully processed or in f_line
5361 : //
5362 : // TODO: change the way this works so we can test the
5363 : // limit after each process_line() call
5364 : //
5365 0 : if(count_lines >= f_event_limit
5366 0 : || snap_communicator::get_current_date() >= date_limit)
5367 : {
5368 : // we reach one or both limits, stop processing so
5369 : // the other events have a chance to run
5370 : //
5371 0 : break;
5372 : }
5373 : }
5374 0 : else if(r == 0 || errno == 0 || errno == EAGAIN || errno == EWOULDBLOCK)
5375 : {
5376 : // no more data available at this time
5377 : break;
5378 : }
5379 : else //if(r < 0)
5380 : {
5381 : // TODO: do something about the error
5382 0 : int const e(errno);
5383 0 : SNAP_LOG_ERROR("an error occurred while reading from socket (errno: ")(e)(" -- ")(strerror(e))(").");
5384 0 : process_error();
5385 0 : return;
5386 : }
5387 0 : }
5388 : }
5389 :
5390 : // process next level too
5391 0 : snap_tcp_client_connection::process_read();
5392 : }
5393 :
5394 :
5395 : /** \brief Instantiation of process_write().
5396 : *
5397 : * This function writes outgoing data to a socket.
5398 : *
5399 : * This function manages our own internal cache, which we use to allow
5400 : * for out of synchronization (non-blocking) output.
5401 : *
5402 : * When the output buffer goes empty, this function calls the
5403 : * process_empty_buffer() callback.
5404 : *
5405 : * \sa write()
5406 : * \sa process_read()
5407 : * \sa process_empty_buffer()
5408 : */
5409 0 : void snap_communicator::snap_tcp_client_buffer_connection::process_write()
5410 : {
5411 0 : if(get_socket() != -1)
5412 : {
5413 0 : errno = 0;
5414 0 : ssize_t const r(snap_tcp_client_connection::write(&f_output[f_position], f_output.size() - f_position));
5415 0 : if(r > 0)
5416 : {
5417 : // some data was written
5418 0 : f_position += r;
5419 0 : if(f_position >= f_output.size())
5420 : {
5421 0 : f_output.clear();
5422 0 : f_position = 0;
5423 0 : process_empty_buffer();
5424 : }
5425 : }
5426 0 : else if(r < 0 && errno != 0 && errno != EAGAIN && errno != EWOULDBLOCK)
5427 : {
5428 : // connection is considered bad, generate an error
5429 : //
5430 0 : int const e(errno);
5431 0 : SNAP_LOG_ERROR("an error occurred while writing to socket of \"")(f_name)("\" (errno: ")(e)(" -- ")(strerror(e))(").");
5432 0 : process_error();
5433 0 : return;
5434 : }
5435 : }
5436 :
5437 : // process next level too
5438 0 : snap_tcp_client_connection::process_write();
5439 : }
5440 :
5441 :
5442 : /** \brief The hang up event occurred.
5443 : *
5444 : * This function closes the socket and then calls the previous level
5445 : * hang up code which removes this connection from the snap_communicator
5446 : * object it was last added in.
5447 : */
5448 0 : void snap_communicator::snap_tcp_client_buffer_connection::process_hup()
5449 : {
5450 : // this connection is dead...
5451 : //
5452 0 : close();
5453 :
5454 : // process next level too
5455 0 : snap_tcp_client_connection::process_hup();
5456 0 : }
5457 :
5458 :
5459 : /** \fn snap_communicator::snap_tcp_client_buffer_connection::process_line(QString const & line);
5460 : * \brief Process a line of data.
5461 : *
5462 : * This is the default virtual class that can be overridden to implement
5463 : * your own processing. By default this function does nothing.
5464 : *
5465 : * \note
5466 : * At this point I implemented this function so one can instantiate
5467 : * a snap_tcp_server_client_buffer_connection without having to
5468 : * derive it, although I do not think that is 100% proper.
5469 : *
5470 : * \param[in] line The line of data that was just read from the input
5471 : * socket.
5472 : */
5473 :
5474 :
5475 :
5476 :
5477 :
5478 : ///////////////////////////////////////////////
5479 : // Snap TCP Server Message Buffer Connection //
5480 : ///////////////////////////////////////////////
5481 :
5482 : /** \brief Initializes a client to read messages from a socket.
5483 : *
5484 : * This implementation creates a message in/out client.
5485 : * This is the most useful client in our Snap! Communicator
5486 : * as it directly sends and receives messages.
5487 : *
5488 : * \param[in] addr The address to connect to.
5489 : * \param[in] port The port to connect to.
5490 : * \param[in] mode Use this mode to connect as (PLAIN, ALWAYS_SECURE or SECURE).
5491 : * \param[in] blocking Whether to keep the socket blocking or make it
5492 : * non-blocking.
5493 : */
5494 0 : snap_communicator::snap_tcp_client_message_connection::snap_tcp_client_message_connection(std::string const & addr, int const port, mode_t const mode, bool const blocking)
5495 0 : : snap_tcp_client_buffer_connection(addr, port, mode, blocking)
5496 : {
5497 0 : }
5498 :
5499 :
5500 : /** \brief Process a line (string) just received.
5501 : *
5502 : * The function parses the line as a message (snap_communicator_message)
5503 : * and then calls the process_message() function if the line was valid.
5504 : *
5505 : * \param[in] line The line of text that was just read.
5506 : */
5507 0 : void snap_communicator::snap_tcp_client_message_connection::process_line(QString const & line)
5508 : {
5509 0 : if(line.isEmpty())
5510 : {
5511 0 : return;
5512 : }
5513 :
5514 0 : snap_communicator_message message;
5515 0 : if(message.from_message(line))
5516 : {
5517 0 : dispatch_message(message);
5518 : }
5519 : else
5520 : {
5521 : // TODO: what to do here? This could be that the version changed
5522 : // and the messages are not compatible anymore.
5523 : //
5524 0 : SNAP_LOG_ERROR("snap_communicator::snap_tcp_client_message_connection::process_line() was asked to process an invalid message (")(line)(")");
5525 : }
5526 : }
5527 :
5528 :
5529 : /** \brief Send a message.
5530 : *
5531 : * This function sends a message to the client on the other side
5532 : * of this connection.
5533 : *
5534 : * \exception snap_communicator_runtime_error
5535 : * This function throws this exception if the write() to the pipe
5536 : * fails to write the entire message. This should only happen if
5537 : * the pipe gets severed.
5538 : *
5539 : * \param[in] message The message to be sent.
5540 : * \param[in] cache Whether to cache the message if there is no connection.
5541 : *
5542 : * \return Always true, although if an error occurs the function throws.
5543 : */
5544 0 : bool snap_communicator::snap_tcp_client_message_connection::send_message(snap_communicator_message const & message, bool cache)
5545 : {
5546 0 : NOTUSED(cache);
5547 :
5548 : // transform the message to a string and write to the socket
5549 : // the writing is asynchronous so the message is saved in a cache
5550 : // and transferred only later when the run() loop is hit again
5551 : //
5552 0 : QString const msg(message.to_message());
5553 0 : QByteArray const utf8(msg.toUtf8());
5554 0 : std::string buf(utf8.data(), utf8.size());
5555 0 : buf += "\n";
5556 0 : return write(buf.c_str(), buf.length()) == static_cast<ssize_t>(buf.length());
5557 : }
5558 :
5559 :
5560 :
5561 :
5562 :
5563 :
5564 :
5565 :
5566 : ////////////////////////////////
5567 : // Snap TCP Server Connection //
5568 : ////////////////////////////////
5569 :
5570 :
5571 : /** \brief Initialize a server connection.
5572 : *
5573 : * This function is used to initialize a server connection, a TCP/IP
5574 : * listener which can accept() new connections.
5575 : *
5576 : * The connection uses a \p mode parameter which can be set to MODE_PLAIN,
5577 : * in which case the \p certificate and \p private_key parameters are
5578 : * ignored, or MODE_SECURE.
5579 : *
5580 : * This connection supports secure SSL communication using a certificate
5581 : * and a private key. These have to be specified as filenames. The
5582 : * `snapcommunicator` daemon makes use of files defined under
5583 : * "/etc/snapwebsites/ssl/..." by default.
5584 : *
5585 : * These files are created using this command line:
5586 : *
5587 : * \code
5588 : * openssl req \
5589 : * -newkey rsa:2048 -nodes -keyout ssl-test.key \
5590 : * -x509 -days 3650 -out ssl-test.crt
5591 : * \endcode
5592 : *
5593 : * Then pass "ssl-test.crt" as the certificate and "ssl-test.key"
5594 : * as the private key.
5595 : *
5596 : * \todo
5597 : * Add support for DH connections. Since our snapcommunicator connections
5598 : * are mostly private, it should not be a huge need at this point, though.
5599 : *
5600 : * \todo
5601 : * Add support for verified certificates. Right now we do not create
5602 : * signed certificates. This does not prevent fully secure transactions,
5603 : * it just cannot verify that the computer on the other side is correct.
5604 : *
5605 : * \warning
5606 : * The \p max_connections parameter is currently ignored because the
5607 : * BIO implementation does not give you an API to change that parameter.
5608 : * That being said, they default to the maximum number that the Linux
5609 : * kernel will accept so it should be just fine.
5610 : *
5611 : * \param[in] addr The address to listen on. It may be set to "0.0.0.0".
5612 : * \param[in] port The port to listen on.
5613 : * \param[in] certificate The filename to a .pem file.
5614 : * \param[in] private_key The filename to a .pem file.
5615 : * \param[in] mode The mode to use to open the connection (PLAIN or SECURE.)
5616 : * \param[in] max_connections The number of connections to keep in the listen queue.
5617 : * \param[in] reuse_addr Whether to mark the socket with the SO_REUSEADDR flag.
5618 : */
5619 0 : snap_communicator::snap_tcp_server_connection::snap_tcp_server_connection(
5620 : std::string const & addr
5621 : , int port
5622 : , std::string const & certificate
5623 : , std::string const & private_key
5624 : , mode_t mode
5625 : , int max_connections
5626 0 : , bool reuse_addr)
5627 0 : : bio_server(addr::string_to_addr(addr, "", port, "tcp"), max_connections, reuse_addr, certificate, private_key, mode)
5628 : {
5629 0 : }
5630 :
5631 :
5632 : /** \brief Reimplement the is_listener() for the snap_tcp_server_connection.
5633 : *
5634 : * A server connection is a listener socket. The library makes
5635 : * use of a completely different callback when a "read" event occurs
5636 : * on these connections.
5637 : *
5638 : * The callback is expected to create the new connection and add
5639 : * it the communicator.
5640 : *
5641 : * \return This version of the function always returns true.
5642 : */
5643 0 : bool snap_communicator::snap_tcp_server_connection::is_listener() const
5644 : {
5645 0 : return true;
5646 : }
5647 :
5648 :
5649 : /** \brief Retrieve the socket of this server connection.
5650 : *
5651 : * This function retrieves the socket this server connection. In this case
5652 : * the socket is defined in the tcp_server class.
5653 : *
5654 : * \return The socket of this client connection.
5655 : */
5656 0 : int snap_communicator::snap_tcp_server_connection::get_socket() const
5657 : {
5658 0 : return bio_server::get_socket();
5659 : }
5660 :
5661 :
5662 :
5663 :
5664 :
5665 :
5666 :
5667 : ///////////////////////////////////////
5668 : // Snap TCP Server Client Connection //
5669 : ///////////////////////////////////////
5670 :
5671 :
5672 : /** \brief Create a client connection created from an accept().
5673 : *
5674 : * This constructor initializes a client connection from a socket
5675 : * that we received from an accept() call.
5676 : *
5677 : * The destructor will automatically close that socket on destruction.
5678 : *
5679 : * \param[in] client The client that acecpt() returned.
5680 : */
5681 0 : snap_communicator::snap_tcp_server_client_connection::snap_tcp_server_client_connection(tcp_client_server::bio_client::pointer_t client)
5682 0 : : f_client(client)
5683 : {
5684 0 : }
5685 :
5686 :
5687 : /** \brief Make sure the socket gets released once we are done witht he connection.
5688 : *
5689 : * This destructor makes sure that the socket gets closed.
5690 : */
5691 0 : snap_communicator::snap_tcp_server_client_connection::~snap_tcp_server_client_connection()
5692 : {
5693 0 : close();
5694 0 : }
5695 :
5696 :
5697 : /** \brief Read data from the TCP server client socket.
5698 : *
5699 : * This function reads as much data up to the specified amount
5700 : * in \p count. The read data is saved in \p buf.
5701 : *
5702 : * \param[in,out] buf The buffer where the data gets read.
5703 : * \param[in] count The maximum number of bytes to read in buf.
5704 : *
5705 : * \return The number of bytes read or -1 if an error occurred.
5706 : */
5707 0 : ssize_t snap_communicator::snap_tcp_server_client_connection::read(void * buf, size_t count)
5708 : {
5709 0 : if(!f_client)
5710 : {
5711 0 : errno = EBADF;
5712 0 : return -1;
5713 : }
5714 0 : return f_client->read(reinterpret_cast<char *>(buf), count);
5715 : }
5716 :
5717 :
5718 : /** \brief Write data to this connection's socket.
5719 : *
5720 : * This function writes up to \p count bytes of data from \p buf
5721 : * to this connection's socket.
5722 : *
5723 : * \warning
5724 : * This write function may not always write all the data you are
5725 : * trying to send to the remote connection. If you want to make
5726 : * sure that all your data is written to the other connection,
5727 : * you want to instead use the snap_tcp_server_client_buffer_connection
5728 : * which overloads the write() function and saves the data to be
5729 : * written to the socket in a buffer. The snap communicator run
5730 : * loop is then responsible for sending all the data.
5731 : *
5732 : * \param[in] buf The buffer of data to be written to the socket.
5733 : * \param[in] count The number of bytes the caller wants to write to the
5734 : * conneciton.
5735 : *
5736 : * \return The number of bytes written to the socket or -1 if an error occurred.
5737 : */
5738 0 : ssize_t snap_communicator::snap_tcp_server_client_connection::write(void const * buf, size_t count)
5739 : {
5740 0 : if(!f_client)
5741 : {
5742 0 : errno = EBADF;
5743 0 : return -1;
5744 : }
5745 0 : return f_client->write(reinterpret_cast<char const *>(buf), count);
5746 : }
5747 :
5748 :
5749 : /** \brief Close the socket of this connection.
5750 : *
5751 : * This function is automatically called whenever the object gets
5752 : * destroyed (see destructor) or detects that the client closed
5753 : * the network connection.
5754 : *
5755 : * Connections cannot be reopened.
5756 : */
5757 0 : void snap_communicator::snap_tcp_server_client_connection::close()
5758 : {
5759 0 : f_client.reset();
5760 0 : }
5761 :
5762 :
5763 : /** \brief Retrieve the socket of this connection.
5764 : *
5765 : * This function returns the socket defined in this connection.
5766 : */
5767 0 : int snap_communicator::snap_tcp_server_client_connection::get_socket() const
5768 : {
5769 0 : if(f_client == nullptr)
5770 : {
5771 : // client connection was closed
5772 : //
5773 0 : return -1;
5774 : }
5775 0 : return f_client->get_socket();
5776 : }
5777 :
5778 :
5779 : /** \brief Tell that we are always a reader.
5780 : *
5781 : * This function always returns true meaning that the connection is
5782 : * always of a reader. In most cases this is safe because if nothing
5783 : * is being written to you then poll() never returns so you do not
5784 : * waste much time in have a TCP connection always marked as a
5785 : * reader.
5786 : *
5787 : * \return The events to listen to for this connection.
5788 : */
5789 0 : bool snap_communicator::snap_tcp_server_client_connection::is_reader() const
5790 : {
5791 0 : return true;
5792 : }
5793 :
5794 :
5795 : /** \brief Retrieve a copy of the client's address.
5796 : *
5797 : * This function makes a copy of the address of this client connection
5798 : * to the \p address parameter and returns the length.
5799 : *
5800 : * If the function returns zero, then the \p address buffer is not
5801 : * modified and no address is defined in this connection.
5802 : *
5803 : * \param[out] address The reference to an address variable where the
5804 : * client's address gets copied.
5805 : *
5806 : * \return Return the length of the address which may be smaller than
5807 : * sizeof(address). If zero, then no address is defined.
5808 : *
5809 : * \sa get_addr()
5810 : */
5811 0 : size_t snap_communicator::snap_tcp_server_client_connection::get_client_address(struct sockaddr_storage & address) const
5812 : {
5813 : // make sure the address is defined and the socket open
5814 : //
5815 0 : if(const_cast<snap_communicator::snap_tcp_server_client_connection *>(this)->define_address() != 0)
5816 : {
5817 0 : return 0;
5818 : }
5819 :
5820 0 : address = f_address;
5821 0 : return f_length;
5822 : }
5823 :
5824 :
5825 : /** \brief Retrieve the address in the form of a string.
5826 : *
5827 : * Like the get_addr() of the tcp client and server classes, this
5828 : * function returns the address in the form of a string which can
5829 : * easily be used to log information and other similar tasks.
5830 : *
5831 : * \return The client's address in the form of a string.
5832 : */
5833 0 : std::string snap_communicator::snap_tcp_server_client_connection::get_client_addr() const
5834 : {
5835 : // make sure the address is defined and the socket open
5836 : //
5837 0 : if(!const_cast<snap_communicator::snap_tcp_server_client_connection *>(this)->define_address())
5838 : {
5839 0 : return std::string();
5840 : }
5841 :
5842 0 : size_t const max_length(std::max(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) + 1);
5843 :
5844 : // in release mode this should not be dynamic (although the syntax is so
5845 : // the warning would happen), but in debug it is likely an alloca()
5846 : #pragma GCC diagnostic push
5847 : #pragma GCC diagnostic ignored "-Wvla"
5848 : char buf[max_length];
5849 : #pragma GCC diagnostic pop
5850 :
5851 0 : char const * r(nullptr);
5852 :
5853 0 : if(f_address.ss_family == AF_INET)
5854 : {
5855 0 : r = inet_ntop(AF_INET, &reinterpret_cast<struct sockaddr_in const &>(f_address).sin_addr, buf, max_length);
5856 : }
5857 : else
5858 : {
5859 0 : r = inet_ntop(AF_INET6, &reinterpret_cast<struct sockaddr_in6 const &>(f_address).sin6_addr, buf, max_length);
5860 : }
5861 :
5862 0 : if(r == nullptr)
5863 : {
5864 0 : int const e(errno);
5865 0 : SNAP_LOG_FATAL("inet_ntop() could not convert IP address (errno: ")(e)(" -- ")(strerror(e))(").");
5866 0 : throw snap_communicator_runtime_error("snap_tcp_server_client_connection::get_addr(): inet_ntop() could not convert IP address properly.");
5867 : }
5868 :
5869 0 : return buf;
5870 : }
5871 :
5872 :
5873 : /** \brief Retrieve the port.
5874 : *
5875 : * This function returns the port of the socket on our side.
5876 : *
5877 : * If the port is not available (not connected?), then -1 is returned.
5878 : *
5879 : * \return The client's port in host order.
5880 : */
5881 0 : int snap_communicator::snap_tcp_server_client_connection::get_client_port() const
5882 : {
5883 : // make sure the address is defined and the socket open
5884 : //
5885 0 : if(!const_cast<snap_communicator::snap_tcp_server_client_connection *>(this)->define_address())
5886 : {
5887 0 : return -1;
5888 : }
5889 :
5890 0 : if(f_address.ss_family == AF_INET)
5891 : {
5892 0 : return ntohs(reinterpret_cast<struct sockaddr_in const &>(f_address).sin_port);
5893 : }
5894 : else
5895 : {
5896 0 : return ntohs(reinterpret_cast<struct sockaddr_in6 const &>(f_address).sin6_port);
5897 : }
5898 : }
5899 :
5900 :
5901 : /** \brief Retrieve the address in the form of a string.
5902 : *
5903 : * Like the get_addr() of the tcp client and server classes, this
5904 : * function returns the address in the form of a string which can
5905 : * easily be used to log information and other similar tasks.
5906 : *
5907 : * \return The client's address in the form of a string.
5908 : */
5909 0 : std::string snap_communicator::snap_tcp_server_client_connection::get_client_addr_port() const
5910 : {
5911 : // get the current address and port
5912 0 : std::string const addr(get_client_addr());
5913 0 : int const port(get_client_port());
5914 :
5915 : // make sure they are defined
5916 0 : if(addr.empty()
5917 0 : || port < 0)
5918 : {
5919 0 : return std::string();
5920 : }
5921 :
5922 : // calculate the result
5923 0 : std::stringstream buf;
5924 0 : if(f_address.ss_family == AF_INET)
5925 : {
5926 0 : buf << addr << ":" << port;
5927 : }
5928 : else
5929 : {
5930 0 : buf << "[" << addr << "]:" << port;
5931 : }
5932 0 : return buf.str();
5933 : }
5934 :
5935 :
5936 : /** \brief Retrieve the socket address if we have not done so yet.
5937 : *
5938 : * This function make sure that the f_address and f_length parameters are
5939 : * defined. This is done by calling the getsockname() function.
5940 : *
5941 : * If f_length is still zero, then it is expected that address was not
5942 : * yet read.
5943 : *
5944 : * Note that the function returns -1 if the socket is now -1 (i.e. the
5945 : * connection is closed) whether or not the function worked before.
5946 : *
5947 : * \return false if the address cannot be defined, true otherwise
5948 : */
5949 0 : bool snap_communicator::snap_tcp_server_client_connection::define_address()
5950 : {
5951 0 : int const s(get_socket());
5952 0 : if(s == -1)
5953 : {
5954 0 : return false;
5955 : }
5956 :
5957 0 : if(f_length == 0)
5958 : {
5959 : // address not defined yet, retrieve with with getsockname()
5960 : //
5961 0 : f_length = sizeof(f_address);
5962 0 : if(getsockname(s, reinterpret_cast<struct sockaddr *>(&f_address), &f_length) != 0)
5963 : {
5964 0 : int const e(errno);
5965 0 : SNAP_LOG_ERROR("getsockname() failed retrieving IP address (errno: ")(e)(" -- ")(strerror(e))(").");
5966 0 : f_length = 0;
5967 0 : return false;
5968 : }
5969 0 : if(f_address.ss_family != AF_INET
5970 0 : && f_address.ss_family != AF_INET6)
5971 : {
5972 0 : SNAP_LOG_ERROR("address family (")(f_address.ss_family)(") returned by getsockname() is not understood, it is neither an IPv4 nor IPv6.");
5973 0 : f_length = 0;
5974 0 : return false;
5975 : }
5976 0 : if(f_length < sizeof(f_address))
5977 : {
5978 : // reset the rest of the structure, just in case
5979 : //
5980 0 : memset(reinterpret_cast<char *>(&f_address) + f_length, 0, sizeof(f_address) - f_length);
5981 : }
5982 : }
5983 :
5984 0 : return true;
5985 : }
5986 :
5987 :
5988 :
5989 :
5990 :
5991 :
5992 : ////////////////////////////////
5993 : // Snap TCP Buffer Connection //
5994 : ////////////////////////////////
5995 :
5996 : /** \brief Initialize a client socket.
5997 : *
5998 : * The client socket gets initialized with the specified 'socket'
5999 : * parameter.
6000 : *
6001 : * If you are a pure client (opposed to a client that was just accepted)
6002 : * you may want to consider using the snap_tcp_client_buffer_connection
6003 : * instead. That gives you a way to open the socket from a set of address
6004 : * and port definitions among other things.
6005 : *
6006 : * This initialization, so things work as expected in our environment,
6007 : * the function marks the socket as non-blocking. This is important for
6008 : * the reader and writer capabilities.
6009 : *
6010 : * \param[in] client The client to be used for reading and writing.
6011 : */
6012 0 : snap_communicator::snap_tcp_server_client_buffer_connection::snap_tcp_server_client_buffer_connection(tcp_client_server::bio_client::pointer_t client)
6013 0 : : snap_tcp_server_client_connection(client)
6014 : {
6015 0 : non_blocking();
6016 0 : }
6017 :
6018 :
6019 : /** \brief Check whether this connection still has some input in its buffer.
6020 : *
6021 : * This function returns true if there is partial incoming data in this
6022 : * object's buffer.
6023 : *
6024 : * \return true if some buffered input is waiting for completion.
6025 : */
6026 0 : bool snap_communicator::snap_tcp_server_client_buffer_connection::has_input() const
6027 : {
6028 0 : return !f_line.empty();
6029 : }
6030 :
6031 :
6032 :
6033 : /** \brief Check whether this connection still has some output in its buffer.
6034 : *
6035 : * This function returns true if there is still some output in the client
6036 : * buffer. Output is added by the write() function, which is called by
6037 : * the send_message() function.
6038 : *
6039 : * \return true if some buffered output is waiting to be sent out.
6040 : */
6041 0 : bool snap_communicator::snap_tcp_server_client_buffer_connection::has_output() const
6042 : {
6043 0 : return !f_output.empty();
6044 : }
6045 :
6046 :
6047 :
6048 : /** \brief Tells that this connection is a writer when we have data to write.
6049 : *
6050 : * This function checks to know whether there is data to be writen to
6051 : * this connection socket. If so then the function returns true. Otherwise
6052 : * it just returns false.
6053 : *
6054 : * This happens whenever you called the write() function and our cache
6055 : * is not empty yet.
6056 : *
6057 : * \return true if there is data to write to the socket, false otherwise.
6058 : */
6059 0 : bool snap_communicator::snap_tcp_server_client_buffer_connection::is_writer() const
6060 : {
6061 0 : return get_socket() != -1 && !f_output.empty();
6062 : }
6063 :
6064 :
6065 : /** \brief Write data to the connection.
6066 : *
6067 : * This function can be used to send data to this TCP/IP connection.
6068 : * The data is bufferized and as soon as the connection can WRITE
6069 : * to the socket, it will wake up and send the data. In other words,
6070 : * we cannot just sleep and wait for an answer. The transfer will
6071 : * be asynchroneous.
6072 : *
6073 : * \todo
6074 : * Determine whether we may end up with really large buffers that
6075 : * grow for a long time. This function only inserts and the
6076 : * process_signal() function only reads some of the bytes but it
6077 : * does not reduce the size of the buffer until all the data was
6078 : * sent.
6079 : *
6080 : * \param[in] data The pointer to the buffer of data to be sent.
6081 : * \param[out] length The number of bytes to send.
6082 : */
6083 0 : ssize_t snap_communicator::snap_tcp_server_client_buffer_connection::write(void const * data, size_t const length)
6084 : {
6085 0 : if(get_socket() == -1)
6086 : {
6087 0 : errno = EBADF;
6088 0 : return -1;
6089 : }
6090 :
6091 0 : if(data != nullptr && length > 0)
6092 : {
6093 0 : char const * d(reinterpret_cast<char const *>(data));
6094 0 : f_output.insert(f_output.end(), d, d + length);
6095 0 : return length;
6096 : }
6097 :
6098 0 : return 0;
6099 : }
6100 :
6101 :
6102 : /** \brief Read and process as much data as possible.
6103 : *
6104 : * This function reads as much incoming data as possible and processes
6105 : * it.
6106 : *
6107 : * If the input includes a newline character ('\n') then this function
6108 : * calls the process_line() callback which can further process that
6109 : * line of data.
6110 : *
6111 : * \todo
6112 : * Look into a way, if possible, to have a single instantiation since
6113 : * as far as I know this code matches the one written in the
6114 : * process_read() of the snap_tcp_client_buffer_connection and
6115 : * the snap_pipe_buffer_connection classes.
6116 : */
6117 0 : void snap_communicator::snap_tcp_server_client_buffer_connection::process_read()
6118 : {
6119 : // we read one character at a time until we get a '\n'
6120 : // since we have a non-blocking socket we can read as
6121 : // much as possible and then check for a '\n' and keep
6122 : // any extra data in a cache.
6123 : //
6124 0 : if(get_socket() != -1)
6125 : {
6126 0 : int count_lines(0);
6127 0 : int64_t const date_limit(snap_communicator::get_current_date() + f_processing_time_limit);
6128 0 : std::vector<char> buffer;
6129 0 : buffer.resize(1024);
6130 : for(;;)
6131 : {
6132 0 : errno = 0;
6133 0 : ssize_t const r(read(&buffer[0], buffer.size()));
6134 0 : if(r > 0)
6135 : {
6136 0 : for(ssize_t position(0); position < r; )
6137 : {
6138 0 : std::vector<char>::const_iterator it(std::find(buffer.begin() + position, buffer.begin() + r, '\n'));
6139 0 : if(it == buffer.begin() + r)
6140 : {
6141 : // no newline, just add the whole thing
6142 0 : f_line += std::string(&buffer[position], r - position);
6143 0 : break; // do not waste time, we know we are done
6144 : }
6145 :
6146 : // retrieve the characters up to the newline
6147 : // character and process the line
6148 : //
6149 0 : f_line += std::string(&buffer[position], it - buffer.begin() - position);
6150 0 : process_line(QString::fromUtf8(f_line.c_str()));
6151 0 : ++count_lines;
6152 :
6153 : // done with that line
6154 : //
6155 0 : f_line.clear();
6156 :
6157 : // we had a newline, we may still have some data
6158 : // in that buffer; (+1 to skip the '\n' itself)
6159 : //
6160 0 : position = it - buffer.begin() + 1;
6161 : }
6162 :
6163 : // when we reach here all the data read in `buffer` is
6164 : // now either fully processed or in f_line
6165 : //
6166 : // TODO: change the way this works so we can test the
6167 : // limit after each process_line() call
6168 : //
6169 0 : if(count_lines >= f_event_limit
6170 0 : || snap_communicator::get_current_date() >= date_limit)
6171 : {
6172 : // we reach one or both limits, stop processing so
6173 : // the other events have a chance to run
6174 : //
6175 0 : break;
6176 : }
6177 : }
6178 0 : else if(r == 0 || errno == 0 || errno == EAGAIN || errno == EWOULDBLOCK)
6179 : {
6180 : // no more data available at this time
6181 : break;
6182 : }
6183 : else //if(r < 0)
6184 : {
6185 0 : int const e(errno);
6186 0 : SNAP_LOG_WARNING("an error occurred while reading from socket (errno: ")(e)(" -- ")(strerror(e))(").");
6187 0 : process_error();
6188 0 : return;
6189 : }
6190 0 : }
6191 : }
6192 :
6193 : // process next level too
6194 0 : snap_tcp_server_client_connection::process_read();
6195 : }
6196 :
6197 :
6198 : /** \brief Write to the connection's socket.
6199 : *
6200 : * This function implementation writes as much data as possible to the
6201 : * connection's socket.
6202 : *
6203 : * This function calls the process_empty_buffer() callback whenever the
6204 : * output buffer goes empty.
6205 : */
6206 0 : void snap_communicator::snap_tcp_server_client_buffer_connection::process_write()
6207 : {
6208 0 : if(get_socket() != -1)
6209 : {
6210 0 : errno = 0;
6211 0 : ssize_t const r(snap_tcp_server_client_connection::write(&f_output[f_position], f_output.size() - f_position));
6212 0 : if(r > 0)
6213 : {
6214 : // some data was written
6215 0 : f_position += r;
6216 0 : if(f_position >= f_output.size())
6217 : {
6218 0 : f_output.clear();
6219 0 : f_position = 0;
6220 0 : process_empty_buffer();
6221 : }
6222 : }
6223 0 : else if(r != 0 && errno != 0 && errno != EAGAIN && errno != EWOULDBLOCK)
6224 : {
6225 : // connection is considered bad, get rid of it
6226 : //
6227 0 : int const e(errno);
6228 0 : SNAP_LOG_ERROR("an error occurred while writing to socket of \"")(f_name)("\" (errno: ")(e)(" -- ")(strerror(e))(").");
6229 0 : process_error();
6230 0 : return;
6231 : }
6232 : }
6233 :
6234 : // process next level too
6235 0 : snap_tcp_server_client_connection::process_write();
6236 : }
6237 :
6238 :
6239 : /** \brief The remote used hanged up.
6240 : *
6241 : * This function makes sure that the connection gets closed properly.
6242 : */
6243 0 : void snap_communicator::snap_tcp_server_client_buffer_connection::process_hup()
6244 : {
6245 : // this connection is dead...
6246 : //
6247 0 : close();
6248 :
6249 0 : snap_tcp_server_client_connection::process_hup();
6250 0 : }
6251 :
6252 :
6253 :
6254 :
6255 :
6256 :
6257 :
6258 : ////////////////////////////////////////
6259 : // Snap TCP Server Message Connection //
6260 : ////////////////////////////////////////
6261 :
6262 : /** \brief Initializes a client to read messages from a socket.
6263 : *
6264 : * This implementation creates a message in/out client.
6265 : * This is the most useful client in our Snap! Communicator
6266 : * as it directly sends and receives messages.
6267 : *
6268 : * \param[in] client The client representing the in/out socket.
6269 : */
6270 0 : snap_communicator::snap_tcp_server_client_message_connection::snap_tcp_server_client_message_connection(tcp_client_server::bio_client::pointer_t client)
6271 0 : : snap_tcp_server_client_buffer_connection(client)
6272 : {
6273 : // TODO: somehow the port seems wrong (i.e. all connections return the same port)
6274 :
6275 : // make sure the socket is defined and well
6276 : //
6277 0 : int const socket(client->get_socket());
6278 0 : if(socket < 0)
6279 : {
6280 0 : SNAP_LOG_ERROR("called with a closed client connection.");
6281 0 : throw std::runtime_error("snap_communicator::snap_tcp_server_client_message_connection::snap_tcp_server_client_message_connection() called with a closed client connection.");
6282 : }
6283 :
6284 0 : struct sockaddr_storage address = sockaddr_storage();
6285 0 : socklen_t length(sizeof(address));
6286 0 : if(getpeername(socket, reinterpret_cast<struct sockaddr *>(&address), &length) != 0)
6287 : {
6288 0 : int const e(errno);
6289 0 : SNAP_LOG_ERROR("getpeername() failed retrieving IP address (errno: ")(e)(" -- ")(strerror(e))(").");
6290 0 : throw std::runtime_error("getpeername() failed to retrieve IP address in snap_communicator::snap_tcp_server_client_message_connection::snap_tcp_server_client_message_connection()");
6291 : }
6292 0 : if(address.ss_family != AF_INET
6293 0 : && address.ss_family != AF_INET6)
6294 : {
6295 0 : SNAP_LOG_ERROR("address family (")(address.ss_family)(") returned by getpeername() is not understood, it is neither an IPv4 nor IPv6.");
6296 0 : throw std::runtime_error("getpeername() returned an address which is not understood in snap_communicator::snap_tcp_server_client_message_connection::snap_tcp_server_client_message_connection()");
6297 : }
6298 0 : if(length < sizeof(address))
6299 : {
6300 : // reset the rest of the structure, just in case
6301 0 : memset(reinterpret_cast<char *>(&address) + length, 0, sizeof(address) - length);
6302 : }
6303 :
6304 0 : constexpr size_t max_length(std::max(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) + 1);
6305 :
6306 : // in release mode this should not be dynamic (although the syntax is so
6307 : // the warning would happen), but in debug it is likely an alloca()
6308 : //
6309 : #pragma GCC diagnostic push
6310 : #pragma GCC diagnostic ignored "-Wvla"
6311 : char buf[max_length];
6312 : #pragma GCC diagnostic pop
6313 :
6314 0 : char const * r(nullptr);
6315 :
6316 0 : if(address.ss_family == AF_INET)
6317 : {
6318 0 : r = inet_ntop(AF_INET, &reinterpret_cast<struct sockaddr_in const &>(address).sin_addr, buf, max_length);
6319 : }
6320 : else
6321 : {
6322 0 : r = inet_ntop(AF_INET6, &reinterpret_cast<struct sockaddr_in6 const &>(address).sin6_addr, buf, max_length);
6323 : }
6324 :
6325 0 : if(r == nullptr)
6326 : {
6327 0 : int const e(errno);
6328 0 : SNAP_LOG_FATAL("inet_ntop() could not convert IP address (errno: ")(e)(" -- ")(strerror(e))(").");
6329 0 : throw snap_communicator_runtime_error("snap_tcp_server_client_message_connection::snap_tcp_server_client_message_connection(): inet_ntop() could not convert IP address properly.");
6330 : }
6331 :
6332 0 : if(address.ss_family == AF_INET)
6333 : {
6334 0 : f_remote_address = QString("%1:%2").arg(buf).arg(ntohs(reinterpret_cast<struct sockaddr_in const &>(address).sin_port));
6335 : }
6336 : else
6337 : {
6338 0 : f_remote_address = QString("[%1]:%2").arg(buf).arg(ntohs(reinterpret_cast<struct sockaddr_in6 const &>(address).sin6_port));
6339 : }
6340 0 : }
6341 :
6342 :
6343 : /** \brief Process a line (string) just received.
6344 : *
6345 : * The function parses the line as a message (snap_communicator_message)
6346 : * and then calls the process_message() function if the line was valid.
6347 : *
6348 : * \param[in] line The line of text that was just read.
6349 : */
6350 0 : void snap_communicator::snap_tcp_server_client_message_connection::process_line(QString const & line)
6351 : {
6352 : // empty lines should not occur, but just in case, just ignore
6353 0 : if(line.isEmpty())
6354 : {
6355 0 : return;
6356 : }
6357 :
6358 0 : snap_communicator_message message;
6359 0 : if(message.from_message(line))
6360 : {
6361 0 : dispatch_message(message);
6362 : }
6363 : else
6364 : {
6365 : // TODO: what to do here? This could because the version changed
6366 : // and the messages are not compatible anymore.
6367 : //
6368 0 : SNAP_LOG_ERROR("process_line() was asked to process an invalid message (")(line)(")");
6369 : }
6370 : }
6371 :
6372 :
6373 : /** \brief Send a message.
6374 : *
6375 : * This function sends a message to the client on the other side
6376 : * of this connection.
6377 : *
6378 : * \exception snap_communicator_runtime_error
6379 : * This function throws this exception if the write() to the pipe
6380 : * fails to write the entire message. This should only happen if
6381 : * the pipe gets severed.
6382 : *
6383 : * \param[in] message The message to be processed.
6384 : * \param[in] cache Whether to cache the message if there is no connection.
6385 : * (Ignore because a client socket has to be there until
6386 : * closed and then it can't be reopened by the server.)
6387 : *
6388 : * \return Always true, although if an error occurs the function throws.
6389 : */
6390 0 : bool snap_communicator::snap_tcp_server_client_message_connection::send_message(snap_communicator_message const & message, bool cache)
6391 : {
6392 0 : NOTUSED(cache);
6393 :
6394 : // transform the message to a string and write to the socket
6395 : // the writing is asynchronous so the message is saved in a cache
6396 : // and transferred only later when the run() loop is hit again
6397 : //
6398 0 : QString const msg(message.to_message());
6399 0 : QByteArray const utf8(msg.toUtf8());
6400 0 : std::string buf(utf8.data(), utf8.size());
6401 0 : buf += "\n";
6402 0 : return write(buf.c_str(), buf.length()) == static_cast<ssize_t>(buf.length());
6403 : }
6404 :
6405 :
6406 : /** \brief Retrieve the remote address information.
6407 : *
6408 : * This function can be used to retrieve the remove address and port
6409 : * information as was specified on the constructor. These can be used
6410 : * to find this specific connection at a later time or create another
6411 : * connection.
6412 : *
6413 : * For example, you may get 192.168.2.17:4040.
6414 : *
6415 : * The function works even after the socket gets closed as we save
6416 : * the remote address and port in a string just after the connection
6417 : * was established.
6418 : *
6419 : * \warning
6420 : * This function returns BOTH: the address and the port.
6421 : *
6422 : * \note
6423 : * These parameters are the same as what was passed to the constructor,
6424 : * only both will have been converted to numbers. So for example when
6425 : * you used "localhost", here you get "::1" or "127.0.0.1" for the
6426 : * address.
6427 : *
6428 : * \return The remote host address and connection port.
6429 : */
6430 0 : QString const & snap_communicator::snap_tcp_server_client_message_connection::get_remote_address() const
6431 : {
6432 0 : return f_remote_address;
6433 : }
6434 :
6435 :
6436 :
6437 :
6438 : //////////////////////////////////////////////////
6439 : // Snap TCP Client Permanent Message Connection //
6440 : //////////////////////////////////////////////////
6441 :
6442 : /** \brief Internal implementation of the snap_tcp_client_permanent_message_connection class.
6443 : *
6444 : * This class is used to handle a thread that will process a connection for
6445 : * us. This allows us to connect in any amount of time required by the
6446 : * Unix system to obtain the connection with the remote server.
6447 : *
6448 : * \todo
6449 : * Having threads at the time we do a fork() is not safe. We may
6450 : * want to reconsider offering this functionality here. Because at
6451 : * this time we would have no control of when the thread is created
6452 : * and thus a way to make sure that no such thread is running when
6453 : * we call fork().
6454 : */
6455 : class snap_tcp_client_permanent_message_connection_impl
6456 : {
6457 : public:
6458 0 : class messenger
6459 : : public snap_communicator::snap_tcp_server_client_message_connection
6460 : {
6461 : public:
6462 : typedef std::shared_ptr<messenger> pointer_t;
6463 :
6464 0 : messenger(snap_communicator::snap_tcp_client_permanent_message_connection * parent, tcp_client_server::bio_client::pointer_t client)
6465 0 : : snap_tcp_server_client_message_connection(client)
6466 0 : , f_parent(parent)
6467 : {
6468 0 : set_name("snap_tcp_client_permanent_message_connection_impl::messenger");
6469 0 : }
6470 :
6471 : messenger(messenger const & rhs) = delete;
6472 : messenger & operator = (messenger const & rhs) = delete;
6473 :
6474 : // snap_connection implementation
6475 0 : virtual void process_empty_buffer()
6476 : {
6477 0 : snap_tcp_server_client_message_connection::process_empty_buffer();
6478 0 : f_parent->process_empty_buffer();
6479 0 : }
6480 :
6481 : // snap_connection implementation
6482 0 : virtual void process_error()
6483 : {
6484 0 : snap_tcp_server_client_message_connection::process_error();
6485 0 : f_parent->process_error();
6486 0 : }
6487 :
6488 : // snap_connection implementation
6489 0 : virtual void process_hup()
6490 : {
6491 0 : snap_tcp_server_client_message_connection::process_hup();
6492 0 : f_parent->process_hup();
6493 0 : }
6494 :
6495 : // snap_connection implementation
6496 0 : virtual void process_invalid()
6497 : {
6498 0 : snap_tcp_server_client_message_connection::process_invalid();
6499 0 : f_parent->process_invalid();
6500 0 : }
6501 :
6502 : // snap_tcp_server_client_message_connection implementation
6503 0 : virtual void process_message(snap_communicator_message const & message)
6504 : {
6505 : // We call the dispatcher from our parent since the child
6506 : // (this messenger) is not given a dispatcher
6507 : //
6508 0 : snap_communicator_message copy(message);
6509 0 : f_parent->dispatch_message(copy);
6510 0 : }
6511 :
6512 : private:
6513 : snap_communicator::snap_tcp_client_permanent_message_connection * f_parent = nullptr;
6514 : };
6515 :
6516 0 : class thread_done_signal
6517 : : public snap_communicator::snap_thread_done_signal
6518 : {
6519 : public:
6520 : typedef std::shared_ptr<thread_done_signal> pointer_t;
6521 :
6522 0 : thread_done_signal(snap_tcp_client_permanent_message_connection_impl * parent_impl)
6523 0 : : f_parent_impl(parent_impl)
6524 : {
6525 0 : set_name("snap_tcp_client_permanent_message_connection_impl::thread_done_signal");
6526 0 : }
6527 :
6528 : thread_done_signal(thread_done_signal const & rhs) = delete;
6529 : thread_done_signal & operator = (thread_done_signal const & rhs) = delete;
6530 :
6531 : /** \brief This signal was emitted.
6532 : *
6533 : * This function gets called whenever the thread is just about to
6534 : * quit. Calling f_thread.is_running() may still return true when
6535 : * you get in the 'thread_done()' callback. However, an
6536 : * f_thread.stop() will return very quickly.
6537 : */
6538 0 : virtual void process_read()
6539 : {
6540 0 : snap_thread_done_signal::process_read();
6541 :
6542 0 : f_parent_impl->thread_done();
6543 0 : }
6544 :
6545 : private:
6546 : snap_tcp_client_permanent_message_connection_impl * f_parent_impl = nullptr;
6547 : };
6548 :
6549 0 : class runner
6550 : : public snap_thread::snap_runner
6551 : {
6552 : public:
6553 0 : runner(snap_tcp_client_permanent_message_connection_impl * parent_impl, std::string const & address, int port, tcp_client_server::bio_client::mode_t mode)
6554 0 : : snap_runner("background snap_tcp_client_permanent_message_connection for asynchroneous connections")
6555 : , f_parent_impl(parent_impl)
6556 : , f_address(address)
6557 : , f_port(port)
6558 0 : , f_mode(mode)
6559 : {
6560 0 : }
6561 :
6562 :
6563 : runner(runner const & rhs) = delete;
6564 : runner & operator = (runner const & rhs) = delete;
6565 :
6566 :
6567 : /** \brief This is the actual function run by the thread.
6568 : *
6569 : * This function calls the connect() function and then
6570 : * tells the main thread we are done.
6571 : */
6572 0 : virtual void run()
6573 : {
6574 0 : connect();
6575 :
6576 : // tell the main thread that we are done
6577 : //
6578 0 : f_parent_impl->trigger_thread_done();
6579 0 : }
6580 :
6581 :
6582 : /** \brief This function attempts to connect.
6583 : *
6584 : * This function attempts a connection to the specified address
6585 : * and port with the specified mode (i.e. plain or encrypted.)
6586 : *
6587 : * The function may take a long time to succeed connecting with
6588 : * the server. The main thread will be awaken whenever this
6589 : * thread dies.
6590 : *
6591 : * If an error occurs, then the f_socket variable member will
6592 : * be set to -1. Otherwise it represents the socket that we
6593 : * just connected with.
6594 : */
6595 0 : void connect()
6596 : {
6597 : try
6598 : {
6599 : // create a socket using the bio_client class,
6600 : // but then just create a duplicate that we will
6601 : // use in a server-client TCP object (because
6602 : // we cannot directly create the right type of
6603 : // object otherwise...)
6604 : //
6605 0 : f_tcp_connection.reset(new tcp_client_server::bio_client(f_address, f_port, f_mode));
6606 : }
6607 0 : catch(tcp_client_server::tcp_client_server_runtime_error const & e)
6608 : {
6609 : // connection failed... we will have to try again later
6610 : //
6611 : // WARNING: our logger is not multi-thread safe
6612 : //SNAP_LOG_ERROR("connection to ")(f_address)(":")(f_port)(" failed with: ")(e.what());
6613 0 : f_last_error = e.what();
6614 0 : f_tcp_connection.reset();
6615 : }
6616 0 : }
6617 :
6618 :
6619 : /** \brief Retrieve the address to connect to.
6620 : *
6621 : * This function returns the address passed in on creation.
6622 : *
6623 : * \note
6624 : * Since the variable is constant, it is likely to never change.
6625 : * However, the c_str() function may change the buffer pointer.
6626 : * Hence, to be 100% safe, you cannot call this function until
6627 : * you make sure that the thread is fully stopped.
6628 : */
6629 0 : std::string const & get_address() const
6630 : {
6631 0 : return f_address;
6632 : }
6633 :
6634 :
6635 : /** \brief Retrieve the port to connect to.
6636 : *
6637 : * This function returns the port passed in on creation.
6638 : *
6639 : * \note
6640 : * Since the variable is constant, it never gets changed
6641 : * which means it is always safe to use it between
6642 : * both threads.
6643 : */
6644 0 : int get_port() const
6645 : {
6646 0 : return f_port;
6647 : }
6648 :
6649 :
6650 : /** \brief Retrieve the client allocated and connected by the thread.
6651 : *
6652 : * This function returns the TCP connection object resulting from
6653 : * connection attempts of the background thread.
6654 : *
6655 : * If the pointer is null, then you may get the corresponding
6656 : * error message using the get_last_error() function.
6657 : *
6658 : * You can get the client TCP connection pointer once. After that
6659 : * you always get a null pointer.
6660 : *
6661 : * \note
6662 : * This function is guarded so the pointer and the object it
6663 : * points to will be valid in another thread that retrieves it.
6664 : *
6665 : * \return The connection pointer.
6666 : */
6667 0 : tcp_client_server::bio_client::pointer_t release_client()
6668 : {
6669 0 : snap_thread::snap_lock lock(f_mutex);
6670 0 : tcp_client_server::bio_client::pointer_t tcp_connection;
6671 0 : tcp_connection.swap(f_tcp_connection);
6672 0 : return tcp_connection;
6673 : }
6674 :
6675 :
6676 : /** \brief Retrieve the last error message that happened.
6677 : *
6678 : * This function returns the last error message that was captured
6679 : * when trying to connect to the socket. The message is the
6680 : * e.what() message from the exception we captured.
6681 : *
6682 : * The message does not get cleared so the function can be called
6683 : * any number of times. To know whether an error was generated
6684 : * on the last attempt, make sure to first get the get_socket()
6685 : * and if it returns -1, then this message is significant,
6686 : * otherwise it is from a previous error.
6687 : *
6688 : * \warning
6689 : * Remember that if the background thread was used the error will
6690 : * NOT be available in the main thread until a full memory barrier
6691 : * was executed. For that reason we make sure that the thread
6692 : * was stopped when we detect an error.
6693 : *
6694 : * \return The last error message.
6695 : */
6696 0 : std::string const & get_last_error() const
6697 : {
6698 0 : return f_last_error;
6699 : }
6700 :
6701 :
6702 : /** \brief Close the connection.
6703 : *
6704 : * This function closes the connection. Since the f_tcp_connection
6705 : * holds the socket to the remote server, we have get this function
6706 : * called in order to completely disconnect.
6707 : *
6708 : * \note
6709 : * This function does not clear the f_last_error parameter so it
6710 : * can be read later.
6711 : */
6712 0 : void close()
6713 : {
6714 0 : f_tcp_connection.reset();
6715 0 : }
6716 :
6717 :
6718 : private:
6719 : snap_tcp_client_permanent_message_connection_impl * f_parent_impl = nullptr;
6720 : std::string const f_address;
6721 : int const f_port;
6722 : tcp_client_server::bio_client::mode_t const f_mode;
6723 : tcp_client_server::bio_client::pointer_t f_tcp_connection = tcp_client_server::bio_client::pointer_t();
6724 : std::string f_last_error = std::string();
6725 : };
6726 :
6727 :
6728 : /** \brief Initialize a permanent message connection implementation object.
6729 : *
6730 : * This object manages the thread used to asynchronically connect to
6731 : * the specified address and port.
6732 : *
6733 : * This class and its sub-classes may end up executing callbacks
6734 : * of the snap_tcp_client_permanent_message_connection object.
6735 : * However, in all cases these are never run from the thread.
6736 : *
6737 : * \param[in] client A pointer to the owner of this
6738 : * snap_tcp_client_permanent_message_connection_impl object.
6739 : * \param[in] address The address we are to connect to.
6740 : * \param[in] port The port we are to connect to.
6741 : * \param[in] mode The mode used to connect.
6742 : */
6743 0 : snap_tcp_client_permanent_message_connection_impl(snap_communicator::snap_tcp_client_permanent_message_connection * parent, std::string const & address, int port, tcp_client_server::bio_client::mode_t mode)
6744 0 : : f_parent(parent)
6745 : //, f_thread_done() -- auto-init
6746 : , f_thread_runner(this, address, port, mode)
6747 0 : , f_thread("background connection handler thread", &f_thread_runner)
6748 : //, f_messenger(nullptr) -- auto-init
6749 : //, f_message_cache() -- auto-init
6750 : {
6751 0 : }
6752 :
6753 :
6754 : snap_tcp_client_permanent_message_connection_impl(snap_tcp_client_permanent_message_connection_impl const & rhs) = delete;
6755 : snap_tcp_client_permanent_message_connection_impl & operator = (snap_tcp_client_permanent_message_connection_impl const & rhs) = delete;
6756 :
6757 : /** \brief Destroy the permanent message connection.
6758 : *
6759 : * This function makes sure that the messenger was lost.
6760 : */
6761 0 : ~snap_tcp_client_permanent_message_connection_impl()
6762 0 : {
6763 : // to make sure we can lose the messenger, first we want to be sure
6764 : // that we do not have a thread running
6765 : //
6766 : try
6767 : {
6768 0 : f_thread.stop();
6769 : }
6770 0 : catch(snap_thread_exception_mutex_failed_error const &)
6771 : {
6772 : }
6773 0 : catch(snap_thread_exception_invalid_error const &)
6774 : {
6775 : }
6776 :
6777 : // in this case we may still have an instance of the f_thread_done
6778 : // which linger around, we want it out
6779 : //
6780 : // Note: the call is safe even if the f_thread_done is null
6781 : //
6782 0 : snap_communicator::instance()->remove_connection(f_thread_done);
6783 :
6784 : // although the f_messenger variable gets reset automatically in
6785 : // the destructor, it would not get removed from the snap
6786 : // communicator instance if we were not doing it explicitly
6787 : //
6788 0 : disconnect();
6789 0 : }
6790 :
6791 :
6792 : /** \brief Direct connect to the messenger.
6793 : *
6794 : * In this case we try to connect without the thread. This allows
6795 : * us to avoid the thread problems, but we are blocked until the
6796 : * OS decides to time out or the connection worked.
6797 : */
6798 0 : void connect()
6799 : {
6800 0 : if(f_done)
6801 : {
6802 0 : SNAP_LOG_ERROR("Permanent connection marked done. Cannot attempt to reconnect.");
6803 0 : return;
6804 : }
6805 :
6806 : // call the thread connect() function from the main thread
6807 : //
6808 0 : f_thread_runner.connect();
6809 :
6810 : // simulate receiving the thread_done() signal
6811 : //
6812 0 : thread_done();
6813 : }
6814 :
6815 :
6816 : /** \brief Check whether the permanent connection is currently connected.
6817 : *
6818 : * This function returns true if the messenger exists, which means that
6819 : * the connection is up.
6820 : *
6821 : * \return true if the connection is up.
6822 : */
6823 0 : bool is_connected()
6824 : {
6825 0 : return f_messenger != nullptr;
6826 : }
6827 :
6828 :
6829 : /** \brief Try to start the thread runner.
6830 : *
6831 : * This function tries to start the thread runner in order to initiate
6832 : * a connection in the background. If the thread could not be started,
6833 : * then the function returns false.
6834 : *
6835 : * If the thread started, then the function returns true. This does
6836 : * not mean that the connection was obtained. This is known once
6837 : * the process_connected() function is called.
6838 : *
6839 : * \return true if the thread was successfully started.
6840 : */
6841 0 : bool background_connect()
6842 : {
6843 0 : if(f_done)
6844 : {
6845 0 : SNAP_LOG_ERROR("Permanent connection marked done. Cannot attempt to reconnect.");
6846 0 : return false;
6847 : }
6848 :
6849 0 : if(f_thread.is_running())
6850 : {
6851 0 : SNAP_LOG_ERROR("A background connection attempt is already in progress. Further requests are ignored.");
6852 0 : return false;
6853 : }
6854 :
6855 : // create the f_thread_done only when required
6856 : //
6857 0 : if(f_thread_done == nullptr)
6858 : {
6859 0 : f_thread_done.reset(new thread_done_signal(this));
6860 : }
6861 :
6862 0 : snap_communicator::instance()->add_connection(f_thread_done);
6863 :
6864 0 : if(!f_thread.start())
6865 : {
6866 0 : SNAP_LOG_ERROR("The thread used to run the background connection process did not start.");
6867 0 : return false;
6868 : }
6869 :
6870 0 : return true;
6871 : }
6872 :
6873 :
6874 : /** \brief Tell the main thread that the background thread is done.
6875 : *
6876 : * This function is called by the thread so the thread_done()
6877 : * function of the thread done object gets called. Only the
6878 : * thread should call this function.
6879 : *
6880 : * As a result the thread_done() function of this class will be
6881 : * called by the main thread.
6882 : */
6883 0 : void trigger_thread_done()
6884 : {
6885 0 : f_thread_done->thread_done();
6886 0 : }
6887 :
6888 :
6889 : /** \brief Signal that the background thread is done.
6890 : *
6891 : * This callback is called whenever the background thread sends
6892 : * a signal to us. This is used to avoid calling end user functions
6893 : * that would certainly cause a lot of problem if called from the
6894 : * thread.
6895 : *
6896 : * The function calls the process_connection_failed() if the
6897 : * connection did not happen.
6898 : *
6899 : * The function calls the process_connected() if the connection
6900 : * did happen.
6901 : *
6902 : * \note
6903 : * This is used only if the user requested that the connection
6904 : * happen in the background (i.e. use_thread was set to true
6905 : * in the snap_tcp_client_permanent_message_connection object
6906 : * constructor.)
6907 : */
6908 0 : void thread_done()
6909 : {
6910 : // if we used the thread we have to remove the signal used
6911 : // to know that the thread was done
6912 : //
6913 0 : snap_communicator::instance()->remove_connection(f_thread_done);
6914 :
6915 : // we will access the f_last_error member of the thread runner
6916 : // which may not be available to the main thread yet, calling
6917 : // stop forces a memory barrier so we are all good.
6918 : //
6919 : // calling stop() has no effect if we did not use the thread,
6920 : // however, not calling stop() when we did use the thread
6921 : // causes all sorts of other problems (especially, the thread
6922 : // never gets joined)
6923 : //
6924 0 : f_thread.stop();
6925 :
6926 0 : tcp_client_server::bio_client::pointer_t client(f_thread_runner.release_client());
6927 0 : if(f_done)
6928 : {
6929 : // already marked done, ignore the result and lose the
6930 : // connection immediately
6931 : //
6932 : //f_thread_running.close(); -- not necessary, 'client' is the connection
6933 0 : return;
6934 : }
6935 :
6936 0 : if(client == nullptr)
6937 : {
6938 : // TODO: fix address in error message using a snap::addr so
6939 : // as to handle IPv6 seemlessly.
6940 : //
6941 0 : SNAP_LOG_ERROR("connection to ")
6942 0 : (f_thread_runner.get_address())
6943 0 : (":")
6944 0 : (f_thread_runner.get_port())
6945 0 : (" failed with: ")
6946 0 : (f_thread_runner.get_last_error());
6947 :
6948 : // signal that an error occurred
6949 : //
6950 0 : f_parent->process_connection_failed(f_thread_runner.get_last_error());
6951 : }
6952 : else
6953 : {
6954 0 : f_messenger.reset(new messenger(f_parent, client));
6955 :
6956 : // add the messenger to the communicator
6957 : //
6958 0 : snap_communicator::instance()->add_connection(f_messenger);
6959 :
6960 : // if some messages were cached, process them immediately
6961 : //
6962 0 : while(!f_message_cache.empty())
6963 : {
6964 0 : f_messenger->send_message(f_message_cache[0]);
6965 0 : f_message_cache.erase(f_message_cache.begin());
6966 : }
6967 :
6968 : // let the client know we are now connected
6969 : //
6970 0 : f_parent->process_connected();
6971 : }
6972 : }
6973 :
6974 : /** \brief Send a message to the connection.
6975 : *
6976 : * This implementation function actually sends the message to the
6977 : * connection, assuming that the connection exists. Otherwise, it
6978 : * may cache the message (if cache is true.)
6979 : *
6980 : * Note that the message does not get cached if mark_done() was
6981 : * called earlier since we are trying to close the whole connection.
6982 : *
6983 : * \param[in] message The message to send.
6984 : * \param[in] cache Whether to cache the message if the connection is
6985 : * currently down.
6986 : *
6987 : * \return true if the message was forwarded, false if the message
6988 : * was ignored or cached.
6989 : */
6990 0 : bool send_message(snap_communicator_message const & message, bool cache)
6991 : {
6992 0 : if(f_messenger != nullptr)
6993 : {
6994 0 : return f_messenger->send_message(message);
6995 : }
6996 :
6997 0 : if(cache && !f_done)
6998 : {
6999 0 : f_message_cache.push_back(message);
7000 : }
7001 :
7002 0 : return false;
7003 : }
7004 :
7005 :
7006 : /** \brief Forget about the messenger connection.
7007 : *
7008 : * This function is used to fully disconnect from the messenger.
7009 : *
7010 : * If there is a messenger, this means:
7011 : *
7012 : * \li Removing the messenger from the snap_communicator instance.
7013 : * \li Closing the connection in the thread object.
7014 : *
7015 : * In most cases, it is called when an error occur, also it happens
7016 : * that we call it explicitly through the disconnect() function
7017 : * of the permanent connection class.
7018 : *
7019 : * \note
7020 : * This is safe, even though it is called from the messenger itself
7021 : * because it will not get deleted yet. This is because the run()
7022 : * loop has a copy in its own temporary copy of the vector of
7023 : * connections.
7024 : */
7025 0 : void disconnect()
7026 : {
7027 0 : if(f_messenger != nullptr)
7028 : {
7029 0 : snap_communicator::instance()->remove_connection(f_messenger);
7030 0 : f_messenger.reset();
7031 :
7032 : // just the messenger does not close the TCP connection because
7033 : // we may have another in the thread runner
7034 : //
7035 0 : f_thread_runner.close();
7036 : }
7037 0 : }
7038 :
7039 :
7040 : /** \brief Return the address and size of the remote computer.
7041 : *
7042 : * This function retrieve the socket address.
7043 : *
7044 : * \param[out] address The binary address of the remote computer.
7045 : *
7046 : * \return The size of the sockaddr structure, 0 if no address is available.
7047 : */
7048 0 : size_t get_client_address(struct sockaddr_storage & address) const
7049 : {
7050 0 : if(f_messenger != nullptr)
7051 : {
7052 0 : return f_messenger->get_client_address(address);
7053 : }
7054 0 : memset(&address, 0, sizeof(address));
7055 0 : return 0;
7056 : }
7057 :
7058 :
7059 : /** \brief Return the address of the f_message object.
7060 : *
7061 : * This function returns the address of the message object.
7062 : *
7063 : * \return The address of the remote computer.
7064 : */
7065 0 : std::string get_client_addr() const
7066 : {
7067 0 : if(f_messenger != nullptr)
7068 : {
7069 0 : return f_messenger->get_client_addr();
7070 : }
7071 0 : return std::string();
7072 : }
7073 :
7074 :
7075 : /** \brief Mark the messenger as done.
7076 : *
7077 : * This function is used to mark the messenger as done. This means it
7078 : * will get removed from the snap_communicator instance as soon as it
7079 : * is done with its current write buffer if there is one.
7080 : *
7081 : * You may also want to call the disconnection() function to actually
7082 : * reset the pointer along the way.
7083 : */
7084 0 : void mark_done()
7085 : {
7086 0 : f_done = true;
7087 :
7088 : // once done we don't attempt to reconnect so we can as well
7089 : // get rid of our existing cache immediately to save some
7090 : // memory
7091 : //
7092 0 : f_message_cache.clear();
7093 :
7094 0 : if(f_messenger != nullptr)
7095 : {
7096 0 : f_messenger->mark_done();
7097 : }
7098 0 : }
7099 :
7100 :
7101 : private:
7102 : snap_communicator::snap_tcp_client_permanent_message_connection * f_parent = nullptr;
7103 : thread_done_signal::pointer_t f_thread_done = thread_done_signal::pointer_t();
7104 : runner f_thread_runner;
7105 : snap::snap_thread f_thread;
7106 : messenger::pointer_t f_messenger = messenger::pointer_t();
7107 : snap_communicator_message::vector_t f_message_cache = snap_communicator_message::vector_t();
7108 : bool f_done = false;
7109 : };
7110 :
7111 :
7112 : /** \brief Initializes this TCP client message connection.
7113 : *
7114 : * This implementation creates what we call a permanent connection.
7115 : * Such a connection may fail once in a while. In such circumstances,
7116 : * the class automatically requests for a reconnection (see various
7117 : * parameters in the regard below.) However, this causes one issue:
7118 : * by default, the connection just never ends. When you are about
7119 : * ready to close the connection, you must call the mark_done()
7120 : * function first. This will tell the various error functions to
7121 : * drop this connection instead of restarting it after a small pause.
7122 : *
7123 : * This constructor makes sure to initialize the timer and saves
7124 : * the address, port, mode, pause, and use_thread parameters.
7125 : *
7126 : * The timer is first set to trigger immediately. This means the TCP
7127 : * connection will be attempted as soon as possible (the next time
7128 : * the run() loop is entered, it will time out immediately.) You
7129 : * are free to call set_timeout_date() with a date in the future if
7130 : * you prefer that the connect be attempted a little later.
7131 : *
7132 : * The \p pause parameter is used if the connection is lost and this
7133 : * timer is used again to attempt a new connection. It will be reused
7134 : * as long as the connection fails (as a delay). It has to be at least
7135 : * 10 microseconds, although really you should not use less than 1
7136 : * second (1000000). You may set the pause parameter to 0 in which case
7137 : * you are responsible to set the delay (by default there will be no
7138 : * delay and thus the timer will never time out.)
7139 : *
7140 : * To start with a delay, instead of trying to connect immediately,
7141 : * you may pass a negative pause parameter. So for example to get the
7142 : * first attempt 5 seconds after you created this object, you use
7143 : * -5000000LL as the pause parameter.
7144 : *
7145 : * The \p use_thread parameter determines whether the connection should
7146 : * be attempted in a thread (asynchroneously) or immediately (which means
7147 : * the timeout callback may block for a while.) If the connection is to
7148 : * a local server with an IP address specified as numbers (i.e. 127.0.0.1),
7149 : * the thread is probably not required. For connections to a remote
7150 : * computer, though, it certainly is important.
7151 : *
7152 : * \param[in] address The address to listen on. It may be set to "0.0.0.0".
7153 : * \param[in] port The port to listen on.
7154 : * \param[in] mode The mode to use to open the connection.
7155 : * \param[in] pause The amount of time to wait before attempting a new
7156 : * connection after a failure, in microseconds, or 0.
7157 : * \param[in] use_thread Whether a thread is used to connect to the
7158 : * server.
7159 : */
7160 0 : snap_communicator::snap_tcp_client_permanent_message_connection::snap_tcp_client_permanent_message_connection
7161 : ( std::string const & address
7162 : , int port
7163 : , tcp_client_server::bio_client::mode_t mode
7164 : , int64_t const pause
7165 : , bool const use_thread
7166 0 : )
7167 : : snap_timer(pause < 0 ? -pause : 0)
7168 0 : , f_impl(new snap_tcp_client_permanent_message_connection_impl(this, address, port, mode))
7169 0 : , f_pause(llabs(pause))
7170 0 : , f_use_thread(use_thread)
7171 : {
7172 0 : }
7173 :
7174 :
7175 : /** \brief Destroy instance
7176 : */
7177 0 : snap_communicator::snap_tcp_client_permanent_message_connection::~snap_tcp_client_permanent_message_connection()
7178 : {
7179 : // Does nothing
7180 0 : }
7181 :
7182 :
7183 : /** \brief Attempt to send a message to this connection.
7184 : *
7185 : * If the connection is currently enabled, the message is sent immediately.
7186 : * Otherwise, it may be cached if the \p cache parameter is set to true.
7187 : * A cached message is forwarded as soon as a new successful connection
7188 : * happens, which can be a problem if messages need to happen in a very
7189 : * specific order (For example, after a reconnection to snapcommunicator
7190 : * you first need to REGISTER or CONNECT...)
7191 : *
7192 : * \param[in] message The message to send to the connected server.
7193 : * \param[in] cache Whether the message should be cached.
7194 : *
7195 : * \return true if the message was sent, false if it was not sent, although
7196 : * if cache was true, it was cached
7197 : */
7198 0 : bool snap_communicator::snap_tcp_client_permanent_message_connection::send_message(snap_communicator_message const & message, bool cache)
7199 : {
7200 0 : return f_impl->send_message(message, cache);
7201 : }
7202 :
7203 :
7204 : /** \brief Check whether the connection is up.
7205 : *
7206 : * This function returns true if the connection is considered to be up.
7207 : * This means sending messages will work quickly instead of being
7208 : * cached up until an actual TCP/IP connection gets established.
7209 : *
7210 : * Note that the connection may have hanged up since, and the system
7211 : * may not have yet detected the fact (i.e. the connection is going
7212 : * to receive the process_hup() call after the event in which you are
7213 : * working.)
7214 : *
7215 : * \return true if connected
7216 : */
7217 0 : bool snap_communicator::snap_tcp_client_permanent_message_connection::is_connected() const
7218 : {
7219 0 : return f_impl->is_connected();
7220 : }
7221 :
7222 :
7223 : /** \brief Disconnect the messenger now.
7224 : *
7225 : * This function kills the current connection.
7226 : *
7227 : * There are a few cases where two daemons communicate between each others
7228 : * and at some point one of them wants to exit and needs to disconnect. This
7229 : * function can be used in that one situation assuming that you have an
7230 : * acknowledgement from the other daemon.
7231 : *
7232 : * Say you have daemon A and B. B wants to quit and before doing so sends
7233 : * a form of "I'm quitting" message to A. In that situation, B is not closing
7234 : * the messenger connection, A is responsible for that (i.e. A acknowledges
7235 : * receipt of the "I'm quitting" message from B by closing the connection.)
7236 : *
7237 : * B also wants to call the mark_done() function to make sure that it
7238 : * does not reconnected a split second later and instead the permanent
7239 : * connection gets removed from the snap_communicator list of connections.
7240 : */
7241 0 : void snap_communicator::snap_tcp_client_permanent_message_connection::disconnect()
7242 : {
7243 0 : f_impl->disconnect();
7244 0 : }
7245 :
7246 :
7247 : /** \brief Overload so we do not have to use namespace everywhere.
7248 : *
7249 : * This function overloads the snap_connection::mark_done() function so
7250 : * we can call it without the need to use snap_timer::mark_done()
7251 : * everywhere.
7252 : */
7253 0 : void snap_communicator::snap_tcp_client_permanent_message_connection::mark_done()
7254 : {
7255 0 : snap_timer::mark_done();
7256 0 : }
7257 :
7258 :
7259 : /** \brief Mark connection as done.
7260 : *
7261 : * This function allows you to mark the permanent connection and the
7262 : * messenger as done.
7263 : *
7264 : * Note that calling this function with false is the same as calling the
7265 : * base class mark_done() function.
7266 : *
7267 : * If the \p message parameter is set to true, we suggest you also call
7268 : * the disconnect() function. That way the messenger will truly get
7269 : * removed from everyone quickly.
7270 : *
7271 : * \param[in] messenger If true, also mark the messenger as done.
7272 : */
7273 0 : void snap_communicator::snap_tcp_client_permanent_message_connection::mark_done(bool messenger)
7274 : {
7275 0 : snap_timer::mark_done();
7276 0 : if(messenger)
7277 : {
7278 0 : f_impl->mark_done();
7279 : }
7280 0 : }
7281 :
7282 :
7283 : /** \brief Retrieve a copy of the client's address.
7284 : *
7285 : * This function makes a copy of the address of this client connection
7286 : * to the \p address parameter and returns the length.
7287 : *
7288 : * \param[in] address The reference to an address variable where the
7289 : * address gets copied.
7290 : *
7291 : * \return Return the length of the address which may be smaller than
7292 : * sizeof(struct sockaddr). If zero, then no address is defined.
7293 : *
7294 : * \sa get_addr()
7295 : */
7296 0 : size_t snap_communicator::snap_tcp_client_permanent_message_connection::get_client_address(struct sockaddr_storage & address) const
7297 : {
7298 0 : return f_impl->get_client_address(address);
7299 : }
7300 :
7301 :
7302 : /** \brief Retrieve the remote computer address as a string.
7303 : *
7304 : * This function returns the address of the remote computer as a string.
7305 : * It will be a canonicalized IP address.
7306 : *
7307 : * \return The cacnonicalized IP address.
7308 : */
7309 0 : std::string snap_communicator::snap_tcp_client_permanent_message_connection::get_client_addr() const
7310 : {
7311 0 : return f_impl->get_client_addr();
7312 : }
7313 :
7314 :
7315 : /** \brief Internal timeout callback implementation.
7316 : *
7317 : * This callback implements the guts of this class: it attempts to connect
7318 : * to the specified address and port, optionally after creating a thread
7319 : * so the attempt can happen asynchroneously.
7320 : *
7321 : * When the connection fails, the timer is used to try again pause
7322 : * microseconds later (pause as specified in the constructor).
7323 : *
7324 : * When a connection succeeds, the timer is disabled until you detect
7325 : * an error while using the connection and re-enable the timer.
7326 : *
7327 : * \warning
7328 : * This function changes the timeout delay to the pause amount
7329 : * as defined with the constructor. If you want to change that
7330 : * amount, you can do so an any point after this function call
7331 : * using the set_timeout_delay() function. If the pause parameter
7332 : * was set to -1, then the timeout never gets changed.
7333 : * However, you should not use a permanent message timer as your
7334 : * own or you will interfer with the internal use of the timer.
7335 : */
7336 0 : void snap_communicator::snap_tcp_client_permanent_message_connection::process_timeout()
7337 : {
7338 : // got a spurious call when already marked done
7339 : //
7340 0 : if(is_done())
7341 : {
7342 0 : return;
7343 : }
7344 :
7345 : // change the timeout delay although we will not use it immediately
7346 : // if we start the thread or attempt an immediate connection, but
7347 : // that way the user can change it by calling set_timeout_delay()
7348 : // at any time after the first process_timeout() call
7349 : //
7350 0 : if(f_pause > 0)
7351 : {
7352 0 : set_timeout_delay(f_pause);
7353 0 : f_pause = 0;
7354 : }
7355 :
7356 0 : if(f_use_thread)
7357 : {
7358 : // in this case we create a thread, run it and know whether the
7359 : // connection succeeded only when the thread tells us it did
7360 : //
7361 : // TODO: the background_connect() may return false in two situations:
7362 : // 1) when the thread is already running and then the behavior
7363 : // we have below is INCORRECT
7364 : // 2) when the thread cannot be started (i.e. could not
7365 : // allocate the stack?) in which case the if() below
7366 : // is the correct behavior
7367 : //
7368 0 : if(f_impl->background_connect())
7369 : {
7370 : // we started the thread successfully, so block the timer
7371 : //
7372 0 : set_enable(false);
7373 : }
7374 : }
7375 : else
7376 : {
7377 : // the success is noted when we receive a call to
7378 : // process_connected(); there we do set_enable(false)
7379 : // so the timer stops
7380 : //
7381 0 : f_impl->connect();
7382 : }
7383 : }
7384 :
7385 :
7386 : /** \brief Process an error.
7387 : *
7388 : * When an error occurs, we restart the timer so we can attempt to reconnect
7389 : * to that server.
7390 : *
7391 : * If you overload this function, make sure to either call this
7392 : * implementation or enable the timer yourselves.
7393 : *
7394 : * \warning
7395 : * This function does not call the snap_timer::process_error() function
7396 : * which means that this connection is not automatically removed from
7397 : * the snapcommunicator object on failures.
7398 : */
7399 0 : void snap_communicator::snap_tcp_client_permanent_message_connection::process_error()
7400 : {
7401 0 : if(is_done())
7402 : {
7403 0 : snap_timer::process_error();
7404 : }
7405 : else
7406 : {
7407 0 : f_impl->disconnect();
7408 0 : set_enable(true);
7409 : }
7410 0 : }
7411 :
7412 :
7413 : /** \brief Process a hang up.
7414 : *
7415 : * When a hang up occurs, we restart the timer so we can attempt to reconnect
7416 : * to that server.
7417 : *
7418 : * If you overload this function, make sure to either call this
7419 : * implementation or enable the timer yourselves.
7420 : *
7421 : * \warning
7422 : * This function does not call the snap_timer::process_hup() function
7423 : * which means that this connection is not automatically removed from
7424 : * the snapcommunicator object on failures.
7425 : */
7426 0 : void snap_communicator::snap_tcp_client_permanent_message_connection::process_hup()
7427 : {
7428 0 : if(is_done())
7429 : {
7430 0 : snap_timer::process_hup();
7431 : }
7432 : else
7433 : {
7434 0 : f_impl->disconnect();
7435 0 : set_enable(true);
7436 : }
7437 0 : }
7438 :
7439 :
7440 : /** \brief Process an invalid signal.
7441 : *
7442 : * When an invalid signal occurs, we restart the timer so we can attempt
7443 : * to reconnect to that server.
7444 : *
7445 : * If you overload this function, make sure to either call this
7446 : * implementation or enable the timer yourselves.
7447 : *
7448 : * \warning
7449 : * This function does not call the snap_timer::process_invalid() function
7450 : * which means that this connection is not automatically removed from
7451 : * the snapcommunicator object on failures.
7452 : */
7453 0 : void snap_communicator::snap_tcp_client_permanent_message_connection::process_invalid()
7454 : {
7455 0 : if(is_done())
7456 : {
7457 0 : snap_timer::process_invalid();
7458 : }
7459 : else
7460 : {
7461 0 : f_impl->disconnect();
7462 0 : set_enable(true);
7463 : }
7464 0 : }
7465 :
7466 :
7467 : /** \brief Make sure that the messenger connection gets removed.
7468 : *
7469 : * This function makes sure that the messenger sub-connection also gets
7470 : * removed from the snap communicator. Otherwise it would lock the system
7471 : * since connections are saved in the snap communicator object as shared
7472 : * pointers.
7473 : */
7474 0 : void snap_communicator::snap_tcp_client_permanent_message_connection::connection_removed()
7475 : {
7476 0 : f_impl->disconnect();
7477 0 : }
7478 :
7479 :
7480 : /** \brief Process a connection failed callback.
7481 : *
7482 : * When a connection attempt fails, we restart the timer so we can
7483 : * attempt to reconnect to that server.
7484 : *
7485 : * If you overload this function, make sure to either call this
7486 : * implementation or enable the timer yourselves.
7487 : *
7488 : * \param[in] error_message The error message that trigged this callback.
7489 : */
7490 0 : void snap_communicator::snap_tcp_client_permanent_message_connection::process_connection_failed(std::string const & error_message)
7491 : {
7492 0 : NOTUSED(error_message);
7493 0 : set_enable(true);
7494 0 : }
7495 :
7496 :
7497 : /** \brief The connection is ready.
7498 : *
7499 : * This callback gets called whenever the connection succeeded and is
7500 : * ready to be used.
7501 : *
7502 : * You should implement this virtual function if you have to initiate
7503 : * the communication. For example, the snapserver has to send a
7504 : * REGISTER to the snapcommunicator system and thus implements this
7505 : * function.
7506 : *
7507 : * The default implementation makes sure that the timer gets turned off
7508 : * so we do not try to reconnect every minute or so.
7509 : */
7510 0 : void snap_communicator::snap_tcp_client_permanent_message_connection::process_connected()
7511 : {
7512 0 : set_enable(false);
7513 0 : }
7514 :
7515 :
7516 :
7517 :
7518 : ////////////////////////////////
7519 : // Snap UDP Server Connection //
7520 : ////////////////////////////////
7521 :
7522 :
7523 : /** \brief Initialize a UDP listener.
7524 : *
7525 : * This function is used to initialize a server connection, a UDP/IP
7526 : * listener which wakes up whenever a send() is sent to this listener
7527 : * address and port.
7528 : *
7529 : * \param[in] communicator The snap communicator controlling this connection.
7530 : * \param[in] addr The address to listen on. It may be set to "0.0.0.0".
7531 : * \param[in] port The port to listen on.
7532 : */
7533 0 : snap_communicator::snap_udp_server_connection::snap_udp_server_connection(std::string const & addr, int port)
7534 0 : : udp_server(addr, port)
7535 : {
7536 0 : }
7537 :
7538 :
7539 : /** \brief Check to know whether this UDP connection is a reader.
7540 : *
7541 : * This function returns true to say that this UDP connection is
7542 : * indeed a reader.
7543 : *
7544 : * \return This function already returns true as we are likely to
7545 : * always want a UDP socket to be listening for incoming
7546 : * packets.
7547 : */
7548 0 : bool snap_communicator::snap_udp_server_connection::is_reader() const
7549 : {
7550 0 : return true;
7551 : }
7552 :
7553 :
7554 : /** \brief Retrieve the socket of this server connection.
7555 : *
7556 : * This function retrieves the socket this server connection. In this case
7557 : * the socket is defined in the udp_server class.
7558 : *
7559 : * \return The socket of this client connection.
7560 : */
7561 0 : int snap_communicator::snap_udp_server_connection::get_socket() const
7562 : {
7563 0 : return udp_server::get_socket();
7564 : }
7565 :
7566 :
7567 : /** \brief Define a secret code.
7568 : *
7569 : * When receiving a message through this UDP socket, this secret code must
7570 : * be included in the message. If not present, then the message gets
7571 : * discarded.
7572 : *
7573 : * By default this parameter is an empty string. This means no secret
7574 : * code is required and UDP communication can be done without it.
7575 : *
7576 : * \note
7577 : * Secret codes are expected to be used only on connections between
7578 : * computers. If the IP address is 127.0.0.1, you probably don't need
7579 : * to have a secret code.
7580 : *
7581 : * \warning
7582 : * Remember that UDP messages are limited in size. If too long, the
7583 : * send_message() function throws an error. So your secret code should
7584 : * remain relatively small.
7585 : *
7586 : * \todo
7587 : * The secret_code string must be a valid UTF-8 string. At this point
7588 : * this is not enforced.
7589 : *
7590 : * \param[in] secret_code The secret code that has to be included in the
7591 : * incoming messages for those to be accepted.
7592 : */
7593 0 : void snap_communicator::snap_udp_server_connection::set_secret_code(std::string const & secret_code)
7594 : {
7595 0 : f_secret_code = secret_code;
7596 0 : }
7597 :
7598 :
7599 : /** \brief Retrieve the server secret code.
7600 : *
7601 : * This function returns the server secret code as defined with the
7602 : * set_secret_code() function. By default this parameter is set to
7603 : * the empty string.
7604 : *
7605 : * Whenever a message is received, this code is checked. If defined
7606 : * in the server and not equal to the code in the message, then the
7607 : * message is discarded (hackers?)
7608 : *
7609 : * The message is also used when sending a message. It gets added
7610 : * to the message if it is not the empty string.
7611 : *
7612 : * \return The secret code.
7613 : */
7614 0 : std::string const & snap_communicator::snap_udp_server_connection::get_secret_code() const
7615 : {
7616 0 : return f_secret_code;
7617 : }
7618 :
7619 :
7620 :
7621 :
7622 : ////////////////////////////////
7623 : // Snap UDP Server Connection //
7624 : ////////////////////////////////
7625 :
7626 :
7627 : /** \brief Initialize a UDP server to send and receive messages.
7628 : *
7629 : * This function initialises a UDP server as a Snap UDP server
7630 : * connection attached to the specified address and port.
7631 : *
7632 : * It is expected to be used to send and receive UDP messages.
7633 : *
7634 : * Note that to send messages, you need the address and port
7635 : * of the destination. In effect, we do not use this server
7636 : * when sending. Instead we create a client that we immediately
7637 : * destruct once the message was sent.
7638 : *
7639 : * \param[in] addr The address to listen on.
7640 : * \param[in] port The port to listen on.
7641 : */
7642 0 : snap_communicator::snap_udp_server_message_connection::snap_udp_server_message_connection(std::string const & addr, int port)
7643 0 : : snap_udp_server_connection(addr, port)
7644 : {
7645 : // allow for looping over all the messages in one go
7646 : //
7647 0 : non_blocking();
7648 0 : }
7649 :
7650 :
7651 : /** \brief Send a UDP message.
7652 : *
7653 : * This function offers you to send a UDP message to the specified
7654 : * address and port. The message should be small enough to fit in
7655 : * on UDP packet or the call will fail.
7656 : *
7657 : * \note
7658 : * The function return true when the message was successfully sent.
7659 : * This does not mean it was received.
7660 : *
7661 : * \param[in] addr The destination address for the message.
7662 : * \param[in] port The destination port for the message.
7663 : * \param[in] message The message to send to the destination.
7664 : * \param[in] secret_code The secret code to send along the message.
7665 : *
7666 : * \return true when the message was sent, false otherwise.
7667 : */
7668 0 : bool snap_communicator::snap_udp_server_message_connection::send_message(
7669 : std::string const & addr
7670 : , int port
7671 : , snap_communicator_message const & message
7672 : , std::string const & secret_code)
7673 : {
7674 : // Note: contrary to the TCP version, a UDP message does not
7675 : // need to include the '\n' character since it is sent
7676 : // in one UDP packet. However, it has a maximum size
7677 : // limit which we enforce here.
7678 : //
7679 0 : udp_client_server::udp_client client(addr, port);
7680 0 : snap_communicator_message m(message);
7681 0 : if(!secret_code.empty())
7682 : {
7683 0 : m.add_parameter("udp_secret", QString::fromUtf8(secret_code.c_str()));
7684 : }
7685 0 : QString const msg(m.to_message());
7686 0 : QByteArray const utf8(msg.toUtf8());
7687 0 : if(static_cast<size_t>(utf8.size()) > DATAGRAM_MAX_SIZE)
7688 : {
7689 : // packet too large for our buffers
7690 : //
7691 0 : throw snap_communicator_invalid_message("message too large for a UDP server");
7692 : }
7693 0 : if(client.send(utf8.data(), utf8.size()) != utf8.size()) // we do not send the '\0'
7694 : {
7695 0 : SNAP_LOG_ERROR("snap_udp_server_message_connection::send_message(): could not send UDP message.");
7696 0 : return false;
7697 : }
7698 :
7699 0 : return true;
7700 : }
7701 :
7702 :
7703 : /** \brief Implementation of the process_read() callback.
7704 : *
7705 : * This function reads the datagram we just received using the
7706 : * recv() function. The size of the datagram cannot be more than
7707 : * DATAGRAM_MAX_SIZE (1Kb at time of writing.)
7708 : *
7709 : * The message is then parsed and further processing is expected
7710 : * to be accomplished in your implementation of process_message().
7711 : *
7712 : * The function actually reads as many pending datagrams as it can.
7713 : */
7714 0 : void snap_communicator::snap_udp_server_message_connection::process_read()
7715 : {
7716 : char buf[DATAGRAM_MAX_SIZE];
7717 : for(;;)
7718 : {
7719 0 : ssize_t const r(recv(buf, sizeof(buf) / sizeof(buf[0]) - 1));
7720 0 : if(r <= 0)
7721 : {
7722 0 : break;
7723 : }
7724 0 : buf[r] = '\0';
7725 0 : QString const udp_message(QString::fromUtf8(buf));
7726 0 : snap::snap_communicator_message message;
7727 0 : if(message.from_message(udp_message))
7728 : {
7729 0 : QString const expected(QString::fromUtf8(get_secret_code().c_str()));
7730 0 : if(message.has_parameter("udp_secret"))
7731 : {
7732 0 : QString const secret(message.get_parameter("udp_secret"));
7733 0 : if(secret != expected)
7734 : {
7735 0 : if(!expected.isEmpty())
7736 : {
7737 : // our secret code and the message secret code do not match
7738 : //
7739 0 : SNAP_LOG_ERROR("the incoming message has an unexpected udp_secret code, message ignored");
7740 0 : return;
7741 : }
7742 :
7743 : // the sender included a UDP secret code but we don't
7744 : // require it so we emit a warning but still accept
7745 : // the message
7746 : //
7747 0 : SNAP_LOG_WARNING("no udp_secret=... parameter was expected (missing secret_code=... settings for this application?)");
7748 : }
7749 : }
7750 0 : else if(!expected.isEmpty())
7751 : {
7752 : // secret code is missing from incoming message
7753 : //
7754 0 : SNAP_LOG_ERROR("the incoming message was expected to have udp_secret code, message ignored");
7755 0 : return;
7756 : }
7757 :
7758 : // we received a valid message, process it
7759 : //
7760 0 : dispatch_message(message);
7761 : }
7762 : else
7763 : {
7764 0 : SNAP_LOG_ERROR("snap_communicator::snap_udp_server_message_connection::process_read() was asked to process an invalid message (")(udp_message)(")");
7765 : }
7766 0 : }
7767 : }
7768 :
7769 :
7770 :
7771 :
7772 : /////////////////////////////////////////////////
7773 : // Snap TCP Blocking Client Message Connection //
7774 : /////////////////////////////////////////////////
7775 :
7776 : /** \brief Blocking client message connection.
7777 : *
7778 : * This object allows you to create a blocking, generally temporary
7779 : * one message connection client. This is specifically used with
7780 : * the snaplock daemon, but it can be used for other things too as
7781 : * required.
7782 : *
7783 : * The connection is expected to be used as shown in the following
7784 : * example which is how it is used to implement the LOCK through
7785 : * our snaplock daemons.
7786 : *
7787 : * \code
7788 : * class my_blocking_connection
7789 : * : public snap_tcp_blocking_client_message_connection
7790 : * {
7791 : * public:
7792 : * my_blocking_connection(std::string const & addr, int port, mode_t mode)
7793 : * : snap_tcp_blocking_client_message_connection(addr, port, mode)
7794 : * {
7795 : * // need to register with snap communicator
7796 : * snap_communicator_message register_message;
7797 : * register_message.set_command("REGISTER");
7798 : * ...
7799 : * blocking_connection.send_message(register_message);
7800 : *
7801 : * run();
7802 : * }
7803 : *
7804 : * ~my_blocking_connection()
7805 : * {
7806 : * // done, send UNLOCK and then make sure to unregister
7807 : * snap_communicator_message unlock_message;
7808 : * unlock_message.set_command("UNLOCK");
7809 : * ...
7810 : * blocking_connection.send_message(unlock_message);
7811 : *
7812 : * snap_communicator_message unregister_message;
7813 : * unregister_message.set_command("UNREGISTER");
7814 : * ...
7815 : * blocking_connection.send_message(unregister_message);
7816 : * }
7817 : *
7818 : * // now that we have a dispatcher, this would probably use
7819 : * // that mechanism instead of a list of if()/else if()
7820 : * //
7821 : * // Please, consider using the dispatcher instead
7822 : * //
7823 : * virtual void process_message(snap_communicator_message const & message)
7824 : * {
7825 : * QString const command(message.get_command());
7826 : * if(command == "LOCKED")
7827 : * {
7828 : * // the lock worked, release hand back to the user
7829 : * done();
7830 : * }
7831 : * else if(command == "READY")
7832 : * {
7833 : * // the REGISTER worked
7834 : * // send the LOCK now
7835 : * snap_communicator_message lock_message;
7836 : * lock_message.set_command("LOCK");
7837 : * ...
7838 : * blocking_connection.send_message(lock_message);
7839 : * }
7840 : * else if(command == "HELP")
7841 : * {
7842 : * // snapcommunicator wants us to tell it what commands
7843 : * // we accept
7844 : * snap_communicator_message commands_message;
7845 : * commands_message.set_command("COMMANDS");
7846 : * ...
7847 : * blocking_connection.send_message(commands_message);
7848 : * }
7849 : * }
7850 : * };
7851 : * my_blocking_connection blocking_connection("127.0.0.1", 4040);
7852 : *
7853 : * // then we can send a message to the service we are interested in
7854 : * blocking_connection.send_message(my_message);
7855 : *
7856 : * // now we call run() waiting for a reply
7857 : * blocking_connection.run();
7858 : * \endcode
7859 : */
7860 0 : snap_communicator::snap_tcp_blocking_client_message_connection::snap_tcp_blocking_client_message_connection(std::string const & addr, int const port, mode_t const mode)
7861 0 : : snap_tcp_client_message_connection(addr, port, mode, true)
7862 : {
7863 0 : }
7864 :
7865 :
7866 : /** \brief Blocking run on the connection.
7867 : *
7868 : * This function reads the incoming messages and calls process_message()
7869 : * on each one of them, in a blocking manner.
7870 : *
7871 : * If you called mark_done() before, the done flag is reset back to false.
7872 : * You will have to call mark_done() again if you again receive a message
7873 : * that is expected to end the loop.
7874 : *
7875 : * \note
7876 : * Internally, the function actually calls process_line() which transforms
7877 : * the line in a message and in turn calls process_message().
7878 : */
7879 0 : void snap_communicator::snap_tcp_blocking_client_message_connection::run()
7880 : {
7881 0 : mark_not_done();
7882 :
7883 0 : do
7884 : {
7885 : for(;;)
7886 : {
7887 : // TBD: can the socket become -1 within the read() loop?
7888 : // (i.e. should not that be just outside of the for(;;)?)
7889 : //
7890 : struct pollfd fd;
7891 0 : fd.events = POLLIN | POLLPRI | POLLRDHUP;
7892 0 : fd.fd = get_socket();
7893 0 : if(fd.fd < 0
7894 0 : || !is_enabled())
7895 : {
7896 : // invalid socket
7897 0 : process_error();
7898 0 : return;
7899 : }
7900 :
7901 : // at this time, this class is used with the lock and
7902 : // the lock has a timeout so we need to block at most
7903 : // for that amount of time and not forever (presumably
7904 : // the snaplock would send us a LOCKFAILED marked with
7905 : // a "timeout" parameter, but we cannot rely on the
7906 : // snaplock being there and responding as expected.)
7907 : //
7908 : // calculate the number of microseconds and then convert
7909 : // them to milliseconds for poll()
7910 : //
7911 0 : int64_t const next_timeout_timestamp(save_timeout_timestamp());
7912 0 : int64_t const now(get_current_date());
7913 0 : int64_t const timeout((next_timeout_timestamp - now) / 1000);
7914 0 : if(timeout <= 0)
7915 : {
7916 : // timed out
7917 : //
7918 0 : process_timeout();
7919 0 : if(is_done())
7920 : {
7921 0 : return;
7922 : }
7923 0 : SNAP_LOG_FATAL("blocking connection timed out.");
7924 0 : throw snap_communicator_runtime_error("snap_communicator::snap_tcp_blocking_client_message_connection::run(): blocking connection timed out");
7925 : }
7926 0 : errno = 0;
7927 0 : fd.revents = 0; // probably useless... (kernel should clear those)
7928 0 : int const r(::poll(&fd, 1, timeout));
7929 0 : if(r < 0)
7930 : {
7931 : // r < 0 means an error occurred
7932 : //
7933 0 : if(errno == EINTR)
7934 : {
7935 : // Note: if the user wants to prevent this error, he should
7936 : // use the snap_signal with the Unix signals that may
7937 : // happen while calling poll().
7938 : //
7939 0 : throw snap_communicator_runtime_error("snap_communicator::snap_tcp_blocking_client_message_connection::run(): EINTR occurred while in poll() -- interrupts are not supported yet though");
7940 : }
7941 0 : if(errno == EFAULT)
7942 : {
7943 0 : throw snap_communicator_parameter_error("snap_communicator::snap_tcp_blocking_client_message_connection::run(): buffer was moved out of our address space?");
7944 : }
7945 0 : if(errno == EINVAL)
7946 : {
7947 : // if this is really because nfds is too large then it may be
7948 : // a "soft" error that can be fixed; that being said, my
7949 : // current version is 16K files which frankly when we reach
7950 : // that level we have a problem...
7951 : //
7952 : struct rlimit rl;
7953 0 : getrlimit(RLIMIT_NOFILE, &rl);
7954 0 : throw snap_communicator_parameter_error(QString("snap_communicator::snap_tcp_blocking_client_message_connection::run(): too many file fds for poll, limit is currently %1, your kernel top limit is %2")
7955 0 : .arg(rl.rlim_cur)
7956 0 : .arg(rl.rlim_max).toStdString());
7957 : }
7958 0 : if(errno == ENOMEM)
7959 : {
7960 0 : throw snap_communicator_runtime_error("snap_communicator::snap_tcp_blocking_client_message_connection::run(): poll() failed because of memory");
7961 : }
7962 0 : int const e(errno);
7963 0 : throw snap_communicator_runtime_error(QString("snap_communicator::snap_tcp_blocking_client_message_connection::run(): poll() failed with error %1").arg(e));
7964 : }
7965 :
7966 0 : if((fd.revents & (POLLIN | POLLPRI)) != 0)
7967 : {
7968 : // read one character at a time otherwise we would be
7969 : // blocked forever
7970 : //
7971 : char buf[2];
7972 0 : int const size(::read(fd.fd, buf, 1));
7973 0 : if(size != 1)
7974 : {
7975 : // invalid read
7976 0 : process_error();
7977 0 : throw snap_communicator_runtime_error(QString("snap_communicator::snap_tcp_blocking_client_message_connection::run(): read() failed reading data from socket (return value = %1)").arg(size));
7978 : }
7979 0 : if(buf[0] == '\n')
7980 : {
7981 : // end of a line, we got a whole message in our buffer
7982 : // notice that we do not add the '\n' to line
7983 0 : break;
7984 : }
7985 0 : buf[1] = '\0';
7986 0 : f_line += buf;
7987 : }
7988 0 : if((fd.revents & POLLERR) != 0)
7989 : {
7990 0 : process_error();
7991 0 : return;
7992 : }
7993 0 : if((fd.revents & (POLLHUP | POLLRDHUP)) != 0)
7994 : {
7995 0 : process_hup();
7996 0 : return;
7997 : }
7998 0 : if((fd.revents & POLLNVAL) != 0)
7999 : {
8000 0 : process_invalid();
8001 0 : return;
8002 : }
8003 0 : }
8004 0 : process_line(QString::fromUtf8(f_line.c_str()));
8005 0 : f_line.clear();
8006 : }
8007 0 : while(!is_done());
8008 : }
8009 :
8010 :
8011 : /** \brief Quick peek on the connection.
8012 : *
8013 : * This function checks for incoming messages and calls process_message()
8014 : * on each one of them. If no messages are found on the pipe, then the
8015 : * function returns immediately.
8016 : *
8017 : * \note
8018 : * Internally, the function actually calls process_line() which transforms
8019 : * the line in a message and in turn calls process_message().
8020 : */
8021 0 : void snap_communicator::snap_tcp_blocking_client_message_connection::peek()
8022 : {
8023 0 : do
8024 : {
8025 : for(;;)
8026 : {
8027 : struct pollfd fd;
8028 0 : fd.events = POLLIN | POLLPRI | POLLRDHUP;
8029 0 : fd.fd = get_socket();
8030 0 : if(fd.fd < 0
8031 0 : || !is_enabled())
8032 : {
8033 : // invalid socket
8034 0 : process_error();
8035 0 : return;
8036 : }
8037 :
8038 0 : errno = 0;
8039 0 : fd.revents = 0; // probably useless... (kernel should clear those)
8040 0 : int const r(::poll(&fd, 1, 0));
8041 0 : if(r < 0)
8042 : {
8043 : // r < 0 means an error occurred
8044 : //
8045 0 : if(errno == EINTR)
8046 : {
8047 : // Note: if the user wants to prevent this error, he should
8048 : // use the snap_signal with the Unix signals that may
8049 : // happen while calling poll().
8050 : //
8051 0 : throw snap_communicator_runtime_error("snap_communicator::snap_tcp_blocking_client_message_connection::run(): EINTR occurred while in poll() -- interrupts are not supported yet though");
8052 : }
8053 0 : if(errno == EFAULT)
8054 : {
8055 0 : throw snap_communicator_parameter_error("snap_communicator::snap_tcp_blocking_client_message_connection::run(): buffer was moved out of our address space?");
8056 : }
8057 0 : if(errno == EINVAL)
8058 : {
8059 : // if this is really because nfds is too large then it may be
8060 : // a "soft" error that can be fixed; that being said, my
8061 : // current version is 16K files which frankly when we reach
8062 : // that level we have a problem...
8063 : //
8064 : struct rlimit rl;
8065 0 : getrlimit(RLIMIT_NOFILE, &rl);
8066 0 : throw snap_communicator_parameter_error(QString("snap_communicator::snap_tcp_blocking_client_message_connection::run(): too many file fds for poll, limit is currently %1, your kernel top limit is %2")
8067 0 : .arg(rl.rlim_cur)
8068 0 : .arg(rl.rlim_max).toStdString());
8069 : }
8070 0 : if(errno == ENOMEM)
8071 : {
8072 0 : throw snap_communicator_runtime_error("snap_communicator::snap_tcp_blocking_client_message_connection::run(): poll() failed because of memory");
8073 : }
8074 0 : int const e(errno);
8075 0 : throw snap_communicator_runtime_error(QString("snap_communicator::snap_tcp_blocking_client_message_connection::run(): poll() failed with error %1").arg(e));
8076 : }
8077 :
8078 0 : if(r == 0)
8079 : {
8080 0 : return;
8081 : }
8082 :
8083 0 : if((fd.revents & (POLLIN | POLLPRI)) != 0)
8084 : {
8085 : // read one character at a time otherwise we would be
8086 : // blocked forever
8087 : //
8088 : char buf[2];
8089 0 : int const size(::read(fd.fd, buf, 1));
8090 0 : if(size != 1)
8091 : {
8092 : // invalid read
8093 0 : process_error();
8094 0 : throw snap_communicator_runtime_error(QString("snap_communicator::snap_tcp_blocking_client_message_connection::run(): read() failed reading data from socket (return value = %1)").arg(size));
8095 : }
8096 0 : if(buf[0] == '\n')
8097 : {
8098 : // end of a line, we got a whole message in our buffer
8099 : // notice that we do not add the '\n' to line
8100 0 : break;
8101 : }
8102 0 : buf[1] = '\0';
8103 0 : f_line += buf;
8104 : }
8105 0 : if((fd.revents & POLLERR) != 0)
8106 : {
8107 0 : process_error();
8108 0 : return;
8109 : }
8110 0 : if((fd.revents & (POLLHUP | POLLRDHUP)) != 0)
8111 : {
8112 0 : process_hup();
8113 0 : return;
8114 : }
8115 0 : if((fd.revents & POLLNVAL) != 0)
8116 : {
8117 0 : process_invalid();
8118 0 : return;
8119 : }
8120 0 : }
8121 0 : process_line(QString::fromUtf8(f_line.c_str()));
8122 0 : f_line.clear();
8123 : }
8124 0 : while(!is_done());
8125 : }
8126 :
8127 :
8128 : /** \brief Send the specified message to the connection on the other end.
8129 : *
8130 : * This function sends the specified message to the other side of the
8131 : * socket connection. If the write somehow fails, then the function
8132 : * returns false.
8133 : *
8134 : * The function blocks until the entire message was written to the
8135 : * socket.
8136 : *
8137 : * \param[in] message The message to send to the connection.
8138 : * \param[in] cache Whether to cache the message if it cannot be sent
8139 : * immediately (ignored at the moment.)
8140 : *
8141 : * \return true if the message was sent succesfully, false otherwise.
8142 : */
8143 0 : bool snap_communicator::snap_tcp_blocking_client_message_connection::send_message(snap_communicator_message const & message, bool cache)
8144 : {
8145 0 : NOTUSED(cache);
8146 :
8147 0 : int const s(get_socket());
8148 0 : if(s >= 0)
8149 : {
8150 : // transform the message to a string and write to the socket
8151 : // the writing is blocking and thus fully synchronous so the
8152 : // function blocks until the message gets fully sent
8153 : //
8154 : // WARNING: we cannot use f_connection.write() because that one
8155 : // is asynchronous (at least, it writes to a buffer
8156 : // and not directly to the socket!)
8157 : //
8158 0 : QString const msg(message.to_message());
8159 0 : QByteArray const utf8(msg.toUtf8());
8160 0 : std::string buf(utf8.data(), utf8.size());
8161 0 : buf += "\n";
8162 0 : return ::write(s, buf.c_str(), buf.length()) == static_cast<ssize_t>(buf.length());
8163 : }
8164 :
8165 0 : return false;
8166 : }
8167 :
8168 :
8169 : /** \brief Overridden callback.
8170 : *
8171 : * This function is overriding the lower level process_error() to make
8172 : * (mostly) sure that the remove_from_communicator() function does not
8173 : * get called because that would generate the creation of a
8174 : * snap_communicator object which we do not want with blocking
8175 : * clients.
8176 : */
8177 0 : void snap_communicator::snap_tcp_blocking_client_message_connection::process_error()
8178 : {
8179 0 : }
8180 :
8181 :
8182 :
8183 :
8184 :
8185 :
8186 :
8187 :
8188 :
8189 : ///////////////////////
8190 : // Snap Communicator //
8191 : ///////////////////////
8192 :
8193 :
8194 : /** \brief Initialize a snap communicator object.
8195 : *
8196 : * This function initializes the snap_communicator object.
8197 : */
8198 0 : snap_communicator::snap_communicator()
8199 : //: f_connections() -- auto-init
8200 : //, f_force_sort(true) -- auto-init
8201 : {
8202 0 : }
8203 :
8204 :
8205 : /** \brief Retrieve the instance() of the snap_communicator.
8206 : *
8207 : * This function returns the instance of the snap_communicator.
8208 : * There is really no reason and it could also create all sorts
8209 : * of problems to have more than one instance hence we created
8210 : * the communicator as a singleton. It also means you cannot
8211 : * actually delete the communicator.
8212 : */
8213 0 : snap_communicator::pointer_t snap_communicator::instance()
8214 : {
8215 0 : if(!g_instance)
8216 : {
8217 0 : g_instance.reset(new snap_communicator);
8218 : }
8219 :
8220 0 : return g_instance;
8221 : }
8222 :
8223 :
8224 : /** \brief Retrieve a reference to the vector of connections.
8225 : *
8226 : * This function returns a reference to all the connections that are
8227 : * currently attached to the snap_communicator system.
8228 : *
8229 : * This is useful to search the array.
8230 : *
8231 : * \return The vector of connections.
8232 : */
8233 0 : snap_communicator::snap_connection::vector_t const & snap_communicator::get_connections() const
8234 : {
8235 0 : return f_connections;
8236 : }
8237 :
8238 :
8239 : /** \brief Attach a connection to the communicator.
8240 : *
8241 : * This function attaches a connection to the communicator. This allows
8242 : * us to execute code for that connection by having the process_signal()
8243 : * function called.
8244 : *
8245 : * Connections are kept in the order in which they are added. This may
8246 : * change the order in which connection callbacks are called. However,
8247 : * events are received asynchronously so do not expect callbacks to be
8248 : * called in any specific order.
8249 : *
8250 : * You may call this function with a null pointer. It simply returns
8251 : * false immediately. This makes it easy to eventually allocate a
8252 : * new connection and then use the return value of this function
8253 : * to know whether the two step process worked or not.
8254 : *
8255 : * \note
8256 : * A connection can only be added once to a snap_communicator object.
8257 : * Also it cannot be shared between multiple communicator objects.
8258 : *
8259 : * \param[in] connection The connection being added.
8260 : *
8261 : * \return true if the connection was added, false if the connection
8262 : * was already present in the communicator list of connections.
8263 : */
8264 0 : bool snap_communicator::add_connection(snap_connection::pointer_t connection)
8265 : {
8266 0 : if(connection == nullptr)
8267 : {
8268 0 : return false;
8269 : }
8270 :
8271 0 : if(!connection->valid_socket())
8272 : {
8273 0 : throw snap_communicator_parameter_error("snap_communicator::add_connection(): connection without a socket cannot be added to a snap_communicator object.");
8274 : }
8275 :
8276 0 : auto const it(std::find(f_connections.begin(), f_connections.end(), connection));
8277 0 : if(it != f_connections.end())
8278 : {
8279 : // already added, can be added only once but we allow multiple
8280 : // calls (however, we do not count those calls, so first call
8281 : // to the remove_connection() does remove it!)
8282 : //
8283 0 : return false;
8284 : }
8285 :
8286 0 : f_connections.push_back(connection);
8287 :
8288 0 : connection->connection_added();
8289 :
8290 0 : return true;
8291 : }
8292 :
8293 :
8294 : /** \brief Remove a connection from a snap_communicator object.
8295 : *
8296 : * This function removes a connection from this snap_communicator object.
8297 : * Note that any one connection can only be added once.
8298 : *
8299 : * \param[in] connection The connection to remove from this snap_communicator.
8300 : *
8301 : * \return true if the connection was removed, false if it was not found.
8302 : */
8303 0 : bool snap_communicator::remove_connection(snap_connection::pointer_t connection)
8304 : {
8305 0 : auto it(std::find(f_connections.begin(), f_connections.end(), connection));
8306 0 : if(it == f_connections.end())
8307 : {
8308 0 : return false;
8309 : }
8310 :
8311 0 : SNAP_LOG_TRACE("removing 1 connection, \"")(connection->get_name())("\", of ")(f_connections.size())(" connections (including this one.)");
8312 0 : f_connections.erase(it);
8313 :
8314 0 : connection->connection_removed();
8315 :
8316 : #if 0
8317 : #ifdef _DEBUG
8318 : std::for_each(
8319 : f_connections.begin()
8320 : , f_connections.end()
8321 : , [](auto const & c)
8322 : {
8323 : SNAP_LOG_TRACE("snap_communicator::remove_connection(): remaining connection: \"")(c->get_name())("\"");
8324 : });
8325 : #endif
8326 : #endif
8327 :
8328 0 : return true;
8329 : }
8330 :
8331 :
8332 : /** \brief Run until all connections are removed.
8333 : *
8334 : * This function "blocks" until all the events added to this
8335 : * snap_communicator instance are removed. Until then, it
8336 : * wakes up and run callback functions whenever an event occurs.
8337 : *
8338 : * In other words, you want to add_connection() before you call
8339 : * this function otherwise the function returns immediately.
8340 : *
8341 : * Note that you can include timeout events so if you need to
8342 : * run some code once in a while, you may just use a timeout
8343 : * event and process your repetitive events that way.
8344 : *
8345 : * \return true if the loop exits because the list of connections is empty.
8346 : */
8347 0 : bool snap_communicator::run()
8348 : {
8349 : // the loop promises to exit once the even_base object has no
8350 : // more connections attached to it
8351 : //
8352 0 : std::vector<bool> enabled;
8353 0 : std::vector<struct pollfd> fds;
8354 0 : f_force_sort = true;
8355 : for(;;)
8356 : {
8357 : // any connections?
8358 0 : if(f_connections.empty())
8359 : {
8360 0 : return true;
8361 : }
8362 :
8363 0 : if(f_force_sort)
8364 : {
8365 : // sort the connections by priority
8366 : //
8367 0 : std::stable_sort(f_connections.begin(), f_connections.end(), snap_connection::compare);
8368 0 : f_force_sort = false;
8369 : }
8370 :
8371 : // make a copy because the callbacks may end up making
8372 : // changes to the main list and we would have problems
8373 : // with that here...
8374 : //
8375 0 : snap_connection::vector_t connections(f_connections);
8376 0 : size_t max_connections(connections.size());
8377 :
8378 : // timeout is do not time out by default
8379 : //
8380 0 : int64_t next_timeout_timestamp(std::numeric_limits<int64_t>::max());
8381 :
8382 : // clear() is not supposed to delete the buffer of vectors
8383 : //
8384 0 : enabled.clear();
8385 0 : fds.clear();
8386 0 : fds.reserve(max_connections); // avoid more than 1 allocation
8387 0 : for(size_t idx(0); idx < max_connections; ++idx)
8388 : {
8389 0 : snap_connection::pointer_t c(connections[idx]);
8390 0 : c->f_fds_position = -1;
8391 :
8392 : // is the connection enabled?
8393 : //
8394 : // note that we save that value for later use in our loop
8395 : // below because otherwise we will miss many events and
8396 : // it tends to break things; that means you may get your
8397 : // callback called even while disabled
8398 : //
8399 0 : enabled.push_back(c->is_enabled());
8400 0 : if(!enabled[idx])
8401 : {
8402 : //SNAP_LOG_TRACE("snap_communicator::run(): connection '")(c->get_name())("' has been disabled, so ignored.");
8403 0 : continue;
8404 : }
8405 : //SNAP_LOG_TRACE("snap_communicator::run(): handling connection ")(idx)("/")(max_connections)(". '")(c->get_name())("' since it is enabled...");
8406 :
8407 : // check whether a timeout is defined in this connection
8408 : //
8409 0 : int64_t const timestamp(c->save_timeout_timestamp());
8410 0 : if(timestamp != -1)
8411 : {
8412 : // the timeout event gives us a time when to tick
8413 : //
8414 0 : if(timestamp < next_timeout_timestamp)
8415 : {
8416 0 : next_timeout_timestamp = timestamp;
8417 : }
8418 : }
8419 :
8420 : // is there any events to listen on?
8421 0 : int e(0);
8422 0 : if(c->is_listener() || c->is_signal())
8423 : {
8424 0 : e |= POLLIN;
8425 : }
8426 0 : if(c->is_reader())
8427 : {
8428 0 : e |= POLLIN | POLLPRI | POLLRDHUP;
8429 : }
8430 0 : if(c->is_writer())
8431 : {
8432 0 : e |= POLLOUT | POLLRDHUP;
8433 : }
8434 0 : if(e == 0)
8435 : {
8436 : // this should only happend on snap_timer objects
8437 : //
8438 0 : continue;
8439 : }
8440 :
8441 : // do we have a currently valid socket? (i.e. the connection
8442 : // may have been closed or we may be handling a timer or
8443 : // signal object)
8444 : //
8445 0 : if(c->get_socket() < 0)
8446 : {
8447 0 : continue;
8448 : }
8449 :
8450 : // this is considered valid, add this connection to the list
8451 : //
8452 : // save the position since we may skip some entries...
8453 : // (otherwise we would have to use -1 as the socket to
8454 : // allow for such dead entries, but avoiding such entries
8455 : // saves time)
8456 : //
8457 0 : c->f_fds_position = fds.size();
8458 :
8459 : //SNAP_LOG_ERROR("*** still waiting on \"")(c->get_name())("\".");
8460 : struct pollfd fd;
8461 0 : fd.fd = c->get_socket();
8462 0 : fd.events = e;
8463 0 : fd.revents = 0; // probably useless... (kernel should clear those)
8464 0 : fds.push_back(fd);
8465 : }
8466 :
8467 : // compute the right timeout
8468 0 : int64_t timeout(-1);
8469 0 : if(next_timeout_timestamp != std::numeric_limits<int64_t>::max())
8470 : {
8471 0 : int64_t const now(get_current_date());
8472 0 : timeout = next_timeout_timestamp - now;
8473 0 : if(timeout < 0)
8474 : {
8475 : // timeout is in the past so timeout immediately, but
8476 : // still check for events if any
8477 0 : timeout = 0;
8478 : }
8479 : else
8480 : {
8481 : // convert microseconds to milliseconds for poll()
8482 0 : timeout /= 1000;
8483 0 : if(timeout == 0)
8484 : {
8485 : // less than one is a waste of time (CPU intenssive
8486 : // until the time is reached, we can be 1 ms off
8487 : // instead...)
8488 0 : timeout = 1;
8489 : }
8490 : }
8491 : }
8492 0 : else if(fds.empty())
8493 : {
8494 0 : SNAP_LOG_FATAL("snap_communicator::run(): nothing to poll() on. All connections are disabled? (Ignoring ")
8495 0 : (max_connections)(" and exiting the run() loop anyway.)");
8496 0 : return false;
8497 : }
8498 :
8499 : //SNAP_LOG_TRACE("snap_communicator::run(): ")
8500 : // ("count ")(fds.size())
8501 : // ("timeout ")(timeout)
8502 : // (" (next was: ")(next_timeout_timestamp)
8503 : // (", current ~ ")(get_current_date())
8504 : // (")");
8505 :
8506 : // TODO: add support for ppoll() so we can support signals cleanly
8507 : // with nearly no additional work from us
8508 : //
8509 0 : errno = 0;
8510 0 : int const r(poll(&fds[0], fds.size(), timeout));
8511 0 : if(r >= 0)
8512 : {
8513 : // quick sanity check
8514 : //
8515 0 : if(static_cast<size_t>(r) > connections.size())
8516 : {
8517 0 : throw snap_communicator_runtime_error("snap_communicator::run(): poll() returned a number of events to handle larger than the input allows");
8518 : }
8519 : //SNAP_LOG_TRACE("tid=")(gettid())(", snap_communicator::run(): ------------------- new set of ")(r)(" events to handle");
8520 :
8521 : // check each connection one by one for:
8522 : //
8523 : // 1) fds events, including signals
8524 : // 2) timeouts
8525 : //
8526 : // and execute the corresponding callbacks
8527 : //
8528 0 : for(size_t idx(0); idx < connections.size(); ++idx)
8529 : {
8530 0 : snap_connection::pointer_t c(connections[idx]);
8531 :
8532 : // is the connection enabled?
8533 : //
8534 : // note that we check whether that connection was enabled
8535 : // before poll() was called; this is very important because
8536 : // the last poll() events must be run even if a previous
8537 : // callback call just disabled this very connection
8538 : // (i.e. at the time we called poll() the connection was
8539 : // still enabled and therefore we are expected to call
8540 : // their callbacks even if it just got disabled by an
8541 : // earlier callback)
8542 : //
8543 0 : if(!enabled[idx])
8544 : {
8545 : //SNAP_LOG_TRACE("snap_communicator::run(): in loop, connection '")(c->get_name())("' has been disabled, so ignored!");
8546 0 : continue;
8547 : }
8548 :
8549 : // if we have a valid fds position then an event other
8550 : // than a timeout occurred on that connection
8551 : //
8552 0 : if(c->f_fds_position >= 0)
8553 : {
8554 0 : struct pollfd * fd(&fds[c->f_fds_position]);
8555 :
8556 : // if any events were found by poll(), process them now
8557 : //
8558 0 : if(fd->revents != 0)
8559 : {
8560 : // an event happened on this one
8561 : //
8562 0 : if((fd->revents & (POLLIN | POLLPRI)) != 0)
8563 : {
8564 : // we consider that Unix signals have the greater priority
8565 : // and thus handle them first
8566 : //
8567 0 : if(c->is_signal())
8568 : {
8569 0 : snap_signal * ss(dynamic_cast<snap_signal *>(c.get()));
8570 0 : if(ss)
8571 : {
8572 0 : ss->process();
8573 : }
8574 : }
8575 0 : else if(c->is_listener())
8576 : {
8577 : // a listener is a special case and we want
8578 : // to call process_accept() instead
8579 : //
8580 0 : c->process_accept();
8581 : }
8582 : else
8583 : {
8584 0 : c->process_read();
8585 : }
8586 : }
8587 0 : if((fd->revents & POLLOUT) != 0)
8588 : {
8589 0 : c->process_write();
8590 : }
8591 0 : if((fd->revents & POLLERR) != 0)
8592 : {
8593 0 : c->process_error();
8594 : }
8595 0 : if((fd->revents & (POLLHUP | POLLRDHUP)) != 0)
8596 : {
8597 0 : c->process_hup();
8598 : }
8599 0 : if((fd->revents & POLLNVAL) != 0)
8600 : {
8601 0 : c->process_invalid();
8602 : }
8603 : }
8604 : }
8605 :
8606 : // now check whether we have a timeout on this connection
8607 : //
8608 0 : int64_t const timestamp(c->get_saved_timeout_timestamp());
8609 0 : if(timestamp != -1)
8610 : {
8611 0 : int64_t const now(get_current_date());
8612 0 : if(now >= timestamp)
8613 : {
8614 : //SNAP_LOG_TRACE("snap_communicator::run(): timer of connection = '")(c->get_name())
8615 : // ("', timestamp = ")(timestamp)
8616 : // (", now = ")(now)
8617 : // (", now >= timestamp --> ")(now >= timestamp ? "TRUE (timed out!)" : "FALSE");
8618 :
8619 : // move the timeout as required first
8620 : // (because the callback may move it again)
8621 : //
8622 0 : c->calculate_next_tick();
8623 :
8624 : // the timeout date needs to be reset if the tick
8625 : // happened for that date
8626 : //
8627 0 : if(now >= c->get_timeout_date())
8628 : {
8629 0 : c->set_timeout_date(-1);
8630 : }
8631 :
8632 : // then run the callback
8633 : //
8634 0 : c->process_timeout();
8635 : }
8636 : }
8637 : }
8638 : }
8639 : else
8640 : {
8641 : // r < 0 means an error occurred
8642 : //
8643 0 : if(errno == EINTR)
8644 : {
8645 : // Note: if the user wants to prevent this error, he should
8646 : // use the snap_signal with the Unix signals that may
8647 : // happen while calling poll().
8648 : //
8649 0 : throw snap_communicator_runtime_error("snap_communicator::run(): EINTR occurred while in poll() -- interrupts are not supported yet though");
8650 : }
8651 0 : if(errno == EFAULT)
8652 : {
8653 0 : throw snap_communicator_parameter_error("snap_communicator::run(): buffer was moved out of our address space?");
8654 : }
8655 0 : if(errno == EINVAL)
8656 : {
8657 : // if this is really because nfds is too large then it may be
8658 : // a "soft" error that can be fixed; that being said, my
8659 : // current version is 16K files which frankly when we reach
8660 : // that level we have a problem...
8661 : //
8662 : struct rlimit rl;
8663 0 : getrlimit(RLIMIT_NOFILE, &rl);
8664 0 : throw snap_communicator_parameter_error(QString("snap_communicator::run(): too many file fds for poll, limit is currently %1, your kernel top limit is %2")
8665 0 : .arg(rl.rlim_cur)
8666 0 : .arg(rl.rlim_max));
8667 : }
8668 0 : if(errno == ENOMEM)
8669 : {
8670 0 : throw snap_communicator_runtime_error("snap_communicator::run(): poll() failed because of memory");
8671 : }
8672 0 : int const e(errno);
8673 0 : throw snap_communicator_runtime_error(QString("snap_communicator::run(): poll() failed with error %1").arg(e));
8674 : }
8675 0 : }
8676 : }
8677 :
8678 :
8679 :
8680 :
8681 :
8682 : /** \brief Get the current date.
8683 : *
8684 : * This function retrieves the current date and time with a precision
8685 : * to the microseconds.
8686 : *
8687 : * \todo
8688 : * This is also defined in snap_child::get_current_date() so we should
8689 : * unify that in some way...
8690 : */
8691 0 : int64_t snap_communicator::get_current_date()
8692 : {
8693 : struct timeval tv;
8694 0 : if(gettimeofday(&tv, nullptr) != 0)
8695 : {
8696 0 : int const err(errno);
8697 0 : SNAP_LOG_FATAL("gettimeofday() failed with errno: ")(err);
8698 0 : throw std::runtime_error("gettimeofday() failed");
8699 : }
8700 0 : return static_cast<int64_t>(tv.tv_sec) * static_cast<int64_t>(1000000)
8701 0 : + static_cast<int64_t>(tv.tv_usec);
8702 : }
8703 :
8704 :
8705 :
8706 :
8707 :
8708 6 : } // namespace snap
8709 : // vim: ts=4 sw=4 et
|