diff options
author | Marcello Stanisci <marcello.stanisci@inria.fr> | 2016-09-26 16:50:57 +0200 |
---|---|---|
committer | Marcello Stanisci <marcello.stanisci@inria.fr> | 2016-09-26 16:50:57 +0200 |
commit | 6d0eb81a357adccd185b631b2793a840d779c162 (patch) | |
tree | 4c7e26fc44e9db4bfd15c8a4a9c5e7f1333da2a3 /src/backend | |
parent | daa8104795567076745f8062a0aaffa0d1eceb0f (diff) | |
parent | a99aa6da2be396404c8469ef2a50509b40917e09 (diff) | |
download | merchant-6d0eb81a357adccd185b631b2793a840d779c162.tar.gz merchant-6d0eb81a357adccd185b631b2793a840d779c162.tar.bz2 merchant-6d0eb81a357adccd185b631b2793a840d779c162.zip |
Merge branch 'receiver'
Conflicts:
src/backend/taler-merchant-httpd.c
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/taler-merchant-httpd.c | 167 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd.h | 4 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_contract.c | 1 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_pay.c | 4 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_track-transaction.c | 19 |
5 files changed, 132 insertions, 63 deletions
diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c index 67f81016..88f9ed50 100644 --- a/src/backend/taler-merchant-httpd.c +++ b/src/backend/taler-merchant-httpd.c @@ -46,10 +46,18 @@ #define UNIX_BACKLOG 500 /** - * NULL-terminated array of all merchants instances known - * by this backend + * Hashmap pointing at merchant instances by 'id'. An 'id' is + * just a string that identifies a merchant instance. When a frontend + * needs to specify an instance to the backend, it does so by 'id' */ -struct MerchantInstance **instances; +struct GNUNET_CONTAINER_MultiHashMap *by_id_map; + +/** + * Hashmap pointing at merchant instances by public key. This map + * is mainly used to check whether there is more than one instance + * using the same key + */ +struct GNUNET_CONTAINER_MultiHashMap *by_kpub_map; /** * The port we are running on @@ -225,6 +233,22 @@ url_handler (void *cls, /** + * Callback that frees all the elements in the hashmap + * + * @param cls closure + * @param key current key + * @param value current value + */ +int +hashmap_free (void *cls, + const struct GNUNET_HashCode *key, + void *value) +{ + GNUNET_free (value); + return GNUNET_YES; +} + +/** * Shutdown task (magically invoked when the application is being * quit) * @@ -250,17 +274,14 @@ do_shutdown (void *cls) } TMH_EXCHANGES_done (); TMH_AUDITORS_done (); - if (NULL != instances) - { - unsigned int i; - for (i=0; NULL != instances[i]; i++) - { - json_decref (instances[i]->j_wire); - GNUNET_free (instances[i]->id); - GNUNET_free (instances[i]); - } - } + GNUNET_CONTAINER_multihashmap_iterate (by_id_map, + &hashmap_free, + NULL); + if (NULL != by_id_map) + GNUNET_CONTAINER_multihashmap_destroy (by_id_map); + if (NULL != by_kpub_map) + GNUNET_CONTAINER_multihashmap_destroy (by_kpub_map); } @@ -403,6 +424,9 @@ instances_iterator_cb (void *cls, struct MerchantInstance *mi; struct IterateInstancesCls *iic; struct GNUNET_CRYPTO_EddsaPrivateKey *pk; + /* used as hashmap keys */ + struct GNUNET_HashCode h_pk; + struct GNUNET_HashCode h_id; iic = cls; substr = strstr (section, "merchant-instance-"); @@ -454,7 +478,11 @@ instances_iterator_cb (void *cls, &mi->pubkey.eddsa_pub); GNUNET_free (pk); - /** To free or not to free **/ + /** + * FIXME: 'token' must NOT be freed, as it is handled by the + * gnunet_configuration facility. OTOH mi->id does need to be freed, + * because it is a duplicate. + */ mi->id = GNUNET_strdup (token + 1); if (0 == strcmp ("default", mi->id)) iic->default_instance = GNUNET_YES; @@ -485,14 +513,52 @@ instances_iterator_cb (void *cls, "Failed to hash wireformat\n"); iic->ret |= GNUNET_SYSERR; } - #if EXTRADEBUG + #define EXTRADEBUG + #ifdef EXTRADEBUGG GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found wireformat instance:\n"); json_dumpf (mi->j_wire, stdout, 0); printf ("\n"); #endif - GNUNET_array_append (instances, iic->current_index, mi); + GNUNET_CRYPTO_hash (mi->id, + strlen(mi->id), + &h_id); + GNUNET_CRYPTO_hash (&mi->pubkey.eddsa_pub, + sizeof (struct GNUNET_CRYPTO_EddsaPublicKey), + &h_pk); + if (GNUNET_OK != + GNUNET_CONTAINER_multihashmap_put (by_id_map, + &h_id, + mi, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to put an entry into the 'by_id' hashmap\n"); + iic->ret |= GNUNET_SYSERR; + } + #ifdef EXTRADEBUG + else { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Added element at %p, by by-id key %s of '%s' in hashmap\n", + mi, + GNUNET_h2s (&h_id), + mi->id); + GNUNET_assert (NULL != GNUNET_CONTAINER_multihashmap_get (by_id_map, + &h_id)); + } + #endif + + if (GNUNET_OK != + GNUNET_CONTAINER_multihashmap_put (by_kpub_map, + &h_pk, + mi, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to put an entry into the 'by_kpub_map' hashmap\n"); + iic->ret |= GNUNET_SYSERR; + } } /** @@ -511,16 +577,29 @@ instances_iterator_cb (void *cls, struct MerchantInstance * get_instance (struct json_t *json) { - unsigned int i; struct json_t *receiver; + const char *receiver_str; + struct GNUNET_HashCode h_receiver; + struct MerchantInstance *ret; + /*FIXME who decrefs receiver?*/ if (NULL == (receiver = json_object_get (json, "receiver"))) receiver = json_string ("default"); - for (i=0; NULL != instances[i]; i++) - if (0 == strcmp (json_string_value (receiver), instances[i]->id)) - return instances[i]; - return NULL; + receiver_str = json_string_value (receiver); + GNUNET_CRYPTO_hash (receiver_str, + strlen (receiver_str), + &h_receiver); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Looking for by-id key %s of '%s' in hashmap\n", + GNUNET_h2s (&h_receiver), + receiver_str); + /* We're fine if that returns NULL, the calling routine knows how + to handle that */ + ret = GNUNET_CONTAINER_multihashmap_get (by_id_map, + &h_receiver); + GNUNET_break (NULL != ret); + return ret; } /** @@ -581,38 +660,6 @@ iterate_instances (const struct GNUNET_CONFIGURATION_Handle *config, GNUNET_PLUGIN_unload (lib_name, iic->plugin); GNUNET_free (lib_name); - GNUNET_array_append (instances, iic->current_index, NULL); - #if EXTRADEBUG - unsigned int i; - for (i=0; NULL != instances[i]; i++) - { - char *hash; - char *priv; - char *pub; - - hash = - GNUNET_STRINGS_data_to_string_alloc (&instances[i]->h_wire, - sizeof (struct GNUNET_HashCode)); - priv = - GNUNET_STRINGS_data_to_string_alloc (&instances[i]->privkey.eddsa_priv, - sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)); - pub = - GNUNET_STRINGS_data_to_string_alloc (&instances[i]->pubkey.eddsa_pub, - sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "instances[%d]: id=%s,\nj_wire=%s,\nj_hash=%s,\npriv=%s,\npub=%s\n", - i, - instances[i]->id, - json_dumps (instances[i]->j_wire, JSON_INDENT (2)), - hash, - priv, - pub); - - GNUNET_free (hash); - GNUNET_free (priv); - GNUNET_free (pub); - } - #endif GNUNET_free (iic); return GNUNET_OK; @@ -666,6 +713,20 @@ run (void *cls, return; } + if (NULL == + (by_id_map = GNUNET_CONTAINER_multihashmap_create(1, GNUNET_NO))) + { + GNUNET_SCHEDULER_shutdown (); + return; + } + + if (NULL == + (by_kpub_map = GNUNET_CONTAINER_multihashmap_create(1, GNUNET_NO))) + { + GNUNET_SCHEDULER_shutdown (); + return; + } + if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (config, "merchant", diff --git a/src/backend/taler-merchant-httpd.h b/src/backend/taler-merchant-httpd.h index 3ea701c0..9c5b5e32 100644 --- a/src/backend/taler-merchant-httpd.h +++ b/src/backend/taler-merchant-httpd.h @@ -46,8 +46,8 @@ struct IterateInstancesCls { /** * Current index in the global array of #MerchantInstance - * types. Used by the callback in order to properly place - * the instance it is parsing + * types. Used by the callback in order to know which index + * is associated to the element being processed. */ unsigned int current_index; diff --git a/src/backend/taler-merchant-httpd_contract.c b/src/backend/taler-merchant-httpd_contract.c index 4dd67dd0..5522acc6 100644 --- a/src/backend/taler-merchant-httpd_contract.c +++ b/src/backend/taler-merchant-httpd_contract.c @@ -259,6 +259,7 @@ MH_handler_contract (struct TMH_RequestHandler *rh, GNUNET_assert (GNUNET_OK == TALER_JSON_hash (jcontract, &contract.h_contract)); + contract.merchant_pub = mi->pubkey; GNUNET_CRYPTO_eddsa_sign (&mi->privkey.eddsa_priv, &contract.purpose, &contract_sig); diff --git a/src/backend/taler-merchant-httpd_pay.c b/src/backend/taler-merchant-httpd_pay.c index 261362c1..bdd67e89 100644 --- a/src/backend/taler-merchant-httpd_pay.c +++ b/src/backend/taler-merchant-httpd_pay.c @@ -922,6 +922,9 @@ MH_handler_pay (struct TMH_RequestHandler *rh, return (GNUNET_NO == res) ? MHD_YES : MHD_NO; } pc->mi = get_instance (root); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "/pay: picked instance %s\n", + pc->mi->id); if (NULL == pc->mi) { @@ -946,6 +949,7 @@ MH_handler_pay (struct TMH_RequestHandler *rh, TALER_amount_hton (&cp.max_fee, &pc->max_fee); cp.h_contract = pc->h_contract; + cp.merchant_pub = pc->mi->pubkey; if (GNUNET_OK != GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_CONTRACT, &cp.purpose, diff --git a/src/backend/taler-merchant-httpd_track-transaction.c b/src/backend/taler-merchant-httpd_track-transaction.c index f36c6908..cb57f71c 100644 --- a/src/backend/taler-merchant-httpd_track-transaction.c +++ b/src/backend/taler-merchant-httpd_track-transaction.c @@ -33,6 +33,11 @@ /** + * Map containing all the known merchant instances + */ +extern struct GNUNET_CONTAINER_MultiHashMap *by_id_map; + +/** * How long to wait before giving up processing with the exchange? */ #define TRACK_TIMEOUT (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)) @@ -767,8 +772,6 @@ coin_cb (void *cls, tcc)); } -extern struct MerchantInstance **instances; - /** * Handle a "/track/transaction" request. * @@ -790,8 +793,8 @@ MH_handler_track_transaction (struct TMH_RequestHandler *rh, unsigned long long transaction_id; const char *str; const char *receiver; - unsigned int i; int ret; + struct GNUNET_HashCode h_receiver; if (NULL == *connection_cls) { @@ -847,12 +850,12 @@ MH_handler_track_transaction (struct TMH_RequestHandler *rh, "receiver"); if (NULL == receiver) receiver = "default"; - + GNUNET_CRYPTO_hash (receiver, + strlen (receiver), + &h_receiver); tctx->mi = NULL; - for (i=0; NULL != instances[i]; i++) - if (0 == strcmp (receiver, instances[i]->id)) - tctx->mi = instances[i]; - + GNUNET_assert (NULL != (tctx->mi = GNUNET_CONTAINER_multihashmap_get (by_id_map, + &h_receiver))); if (NULL == tctx->mi) return TMH_RESPONSE_reply_bad_request (connection, "unknown receiver"); |