summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bank-lib/bank_api_admin.c6
-rw-r--r--src/bank-lib/bank_api_credit.c6
-rw-r--r--src/bank-lib/bank_api_debit.c6
-rw-r--r--src/bank-lib/bank_api_transfer.c172
-rw-r--r--src/exchange-tools/taler-wire.c28
-rw-r--r--src/exchange/taler-exchange-aggregator.c40
-rw-r--r--src/include/taler_bank_service.h64
-rw-r--r--src/lib/auditor_api_curl_defaults.c17
-rw-r--r--src/lib/auditor_api_curl_defaults.h5
-rw-r--r--src/lib/auditor_api_deposit_confirmation.c29
-rw-r--r--src/lib/auditor_api_exchanges.c15
-rw-r--r--src/lib/auditor_api_handle.c31
-rw-r--r--src/lib/auditor_api_handle.h8
-rw-r--r--src/lib/exchange_api_curl_defaults.c6
-rw-r--r--src/lib/exchange_api_deposit.c12
-rw-r--r--src/lib/exchange_api_deposits_get.c7
-rw-r--r--src/lib/exchange_api_handle.c24
-rw-r--r--src/lib/exchange_api_link.c7
-rw-r--r--src/lib/exchange_api_melt.c12
-rw-r--r--src/lib/exchange_api_recoup.c12
-rw-r--r--src/lib/exchange_api_refreshes_reveal.c12
-rw-r--r--src/lib/exchange_api_refund.c12
-rw-r--r--src/lib/exchange_api_reserves_get.c7
-rw-r--r--src/lib/exchange_api_transfers_get.c7
-rw-r--r--src/lib/exchange_api_wire.c11
-rw-r--r--src/lib/exchange_api_withdraw.c12
-rw-r--r--src/testing/testing_api_cmd_bank_transfer.c18
27 files changed, 349 insertions, 237 deletions
diff --git a/src/bank-lib/bank_api_admin.c b/src/bank-lib/bank_api_admin.c
index 0acc33ca..2cc3ec8e 100644
--- a/src/bank-lib/bank_api_admin.c
+++ b/src/bank-lib/bank_api_admin.c
@@ -218,7 +218,8 @@ TALER_BANK_admin_add_incoming (struct GNUNET_CURL_Context *ctx,
"Content-Type: application/json");
eh = curl_easy_init ();
- if ( (GNUNET_OK !=
+ if ( (NULL == eh) ||
+ (GNUNET_OK !=
TALER_BANK_setup_auth_ (eh,
auth)) ||
(CURLE_OK !=
@@ -232,7 +233,8 @@ TALER_BANK_admin_add_incoming (struct GNUNET_CURL_Context *ctx,
{
GNUNET_break (0);
TALER_BANK_admin_add_incoming_cancel (aai);
- curl_easy_cleanup (eh);
+ if (NULL != eh)
+ curl_easy_cleanup (eh);
json_decref (admin_obj);
return NULL;
}
diff --git a/src/bank-lib/bank_api_credit.c b/src/bank-lib/bank_api_credit.c
index be5b1908..bb0d8663 100644
--- a/src/bank-lib/bank_api_credit.c
+++ b/src/bank-lib/bank_api_credit.c
@@ -276,7 +276,8 @@ TALER_BANK_credit_history (struct GNUNET_CURL_Context *ctx,
"Requesting credit history at `%s'\n",
hh->request_url);
eh = curl_easy_init ();
- if ( (GNUNET_OK !=
+ if ( (NULL == eh) ||
+ (GNUNET_OK !=
TALER_BANK_setup_auth_ (eh,
auth)) ||
(CURLE_OK !=
@@ -286,7 +287,8 @@ TALER_BANK_credit_history (struct GNUNET_CURL_Context *ctx,
{
GNUNET_break (0);
TALER_BANK_credit_history_cancel (hh);
- curl_easy_cleanup (eh);
+ if (NULL != eh)
+ curl_easy_cleanup (eh);
return NULL;
}
hh->job = GNUNET_CURL_job_add2 (ctx,
diff --git a/src/bank-lib/bank_api_debit.c b/src/bank-lib/bank_api_debit.c
index eec4a1df..9b4e9a49 100644
--- a/src/bank-lib/bank_api_debit.c
+++ b/src/bank-lib/bank_api_debit.c
@@ -274,7 +274,8 @@ TALER_BANK_debit_history (struct GNUNET_CURL_Context *ctx,
"Requesting history at `%s'\n",
hh->request_url);
eh = curl_easy_init ();
- if ( (GNUNET_OK !=
+ if ( (NULL == eh) ||
+ (GNUNET_OK !=
TALER_BANK_setup_auth_ (eh,
auth)) ||
(CURLE_OK !=
@@ -284,7 +285,8 @@ TALER_BANK_debit_history (struct GNUNET_CURL_Context *ctx,
{
GNUNET_break (0);
TALER_BANK_debit_history_cancel (hh);
- curl_easy_cleanup (eh);
+ if (NULL != eh)
+ curl_easy_cleanup (eh);
return NULL;
}
hh->job = GNUNET_CURL_job_add2 (ctx,
diff --git a/src/bank-lib/bank_api_transfer.c b/src/bank-lib/bank_api_transfer.c
index 94ad58fd..e713f040 100644
--- a/src/bank-lib/bank_api_transfer.c
+++ b/src/bank-lib/bank_api_transfer.c
@@ -66,7 +66,8 @@ struct WirePackP
GNUNET_NETWORK_STRUCT_END
/**
- * Prepare for exeuction of a wire transfer.
+ * Prepare for execution of a wire transfer from the exchange to some
+ * merchant.
*
* @param destination_account_payto_uri payto:// URL identifying where to send the money
* @param amount amount to transfer, already rounded
@@ -77,19 +78,27 @@ GNUNET_NETWORK_STRUCT_END
* @param[out] buf_size set to number of bytes in @a buf, 0 on error
*/
void
-TALER_BANK_prepare_wire_transfer (const char *destination_account_payto_uri,
- const struct TALER_Amount *amount,
- const char *exchange_base_url,
- const struct
- TALER_WireTransferIdentifierRawP *wtid,
- void **buf,
- size_t *buf_size)
+TALER_BANK_prepare_transfer (const char *destination_account_payto_uri,
+ const struct TALER_Amount *amount,
+ const char *exchange_base_url,
+ const struct
+ TALER_WireTransferIdentifierRawP *wtid,
+ void **buf,
+ size_t *buf_size)
{
struct WirePackP *wp;
size_t d_len = strlen (destination_account_payto_uri) + 1;
size_t u_len = strlen (exchange_base_url) + 1;
char *end;
+ if ( (d_len > (size_t) UINT32_MAX) ||
+ (u_len > (size_t) UINT32_MAX) )
+ {
+ GNUNET_break (0); /* that's some long URL... */
+ *buf = NULL;
+ *buf_size = 0;
+ return;
+ }
*buf_size = sizeof (*wp) + d_len + u_len;
wp = GNUNET_malloc (*buf_size);
GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE,
@@ -111,9 +120,9 @@ TALER_BANK_prepare_wire_transfer (const char *destination_account_payto_uri,
/**
- * @brief An transfer Handle
+ * @brief Handle for an active wire transfer.
*/
-struct TALER_BANK_WireExecuteHandle
+struct TALER_BANK_TransferHandle
{
/**
@@ -134,7 +143,7 @@ struct TALER_BANK_WireExecuteHandle
/**
* Function to call with the result.
*/
- TALER_BANK_ConfirmationCallback cb;
+ TALER_BANK_TransferCallback cb;
/**
* Closure for @a cb.
@@ -148,7 +157,7 @@ struct TALER_BANK_WireExecuteHandle
* Function called when we're done processing the
* HTTP /transfer request.
*
- * @param cls the `struct TALER_BANK_WireExecuteHandle`
+ * @param cls the `struct TALER_BANK_TransferHandle`
* @param response_code HTTP response code, 0 on error
* @param response parsed JSON result, NULL on error
*/
@@ -157,14 +166,13 @@ handle_transfer_finished (void *cls,
long response_code,
const void *response)
{
- struct TALER_BANK_WireExecuteHandle *weh = cls;
+ struct TALER_BANK_TransferHandle *th = cls;
+ const json_t *j = response;
uint64_t row_id = UINT64_MAX;
- struct GNUNET_TIME_Absolute timestamp;
+ struct GNUNET_TIME_Absolute timestamp = GNUNET_TIME_UNIT_FOREVER_ABS;
enum TALER_ErrorCode ec;
- const json_t *j = response;
- weh->job = NULL;
- timestamp = GNUNET_TIME_UNIT_FOREVER_ABS;
+ th->job = NULL;
switch (response_code)
{
case 0:
@@ -198,19 +206,20 @@ handle_transfer_finished (void *cls,
(or API version conflict); just pass JSON reply to the application */
ec = TALER_JSON_get_error_code (j);
break;
- case MHD_HTTP_FORBIDDEN:
- /* Access denied */
- ec = TALER_JSON_get_error_code (j);
- break;
case MHD_HTTP_UNAUTHORIZED:
- /* Nothing really to verify, bank says one of the signatures is
- invalid; as we checked them, this should never happen, we
- should pass the JSON reply to the application */
+ /* Nothing really to verify, bank says our credentials are
+ invalid. We should pass the JSON reply to the application. */
ec = TALER_JSON_get_error_code (j);
break;
case MHD_HTTP_NOT_FOUND:
- /* Nothing really to verify, this should never
- happen, we should pass the JSON reply to the application */
+ /* Nothing really to verify, endpoint wrong -- could be user unknown */
+ ec = TALER_JSON_get_error_code (j);
+ break;
+ case MHD_HTTP_CONFLICT:
+ /* Nothing really to verify. Server says we used the same transfer request
+ UID before, but with different details. Should not happen if the user
+ properly used #TALER_BANK_prepare_transfer() and our PRNG is not
+ broken... */
ec = TALER_JSON_get_error_code (j);
break;
case MHD_HTTP_INTERNAL_SERVER_ERROR:
@@ -228,12 +237,12 @@ handle_transfer_finished (void *cls,
response_code = 0;
break;
}
- weh->cb (weh->cb_cls,
- response_code,
- ec,
- row_id,
- timestamp);
- TALER_BANK_execute_wire_transfer_cancel (weh);
+ th->cb (th->cb_cls,
+ response_code,
+ ec,
+ row_id,
+ timestamp);
+ TALER_BANK_transfer_cancel (th);
}
@@ -248,16 +257,16 @@ handle_transfer_finished (void *cls,
* @param cc_cls closure for @a cc
* @return NULL on error
*/
-struct TALER_BANK_WireExecuteHandle *
-TALER_BANK_execute_wire_transfer (struct GNUNET_CURL_Context *ctx,
- const struct
- TALER_BANK_AuthenticationData *auth,
- const void *buf,
- size_t buf_size,
- TALER_BANK_ConfirmationCallback cc,
- void *cc_cls)
+struct TALER_BANK_TransferHandle *
+TALER_BANK_transfer (struct GNUNET_CURL_Context *ctx,
+ const struct
+ TALER_BANK_AuthenticationData *auth,
+ const void *buf,
+ size_t buf_size,
+ TALER_BANK_TransferCallback cc,
+ void *cc_cls)
{
- struct TALER_BANK_WireExecuteHandle *weh;
+ struct TALER_BANK_TransferHandle *th;
json_t *transfer_obj;
CURL *eh;
const struct WirePackP *wp = buf;
@@ -281,6 +290,12 @@ TALER_BANK_execute_wire_transfer (struct GNUNET_CURL_Context *ctx,
}
destination_account_uri = (const char *) &wp[1];
exchange_base_url = destination_account_uri + d_len;
+ if ( ('\0' != destination_account_uri[d_len - 1]) ||
+ ('\0' != exchange_base_url[u_len - 1]) )
+ {
+ GNUNET_break (0);
+ return NULL;
+ }
if (NULL == auth->wire_gateway_url)
{
GNUNET_break (0);
@@ -288,15 +303,15 @@ TALER_BANK_execute_wire_transfer (struct GNUNET_CURL_Context *ctx,
}
TALER_amount_ntoh (&amount,
&wp->amount);
- weh = GNUNET_new (struct TALER_BANK_WireExecuteHandle);
- weh->cb = cc;
- weh->cb_cls = cc_cls;
- weh->request_url = TALER_url_join (auth->wire_gateway_url,
- "transfer",
- NULL);
- if (NULL == weh->request_url)
+ th = GNUNET_new (struct TALER_BANK_TransferHandle);
+ th->cb = cc;
+ th->cb_cls = cc_cls;
+ th->request_url = TALER_url_join (auth->wire_gateway_url,
+ "transfer",
+ NULL);
+ if (NULL == th->request_url)
{
- GNUNET_free (weh);
+ GNUNET_free (th);
GNUNET_break (0);
return NULL;
}
@@ -312,58 +327,65 @@ TALER_BANK_execute_wire_transfer (struct GNUNET_CURL_Context *ctx,
GNUNET_break (0);
return NULL;
}
- weh->post_ctx.headers = curl_slist_append
- (weh->post_ctx.headers,
- "Content-Type: application/json");
-
eh = curl_easy_init ();
- if ( (GNUNET_OK !=
+ if ( (NULL == eh) ||
+ (GNUNET_OK !=
TALER_BANK_setup_auth_ (eh,
auth)) ||
(CURLE_OK !=
curl_easy_setopt (eh,
CURLOPT_URL,
- weh->request_url)) ||
+ th->request_url)) ||
(GNUNET_OK !=
- TALER_curl_easy_post (&weh->post_ctx,
+ TALER_curl_easy_post (&th->post_ctx,
eh,
transfer_obj)) )
{
GNUNET_break (0);
- TALER_BANK_execute_wire_transfer_cancel (weh);
- curl_easy_cleanup (eh);
+ TALER_BANK_transfer_cancel (th);
+ if (NULL != eh)
+ curl_easy_cleanup (eh);
json_decref (transfer_obj);
return NULL;
}
json_decref (transfer_obj);
- weh->job = GNUNET_CURL_job_add2 (ctx,
- eh,
- weh->post_ctx.headers,
- &handle_transfer_finished,
- weh);
- return weh;
+ th->job = GNUNET_CURL_job_add2 (ctx,
+ eh,
+ th->post_ctx.headers,
+ &handle_transfer_finished,
+ th);
+ return th;
}
/**
- * Cancel a wire transfer. This function cannot be used on a request handle
- * if a response is already served for it.
+ * Abort execution of a wire transfer. For example, because we are shutting
+ * down. Note that if an execution is aborted, it may or may not still
+ * succeed.
+ *
+ * The caller MUST run #TALER_BANK_transfer() again for the same request as
+ * soon as possilbe, to ensure that the request either ultimately succeeds or
+ * ultimately fails. Until this has been done, the transaction is in limbo
+ * (i.e. may or may not have been committed).
+ *
+ * This function cannot be used on a request handle if a response is already
+ * served for it.
*
- * @param weh the wire transfer request handle
+ * @param th the wire transfer request handle
*/
void
-TALER_BANK_execute_wire_transfer_cancel (struct
- TALER_BANK_WireExecuteHandle *weh)
+TALER_BANK_transfer_cancel (struct
+ TALER_BANK_TransferHandle *th)
{
- if (NULL != weh->job)
+ if (NULL != th->job)
{
- GNUNET_CURL_job_cancel (weh->job);
- weh->job = NULL;
+ GNUNET_CURL_job_cancel (th->job);
+ th->job = NULL;
}
- TALER_curl_easy_post_finished (&weh->post_ctx);
- GNUNET_free (weh->request_url);
- GNUNET_free (weh);
+ TALER_curl_easy_post_finished (&th->post_ctx);
+ GNUNET_free (th->request_url);
+ GNUNET_free (th);
}
diff --git a/src/exchange-tools/taler-wire.c b/src/exchange-tools/taler-wire.c
index 7fc3b041..d5a915a9 100644
--- a/src/exchange-tools/taler-wire.c
+++ b/src/exchange-tools/taler-wire.c
@@ -70,7 +70,7 @@ static char *destination_account_url;
/**
* Handle for executing the wire transfer.
*/
-static struct TALER_BANK_WireExecuteHandle *eh;
+static struct TALER_BANK_TransferHandle *eh;
/**
* Handle to ongoing history operation.
@@ -189,18 +189,18 @@ execute_wire_transfer ()
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
&wtid,
sizeof (wtid));
- TALER_BANK_prepare_wire_transfer (destination_account_url,
- &amount,
- "http://exchange.example.com/",
- &wtid,
- &buf,
- &buf_size);
- eh = TALER_BANK_execute_wire_transfer (ctx,
- &auth,
- buf,
- buf_size,
- &confirmation_cb,
- NULL);
+ TALER_BANK_prepare_transfer (destination_account_url,
+ &amount,
+ "http://exchange.example.com/",
+ &wtid,
+ &buf,
+ &buf_size);
+ eh = TALER_BANK_transfer (ctx,
+ &auth,
+ buf,
+ buf_size,
+ &confirmation_cb,
+ NULL);
if (NULL == eh)
{
fprintf (stderr,
@@ -260,7 +260,7 @@ do_shutdown (void *cls)
}
if (NULL != eh)
{
- TALER_BANK_execute_wire_transfer_cancel (eh);
+ TALER_BANK_transfer_cancel (eh);
eh = NULL;
}
TALER_BANK_auth_free (&auth);
diff --git a/src/exchange/taler-exchange-aggregator.c b/src/exchange/taler-exchange-aggregator.c
index bf066d84..e115e52d 100644
--- a/src/exchange/taler-exchange-aggregator.c
+++ b/src/exchange/taler-exchange-aggregator.c
@@ -82,7 +82,7 @@ struct WirePrepareData
/**
* Wire execution handle.
*/
- struct TALER_BANK_WireExecuteHandle *eh;
+ struct TALER_BANK_TransferHandle *eh;
/**
* Wire account used for this preparation.
@@ -565,7 +565,7 @@ shutdown_task (void *cls)
{
if (NULL != wpd->eh)
{
- TALER_BANK_execute_wire_transfer_cancel (wpd->eh);
+ TALER_BANK_transfer_cancel (wpd->eh);
wpd->eh = NULL;
}
db_plugin->rollback (db_plugin->cls,
@@ -1211,12 +1211,12 @@ expired_reserve_cb (void *cls,
ctc->wa = wa;
ctc->session = session;
ctc->method = TALER_payto_get_method (account_payto_uri);
- TALER_BANK_prepare_wire_transfer (account_payto_uri,
- &amount_without_fee,
- exchange_base_url,
- &wtid,
- &buf,
- &buf_size);
+ TALER_BANK_prepare_transfer (account_payto_uri,
+ &amount_without_fee,
+ exchange_base_url,
+ &wtid,
+ &buf,
+ &buf_size);
/* Commit our intention to execute the wire transfer! */
qs = db_plugin->wire_prepare_data_insert (db_plugin->cls,
ctc->session,
@@ -1581,12 +1581,12 @@ run_aggregation (void *cls)
char *url;
url = TALER_JSON_wire_to_payto (au->wire);
- TALER_BANK_prepare_wire_transfer (url,
- &au->final_amount,
- exchange_base_url,
- &au->wtid,
- &buf,
- &buf_size);
+ TALER_BANK_prepare_transfer (url,
+ &au->final_amount,
+ exchange_base_url,
+ &au->wtid,
+ &buf,
+ &buf_size);
GNUNET_free (url);
}
GNUNET_free_non_null (au->additional_rows);
@@ -1804,12 +1804,12 @@ wire_prepare_cb (void *cls,
return;
}
wa = wpd->wa;
- wpd->eh = TALER_BANK_execute_wire_transfer (ctx,
- &wa->auth,
- buf,
- buf_size,
- &wire_confirm_cb,
- NULL);
+ wpd->eh = TALER_BANK_transfer (ctx,
+ &wa->auth,
+ buf,
+ buf_size,
+ &wire_confirm_cb,
+ NULL);
if (NULL == wpd->eh)
{
GNUNET_break (0); /* Irrecoverable */
diff --git a/src/include/taler_bank_service.h b/src/include/taler_bank_service.h
index 41d3d8d3..e65a4847 100644
--- a/src/include/taler_bank_service.h
+++ b/src/include/taler_bank_service.h
@@ -174,19 +174,19 @@ TALER_BANK_admin_add_incoming_cancel (struct
* @param[out] buf_size set to number of bytes in @a buf, 0 on error
*/
void
-TALER_BANK_prepare_wire_transfer (const char *destination_account_payto_uri,
- const struct TALER_Amount *amount,
- const char *exchange_base_url,
- const struct
- TALER_WireTransferIdentifierRawP *wtid,
- void **buf,
- size_t *buf_size);
+TALER_BANK_prepare_transfer (const char *destination_account_payto_uri,
+ const struct TALER_Amount *amount,
+ const char *exchange_base_url,
+ const struct
+ TALER_WireTransferIdentifierRawP *wtid,
+ void **buf,
+ size_t *buf_size);
/**
* Handle for active wire transfer.
*/
-struct TALER_BANK_WireExecuteHandle;
+struct TALER_BANK_TransferHandle;
/**
@@ -199,11 +199,11 @@ struct TALER_BANK_WireExecuteHandle;
* @param timestamp when did the transaction go into effect
*/
typedef void
-(*TALER_BANK_ConfirmationCallback)(void *cls,
- unsigned int response_code,
- enum TALER_ErrorCode ec,
- uint64_t row_id,
- struct GNUNET_TIME_Absolute timestamp);
+(*TALER_BANK_TransferCallback)(void *cls,
+ unsigned int response_code,
+ enum TALER_ErrorCode ec,
+ uint64_t row_id,
+ struct GNUNET_TIME_Absolute timestamp);
/**
@@ -217,30 +217,32 @@ typedef void
* @param cc_cls closure for @a cc
* @return NULL on error
*/
-struct TALER_BANK_WireExecuteHandle *
-TALER_BANK_execute_wire_transfer (struct GNUNET_CURL_Context *ctx,
- const struct
- TALER_BANK_AuthenticationData *auth,
- const void *buf,
- size_t buf_size,
- TALER_BANK_ConfirmationCallback cc,
- void *cc_cls);
+struct TALER_BANK_TransferHandle *
+TALER_BANK_transfer (struct GNUNET_CURL_Context *ctx,
+ const struct TALER_BANK_AuthenticationData *auth,
+ const void *buf,
+ size_t buf_size,
+ TALER_BANK_TransferCallback cc,
+ void *cc_cls);
/**
- * Abort execution of a wire transfer. For example, because we are
- * shutting down. Note that if an execution is aborted, it may or
- * may not still succeed. The caller MUST run @e
- * execute_wire_transfer again for the same request as soon as
- * possilbe, to ensure that the request either ultimately succeeds
- * or ultimately fails. Until this has been done, the transaction is
- * in limbo (i.e. may or may not have been committed).
+ * Abort execution of a wire transfer. For example, because we are shutting
+ * down. Note that if an execution is aborted, it may or may not still
+ * succeed.
*
- * @param weh execution to cancel
+ * The caller MUST run #TALER_BANK_transfer() again for the same request as
+ * soon as possilbe, to ensure that the request either ultimately succeeds or
+ * ultimately fails. Until this has been done, the transaction is in limbo
+ * (i.e. may or may not have been committed).
+ *
+ * This function cannot be used on a request handle if a response is already
+ * served for it.
+ *
+ * @param th handle of the wire transfer request to cancel
*/
void
-TALER_BANK_execute_wire_transfer_cancel (struct
- TALER_BANK_WireExecuteHandle *weh);
+TALER_BANK_transfer_cancel (struct TALER_BANK_TransferHandle *th);
/* ********************* /history/incoming *********************** */
diff --git a/src/lib/auditor_api_curl_defaults.c b/src/lib/auditor_api_curl_defaults.c
index 15c60862..d8c6f619 100644
--- a/src/lib/auditor_api_curl_defaults.c
+++ b/src/lib/auditor_api_curl_defaults.c
@@ -19,7 +19,6 @@
* @brief curl easy handle defaults
* @author Florian Dold
*/
-
#include "auditor_api_curl_defaults.h"
@@ -30,7 +29,7 @@
* @param url URL to query
*/
CURL *
-TAL_curl_easy_get (const char *url)
+TALER_AUDITOR_curl_easy_get_ (const char *url)
{
CURL *eh;
struct GNUNET_AsyncScopeSave scope;
@@ -38,15 +37,25 @@ TAL_curl_easy_get (const char *url)
GNUNET_async_scope_get (&scope);
eh = curl_easy_init ();
-
+ if (NULL == eh)
+ return NULL;
GNUNET_assert (CURLE_OK ==
curl_easy_setopt (eh,
CURLOPT_URL,
url));
GNUNET_assert (CURLE_OK ==
curl_easy_setopt (eh,
+ CURLOPT_FOLLOWLOCATION,
+ 1L));
+ /* limit MAXREDIRS to 5 as a simple security measure against
+ a potential infinite loop caused by a malicious target */
+ GNUNET_assert (CURLE_OK ==
+ curl_easy_setopt (eh,
+ CURLOPT_MAXREDIRS,
+ 5L));
+ GNUNET_assert (CURLE_OK ==
+ curl_easy_setopt (eh,
CURLOPT_TCP_FASTOPEN,
1L));
-
return eh;
}
diff --git a/src/lib/auditor_api_curl_defaults.h b/src/lib/auditor_api_curl_defaults.h
index e16f9004..99e1e07e 100644
--- a/src/lib/auditor_api_curl_defaults.h
+++ b/src/lib/auditor_api_curl_defaults.h
@@ -14,17 +14,14 @@
TALER; see the file COPYING. If not, see
<http://www.gnu.org/licenses/>
*/
-
/**
* @file lib/auditor_api_curl_defaults.h
* @brief curl easy handle defaults
* @author Florian Dold
*/
-
#ifndef _TALER_CURL_DEFAULTS_H
#define _TALER_CURL_DEFAULTS_H
-
#include "platform.h"
#include <gnunet/gnunet_curl_lib.h>
@@ -36,6 +33,6 @@
* @param url URL to query
*/
CURL *
-TAL_curl_easy_get (const char *url);
+TALER_AUDITOR_curl_easy_get_ (const char *url);
#endif /* _TALER_CURL_DEFAULTS_H */
diff --git a/src/lib/auditor_api_deposit_confirmation.c b/src/lib/auditor_api_deposit_confirmation.c
index 54a99c71..ddaf9b7c 100644
--- a/src/lib/auditor_api_deposit_confirmation.c
+++ b/src/lib/auditor_api_deposit_confirmation.c
@@ -290,7 +290,7 @@ TALER_AUDITOR_deposit_confirmation (struct TALER_AUDITOR_Handle *auditor,
(void) GNUNET_TIME_round_abs (&ep_expire);
(void) GNUNET_TIME_round_abs (&ep_end);
GNUNET_assert (GNUNET_YES ==
- MAH_handle_is_ready (auditor));
+ TALER_AUDITOR_handle_is_ready_ (auditor));
if (GNUNET_OK !=
verify_signatures (h_wire,
h_contract_terms,
@@ -346,20 +346,23 @@ TALER_AUDITOR_deposit_confirmation (struct TALER_AUDITOR_Handle *auditor,
dh->auditor = auditor;
dh->cb = cb;
dh->cb_cls = cb_cls;
- dh->url = MAH_path_to_url (auditor, "/deposit-confirmation");
+ dh->url = TALER_AUDITOR_path_to_url_ (auditor,
+ "/deposit-confirmation");
+ eh = TALER_AUDITOR_curl_easy_get_ (dh->url);
- eh = TAL_curl_easy_get (dh->url);
- GNUNET_assert (CURLE_OK ==
- curl_easy_setopt (eh,
- CURLOPT_CUSTOMREQUEST,
- "PUT"));
- if (GNUNET_OK !=
- TALER_curl_easy_post (&dh->ctx,
- eh,
- deposit_confirmation_obj))
+ if ( (NULL == eh) ||
+ (CURLE_OK !=
+ curl_easy_setopt (eh,
+ CURLOPT_CUSTOMREQUEST,
+ "PUT")) ||
+ (GNUNET_OK !=
+ TALER_curl_easy_post (&dh->ctx,
+ eh,
+ deposit_confirmation_obj)) )
{
GNUNET_break (0);
- curl_easy_cleanup (eh);
+ if (NULL != eh)
+ curl_easy_cleanup (eh);
json_decref (deposit_confirmation_obj);
GNUNET_free (dh->url);
GNUNET_free (dh);
@@ -369,7 +372,7 @@ TALER_AUDITOR_deposit_confirmation (struct TALER_AUDITOR_Handle *auditor,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"URL for deposit-confirmation: `%s'\n",
dh->url);
- ctx = MAH_handle_to_context (auditor);
+ ctx = TALER_AUDITOR_handle_to_context_ (auditor);
dh->job = GNUNET_CURL_job_add2 (ctx,
eh,
dh->ctx.headers,
diff --git a/src/lib/auditor_api_exchanges.c b/src/lib/auditor_api_exchanges.c
index 09bdcc57..329b0106 100644
--- a/src/lib/auditor_api_exchanges.c
+++ b/src/lib/auditor_api_exchanges.c
@@ -201,19 +201,26 @@ TALER_AUDITOR_list_exchanges (struct TALER_AUDITOR_Handle *auditor,
CURL *eh;
GNUNET_assert (GNUNET_YES ==
- MAH_handle_is_ready (auditor));
+ TALER_AUDITOR_handle_is_ready_ (auditor));
leh = GNUNET_new (struct TALER_AUDITOR_ListExchangesHandle);
leh->auditor = auditor;
leh->cb = cb;
leh->cb_cls = cb_cls;
- leh->url = MAH_path_to_url (auditor, "/exchanges");
+ leh->url = TALER_AUDITOR_path_to_url_ (auditor, "/exchanges");
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"URL for list-exchanges: `%s'\n",
leh->url);
- eh = TAL_curl_easy_get (leh->url);
- ctx = MAH_handle_to_context (auditor);
+ eh = TALER_AUDITOR_curl_easy_get_ (leh->url);
+ if (NULL == eh)
+ {
+ GNUNET_break (0);
+ GNUNET_free (leh->url);
+ GNUNET_free (leh);
+ return NULL;
+ }
+ ctx = TALER_AUDITOR_handle_to_context_ (auditor);
leh->job = GNUNET_CURL_job_add (ctx,
eh,
GNUNET_NO,
diff --git a/src/lib/auditor_api_handle.c b/src/lib/auditor_api_handle.c
index 3d953dc5..c0555598 100644
--- a/src/lib/auditor_api_handle.c
+++ b/src/lib/auditor_api_handle.c
@@ -367,7 +367,7 @@ version_completed_cb (void *cls,
* @return ctx context to execute jobs in
*/
struct GNUNET_CURL_Context *
-MAH_handle_to_context (struct TALER_AUDITOR_Handle *h)
+TALER_AUDITOR_handle_to_context_ (struct TALER_AUDITOR_Handle *h)
{
return h->ctx;
}
@@ -380,7 +380,7 @@ MAH_handle_to_context (struct TALER_AUDITOR_Handle *h)
* @return #GNUNET_YES if we are ready, #GNUNET_NO if not
*/
int
-MAH_handle_is_ready (struct TALER_AUDITOR_Handle *h)
+TALER_AUDITOR_handle_is_ready_ (struct TALER_AUDITOR_Handle *h)
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Checking if auditor %p (%s) is now ready: %s\n",
@@ -399,8 +399,8 @@ MAH_handle_is_ready (struct TALER_AUDITOR_Handle *h)
* @return the full URL to use with cURL
*/
char *
-MAH_path_to_url (struct TALER_AUDITOR_Handle *h,
- const char *path)
+TALER_AUDITOR_path_to_url_ (struct TALER_AUDITOR_Handle *h,
+ const char *path)
{
char *ret;
GNUNET_assert ('/' == path[0]);
@@ -473,16 +473,25 @@ request_version (void *cls)
GNUNET_assert (NULL == auditor->vr);
vr = GNUNET_new (struct VersionRequest);
vr->auditor = auditor;
- vr->url = MAH_path_to_url (auditor,
- "/version");
+ vr->url = TALER_AUDITOR_path_to_url_ (auditor,
+ "/version");
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Requesting auditor version with URL `%s'.\n",
vr->url);
- eh = TAL_curl_easy_get (vr->url);
- GNUNET_assert (CURLE_OK ==
- curl_easy_setopt (eh,
- CURLOPT_TIMEOUT,
- (long) 300));
+ eh = TALER_AUDITOR_curl_easy_get_ (vr->url);
+ if (NULL == eh)
+ {
+ GNUNET_break (0);
+ auditor->retry_delay = EXCHANGE_LIB_BACKOFF (auditor->retry_delay);
+ auditor->retry_task = GNUNET_SCHEDULER_add_delayed (auditor->retry_delay,
+ &request_version,
+ auditor);
+ return;
+ }
+ GNUNET_break (CURLE_OK ==
+ curl_easy_setopt (eh,
+ CURLOPT_TIMEOUT,
+ (long) 300));
vr->job = GNUNET_CURL_job_add (auditor->ctx,
eh,
GNUNET_NO,
diff --git a/src/lib/auditor_api_handle.h b/src/lib/auditor_api_handle.h
index 013fe9b0..7ff5bfcd 100644
--- a/src/lib/auditor_api_handle.h
+++ b/src/lib/auditor_api_handle.h
@@ -31,7 +31,7 @@
* @return ctx context to execute jobs in
*/
struct GNUNET_CURL_Context *
-MAH_handle_to_context (struct TALER_AUDITOR_Handle *h);
+TALER_AUDITOR_handle_to_context_ (struct TALER_AUDITOR_Handle *h);
/**
@@ -41,7 +41,7 @@ MAH_handle_to_context (struct TALER_AUDITOR_Handle *h);
* @return #GNUNET_YES if we are ready, #GNUNET_NO if not
*/
int
-MAH_handle_is_ready (struct TALER_AUDITOR_Handle *h);
+TALER_AUDITOR_handle_is_ready_ (struct TALER_AUDITOR_Handle *h);
/**
@@ -52,8 +52,8 @@ MAH_handle_is_ready (struct TALER_AUDITOR_Handle *h);
* @return the full URL to use with cURL
*/
char *
-MAH_path_to_url (struct TALER_AUDITOR_Handle *h,
- const char *path);
+TALER_AUDITOR_path_to_url_ (struct TALER_AUDITOR_Handle *h,
+ const char *path);
/* end of auditor_api_handle.h */
diff --git a/src/lib/exchange_api_curl_defaults.c b/src/lib/exchange_api_curl_defaults.c
index 26c1ac7d..82d3ace1 100644
--- a/src/lib/exchange_api_curl_defaults.c
+++ b/src/lib/exchange_api_curl_defaults.c
@@ -24,8 +24,8 @@
/**
- * Get a curl handle with the right defaults
- * for the exchange lib. In the future, we might manage a pool of connections here.
+ * Get a curl handle with the right defaults for the exchange lib. In the
+ * future, we might manage a pool of connections here.
*
* @param url URL to query
*/
@@ -35,6 +35,8 @@ TALER_EXCHANGE_curl_easy_get_ (const char *url)
CURL *eh;
eh = curl_easy_init ();
+ if (NULL == eh)
+ return NULL;
GNUNET_assert (CURLE_OK ==
curl_easy_setopt (eh,
CURLOPT_URL,
diff --git a/src/lib/exchange_api_deposit.c b/src/lib/exchange_api_deposit.c
index 24b9f6fe..928a378b 100644
--- a/src/lib/exchange_api_deposit.c
+++ b/src/lib/exchange_api_deposit.c
@@ -627,13 +627,15 @@ TALER_EXCHANGE_deposit (struct TALER_EXCHANGE_Handle *exchange,
not copy the pointer */
eh = TALER_EXCHANGE_curl_easy_get_ (dh->url);
- if (GNUNET_OK !=
- TALER_curl_easy_post (&dh->ctx,
- eh,
- deposit_obj))
+ if ( (NULL == eh) ||
+ (GNUNET_OK !=
+ TALER_curl_easy_post (&dh->ctx,
+ eh,
+ deposit_obj)) )
{
GNUNET_break (0);
- curl_easy_cleanup (eh);
+ if (NULL != eh)
+ curl_easy_cleanup (eh);
json_decref (deposit_obj);
GNUNET_free (dh->url);
GNUNET_free (dh);
diff --git a/src/lib/exchange_api_deposits_get.c b/src/lib/exchange_api_deposits_get.c
index 40d86401..bfacd178 100644
--- a/src/lib/exchange_api_deposits_get.c
+++ b/src/lib/exchange_api_deposits_get.c
@@ -367,6 +367,13 @@ TALER_EXCHANGE_deposits_get (struct TALER_EXCHANGE_Handle *exchange,
dwh->depconf.coin_pub = *coin_pub;
eh = TALER_EXCHANGE_curl_easy_get_ (dwh->url);
+ if (NULL == eh)
+ {
+ GNUNET_break (0);
+ GNUNET_free (dwh->url);
+ GNUNET_free (dwh);
+ return NULL;
+ }
ctx = TEAH_handle_to_context (exchange);
dwh->job = GNUNET_CURL_job_add (ctx,
eh,
diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c
index 0d3118bf..ce6ef2e2 100644
--- a/src/lib/exchange_api_handle.c
+++ b/src/lib/exchange_api_handle.c
@@ -1954,14 +1954,22 @@ request_keys (void *cls)
"Requesting keys with URL `%s'.\n",
kr->url);
eh = TALER_EXCHANGE_curl_easy_get_ (kr->url);
- GNUNET_assert (CURLE_OK ==
- curl_easy_setopt (eh,
- CURLOPT_VERBOSE,
- 0));
- GNUNET_assert (CURLE_OK ==
- curl_easy_setopt (eh,
- CURLOPT_TIMEOUT,
- (long) 300));
+ if (NULL == eh)
+ {
+ exchange->retry_delay = EXCHANGE_LIB_BACKOFF (exchange->retry_delay);
+ exchange->retry_task = GNUNET_SCHEDULER_add_delayed (exchange->retry_delay,
+ &request_keys,
+ exchange);
+ return;
+ }
+ GNUNET_break (CURLE_OK ==
+ curl_easy_setopt (eh,
+ CURLOPT_VERBOSE,
+ 0));
+ GNUNET_break (CURLE_OK ==
+ curl_easy_setopt (eh,
+ CURLOPT_TIMEOUT,
+ (long) 300));
GNUNET_assert (CURLE_OK ==
curl_easy_setopt (eh,
CURLOPT_HEADERFUNCTION,
diff --git a/src/lib/exchange_api_link.c b/src/lib/exchange_api_link.c
index e659a41c..aa508ecf 100644
--- a/src/lib/exchange_api_link.c
+++ b/src/lib/exchange_api_link.c
@@ -456,6 +456,13 @@ TALER_EXCHANGE_link (struct TALER_EXCHANGE_Handle *exchange,
lh->url = TEAH_path_to_url (exchange,
arg_str);
eh = TALER_EXCHANGE_curl_easy_get_ (lh->url);
+ if (NULL == eh)
+ {
+ GNUNET_break (0);
+ GNUNET_free (lh->url);
+ GNUNET_free (lh);
+ return NULL;
+ }
ctx = TEAH_handle_to_context (exchange);
lh->job = GNUNET_CURL_job_add (ctx,
eh,
diff --git a/src/lib/exchange_api_melt.c b/src/lib/exchange_api_melt.c
index 5a3abba8..39d9d4e0 100644
--- a/src/lib/exchange_api_melt.c
+++ b/src/lib/exchange_api_melt.c
@@ -457,13 +457,15 @@ TALER_EXCHANGE_melt (struct TALER_EXCHANGE_Handle *exchange,
mh->url = TEAH_path_to_url (exchange,
arg_str);
eh = TALER_EXCHANGE_curl_easy_get_ (mh->url);
- if (GNUNET_OK !=
- TALER_curl_easy_post (&mh->ctx,
- eh,
- melt_obj))
+ if ( (NULL == eh) ||
+ (GNUNET_OK !=
+ TALER_curl_easy_post (&mh->ctx,
+ eh,
+ melt_obj)) )
{
GNUNET_break (0);
- curl_easy_cleanup (eh);
+ if (NULL != eh)
+ curl_easy_cleanup (eh);
json_decref (melt_obj);
GNUNET_free (mh->url);
GNUNET_free (mh);
diff --git a/src/lib/exchange_api_recoup.c b/src/lib/exchange_api_recoup.c
index 013d480b..5a275935 100644
--- a/src/lib/exchange_api_recoup.c
+++ b/src/lib/exchange_api_recoup.c
@@ -390,13 +390,15 @@ TALER_EXCHANGE_recoup (struct TALER_EXCHANGE_Handle *exchange,
arg_str);
ph->was_refreshed = was_refreshed;
eh = TALER_EXCHANGE_curl_easy_get_ (ph->url);
- if (GNUNET_OK !=
- TALER_curl_easy_post (&ph->ctx,
- eh,
- recoup_obj))
+ if ( (NULL == eh) ||
+ (GNUNET_OK !=
+ TALER_curl_easy_post (&ph->ctx,
+ eh,
+ recoup_obj)) )
{
GNUNET_break (0);
- curl_easy_cleanup (eh);
+ if (NULL != eh)
+ curl_easy_cleanup (eh);
json_decref (recoup_obj);
GNUNET_free (ph->url);
GNUNET_free (ph);
diff --git a/src/lib/exchange_api_refreshes_reveal.c b/src/lib/exchange_api_refreshes_reveal.c
index 20e19673..25b937b9 100644
--- a/src/lib/exchange_api_refreshes_reveal.c
+++ b/src/lib/exchange_api_refreshes_reveal.c
@@ -462,13 +462,15 @@ TALER_EXCHANGE_refreshes_reveal (struct TALER_EXCHANGE_Handle *exchange,
arg_str);
eh = TALER_EXCHANGE_curl_easy_get_ (rrh->url);
- if (GNUNET_OK !=
- TALER_curl_easy_post (&rrh->ctx,
- eh,
- reveal_obj))
+ if ( (NULL == eh) ||
+ (GNUNET_OK !=
+ TALER_curl_easy_post (&rrh->ctx,
+ eh,
+ reveal_obj)) )
{
GNUNET_break (0);
- curl_easy_cleanup (eh);
+ if (NULL != eh)
+ curl_easy_cleanup (eh);
json_decref (reveal_obj);
GNUNET_free (rrh->url);
GNUNET_free (rrh);
diff --git a/src/lib/exchange_api_refund.c b/src/lib/exchange_api_refund.c
index 8c50c80b..d14481e7 100644
--- a/src/lib/exchange_api_refund.c
+++ b/src/lib/exchange_api_refund.c
@@ -388,13 +388,15 @@ TALER_EXCHANGE_refund2 (struct TALER_EXCHANGE_Handle *exchange,
refund_fee);
eh = TALER_EXCHANGE_curl_easy_get_ (rh->url);
- if (GNUNET_OK !=
- TALER_curl_easy_post (&rh->ctx,
- eh,
- refund_obj))
+ if ( (NULL == eh) ||
+ (GNUNET_OK !=
+ TALER_curl_easy_post (&rh->ctx,
+ eh,
+ refund_obj)) )
{
GNUNET_break (0);
- curl_easy_cleanup (eh);
+ if (NULL != eh)
+ curl_easy_cleanup (eh);
json_decref (refund_obj);
GNUNET_free (rh->url);
GNUNET_free (rh);
diff --git a/src/lib/exchange_api_reserves_get.c b/src/lib/exchange_api_reserves_get.c
index 37adace5..39932d65 100644
--- a/src/lib/exchange_api_reserves_get.c
+++ b/src/lib/exchange_api_reserves_get.c
@@ -275,6 +275,13 @@ TALER_EXCHANGE_reserves_get (struct TALER_EXCHANGE_Handle *exchange,
rgh->url = TEAH_path_to_url (exchange,
arg_str);
eh = TALER_EXCHANGE_curl_easy_get_ (rgh->url);
+ if (NULL == eh)
+ {
+ GNUNET_break (0);
+ GNUNET_free (rgh->url);
+ GNUNET_free (rgh);
+ return NULL;
+ }
ctx = TEAH_handle_to_context (exchange);
rgh->job = GNUNET_CURL_job_add (ctx,
eh,
diff --git a/src/lib/exchange_api_transfers_get.c b/src/lib/exchange_api_transfers_get.c
index 25a1fea8..589a809e 100644
--- a/src/lib/exchange_api_transfers_get.c
+++ b/src/lib/exchange_api_transfers_get.c
@@ -367,6 +367,13 @@ TALER_EXCHANGE_transfers_get (struct TALER_EXCHANGE_Handle *exchange,
wdh->url = TEAH_path_to_url (wdh->exchange,
arg_str);
eh = TALER_EXCHANGE_curl_easy_get_ (wdh->url);
+ if (NULL == eh)
+ {
+ GNUNET_break (0);
+ GNUNET_free (wdh->url);
+ GNUNET_free (wdh);
+ return NULL;
+ }
ctx = TEAH_handle_to_context (exchange);
wdh->job = GNUNET_CURL_job_add (ctx,
eh,
diff --git a/src/lib/exchange_api_wire.c b/src/lib/exchange_api_wire.c
index 81b9f430..1ac44c70 100644
--- a/src/lib/exchange_api_wire.c
+++ b/src/lib/exchange_api_wire.c
@@ -405,9 +405,16 @@ TALER_EXCHANGE_wire (struct TALER_EXCHANGE_Handle *exchange,
wh->exchange = exchange;
wh->cb = wire_cb;
wh->cb_cls = wire_cb_cls;
- wh->url = TEAH_path_to_url (exchange, "/wire");
-
+ wh->url = TEAH_path_to_url (exchange,
+ "/wire");
eh = TALER_EXCHANGE_curl_easy_get_ (wh->url);
+ if (NULL == eh)
+ {
+ GNUNET_break (0);
+ GNUNET_free (wh->url);
+ GNUNET_free (wh);
+ return NULL;
+ }
ctx = TEAH_handle_to_context (exchange);
wh->job = GNUNET_CURL_job_add (ctx,
eh,
diff --git a/src/lib/exchange_api_withdraw.c b/src/lib/exchange_api_withdraw.c
index 47c05082..85f64523 100644
--- a/src/lib/exchange_api_withdraw.c
+++ b/src/lib/exchange_api_withdraw.c
@@ -427,13 +427,15 @@ reserve_withdraw_internal (struct TALER_EXCHANGE_Handle *exchange,
wh->url = TEAH_path_to_url (exchange,
arg_str);
eh = TALER_EXCHANGE_curl_easy_get_ (wh->url);
- if (GNUNET_OK !=
- TALER_curl_easy_post (&wh->ctx,
- eh,
- withdraw_obj))
+ if ( (NULL == eh) ||
+ (GNUNET_OK !=
+ TALER_curl_easy_post (&wh->ctx,
+ eh,
+ withdraw_obj)) )
{
GNUNET_break (0);
- curl_easy_cleanup (eh);
+ if (NULL != eh)
+ curl_easy_cleanup (eh);
json_decref (withdraw_obj);
GNUNET_free (wh->url);
GNUNET_CRYPTO_rsa_public_key_free (wh->pk.key.rsa_public_key);
diff --git a/src/testing/testing_api_cmd_bank_transfer.c b/src/testing/testing_api_cmd_bank_transfer.c
index 6aa926df..f8dfc0b8 100644
--- a/src/testing/testing_api_cmd_bank_transfer.c
+++ b/src/testing/testing_api_cmd_bank_transfer.c
@@ -76,7 +76,7 @@ struct TransferState
/**
* Handle to the pending request at the fakebank.
*/
- struct TALER_BANK_WireExecuteHandle *weh;
+ struct TALER_BANK_TransferHandle *weh;
/**
* Interpreter state.
@@ -233,15 +233,15 @@ transfer_run (void *cls,
TALER_amount2s (&fts->amount),
fts->account_debit_url,
fts->payto_credit_account);
- TALER_BANK_prepare_wire_transfer (fts->payto_credit_account,
- &fts->amount,
- fts->exchange_base_url,
- &fts->wtid,
- &buf,
- &buf_size);
+ TALER_BANK_prepare_transfer (fts->payto_credit_account,
+ &fts->amount,
+ fts->exchange_base_url,
+ &fts->wtid,
+ &buf,
+ &buf_size);
fts->is = is;
fts->weh
- = TALER_BANK_execute_wire_transfer
+ = TALER_BANK_transfer
(TALER_TESTING_interpreter_get_context (is),
&fts->auth,
buf,
@@ -276,7 +276,7 @@ transfer_cleanup (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Command %s did not complete\n",
cmd->label);
- TALER_BANK_execute_wire_transfer_cancel (fts->weh);
+ TALER_BANK_transfer_cancel (fts->weh);
fts->weh = NULL;
}
if (NULL != fts->retry_task)