From a03ce46d2a3a1448b20b0f3cb2dbabe941e7b826 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Mon, 1 May 2023 23:11:11 +0200 Subject: fix various memory-use issues --- src/backend/taler-merchant-httpd_exchanges.c | 18 ++++- src/backend/taler-merchant-httpd_helper.c | 6 +- ...-httpd_private-post-reserves-ID-authorize-tip.c | 10 +++ .../taler-merchant-httpd_private-post-reserves.c | 21 ++++-- src/backenddb/plugin_merchantdb_postgres.c | 4 +- src/include/taler_merchant_testing_lib.h | 10 +-- src/testing/testing_api_cmd_checkserver.c | 18 ++--- src/testing/testing_api_cmd_post_using_templates.c | 80 ++++++++++++++++------ src/testing/testing_api_cmd_testserver.c | 43 +++++++----- 9 files changed, 148 insertions(+), 62 deletions(-) (limited to 'src') diff --git a/src/backend/taler-merchant-httpd_exchanges.c b/src/backend/taler-merchant-httpd_exchanges.c index df38bca2..f4695184 100644 --- a/src/backend/taler-merchant-httpd_exchanges.c +++ b/src/backend/taler-merchant-httpd_exchanges.c @@ -1191,6 +1191,7 @@ TMH_EXCHANGES_find_exchange (const char *chosen_exchange, GNUNET_CONTAINER_DLL_insert (exchange->fo_head, exchange->fo_tail, fo); + if ( (GNUNET_TIME_absolute_is_past (exchange->first_retry)) && (force_reload || (GNUNET_TIME_absolute_is_past ( @@ -1207,9 +1208,20 @@ TMH_EXCHANGES_find_exchange (const char *chosen_exchange, GNUNET_log (GNUNET_ERROR_TYPE_INFO, "/keys retry forced, waiting until %s\n", GNUNET_TIME_absolute2s (exchange->first_retry)); - exchange->keys_expiration - = TALER_EXCHANGE_check_keys_current (exchange->conn, - TALER_EXCHANGE_CKF_FORCE_DOWNLOAD); + if (NULL == exchange->conn) + { + /* Not connected at all yet */ + exchange->retry_task + = GNUNET_SCHEDULER_add_now (&retry_exchange, + exchange); + } + else + { + /* Use existing connection, but update /keys */ + exchange->keys_expiration + = TALER_EXCHANGE_check_keys_current (exchange->conn, + TALER_EXCHANGE_CKF_FORCE_DOWNLOAD); + } return fo; } diff --git a/src/backend/taler-merchant-httpd_helper.c b/src/backend/taler-merchant-httpd_helper.c index b93cdb12..0e026a87 100644 --- a/src/backend/taler-merchant-httpd_helper.c +++ b/src/backend/taler-merchant-httpd_helper.c @@ -806,11 +806,15 @@ add_matching_account (void *cls, acc = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("payto_uri", payto_uri), + GNUNET_JSON_pack_data_auto ("master_sig", + master_sig), GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_string ("conversion_url", conversion_url)), GNUNET_JSON_pack_array_incref ("credit_restrictions", - (json_t *) credit_restrictions) + (json_t *) credit_restrictions), + GNUNET_JSON_pack_array_incref ("debit_restrictions", + (json_t *) debit_restrictions) ); GNUNET_assert (0 == json_array_append_new (rc->accounts, diff --git a/src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.c b/src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.c index 283321db..3ffac7f3 100644 --- a/src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.c +++ b/src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.c @@ -124,9 +124,19 @@ authorize_tip (const struct TMH_RequestHandler *rh, taler_tip_uri = TMH_make_taler_tip_uri (connection, &tip_id, hc->instance->settings.id); + if (NULL == taler_tip_uri) + { + GNUNET_break_op (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_GENERIC_PARAMETER_MISSING, + "host"); + } tip_status_url = TMH_make_tip_status_url (connection, &tip_id, hc->instance->settings.id); + GNUNET_assert (NULL != tip_status_url); + GNUNET_assert (! GNUNET_TIME_absolute_is_zero (expiration.abs_time)); res = TALER_MHD_REPLY_JSON_PACK ( connection, MHD_HTTP_OK, diff --git a/src/backend/taler-merchant-httpd_private-post-reserves.c b/src/backend/taler-merchant-httpd_private-post-reserves.c index a6008f32..4001badd 100644 --- a/src/backend/taler-merchant-httpd_private-post-reserves.c +++ b/src/backend/taler-merchant-httpd_private-post-reserves.c @@ -229,7 +229,6 @@ handle_exchange (void *cls, } rc->suspended = GNUNET_NO; MHD_resume_connection (rc->connection); - TALER_MHD_daemon_trigger (); /* we resumed, kick MHD */ GNUNET_CONTAINER_DLL_remove (rc_head, rc_tail, rc); @@ -237,18 +236,22 @@ handle_exchange (void *cls, { rc->ec = TALER_EC_MERCHANT_GENERIC_EXCHANGE_TIMEOUT; rc->http_status = MHD_HTTP_GATEWAY_TIMEOUT; + TALER_MHD_daemon_trigger (); /* we resumed, kick MHD */ return; } if (NULL == eh) { rc->ec = TALER_EC_MERCHANT_GENERIC_EXCHANGE_CONNECT_FAILURE; rc->http_status = MHD_HTTP_BAD_GATEWAY; + TALER_MHD_daemon_trigger (); /* we resumed, kick MHD */ return; } if (MHD_HTTP_OK != hr->http_status) { + GNUNET_assert (TALER_EC_NONE != hr->ec); rc->ec = hr->ec; rc->http_status = hr->http_status; + TALER_MHD_daemon_trigger (); /* we resumed, kick MHD */ return; } keys = TALER_EXCHANGE_get_keys (eh); @@ -256,6 +259,7 @@ handle_exchange (void *cls, { rc->ec = TALER_EC_MERCHANT_GENERIC_EXCHANGE_KEYS_FAILURE; rc->http_status = MHD_HTTP_BAD_GATEWAY; + TALER_MHD_daemon_trigger (); /* we resumed, kick MHD */ return; } rc->master_pub = keys->master_pub; @@ -267,17 +271,20 @@ handle_exchange (void *cls, { rc->ec = TALER_EC_GENERIC_DB_FETCH_FAILED; rc->http_status = MHD_HTTP_CONFLICT; + TALER_MHD_daemon_trigger (); /* we resumed, kick MHD */ return; } if (0 == json_array_size (rc->accounts)) { rc->ec = TALER_EC_MERCHANT_PRIVATE_POST_RESERVES_UNSUPPORTED_WIRE_METHOD; rc->http_status = MHD_HTTP_CONFLICT; + TALER_MHD_daemon_trigger (); /* we resumed, kick MHD */ return; } } rc->reserve_expiration = GNUNET_TIME_relative_to_timestamp (keys->reserve_closing_delay); + TALER_MHD_daemon_trigger (); /* we resumed, kick MHD */ } @@ -321,17 +328,13 @@ TMH_private_post_reserves (const struct TMH_RequestHandler *rh, GNUNET_assert (NULL != mi); if (NULL == rc) { - rc = GNUNET_new (struct PostReserveContext); rc->connection = connection; rc->hc = hc; - rc->accounts = json_array (); - GNUNET_assert (NULL != rc->accounts); hc->ctx = rc; hc->cc = &reserve_context_cleanup; { - enum GNUNET_GenericReturnValue res; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_string ("exchange_url", &rc->exchange_url), @@ -342,6 +345,8 @@ TMH_private_post_reserves (const struct TMH_RequestHandler *rh, &rc->initial_balance), GNUNET_JSON_spec_end () }; + enum GNUNET_GenericReturnValue res; + res = TALER_MHD_parse_json_data (connection, hc->request_body, spec); @@ -375,6 +380,8 @@ TMH_private_post_reserves (const struct TMH_RequestHandler *rh, NULL); } GNUNET_assert (GNUNET_NO == rc->suspended); + GNUNET_assert (! GNUNET_TIME_absolute_is_zero ( + rc->reserve_expiration.abs_time)); { struct TALER_ReservePublicKeyP reserve_pub; struct TALER_ReservePrivateKeyP reserve_priv; @@ -406,8 +413,8 @@ TMH_private_post_reserves (const struct TMH_RequestHandler *rh, MHD_HTTP_OK, GNUNET_JSON_pack_data_auto ("reserve_pub", &reserve_pub), - GNUNET_JSON_pack_array_steal ("accounts", - rc->accounts)); + GNUNET_JSON_pack_array_incref ("accounts", + rc->accounts)); } } diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c index baaad568..c7ffe2a5 100644 --- a/src/backenddb/plugin_merchantdb_postgres.c +++ b/src/backenddb/plugin_merchantdb_postgres.c @@ -5336,7 +5336,9 @@ lookup_reserve_for_tip_cb (void *cls, continue; } if ( (! GNUNET_TIME_absolute_is_never (lac->expiration.abs_time)) && - GNUNET_TIME_timestamp_cmp (expiration, >, lac->expiration) && + GNUNET_TIME_timestamp_cmp (expiration, + >, + lac->expiration) && GNUNET_TIME_relative_cmp ( GNUNET_TIME_absolute_get_remaining (lac->expiration.abs_time), >, diff --git a/src/include/taler_merchant_testing_lib.h b/src/include/taler_merchant_testing_lib.h index 89c90cf9..c860baf2 100644 --- a/src/include/taler_merchant_testing_lib.h +++ b/src/include/taler_merchant_testing_lib.h @@ -1903,11 +1903,11 @@ TALER_TESTING_cmd_checkserver2 (const char *label, op (paths, const char *) \ op (payto_uris, const char *) \ op (amounts, const struct TALER_Amount) \ - op (urls, char *) \ - op (http_methods, char *) \ - op (http_header, char *) \ - op (http_body, void *) \ - op (http_body_size, size_t) \ + op (urls, const char *) \ + op (http_methods, const char *) \ + op (http_header, const char *) \ + op (http_body, const void *) \ + op (http_body_size, const size_t) \ op (planchet_secrets, const struct TALER_PlanchetMasterSecretP) diff --git a/src/testing/testing_api_cmd_checkserver.c b/src/testing/testing_api_cmd_checkserver.c index aa75e374..39df54f6 100644 --- a/src/testing/testing_api_cmd_checkserver.c +++ b/src/testing/testing_api_cmd_checkserver.c @@ -79,6 +79,7 @@ struct CheckState }; + /** * Run the command. * @@ -93,11 +94,11 @@ checkserver_run (void *cls, { struct CheckState *cs = cls; const struct TALER_TESTING_Command *ref; - char **url; - char **http_method; - char **header; - void **body; - size_t *body_size; + const char **url; + const char **http_method; + const char **header; + const void **body; + const size_t *body_size; (void) cmd; cs->is = is; @@ -181,8 +182,10 @@ checkserver_run (void *cls, cs->index, &body_size)) TALER_TESTING_interpreter_fail (is); - if ( ( (NULL == cs->expected_body) && (NULL != *body)) || - ( (NULL != cs->expected_body) && (NULL == body)) || + if ( ( (NULL == cs->expected_body) && + (NULL != *body) ) || + ( (NULL != cs->expected_body) && + (NULL == body) ) || ( (NULL != cs->expected_body) && ( (*body_size != strlen (cs->expected_body)) || (0 != memcmp (cs->expected_body, @@ -197,7 +200,6 @@ checkserver_run (void *cls, TALER_TESTING_interpreter_fail (is); return; } - TALER_TESTING_interpreter_next (is); } diff --git a/src/testing/testing_api_cmd_post_using_templates.c b/src/testing/testing_api_cmd_post_using_templates.c index e0c9c2e1..38743281 100644 --- a/src/testing/testing_api_cmd_post_using_templates.c +++ b/src/testing/testing_api_cmd_post_using_templates.c @@ -28,7 +28,6 @@ #include "taler_merchant_testing_lib.h" - /** * State of a "POST /templates" CMD. */ @@ -80,7 +79,7 @@ struct PostUsingTemplatesState /** * Order id. */ - const char *order_id; + char *order_id; /** * The order id we expect the merchant to assign (if not NULL). @@ -163,10 +162,10 @@ struct PostUsingTemplatesState */ static void using_claim_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, - const json_t *contract_terms, - const struct TALER_MerchantSignatureP *sig, - const struct TALER_PrivateContractHashP *hash) + const struct TALER_MERCHANT_HttpResponse *hr, + const json_t *contract_terms, + const struct TALER_MerchantSignatureP *sig, + const struct TALER_PrivateContractHashP *hash) { struct PostUsingTemplatesState *tis = cls; struct TALER_MerchantPublicKeyP merchant_pub; @@ -403,7 +402,7 @@ post_using_templates_traits (void *cls, { struct PostUsingTemplatesState *pts = cls; struct TALER_TESTING_Trait traits[] = { - TALER_TESTING_make_trait_order_id (&pts->order_id), + TALER_TESTING_make_trait_order_id ((const char **) &pts->order_id), TALER_TESTING_make_trait_contract_terms (pts->contract_terms), TALER_TESTING_make_trait_order_terms (pts->order_terms), TALER_TESTING_make_trait_h_contract_terms (&pts->h_contract_terms), @@ -443,6 +442,9 @@ post_using_templates_cleanup (void *cls, "POST /using-templates operation did not complete\n"); TALER_MERCHANT_using_templates_post_cancel (tis->iph); } + json_decref (tis->order_terms); + json_decref (tis->contract_terms); + GNUNET_free (tis->order_id); GNUNET_free (tis); } @@ -484,22 +486,58 @@ make_order_json (const char *using_template_id, struct GNUNET_TIME_Timestamp refund = refund_deadline; struct GNUNET_TIME_Timestamp pay = pay_deadline; json_t *contract_terms; + struct TALER_Amount tamount; + json_t *arr; + if (NULL != amount) + GNUNET_assert (GNUNET_OK == + TALER_string_to_amount (amount, + &tamount)); /* Include required fields and some dummy objects to test forgetting. */ - contract_terms = json_pack ( - "{s:s, s:s?, s:s, s:s, s:o, s:o, s:s, s:[{s:s}, {s:s}, {s:s}]}", - "summary", "merchant-lib testcase", - "using_template_id", using_template_id, - "amount", amount, - "fulfillment_url", "https://example.com", - "refund_deadline", GNUNET_JSON_from_timestamp (refund), - "pay_deadline", GNUNET_JSON_from_timestamp (pay), - "dummy_obj", "EUR:1.0", - "dummy_array", /* For testing forgetting parts of arrays */ - "item", "speakers", - "item", "headphones", - "item", "earbuds" - ); + arr = json_array (); + GNUNET_assert (NULL != arr); + GNUNET_assert (0 == + json_array_append_new ( + arr, + GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ( + "item", "speakers")))); + GNUNET_assert (0 == + json_array_append_new ( + arr, + GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ( + "item", "headphones")))); + GNUNET_assert (0 == + json_array_append_new ( + arr, + GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ( + "item", "earbuds")))); + contract_terms = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ("summary", + "merchant-lib testcase"), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ( + "using_template_id", using_template_id)), + NULL == amount + ? GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ("amount", + NULL)) + : TALER_JSON_pack_amount ("amount", + &tamount), + GNUNET_JSON_pack_string ("fulfillment_url", + "https://example.com"), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_timestamp ("refund_deadline", + refund)), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_timestamp ("pay_deadline", + pay)), + GNUNET_JSON_pack_string ("dummy_obj", + "EUR:1.0"), + GNUNET_JSON_pack_array_steal ("dummy_array", + arr)); GNUNET_assert (GNUNET_OK == TALER_JSON_expand_path (contract_terms, "$.dummy_obj", diff --git a/src/testing/testing_api_cmd_testserver.c b/src/testing/testing_api_cmd_testserver.c index ee32fd77..e80dcd78 100644 --- a/src/testing/testing_api_cmd_testserver.c +++ b/src/testing/testing_api_cmd_testserver.c @@ -47,8 +47,15 @@ struct TestserverState */ uint16_t port; + /** + * Array where we remember all of the requests this + * server answered. + */ struct RequestCtx **rcs; + /** + * Length of the @a rcs array + */ unsigned int rcs_length; }; @@ -80,6 +87,9 @@ struct RequestCtx */ size_t body_size; + /** + * Set to true when we are done with the request. + */ bool done; }; @@ -150,7 +160,7 @@ handler_cb (void *cls, "Taler-test-header"); if (NULL != hdr) rc->header = GNUNET_strdup (hdr); - if (NULL != hdr) + if (NULL != url) rc->url = GNUNET_strdup (url); GNUNET_array_append (ts->rcs, ts->rcs_length, @@ -195,9 +205,6 @@ handler_cb (void *cls, rc->body = body; rc->body_size += *upload_data_size; *upload_data_size = 0; - GNUNET_array_append (ts->rcs, - ts->rcs_length, - rc); return MHD_YES; } @@ -276,28 +283,30 @@ testserver_cleanup (void *cls, struct TestserverState *ser = cls; (void) cmd; + if (NULL != ser->mhd) + { + MHD_stop_daemon (ser->mhd); + ser->mhd = NULL; + } for (unsigned int i = 0; ircs_length; i++) { struct RequestCtx *rc = ser->rcs[i]; + GNUNET_assert (rc->done); GNUNET_free (rc->url); GNUNET_free (rc->http_method); GNUNET_free (rc->header); GNUNET_free (rc->body); + GNUNET_free (rc); } GNUNET_array_grow (ser->rcs, ser->rcs_length, 0); - if (NULL != ser->mhd) - { - MHD_stop_daemon (ser->mhd); - ser->mhd = NULL; - } GNUNET_free (ser); } -static int +static enum GNUNET_GenericReturnValue traits_testserver (void *cls, const void **ret, const char *trait, @@ -306,24 +315,26 @@ traits_testserver (void *cls, struct TestserverState *ser = cls; if (index >= ser->rcs_length) - return MHD_NO; + return GNUNET_NO; { - struct RequestCtx *rc = ser->rcs[index]; + const struct RequestCtx *rc = ser->rcs[index]; struct TALER_TESTING_Trait traits[] = { TALER_TESTING_make_trait_urls (index, - &rc->url), + (const char **) &rc->url), TALER_TESTING_make_trait_http_methods (index, - &rc->http_method), + (const char **) &rc->http_method), TALER_TESTING_make_trait_http_header (index, - &rc->header), + (const char **) &rc->header), TALER_TESTING_make_trait_http_body (index, - &rc->body), + (const void **) &rc->body), TALER_TESTING_make_trait_http_body_size (index, &rc->body_size), TALER_TESTING_trait_end (), }; + if (! rc->done) + return GNUNET_NO; return TALER_TESTING_get_trait (traits, ret, trait, -- cgit v1.2.3