LCOV - code coverage report
Current view: top level - snapwebsites - snap_communicator.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 2 1870 0.1 %
Date: 2019-12-15 17:13:15 Functions: 2 295 0.7 %
Legend: Lines: hit not hit

          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

Generated by: LCOV version 1.13