diff options
Diffstat (limited to 'src/exchange/taler-exchange-httpd_keys.c')
-rw-r--r-- | src/exchange/taler-exchange-httpd_keys.c | 99 |
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 | */ |
345 | static pthread_key_t key_state; | 343 | static 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 | */ |
354 | static volatile uint64_t key_generation; | 352 | static 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; | |||
392 | static struct TALER_SecurityModulePublicKeyP esign_sm_pub; | 390 | static 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 | */ | ||
398 | static 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 | */ | ||
404 | static pthread_mutex_t skr_mutex = PTHREAD_MUTEX_INITIALIZER; | ||
405 | |||
406 | /** | ||
407 | * Are we shutting down? | 393 | * Are we shutting down? |
408 | */ | 394 | */ |
409 | static bool terminating; | 395 | static bool terminating; |
410 | 396 | ||
411 | /** | 397 | /** |
412 | * Did we ever initialize #key_state? | ||
413 | */ | ||
414 | static 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) | |||
510 | static void | 487 | static void |
511 | check_denom_sm_pub (const struct TALER_SecurityModulePublicKeyP *sm_pub) | 488 | check_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) | |||
536 | static void | 511 | static void |
537 | check_esign_sm_pub (const struct TALER_SecurityModulePublicKeyP *sm_pub) | 512 | check_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 | */ | ||
905 | static void | ||
906 | destroy_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 | */ | ||
920 | int | 872 | int |
921 | TEH_keys_init () | 873 | TEH_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 () | |||
949 | void __attribute__ ((destructor)) | 893 | void __attribute__ ((destructor)) |
950 | TEH_keys_finished () | 894 | TEH_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, |