aboutsummaryrefslogtreecommitdiff
path: root/src/extensions
diff options
context:
space:
mode:
Diffstat (limited to 'src/extensions')
-rw-r--r--src/extensions/auction_brandt/extension_auction_brandt.c166
1 files changed, 145 insertions, 21 deletions
diff --git a/src/extensions/auction_brandt/extension_auction_brandt.c b/src/extensions/auction_brandt/extension_auction_brandt.c
index a5f3af8c..24ac452b 100644
--- a/src/extensions/auction_brandt/extension_auction_brandt.c
+++ b/src/extensions/auction_brandt/extension_auction_brandt.c
@@ -27,6 +27,8 @@
#include <microhttpd.h>
#define AUCTION_BRANDT "auction_brandt"
+#define LOG_PREFIX "[auction_brandt] "
+#define MAX_RESULT_SIZE 10 * 1024
/* Path to the replay program. */
static char *replay_program;
@@ -77,7 +79,7 @@ json_error (json_t **output,
GNUNET_assert (*output);
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "[auction_brandt] got error: %s\n",
+ LOG_PREFIX "got error: %s\n",
error);
return GNUNET_SYSERR;
@@ -86,6 +88,7 @@ json_error (json_t **output,
/**
* @brief returns an JSON with the result
*/
+#if 0
static enum GNUNET_GenericReturnValue
json_result (json_t **output,
const struct transcript *tr)
@@ -119,6 +122,9 @@ json_result (json_t **output,
}
+#endif
+
+
/*
* @brief Parses a given json as transcript.
*
@@ -126,13 +132,16 @@ json_result (json_t **output,
* @param[out] transcript Parsed transcript data
* @param[out] jresult JSON output, both, for results or errors
* @return GNUNET_OK on succes
+ *
+ * TODO:
+ * - fix leakages
+ * - parse and verify signatures
*/
static enum GNUNET_GenericReturnValue
parse_transcript (const json_t *jtr,
struct transcript *tr,
json_t **output)
{
- // TODO: json_error_t jerror;
// TODO: struct GNUNET_CRYPTO_EddsaSignature sig;
GNUNET_assert (jtr);
@@ -167,7 +176,7 @@ parse_transcript (const json_t *jtr,
if (! json_is_array (prices))
- // TODO: leak!?
+ // TODO: fix leak!?
return json_error (output, "no prices found");
tr->k = json_array_size (prices);
@@ -176,7 +185,7 @@ parse_transcript (const json_t *jtr,
json_array_foreach (prices, idx, val)
{
if (! json_is_string (val))
- // TODO: leak!_
+ // TODO: fix leak!_
return json_error (output, "prices not strings");
tr->prices[idx] = (char *) json_string_value (val);
@@ -192,7 +201,7 @@ parse_transcript (const json_t *jtr,
bidders = json_object_get (jtr, "bidders");
if (! bidders || ! json_is_array (bidders))
- // TODO: leak!_
+ // TODO: fix leak!_
return json_error (output, "bidders not found");
// TODO: parse bidders as pub keys;
@@ -207,14 +216,14 @@ parse_transcript (const json_t *jtr,
messages = json_object_get (jtr, "transcript");
if (! json_is_array (messages))
- // TODO: leak!
+ // TODO: fix leak!
return json_error (output, "no messages found");
nm = json_array_size (messages);
if (nm != (4 * tr->n))
- // TODO: leak!
+ // TODO: fix leak!
return json_error (output, "not the right no. of messages found");
}
@@ -229,7 +238,8 @@ parse_transcript (const json_t *jtr,
if (! json_is_array (winners))
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "winners not provided, continuing without\n");
+ LOG_PREFIX "winners not provided, continuing without\n");
+ // TODO: fix leakage
goto CONT;
}
@@ -255,13 +265,118 @@ parse_transcript (const json_t *jtr,
spec,
(const char**) &error,
NULL))
- // TODO: leak!
+ // TODO: fix leak!
return json_error (output, "couldn't parse winners");
}
CONT:
+ // TODO: fix leakages
+ }
+ *output = NULL;
+ return GNUNET_OK;
+}
+
+
+/**
+ * @brief replay an auction using the external program
+ *
+ * @param[in] root The original JSON transcript
+ * @param[in] transcript The transcript object parsed so far
+ * @param[out] result The JSON result from the program
+ * @return GNUNET_OK on success
+ *
+ * TODO: Make this asynchronous (giving out a replay-ID to poll from)?
+ */
+static enum GNUNET_GenericReturnValue
+replay_transcript (const json_t*root,
+ struct transcript *tr,
+ json_t **result)
+{
+ struct GNUNET_DISK_PipeHandle *pi;
+ struct GNUNET_DISK_PipeHandle *po;
+ const struct GNUNET_DISK_FileHandle *fd;
+ struct GNUNET_OS_Process *proc;
+
+ pi = GNUNET_DISK_pipe (GNUNET_DISK_PF_BLOCKING_WRITE);
+ po = GNUNET_DISK_pipe (GNUNET_DISK_PF_BLOCKING_READ);
+ proc = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ERR,
+ pi, po, NULL,
+ replay_program,
+ replay_program,
+ NULL);
+ if (NULL == proc)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ LOG_PREFIX "couldn't create auction replay program '%s'\n",
+ replay_program);
+
+ return json_error (result, "internal error");
+ }
+
+ // Write original transcript JSON to stdin
+ {
+ ssize_t sz;
+ char *str;
+ size_t str_len;
+
+
+ fd = GNUNET_DISK_pipe_handle (pi, GNUNET_DISK_PIPE_END_WRITE);
+ str = json_dumps (root, JSON_COMPACT);
+ str_len = strlen (str);
+ sz = GNUNET_DISK_file_write (fd,
+ str,
+ str_len);
+ free (str);
+ if (sz != str_len)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ LOG_PREFIX "couldn't write all data to replay_program\n");
+ }
+ }
+
+ // Read output from stdout
+ {
+ ssize_t sz;
+ char buf[MAX_RESULT_SIZE];
+ fd = GNUNET_DISK_pipe_handle (po, GNUNET_DISK_PIPE_END_READ);
+
+ sz = GNUNET_DISK_file_read (fd,
+ buf,
+ sizeof(buf));
+ if (GNUNET_SYSERR == sz)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ LOG_PREFIX "couldn't read data from replay_program\n");
+ }
+ else
+ {
+ json_error_t error;
+ json_t *res;
+ res = json_loads (buf,
+ JSON_DECODE_ANY,
+ &error);
+
+ if (! res)
+ return json_error (result, error.text);
+
+ *result = json_copy (res);
+ json_decref (res);
+ }
}
- return json_result (output, tr);
+
+ if (GNUNET_OK != GNUNET_OS_process_wait (proc))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ LOG_PREFIX "error while launching auction replay program '%s'\n",
+ replay_program);
+
+ json_object_clear (*result);
+ return json_error (result, "internal error");
+ }
+
+
+ // TODO: parse result
+ return GNUNET_OK;
}
@@ -338,7 +453,7 @@ auction_http_get_handler (
/* TODO: return some meta-data about supported version, limits, etc.*/
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "auction_http_get_handler not implemented yet\n");
+ LOG_PREFIX "auction_http_get_handler not implemented yet\n");
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_NOT_IMPLEMENTED,
@@ -359,17 +474,26 @@ auction_http_post_handler (
{
struct transcript tr = {};
enum GNUNET_GenericReturnValue ret;
- json_t *result;
-
- ret = parse_transcript (root, &tr, &result);
-
- /* TODO */
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "auction_http_post_handler not implemented yet\n");
+ json_t *result1;
+ json_t *result2;
+
+ ret = parse_transcript (root,
+ &tr,
+ &result1);
+ if (GNUNET_OK != ret)
+ return TALER_MHD_reply_json_steal (connection,
+ result1,
+ MHD_HTTP_BAD_REQUEST);
+ GNUNET_assert (NULL == result1);
+
+ ret = replay_transcript (root,
+ &tr,
+ &result2);
return TALER_MHD_reply_json_steal (connection,
- result,
- GNUNET_OK == ret? MHD_HTTP_OK :
+ result2,
+ GNUNET_OK == ret?
+ MHD_HTTP_OK :
MHD_HTTP_BAD_REQUEST);
}
@@ -427,7 +551,7 @@ libtaler_extension_auction_brandt_init (void *arg)
}
/* TODO: check if replay_program is actually executable */
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "[auction_brandt] loading... using replay_program '%s'\n",
+ LOG_PREFIX "loading... using replay_program '%s'\n",
replay_program);
return &TE_auction_brandt;