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
|