summaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorMarcello Stanisci <marcello.stanisci@inria.fr>2016-09-26 16:50:57 +0200
committerMarcello Stanisci <marcello.stanisci@inria.fr>2016-09-26 16:50:57 +0200
commit6d0eb81a357adccd185b631b2793a840d779c162 (patch)
tree4c7e26fc44e9db4bfd15c8a4a9c5e7f1333da2a3 /src/backend
parentdaa8104795567076745f8062a0aaffa0d1eceb0f (diff)
parenta99aa6da2be396404c8469ef2a50509b40917e09 (diff)
downloadmerchant-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.c167
-rw-r--r--src/backend/taler-merchant-httpd.h4
-rw-r--r--src/backend/taler-merchant-httpd_contract.c1
-rw-r--r--src/backend/taler-merchant-httpd_pay.c4
-rw-r--r--src/backend/taler-merchant-httpd_track-transaction.c19
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");