From b81a5fb3aacb14b95be66771ebad2b3f047cbf2b Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 12 Dec 2020 22:40:40 +0100 Subject: add sync and timeout functionality to helpers --- src/util/crypto_helper_denom.c | 84 ++++++++++++++++++++++++------------ src/util/crypto_helper_esign.c | 82 +++++++++++++++++++++++------------ src/util/taler-helper-crypto-eddsa.c | 29 +++++++++++-- src/util/taler-helper-crypto-eddsa.h | 3 ++ src/util/taler-helper-crypto-rsa.c | 28 ++++++++++-- src/util/taler-helper-crypto-rsa.h | 2 + 6 files changed, 165 insertions(+), 63 deletions(-) diff --git a/src/util/crypto_helper_denom.c b/src/util/crypto_helper_denom.c index 81a4e8fd7..7326f70ff 100644 --- a/src/util/crypto_helper_denom.c +++ b/src/util/crypto_helper_denom.c @@ -57,6 +57,11 @@ struct TALER_CRYPTO_DenominationHelper * The UNIX domain socket, -1 if we are currently not connected. */ int sock; + + /** + * Have we ever been sync'ed? + */ + bool synced; }; @@ -348,6 +353,41 @@ handle_mt_purge (struct TALER_CRYPTO_DenominationHelper *dh, } +/** + * Wait until the socket is ready to read. + * + * @param dh helper to wait for + * @return false on timeout (after 5s) + */ +static bool +await_read_ready (struct TALER_CRYPTO_DenominationHelper *dh) +{ + /* wait for reply with 5s timeout */ + struct pollfd pfd = { + .fd = dh->sock, + .events = POLLIN + }; + sigset_t sigmask; + struct timespec ts = { + .tv_sec = 5 + }; + int ret; + + GNUNET_assert (0 == sigemptyset (&sigmask)); + GNUNET_assert (0 == sigaddset (&sigmask, SIGTERM)); + GNUNET_assert (0 == sigaddset (&sigmask, SIGHUP)); + ret = ppoll (&pfd, + 1, + &ts, + &sigmask); + if ( (-1 == ret) && + (EINTR != errno) ) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, + "ppoll"); + return (0 < ret); +} + + void TALER_CRYPTO_helper_denom_poll (struct TALER_CRYPTO_DenominationHelper *dh) { @@ -368,7 +408,13 @@ TALER_CRYPTO_helper_denom_poll (struct TALER_CRYPTO_DenominationHelper *dh) if (ret < 0) { if (EAGAIN == errno) - break; + { + if (dh->synced) + break; + if (! await_read_ready (dh)) + break; /* timeout */ + continue; /* try again */ + } GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "recv"); do_disconnect (dh); @@ -404,6 +450,11 @@ TALER_CRYPTO_helper_denom_poll (struct TALER_CRYPTO_DenominationHelper *dh) return; } break; + case TALER_HELPER_RSA_SYNCED: + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Now synchronized with RSA helper\n"); + dh->synced = true; + break; default: GNUNET_break_op (0); do_disconnect (dh); @@ -466,34 +517,11 @@ TALER_CRYPTO_helper_denom_sign ( const struct GNUNET_MessageHeader *hdr = (const struct GNUNET_MessageHeader *) buf; + if (! await_read_ready (dh)) { - /* wait for reply with 5s timeout */ - struct pollfd pfd = { - .fd = dh->sock, - .events = POLLIN - }; - sigset_t sigmask; - struct timespec ts = { - .tv_sec = 5 - }; - - GNUNET_assert (0 == sigemptyset (&sigmask)); - GNUNET_assert (0 == sigaddset (&sigmask, SIGTERM)); - GNUNET_assert (0 == sigaddset (&sigmask, SIGHUP)); - ret = ppoll (&pfd, - 1, - &ts, - &sigmask); - if ( (-1 == ret) && - (EINTR != errno) ) - GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, - "ppoll"); - if (0 >= ret) - { - do_disconnect (dh); - *ec = TALER_EC_GENERIC_TIMEOUT; - return ds; - } + do_disconnect (dh); + *ec = TALER_EC_GENERIC_TIMEOUT; + return ds; } ret = recv (dh->sock, buf, diff --git a/src/util/crypto_helper_esign.c b/src/util/crypto_helper_esign.c index 39130e04f..1cf20e914 100644 --- a/src/util/crypto_helper_esign.c +++ b/src/util/crypto_helper_esign.c @@ -57,6 +57,11 @@ struct TALER_CRYPTO_ExchangeSignHelper * The UNIX domain socket, -1 if we are currently not connected. */ int sock; + + /** + * Have we reached the sync'ed state? + */ + bool synced; }; @@ -309,6 +314,41 @@ handle_mt_purge (struct TALER_CRYPTO_ExchangeSignHelper *esh, } +/** + * Wait until the socket is ready to read. + * + * @param dh helper to wait for + * @return false on timeout (after 5s) + */ +static bool +await_read_ready (struct TALER_CRYPTO_ExchangeSignHelper *esh) +{ + /* wait for reply with 5s timeout */ + struct pollfd pfd = { + .fd = esh->sock, + .events = POLLIN + }; + sigset_t sigmask; + struct timespec ts = { + .tv_sec = 5 + }; + int ret; + + GNUNET_assert (0 == sigemptyset (&sigmask)); + GNUNET_assert (0 == sigaddset (&sigmask, SIGTERM)); + GNUNET_assert (0 == sigaddset (&sigmask, SIGHUP)); + ret = ppoll (&pfd, + 1, + &ts, + &sigmask); + if ( (-1 == ret) && + (EINTR != errno) ) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, + "ppoll"); + return (0 < ret); +} + + void TALER_CRYPTO_helper_esign_poll (struct TALER_CRYPTO_ExchangeSignHelper *esh) { @@ -329,7 +369,13 @@ TALER_CRYPTO_helper_esign_poll (struct TALER_CRYPTO_ExchangeSignHelper *esh) if (ret < 0) { if (EAGAIN == errno) - break; + { + if (esh->synced) + break; + if (! await_read_ready (esh)) + break; /* timeout */ + continue; /* try again */ + } GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "recv"); do_disconnect (esh); @@ -365,6 +411,11 @@ TALER_CRYPTO_helper_esign_poll (struct TALER_CRYPTO_ExchangeSignHelper *esh) return; } break; + case TALER_HELPER_EDDSA_SYNCED: + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Now synchronized with EdDSA helper\n"); + esh->synced = true; + break; default: GNUNET_break_op (0); do_disconnect (esh); @@ -422,33 +473,10 @@ TALER_CRYPTO_helper_esign_sign_ ( const struct GNUNET_MessageHeader *hdr = (const struct GNUNET_MessageHeader *) buf; + if (! await_read_ready (esh)) { - /* wait for reply with 5s timeout */ - struct pollfd pfd = { - .fd = esh->sock, - .events = POLLIN - }; - sigset_t sigmask; - struct timespec ts = { - .tv_sec = 5 - }; - - GNUNET_assert (0 == sigemptyset (&sigmask)); - GNUNET_assert (0 == sigaddset (&sigmask, SIGTERM)); - GNUNET_assert (0 == sigaddset (&sigmask, SIGHUP)); - ret = ppoll (&pfd, - 1, - &ts, - &sigmask); - if ( (-1 == ret) && - (EINTR != errno) ) - GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, - "ppoll"); - if (0 >= ret) - { - do_disconnect (esh); - return TALER_EC_GENERIC_TIMEOUT; - } + do_disconnect (esh); + return TALER_EC_GENERIC_TIMEOUT; } ret = recv (esh->sock, buf, diff --git a/src/util/taler-helper-crypto-eddsa.c b/src/util/taler-helper-crypto-eddsa.c index af1cc24d6..71a34fa2f 100644 --- a/src/util/taler-helper-crypto-eddsa.c +++ b/src/util/taler-helper-crypto-eddsa.c @@ -879,9 +879,28 @@ read_job (void *cls) key)) { /* client died, skip the rest */ + client = NULL; break; } } + if (NULL != client) + { + struct GNUNET_MessageHeader synced = { + .type = htons (TALER_HELPER_EDDSA_SYNCED), + .size = htons (sizeof (synced)) + }; + + if (GNUNET_OK != + transmit (&client->addr, + client->addr_size, + &synced)) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Client %s must have disconnected\n", + client->addr.sun_path); + free_client (client); + } + } } break; case TALER_HELPER_EDDSA_MT_REQ_SIGN: @@ -1532,10 +1551,12 @@ run (void *cls, unix_sock, &read_job, NULL); - - /* start job to keep keys up-to-date */ - keygen_task = GNUNET_SCHEDULER_add_now (&update_keys, - NULL); + /* start job to keep keys up-to-date; MUST be run before the #read_task, + hence with priority. */ + keygen_task = GNUNET_SCHEDULER_add_with_priority ( + GNUNET_SCHEDULER_PRIORITY_URGENT, + &update_keys, + NULL); /* start job to handle completed work */ { diff --git a/src/util/taler-helper-crypto-eddsa.h b/src/util/taler-helper-crypto-eddsa.h index 7c014e45e..5d632301f 100644 --- a/src/util/taler-helper-crypto-eddsa.h +++ b/src/util/taler-helper-crypto-eddsa.h @@ -31,6 +31,9 @@ #define TALER_HELPER_EDDSA_MT_RES_SIGNATURE 17 #define TALER_HELPER_EDDSA_MT_RES_SIGN_FAILURE 18 +#define TALER_HELPER_EDDSA_SYNCED 19 + + GNUNET_NETWORK_STRUCT_BEGIN /** diff --git a/src/util/taler-helper-crypto-rsa.c b/src/util/taler-helper-crypto-rsa.c index aeb747d9b..ec1158ee7 100644 --- a/src/util/taler-helper-crypto-rsa.c +++ b/src/util/taler-helper-crypto-rsa.c @@ -1061,6 +1061,24 @@ read_job (void *cls) if (NULL == client) break; } + if (NULL != client) + { + struct GNUNET_MessageHeader synced = { + .type = htons (TALER_HELPER_RSA_SYNCED), + .size = htons (sizeof (synced)) + }; + + if (GNUNET_OK != + transmit (&client->addr, + client->addr_size, + &synced)) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Client %s must have disconnected\n", + client->addr.sun_path); + free_client (client); + } + } } break; case TALER_HELPER_RSA_MT_REQ_SIGN: @@ -1914,10 +1932,12 @@ run (void *cls, unix_sock, &read_job, NULL); - - /* start job to keep keys up-to-date */ - keygen_task = GNUNET_SCHEDULER_add_now (&update_denominations, - NULL); + /* start job to keep keys up-to-date; MUST be run before the #read_task, + hence with priority. */ + keygen_task = GNUNET_SCHEDULER_add_with_priority ( + GNUNET_SCHEDULER_PRIORITY_URGENT, + &update_denominations, + NULL); /* start job to handle completed work */ { diff --git a/src/util/taler-helper-crypto-rsa.h b/src/util/taler-helper-crypto-rsa.h index d7617e551..00087a735 100644 --- a/src/util/taler-helper-crypto-rsa.h +++ b/src/util/taler-helper-crypto-rsa.h @@ -31,6 +31,8 @@ #define TALER_HELPER_RSA_MT_RES_SIGNATURE 7 #define TALER_HELPER_RSA_MT_RES_SIGN_FAILURE 8 +#define TALER_HELPER_RSA_SYNCED 9 + GNUNET_NETWORK_STRUCT_BEGIN /** -- cgit v1.2.3