LCOV - code coverage report
Current view: top level - eventdispatcher - tcp_base.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1 8 12.5 %
Date: 2019-08-08 02:52:36 Functions: 2 4 50.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Event Dispatcher
       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             : // make sure we use OpenSSL with multi-thread support
      19             : // (TODO: move to .cpp once we have the impl!)
      20             : #define OPENSSL_THREAD_DEFINES
      21             : 
      22             : // self
      23             : //
      24             : #include    "eventdispatcher/tcp_base.h"
      25             : 
      26             : #include    "eventdispatcher/exception.h"
      27             : #include    "eventdispatcher/tcp_private.h"
      28             : 
      29             : 
      30             : // cppthread lib
      31             : //
      32             : #include    <cppthread/guard.h>
      33             : #include    <cppthread/mutex.h>
      34             : #include    <cppthread/thread.h>
      35             : 
      36             : 
      37             : // snaplogger lib
      38             : //
      39             : #include "snaplogger/message.h"
      40             : 
      41             : 
      42             : // snapdev lib
      43             : //
      44             : //#include "snapdev/not_reached.h"
      45             : #include "snapdev/not_used.h"
      46             : //#include "snapdev/raii_generic_deleter.h"
      47             : 
      48             : 
      49             : // OpenSSL lib
      50             : //
      51             : #include <openssl/bio.h>
      52             : #include <openssl/err.h>
      53             : #include <openssl/ssl.h>
      54             : 
      55             : 
      56             : //// C++
      57             : ////
      58             : //#include <sstream>
      59             : //#include <iomanip>
      60             : //
      61             : //
      62             : //// C lib
      63             : ////
      64             : //#include <netdb.h>
      65             : //#include <netinet/tcp.h>
      66             : //#include <poll.h>
      67             : //#include <string.h>
      68             : //#include <sys/ioctl.h>
      69             : //#include <sys/socket.h>
      70             : //#include <sys/types.h>
      71             : //#include <unistd.h>
      72             : 
      73             : 
      74             : // last include
      75             : //
      76             : #include "snapdev/poison.h"
      77             : 
      78             : 
      79             : 
      80             : 
      81             : #ifndef OPENSSL_THREADS
      82             : #error "OPENSSL_THREADS is not defined. Event Dispatcher requires OpenSSL to support multi-threading."
      83             : #endif
      84             : 
      85             : namespace ed
      86             : {
      87             : 
      88             : 
      89             : //   namespace
      90             : //   {
      91             : //   
      92             : //   
      93             : //   
      94             : //   ///** \brief Data handled by each lock.
      95             : //   // *
      96             : //   // * This function holds the data handled on a per lock basis.
      97             : //   // * Even if your daemon is not using multiple threads, this
      98             : //   // * is likely to kick in.
      99             : //   // */
     100             : //   //class crypto_lock_t
     101             : //   //{
     102             : //   //public:
     103             : //   //    typedef std::vector<crypto_lock_t>  vector_t;
     104             : //   //
     105             : //   //                        crypto_lock_t()
     106             : //   //                        {
     107             : //   //                            pthread_mutex_init(&f_mutex, nullptr);
     108             : //   //                        }
     109             : //   //
     110             : //   //                        ~crypto_lock_t()
     111             : //   //                        {
     112             : //   //                            pthread_mutex_destroy(&f_mutex);
     113             : //   //                        }
     114             : //   //
     115             : //   //    void                lock()
     116             : //   //                        {
     117             : //   //                            pthread_mutex_lock(&f_mutex);
     118             : //   //                        }
     119             : //   //
     120             : //   //    void                unlock()
     121             : //   //                        {
     122             : //   //                            pthread_mutex_unlock(&f_mutex);
     123             : //   //                        }
     124             : //   //
     125             : //   //private:
     126             : //   //    pthread_mutex_t     f_mutex = pthread_mutex_t();
     127             : //   //};
     128             : //   
     129             : //   
     130             : //   /** \brief The vector of locks.
     131             : //    *
     132             : //    * This function is initialized by the crypto_thread_setup().
     133             : //    *
     134             : //    * It is defined as a pointer in case someone was to try to access this
     135             : //    * pointer before entering main().
     136             : //    */
     137             : //   //crypto_lock_t::vector_t *   g_locks = nullptr;
     138             : //   cppthread::mutex::direct_vector_t  *   g_locks = nullptr;
     139             : //   
     140             : //   
     141             : //   /** \brief Retrieve the system thread identifier.
     142             : //    *
     143             : //    * This function is used by the OpenSSL library to attach an internal thread
     144             : //    * identifier (\p tid) to a system thread identifier.
     145             : //    *
     146             : //    * \param[in] tid  The crypto internal thread identifier.
     147             : //    */
     148             : //   void pthreads_thread_id(CRYPTO_THREADID * tid)
     149             : //   {
     150             : //       // on 19.04 the macro does not use tid
     151             : //       //
     152             : //       snap::NOTUSED(tid);
     153             : //   
     154             : //       CRYPTO_THREADID_set_numeric(tid, cppthread::gettid());
     155             : //   }
     156             : //   
     157             : //   
     158             : //   /** \brief Handle locks and unlocks.
     159             : //    *
     160             : //    * This function is a callback used to lock and unlock mutexes as required.
     161             : //    *
     162             : //    * \param[in] mode  Whether lock or unlock in read or write mode.
     163             : //    * \param[in] type  The "type" of lock (i.e. the index).
     164             : //    * \param[in] file  The filename of the source asking for a lock/unlock.
     165             : //    * \param[in] line  The line number in file where the call was made.
     166             : //    */
     167             : //   void pthreads_locking_callback(int mode, int type, char const * file, int line)
     168             : //   {
     169             : //       snap::NOTUSED(file);
     170             : //       snap::NOTUSED(line);
     171             : //   
     172             : //       if(g_locks == nullptr)
     173             : //       {
     174             : //           throw event_dispatcher_initialization_missing("g_locks was not initialized");
     175             : //       }
     176             : //   
     177             : //   /*
     178             : //   # ifdef undef
     179             : //       BIO_printf(bio_err, "thread=%4d mode=%s lock=%s %s:%d\n",
     180             : //                  CRYPTO_thread_id(),
     181             : //                  (mode & CRYPTO_LOCK) ? "l" : "u",
     182             : //                  (type & CRYPTO_READ) ? "r" : "w", file, line);
     183             : //   # endif
     184             : //       if (CRYPTO_LOCK_SSL_CERT == type)
     185             : //               BIO_printf(bio_err,"(t,m,f,l) %ld %d %s %d\n",
     186             : //                          CRYPTO_thread_id(),
     187             : //                          mode,file,line);
     188             : //   */
     189             : //   
     190             : //       // Note: at this point we ignore READ | WRITE because we do not have
     191             : //       //       such a concept with a simple mutex; we could take those in
     192             : //       //       account with a semaphore though.
     193             : //       //
     194             : //       if((mode & CRYPTO_LOCK) != 0)
     195             : //       {
     196             : //           (*g_locks)[type].lock();
     197             : //       }
     198             : //       else
     199             : //       {
     200             : //           (*g_locks)[type].unlock();
     201             : //       }
     202             : //   }
     203             : //   
     204             : //   
     205             : //   /** \brief This function is called once on initialization.
     206             : //    *
     207             : //    * This function is called when the bio_initialize() function. It is
     208             : //    * expected that the bio_initialize() function is called once by the
     209             : //    * main thread before any other thread has a chance to do so.
     210             : //    */
     211             : //   void crypto_thread_setup()
     212             : //   {
     213             : //       cppthread::guard g(*cppthread::g_system_mutex);
     214             : //   
     215             : //       if(g_locks != nullptr)
     216             : //       {
     217             : //           throw event_dispatcher_initialization_error(
     218             : //                   "crypto_thread_setup() called for the second time."
     219             : //                   " This usually means two threads are initializing"
     220             : //                   " the BIO environment simultaneously.");
     221             : //       }
     222             : //   
     223             : //       g_locks = new cppthread::mutex::direct_vector_t(CRYPTO_num_locks());
     224             : //   
     225             : //       CRYPTO_THREADID_set_callback(pthreads_thread_id);
     226             : //       CRYPTO_set_locking_callback(pthreads_locking_callback);
     227             : //   }
     228             : //   
     229             : //   
     230             : //   /** \brief This function cleans up the thread setup.
     231             : //    *
     232             : //    * This function could be called to clean up the setup created to support
     233             : //    * multiple threads running with the OpenSSL library.
     234             : //    *
     235             : //    * \note
     236             : //    * At this time this function never gets called. So we have a small leak
     237             : //    * but that's only on a quit.
     238             : //    */
     239             : //   void thread_cleanup()
     240             : //   {
     241             : //       CRYPTO_set_locking_callback(nullptr);
     242             : //   
     243             : //       delete g_locks;
     244             : //       g_locks = nullptr;
     245             : //   }
     246             : //   
     247             : //   
     248             : //   /** \brief This function cleans up the error state of a thread.
     249             : //    *
     250             : //    * Whenever the OpenSSL system runs in a thread, it may create a
     251             : //    * state to save various information, especially its error queue.
     252             : //    *
     253             : //    * \sa cleanup_on_thread_exit()
     254             : //    */
     255             : //   void per_thread_cleanup()
     256             : //   {
     257             : //   #if __cplusplus < 201700
     258             : //       // this function is not necessary in newer versions of OpenSSL
     259             : //       //
     260             : //       ERR_remove_thread_state(nullptr);
     261             : //   #endif
     262             : //   }
     263             : //   
     264             : //   
     265             : //   
     266             : //   
     267             : //   
     268             : //   
     269             : //   
     270             : //   /** \brief Whether the bio_initialize() function was already called.
     271             : //    *
     272             : //    * This flag is used to know whether the bio_initialize() function was
     273             : //    * already called. Only the bio_initialize() function is expected to
     274             : //    * make use of this flag. Other functions should simply call the
     275             : //    * bio_initialize() function (future versions may include addition
     276             : //    * flags or use various bits in an integer instead.)
     277             : //    */
     278             : //   bool g_bio_initialized = false;
     279             : //   
     280             : //   
     281             : //   /** \brief Initialize the BIO library.
     282             : //    *
     283             : //    * This function is called by the BIO implementations to initialize the
     284             : //    * BIO library as required. It can be called any number of times. The
     285             : //    * initialization will happen only once.
     286             : //    */
     287             : //   void bio_initialize()
     288             : //   {
     289             : //       cppthread::guard g(*cppthread::g_system_mutex);
     290             : //   
     291             : //       // already initialized?
     292             : //       //
     293             : //       if(g_bio_initialized)
     294             : //       {
     295             : //           return;
     296             : //       }
     297             : //       g_bio_initialized = true;
     298             : //   
     299             : //       // Make sure the SSL library gets initialized
     300             : //       //
     301             : //       SSL_library_init();
     302             : //   
     303             : //       // TBD: should we call the load string functions only when we
     304             : //       //      are about to generate the first error?
     305             : //       //
     306             : //       ERR_load_crypto_strings();
     307             : //       ERR_load_SSL_strings();
     308             : //       SSL_load_error_strings();
     309             : //   
     310             : //       // TODO: define a way to only define safe algorithms?
     311             : //       //       (it looks like we can force TLSv1.2 below at least)
     312             : //       //
     313             : //       OpenSSL_add_all_algorithms();
     314             : //   
     315             : //       // TBD: need a PRNG seeding before creating a new SSL context?
     316             : //   
     317             : //       // then initialize the library so it works in a multithreaded
     318             : //       // environment
     319             : //       //
     320             : //       crypto_thread_setup();
     321             : //   }
     322             : //   
     323             : //   
     324             : //   /** \brief Clean up the BIO environment.
     325             : //    *
     326             : //    * This function cleans up the BIO environment.
     327             : //    *
     328             : //    * \note
     329             : //    * This function is here mainly for documentation rather than to get called.
     330             : //    * Whenever you exit a process that uses the BIO calls it will leak
     331             : //    * a few things. To make the process really spanking clean, you want
     332             : //    * to call this function before exit(3). You have to make sure that
     333             : //    * you call this function only after every single BIO object was
     334             : //    * closed and none must be opened after this call.
     335             : //    */
     336             : //   void bio_cleanup()
     337             : //   {
     338             : //   #if __cplusplus < 201700
     339             : //       // this function is not necessary in newer versions of OpenSSL
     340             : //       //
     341             : //       ERR_remove_state(0);
     342             : //   #endif
     343             : //   
     344             : //       EVP_cleanup();
     345             : //       CRYPTO_cleanup_all_ex_data();
     346             : //       ERR_free_strings();
     347             : //   }
     348             : //   
     349             : //   
     350             : //   /** \brief Get all the error messages and output them in our logs.
     351             : //    *
     352             : //    * This function reads all existing errors from the OpenSSL library
     353             : //    * and send them to our logs.
     354             : //    *
     355             : //    * \param[in] sni  Whether SNI is ON (true) or OFF (false).
     356             : //    */
     357             : //   int bio_log_errors()
     358             : //   {
     359             : //       // allow for up to 5 errors in one go, but we have a HUGE problem
     360             : //       // at this time as in some cases the same error is repeated forever
     361             : //       //
     362             : //       for(int i(0);; ++i)
     363             : //       {
     364             : //           char const * filename(nullptr);
     365             : //           int line(0);
     366             : //           char const * data(nullptr);
     367             : //           int flags(0);
     368             : //           unsigned long bio_errno(ERR_get_error_line_data(&filename, &line, &data, &flags));
     369             : //           if(bio_errno == 0)
     370             : //           {
     371             : //               // no more errors
     372             : //               //
     373             : //               return i;
     374             : //           }
     375             : //   
     376             : //           // get corresponding messages too
     377             : //           //
     378             : //           // Note: current OpenSSL documentation on Ubuntu says errmsg[]
     379             : //           //       should be at least 120 characters BUT the code actually
     380             : //           //       use a limit of 256...
     381             : //           //
     382             : //           char errmsg[256];
     383             : //           ERR_error_string_n(bio_errno, errmsg, sizeof(errmsg) / sizeof(errmsg[0]));
     384             : //           // WARNING: the ERR_error_string() function is NOT multi-thread safe
     385             : //   
     386             : //   #pragma GCC diagnostic push
     387             : //   #pragma GCC diagnostic ignored "-Wold-style-cast"
     388             : //           int const lib_num(ERR_GET_LIB(bio_errno));
     389             : //           int const func_num(ERR_GET_FUNC(bio_errno));
     390             : //   #pragma GCC diagnostic pop
     391             : //           char const * lib_name(ERR_lib_error_string(lib_num));
     392             : //           char const * func_name(ERR_func_error_string(func_num));
     393             : //           int const reason_num(ERR_GET_REASON(bio_errno));
     394             : //           char const * reason(ERR_reason_error_string(reason_num));
     395             : //   
     396             : //           if(lib_name == nullptr)
     397             : //           {
     398             : //               lib_name = "<no libname>";
     399             : //           }
     400             : //           if(func_name == nullptr)
     401             : //           {
     402             : //               func_name = "<no funcname>";
     403             : //           }
     404             : //           if(reason == nullptr)
     405             : //           {
     406             : //               reason = "<no reason>";
     407             : //           }
     408             : //   
     409             : //           // the format used by the OpenSSL library is as follow:
     410             : //           //
     411             : //           //     [pid]:error:[error code]:[library name]:[function name]:[reason string]:[file name]:[line]:[optional text message]
     412             : //           //
     413             : //           // we do not duplicate the [pid] and "error" but include all the
     414             : //           // other fields
     415             : //           //
     416             : //           SNAP_LOG_ERROR
     417             : //               << "OpenSSL: ["
     418             : //               << bio_errno // should be shown in hex...
     419             : //               << "/"
     420             : //               << lib_num
     421             : //               << "|"
     422             : //               << func_num
     423             : //               << "|"
     424             : //               << reason_num
     425             : //               << "]:["
     426             : //               << lib_name
     427             : //               << "]:["
     428             : //               << func_name
     429             : //               << "]:["
     430             : //               << reason
     431             : //               << "]:["
     432             : //               << filename
     433             : //               << "]:["
     434             : //               << line
     435             : //               << "]:["
     436             : //               << ((flags & ERR_TXT_STRING) != 0 && data != nullptr ? data : "(no details)")
     437             : //               << "]";
     438             : //       }
     439             : //   }
     440             : //   
     441             : //   
     442             : //   /** \brief Free a BIO object.
     443             : //    *
     444             : //    * This deleter is used to make sure that the BIO object gets freed
     445             : //    * whenever the object holding it gets destroyed.
     446             : //    *
     447             : //    * Note that deleting a BIO connection calls shutdown() and close()
     448             : //    * on the socket. In other words, it hangs up.
     449             : //    *
     450             : //    * \param[in] bio  The BIO object to be freed.
     451             : //    */
     452             : //   void bio_deleter(BIO * bio)
     453             : //   {
     454             : //       // IMPORTANT NOTE:
     455             : //       //
     456             : //       //   The BIO_free_all() calls shutdown() on the socket. This is not
     457             : //       //   acceptable in a normal Unix application that makes use of fork().
     458             : //       //   So... instead we ask the BIO interface to not close the socket,
     459             : //       //   and instead we close it ourselves. This means the shutdown()
     460             : //       //   never gets called.
     461             : //       //
     462             : //       BIO_set_close(bio, BIO_NOCLOSE);
     463             : //   
     464             : //       int c;
     465             : //   #pragma GCC diagnostic push
     466             : //   #pragma GCC diagnostic ignored "-Wold-style-cast"
     467             : //       BIO_get_fd(bio, &c);
     468             : //   #pragma GCC diagnostic pop
     469             : //       if(c != -1)
     470             : //       {
     471             : //           close(c);
     472             : //       }
     473             : //   
     474             : //       BIO_free_all(bio);
     475             : //   }
     476             : //   
     477             : //   
     478             : //   /** \brief Free an SSL_CTX object.
     479             : //    *
     480             : //    * This deleter is used to make sure that the SSL_CTX object gets
     481             : //    * freed whenever the object holding it gets destroyed.
     482             : //    */
     483             : //   void ssl_ctx_deleter(SSL_CTX * ssl_ctx)
     484             : //   {
     485             : //       SSL_CTX_free(ssl_ctx);
     486             : //   }
     487             : //   
     488             : //   
     489             : //   }
     490             : //   // no name namespace
     491             : 
     492             : 
     493             : 
     494             : 
     495             : 
     496             : 
     497             : 
     498             : 
     499             : 
     500             : 
     501             : 
     502             : 
     503             : 
     504             : 
     505             : 
     506             : 
     507             : /** \brief Clean up the BIO environment.
     508             :  *
     509             :  * This function cleans up the BIO environment.
     510             :  *
     511             :  * \note
     512             :  * This function is here for documentation rather than to get called.
     513             :  * Whenever you exit a process that uses the BIO calls it will leak
     514             :  * a few things. To make the process really spanking clean, you want
     515             :  * to call this function before exit(3). You have to make sure that
     516             :  * you call this function only after every single BIO object was
     517             :  * closed and none must be opened after this call.
     518             :  */
     519           0 : void cleanup()
     520             : {
     521           0 :     detail::thread_cleanup();
     522           0 :     detail::bio_cleanup();
     523           0 : }
     524             : 
     525             : 
     526             : /** \brief Before a thread exits, this function must be called.
     527             :  *
     528             :  * Any error which is still attached to a thread must be removed
     529             :  * before the thread dies or it will be lost. This function must
     530             :  * be called before you return from your
     531             :  * snap::snap_thread::snap_runner::run()
     532             :  * function.
     533             :  *
     534             :  * The thread must be pro-active and make sure to catch() errors
     535             :  * if necessary to ensure that this function gets called before
     536             :  * it exists.
     537             :  *
     538             :  * Also, this means all BIO connections were properly terminated
     539             :  * before the thread returns.
     540             :  *
     541             :  * \note
     542             :  * TBD--this may not be required. I read a few things a while back
     543             :  * saying that certain things were now automatic in the BIO library
     544             :  * and this may very well be one of them. To test this function,
     545             :  * see the snapdbproxy/src/snapdbproxy_connection.cpp and see how
     546             :  * it works one way or the other.
     547             :  */
     548           0 : void cleanup_on_thread_exit()
     549             : {
     550           0 :     detail::per_thread_cleanup();
     551           0 : }
     552             : 
     553             : 
     554             : 
     555             : 
     556             : 
     557             : 
     558             : 
     559             : 
     560             : 
     561             : 
     562             : 
     563             : 
     564           6 : } // namespace ed
     565             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.12