[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-exchange] branch master updated: dynamic curl timeouts for /keys
From: |
gnunet |
Subject: |
[taler-exchange] branch master updated: dynamic curl timeouts for /keys and /wire requests |
Date: |
Tue, 12 Jan 2021 15:12:28 +0100 |
This is an automated email from the git hooks/post-receive script.
dold pushed a commit to branch master
in repository exchange.
The following commit(s) were added to refs/heads/master by this push:
new 8f887a21 dynamic curl timeouts for /keys and /wire requests
8f887a21 is described below
commit 8f887a215e115d7e5f10a558b465521a6da0133c
Author: Florian Dold <florian@dold.me>
AuthorDate: Tue Jan 12 15:08:15 2021 +0100
dynamic curl timeouts for /keys and /wire requests
---
src/lib/exchange_api_handle.c | 120 ++++++++---------------------------------
src/lib/exchange_api_handle.h | 121 ++++++++++++++++++++++++++++++++++++++++++
src/lib/exchange_api_wire.c | 24 +++++++++
3 files changed, 166 insertions(+), 99 deletions(-)
diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c
index c3ed6373..bd6f1cfb 100644
--- a/src/lib/exchange_api_handle.c
+++ b/src/lib/exchange_api_handle.c
@@ -68,27 +68,6 @@
GNUNET_log (type, "Curl function `%s' has failed at `%s:%d' with error: %s",
\
function, __FILE__, __LINE__, curl_easy_strerror (code));
-/**
- * Stages of initialization for the `struct TALER_EXCHANGE_Handle`
- */
-enum ExchangeHandleState
-{
- /**
- * Just allocated.
- */
- MHS_INIT = 0,
-
- /**
- * Obtained the exchange's certification data and keys.
- */
- MHS_CERT = 1,
-
- /**
- * Failed to initialize (fatal).
- */
- MHS_FAILED = 2
-};
-
/**
* Data for the request to get the /keys of a exchange.
@@ -145,83 +124,6 @@ struct TEAH_AuditorListEntry
};
-/**
- * Handle to the exchange
- */
-struct TALER_EXCHANGE_Handle
-{
- /**
- * The context of this handle
- */
- struct GNUNET_CURL_Context *ctx;
-
- /**
- * The URL of the exchange (i.e. "http://exchange.taler.net/")
- */
- char *url;
-
- /**
- * Function to call with the exchange's certification data,
- * NULL if this has already been done.
- */
- TALER_EXCHANGE_CertificationCallback cert_cb;
-
- /**
- * Closure to pass to @e cert_cb.
- */
- void *cert_cb_cls;
-
- /**
- * Data for the request to get the /keys of a exchange,
- * NULL once we are past stage #MHS_INIT.
- */
- struct KeysRequest *kr;
-
- /**
- * Task for retrying /keys request.
- */
- struct GNUNET_SCHEDULER_Task *retry_task;
-
- /**
- * Raw key data of the exchange, only valid if
- * @e handshake_complete is past stage #MHS_CERT.
- */
- json_t *key_data_raw;
-
- /**
- * Head of DLL of auditors of this exchange.
- */
- struct TEAH_AuditorListEntry *auditors_head;
-
- /**
- * Tail of DLL of auditors of this exchange.
- */
- struct TEAH_AuditorListEntry *auditors_tail;
-
- /**
- * Key data of the exchange, only valid if
- * @e handshake_complete is past stage #MHS_CERT.
- */
- struct TALER_EXCHANGE_Keys key_data;
-
- /**
- * Retry /keys frequency.
- */
- struct GNUNET_TIME_Relative retry_delay;
-
- /**
- * When does @e key_data expire?
- */
- struct GNUNET_TIME_Absolute key_data_expiration;
-
- /**
- * Stage of the exchange's initialization routines.
- */
- enum ExchangeHandleState state;
-
-};
-
-
/* ***************** Internal /keys fetching ************* */
/**
@@ -250,6 +152,7 @@ struct KeysRequest
*/
struct GNUNET_TIME_Absolute expire;
+ struct GNUNET_SCHEDULER_Task *timeout_task;
};
@@ -1201,6 +1104,8 @@ keys_completed_cb (void *cls,
{
case 0:
free_keys_request (kr);
+ /* FIXME: Maybe we should only increment when we know it's a timeout? */
+ exchange->keys_error_count++;
exchange->kr = NULL;
GNUNET_assert (NULL == exchange->retry_task);
exchange->retry_delay = EXCHANGE_LIB_BACKOFF (exchange->retry_delay);
@@ -1209,6 +1114,7 @@ keys_completed_cb (void *cls,
exchange);
return;
case MHD_HTTP_OK:
+ exchange->keys_error_count = 0;
if (NULL == j)
{
response_code = 0;
@@ -1290,6 +1196,8 @@ keys_completed_cb (void *cls,
exchange->retry_delay = GNUNET_TIME_UNIT_ZERO;
break;
default:
+ if (MHD_HTTP_GATEWAY_TIMEOUT == response_code)
+ exchange->keys_error_count++;
hr.ec = TALER_JSON_get_error_code (j);
hr.hint = TALER_JSON_get_error_hint (j);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -1882,6 +1790,20 @@ TALER_EXCHANGE_connect (
}
+/**
+ * Compute the network timeout for the next request to /keys.
+ *
+ * @param exchange the exchange handle
+ * @returns the timeout in seconds (for use by CURL)
+ */
+static long
+get_keys_timeout_seconds (struct TALER_EXCHANGE_Handle *exchange)
+{
+ return GNUNET_MIN (60,
+ 5 + (1L << exchange->keys_error_count));
+}
+
+
/**
* Initiate download of /keys from the exchange.
*
@@ -1936,7 +1858,7 @@ request_keys (void *cls)
GNUNET_break (CURLE_OK ==
curl_easy_setopt (eh,
CURLOPT_TIMEOUT,
- (long) 300));
+ get_keys_timeout_seconds (exchange)));
GNUNET_assert (CURLE_OK ==
curl_easy_setopt (eh,
CURLOPT_HEADERFUNCTION,
diff --git a/src/lib/exchange_api_handle.h b/src/lib/exchange_api_handle.h
index b4b8ccf5..1a7e8ee7 100644
--- a/src/lib/exchange_api_handle.h
+++ b/src/lib/exchange_api_handle.h
@@ -58,6 +58,118 @@ struct TEAH_AuditorInteractionEntry
struct TALER_AUDITOR_DepositConfirmationHandle *dch;
};
+/**
+ * Stages of initialization for the `struct TALER_EXCHANGE_Handle`
+ */
+enum ExchangeHandleState
+{
+ /**
+ * Just allocated.
+ */
+ MHS_INIT = 0,
+
+ /**
+ * Obtained the exchange's certification data and keys.
+ */
+ MHS_CERT = 1,
+
+ /**
+ * Failed to initialize (fatal).
+ */
+ MHS_FAILED = 2
+};
+
+
+/**
+ * Handle to the exchange
+ */
+struct TALER_EXCHANGE_Handle
+{
+ /**
+ * The context of this handle
+ */
+ struct GNUNET_CURL_Context *ctx;
+
+ /**
+ * The URL of the exchange (i.e. "http://exchange.taler.net/")
+ */
+ char *url;
+
+ /**
+ * Function to call with the exchange's certification data,
+ * NULL if this has already been done.
+ */
+ TALER_EXCHANGE_CertificationCallback cert_cb;
+
+ /**
+ * Closure to pass to @e cert_cb.
+ */
+ void *cert_cb_cls;
+
+ /**
+ * Data for the request to get the /keys of a exchange,
+ * NULL once we are past stage #MHS_INIT.
+ */
+ struct KeysRequest *kr;
+
+ /**
+ * Task for retrying /keys request.
+ */
+ struct GNUNET_SCHEDULER_Task *retry_task;
+
+ /**
+ * Raw key data of the exchange, only valid if
+ * @e handshake_complete is past stage #MHS_CERT.
+ */
+ json_t *key_data_raw;
+
+ /**
+ * Head of DLL of auditors of this exchange.
+ */
+ struct TEAH_AuditorListEntry *auditors_head;
+
+ /**
+ * Tail of DLL of auditors of this exchange.
+ */
+ struct TEAH_AuditorListEntry *auditors_tail;
+
+ /**
+ * Key data of the exchange, only valid if
+ * @e handshake_complete is past stage #MHS_CERT.
+ */
+ struct TALER_EXCHANGE_Keys key_data;
+
+ /**
+ * Retry /keys frequency.
+ */
+ struct GNUNET_TIME_Relative retry_delay;
+
+ /**
+ * When does @e key_data expire?
+ */
+ struct GNUNET_TIME_Absolute key_data_expiration;
+
+ /**
+ * Number of subsequent failed requests to /keys.
+ *
+ * Used to compute the CURL timeout for the request.
+ */
+ unsigned int keys_error_count;
+
+ /**
+ * Number of subsequent failed requests to /wire.
+ *
+ * Used to compute the CURL timeout for the request.
+ */
+ unsigned int wire_error_count;
+
+ /**
+ * Stage of the exchange's initialization routines.
+ */
+ enum ExchangeHandleState state;
+
+};
+
/**
* Function called for each auditor to give us a chance to possibly
@@ -111,6 +223,15 @@ struct GNUNET_CURL_Context *
TEAH_handle_to_context (struct TALER_EXCHANGE_Handle *h);
+/**
+ * Check if the handle is ready to process requests.
+ *
+ * @param h the exchange handle to query
+ * @return #GNUNET_YES if we are ready, #GNUNET_NO if not
+ */
+int
+TEAH_handle_is_ready (struct TALER_EXCHANGE_Handle *h);
+
/**
* Check if the handle is ready to process requests.
*
diff --git a/src/lib/exchange_api_wire.c b/src/lib/exchange_api_wire.c
index 8653d5a9..eb0894c8 100644
--- a/src/lib/exchange_api_wire.c
+++ b/src/lib/exchange_api_wire.c
@@ -219,6 +219,8 @@ handle_wire_finished (void *cls,
{
case 0:
hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
+ /* FIXME: Maybe we should only increment when we know it's a timeout? */
+ wh->exchange->wire_error_count++;
break;
case MHD_HTTP_OK:
{
@@ -233,6 +235,8 @@ handle_wire_finished (void *cls,
GNUNET_JSON_spec_end ()
};
+ wh->exchange->wire_error_count = 0;
+
if (GNUNET_OK !=
GNUNET_JSON_parse (j,
spec,
@@ -356,6 +360,8 @@ handle_wire_finished (void *cls,
break;
default:
/* unexpected response code */
+ if (MHD_HTTP_GATEWAY_TIMEOUT == response_code)
+ wh->exchange->wire_error_count++;
GNUNET_break_op (0);
hr.ec = TALER_JSON_get_error_code (j);
hr.hint = TALER_JSON_get_error_hint (j);
@@ -374,6 +380,20 @@ handle_wire_finished (void *cls,
}
+/**
+ * Compute the network timeout for the next request to /wire.
+ *
+ * @param exchange the exchange handle
+ * @returns the timeout in seconds (for use by CURL)
+ */
+static long
+get_wire_timeout_seconds (struct TALER_EXCHANGE_Handle *exchange)
+{
+ return GNUNET_MIN (60,
+ 5 + (1L << exchange->wire_error_count));
+}
+
+
/**
* Obtain information about a exchange's wire instructions.
* A exchange may provide wire instructions for creating
@@ -416,6 +436,10 @@ TALER_EXCHANGE_wire (struct TALER_EXCHANGE_Handle
*exchange,
wh->url = TEAH_path_to_url (exchange,
"/wire");
eh = TALER_EXCHANGE_curl_easy_get_ (wh->url);
+ GNUNET_break (CURLE_OK ==
+ curl_easy_setopt (eh,
+ CURLOPT_TIMEOUT,
+ get_wire_timeout_seconds (wh->exchange)));
if (NULL == eh)
{
GNUNET_break (0);
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [taler-exchange] branch master updated: dynamic curl timeouts for /keys and /wire requests,
gnunet <=