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

          Line data    Source code
       1             : // TCP Client & Server -- classes to ease handling sockets
       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             : // self
      19             : //
      20             : #include "snapwebsites/tcp_client_server.h"
      21             : 
      22             : 
      23             : // snapwebsites lib
      24             : //
      25             : #include "snapwebsites/log.h"
      26             : 
      27             : 
      28             : // snapdev lib
      29             : //
      30             : #include <snapdev/not_reached.h>
      31             : #include <snapdev/not_used.h>
      32             : #include <snapdev/raii_generic_deleter.h>
      33             : 
      34             : 
      35             : // C++
      36             : //
      37             : #include <sstream>
      38             : #include <iomanip>
      39             : 
      40             : 
      41             : // C lib
      42             : //
      43             : #include <netdb.h>
      44             : #include <netinet/tcp.h>
      45             : #include <poll.h>
      46             : #include <string.h>
      47             : #include <sys/ioctl.h>
      48             : #include <sys/socket.h>
      49             : #include <sys/types.h>
      50             : #include <unistd.h>
      51             : 
      52             : 
      53             : // last include
      54             : //
      55             : #include <snapdev/poison.h>
      56             : 
      57             : 
      58             : 
      59             : 
      60             : #ifndef OPENSSL_THREADS
      61             : #error "OPENSSL_THREADS is not defined. Snap! requires support for multiple threads in OpenSSL."
      62             : #endif
      63             : 
      64             : namespace tcp_client_server
      65             : {
      66             : 
      67             : 
      68             : namespace
      69             : {
      70             : 
      71             : /** \brief Address info class to auto-free the structures.
      72             :  *
      73             :  * This class is used so we can auto-free the addrinfo structure(s)
      74             :  * because otherwise we find ourselves with many freeaddrinfo()
      75             :  * calls (and that's not safe in case you have exceptions.)
      76             :  */
      77             : typedef std::unique_ptr<struct addrinfo, snap::raii_pointer_deleter<struct addrinfo, decltype(&::freeaddrinfo), &::freeaddrinfo>> addrinfo_t;
      78             : 
      79             : 
      80             : 
      81             : 
      82             : /** \brief Data handled by each lock.
      83             :  *
      84             :  * This function holds the data handled on a per lock basis.
      85             :  * Even if your daemon is not using multiple threads, this
      86             :  * is likely to kick in.
      87             :  */
      88             : class crypto_lock_t
      89             : {
      90             : public:
      91             :     typedef std::vector<crypto_lock_t>  vector_t;
      92             : 
      93           0 :                         crypto_lock_t()
      94           0 :                         {
      95           0 :                             pthread_mutex_init(&f_mutex, nullptr);
      96           0 :                         }
      97             : 
      98           0 :                         ~crypto_lock_t()
      99           0 :                         {
     100           0 :                             pthread_mutex_destroy(&f_mutex);
     101           0 :                         }
     102             : 
     103           0 :     void                lock()
     104             :                         {
     105           0 :                             pthread_mutex_lock(&f_mutex);
     106           0 :                         }
     107             : 
     108           0 :     void                unlock()
     109             :                         {
     110           0 :                             pthread_mutex_unlock(&f_mutex);
     111           0 :                         }
     112             : 
     113             : private:
     114             :     pthread_mutex_t     f_mutex = pthread_mutex_t();
     115             : };
     116             : 
     117             : 
     118             : /** \brief The vector of locks.
     119             :  *
     120             :  * This function is initialized by the crypto_thread_setup().
     121             :  *
     122             :  * It is defined as a pointer in case someone was to try to access this
     123             :  * pointer before entering main().
     124             :  */
     125             : crypto_lock_t::vector_t *   g_locks = nullptr;
     126             : 
     127             : 
     128             : /** \brief Retrieve the system thread identifier.
     129             :  *
     130             :  * This function is used by the OpenSSL library to attach an internal thread
     131             :  * identifier (\p tid) to a system thread identifier.
     132             :  *
     133             :  * \param[in] tid  The crypto internal thread identifier.
     134             :  */
     135           0 : void pthreads_thread_id(CRYPTO_THREADID * tid)
     136             : {
     137             :     // on 19.04 the macro does not use tid
     138             :     //
     139           0 :     snap::NOTUSED(tid);
     140             : 
     141             :     CRYPTO_THREADID_set_numeric(tid, static_cast<unsigned long>(pthread_self()));
     142           0 : }
     143             : 
     144             : 
     145             : /** \brief Handle locks and unlocks.
     146             :  *
     147             :  * This function is a callback used to lock and unlock mutexes as required.
     148             :  *
     149             :  * \param[in] mode  Whether lock or unlock in read or write mode.
     150             :  * \param[in] type  The "type" of lock (i.e. the index).
     151             :  * \param[in] file  The filename of the source asking for a lock/unlock.
     152             :  * \param[in] line  The line number in file where the call was made.
     153             :  */
     154           0 : void pthreads_locking_callback(int mode, int type, char const * file, int line)
     155             : {
     156           0 :     snap::NOTUSED(file);
     157           0 :     snap::NOTUSED(line);
     158             : 
     159           0 :     if(g_locks == nullptr)
     160             :     {
     161           0 :         throw tcp_client_server_initialization_missing_error("g_locks was not initialized");
     162             :     }
     163             : 
     164             : /*
     165             : # ifdef undef
     166             :     BIO_printf(bio_err, "thread=%4d mode=%s lock=%s %s:%d\n",
     167             :                CRYPTO_thread_id(),
     168             :                (mode & CRYPTO_LOCK) ? "l" : "u",
     169             :                (type & CRYPTO_READ) ? "r" : "w", file, line);
     170             : # endif
     171             :     if (CRYPTO_LOCK_SSL_CERT == type)
     172             :             BIO_printf(bio_err,"(t,m,f,l) %ld %d %s %d\n",
     173             :                        CRYPTO_thread_id(),
     174             :                        mode,file,line);
     175             : */
     176             : 
     177             :     // Note: at this point we ignore READ | WRITE because we do not have
     178             :     //       such a concept with a simple mutex; we could take those in
     179             :     //       account with a semaphore though.
     180             :     //
     181           0 :     if((mode & CRYPTO_LOCK) != 0)
     182             :     {
     183           0 :         (*g_locks)[type].lock();
     184             :     }
     185             :     else
     186             :     {
     187           0 :         (*g_locks)[type].unlock();
     188             :     }
     189           0 : }
     190             : 
     191             : 
     192             : /** \brief This function is called once on initialization.
     193             :  *
     194             :  * This function is called when the bio_initialize() function. It is
     195             :  * expected that the bio_initialize() function is called once by the
     196             :  * main thread before any other thread has a chance to do so.
     197             :  */
     198           0 : void crypto_thread_setup()
     199             : {
     200           0 :     if(g_locks != nullptr)
     201             :     {
     202           0 :         throw tcp_client_server_initialization_error("crypto_thread_setup() called for the second time. This usually means two threads are initializing the BIO environment simultaneously.");
     203             :     }
     204             : 
     205           0 :     g_locks = new crypto_lock_t::vector_t(CRYPTO_num_locks());
     206             : 
     207             :     CRYPTO_THREADID_set_callback(pthreads_thread_id);
     208             :     CRYPTO_set_locking_callback(pthreads_locking_callback);
     209           0 : }
     210             : 
     211             : 
     212             : /** \brief This function cleans up the thread setup.
     213             :  *
     214             :  * This function could be called to clean up the setup created to support
     215             :  * multiple threads running with the OpenSSL library.
     216             :  *
     217             :  * \note
     218             :  * At this time this function never gets called.
     219             :  */
     220           0 : void thread_cleanup()
     221             : {
     222             :     CRYPTO_set_locking_callback(nullptr);
     223             : 
     224           0 :     delete g_locks;
     225           0 :     g_locks = nullptr;
     226           0 : }
     227             : 
     228             : 
     229             : /** \brief This function cleans up the error state of a thread.
     230             :  *
     231             :  * Whenever the OpenSSL system runs in a thread, it may create a
     232             :  * state to save various information, especially its error queue.
     233             :  *
     234             :  * This function should be called before your
     235             :  * snap::snap_thread::snap_runner::run()
     236             :  * function returns.
     237             :  */
     238           0 : void per_thread_cleanup()
     239             : {
     240             : #if __cplusplus < 201700
     241             :     // this function is not necessary in newer versions of OpenSSL
     242             :     //
     243             :     ERR_remove_thread_state(nullptr);
     244             : #endif
     245           0 : }
     246             : 
     247             : 
     248             : 
     249             : 
     250             : /** \brief Whether the bio_initialize() function was already called.
     251             :  *
     252             :  * This flag is used to know whether the bio_initialize() function was
     253             :  * already called. Only the bio_initialize() function is expected to
     254             :  * make use of this flag. Other functions should simply call the
     255             :  * bio_initialize() function (future versions may include addition
     256             :  * flags or use various bits in an integer instead.)
     257             :  */
     258             : bool g_bio_initialized = false;
     259             : 
     260             : 
     261             : /** \brief Initialize the BIO library.
     262             :  *
     263             :  * This function is called by the BIO implementations to initialize the
     264             :  * BIO library as required. It can be called any number of times. The
     265             :  * initialization will happen only once.
     266             :  */
     267           0 : void bio_initialize()
     268             : {
     269             :     // TBD: I don't think we could have a lock here that would be safe?
     270             :     // i.e. a `static std::mutex;` variable c ould not be guaranteed that
     271             :     // it is initialized only by on single thread; at this point, if you
     272             :     // are using multiple threads that use the BIO interface together,
     273             :     // you have to initialize one BIO object before you create the first
     274             :     // thread to ensure it is secure, or you have to have your own
     275             :     // secured call to all BIO object creation (once created, they can
     276             :     // be used concurrently) -- See SNAP-628 too.
     277             :     //
     278             : 
     279             :     // already initialized?
     280             :     //
     281           0 :     if(g_bio_initialized)
     282             :     {
     283           0 :         return;
     284             :     }
     285           0 :     g_bio_initialized = true;
     286             : 
     287             :     // Make sure the SSL library gets initialized
     288             :     //
     289           0 :     SSL_library_init();
     290             : 
     291             :     // TBD: should we call the load string functions only when we
     292             :     //      are about to generate the first error?
     293             :     //
     294           0 :     ERR_load_crypto_strings();
     295           0 :     ERR_load_SSL_strings();
     296           0 :     SSL_load_error_strings();
     297             : 
     298             :     // TODO: define a way to only define safe algorithms?
     299             :     //       (it looks like we can force TLSv1.2 below at least)
     300             :     //
     301           0 :     OpenSSL_add_all_algorithms();
     302             : 
     303             :     // TBD: need a PRNG seeding before creating a new SSL context?
     304             : 
     305             :     // then initialize the library so it works in a multithreaded
     306             :     // environment
     307             :     //
     308           0 :     crypto_thread_setup();
     309             : }
     310             : 
     311             : 
     312             : /** \brief Clean up the BIO environment.
     313             :  *
     314             :  * This function cleans up the BIO environment.
     315             :  *
     316             :  * \note
     317             :  * This function is here mainly for documentation rather than to get called.
     318             :  * Whenever you exit a process that uses the BIO calls it will leak
     319             :  * a few things. To make the process really spanking clean, you want
     320             :  * to call this function before exit(3). You have to make sure that
     321             :  * you call this function only after every single BIO object was
     322             :  * closed and none must be opened after this call.
     323             :  */
     324           0 : void bio_cleanup()
     325             : {
     326             : #if __cplusplus < 201700
     327             :     // this function is not necessary in newer versions of OpenSSL
     328             :     //
     329             :     ERR_remove_state(0);
     330             : #endif
     331             : 
     332             :     EVP_cleanup();
     333             :     CRYPTO_cleanup_all_ex_data();
     334             :     ERR_free_strings();
     335           0 : }
     336             : 
     337             : 
     338             : /** \brief Get all the error messages and output them in our logs.
     339             :  *
     340             :  * This function reads all existing errors from the OpenSSL library
     341             :  * and send them to our logs.
     342             :  *
     343             :  * \param[in] sni  Whether SNI is ON (true) or OFF (false).
     344             :  */
     345           0 : int bio_log_errors()
     346             : {
     347             :     // allow for up to 5 errors in one go, but we have a HUGE problem
     348             :     // at this time as in some cases the same error is repeated forever
     349             :     //
     350           0 :     for(int i(0);; ++i)
     351             :     {
     352           0 :         char const * filename(nullptr);
     353           0 :         int line(0);
     354           0 :         char const * data(nullptr);
     355           0 :         int flags(0);
     356           0 :         unsigned long bio_errno(ERR_get_error_line_data(&filename, &line, &data, &flags));
     357           0 :         if(bio_errno == 0)
     358             :         {
     359             :             // no more errors
     360             :             //
     361           0 :             return i;
     362             :         }
     363             : 
     364             :         // get corresponding messages too
     365             :         //
     366             :         // Note: current OpenSSL documentation on Ubuntu says errmsg[]
     367             :         //       should be at least 120 characters BUT the code actually
     368             :         //       use a limit of 256...
     369             :         //
     370             :         char errmsg[256];
     371           0 :         ERR_error_string_n(bio_errno, errmsg, sizeof(errmsg) / sizeof(errmsg[0]));
     372             :         // WARNING: the ERR_error_string() function is NOT multi-thread safe
     373             : 
     374             : #pragma GCC diagnostic push
     375             : #pragma GCC diagnostic ignored "-Wold-style-cast"
     376           0 :         int const lib_num(ERR_GET_LIB(bio_errno));
     377           0 :         int const func_num(ERR_GET_FUNC(bio_errno));
     378             : #pragma GCC diagnostic pop
     379           0 :         char const * lib_name(ERR_lib_error_string(lib_num));
     380           0 :         char const * func_name(ERR_func_error_string(func_num));
     381           0 :         int const reason_num(ERR_GET_REASON(bio_errno));
     382           0 :         char const * reason(ERR_reason_error_string(reason_num));
     383             : 
     384           0 :         if(lib_name == nullptr)
     385             :         {
     386           0 :             lib_name = "<no libname>";
     387             :         }
     388           0 :         if(func_name == nullptr)
     389             :         {
     390           0 :             func_name = "<no funcname>";
     391             :         }
     392           0 :         if(reason == nullptr)
     393             :         {
     394           0 :             reason = "<no reason>";
     395             :         }
     396             : 
     397             :         // the format used by the OpenSSL library is as follow:
     398             :         //
     399             :         //     [pid]:error:[error code]:[library name]:[function name]:[reason string]:[file name]:[line]:[optional text message]
     400             :         //
     401             :         // we do not duplicate the [pid] and "error" but include all the
     402             :         // other fields
     403             :         //
     404           0 :         SNAP_LOG_ERROR("OpenSSL: [")
     405           0 :                       (bio_errno) // should be shown in hex...
     406           0 :                       ("/")
     407           0 :                       (lib_num)
     408           0 :                       ("|")
     409           0 :                       (func_num)
     410           0 :                       ("|")
     411           0 :                       (reason_num)
     412           0 :                       ("]:[")
     413           0 :                       (lib_name)
     414           0 :                       ("]:[")
     415           0 :                       (func_name)
     416           0 :                       ("]:[")
     417           0 :                       (reason)
     418           0 :                       ("]:[")
     419           0 :                       (filename)
     420           0 :                       ("]:[")
     421           0 :                       (line)
     422           0 :                       ("]:[")
     423           0 :                       ((flags & ERR_TXT_STRING) != 0 && data != nullptr ? data : "(no details)")
     424           0 :                       ("]");
     425           0 :     }
     426             : }
     427             : 
     428             : 
     429             : /** \brief Free a BIO object.
     430             :  *
     431             :  * This deleter is used to make sure that the BIO object gets freed
     432             :  * whenever the object holding it gets destroyed.
     433             :  *
     434             :  * Note that deleting a BIO connection calls shutdown() and close()
     435             :  * on the socket. In other words, it hangs up.
     436             :  *
     437             :  * \param[in] bio  The BIO object to be freed.
     438             :  */
     439           0 : void bio_deleter(BIO * bio)
     440             : {
     441             :     // IMPORTANT NOTE:
     442             :     //
     443             :     //   The BIO_free_all() calls shutdown() on the socket. This is not
     444             :     //   acceptable in a normal Unix application that makes use of fork().
     445             :     //   So... instead we ask the BIO interface to not close the socket,
     446             :     //   and instead we close it ourselves. This means the shutdown()
     447             :     //   never gets called.
     448             :     //
     449           0 :     BIO_set_close(bio, BIO_NOCLOSE);
     450             : 
     451             :     int c;
     452             : #pragma GCC diagnostic push
     453             : #pragma GCC diagnostic ignored "-Wold-style-cast"
     454           0 :     BIO_get_fd(bio, &c);
     455             : #pragma GCC diagnostic pop
     456           0 :     if(c != -1)
     457             :     {
     458           0 :         close(c);
     459             :     }
     460             : 
     461           0 :     BIO_free_all(bio);
     462           0 : }
     463             : 
     464             : 
     465             : /** \brief Free an SSL_CTX object.
     466             :  *
     467             :  * This deleter is used to make sure that the SSL_CTX object gets
     468             :  * freed whenever the object holding it gets destroyed.
     469             :  */
     470           0 : void ssl_ctx_deleter(SSL_CTX * ssl_ctx)
     471             : {
     472           0 :     SSL_CTX_free(ssl_ctx);
     473           0 : }
     474             : 
     475             : 
     476             : }
     477             : // no name namespace
     478             : 
     479             : 
     480             : 
     481             : // ========================= CLIENT =========================
     482             : 
     483             : 
     484             : /** \class tcp_client
     485             :  * \brief Create a client socket and connect to a server.
     486             :  *
     487             :  * This class is a client socket implementation used to connect to a server.
     488             :  * The server is expected to be running at the time the client is created
     489             :  * otherwise it fails connecting.
     490             :  *
     491             :  * This class is not appropriate to connect to a server that may come and go
     492             :  * over time.
     493             :  */
     494             : 
     495             : /** \brief Contruct a tcp_client object.
     496             :  *
     497             :  * The tcp_client constructor initializes a TCP client object by connecting
     498             :  * to the specified server. The server is defined with the \p addr and
     499             :  * \p port specified as parameters.
     500             :  *
     501             :  * \exception tcp_client_server_parameter_error
     502             :  * This exception is raised if the \p port parameter is out of range or the
     503             :  * IP address is an empty string or otherwise an invalid address.
     504             :  *
     505             :  * \exception tcp_client_server_runtime_error
     506             :  * This exception is raised if the client cannot create the socket or it
     507             :  * cannot connect to the server.
     508             :  *
     509             :  * \param[in] addr  The address of the server to connect to. It must be valid.
     510             :  * \param[in] port  The port the server is listening on.
     511             :  */
     512           0 : tcp_client::tcp_client(std::string const & addr, int port)
     513             :     : f_socket(-1)
     514             :     , f_port(port)
     515           0 :     , f_addr(addr)
     516             : {
     517           0 :     if(f_port < 0 || f_port >= 65536)
     518             :     {
     519           0 :         throw tcp_client_server_parameter_error("invalid port for a client socket");
     520             :     }
     521           0 :     if(f_addr.empty())
     522             :     {
     523           0 :         throw tcp_client_server_parameter_error("an empty address is not valid for a client socket");
     524             :     }
     525             : 
     526           0 :     std::stringstream decimal_port;
     527           0 :     decimal_port << f_port;
     528             :     struct addrinfo hints;
     529           0 :     memset(&hints, 0, sizeof(hints));
     530           0 :     hints.ai_family = AF_UNSPEC;
     531           0 :     hints.ai_socktype = SOCK_STREAM;
     532           0 :     hints.ai_protocol = IPPROTO_TCP;
     533           0 :     std::string port_str(decimal_port.str());
     534           0 :     struct addrinfo * addrinfo(nullptr);
     535           0 :     int const r(getaddrinfo(addr.c_str(), port_str.c_str(), &hints, &addrinfo));
     536           0 :     addrinfo_t addr_info(addrinfo);
     537           0 :     if(r != 0
     538           0 :     || addrinfo == nullptr)
     539             :     {
     540           0 :         int const e(errno);
     541           0 :         SNAP_LOG_FATAL("getaddrinfo() failed to parse the address and port strings (errno: ")(e)(" -- ")(strerror(e))(")");
     542           0 :         throw tcp_client_server_runtime_error("invalid address or port: \"" + addr + ":" + port_str + "\"");
     543             :     }
     544             : 
     545           0 :     f_socket = socket(addr_info.get()->ai_family, SOCK_STREAM, IPPROTO_TCP);
     546           0 :     if(f_socket < 0)
     547             :     {
     548           0 :         int const e(errno);
     549           0 :         SNAP_LOG_FATAL("socket() failed to create a socket descriptor (errno: ")(e)(" -- ")(strerror(e))(")");
     550           0 :         throw tcp_client_server_runtime_error("could not create socket for client");
     551             :     }
     552             : 
     553           0 :     if(connect(f_socket, addr_info.get()->ai_addr, addr_info.get()->ai_addrlen) < 0)
     554             :     {
     555           0 :         int const e(errno);
     556           0 :         SNAP_LOG_FATAL("connect() failed to connect a socket (errno: ")(e)(" -- ")(strerror(e))(")");
     557           0 :         close(f_socket);
     558           0 :         throw tcp_client_server_runtime_error("could not connect client socket to \"" + f_addr + "\"");
     559             :     }
     560           0 : }
     561             : 
     562             : /** \brief Clean up the TCP client object.
     563             :  *
     564             :  * This function cleans up the TCP client object by closing the attached socket.
     565             :  *
     566             :  * \note
     567             :  * DO NOT use the shutdown() call since we may end up forking and using
     568             :  * that connection in the child.
     569             :  */
     570           0 : tcp_client::~tcp_client()
     571             : {
     572           0 :     close(f_socket);
     573           0 : }
     574             : 
     575             : /** \brief Get the socket descriptor.
     576             :  *
     577             :  * This function returns the TCP client socket descriptor. This can be
     578             :  * used to change the descriptor behavior (i.e. make it non-blocking for
     579             :  * example.)
     580             :  *
     581             :  * \return The socket descriptor.
     582             :  */
     583           0 : int tcp_client::get_socket() const
     584             : {
     585           0 :     return f_socket;
     586             : }
     587             : 
     588             : /** \brief Get the TCP client port.
     589             :  *
     590             :  * This function returns the port used when creating the TCP client.
     591             :  * Note that this is the port the server is listening to and not the port
     592             :  * the TCP client is currently connected to.
     593             :  *
     594             :  * \return The TCP client port.
     595             :  */
     596           0 : int tcp_client::get_port() const
     597             : {
     598           0 :     return f_port;
     599             : }
     600             : 
     601             : /** \brief Get the TCP server address.
     602             :  *
     603             :  * This function returns the address used when creating the TCP address as is.
     604             :  * Note that this is the address of the server where the client is connected
     605             :  * and not the address where the client is running (although it may be the
     606             :  * same.)
     607             :  *
     608             :  * Use the get_client_addr() function to retrieve the client's TCP address.
     609             :  *
     610             :  * \return The TCP client address.
     611             :  */
     612           0 : std::string tcp_client::get_addr() const
     613             : {
     614           0 :     return f_addr;
     615             : }
     616             : 
     617             : /** \brief Get the TCP client port.
     618             :  *
     619             :  * This function retrieve the port of the client (used on your computer).
     620             :  * This is retrieved from the socket using the getsockname() function.
     621             :  *
     622             :  * \return The port or -1 if it cannot be determined.
     623             :  */
     624           0 : int tcp_client::get_client_port() const
     625             : {
     626             :     struct sockaddr addr;
     627           0 :     socklen_t len(sizeof(addr));
     628           0 :     int r(getsockname(f_socket, &addr, &len));
     629           0 :     if(r != 0)
     630             :     {
     631           0 :         return -1;
     632             :     }
     633             :     // Note: I know the port is at the exact same location in both
     634             :     //       structures in Linux but it could change on other Unices
     635           0 :     if(addr.sa_family == AF_INET)
     636             :     {
     637             :         // IPv4
     638           0 :         return reinterpret_cast<sockaddr_in *>(&addr)->sin_port;
     639             :     }
     640           0 :     if(addr.sa_family == AF_INET6)
     641             :     {
     642             :         // IPv6
     643           0 :         return reinterpret_cast<sockaddr_in6 *>(&addr)->sin6_port;
     644             :     }
     645           0 :     return -1;
     646             : }
     647             : 
     648             : /** \brief Get the TCP client address.
     649             :  *
     650             :  * This function retrieve the IP address of the client (your computer).
     651             :  * This is retrieved from the socket using the getsockname() function.
     652             :  *
     653             :  * \return The IP address as a string.
     654             :  */
     655           0 : std::string tcp_client::get_client_addr() const
     656             : {
     657             :     struct sockaddr addr;
     658           0 :     socklen_t len(sizeof(addr));
     659           0 :     int const r(getsockname(f_socket, &addr, &len));
     660           0 :     if(r != 0)
     661             :     {
     662           0 :         throw tcp_client_server_runtime_error("address not available");
     663             :     }
     664             :     char buf[BUFSIZ];
     665           0 :     switch(addr.sa_family)
     666             :     {
     667           0 :     case AF_INET:
     668           0 :         if(len < sizeof(struct sockaddr_in))
     669             :         {
     670           0 :             throw tcp_client_server_runtime_error("address size incompatible (AF_INET)");
     671             :         }
     672           0 :         inet_ntop(AF_INET, &reinterpret_cast<struct sockaddr_in *>(&addr)->sin_addr, buf, sizeof(buf));
     673           0 :         break;
     674             : 
     675           0 :     case AF_INET6:
     676           0 :         if(len < sizeof(struct sockaddr_in6))
     677             :         {
     678           0 :             throw tcp_client_server_runtime_error("address size incompatible (AF_INET6)");
     679             :         }
     680           0 :         inet_ntop(AF_INET6, &reinterpret_cast<struct sockaddr_in6 *>(&addr)->sin6_addr, buf, sizeof(buf));
     681           0 :         break;
     682             : 
     683           0 :     default:
     684           0 :         throw tcp_client_server_runtime_error("unknown address family");
     685             : 
     686             :     }
     687           0 :     return buf;
     688             : }
     689             : 
     690             : /** \brief Read data from the socket.
     691             :  *
     692             :  * A TCP socket is a stream type of socket and one can read data from it
     693             :  * as if it were a regular file. This function reads \p size bytes and
     694             :  * returns. The function returns early if the server closes the connection.
     695             :  *
     696             :  * If your socket is blocking, \p size should be exactly what you are
     697             :  * expecting or this function will block forever or until the server
     698             :  * closes the connection.
     699             :  *
     700             :  * The function returns -1 if an error occurs. The error is available in
     701             :  * errno as expected in the POSIX interface.
     702             :  *
     703             :  * \param[in,out] buf  The buffer where the data is read.
     704             :  * \param[in] size  The size of the buffer.
     705             :  *
     706             :  * \return The number of bytes read from the socket, or -1 on errors.
     707             :  */
     708           0 : int tcp_client::read(char *buf, size_t size)
     709             : {
     710           0 :     return static_cast<int>(::read(f_socket, buf, size));
     711             : }
     712             : 
     713             : 
     714             : /** \brief Read one line.
     715             :  *
     716             :  * This function reads one line from the current location up to the next
     717             :  * '\\n' character. We do not have any special handling of the '\\r'
     718             :  * character.
     719             :  *
     720             :  * The function may return 0 in which case the server closed the connection.
     721             :  *
     722             :  * \param[out] line  The resulting line read from the server.
     723             :  *
     724             :  * \return The number of bytes read from the socket, or -1 on errors.
     725             :  *         If the function returns 0 or more, then the \p line parameter
     726             :  *         represents the characters read on the network.
     727             :  */
     728           0 : int tcp_client::read_line(std::string& line)
     729             : {
     730           0 :     line.clear();
     731           0 :     int len(0);
     732             :     for(;;)
     733             :     {
     734             :         char c;
     735           0 :         int r(read(&c, sizeof(c)));
     736           0 :         if(r <= 0)
     737             :         {
     738           0 :             return len == 0 && r < 0 ? -1 : len;
     739             :         }
     740           0 :         if(c == '\n')
     741             :         {
     742           0 :             return len;
     743             :         }
     744           0 :         ++len;
     745           0 :         line += c;
     746           0 :     }
     747             : }
     748             : 
     749             : 
     750             : /** \brief Write data to the socket.
     751             :  *
     752             :  * A TCP socket is a stream type of socket and one can write data to it
     753             :  * as if it were a regular file. This function writes \p size bytes to
     754             :  * the socket and then returns. This function returns early if the server
     755             :  * closes the connection.
     756             :  *
     757             :  * If your socket is not blocking, less than \p size bytes may be written
     758             :  * to the socket. In that case you are responsible for calling the function
     759             :  * again to write the remainder of the buffer until the function returns
     760             :  * a number of bytes written equal to \p size.
     761             :  *
     762             :  * The function returns -1 if an error occurs. The error is available in
     763             :  * errno as expected in the POSIX interface.
     764             :  *
     765             :  * \param[in] buf  The buffer with the data to send over the socket.
     766             :  * \param[in] size  The number of bytes in buffer to send over the socket.
     767             :  *
     768             :  * \return The number of bytes that were actually accepted by the socket
     769             :  * or -1 if an error occurs.
     770             :  */
     771           0 : int tcp_client::write(const char *buf, size_t size)
     772             : {
     773           0 :     return static_cast<int>(::write(f_socket, buf, size));
     774             : }
     775             : 
     776             : 
     777             : // ========================= SERVER =========================
     778             : 
     779             : /** \brief Initialize the server and start listening for connections.
     780             :  *
     781             :  * The server constructor creates a socket, binds it, and then listen to it.
     782             :  *
     783             :  * By default the server accepts a maximum of \p max_connections (set to
     784             :  * 0 or less to get the default tcp_server::MAX_CONNECTIONS) in its waiting queue.
     785             :  * If you use the server and expect a low connection rate, you may want to
     786             :  * reduce the count to 5. Although some very busy servers use larger numbers.
     787             :  * This value gets clamped to a minimum of 5 and a maximum of 1,000.
     788             :  *
     789             :  * Note that the maximum number of connections is actually limited to
     790             :  * /proc/sys/net/core/somaxconn connections. This number is generally 128 
     791             :  * in 2016. So the  super high limit of 1,000 is anyway going to be ignored
     792             :  * by the OS.
     793             :  *
     794             :  * The address is made non-reusable (which is the default for TCP sockets.)
     795             :  * It is possible to mark the server address as immediately reusable by
     796             :  * setting the \p reuse_addr to true.
     797             :  *
     798             :  * By default the server is marked as "keepalive". You can turn it off
     799             :  * using the keepalive() function with false.
     800             :  *
     801             :  * \exception tcp_client_server_parameter_error
     802             :  * This exception is raised if the address parameter is an empty string or
     803             :  * otherwise an invalid IP address, or if the port is out of range.
     804             :  *
     805             :  * \exception tcp_client_server_runtime_error
     806             :  * This exception is raised if the socket cannot be created, bound to
     807             :  * the specified IP address and port, or listen() fails on the socket.
     808             :  *
     809             :  * \param[in] addr  The address to listen on. It may be set to "0.0.0.0".
     810             :  * \param[in] port  The port to listen on.
     811             :  * \param[in] max_connections  The number of connections to keep in the listen queue.
     812             :  * \param[in] reuse_addr  Whether to mark the socket with the SO_REUSEADDR flag.
     813             :  * \param[in] auto_close  Automatically close the client socket in accept and the destructor.
     814             :  */
     815           0 : tcp_server::tcp_server(std::string const & addr, int port, int max_connections, bool reuse_addr, bool auto_close)
     816           0 :     : f_max_connections(max_connections <= 0 ? MAX_CONNECTIONS : max_connections)
     817             :     //, f_socket(-1) -- auto-init
     818             :     , f_port(port)
     819             :     , f_addr(addr)
     820             :     //, f_accepted_socket(-1) -- auto-init
     821             :     //, f_keepalive(true) -- auto-init
     822           0 :     , f_auto_close(auto_close)
     823             : {
     824           0 :     if(f_addr.empty())
     825             :     {
     826           0 :         throw tcp_client_server_parameter_error("the address cannot be an empty string.");
     827             :     }
     828           0 :     if(f_port < 0 || f_port >= 65536)
     829             :     {
     830           0 :         throw tcp_client_server_parameter_error("invalid port for a client socket.");
     831             :     }
     832           0 :     if(f_max_connections < 5)
     833             :     {
     834           0 :         f_max_connections = 5;
     835             :     }
     836           0 :     else if(f_max_connections > 1000)
     837             :     {
     838           0 :         f_max_connections = 1000;
     839             :     }
     840             : 
     841             :     //char decimal_port[16];
     842           0 :     std::stringstream decimal_port;
     843           0 :     decimal_port << f_port;
     844             :     //snprintf(decimal_port, sizeof(decimal_port), "%d", f_port);
     845             :     //decimal_port[sizeof(decimal_port) / sizeof(decimal_port[0]) - 1] = '\0';
     846             :     struct addrinfo hints;
     847           0 :     memset(&hints, 0, sizeof(hints));
     848           0 :     hints.ai_family = AF_UNSPEC;
     849           0 :     hints.ai_socktype = SOCK_STREAM;
     850           0 :     hints.ai_protocol = IPPROTO_TCP;
     851           0 :     std::string port_str(decimal_port.str());
     852           0 :     struct addrinfo * addrinfo(nullptr);
     853           0 :     int const r(getaddrinfo(addr.c_str(), port_str.c_str(), &hints, &addrinfo));
     854           0 :     addrinfo_t addr_info(addrinfo);
     855           0 :     if(r != 0
     856           0 :     || addrinfo == nullptr)
     857             :     {
     858           0 :         throw tcp_client_server_runtime_error("invalid address or port: \"" + addr + ":" + port_str + "\"");
     859             :     }
     860             : 
     861           0 :     f_socket = socket(addr_info.get()->ai_family, SOCK_STREAM, IPPROTO_TCP);
     862           0 :     if(f_socket < 0)
     863             :     {
     864           0 :         int const e(errno);
     865           0 :         SNAP_LOG_FATAL("socket() failed to create a socket descriptor (errno: ")(e)(" -- ")(strerror(e))(")");
     866           0 :         throw tcp_client_server_runtime_error("could not create socket for client");
     867             :     }
     868             : 
     869             :     // this should be optional as reusing an address for TCP/IP is not 100% safe
     870           0 :     if(reuse_addr)
     871             :     {
     872             :         // try to mark the socket address as immediately reusable
     873             :         // if this fails, we ignore the error (TODO log an INFO message)
     874           0 :         int optval(1);
     875           0 :         socklen_t const optlen(sizeof(optval));
     876           0 :         snap::NOTUSED(setsockopt(f_socket, SOL_SOCKET, SO_REUSEADDR, &optval, optlen));
     877             :     }
     878             : 
     879           0 :     if(bind(f_socket, addr_info.get()->ai_addr, addr_info.get()->ai_addrlen) < 0)
     880             :     {
     881           0 :         close(f_socket);
     882           0 :         throw tcp_client_server_runtime_error("could not bind the socket to \"" + f_addr + "\"");
     883             :     }
     884             : 
     885             :     // start listening, we expect the caller to then call accept() to
     886             :     // acquire connections
     887           0 :     if(listen(f_socket, f_max_connections) < 0)
     888             :     {
     889           0 :         close(f_socket);
     890           0 :         throw tcp_client_server_runtime_error("could not listen to the socket bound to \"" + f_addr + "\"");
     891             :     }
     892           0 : }
     893             : 
     894             : 
     895             : /** \brief Clean up the server sockets.
     896             :  *
     897             :  * This function ensures that the server sockets get cleaned up.
     898             :  *
     899             :  * If the \p auto_close parameter was set to true in the constructor, then
     900             :  * the last accepter socket gets closed by this function.
     901             :  *
     902             :  * \note
     903             :  * DO NOT use the shutdown() call since we may end up forking and using
     904             :  * that connection in the child.
     905             :  */
     906           0 : tcp_server::~tcp_server()
     907             : {
     908           0 :     close(f_socket);
     909           0 :     if(f_auto_close && f_accepted_socket != -1)
     910             :     {
     911           0 :         close(f_accepted_socket);
     912             :     }
     913           0 : }
     914             : 
     915             : 
     916             : /** \brief Retrieve the socket descriptor.
     917             :  *
     918             :  * This function returns the socket descriptor. It can be used to
     919             :  * tweak things on the socket such as making it non-blocking or
     920             :  * directly accessing the data.
     921             :  *
     922             :  * \return The socket descriptor.
     923             :  */
     924           0 : int tcp_server::get_socket() const
     925             : {
     926           0 :     return f_socket;
     927             : }
     928             : 
     929             : 
     930             : /** \brief Retrieve the maximum number of connections.
     931             :  *
     932             :  * This function returns the maximum number of connections that can
     933             :  * be accepted by the socket. This was set by the constructor and
     934             :  * it cannot be changed later.
     935             :  *
     936             :  * \return The maximum number of incoming connections.
     937             :  */
     938           0 : int tcp_server::get_max_connections() const
     939             : {
     940           0 :     return f_max_connections;
     941             : }
     942             : 
     943             : 
     944             : /** \brief Return the server port.
     945             :  *
     946             :  * This function returns the port the server was created with. This port
     947             :  * is exactly what the server currently uses. It cannot be changed.
     948             :  *
     949             :  * \return The server port.
     950             :  */
     951           0 : int tcp_server::get_port() const
     952             : {
     953           0 :     return f_port;
     954             : }
     955             : 
     956             : 
     957             : /** \brief Retrieve the server IP address.
     958             :  *
     959             :  * This function returns the IP address used to bind the socket. This
     960             :  * is the address clients have to use to connect to the server unless
     961             :  * the address was set to all zeroes (0.0.0.0) in which case any user
     962             :  * can connect.
     963             :  *
     964             :  * The IP address cannot be changed.
     965             :  *
     966             :  * \return The server IP address.
     967             :  */
     968           0 : std::string tcp_server::get_addr() const
     969             : {
     970           0 :     return f_addr;
     971             : }
     972             : 
     973             : 
     974             : /** \brief Return the current status of the keepalive flag.
     975             :  *
     976             :  * This function returns the current status of the keepalive flag. This
     977             :  * flag is set to true by default (in the constructor.) It can be
     978             :  * changed with the keepalive() function.
     979             :  *
     980             :  * The flag is used to mark new connections with the SO_KEEPALIVE flag.
     981             :  * This is used whenever a service may take a little to long to answer
     982             :  * and avoid losing the TCP connection before the answer is sent to
     983             :  * the client.
     984             :  *
     985             :  * \return The current status of the keepalive flag.
     986             :  */
     987           0 : bool tcp_server::get_keepalive() const
     988             : {
     989           0 :     return f_keepalive;
     990             : }
     991             : 
     992             : 
     993             : /** \brief Set the keepalive flag.
     994             :  *
     995             :  * This function sets the keepalive flag to either true (i.e. mark connection
     996             :  * sockets with the SO_KEEPALIVE flag) or false. The default is true (as set
     997             :  * in the constructor,) because in most cases this is a feature people want.
     998             :  *
     999             :  * \param[in] yes  Whether to keep new connections alive even when no traffic
    1000             :  * goes through.
    1001             :  */
    1002           0 : void tcp_server::set_keepalive(bool yes)
    1003             : {
    1004           0 :     f_keepalive = yes;
    1005           0 : }
    1006             : 
    1007             : 
    1008             : /** \brief Accept a connection.
    1009             :  *
    1010             :  * A TCP server accepts incoming connections. This call is a blocking call.
    1011             :  * If no connections are available on the line, then the call blocks until
    1012             :  * a connection becomes available.
    1013             :  *
    1014             :  * To prevent being blocked by this call you can either check the status of
    1015             :  * the file descriptor (use the get_socket() function to retrieve the
    1016             :  * descriptor and use an appropriate wait with 0 as a timeout,) or transform
    1017             :  * the socket in a non-blocking socket (not tested, though.)
    1018             :  *
    1019             :  * This TCP socket implementation is expected to be used in one of two ways:
    1020             :  *
    1021             :  * (1) the main server accepts connections and then fork()'s to handle the
    1022             :  * transaction with the client, in that case we want to set the \p auto_close
    1023             :  * parameter of the constructor to true so the accept() function automatically
    1024             :  * closes the last accepted socket.
    1025             :  *
    1026             :  * (2) the main server keeps a set of connections and handles them alongside
    1027             :  * the main server connection. Although there are limits to what you can do
    1028             :  * in this way, it is very efficient, but this also means the accept() call
    1029             :  * cannot close the last accepted socket since the rest of the software may
    1030             :  * still be working on it.
    1031             :  *
    1032             :  * The function returns a client/server socket. This is the socket one can
    1033             :  * use to communicate with the client that just connected to the server. This
    1034             :  * descriptor can be written to or read from.
    1035             :  *
    1036             :  * This function is the one that applies the keepalive flag to the
    1037             :  * newly accepted socket.
    1038             :  *
    1039             :  * \note
    1040             :  * If you prevent SIGCHLD from stopping your code, you may want to allow it
    1041             :  * when calling this function (that is, if you're interested in getting that
    1042             :  * information immediately, otherwise it is cleaner to always block those
    1043             :  * signals.)
    1044             :  *
    1045             :  * \note
    1046             :  * DO NOT use the shutdown() call since we may end up forking and using
    1047             :  * that connection in the child.
    1048             :  *
    1049             :  * \param[in] max_wait_ms  The maximum number of milliseconds to wait for
    1050             :  *            a message. If set to -1 (the default), accept() will block
    1051             :  *            indefintely.
    1052             :  *
    1053             :  * \return A client socket descriptor or -1 if an error occured, -2 if timeout and max_wait is set.
    1054             :  */
    1055           0 : int tcp_server::accept( int const max_wait_ms )
    1056             : {
    1057             :     // auto-close?
    1058           0 :     if(f_auto_close && f_accepted_socket != -1)
    1059             :     {
    1060             :         // if the close is interrupted, make sure we try again otherwise
    1061             :         // we could lose that stream until next restart (this could happen
    1062             :         // if you have SIGCHLD)
    1063           0 :         if(close(f_accepted_socket) == -1)
    1064             :         {
    1065           0 :             if(errno == EINTR)
    1066             :             {
    1067           0 :                 close(f_accepted_socket);
    1068             :             }
    1069             :         }
    1070             :     }
    1071           0 :     f_accepted_socket = -1;
    1072             : 
    1073           0 :     if( max_wait_ms > -1 )
    1074             :     {
    1075             :         struct pollfd fd;
    1076           0 :         fd.events = POLLIN | POLLPRI | POLLRDHUP;
    1077           0 :         fd.fd = f_socket;
    1078           0 :         int const retval(poll(&fd, 1, max_wait_ms));
    1079             : 
    1080             : // on newer system each input of select() must be a distinct fd_set...
    1081             : //        fd_set s;
    1082             : //        //
    1083             : //        FD_ZERO(&s);
    1084             : //#pragma GCC diagnostic push
    1085             : //#pragma GCC diagnostic ignored "-Wold-style-cast"
    1086             : //        FD_SET(f_socket, &s);
    1087             : //#pragma GCC diagnostic pop
    1088             : //        //
    1089             : //        struct timeval timeout;
    1090             : //        timeout.tv_sec = max_wait_ms / 1000;
    1091             : //        timeout.tv_usec = (max_wait_ms % 1000) * 1000;
    1092             : //        int const retval = select(f_socket + 1, &s, nullptr, &s, &timeout);
    1093             :         //
    1094           0 :         if( retval == -1 )
    1095             :         {
    1096             :             // error
    1097             :             //
    1098           0 :             return -1;
    1099             :         }
    1100           0 :         else if( retval == 0 )
    1101             :         {
    1102             :             // timeout
    1103             :             //
    1104           0 :             return -2;
    1105             :         }
    1106             :     }
    1107             : 
    1108             :     // accept the next connection
    1109             :     struct sockaddr_in accepted_addr;
    1110           0 :     socklen_t addr_len(sizeof(accepted_addr));
    1111           0 :     memset(&accepted_addr, 0, sizeof(accepted_addr));
    1112           0 :     f_accepted_socket = ::accept(f_socket, reinterpret_cast<struct sockaddr *>(&accepted_addr), &addr_len);
    1113             : 
    1114             :     // mark the new connection with the SO_KEEPALIVE flag
    1115           0 :     if(f_accepted_socket != -1 && f_keepalive)
    1116             :     {
    1117             :         // if this fails, we ignore the error, but still log the event
    1118           0 :         int optval(1);
    1119           0 :         socklen_t const optlen(sizeof(optval));
    1120           0 :         if(setsockopt(f_accepted_socket, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) != 0)
    1121             :         {
    1122           0 :             SNAP_LOG_WARNING("tcp_server::accept(): an error occurred trying to mark accepted socket with SO_KEEPALIVE.");
    1123             :         }
    1124             :     }
    1125             : 
    1126           0 :     return f_accepted_socket;
    1127             : }
    1128             : 
    1129             : 
    1130             : /** \brief Retrieve the last accepted socket descriptor.
    1131             :  *
    1132             :  * This function returns the last accepted socket descriptor as retrieved by
    1133             :  * accept(). If accept() was never called or failed, then this returns -1.
    1134             :  *
    1135             :  * Note that it is possible that the socket was closed in between in which
    1136             :  * case this value is going to be an invalid socket.
    1137             :  *
    1138             :  * \return The last accepted socket descriptor.
    1139             :  */
    1140           0 : int tcp_server::get_last_accepted_socket() const
    1141             : {
    1142           0 :     return f_accepted_socket;
    1143             : }
    1144             : 
    1145             : 
    1146             : 
    1147             : 
    1148             : // ========================= BIO CLIENT =========================
    1149             : 
    1150             : 
    1151             : /** \class bio_client
    1152             :  * \brief Create a BIO client and connect to a server, eventually with TLS.
    1153             :  *
    1154             :  * This class is a client socket implementation used to connect to a server.
    1155             :  * The server is expected to be running at the time the client is created
    1156             :  * otherwise it fails connecting.
    1157             :  *
    1158             :  * This class is not appropriate to connect to a server that may come and go
    1159             :  * over time.
    1160             :  *
    1161             :  * The BIO extension is from the OpenSSL library and it allows the client
    1162             :  * to connect using SSL. At this time connections are either secure or
    1163             :  * not secure. If a secure connection fails, you may attempt again without
    1164             :  * TLS or other encryption mechanism.
    1165             :  */
    1166             : 
    1167             : 
    1168             : namespace
    1169             : {
    1170             : 
    1171             : 
    1172           0 : char const * tls_rt_type(int type)
    1173             : {
    1174           0 :     switch(type)
    1175             :     {
    1176             : #ifdef SSL3_RT_HEADER
    1177           0 :     case SSL3_RT_HEADER:
    1178           0 :         return "TLS header";
    1179             : #endif
    1180           0 :     case SSL3_RT_CHANGE_CIPHER_SPEC:
    1181           0 :         return "TLS change cipher";
    1182           0 :     case SSL3_RT_ALERT:
    1183           0 :         return "TLS alert";
    1184           0 :     case SSL3_RT_HANDSHAKE:
    1185           0 :         return "TLS handshake";
    1186           0 :     case SSL3_RT_APPLICATION_DATA:
    1187           0 :         return "TLS app data";
    1188           0 :     default:
    1189           0 :         return "TLS Unknown";
    1190             :     }
    1191             : }
    1192             : 
    1193             : 
    1194           0 : char const * ssl_msg_type(int ssl_ver, int msg)
    1195             : {
    1196             : #ifdef SSL2_VERSION_MAJOR
    1197             :     if(ssl_ver == SSL2_VERSION_MAJOR)
    1198             :     {
    1199             :         switch(msg)
    1200             :         {
    1201             :         case SSL2_MT_ERROR:
    1202             :             return "Error";
    1203             :         case SSL2_MT_CLIENT_HELLO:
    1204             :             return "Client hello";
    1205             :         case SSL2_MT_CLIENT_MASTER_KEY:
    1206             :             return "Client key";
    1207             :         case SSL2_MT_CLIENT_FINISHED:
    1208             :             return "Client finished";
    1209             :         case SSL2_MT_SERVER_HELLO:
    1210             :             return "Server hello";
    1211             :         case SSL2_MT_SERVER_VERIFY:
    1212             :             return "Server verify";
    1213             :         case SSL2_MT_SERVER_FINISHED:
    1214             :             return "Server finished";
    1215             :         case SSL2_MT_REQUEST_CERTIFICATE:
    1216             :             return "Request CERT";
    1217             :         case SSL2_MT_CLIENT_CERTIFICATE:
    1218             :             return "Client CERT";
    1219             :         }
    1220             :     }
    1221             :     else
    1222             : #endif
    1223           0 :     if(ssl_ver == SSL3_VERSION_MAJOR)
    1224             :     {
    1225           0 :         switch(msg)
    1226             :         {
    1227           0 :         case SSL3_MT_HELLO_REQUEST:
    1228           0 :             return "Hello request";
    1229           0 :         case SSL3_MT_CLIENT_HELLO:
    1230           0 :             return "Client hello";
    1231           0 :         case SSL3_MT_SERVER_HELLO:
    1232           0 :             return "Server hello";
    1233             : #ifdef SSL3_MT_NEWSESSION_TICKET
    1234           0 :         case SSL3_MT_NEWSESSION_TICKET:
    1235           0 :             return "Newsession Ticket";
    1236             : #endif
    1237           0 :         case SSL3_MT_CERTIFICATE:
    1238           0 :             return "Certificate";
    1239           0 :         case SSL3_MT_SERVER_KEY_EXCHANGE:
    1240           0 :             return "Server key exchange";
    1241           0 :         case SSL3_MT_CLIENT_KEY_EXCHANGE:
    1242           0 :             return "Client key exchange";
    1243           0 :         case SSL3_MT_CERTIFICATE_REQUEST:
    1244           0 :             return "Request CERT";
    1245           0 :         case SSL3_MT_SERVER_DONE:
    1246           0 :             return "Server finished";
    1247           0 :         case SSL3_MT_CERTIFICATE_VERIFY:
    1248           0 :             return "CERT verify";
    1249           0 :         case SSL3_MT_FINISHED:
    1250           0 :             return "Finished";
    1251             : #ifdef SSL3_MT_CERTIFICATE_STATUS
    1252           0 :         case SSL3_MT_CERTIFICATE_STATUS:
    1253           0 :             return "Certificate Status";
    1254             : #endif
    1255             :         }
    1256             :     }
    1257           0 :     return "Unknown";
    1258             : }
    1259             : 
    1260             : 
    1261           0 : void ssl_trace(
    1262             :         int direction,
    1263             :         int ssl_ver,
    1264             :         int content_type,
    1265             :         void const * buf, size_t len,
    1266             :         SSL * ssl,
    1267             :         void * userp)
    1268             : {
    1269           0 :     snap::NOTUSED(ssl);
    1270           0 :     snap::NOTUSED(userp);
    1271             : 
    1272           0 :     std::stringstream out;
    1273             :     char const * msg_name;
    1274             :     int msg_type;
    1275             : 
    1276             :     // VERSION
    1277             :     //
    1278           0 :     out << SSL_get_version(ssl);
    1279             : 
    1280             :     // DIRECTION
    1281             :     //
    1282           0 :     out << (direction == 0 ? " (IN), " : " (OUT), ");
    1283             : 
    1284             :     // keep only major version
    1285             :     //
    1286           0 :     ssl_ver >>= 8;
    1287             : 
    1288             :     // TLS RT NAME
    1289             :     //
    1290           0 :     if(ssl_ver == SSL3_VERSION_MAJOR
    1291           0 :     && content_type != 0)
    1292             :     {
    1293           0 :         out << tls_rt_type(content_type);
    1294             :     }
    1295             :     else
    1296             :     {
    1297           0 :         out << "(no tls_tr_type)";
    1298             :     }
    1299             : 
    1300           0 :     if(len >= 1)
    1301             :     {
    1302           0 :         msg_type = * reinterpret_cast<unsigned char const *>(buf);
    1303           0 :         msg_name = ssl_msg_type(ssl_ver, msg_type);
    1304             : 
    1305           0 :         out << ", ";
    1306           0 :         out << msg_name;
    1307           0 :         out << " (";
    1308           0 :         out << std::to_string(msg_type);
    1309           0 :         out << "):";
    1310             :     }
    1311             : 
    1312           0 :     out << std::hex;
    1313           0 :     for(size_t line(0); line < len; line += 16)
    1314             :     {
    1315           0 :         out << std::endl
    1316             :             << (direction == 0 ? "<" : ">")
    1317             :             << " "
    1318           0 :             << std::setfill('0') << std::setw(4) << line
    1319           0 :             << "-  ";
    1320             :         size_t idx;
    1321           0 :         for(idx = 0; line + idx < len && idx < 16; ++idx)
    1322             :         {
    1323           0 :             if(idx == 8)
    1324             :             {
    1325           0 :                 out << "   ";
    1326             :             }
    1327             :             else
    1328             :             {
    1329           0 :                 out << " ";
    1330             :             }
    1331           0 :             int const c(reinterpret_cast<unsigned char const *>(buf)[line + idx]);
    1332           0 :             out << std::setfill('0') << std::setw(2) << static_cast<int>(c);
    1333             :         }
    1334           0 :         for(; idx < 16; ++idx)
    1335             :         {
    1336           0 :             if(idx == 8)
    1337             :             {
    1338           0 :                 out << "  ";
    1339             :             }
    1340           0 :             out << "   ";
    1341             :         }
    1342           0 :         out << "   ";
    1343           0 :         for(idx = 0; line + idx < len && idx < 16; ++idx)
    1344             :         {
    1345           0 :             if(idx == 8)
    1346             :             {
    1347           0 :                 out << " ";
    1348             :             }
    1349           0 :             char c(reinterpret_cast<char const *>(buf)[line + idx]);
    1350           0 :             if(c < ' ' || c > '~')
    1351             :             {
    1352           0 :                 c = '.';
    1353             :             }
    1354           0 :             out << c;
    1355             :         }
    1356             :     }
    1357             : 
    1358           0 :     std::cerr << out.str() << std::endl;
    1359           0 : }
    1360             : 
    1361             : 
    1362             : } // no name namespace
    1363             : 
    1364             : 
    1365             : 
    1366             : 
    1367             : 
    1368             : 
    1369             : /** \brief Initialize the options object to the defaults.
    1370             :  *
    1371             :  * This constructor sets up the default options in this structure.
    1372             :  */
    1373           0 : bio_client::options::options()
    1374             : {
    1375           0 : }
    1376             : 
    1377             : 
    1378             : /** \brief Specify the depth of SSL certificate verification.
    1379             :  *
    1380             :  * When verifying a certificate, you may end up with a very long chain.
    1381             :  * In most cases, a very long chain is not sensible and probably means
    1382             :  * something fishy is going on. For this reason, this is verified here.
    1383             :  *
    1384             :  * The default is 4. Some people like to use 5 or 6. The full range
    1385             :  * allows for way more, although really it should be very much
    1386             :  * limited.
    1387             :  *
    1388             :  * \exception
    1389             :  * This function accepts a number between 1 and 100. Any number outside
    1390             :  * of that range and this exception is raised.
    1391             :  *
    1392             :  * \param[in] depth  The depth for the verification of certificates.
    1393             :  */
    1394           0 : void bio_client::options::set_verification_depth(size_t depth)
    1395             : {
    1396           0 :     if(depth == 0
    1397           0 :     || depth > MAX_VERIFICATION_DEPTH)
    1398             :     {
    1399           0 :         throw tcp_client_server_parameter_error("the depth parameter must be defined between 1 and 100 inclusive");
    1400             :     }
    1401             : 
    1402           0 :     f_verification_depth = depth;
    1403           0 : }
    1404             : 
    1405             : 
    1406             : /** \brief Retrieve the verification maximum depth allowed.
    1407             :  *
    1408             :  * This function returns the verification depth parameter. This number
    1409             :  * will always be between 1 and 100 inclusive.
    1410             :  *
    1411             :  * The inclusive maximum is actually defined as MAX_VERIFICATION_DEPTH.
    1412             :  *
    1413             :  * The default depth is 4.
    1414             :  *
    1415             :  * \return The current verification depth.
    1416             :  */
    1417           0 : size_t bio_client::options::get_verification_depth() const
    1418             : {
    1419           0 :     return f_verification_depth;
    1420             : }
    1421             : 
    1422             : 
    1423             : /** \brief Change the SSL options.
    1424             :  *
    1425             :  * This function sets the SSL options to the new \p ssl_options
    1426             :  * values.
    1427             :  *
    1428             :  * By default the bio_clent forbids:
    1429             :  *
    1430             :  * * SSL version 2
    1431             :  * * SSL version 3
    1432             :  * * TLS version 1.0
    1433             :  * * SSL compression
    1434             :  *
    1435             :  * which are parameter that are known to create security issues.
    1436             :  *
    1437             :  * To make it easier to add options to the defaults, the class
    1438             :  * offers the DEFAULT_SSL_OPTIONS option. Just add and remove
    1439             :  * bits starting from that value.
    1440             :  *
    1441             :  * \param[in] ssl_options  The new SSL options.
    1442             :  */
    1443           0 : void bio_client::options::set_ssl_options(ssl_options_t ssl_options)
    1444             : {
    1445           0 :     f_ssl_options = ssl_options;
    1446           0 : }
    1447             : 
    1448             : 
    1449             : /** \brief Retrieve the current SSL options.
    1450             :  *
    1451             :  * This function can be used to add and remove SSL options to
    1452             :  * bio_client connections.
    1453             :  *
    1454             :  * For example, to also prevent TLS 1.1, add the new flag:
    1455             :  *
    1456             :  * \code
    1457             :  *      bio.set_ssl_options(bio.get_ssl_options() | SSL_OP_NO_TLSv1_1);
    1458             :  * \endcode
    1459             :  *
    1460             :  * And to allow compression, remove a flag which is set by default:
    1461             :  *
    1462             :  * \code
    1463             :  *      bio.set_ssl_options(bio.get_ssl_options() & ~(SSL_OP_NO_COMPRESSION));
    1464             :  * \endcode
    1465             :  *
    1466             :  * \return The current SSL options.
    1467             :  */
    1468           0 : bio_client::options::ssl_options_t bio_client::options::get_ssl_options() const
    1469             : {
    1470           0 :     return f_ssl_options;
    1471             : }
    1472             : 
    1473             : 
    1474             : /** \brief Change the default path to SSL certificates.
    1475             :  *
    1476             :  * By default, we define the path to the SSL certificate as defined
    1477             :  * on Ubuntu. This is under "/etc/ssl/certs".
    1478             :  *
    1479             :  * This function let you change that path to another one. Maybe you
    1480             :  * would prefer to not allow all certificates to work in your
    1481             :  * circumstances.
    1482             :  *
    1483             :  * \param[in] path  The new path to SSL certificates used to verify
    1484             :  *                  secure connections.
    1485             :  */
    1486           0 : void bio_client::options::set_ssl_certificate_path(std::string const path)
    1487             : {
    1488           0 :     f_ssl_certificate_path = path;
    1489           0 : }
    1490             : 
    1491             : 
    1492             : /** \brief Return the current SSL certificate path.
    1493             :  *
    1494             :  * This function returns the path where the SSL interface will
    1495             :  * look for the root certificates used to verify a connection's
    1496             :  * security.
    1497             :  *
    1498             :  * \return The current SSL certificate path.
    1499             :  */
    1500           0 : std::string const & bio_client::options::get_ssl_certificate_path() const
    1501             : {
    1502           0 :     return f_ssl_certificate_path;
    1503             : }
    1504             : 
    1505             : 
    1506             : /** \brief Set whether the SO_KEEPALIVE should be set.
    1507             :  *
    1508             :  * By default this option is turned ON meaning that all BIO_client have their
    1509             :  * SO_KEEPALIVE turned on when created.
    1510             :  *
    1511             :  * You may turn this off if you are creating a socket for a very short
    1512             :  * period of time, such as to send a fast REST command to a server.
    1513             :  *
    1514             :  * \attention
    1515             :  * As per the TCP RFC, you should only use keepalive on a server, not a
    1516             :  * client. (The client can quit any time and if it tries to access the
    1517             :  * server and it fails, it can either quit or reconnect then.) That being
    1518             :  * said, at times a server does not set the Keep-Alive and the client may
    1519             :  * want to use it to maintain the connection when not much happens for
    1520             :  * long durations.
    1521             :  *
    1522             :  * https://tools.ietf.org/html/rfc1122#page-101
    1523             :  *
    1524             :  * Some numbers about Keep-Alive:
    1525             :  *
    1526             :  * https://www.veritas.com/support/en_US/article.100028680
    1527             :  *
    1528             :  * For Linux (in seconds):
    1529             :  *
    1530             :  * \code
    1531             :  * tcp_keepalive_time = 7200
    1532             :  * tcp_keepalive_intvl = 75
    1533             :  * tcp_keepalive_probes = 9
    1534             :  * \endcode
    1535             :  *
    1536             :  * These can be access through the /proc file system:
    1537             :  *
    1538             :  * \code
    1539             :  * /proc/sys/net/ipv4/tcp_keepalive_time
    1540             :  * /proc/sys/net/ipv4/tcp_keepalive_intvl
    1541             :  * /proc/sys/net/ipv4/tcp_keepalive_probes
    1542             :  * \endcode
    1543             :  *
    1544             :  * See: http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/usingkeepalive.html
    1545             :  *
    1546             :  * \warning
    1547             :  * These numbers are used by all applications using TCP. Remember that
    1548             :  * changing them will affect all your clients and servers.
    1549             :  *
    1550             :  * \param[in] keepalive  true if you want the SO_KEEP_ALIVE turned on.
    1551             :  *
    1552             :  * \sa get_keepalive()
    1553             :  */
    1554           0 : void bio_client::options::set_keepalive(bool keepalive)
    1555             : {
    1556           0 :     f_keepalive = keepalive;
    1557           0 : }
    1558             : 
    1559             : 
    1560             : /** \brief Retrieve the SO_KEEPALIVE flag.
    1561             :  *
    1562             :  * This function returns the current value of the SO_KEEPALIVE flag. By
    1563             :  * default this is true.
    1564             :  *
    1565             :  * Note that this function returns the flag status in the options, not
    1566             :  * a connected socket.
    1567             :  *
    1568             :  * \return The current status of the SO_KEEPALIVE flag (true or false).
    1569             :  *
    1570             :  * \sa set_keepalive()
    1571             :  */
    1572           0 : bool bio_client::options::get_keepalive() const
    1573             : {
    1574           0 :     return f_keepalive;
    1575             : }
    1576             : 
    1577             : 
    1578             : /** \brief Set whether the SNI should be included in the SSL request.
    1579             :  *
    1580             :  * Whenever SSL connects a server, it has the option to include the
    1581             :  * Server Name Indication, which is the server hostname to which
    1582             :  * are think you are connecting. That way the server can verify that
    1583             :  * you indeed were sent to the right server.
    1584             :  *
    1585             :  * The default is set to true, however, if you create a bio_client
    1586             :  * object using an IP address (opposed to the hostname) then no
    1587             :  * SNI will be included unless you also call the set_host() function
    1588             :  * to setup the host.
    1589             :  *
    1590             :  * In other words, you can use the IP address on the bio_client
    1591             :  * constructor and the hostname in the options and you will still
    1592             :  * be able to get the SNI setup as expected.
    1593             :  *
    1594             :  * \param[in] sni  true if you want the SNI to be included.
    1595             :  *
    1596             :  * \sa get_sni()
    1597             :  * \sa set_host()
    1598             :  */
    1599           0 : void bio_client::options::set_sni(bool sni)
    1600             : {
    1601           0 :     f_sni = sni;
    1602           0 : }
    1603             : 
    1604             : 
    1605             : /** \brief Retrieve the SNI flag.
    1606             :  *
    1607             :  * This function returns the current value of the SNI flag. By
    1608             :  * default this is true.
    1609             :  *
    1610             :  * Note that although the flag is true by default, the SSL request
    1611             :  * may still not get to work if you don't include the host with
    1612             :  * the set_host() and construct a bio_client object with an IP
    1613             :  * address (opposed to a hostname.)
    1614             :  *
    1615             :  * \return The current status of the SNI (true or false).
    1616             :  *
    1617             :  * \sa set_sni()
    1618             :  * \sa set_host()
    1619             :  */
    1620           0 : bool bio_client::options::get_sni() const
    1621             : {
    1622           0 :     return f_sni;
    1623             : }
    1624             : 
    1625             : 
    1626             : /** \brief Set the hostname.
    1627             :  *
    1628             :  * This function is used to setup the SNI hostname.
    1629             :  *
    1630             :  * The Server Name Indication is added to the SSL Hello message if
    1631             :  * available (i.e. the host was specified here or the bio_client
    1632             :  * constructor is called with the hostname and not an IP address.)
    1633             :  *
    1634             :  * If you construct the bio_client object with an IP address, you
    1635             :  * can use this set_host() function to specify the hostname, but
    1636             :  * you still need to make sure that both are a match.
    1637             :  *
    1638             :  * \param[in] host  The host being accessed.
    1639             :  */
    1640           0 : void bio_client::options::set_host(std::string const & host)
    1641             : {
    1642           0 :     f_host = host;
    1643           0 : }
    1644             : 
    1645             : 
    1646             : /** \brief Retrieve the hostname.
    1647             :  *
    1648             :  * This function is used to retrieve the hostname. This name has
    1649             :  * priority over the \p addr parameter specified to the
    1650             :  * bio_client constructor.
    1651             :  *
    1652             :  * By default this name is empty in which case the bio_client
    1653             :  * constructor checks the \p addr parameter and if it is
    1654             :  * a hostname (opposed to direct IP addresses) then it uses
    1655             :  * that \p addr parameter instead.
    1656             :  *
    1657             :  * If you do not want the Server Name Indication in the SSL
    1658             :  * request, you must call set_sni(false) so even if the
    1659             :  * bio_client constructor is called with a hostname, the
    1660             :  * SNI won't be included in the request.
    1661             :  *
    1662             :  * \return A referemce string with the hostname.
    1663             :  */
    1664           0 : std::string const & bio_client::options::get_host() const
    1665             : {
    1666           0 :     return f_host;
    1667             : }
    1668             : 
    1669             : 
    1670             : 
    1671             : 
    1672             : 
    1673             : /** \brief Contruct a bio_client object.
    1674             :  *
    1675             :  * The bio_client constructor initializes a BIO connector and connects
    1676             :  * to the specified server. The server is defined with the \p addr and
    1677             :  * \p port specified as parameters. The connection tries to use TLS if
    1678             :  * the \p mode parameter is set to MODE_SECURE. Note that you may force
    1679             :  * a secure connection using MODE_SECURE_REQUIRED. With MODE_SECURE,
    1680             :  * the connection to the server can be obtained even if a secure
    1681             :  * connection could not be made to work.
    1682             :  *
    1683             :  * \todo
    1684             :  * Create another client with BIO_new_socket() so one can create an SSL
    1685             :  * connection with a socket retrieved from an accept() call.
    1686             :  *
    1687             :  * \exception tcp_client_server_parameter_error
    1688             :  * This exception is raised if the \p port parameter is out of range or the
    1689             :  * IP address is an empty string or otherwise an invalid address.
    1690             :  *
    1691             :  * \exception tcp_client_server_initialization_error
    1692             :  * This exception is raised if the client cannot create the socket or it
    1693             :  * cannot connect to the server.
    1694             :  *
    1695             :  * \param[in] addr  The address of the server to connect to. It must be valid.
    1696             :  * \param[in] port  The port the server is listening on.
    1697             :  * \param[in] mode  Whether to use SSL when connecting.
    1698             :  * \param[in] opt  Additional options.
    1699             :  */
    1700           0 : bio_client::bio_client(std::string const & addr, int port, mode_t mode, options const & opt)
    1701             : {
    1702           0 :     if(port < 0 || port >= 65536)
    1703             :     {
    1704           0 :         throw tcp_client_server_parameter_error("invalid port for a client socket");
    1705             :     }
    1706           0 :     if(addr.empty())
    1707             :     {
    1708           0 :         throw tcp_client_server_parameter_error("an empty address is not valid for a client socket");
    1709             :     }
    1710             : 
    1711           0 :     bio_initialize();
    1712             : 
    1713           0 :     switch(mode)
    1714             :     {
    1715           0 :     case mode_t::MODE_SECURE:
    1716             :     case mode_t::MODE_ALWAYS_SECURE:
    1717             :         {
    1718             :             // Use TLS v1 only as all versions of SSL are flawed...
    1719             :             // (see below the SSL_CTX_set_options() for additional details
    1720             :             // about that since here it does indeed say SSLv23...)
    1721             :             //
    1722           0 :             std::shared_ptr<SSL_CTX> ssl_ctx; // use a reset(), see SNAP-507
    1723           0 :             ssl_ctx.reset(SSL_CTX_new(SSLv23_client_method()), ssl_ctx_deleter);
    1724           0 :             if(ssl_ctx == nullptr)
    1725             :             {
    1726           0 :                 bio_log_errors();
    1727           0 :                 throw tcp_client_server_initialization_error("failed creating an SSL_CTX object");
    1728             :             }
    1729             : 
    1730             :             // allow up to 4 certificates in the chain otherwise fail
    1731             :             // (this is not a very strong security feature though)
    1732             :             //
    1733           0 :             SSL_CTX_set_verify_depth(ssl_ctx.get(), opt.get_verification_depth());
    1734             : 
    1735             :             // make sure SSL v2/3 is not used, also compression in SSL is
    1736             :             // known to have security issues
    1737             :             //
    1738           0 :             SSL_CTX_set_options(ssl_ctx.get(), opt.get_ssl_options());
    1739             : 
    1740             :             // limit the number of ciphers the connection can use
    1741           0 :             if(mode == mode_t::MODE_SECURE)
    1742             :             {
    1743             :                 // this is used by local connections and we get a very strong
    1744             :                 // algorithm anyway, but at this point I do not know why it
    1745             :                 // does not work with the limited list below...
    1746             :                 //
    1747             :                 // TODO: test with adding DH support in the server then
    1748             :                 //       maybe (probably) that the "HIGH" will work for
    1749             :                 //       this entry too...
    1750             :                 //
    1751           0 :                 SSL_CTX_set_cipher_list(ssl_ctx.get(), "ALL");
    1752             :             }
    1753             :             else
    1754             :             {
    1755           0 :                 SSL_CTX_set_cipher_list(ssl_ctx.get(), "HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4");
    1756             :             }
    1757             : 
    1758             :             // load root certificates (correct path for Ubuntu?)
    1759             :             // TODO: allow client to set the path to certificates
    1760           0 :             if(SSL_CTX_load_verify_locations(ssl_ctx.get(), nullptr, "/etc/ssl/certs") != 1)
    1761             :             {
    1762           0 :                 bio_log_errors();
    1763           0 :                 throw tcp_client_server_initialization_error("failed loading verification certificates in an SSL_CTX object");
    1764             :             }
    1765             :             //SSL_CTX_set_msg_callback(ssl_ctx.get(), ssl_trace);
    1766             :             //SSL_CTX_set_msg_callback_arg(ssl_ctx.get(), this);
    1767             : 
    1768             :             // create a BIO connected to SSL ciphers
    1769             :             //
    1770           0 :             std::shared_ptr<BIO> bio;
    1771           0 :             bio.reset(BIO_new_ssl_connect(ssl_ctx.get()), bio_deleter);
    1772           0 :             if(!bio)
    1773             :             {
    1774           0 :                 bio_log_errors();
    1775           0 :                 throw tcp_client_server_initialization_error("failed initializing a BIO object");
    1776             :             }
    1777             : 
    1778             :             // verify that the connection worked
    1779             :             //
    1780           0 :             SSL * ssl(nullptr);
    1781             : #pragma GCC diagnostic push
    1782             : #pragma GCC diagnostic ignored "-Wold-style-cast"
    1783           0 :             BIO_get_ssl(bio.get(), &ssl);
    1784             : #pragma GCC diagnostic pop
    1785           0 :             if(ssl == nullptr)
    1786             :             {
    1787             :                 // TBD: does this mean we would have a plain connection?
    1788           0 :                 bio_log_errors();
    1789           0 :                 throw tcp_client_server_initialization_error("failed retrieving the SSL contact from BIO object");
    1790             :             }
    1791             : 
    1792             :             // allow automatic retries in case the connection somehow needs
    1793             :             // an SSL renegotiation (maybe we should turn that off for cases
    1794             :             // where we connect to a secure payment gateway?)
    1795             :             //
    1796           0 :             SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
    1797             : 
    1798             :             // setup the Server Name Indication (SNI)
    1799             :             //
    1800           0 :             bool using_sni(false);
    1801           0 :             if(opt.get_sni())
    1802             :             {
    1803           0 :                 std::string host(opt.get_host());
    1804             :                 struct in6_addr ignore;
    1805           0 :                 if(host.empty()
    1806           0 :                 && inet_pton(AF_INET, addr.c_str(), &ignore) == 0   // must fail
    1807           0 :                 && inet_pton(AF_INET6, addr.c_str(), &ignore) == 0) // must fail
    1808             :                 {
    1809             :                     // addr is not an IP address written as is,
    1810             :                     // it must be a hostname
    1811             :                     //
    1812           0 :                     host = addr;
    1813             :                 }
    1814           0 :                 if(!host.empty())
    1815             :                 {
    1816             : #pragma GCC diagnostic push
    1817             : #pragma GCC diagnostic ignored "-Wold-style-cast"
    1818             :                     // not only old style cast (but it's C, so expected)
    1819             :                     // but they want a non-constant pointer!?
    1820             :                     //
    1821           0 :                     SSL_set_tlsext_host_name(ssl, const_cast<char *>(host.c_str()));
    1822             : #pragma GCC diagnostic pop
    1823           0 :                     using_sni = true;
    1824             :                 }
    1825             :             }
    1826             : 
    1827             :             // TODO: other SSL initialization?
    1828             : 
    1829             : #pragma GCC diagnostic push
    1830             : #pragma GCC diagnostic ignored "-Wold-style-cast"
    1831           0 :             BIO_set_conn_hostname(bio.get(), const_cast<char *>(addr.c_str()));
    1832           0 :             BIO_set_conn_port(bio.get(), const_cast<char *>(std::to_string(port).c_str()));
    1833             : #pragma GCC diagnostic pop
    1834             : 
    1835             :             // connect to the server (open the socket)
    1836             :             //
    1837           0 :             if(BIO_do_connect(bio.get()) <= 0)
    1838             :             {
    1839           0 :                 if(!using_sni)
    1840             :                 {
    1841           0 :                     SNAP_LOG_WARNING("the SNI feature is turned off,"
    1842             :                             " often failure to connect with SSL is because the SSL Hello message is missing the SNI (Server Name In)."
    1843             :                             " See the bio_client::options::set_sni().");
    1844             :                 }
    1845           0 :                 bio_log_errors();
    1846           0 :                 throw tcp_client_server_initialization_error("SSL BIO_do_connect() failed connecting BIO object to server");
    1847             :             }
    1848             : 
    1849             :             // encryption handshake
    1850             :             //
    1851           0 :             if(BIO_do_handshake(bio.get()) != 1)
    1852             :             {
    1853           0 :                 if(!using_sni)
    1854             :                 {
    1855           0 :                     SNAP_LOG_WARNING("the SNI feature is turned off,"
    1856             :                             " often failure to connect with SSL is because the SSL Hello message is missing the SNI (Server Name In)."
    1857             :                             " See the bio_client::options::set_sni().");
    1858             :                 }
    1859           0 :                 bio_log_errors();
    1860             :                 throw tcp_client_server_initialization_error("failed establishing a secure BIO connection with server, handshake failed."
    1861             :                             " Often such failures to process SSL is because the SSL Hello message is missing the SNI (Server Name In)."
    1862           0 :                             " See the bio_client::options::set_sni().");
    1863             :             }
    1864             : 
    1865             :             // verify that the peer certificate was signed by a
    1866             :             // recognized root authority
    1867             :             //
    1868           0 :             if(SSL_get_peer_certificate(ssl) == nullptr)
    1869             :             {
    1870           0 :                 bio_log_errors();
    1871           0 :                 throw tcp_client_server_initialization_error("peer failed presenting a certificate for security verification");
    1872             :             }
    1873             : 
    1874             :             // XXX: check that the call below is similar to the example
    1875             :             //      usage of SSL_CTX_set_verify() which checks the name
    1876             :             //      of the certificate, etc.
    1877             :             //
    1878           0 :             if(SSL_get_verify_result(ssl) != X509_V_OK)
    1879             :             {
    1880           0 :                 if(mode != mode_t::MODE_SECURE)
    1881             :                 {
    1882           0 :                     bio_log_errors();
    1883           0 :                     throw tcp_client_server_initialization_error("peer certificate could not be verified");
    1884             :                 }
    1885           0 :                 SNAP_LOG_WARNING("connecting with SSL but certificate verification failed.");
    1886             :             }
    1887             : 
    1888             :             // it worked, save the results
    1889             :             //
    1890           0 :             f_ssl_ctx.swap(ssl_ctx);
    1891           0 :             f_bio.swap(bio);
    1892             : 
    1893             :             // secure connection ready
    1894             :             //
    1895           0 :             char const * cipher_name(SSL_get_cipher(ssl));
    1896           0 :             int cipher_bits(0);
    1897           0 :             SSL_get_cipher_bits(ssl, &cipher_bits);
    1898           0 :             SNAP_LOG_DEBUG("connected with SSL cipher \"")(cipher_name)("\" representing ")(cipher_bits)(" bits of encryption.");
    1899             :         }
    1900           0 :         break;
    1901             : 
    1902           0 :     case mode_t::MODE_PLAIN:
    1903             :         {
    1904             :             // create a plain BIO connection
    1905             :             //
    1906           0 :             std::shared_ptr<BIO> bio;  // use reset(), see SNAP-507
    1907           0 :             bio.reset(BIO_new(BIO_s_connect()), bio_deleter);
    1908           0 :             if(!bio)
    1909             :             {
    1910           0 :                 bio_log_errors();
    1911           0 :                 throw tcp_client_server_initialization_error("failed initializing a BIO object");
    1912             :             }
    1913             : 
    1914             : #pragma GCC diagnostic push
    1915             : #pragma GCC diagnostic ignored "-Wold-style-cast"
    1916           0 :             BIO_set_conn_hostname(bio.get(), const_cast<char *>(addr.c_str()));
    1917           0 :             BIO_set_conn_port(bio.get(), const_cast<char *>(std::to_string(port).c_str()));
    1918             : #pragma GCC diagnostic pop
    1919             : 
    1920             :             // connect to the server (open the socket)
    1921             :             //
    1922           0 :             if(BIO_do_connect(bio.get()) <= 0)
    1923             :             {
    1924           0 :                 bio_log_errors();
    1925           0 :                 throw tcp_client_server_initialization_error("failed connecting BIO object to server");
    1926             :             }
    1927             : 
    1928             :             // it worked, save the results
    1929             :             //
    1930           0 :             f_bio.swap(bio);
    1931             : 
    1932             :             // plain connection ready
    1933             :         }
    1934           0 :         break;
    1935             : 
    1936             :     }
    1937             : 
    1938           0 :     if(opt.get_keepalive())
    1939             :     {
    1940             :         // retrieve the socket (we are still in the constructor so avoid
    1941             :         // calling other functions...)
    1942             :         //
    1943           0 :         int socket(-1);
    1944             : #pragma GCC diagnostic push
    1945             : #pragma GCC diagnostic ignored "-Wold-style-cast"
    1946           0 :         BIO_get_fd(f_bio.get(), &socket);
    1947             : #pragma GCC diagnostic pop
    1948           0 :         if(socket >= 0)
    1949             :         {
    1950             :             // if this call fails, we ignore the error, but still log the event
    1951             :             //
    1952           0 :             int optval(1);
    1953           0 :             socklen_t const optlen(sizeof(optval));
    1954           0 :             if(setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) != 0)
    1955             :             {
    1956           0 :                 SNAP_LOG_WARNING("an error occurred trying to mark client socket with SO_KEEPALIVE.");
    1957             :             }
    1958             :         }
    1959             :     }
    1960           0 : }
    1961             : 
    1962             : 
    1963             : /** \brief Create a BIO client object from an actual BIO pointer.
    1964             :  *
    1965             :  * This function is called by the server whenever it accepts a new BIO
    1966             :  * connection. The server then can return the bio_client object instead
    1967             :  * of a BIO object.
    1968             :  *
    1969             :  * \param[in] bio  The BIO pointer representing a BIO connection with a client.
    1970             :  */
    1971           0 : bio_client::bio_client(std::shared_ptr<BIO> bio)
    1972             :     //: f_ssl_ctx(nullptr) -- auto-init
    1973           0 :     : f_bio(bio)
    1974             : {
    1975           0 :     if(bio)
    1976             :     {
    1977             :         // TODO: somehow this does not seem to give us any information
    1978             :         //       about the cipher and other details...
    1979             :         //
    1980             :         //       this is because it is (way) too early, we did not even
    1981             :         //       receive the HELLO yet!
    1982             :         //
    1983           0 :         SSL * ssl(nullptr);
    1984             : #pragma GCC diagnostic push
    1985             : #pragma GCC diagnostic ignored "-Wold-style-cast"
    1986           0 :         BIO_get_ssl(bio.get(), &ssl);
    1987             : #pragma GCC diagnostic pop
    1988           0 :         if(ssl != nullptr)
    1989             :         {
    1990           0 :             char const * cipher_name(SSL_get_cipher(ssl));
    1991           0 :             int cipher_bits(0);
    1992           0 :             SSL_get_cipher_bits(ssl, &cipher_bits);
    1993           0 :             SNAP_LOG_DEBUG("accepted BIO client with SSL cipher \"")(cipher_name)("\" representing ")(cipher_bits)(" bits of encryption.");
    1994             :         }
    1995             :     }
    1996           0 : }
    1997             : 
    1998             : 
    1999             : /** \brief Clean up the BIO client object.
    2000             :  *
    2001             :  * This function cleans up the BIO client object by freeing the SSL_CTX
    2002             :  * and the BIO objects.
    2003             :  */
    2004           0 : bio_client::~bio_client()
    2005             : {
    2006             :     // f_bio and f_ssl_ctx are allocated using shared pointers with
    2007             :     // a deleter so we have nothing to do here.
    2008           0 : }
    2009             : 
    2010             : 
    2011             : /** \brief Close the connection.
    2012             :  *
    2013             :  * This function closes the connection by losing the f_bio object.
    2014             :  *
    2015             :  * As we are at it, we also lose the SSL context since we are not going
    2016             :  * to use it anymore either.
    2017             :  */
    2018           0 : void bio_client::close()
    2019             : {
    2020           0 :     f_bio.reset();
    2021           0 :     f_ssl_ctx.reset();
    2022           0 : }
    2023             : 
    2024             : 
    2025             : /** \brief Get the socket descriptor.
    2026             :  *
    2027             :  * This function returns the TCP client socket descriptor. This can be
    2028             :  * used to change the descriptor behavior (i.e. make it non-blocking for
    2029             :  * example.)
    2030             :  *
    2031             :  * \note
    2032             :  * If the socket was closed, then the function returns -1.
    2033             :  *
    2034             :  * \warning
    2035             :  * This socket is generally managed by the BIO library and thus it may
    2036             :  * create unwanted side effects to change the socket under the feet of
    2037             :  * the BIO library...
    2038             :  *
    2039             :  * \return The socket descriptor.
    2040             :  */
    2041           0 : int bio_client::get_socket() const
    2042             : {
    2043           0 :     if(f_bio)
    2044             :     {
    2045             :         int c;
    2046             : #pragma GCC diagnostic push
    2047             : #pragma GCC diagnostic ignored "-Wold-style-cast"
    2048           0 :         BIO_get_fd(f_bio.get(), &c);
    2049             : #pragma GCC diagnostic pop
    2050           0 :         return c;
    2051             :     }
    2052             : 
    2053           0 :     return -1;
    2054             : }
    2055             : 
    2056             : 
    2057             : /** \brief Get the TCP client port.
    2058             :  *
    2059             :  * This function returns the port used when creating the TCP client.
    2060             :  * Note that this is the port the server is listening to and not the port
    2061             :  * the TCP client is currently connected to.
    2062             :  *
    2063             :  * \note
    2064             :  * If the connection was closed, return -1.
    2065             :  *
    2066             :  * \return The TCP client port.
    2067             :  */
    2068           0 : int bio_client::get_port() const
    2069             : {
    2070           0 :     if(f_bio)
    2071             :     {
    2072           0 :         return std::atoi(BIO_get_conn_port(f_bio.get()));
    2073             :     }
    2074             : 
    2075           0 :     return -1;
    2076             : }
    2077             : 
    2078             : 
    2079             : /** \brief Get the TCP server address.
    2080             :  *
    2081             :  * This function returns the address used when creating the TCP address as is.
    2082             :  * Note that this is the address of the server where the client is connected
    2083             :  * and not the address where the client is running (although it may be the
    2084             :  * same.)
    2085             :  *
    2086             :  * Use the get_client_addr() function to retrieve the client's TCP address.
    2087             :  *
    2088             :  * \note
    2089             :  * If the connection was closed, this function returns "".
    2090             :  *
    2091             :  * \return The TCP client address.
    2092             :  */
    2093           0 : std::string bio_client::get_addr() const
    2094             : {
    2095           0 :     if(f_bio)
    2096             :     {
    2097           0 :         return BIO_get_conn_hostname(f_bio.get());
    2098             :     }
    2099             : 
    2100           0 :     return "";
    2101             : }
    2102             : 
    2103             : 
    2104             : /** \brief Get the TCP client port.
    2105             :  *
    2106             :  * This function retrieve the port of the client (used on your computer).
    2107             :  * This is retrieved from the socket using the getsockname() function.
    2108             :  *
    2109             :  * \return The port or -1 if it cannot be determined.
    2110             :  */
    2111           0 : int bio_client::get_client_port() const
    2112             : {
    2113             :     // get_socket() returns -1 if f_bio is nullptr
    2114             :     //
    2115           0 :     int const s(get_socket());
    2116           0 :     if(s < 0)
    2117             :     {
    2118           0 :         return -1;
    2119             :     }
    2120             : 
    2121             :     struct sockaddr addr;
    2122           0 :     socklen_t len(sizeof(addr));
    2123           0 :     int const r(getsockname(s, &addr, &len));
    2124           0 :     if(r != 0)
    2125             :     {
    2126           0 :         return -1;
    2127             :     }
    2128             :     // Note: I know the port is at the exact same location in both
    2129             :     //       structures in Linux but it could change on other Unices
    2130           0 :     switch(addr.sa_family)
    2131             :     {
    2132           0 :     case AF_INET:
    2133             :         // IPv4
    2134           0 :         return reinterpret_cast<sockaddr_in *>(&addr)->sin_port;
    2135             : 
    2136           0 :     case AF_INET6:
    2137             :         // IPv6
    2138           0 :         return reinterpret_cast<sockaddr_in6 *>(&addr)->sin6_port;
    2139             : 
    2140           0 :     default:
    2141           0 :         return -1;
    2142             : 
    2143             :     }
    2144             :     snap::NOTREACHED();
    2145             : }
    2146             : 
    2147             : 
    2148             : /** \brief Get the TCP client address.
    2149             :  *
    2150             :  * This function retrieve the IP address of the client (your computer).
    2151             :  * This is retrieved from the socket using the getsockname() function.
    2152             :  *
    2153             :  * \note
    2154             :  * The function returns an empty string if the connection was lost
    2155             :  * or purposefully closed.
    2156             :  *
    2157             :  * \return The IP address as a string.
    2158             :  */
    2159           0 : std::string bio_client::get_client_addr() const
    2160             : {
    2161             :     // the socket may be invalid, i.e. f_bio may have been deallocated.
    2162             :     //
    2163           0 :     int const s(get_socket());
    2164           0 :     if(s < 0)
    2165             :     {
    2166           0 :         return std::string();
    2167             :     }
    2168             : 
    2169             :     struct sockaddr addr;
    2170           0 :     socklen_t len(sizeof(addr));
    2171           0 :     int const r(getsockname(s, &addr, &len));
    2172           0 :     if(r != 0)
    2173             :     {
    2174           0 :         throw tcp_client_server_runtime_error("failed reading address");
    2175             :     }
    2176             :     char buf[BUFSIZ];
    2177           0 :     switch(addr.sa_family)
    2178             :     {
    2179           0 :     case AF_INET:
    2180             :         // TODO: verify that 'r' >= sizeof(something)
    2181           0 :         inet_ntop(AF_INET, &reinterpret_cast<struct sockaddr_in *>(&addr)->sin_addr, buf, sizeof(buf));
    2182           0 :         break;
    2183             : 
    2184           0 :     case AF_INET6:
    2185             :         // TODO: verify that 'r' >= sizeof(something)
    2186           0 :         inet_ntop(AF_INET6, &reinterpret_cast<struct sockaddr_in6 *>(&addr)->sin6_addr, buf, sizeof(buf));
    2187           0 :         break;
    2188             : 
    2189           0 :     default:
    2190           0 :         throw tcp_client_server_runtime_error("unknown address family");
    2191             : 
    2192             :     }
    2193           0 :     return buf;
    2194             : }
    2195             : 
    2196             : 
    2197             : /** \brief Read data from the socket.
    2198             :  *
    2199             :  * A TCP socket is a stream type of socket and one can read data from it
    2200             :  * as if it were a regular file. This function reads \p size bytes and
    2201             :  * returns. The function returns early if the server closes the connection.
    2202             :  *
    2203             :  * If your socket is blocking, \p size should be exactly what you are
    2204             :  * expecting or this function will block forever or until the server
    2205             :  * closes the connection.
    2206             :  *
    2207             :  * The function returns -1 if an error occurs. The error is available in
    2208             :  * errno as expected in the POSIX interface.
    2209             :  *
    2210             :  * \note
    2211             :  * If the connection was closed, this function returns -1.
    2212             :  *
    2213             :  * \warning
    2214             :  * When the function returns zero, it is likely that the server closed
    2215             :  * the connection. It may also be that the buffer was empty and that
    2216             :  * the BIO decided to return early. Since we use a blocking mechanism
    2217             :  * by default, that should not happen.
    2218             :  *
    2219             :  * \todo
    2220             :  * At this point, I do not know for sure whether errno is properly set
    2221             :  * or not. It is not unlikely that the BIO library does not keep a clean
    2222             :  * errno error since they have their own error management.
    2223             :  *
    2224             :  * \param[in,out] buf  The buffer where the data is read.
    2225             :  * \param[in] size  The size of the buffer.
    2226             :  *
    2227             :  * \return The number of bytes read from the socket, or -1 on errors.
    2228             :  *
    2229             :  * \sa read_line()
    2230             :  * \sa write()
    2231             :  */
    2232           0 : int bio_client::read(char * buf, size_t size)
    2233             : {
    2234           0 :     if(!f_bio)
    2235             :     {
    2236           0 :         errno = EBADF;
    2237           0 :         return -1;
    2238             :     }
    2239             : 
    2240           0 :     int const r(static_cast<int>(BIO_read(f_bio.get(), buf, size)));
    2241           0 :     if(r <= -2)
    2242             :     {
    2243             :         // the BIO is not implemented
    2244             :         //
    2245           0 :         bio_log_errors();
    2246           0 :         errno = EIO;
    2247           0 :         return -1;
    2248             :     }
    2249           0 :     if(r == -1 || r == 0)
    2250             :     {
    2251           0 :         if(BIO_should_retry(f_bio.get()))
    2252             :         {
    2253           0 :             errno = EAGAIN;
    2254           0 :             return 0;
    2255             :         }
    2256             :         // did we reach the "end of the file"? i.e. did the server
    2257             :         // close our connection? (this better replicates what a
    2258             :         // normal socket does when reading from a closed socket)
    2259             :         //
    2260           0 :         if(BIO_eof(f_bio.get()))
    2261             :         {
    2262           0 :             return 0;
    2263             :         }
    2264           0 :         if(r != 0)
    2265             :         {
    2266             :             // the BIO generated an error
    2267           0 :             bio_log_errors();
    2268           0 :             errno = EIO;
    2269           0 :             return -1;
    2270             :         }
    2271             :     }
    2272           0 :     return r;
    2273             : }
    2274             : 
    2275             : 
    2276             : /** \brief Read one line.
    2277             :  *
    2278             :  * This function reads one line from the current location up to the next
    2279             :  * '\\n' character. We do not have any special handling of the '\\r'
    2280             :  * character.
    2281             :  *
    2282             :  * The function may return 0 (an empty string) when the server closes
    2283             :  * the connection.
    2284             :  *
    2285             :  * \note
    2286             :  * If the connection was closed then this function returns -1.
    2287             :  *
    2288             :  * \warning
    2289             :  * A return value of zero can mean "empty line" and not end of file. It
    2290             :  * is up to you to know whether your protocol allows for empty lines or
    2291             :  * not. If so, you may not be able to make use of this function.
    2292             :  *
    2293             :  * \param[out] line  The resulting line read from the server. The function
    2294             :  *                   first clears the contents.
    2295             :  *
    2296             :  * \return The number of bytes read from the socket, or -1 on errors.
    2297             :  *         If the function returns 0 or more, then the \p line parameter
    2298             :  *         represents the characters read on the network without the '\n'.
    2299             :  *
    2300             :  * \sa read()
    2301             :  */
    2302           0 : int bio_client::read_line(std::string & line)
    2303             : {
    2304           0 :     line.clear();
    2305           0 :     int len(0);
    2306             :     for(;;)
    2307             :     {
    2308             :         char c;
    2309           0 :         int r(read(&c, sizeof(c)));
    2310           0 :         if(r <= 0)
    2311             :         {
    2312           0 :             return len == 0 && r < 0 ? -1 : len;
    2313             :         }
    2314           0 :         if(c == '\n')
    2315             :         {
    2316           0 :             return len;
    2317             :         }
    2318           0 :         ++len;
    2319           0 :         line += c;
    2320           0 :     }
    2321             : }
    2322             : 
    2323             : 
    2324             : /** \brief Write data to the socket.
    2325             :  *
    2326             :  * A BIO socket is a stream type of socket and one can write data to it
    2327             :  * as if it were a regular file. This function writes \p size bytes to
    2328             :  * the socket and then returns. This function returns early if the server
    2329             :  * closes the connection.
    2330             :  *
    2331             :  * If your socket is not blocking, less than \p size bytes may be written
    2332             :  * to the socket. In that case you are responsible for calling the function
    2333             :  * again to write the remainder of the buffer until the function returns
    2334             :  * a number of bytes written equal to \p size.
    2335             :  *
    2336             :  * The function returns -1 if an error occurs. The error is available in
    2337             :  * errno as expected in the POSIX interface.
    2338             :  *
    2339             :  * \note
    2340             :  * If the connection was closed, return -1.
    2341             :  *
    2342             :  * \todo
    2343             :  * At this point, I do not know for sure whether errno is properly set
    2344             :  * or not. It is not unlikely that the BIO library does not keep a clean
    2345             :  * errno error since they have their own error management.
    2346             :  *
    2347             :  * \param[in] buf  The buffer with the data to send over the socket.
    2348             :  * \param[in] size  The number of bytes in buffer to send over the socket.
    2349             :  *
    2350             :  * \return The number of bytes that were actually accepted by the socket
    2351             :  * or -1 if an error occurs.
    2352             :  *
    2353             :  * \sa read()
    2354             :  */
    2355           0 : int bio_client::write(char const * buf, size_t size)
    2356             : {
    2357             : #ifdef _DEBUG
    2358             :     // This write is useful when developing APIs against 3rd party
    2359             :     // servers, otherwise, it's just too much debug
    2360             :     //SNAP_LOG_TRACE("bio_client::write(): buf=")(buf)(", size=")(size);
    2361             : #endif
    2362           0 :     if(!f_bio)
    2363             :     {
    2364           0 :         errno = EBADF;
    2365           0 :         return -1;
    2366             :     }
    2367             : 
    2368           0 :     int const r(static_cast<int>(BIO_write(f_bio.get(), buf, size)));
    2369           0 :     if(r <= -2)
    2370             :     {
    2371             :         // the BIO is not implemented
    2372           0 :         bio_log_errors();
    2373           0 :         errno = EIO;
    2374           0 :         return -1;
    2375             :     }
    2376           0 :     if(r == -1 || r == 0)
    2377             :     {
    2378           0 :         if(BIO_should_retry(f_bio.get()))
    2379             :         {
    2380           0 :             errno = EAGAIN;
    2381           0 :             return 0;
    2382             :         }
    2383             :         // the BIO generated an error (TBD should we check BIO_eof() too?)
    2384           0 :         bio_log_errors();
    2385           0 :         errno = EIO;
    2386           0 :         return -1;
    2387             :     }
    2388           0 :     BIO_flush(f_bio.get());
    2389           0 :     return r;
    2390             : }
    2391             : 
    2392             : 
    2393             : 
    2394             : 
    2395             : 
    2396             : 
    2397             : 
    2398             : 
    2399             : 
    2400             : // ========================= BIO SERVER =========================
    2401             : 
    2402             : 
    2403             : /** \class bio_server
    2404             :  * \brief Create a BIO server, bind it, and listen for connections.
    2405             :  *
    2406             :  * This class is a server socket implementation used to listen for
    2407             :  * connections that are to use TLS encryptions.
    2408             :  *
    2409             :  * The bind address must be available for the server initialization
    2410             :  * to succeed.
    2411             :  *
    2412             :  * The BIO extension is from the OpenSSL library and it allows the server
    2413             :  * to allow connections using SSL (TLS really now a day). The server
    2414             :  * expects to be given information about a certificate and a private
    2415             :  * key to function. You may also use the server in a non-secure manner
    2416             :  * (without the TLS layer) so you do not need to implement two instances
    2417             :  * of your server, one with bio_server and one with tcp_server.
    2418             :  */
    2419             : 
    2420             : 
    2421             : 
    2422             : 
    2423             : /** \brief Contruct a bio_server object.
    2424             :  *
    2425             :  * The bio_server constructor initializes a BIO server and listens
    2426             :  * for connections from the specified address and port.
    2427             :  *
    2428             :  * The \p certificate and \p private_key filenames are expected to point
    2429             :  * to a PEM file (.pem extension) that include the encryption information.
    2430             :  *
    2431             :  * The certificate file may include a chain in which case the whole chain
    2432             :  * will be taken in account.
    2433             :  *
    2434             :  * \warning
    2435             :  * Currently the max_connections parameter is pretty much ignored since
    2436             :  * there is no way to pass that paramter down to the BIO interface. In
    2437             :  * that code they use the SOMAXCONN definition which under Linux is
    2438             :  * defined at 128 (Ubuntu 16.04.1). See:
    2439             :  * /usr/include/x86_64-linux-gnu/bits/socket.h
    2440             :  *
    2441             :  * \param[in] addr_port  The address and port defined in an addr object.
    2442             :  * \param[in] max_connections  The number of connections to keep in the listen queue.
    2443             :  * \param[in] reuse_addr  Whether to mark the socket with the SO_REUSEADDR flag.
    2444             :  * \param[in] certificate  The server certificate filename (PEM).
    2445             :  * \param[in] private_key  The server private key filename (PEM).
    2446             :  * \param[in] mode  The mode used to create the listening socket.
    2447             :  */
    2448           0 : bio_server::bio_server(addr::addr const & addr_port, int max_connections, bool reuse_addr, std::string const & certificate, std::string const & private_key, mode_t mode)
    2449           0 :     : f_max_connections(max_connections <= 0 ? MAX_CONNECTIONS : max_connections)
    2450             : {
    2451           0 :     if(f_max_connections < 5)
    2452             :     {
    2453           0 :         f_max_connections = 5;
    2454             :     }
    2455           0 :     else if(f_max_connections > 1000)
    2456             :     {
    2457           0 :         f_max_connections = 1000;
    2458             :     }
    2459             : 
    2460           0 :     bio_initialize();
    2461             : 
    2462           0 :     switch(mode)
    2463             :     {
    2464           0 :     case mode_t::MODE_SECURE:
    2465             :         {
    2466             :             // the following code is based on the example shown in the man page
    2467             :             //
    2468             :             //        man BIO_f_ssl
    2469             :             //
    2470           0 :             if(certificate.empty()
    2471           0 :             || private_key.empty())
    2472             :             {
    2473           0 :                 throw tcp_client_server_parameter_error("with MODE_SECURE you must specify a certificate and a private_key filename");
    2474             :             }
    2475             : 
    2476           0 :             std::shared_ptr<SSL_CTX> ssl_ctx; // use reset(), see SNAP-507
    2477           0 :             ssl_ctx.reset(SSL_CTX_new(SSLv23_server_method()), ssl_ctx_deleter);
    2478           0 :             if(!ssl_ctx)
    2479             :             {
    2480           0 :                 bio_log_errors();
    2481           0 :                 throw tcp_client_server_initialization_error("failed creating an SSL_CTX server object");
    2482             :             }
    2483             : 
    2484           0 :             SSL_CTX_set_cipher_list(ssl_ctx.get(), "ALL");//"HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4");
    2485             : 
    2486             :             // Assign the certificate to the SSL context
    2487             :             //
    2488             :             // TBD: we may want to use SSL_CTX_use_certificate_file() instead
    2489             :             //      (i.e. not the "chained" version)
    2490             :             //
    2491           0 :             if(!SSL_CTX_use_certificate_chain_file(ssl_ctx.get(), certificate.c_str()))
    2492             :             {
    2493           0 :                 bio_log_errors();
    2494           0 :                 throw tcp_client_server_initialization_error("failed initializing an SSL_CTX server object certificate");
    2495             :             }
    2496             : 
    2497             :             // Assign the private key to the SSL context
    2498             :             //
    2499           0 :             if(!SSL_CTX_use_PrivateKey_file(ssl_ctx.get(), private_key.c_str(), SSL_FILETYPE_PEM))
    2500             :             {
    2501             :                 // on failure, try again again with the RSA version, just in case
    2502             :                 // (probably useless?)
    2503             :                 //
    2504           0 :                 if(!SSL_CTX_use_RSAPrivateKey_file(ssl_ctx.get(), private_key.c_str(), SSL_FILETYPE_PEM))
    2505             :                 {
    2506           0 :                     bio_log_errors();
    2507           0 :                     throw tcp_client_server_initialization_error("failed initializing an SSL_CTX server object private key");
    2508             :                 }
    2509             :             }
    2510             : 
    2511             :             // Verify that the private key and certifcate are a match
    2512             :             //
    2513           0 :             if(!SSL_CTX_check_private_key(ssl_ctx.get()))
    2514             :             {
    2515           0 :                 bio_log_errors();
    2516           0 :                 throw tcp_client_server_initialization_error("failed initializing an SSL_CTX server object private key");
    2517             :             }
    2518             : 
    2519             :             // create a BIO connection with SSL
    2520             :             //
    2521           0 :             std::unique_ptr<BIO, void (*)(BIO *)> bio(BIO_new_ssl(ssl_ctx.get(), 0), bio_deleter);
    2522           0 :             if(!bio)
    2523             :             {
    2524           0 :                 bio_log_errors();
    2525           0 :                 throw tcp_client_server_initialization_error("failed initializing a BIO server object");
    2526             :             }
    2527             : 
    2528             :             // get the SSL pointer, which generally means that the BIO
    2529             :             // allocate succeeded fully, so we can set auto-retry
    2530             :             //
    2531           0 :             SSL * ssl(nullptr);
    2532             : #pragma GCC diagnostic push
    2533             : #pragma GCC diagnostic ignored "-Wold-style-cast"
    2534           0 :             BIO_get_ssl(bio.get(), &ssl);
    2535             : #pragma GCC diagnostic pop
    2536           0 :             if(ssl == nullptr)
    2537             :             {
    2538             :                 // TBD: does this mean we would have a plain connection?
    2539           0 :                 bio_log_errors();
    2540           0 :                 throw tcp_client_server_initialization_error("failed connecting BIO object with SSL_CTX object");
    2541             :             }
    2542             : 
    2543             :             // allow automatic retries in case the connection somehow needs
    2544             :             // an SSL renegotiation (maybe we should turn that off for cases
    2545             :             // where we connect to a secure payment gateway?)
    2546             :             //
    2547           0 :             SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
    2548             : 
    2549             :             // create a listening connection
    2550             :             //
    2551           0 :             std::shared_ptr<BIO> listen;  // use reset(), see SNAP-507
    2552           0 :             listen.reset(BIO_new_accept(addr_port.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_PORT).c_str()), bio_deleter);
    2553           0 :             if(!listen)
    2554             :             {
    2555           0 :                 bio_log_errors();
    2556           0 :                 throw tcp_client_server_initialization_error("failed initializing a BIO server object");
    2557             :             }
    2558             : 
    2559           0 :             BIO_set_bind_mode(listen.get(), reuse_addr ? BIO_BIND_REUSEADDR : BIO_BIND_NORMAL);
    2560             : 
    2561             :             // Attach the SSL bio to the listening BIO, this means whenever
    2562             :             // a new connection is accepted, it automatically attaches it to
    2563             :             // an SSL connection
    2564             :             //
    2565             : #pragma GCC diagnostic push
    2566             : #pragma GCC diagnostic ignored "-Wold-style-cast"
    2567           0 :             BIO_set_accept_bios(listen.get(), bio.get());
    2568             : #pragma GCC diagnostic pop
    2569             : 
    2570             :             // WARNING: the listen object takes ownership of the `bio`
    2571             :             //          pointer and thus we have to make sure that we
    2572             :             //          do not keep it in our unique_ptr<>().
    2573             :             //
    2574           0 :             snap::NOTUSED(bio.release());
    2575             : 
    2576             :             // Actually call bind() and listen() on the socket
    2577             :             //
    2578             :             // IMPORTANT NOTE: The BIO_do_accept() is overloaded, it does
    2579             :             // two things: (a) it bind() + listen() when called the very
    2580             :             // first time (i.e. the call right here); (b) it actually
    2581             :             // accepts a client connection
    2582             :             //
    2583           0 :             int const r(BIO_do_accept(listen.get()));
    2584           0 :             if(r <= 0)
    2585             :             {
    2586           0 :                 bio_log_errors();
    2587           0 :                 throw tcp_client_server_initialization_error("failed initializing the BIO server socket to listen for client connections");
    2588             :             }
    2589             : 
    2590             :             // it worked, save the results
    2591           0 :             f_ssl_ctx.swap(ssl_ctx);
    2592           0 :             f_listen.swap(listen);
    2593             : 
    2594             :             // secure connection ready
    2595             :         }
    2596           0 :         break;
    2597             : 
    2598           0 :     case mode_t::MODE_PLAIN:
    2599             :         {
    2600           0 :             std::shared_ptr<BIO> listen; // use reset(), see SNAP-507
    2601           0 :             listen.reset(BIO_new_accept(addr_port.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_PORT).c_str()), bio_deleter);
    2602           0 :             if(!listen)
    2603             :             {
    2604           0 :                 bio_log_errors();
    2605           0 :                 throw tcp_client_server_initialization_error("failed initializing a BIO server object");
    2606             :             }
    2607             : 
    2608           0 :             BIO_set_bind_mode(listen.get(), BIO_BIND_REUSEADDR);
    2609             : 
    2610             :             // Actually call bind() and listen() on the socket
    2611             :             //
    2612             :             // IMPORTANT NOTE: The BIO_do_accept() is overloaded, it does
    2613             :             // two things: (a) it bind() + listen() when called the very
    2614             :             // first time (i.e. the call right here); (b) it actually
    2615             :             // accepts a client connection
    2616             :             //
    2617           0 :             int const r(BIO_do_accept(listen.get()));
    2618           0 :             if(r <= 0)
    2619             :             {
    2620           0 :                 bio_log_errors();
    2621           0 :                 throw tcp_client_server_initialization_error("failed initializing the BIO server socket to listen for client connections");
    2622             :             }
    2623             : 
    2624             :             // it worked, save the results
    2625             :             //
    2626           0 :             f_listen.swap(listen);
    2627             :         }
    2628           0 :         break;
    2629             : 
    2630             :     }
    2631           0 : }
    2632             : 
    2633             : 
    2634             : /** \brief Tell you whether the server uses a secure BIO or not.
    2635             :  *
    2636             :  * This function checks whether the BIO is using encryption (true)
    2637             :  * or is a plain connection (false).
    2638             :  *
    2639             :  * \return true if the BIO was created in secure mode.
    2640             :  */
    2641           0 : bool bio_server::is_secure() const
    2642             : {
    2643           0 :     return f_ssl_ctx != nullptr;
    2644             : }
    2645             : 
    2646             : 
    2647             : /** \brief Get the listening socket.
    2648             :  *
    2649             :  * This function returns the file descriptor of the listening socket.
    2650             :  * By default the socket is in blocking mode.
    2651             :  *
    2652             :  * \return The listening socket file descriptor.
    2653             :  */
    2654           0 : int bio_server::get_socket() const
    2655             : {
    2656           0 :     if(f_listen)
    2657             :     {
    2658             :         int c;
    2659             : #pragma GCC diagnostic push
    2660             : #pragma GCC diagnostic ignored "-Wold-style-cast"
    2661           0 :         BIO_get_fd(f_listen.get(), &c);
    2662             : #pragma GCC diagnostic pop
    2663           0 :         return c;
    2664             :     }
    2665             : 
    2666           0 :     return -1;
    2667             : }
    2668             : 
    2669             : 
    2670             : /** \brief Retrieve one new connection.
    2671             :  *
    2672             :  * This function will wait until a new connection arrives and returns a
    2673             :  * new bio_client object for each new connection.
    2674             :  *
    2675             :  * If the socket is made non-blocking then the function may return without
    2676             :  * a bio_client object (i.e. a null pointer instead.)
    2677             :  *
    2678             :  * \return A shared pointer to a newly allocated bio_client object.
    2679             :  */
    2680           0 : bio_client::pointer_t bio_server::accept()
    2681             : {
    2682             :     // TBD: does one call to BIO_do_accept() accept at most one connection
    2683             :     //      at a time or could it be that 'r' will be set to 2, 3, 4...
    2684             :     //      as more connections get accepted?
    2685             :     //
    2686           0 :     int const r(BIO_do_accept(f_listen.get()));
    2687           0 :     if(r <= 0)
    2688             :     {
    2689             :         // TBD: should we instead return an empty shared pointer in this case?
    2690             :         //
    2691           0 :         bio_log_errors();
    2692           0 :         throw tcp_client_server_runtime_error("failed accepting a new BIO");
    2693             :     }
    2694             : 
    2695             :     // retrieve the new connection by "popping it"
    2696             :     //
    2697           0 :     std::shared_ptr<BIO> bio; // use reset(), see SNAP-507
    2698           0 :     bio.reset(BIO_pop(f_listen.get()), bio_deleter);
    2699           0 :     if(bio == nullptr)
    2700             :     {
    2701           0 :         bio_log_errors();
    2702           0 :         throw tcp_client_server_runtime_error("failed retrieving the accepted BIO");
    2703             :     }
    2704             : 
    2705             :     // mark the new connection with the SO_KEEPALIVE flag
    2706           0 :     if(f_keepalive)
    2707             :     {
    2708             :         // retrieve the socket (we do not yet have a bio_client object
    2709             :         // so we cannot call a get_socket() function...)
    2710             :         //
    2711           0 :         int socket(-1);
    2712             : #pragma GCC diagnostic push
    2713             : #pragma GCC diagnostic ignored "-Wold-style-cast"
    2714           0 :         BIO_get_fd(bio.get(), &socket);
    2715             : #pragma GCC diagnostic pop
    2716           0 :         if(socket >= 0)
    2717             :         {
    2718             :             // if this call fails, we ignore the error, but still log the event
    2719             :             //
    2720           0 :             int optval(1);
    2721           0 :             socklen_t const optlen(sizeof(optval));
    2722           0 :             if(setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) != 0)
    2723             :             {
    2724           0 :                 SNAP_LOG_WARNING("bio_server::accept(): an error occurred trying to mark accepted socket with SO_KEEPALIVE.");
    2725             :             }
    2726             :         }
    2727             :     }
    2728             : 
    2729           0 :     return bio_client::pointer_t(new bio_client(bio));
    2730             : }
    2731             : 
    2732             : 
    2733             : 
    2734             : 
    2735             : 
    2736             : 
    2737             : 
    2738             : 
    2739             : 
    2740             : 
    2741             : 
    2742             : 
    2743             : 
    2744             : /** \brief Clean up the BIO environment.
    2745             :  *
    2746             :  * This function cleans up the BIO environment.
    2747             :  *
    2748             :  * \note
    2749             :  * This function is here for documentation rather than to get called.
    2750             :  * Whenever you exit a process that uses the BIO calls it will leak
    2751             :  * a few things. To make the process really spanking clean, you want
    2752             :  * to call this function before exit(3). You have to make sure that
    2753             :  * you call this function only after every single BIO object was
    2754             :  * closed and none must be opened after this call.
    2755             :  */
    2756           0 : void cleanup()
    2757             : {
    2758           0 :     thread_cleanup();
    2759           0 :     bio_cleanup();
    2760           0 : }
    2761             : 
    2762             : 
    2763             : /** \brief Before a thread exits, this function must be called.
    2764             :  *
    2765             :  * Any error which is still attached to a thread must be removed
    2766             :  * before the thread dies or it will be lost. This function must
    2767             :  * be called before you return from your
    2768             :  * snap::snap_thread::snap_runner::run()
    2769             :  * function.
    2770             :  *
    2771             :  * The thread must be pro-active and make sure to catch() errors
    2772             :  * if necessary to ensure that this function gets called before
    2773             :  * it exists.
    2774             :  *
    2775             :  * Also, this means all BIO connections were properly terminated
    2776             :  * before the thread returns.
    2777             :  *
    2778             :  * \note
    2779             :  * TBD--this may not be required. I read a few things a while back
    2780             :  * saying that certain things were now automatic in the BIO library
    2781             :  * and this may very well be one of them. To test this function,
    2782             :  * see the snapdbproxy/src/snapdbproxy_connection.cpp and see how
    2783             :  * it works one way or the other.
    2784             :  */
    2785           0 : void cleanup_on_thread_exit()
    2786             : {
    2787           0 :     per_thread_cleanup();
    2788           0 : }
    2789             : 
    2790             : 
    2791             : 
    2792             : 
    2793             : 
    2794             : 
    2795             : 
    2796             : 
    2797             : 
    2798             : // ========================= HELPER FUNCTIONS =========================
    2799             : 
    2800             : 
    2801             : 
    2802             : /** \brief Check wether a string represents an IPv4 address.
    2803             :  *
    2804             :  * This function quickly checks whether the specified string defines a
    2805             :  * valid IPv4 address. It supports all classes (a.b.c.d, a.b.c., a.b, a)
    2806             :  * and all numbers can be in decimal, hexadecimal, or octal.
    2807             :  *
    2808             :  * \note
    2809             :  * The function can be called with a null pointer in which case it
    2810             :  * immediate returns false.
    2811             :  *
    2812             :  * \param[in] ip  A pointer to a string holding an address.
    2813             :  *
    2814             :  * \return true if the \p ip string represents an IPv4 address.
    2815             :  *
    2816             :  * \sa snap_inet::inet_pton_v6()
    2817             :  */
    2818           0 : bool is_ipv4(char const * ip)
    2819             : {
    2820           0 :     if(ip == nullptr)
    2821             :     {
    2822           0 :         return false;
    2823             :     }
    2824             : 
    2825             :     // we must have (1) a number then (2) a dot or end of string
    2826             :     // with a maximum of 4 numbers and 3 dots
    2827             :     //
    2828             :     int64_t addr[4];
    2829           0 :     size_t pos(0);
    2830           0 :     for(;; ++ip, ++pos)
    2831             :     {
    2832           0 :         if(*ip < '0' || *ip > '9' || pos >= sizeof(addr) / sizeof(addr[0]))
    2833             :         {
    2834             :             // not a valid number
    2835           0 :             return false;
    2836             :         }
    2837           0 :         int64_t value(0);
    2838             : 
    2839             :         // number, may be decimal, octal, or hexadecimal
    2840           0 :         if(*ip == '0')
    2841             :         {
    2842           0 :             if(ip[1] == 'x' || ip[1] == 'X')
    2843             :             {
    2844             :                 // expect hexadecimal
    2845           0 :                 bool first(true);
    2846           0 :                 for(ip += 2;; ++ip, first = false)
    2847             :                 {
    2848           0 :                     if(*ip >= '0' && *ip <= '9')
    2849             :                     {
    2850           0 :                         value = value * 16 + *ip - '0';
    2851             :                     }
    2852           0 :                     else if(*ip >= 'a' && *ip <= 'f')
    2853             :                     {
    2854           0 :                         value = value * 16 + *ip - 'a' + 10;
    2855             :                     }
    2856           0 :                     else if(*ip >= 'A' && *ip <= 'F')
    2857             :                     {
    2858           0 :                         value = value * 16 + *ip - 'A' + 10;
    2859             :                     }
    2860             :                     else
    2861             :                     {
    2862           0 :                         if(first)
    2863             :                         {
    2864             :                             // not even one digit, not good
    2865           0 :                             return false;
    2866             :                         }
    2867             :                         // not valid hexadecimal, may be '.' or '\0' (tested below)
    2868           0 :                         break;
    2869             :                     }
    2870           0 :                     if(value >= 0x100000000)
    2871             :                     {
    2872             :                         // too large even if we have no dots
    2873           0 :                         return false;
    2874             :                     }
    2875           0 :                 }
    2876             :             }
    2877             :             else
    2878             :             {
    2879             :                 // expect octal
    2880           0 :                 for(++ip; *ip >= '0' && *ip <= '8'; ++ip)
    2881             :                 {
    2882           0 :                     value = value * 8 + *ip - '0';
    2883           0 :                     if(value >= 0x100000000)
    2884             :                     {
    2885             :                         // too large even if we have no dots
    2886           0 :                         return false;
    2887             :                     }
    2888             :                 }
    2889             :             }
    2890             :         }
    2891             :         else
    2892             :         {
    2893             :             // expect decimal
    2894           0 :             for(; *ip >= '0' && *ip <= '9'; ++ip)
    2895             :             {
    2896           0 :                 value = value * 10 + *ip - '0';
    2897           0 :                 if(value >= 0x100000000)
    2898             :                 {
    2899             :                     // too large even if we have no dots
    2900           0 :                     return false;
    2901             :                 }
    2902             :             }
    2903             :         }
    2904             : //std::cerr << "value[" << pos << "] = " << value << "\n";
    2905           0 :         addr[pos] = value;
    2906           0 :         if(*ip != '.')
    2907             :         {
    2908           0 :             if(*ip != '\0')
    2909             :             {
    2910           0 :                 return false;
    2911             :             }
    2912           0 :             ++pos;
    2913           0 :             break;
    2914             :         }
    2915           0 :     }
    2916             : 
    2917             : //std::cerr << "pos = " << pos << "\n";
    2918           0 :     switch(pos)
    2919             :     {
    2920           0 :     case 1:
    2921             :         // one large value is considered valid for IPv4
    2922             :         // max. was already checked
    2923           0 :         return true;
    2924             : 
    2925           0 :     case 2:
    2926           0 :         return addr[0] < 256 && addr[1] < 0x1000000;
    2927             : 
    2928           0 :     case 3:
    2929           0 :         return addr[0] < 256 && addr[1] < 256 && addr[2] < 0x10000;
    2930             : 
    2931           0 :     case 4:
    2932           0 :         return addr[0] < 256 && addr[1] < 256 && addr[2] < 256 && addr[3] < 256;
    2933             : 
    2934             :     //case 0: (can happen on empty string)
    2935           0 :     default:
    2936             :         // no values, that is incorrect!?
    2937           0 :         return false;
    2938             : 
    2939             :     }
    2940             : 
    2941             :     snap::NOTREACHED();
    2942             : }
    2943             : 
    2944             : 
    2945             : /** \brief Check wether a string represents an IPv6 address.
    2946             :  *
    2947             :  * This function quickly checks whether the specified string defines a
    2948             :  * valid IPv6 address. It supports the IPv4 notation at times used
    2949             :  * inside an IPv6 notation.
    2950             :  *
    2951             :  * \note
    2952             :  * The function can be called with a null pointer in which case it
    2953             :  * immediate returns false.
    2954             :  *
    2955             :  * \param[in] ip  A pointer to a string holding an address.
    2956             :  *
    2957             :  * \return true if the \p ip string represents an IPv6 address.
    2958             :  */
    2959           0 : bool is_ipv6(char const * ip)
    2960             : {
    2961           0 :     if(ip == nullptr)
    2962             :     {
    2963           0 :         return false;
    2964             :     }
    2965             : 
    2966             :     // an IPv6 is a set of 16 bit numbers separated by colon
    2967             :     // the last two numbers can represented in dot notation (ipv4 class a)
    2968             :     //
    2969           0 :     bool found_colon_colon(false);
    2970           0 :     int count(0);
    2971           0 :     if(*ip == ':'
    2972           0 :     && ip[1] == ':')
    2973             :     {
    2974           0 :         found_colon_colon = true;
    2975           0 :         ip += 2;
    2976             :     }
    2977           0 :     for(; *ip != '\0'; ++ip)
    2978             :     {
    2979           0 :         if(count >= 8)
    2980             :         {
    2981           0 :             return false;
    2982             :         }
    2983             : 
    2984             :         // all numbers are in hexadecimal
    2985           0 :         int value(0);
    2986           0 :         bool first(true);
    2987           0 :         for(;; ++ip, first = false)
    2988             :         {
    2989           0 :             if(*ip >= '0' && *ip <= '9')
    2990             :             {
    2991           0 :                 value = value * 16 + *ip - '0';
    2992             :             }
    2993           0 :             else if(*ip >= 'a' && *ip <= 'f')
    2994             :             {
    2995           0 :                 value = value * 16 + *ip - 'a' + 10;
    2996             :             }
    2997           0 :             else if(*ip >= 'A' && *ip <= 'F')
    2998             :             {
    2999           0 :                 value = value * 16 + *ip - 'A' + 10;
    3000             :             }
    3001             :             else
    3002             :             {
    3003           0 :                 if(first)
    3004             :                 {
    3005             :                     // not even one digit, not good
    3006           0 :                     return false;
    3007             :                 }
    3008             :                 // not valid hexadecimal, may be ':' or '\0' (tested below)
    3009           0 :                 break;
    3010             :             }
    3011           0 :             if(value >= 0x10000)
    3012             :             {
    3013             :                 // too large, must be 16 bit numbers
    3014           0 :                 return false;
    3015             :             }
    3016             :         }
    3017           0 :         ++count;
    3018             : //std::cerr << count << ". value=" << value << " -> " << static_cast<int>(*ip) << "\n";
    3019           0 :         if(*ip == '\0')
    3020             :         {
    3021           0 :             break;
    3022             :         }
    3023             : 
    3024             :         // note: if we just found a '::' then here *ip == ':' still
    3025           0 :         if(*ip == '.')
    3026             :         {
    3027             :             // if we have a '.' we must end with an IPv4 and we either
    3028             :             // need found_colon_colon to be true or the count must be
    3029             :             // exactly 6 (1 "missing" colon)
    3030             :             //
    3031           0 :             if(!found_colon_colon
    3032           0 :             && count != 7)  // we test with 7 because the first IPv4 number was already read
    3033             :             {
    3034           0 :                 return false;
    3035             :             }
    3036             :             // also the value is 0 to 255 or it's an error too, but the
    3037             :             // problem here is that we need a decimal number and we just
    3038             :             // checked it as an hexadecimal...
    3039             :             //
    3040           0 :             if((value & 0x00f) >= 0x00a
    3041           0 :             || (value & 0x0f0) >= 0x0a0
    3042           0 :             || (value & 0xf00) >= 0xa00)
    3043             :             {
    3044           0 :                 return false;
    3045             :             }
    3046             :             // transform back to a decimal number to verify the max.
    3047             :             //
    3048           0 :             value = (value & 0x00f) + (value & 0x0f0) / 16 * 10 + (value & 0xf00) / 256 * 100;
    3049           0 :             if(value > 255)
    3050             :             {
    3051           0 :                 return false;
    3052             :             }
    3053             :             // now check the other numbers
    3054           0 :             int pos(1); // start at 1 since we already have 1 number checked
    3055           0 :             for(++ip; *ip != '\0'; ++ip, ++pos)
    3056             :             {
    3057           0 :                 if(*ip < '0' || *ip > '9' || pos >= 4)
    3058             :                 {
    3059             :                     // not a valid number
    3060           0 :                     return false;
    3061             :                 }
    3062             : 
    3063             :                 // only expect decimal in this case in class d (a.b.c.d)
    3064           0 :                 value = 0;
    3065           0 :                 for(; *ip >= '0' && *ip <= '9'; ++ip)
    3066             :                 {
    3067           0 :                     value = value * 10 + *ip - '0';
    3068           0 :                     if(value > 255)
    3069             :                     {
    3070             :                         // too large
    3071           0 :                         return false;
    3072             :                     }
    3073             :                 }
    3074             : 
    3075           0 :                 if(*ip != '.')
    3076             :                 {
    3077           0 :                     if(*ip != '\0')
    3078             :                     {
    3079           0 :                         return false;
    3080             :                     }
    3081           0 :                     break;
    3082             :                 }
    3083             :             }
    3084             : 
    3085             :             // we got a valid IPv4 at the end of IPv6 and we
    3086             :             // found the '\0' so we are all good...
    3087             :             //
    3088           0 :             return true;
    3089             :         }
    3090             : 
    3091           0 :         if(*ip != ':')
    3092             :         {
    3093           0 :             return false;
    3094             :         }
    3095             : 
    3096             :         // double colon?
    3097           0 :         if(ip[1] == ':')
    3098             :         {
    3099             : #pragma GCC diagnostic push
    3100             : #pragma GCC diagnostic ignored "-Wstrict-overflow"
    3101           0 :             if(!found_colon_colon && count < 6)
    3102             : #pragma GCC diagnostic pop
    3103             :             {
    3104             :                 // we can accept one '::'
    3105           0 :                 ++ip;
    3106           0 :                 found_colon_colon = true;
    3107             :             }
    3108             :             else
    3109             :             {
    3110             :                 // a second :: is not valid for an IPv6
    3111           0 :                 return false;
    3112             :             }
    3113             :         }
    3114             :     }
    3115             : 
    3116           0 :     return count == 8 || (count >= 1 && found_colon_colon);
    3117             : }
    3118             : 
    3119             : 
    3120             : /** \brief Retrieve an address and a port from a string.
    3121             :  *
    3122             :  * This function breaks up an address and a port number from a string.
    3123             :  *
    3124             :  * The address can either be an IPv4 address followed by a colon and
    3125             :  * the port number, or an IPv6 address written between square brackets
    3126             :  * ([::1]) followed by a colon and the port number. We also support
    3127             :  * just a port specification as in ":4040".
    3128             :  *
    3129             :  * Port numbers are limited to a number between 1 and 65535 inclusive.
    3130             :  * They can only be specified in base 10.
    3131             :  *
    3132             :  * The port is optional only if a \p default_port is provided (by
    3133             :  * default the \p default_port parameter is set to zero meaning that
    3134             :  * it is not specified.)
    3135             :  *
    3136             :  * If the addr_port string is empty, then the addr and port parameters
    3137             :  * are not modified, which means you want to define them with defaults
    3138             :  * before calling this function.
    3139             :  *
    3140             :  * \exception snapwebsites_exception_invalid_parameters
    3141             :  * If any parameter is considered invalid (albeit the validity of the
    3142             :  * address is not checked since it could be a fully qualified domain
    3143             :  * name) then this exception is raised.
    3144             :  *
    3145             :  * \param[in] addr_port  The address and port pair.
    3146             :  * \param[in,out] addr  The address part, without the square brackets for
    3147             :  *                IPv6 addresses.
    3148             :  * \param[in,out] port  The port number (1 to 65535 inclusive.)
    3149             :  * \param[in] protocol  The protocol for the port (i.e. "tcp" or "udp")
    3150             :  */
    3151           0 : void get_addr_port(QString const & addr_port, QString & addr, int & port, char const * protocol)
    3152             : {
    3153             :     // if there is a colon, we may have a port or IPv6
    3154             :     //
    3155           0 :     int const p(addr_port.lastIndexOf(":"));
    3156           0 :     if(p != -1)
    3157             :     {
    3158           0 :         QString port_str;
    3159             : 
    3160             :         // if there is a ']' then we have an IPv6
    3161             :         //
    3162           0 :         int const bracket(addr_port.lastIndexOf("]"));
    3163           0 :         if(bracket != -1)
    3164             :         {
    3165             :             // we must have a starting '[' otherwise it is wrong
    3166             :             //
    3167           0 :             if(addr_port[0] != '[')
    3168             :             {
    3169           0 :                 SNAP_LOG_FATAL("invalid address/port specification in \"")(addr_port)("\" (missing '[' at the start.)");
    3170           0 :                 throw tcp_client_server_parameter_error("get_addr_port(): invalid [IPv6]:port specification, '[' missing.");
    3171             :             }
    3172             : 
    3173             :             // extract the address
    3174             :             //
    3175           0 :             addr = addr_port.mid(1, bracket - 1); // exclude the '[' and ']'
    3176             : 
    3177             :             // is there a port?
    3178             :             //
    3179           0 :             if(p == bracket + 1)
    3180             :             {
    3181             :                 // IPv6 port specification is just after the ']'
    3182             :                 //
    3183           0 :                 port_str = addr_port.mid(p + 1); // ignore the ':'
    3184             :             }
    3185           0 :             else if(bracket != addr_port.length() - 1)
    3186             :             {
    3187             :                 // the ']' is not at the very end when no port specified
    3188             :                 //
    3189           0 :                 SNAP_LOG_FATAL("invalid address/port specification in \"")(addr_port)("\" (']' is not at the end)");
    3190           0 :                 throw tcp_client_server_parameter_error("get_addr_port(): invalid [IPv6]:port specification, ']' not at the end.");
    3191             :             }
    3192             :         }
    3193             :         else
    3194             :         {
    3195             :             // IPv4 port specification
    3196             :             //
    3197           0 :             if(p > 0)
    3198             :             {
    3199             :                 // if p is zero, then we just had a port (:4040)
    3200             :                 //
    3201           0 :                 addr = addr_port.mid(0, p); // ignore the ':'
    3202             :             }
    3203           0 :             port_str = addr_port.mid(p + 1); // ignore the ':'
    3204             :         }
    3205             : 
    3206             :         // if port_str is still empty, we had an IPv6 without port
    3207             :         //
    3208           0 :         if(!port_str.isEmpty())
    3209             :         {
    3210             :             // first check whether the port is a number
    3211             :             //
    3212           0 :             bool ok(false);
    3213           0 :             port = port_str.toInt(&ok, 10); // force base 10
    3214           0 :             if(!ok)
    3215             :             {
    3216             :                 // not a valid number, try to get it from /etc/services
    3217             :                 //
    3218           0 :                 struct servent const * s(getservbyname(port_str.toUtf8().data(), protocol));
    3219           0 :                 if(s == nullptr)
    3220             :                 {
    3221           0 :                     SNAP_LOG_FATAL("invalid port specification in \"")(addr_port)("\", port not a decimal number nor a known service name.");
    3222           0 :                     throw tcp_client_server_parameter_error("get_addr_port(): invalid addr:port specification, port number or name is not valid.");
    3223             :                 }
    3224           0 :                 port = s->s_port;
    3225             :             }
    3226             :         }
    3227             :     }
    3228           0 :     else if(!addr_port.isEmpty())
    3229             :     {
    3230             :         // just an IPv4 address specified, no port
    3231             :         //
    3232           0 :         addr = addr_port;
    3233             :     }
    3234             : 
    3235             :     // the address could end up being the empty string here
    3236           0 :     if(addr.isEmpty())
    3237             :     {
    3238           0 :         SNAP_LOG_FATAL("invalid address/port specification in \"")(addr_port)("\", address is empty.");
    3239           0 :         throw tcp_client_server_parameter_error("get_addr_port(): invalid addr:port specification, address is empty (this generally happens when a request is done with no default address).");
    3240             :     }
    3241             : 
    3242             :     // finally verify that the port is in range
    3243           0 :     if(port <= 0
    3244           0 :     || port > 65535)
    3245             :     {
    3246           0 :         SNAP_LOG_FATAL("invalid address/port specification in \"")(addr_port)("\", port out of bounds.");
    3247           0 :         throw tcp_client_server_parameter_error("get_addr_port(): invalid addr:port specification, port number is out of bounds (1 .. 65535).");
    3248             :     }
    3249           0 : }
    3250             : 
    3251             : 
    3252             : 
    3253           6 : } // namespace tcp_client_server
    3254             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.13