aboutsummaryrefslogtreecommitdiff
path: root/src/exchange/taler-exchange-httpd_keys.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/exchange/taler-exchange-httpd_keys.c')
-rw-r--r--src/exchange/taler-exchange-httpd_keys.c99
1 files changed, 11 insertions, 88 deletions
diff --git a/src/exchange/taler-exchange-httpd_keys.c b/src/exchange/taler-exchange-httpd_keys.c
index 216afd7c5..f37aafbd1 100644
--- a/src/exchange/taler-exchange-httpd_keys.c
+++ b/src/exchange/taler-exchange-httpd_keys.c
@@ -19,7 +19,6 @@
19 * @author Christian Grothoff 19 * @author Christian Grothoff
20 */ 20 */
21#include "platform.h" 21#include "platform.h"
22#include <pthread.h>
23#include "taler_json_lib.h" 22#include "taler_json_lib.h"
24#include "taler_mhd_lib.h" 23#include "taler_mhd_lib.h"
25#include "taler-exchange-httpd.h" 24#include "taler-exchange-httpd.h"
@@ -339,10 +338,9 @@ struct SuspendedKeysRequests
339 338
340 339
341/** 340/**
342 * Thread-local. Contains a pointer to `struct TEH_KeyStateHandle` or NULL. 341 * Stores the latest generation of our key state.
343 * Stores the per-thread latest generation of our key state.
344 */ 342 */
345static pthread_key_t key_state; 343static struct TEH_KeyStateHandle *key_state;
346 344
347/** 345/**
348 * Counter incremented whenever we have a reason to re-build the keys because 346 * Counter incremented whenever we have a reason to re-build the keys because
@@ -351,7 +349,7 @@ static pthread_key_t key_state;
351 * changes, the variable MUST be volatile. See #TEH_keys_get_state() and 349 * changes, the variable MUST be volatile. See #TEH_keys_get_state() and
352 * #TEH_keys_update_states() for uses of this variable. 350 * #TEH_keys_update_states() for uses of this variable.
353 */ 351 */
354static volatile uint64_t key_generation; 352static uint64_t key_generation;
355 353
356/** 354/**
357 * Head of DLL of suspended /keys requests. 355 * Head of DLL of suspended /keys requests.
@@ -392,29 +390,11 @@ static struct TALER_SecurityModulePublicKeyP denom_sm_pub;
392static struct TALER_SecurityModulePublicKeyP esign_sm_pub; 390static struct TALER_SecurityModulePublicKeyP esign_sm_pub;
393 391
394/** 392/**
395 * Mutex protecting access to #denom_sm_pub and #esign_sm_pub.
396 * (Could be split into two locks if ever needed.)
397 */
398static pthread_mutex_t sm_pub_mutex = PTHREAD_MUTEX_INITIALIZER;
399
400/**
401 * Mutex protecting access to #skr_head and #skr_tail.
402 * (Could be split into two locks if ever needed.)
403 */
404static pthread_mutex_t skr_mutex = PTHREAD_MUTEX_INITIALIZER;
405
406/**
407 * Are we shutting down? 393 * Are we shutting down?
408 */ 394 */
409static bool terminating; 395static bool terminating;
410 396
411/** 397/**
412 * Did we ever initialize #key_state?
413 */
414static bool key_state_available;
415
416
417/**
418 * Suspend /keys request while we (hopefully) are waiting to be 398 * Suspend /keys request while we (hopefully) are waiting to be
419 * provisioned with key material. 399 * provisioned with key material.
420 * 400 *
@@ -427,10 +407,8 @@ suspend_request (struct MHD_Connection *connection)
427 407
428 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 408 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
429 "Suspending /keys request until key material changes\n"); 409 "Suspending /keys request until key material changes\n");
430 GNUNET_assert (0 == pthread_mutex_lock (&skr_mutex));
431 if (terminating) 410 if (terminating)
432 { 411 {
433 GNUNET_assert (0 == pthread_mutex_unlock (&skr_mutex));
434 return TALER_MHD_reply_with_error (connection, 412 return TALER_MHD_reply_with_error (connection,
435 MHD_HTTP_INTERNAL_SERVER_ERROR, 413 MHD_HTTP_INTERNAL_SERVER_ERROR,
436 TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING, 414 TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING,
@@ -452,9 +430,9 @@ suspend_request (struct MHD_Connection *connection)
452 skr_size--; 430 skr_size--;
453 skr_connection = skr->connection; 431 skr_connection = skr->connection;
454 MHD_resume_connection (skr->connection); 432 MHD_resume_connection (skr->connection);
433 TALER_MHD_daemon_trigger ();
455 GNUNET_free (skr); 434 GNUNET_free (skr);
456 } 435 }
457 GNUNET_assert (0 == pthread_mutex_unlock (&skr_mutex));
458 return MHD_YES; 436 return MHD_YES;
459} 437}
460 438
@@ -464,7 +442,6 @@ TEH_resume_keys_requests (bool do_shutdown)
464{ 442{
465 struct SuspendedKeysRequests *skr; 443 struct SuspendedKeysRequests *skr;
466 444
467 GNUNET_assert (0 == pthread_mutex_lock (&skr_mutex));
468 if (do_shutdown) 445 if (do_shutdown)
469 terminating = true; 446 terminating = true;
470 while (NULL != (skr = skr_head)) 447 while (NULL != (skr = skr_head))
@@ -474,9 +451,9 @@ TEH_resume_keys_requests (bool do_shutdown)
474 skr); 451 skr);
475 skr_size--; 452 skr_size--;
476 MHD_resume_connection (skr->connection); 453 MHD_resume_connection (skr->connection);
454 TALER_MHD_daemon_trigger ();
477 GNUNET_free (skr); 455 GNUNET_free (skr);
478 } 456 }
479 GNUNET_assert (0 == pthread_mutex_unlock (&skr_mutex));
480} 457}
481 458
482 459
@@ -510,7 +487,6 @@ clear_response_cache (struct TEH_KeyStateHandle *ksh)
510static void 487static void
511check_denom_sm_pub (const struct TALER_SecurityModulePublicKeyP *sm_pub) 488check_denom_sm_pub (const struct TALER_SecurityModulePublicKeyP *sm_pub)
512{ 489{
513 GNUNET_assert (0 == pthread_mutex_lock (&sm_pub_mutex));
514 if (0 != 490 if (0 !=
515 GNUNET_memcmp (sm_pub, 491 GNUNET_memcmp (sm_pub,
516 &denom_sm_pub)) 492 &denom_sm_pub))
@@ -523,7 +499,6 @@ check_denom_sm_pub (const struct TALER_SecurityModulePublicKeyP *sm_pub)
523 } 499 }
524 denom_sm_pub = *sm_pub; /* TOFU ;-) */ 500 denom_sm_pub = *sm_pub; /* TOFU ;-) */
525 } 501 }
526 GNUNET_assert (0 == pthread_mutex_unlock (&sm_pub_mutex));
527} 502}
528 503
529 504
@@ -536,7 +511,6 @@ check_denom_sm_pub (const struct TALER_SecurityModulePublicKeyP *sm_pub)
536static void 511static void
537check_esign_sm_pub (const struct TALER_SecurityModulePublicKeyP *sm_pub) 512check_esign_sm_pub (const struct TALER_SecurityModulePublicKeyP *sm_pub)
538{ 513{
539 GNUNET_assert (0 == pthread_mutex_lock (&sm_pub_mutex));
540 if (0 != 514 if (0 !=
541 GNUNET_memcmp (sm_pub, 515 GNUNET_memcmp (sm_pub,
542 &esign_sm_pub)) 516 &esign_sm_pub))
@@ -549,7 +523,6 @@ check_esign_sm_pub (const struct TALER_SecurityModulePublicKeyP *sm_pub)
549 } 523 }
550 esign_sm_pub = *sm_pub; /* TOFU ;-) */ 524 esign_sm_pub = *sm_pub; /* TOFU ;-) */
551 } 525 }
552 GNUNET_assert (0 == pthread_mutex_unlock (&sm_pub_mutex));
553} 526}
554 527
555 528
@@ -896,38 +869,9 @@ destroy_key_state (struct TEH_KeyStateHandle *ksh,
896} 869}
897 870
898 871
899/**
900 * Free all resources associated with @a cls. Called when
901 * the respective pthread is destroyed.
902 *
903 * @param[in] cls a `struct TEH_KeyStateHandle`.
904 */
905static void
906destroy_key_state_cb (void *cls)
907{
908 struct TEH_KeyStateHandle *ksh = cls;
909
910 destroy_key_state (ksh,
911 true);
912}
913
914
915/**
916 * Initialize keys submodule.
917 *
918 * @return #GNUNET_OK on success
919 */
920int 872int
921TEH_keys_init () 873TEH_keys_init ()
922{ 874{
923 if (0 !=
924 pthread_key_create (&key_state,
925 &destroy_key_state_cb))
926 {
927 GNUNET_break (0);
928 return GNUNET_SYSERR;
929 }
930 key_state_available = true;
931 if (GNUNET_OK != 875 if (GNUNET_OK !=
932 GNUNET_CONFIGURATION_get_value_time (TEH_cfg, 876 GNUNET_CONFIGURATION_get_value_time (TEH_cfg,
933 "exchange", 877 "exchange",
@@ -949,11 +893,9 @@ TEH_keys_init ()
949void __attribute__ ((destructor)) 893void __attribute__ ((destructor))
950TEH_keys_finished () 894TEH_keys_finished ()
951{ 895{
952 if (key_state_available) 896 if (NULL != key_state)
953 { 897 destroy_key_state (key_state,
954 GNUNET_assert (0 == 898 true);
955 pthread_key_delete (key_state));
956 }
957} 899}
958 900
959 901
@@ -1799,22 +1741,14 @@ get_key_state (bool management_only)
1799 struct TEH_KeyStateHandle *old_ksh; 1741 struct TEH_KeyStateHandle *old_ksh;
1800 struct TEH_KeyStateHandle *ksh; 1742 struct TEH_KeyStateHandle *ksh;
1801 1743
1802 GNUNET_assert (key_state_available); 1744 old_ksh = key_state;
1803 old_ksh = pthread_getspecific (key_state);
1804 if (NULL == old_ksh) 1745 if (NULL == old_ksh)
1805 { 1746 {
1806 ksh = build_key_state (NULL, 1747 ksh = build_key_state (NULL,
1807 management_only); 1748 management_only);
1808 if (NULL == ksh) 1749 if (NULL == ksh)
1809 return NULL; 1750 return NULL;
1810 if (0 != pthread_setspecific (key_state, 1751 key_state = ksh;
1811 ksh))
1812 {
1813 GNUNET_break (0);
1814 destroy_key_state (ksh,
1815 true);
1816 return NULL;
1817 }
1818 return ksh; 1752 return ksh;
1819 } 1753 }
1820 if ( (old_ksh->key_generation < key_generation) || 1754 if ( (old_ksh->key_generation < key_generation) ||
@@ -1826,15 +1760,7 @@ get_key_state (bool management_only)
1826 (unsigned long long) key_generation); 1760 (unsigned long long) key_generation);
1827 ksh = build_key_state (old_ksh->helpers, 1761 ksh = build_key_state (old_ksh->helpers,
1828 management_only); 1762 management_only);
1829 if (0 != pthread_setspecific (key_state, 1763 key_state = ksh;
1830 ksh))
1831 {
1832 GNUNET_break (0);
1833 if (NULL != ksh)
1834 destroy_key_state (ksh,
1835 false);
1836 return NULL;
1837 }
1838 old_ksh->helpers = NULL; 1764 old_ksh->helpers = NULL;
1839 destroy_key_state (old_ksh, 1765 destroy_key_state (old_ksh,
1840 false); 1766 false);
@@ -2099,17 +2025,14 @@ TEH_keys_get_handler (struct TEH_RequestContext *rc,
2099 ksh = TEH_keys_get_state (); 2025 ksh = TEH_keys_get_state ();
2100 if (NULL == ksh) 2026 if (NULL == ksh)
2101 { 2027 {
2102 GNUNET_assert (0 == pthread_mutex_lock (&skr_mutex));
2103 if ( (SKR_LIMIT == skr_size) && 2028 if ( (SKR_LIMIT == skr_size) &&
2104 (rc->connection == skr_connection) ) 2029 (rc->connection == skr_connection) )
2105 { 2030 {
2106 GNUNET_assert (0 == pthread_mutex_unlock (&skr_mutex));
2107 return TALER_MHD_reply_with_error (rc->connection, 2031 return TALER_MHD_reply_with_error (rc->connection,
2108 MHD_HTTP_INTERNAL_SERVER_ERROR, 2032 MHD_HTTP_INTERNAL_SERVER_ERROR,
2109 TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING, 2033 TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING,
2110 "too many connections suspended on /keys"); 2034 "too many connections suspended on /keys");
2111 } 2035 }
2112 GNUNET_assert (0 == pthread_mutex_unlock (&skr_mutex));
2113 return suspend_request (rc->connection); 2036 return suspend_request (rc->connection);
2114 } 2037 }
2115 krd = bsearch (&last_issue_date, 2038 krd = bsearch (&last_issue_date,