* guaranteed minimum number of homomorphic operations with this ciphertext
*/
int32_t remaining_ops GNUNET_PACKED;
-
+
/**
* The bits of the ciphertext.
*/
* @param m Plaintext to encrypt.
* @param desired_ops How many homomorphic ops the caller intends to use
* @param[out] ciphertext Encrytion of @a plaintext with @a public_key.
- * @return guaranteed number of supported homomorphic operations >= 1,
+ * @return guaranteed number of supported homomorphic operations >= 1,
* or desired_ops, in case that is lower,
* or -1 if less than one homomorphic operation is possible
*/
/**
- * Get the number of remaining supported homomorphic operations.
+ * Get the number of remaining supported homomorphic operations.
*
* @param c Paillier cipher text.
* @return the number of remaining homomorphic operations
/*
This file is part of GNUnet.
- (C) 2013 Christian Grothoff (and other contributing authors)
+ (C) 2013, 2014 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
/**
* Version of the scalarproduct API.
*/
-#define GNUNET_SCALARPRODUCT_VERSION 0x00000043
+#define GNUNET_SCALARPRODUCT_VERSION 0x00000044
+/**
+ * Result status values for the computation.
+ */
enum GNUNET_SCALARPRODUCT_ResponseStatus
{
+ /**
+ * The computation was successful.
+ */
GNUNET_SCALARPRODUCT_Status_Success = 0,
+
+ /**
+ * We encountered some error.
+ */
GNUNET_SCALARPRODUCT_Status_Failure,
+
+ /**
+ * We got an invalid response.
+ */
GNUNET_SCALARPRODUCT_Status_InvalidResponse,
+
+ /**
+ * We got disconnected from the SCALARPRODUCT service.
+ */
GNUNET_SCALARPRODUCT_Status_ServiceDisconnected
};
*/
struct GNUNET_SCALARPRODUCT_Handle;
+
+GNUNET_NETWORK_STRUCT_BEGIN
+
/**
* An element key-value pair for scalarproduct
*/
-struct GNUNET_SCALARPRODUCT_Element {
- int32_t value;
- struct GNUNET_HashCode key;
+struct GNUNET_SCALARPRODUCT_Element
+{
+ /**
+ * Key used to identify matching pairs of values to multiply.
+ */
+ struct GNUNET_HashCode key;
+
+ /**
+ * Value to multiply in scalar product.
+ */
+ int64_t value GNUNET_PACKED;
};
+GNUNET_NETWORK_STRUCT_END
+
/**
* Continuation called to notify client about result of the
* @param cls closure
* @param status Status of the request
*/
-typedef void (*GNUNET_SCALARPRODUCT_ContinuationWithStatus) (void *cls,
- enum GNUNET_SCALARPRODUCT_ResponseStatus status);
+typedef void
+(*GNUNET_SCALARPRODUCT_ContinuationWithStatus) (void *cls,
+ enum GNUNET_SCALARPRODUCT_ResponseStatus status);
/**
* @param status Status of the request
* @param result result of the computation
*/
-typedef void (*GNUNET_SCALARPRODUCT_DatumProcessor) (void *cls,
- enum GNUNET_SCALARPRODUCT_ResponseStatus status,
- gcry_mpi_t result);
+typedef void
+(*GNUNET_SCALARPRODUCT_DatumProcessor) (void *cls,
+ enum GNUNET_SCALARPRODUCT_ResponseStatus status,
+ gcry_mpi_t result);
+
/**
* Entry in the request queue per client
*/
struct GNUNET_SCALARPRODUCT_ComputationHandle;
+
/**
* Request by Alice's client for computing a scalar product
*
* @param session_key Session key should be unique to the requesting client
* @param peer PeerID of the other peer
* @param elements Array of elements of the vector
- * @param element_count Number of elements in the vector
+ * @param element_count Number of elements in the @a elements vector
* @param cont Callback function
- * @param cont_cls Closure for the callback function
- *
+ * @param cont_cls Closure for the @a cont callback function
* @return a new handle for this computation
*/
struct GNUNET_SCALARPRODUCT_ComputationHandle *
-GNUNET_SCALARPRODUCT_start_computation (const struct GNUNET_CONFIGURATION_Handle * cfg,
- const struct GNUNET_HashCode * session_key,
+GNUNET_SCALARPRODUCT_start_computation (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const struct GNUNET_HashCode *session_key,
const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_SCALARPRODUCT_Element * elements,
+ const struct GNUNET_SCALARPRODUCT_Element *elements,
uint32_t element_count,
GNUNET_SCALARPRODUCT_DatumProcessor cont,
- void * cont_cls);
+ void *cont_cls);
+
/**
* Used by Bob's client to cooperate with Alice,
* @param cfg the gnunet configuration handle
* @param session_key Session key unique to the requesting client
* @param elements Array of elements of the vector
- * @param element_count Number of elements in the vector
+ * @param element_count Number of elements in the @a elements vector
* @param cont Callback function
- * @param cont_cls Closure for the callback function
- *
+ * @param cont_cls Closure for the @a cont callback function
* @return a new handle for this computation
*/
struct GNUNET_SCALARPRODUCT_ComputationHandle *
-GNUNET_SCALARPRODUCT_accept_computation (const struct GNUNET_CONFIGURATION_Handle * cfg,
- const struct GNUNET_HashCode * key,
- const struct GNUNET_SCALARPRODUCT_Element * elements,
- uint32_t element_count,
- GNUNET_SCALARPRODUCT_ContinuationWithStatus cont,
- void * cont_cls);
+GNUNET_SCALARPRODUCT_accept_computation (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const struct GNUNET_HashCode *key,
+ const struct GNUNET_SCALARPRODUCT_Element *elements,
+ uint32_t element_count,
+ GNUNET_SCALARPRODUCT_ContinuationWithStatus cont,
+ void *cont_cls);
/**
_ ("Need elements to compute the vectorproduct, got none.\n"));
return;
}
-
- elements = (struct GNUNET_SCALARPRODUCT_Element *)
+
+ elements = (struct GNUNET_SCALARPRODUCT_Element *)
GNUNET_malloc(sizeof(struct GNUNET_SCALARPRODUCT_Element)*element_count);
-
+
for (i = 0; i < element_count;i++)
{
struct GNUNET_SCALARPRODUCT_Element element;
char* separator=NULL;
-
+
// get the length of the current key,value; tupel
for (end = begin; *end != ';'; end++)
if (*end == ',')
separator = end;
-
+
// final element
- if ((NULL == separator)
+ if ((NULL == separator)
|| (begin == separator)
|| (separator == end - 1 )) {
LOG (GNUNET_ERROR_TYPE_ERROR,
GNUNET_free(elements);
return;
}
-
+
// read the element's key
*separator = 0;
GNUNET_CRYPTO_hash (begin, strlen (begin), &element.key);
-
+
// read the element's value
- if (1 != sscanf (separator+1, "%" SCNd32 ";", &element.value))
+ if (1 != sscanf (separator+1, "%" SCNd64 ";", &element.value))
{
LOG (GNUNET_ERROR_TYPE_ERROR,
- _ ("Could not convert `%s' to int32_t.\n"), begin);
+ _ ("Could not convert `%s' to int64_t.\n"), begin);
GNUNET_free(elements);
return;
}
-
+
elements[i]=element;
begin = end+1;
}
#define LOG(kind,...) GNUNET_log_from (kind, "scalarproduct", __VA_ARGS__)
-///////////////////////////////////////////////////////////////////////////////
-// Service Structure Definitions
-///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Maximum count of elements we can put into a multipart message
+ */
+#define MULTIPART_ELEMENT_CAPACITY ((GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - sizeof (struct MultipartMessage)) / sizeof (struct GNUNET_CRYPTO_PaillierCiphertext))
+
+
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * Message type passed from requesting service Alice to responding
+ * service Bob to initiate a request and make Bob participate in our
+ * protocol
+ */
+struct ServiceRequestMessage
+{
+ /**
+ * GNUNET message header
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * the transaction/session key used to identify a session
+ */
+ struct GNUNET_HashCode session_id;
+
+ /**
+ * Alice's public key
+ */
+ struct GNUNET_CRYPTO_PaillierPublicKey public_key;
+
+};
+
+
+/**
+ * FIXME.
+ */
+struct AliceCryptodataMessage
+{
+ /**
+ * GNUNET message header
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * how many elements we appended to this message
+ */
+ uint32_t contained_element_count GNUNET_PACKED;
+
+ /**
+ * struct GNUNET_CRYPTO_PaillierCiphertext[contained_element_count]
+ */
+};
+
+
+/**
+ * Multipart Message type passed between to supply additional elements
+ * for the peer
+ */
+struct MultipartMessage
+{
+ /**
+ * GNUNET message header
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * how many elements we supply within this message
+ */
+ uint32_t contained_element_count GNUNET_PACKED;
+
+ // struct GNUNET_CRYPTO_PaillierCiphertext[multipart_element_count]
+};
+
+
+/**
+ * Message type passed from responding service Bob to responding service Alice
+ * to complete a request and allow Alice to compute the result
+ */
+struct ServiceResponseMessage
+{
+ /**
+ * GNUNET message header
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * how many elements the session input had
+ */
+ uint32_t total_element_count GNUNET_PACKED;
+
+ /**
+ * how many elements were included after the mask was applied
+ * including all multipart msgs.
+ */
+ uint32_t used_element_count GNUNET_PACKED;
+
+ /**
+ * how many elements this individual message delivers
+ */
+ uint32_t contained_element_count GNUNET_PACKED;
+
+ /**
+ * the transaction/session key used to identify a session
+ */
+ struct GNUNET_HashCode key;
+
+ /**
+ * followed by s | s' | k[i][perm]
+ */
+};
+
+GNUNET_NETWORK_STRUCT_END
/**
const struct GNUNET_SCHEDULER_TaskContext * tc)
{
struct ServiceSession * s = cls;
- struct GNUNET_SCALARPRODUCT_client_response * msg;
+ struct ClientResponseMessage * msg;
s->client_notification_task = GNUNET_SCHEDULER_NO_TASK;
- msg = GNUNET_new (struct GNUNET_SCALARPRODUCT_client_response);
+ msg = GNUNET_new (struct ClientResponseMessage);
+ msg->header.size = htons (sizeof (struct ClientResponseMessage));
msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_RESULT);
- memcpy (&msg->key, &s->session_id, sizeof (struct GNUNET_HashCode));
- memcpy (&msg->peer, &s->peer, sizeof ( struct GNUNET_PeerIdentity));
- msg->header.size = htons (sizeof (struct GNUNET_SCALARPRODUCT_client_response));
// signal error if not signalized, positive result-range field but zero length.
msg->product_length = htonl (0);
msg->status = htonl(s->active);
s->msg = &msg->header;
//transmit this message to our client
- s->client_transmit_handle =
- GNUNET_SERVER_notify_transmit_ready (s->client,
- sizeof (struct GNUNET_SCALARPRODUCT_client_response),
- GNUNET_TIME_UNIT_FOREVER_REL,
- &cb_transfer_message,
- s);
+ s->client_transmit_handle
+ = GNUNET_SERVER_notify_transmit_ready (s->client,
+ sizeof (struct ClientResponseMessage),
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ &cb_transfer_message,
+ s);
// if we could not even queue our request, something is wrong
- if (NULL == s->client_transmit_handle) {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Could not send message to client (%p)!\n"), s->client);
+ if (NULL == s->client_transmit_handle)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ _("Could not send message to client (%p)!\n"), s->client);
GNUNET_SERVER_client_disconnect(s->client);
free_session_variables(s);
GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, s);
GNUNET_free(s);
}
else
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Sending session-end notification to client (%p) for session %s\n"), &s->client, GNUNET_h2s (&s->session_id));
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ _("Sending session-end notification to client (%p) for session %s\n"),
+ s->client,
+ GNUNET_h2s (&s->session_id));
}
prepare_alices_cyrptodata_message (void *cls)
{
struct ServiceSession * s = cls;
- struct GNUNET_SCALARPRODUCT_alices_cryptodata_message * msg;
+ struct AliceCryptodataMessage * msg;
struct GNUNET_CRYPTO_PaillierCiphertext * payload;
unsigned int i;
uint32_t msg_length;
gcry_mpi_t a;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Successfully created new channel to peer (%s)!\n"), GNUNET_i2s (&s->peer));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ _ ("Successfully created new channel to peer (%s)!\n"),
+ GNUNET_i2s (&s->peer));
- msg_length = sizeof (struct GNUNET_SCALARPRODUCT_alices_cryptodata_message)
+ msg_length = sizeof (struct AliceCryptodataMessage)
+s->used_element_count * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext);
if (GNUNET_SERVER_MAX_MESSAGE_SIZE > msg_length) {
}
else {
//create a multipart msg, first we calculate a new msg size for the head msg
- s->transferred_element_count = (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - sizeof (struct GNUNET_SCALARPRODUCT_alices_cryptodata_message))
+ s->transferred_element_count = (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - sizeof (struct AliceCryptodataMessage))
/ sizeof (struct GNUNET_CRYPTO_PaillierCiphertext);
- msg_length = sizeof (struct GNUNET_SCALARPRODUCT_alices_cryptodata_message)
+ msg_length = sizeof (struct AliceCryptodataMessage)
+s->transferred_element_count * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext);
}
{
struct ServiceSession * s = cls;
struct GNUNET_CRYPTO_PaillierCiphertext * payload;
- struct GNUNET_SCALARPRODUCT_multipart_message * msg;
+ struct MultipartMessage * msg;
unsigned int i;
unsigned int j;
uint32_t msg_length;
uint32_t todo_count;
- msg_length = sizeof (struct GNUNET_SCALARPRODUCT_multipart_message);
+ msg_length = sizeof (struct MultipartMessage);
todo_count = s->used_element_count - s->transferred_element_count;
if (todo_count > MULTIPART_ELEMENT_CAPACITY / 2)
const struct GNUNET_SCHEDULER_TaskContext
* tc)
{
- struct ServiceSession * s = (struct ServiceSession *) cls;
- struct GNUNET_SCALARPRODUCT_service_response * msg;
+ struct ServiceSession * s = cls;
+ struct ServiceResponseMessage * msg;
uint32_t msg_length = 0;
struct GNUNET_CRYPTO_PaillierCiphertext * payload;
int i;
- msg_length = sizeof (struct GNUNET_SCALARPRODUCT_service_response)
+ msg_length = sizeof (struct ServiceResponseMessage)
+ 2 * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext); // s, stick
if (GNUNET_SERVER_MAX_MESSAGE_SIZE >
* @param request the requesting session + bob's requesting peer
*/
static void
-compute_service_response (struct ServiceSession * session)
+compute_service_response (struct ServiceSession *session)
{
int i;
unsigned int * p;
struct ServiceSession * s = (struct ServiceSession*) cls;
struct SortedValue * e = GNUNET_new (struct SortedValue);
struct SortedValue * o = s->a_head;
+ int64_t val;
e->elem = value;
e->val = gcry_mpi_new (0);
- if (0 > e->elem->value)
- gcry_mpi_sub_ui (e->val, e->val, abs (e->elem->value));
+ val = (int64_t) GNUNET_ntohll (e->elem->value);
+ if (0 > val)
+ gcry_mpi_sub_ui (e->val, e->val, - val);
else
- gcry_mpi_add_ui (e->val, e->val, e->elem->value);
+ gcry_mpi_add_ui (e->val, e->val, val);
// insert as first element with the lowest key
if (NULL == s->a_head
const struct GNUNET_SCHEDULER_TaskContext *tc)
{
struct ServiceSession * s = cls;
- struct GNUNET_SCALARPRODUCT_client_response * msg;
+ struct ClientResponseMessage *msg;
unsigned char * product_exported = NULL;
size_t product_length = 0;
uint32_t msg_length = 0;
gcry_mpi_release (value);
}
- msg_length = sizeof (struct GNUNET_SCALARPRODUCT_client_response) +product_length;
+ msg_length = sizeof (struct ClientResponseMessage) + product_length;
msg = GNUNET_malloc (msg_length);
- msg->key = s->session_id;
- msg->peer = s->peer;
if (product_exported != NULL) {
memcpy (&msg[1], product_exported, product_length);
GNUNET_free (product_exported);
static void
prepare_alices_computation_request (struct ServiceSession * s)
{
- struct GNUNET_SCALARPRODUCT_service_request * msg;
+ struct ServiceRequestMessage * msg;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Successfully created new channel to peer (%s)!\n"), GNUNET_i2s (&s->peer));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ _("Successfully created new channel to peer (%s)!\n"),
+ GNUNET_i2s (&s->peer));
- msg = GNUNET_new (struct GNUNET_SCALARPRODUCT_service_request);
+ msg = GNUNET_new (struct ServiceRequestMessage);
msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ALICE_CRYPTODATA);
memcpy (&msg->session_id, &s->session_id, sizeof (struct GNUNET_HashCode));
- msg->header.size = htons (sizeof (struct GNUNET_SCALARPRODUCT_service_request));
+ msg->header.size = htons (sizeof (struct ServiceRequestMessage));
s->msg = (struct GNUNET_MessageHeader *) msg;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Transmitting service request.\n"));
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ _("Transmitting service request.\n"));
//transmit via cadet messaging
- s->service_transmit_handle = GNUNET_CADET_notify_transmit_ready (s->channel, GNUNET_YES,
- GNUNET_TIME_UNIT_FOREVER_REL,
- sizeof (struct GNUNET_SCALARPRODUCT_service_request),
- &cb_transfer_message,
- s);
+ s->service_transmit_handle
+ = GNUNET_CADET_notify_transmit_ready (s->channel, GNUNET_YES,
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ sizeof (struct ServiceRequestMessage),
+ &cb_transfer_message,
+ s);
if (!s->service_transmit_handle) {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _ ("Could not send message to channel!\n"));
+ _("Could not send message to channel!\n"));
GNUNET_free (msg);
s->msg = NULL;
s->active = GNUNET_SYSERR;
prepare_alices_cyrptodata_message_multipart (void *cls)
{
struct ServiceSession * s = cls;
- struct GNUNET_SCALARPRODUCT_multipart_message * msg;
+ struct MultipartMessage * msg;
struct GNUNET_CRYPTO_PaillierCiphertext * payload;
unsigned int i;
uint32_t msg_length;
uint32_t todo_count;
gcry_mpi_t a;
- msg_length = sizeof (struct GNUNET_SCALARPRODUCT_multipart_message);
+ msg_length = sizeof (struct MultipartMessage);
todo_count = s->used_element_count - s->transferred_element_count;
if (todo_count > MULTIPART_ELEMENT_CAPACITY)
struct GNUNET_SERVER_Client *client,
const struct GNUNET_MessageHeader *message)
{
- const struct GNUNET_SCALARPRODUCT_computation_message_multipart * msg = (const struct GNUNET_SCALARPRODUCT_computation_message_multipart *) message;
+ const struct ComputationMultipartMessage * msg = (const struct ComputationMultipartMessage *) message;
struct ServiceSession * s;
uint32_t contained_count;
struct GNUNET_SCALARPRODUCT_Element * elements;
contained_count = ntohl (msg->element_count_contained);
//sanity check: is the message as long as the message_count fields suggests?
- if ((ntohs (msg->header.size) != (sizeof (struct GNUNET_SCALARPRODUCT_computation_message_multipart) +contained_count * sizeof (struct GNUNET_SCALARPRODUCT_Element)))
- || (0 == contained_count) || (s->total < s->transferred_element_count + contained_count)) {
+ if ((ntohs (msg->header.size) != (sizeof (struct ComputationMultipartMessage) +contained_count * sizeof (struct GNUNET_SCALARPRODUCT_Element)))
+ || (0 == contained_count) || (s->total < s->transferred_element_count + contained_count))
+ {
GNUNET_break_op (0);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
return;
struct GNUNET_SET_Element set_elem;
struct GNUNET_SCALARPRODUCT_Element * elem;
- if (0 == ntohl (elements[i].value))
+ if (0 == GNUNET_ntohll (elements[i].value))
continue;
elem = GNUNET_new (struct GNUNET_SCALARPRODUCT_Element);
struct GNUNET_SERVER_Client *client,
const struct GNUNET_MessageHeader *message)
{
- const struct GNUNET_SCALARPRODUCT_computation_message * msg = (const struct GNUNET_SCALARPRODUCT_computation_message *) message;
+ const struct ComputationMessage * msg = (const struct ComputationMessage *) message;
struct ServiceSession * s;
uint32_t contained_count;
uint32_t total_count;
}
//sanity check: is the message as long as the message_count fields suggests?
- if ((ntohs (msg->header.size) != (sizeof (struct GNUNET_SCALARPRODUCT_computation_message) +contained_count * sizeof (struct GNUNET_SCALARPRODUCT_Element)))
- || (0 == total_count)) {
+ if ((ntohs (msg->header.size) !=
+ (sizeof (struct ComputationMessage) + contained_count * sizeof (struct GNUNET_SCALARPRODUCT_Element)))
+ || (0 == total_count))
+ {
GNUNET_break_op (0);
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
struct GNUNET_SET_Element set_elem;
struct GNUNET_SCALARPRODUCT_Element * elem;
- if (0 == ntohl (elements[i].value))
+ if (0 == GNUNET_ntohll (elements[i].value))
continue;
elem = GNUNET_new (struct GNUNET_SCALARPRODUCT_Element);
const struct GNUNET_MessageHeader * message)
{
struct ServiceSession * s;
- const struct GNUNET_SCALARPRODUCT_multipart_message * msg = (const struct GNUNET_SCALARPRODUCT_multipart_message *) message;
+ const struct MultipartMessage * msg = (const struct MultipartMessage *) message;
struct GNUNET_CRYPTO_PaillierCiphertext *payload;
uint32_t contained_elements;
uint32_t msg_length;
goto except;
}
// shorter than minimum?
- if (ntohs (msg->header.size) <= sizeof (struct GNUNET_SCALARPRODUCT_multipart_message)) {
+ if (ntohs (msg->header.size) <= sizeof (struct MultipartMessage)) {
goto except;
}
contained_elements = ntohl (msg->contained_element_count);
- msg_length = sizeof (struct GNUNET_SCALARPRODUCT_multipart_message)
+ msg_length = sizeof (struct MultipartMessage)
+contained_elements * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext);
//sanity check
if ((ntohs (msg->header.size) != msg_length)
const struct GNUNET_MessageHeader * message)
{
struct ServiceSession * s;
- const struct GNUNET_SCALARPRODUCT_alices_cryptodata_message * msg = (const struct GNUNET_SCALARPRODUCT_alices_cryptodata_message *) message;
+ const struct AliceCryptodataMessage * msg = (const struct AliceCryptodataMessage *) message;
struct GNUNET_CRYPTO_PaillierCiphertext *payload;
uint32_t contained_elements = 0;
uint32_t msg_length;
}
// shorter than minimum?
- if (ntohs (msg->header.size) <= sizeof (struct GNUNET_SCALARPRODUCT_multipart_message)) {
+ if (ntohs (msg->header.size) <= sizeof (struct MultipartMessage))
+ {
goto invalid_msg;
}
contained_elements = ntohl (msg->contained_element_count);
- msg_length = sizeof (struct GNUNET_SCALARPRODUCT_alices_cryptodata_message)
+ msg_length = sizeof (struct AliceCryptodataMessage)
+contained_elements * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext);
//sanity check: is the message as long as the message_count fields suggests?
{
struct ServiceSession * s;
struct ServiceSession * client_session;
- const struct GNUNET_SCALARPRODUCT_service_request * msg = (const struct GNUNET_SCALARPRODUCT_service_request *) message;
+ const struct ServiceRequestMessage * msg = (const struct ServiceRequestMessage *) message;
s = (struct ServiceSession *) * channel_ctx;
if ((BOB != s->role) || (s->total != 0)) {
return GNUNET_SYSERR;
}
// shorter than expected?
- if (ntohs (msg->header.size) != sizeof (struct GNUNET_SCALARPRODUCT_service_request)) {
+ if (ntohs (msg->header.size) != sizeof (struct ServiceRequestMessage)) {
GNUNET_free (s);
GNUNET_break_op (0);
return GNUNET_SYSERR;
const struct GNUNET_MessageHeader * message)
{
struct ServiceSession * s;
- const struct GNUNET_SCALARPRODUCT_multipart_message * msg = (const struct GNUNET_SCALARPRODUCT_multipart_message *) message;
+ const struct MultipartMessage * msg = (const struct MultipartMessage *) message;
struct GNUNET_CRYPTO_PaillierCiphertext * payload;
size_t i;
uint32_t contained = 0;
goto invalid_msg;
}
msg_size = ntohs (msg->header.size);
- required_size = sizeof (struct GNUNET_SCALARPRODUCT_multipart_message)
+ required_size = sizeof (struct MultipartMessage)
+ 2 * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext);
// shorter than minimum?
if (required_size > msg_size) {
goto invalid_msg;
}
contained = ntohl (msg->contained_element_count);
- required_size = sizeof (struct GNUNET_SCALARPRODUCT_multipart_message)
+ required_size = sizeof (struct MultipartMessage)
+ 2 * contained * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext);
//sanity check: is the message as long as the message_count fields suggests?
if ((required_size != msg_size) || (s->used_element_count < s->transferred_element_count + contained)) {
*/
static int
handle_bobs_cryptodata_message (void *cls,
- struct GNUNET_CADET_Channel * channel,
+ struct GNUNET_CADET_Channel *channel,
void **channel_ctx,
- const struct GNUNET_MessageHeader * message)
+ const struct GNUNET_MessageHeader *message)
{
struct ServiceSession * s;
- const struct GNUNET_SCALARPRODUCT_service_response * msg = (const struct GNUNET_SCALARPRODUCT_service_response *) message;
+ const struct ServiceResponseMessage *msg = (const struct ServiceResponseMessage *) message;
struct GNUNET_CRYPTO_PaillierCiphertext * payload;
size_t i;
uint32_t contained = 0;
}
//we need at least a full message without elements attached
msg_size = ntohs (msg->header.size);
- required_size = sizeof (struct GNUNET_SCALARPRODUCT_service_response) + 2 * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext);
+ required_size = sizeof (struct ServiceResponseMessage) + 2 * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext);
if (required_size > msg_size) {
goto invalid_msg;
}
contained = ntohl (msg->contained_element_count);
- required_size = sizeof (struct GNUNET_SCALARPRODUCT_service_response)
+ required_size = sizeof (struct ServiceResponseMessage)
+ 2 * contained * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)
+ 2 * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext);
//sanity check: is the message as long as the message_count fields suggests?
extern "C"
{
#endif
-///////////////////////////////////////////////////////////////////////////////
-// Defines
-///////////////////////////////////////////////////////////////////////////////
-/**
- * Maximum count of elements we can put into a multipart message
- */
-#define MULTIPART_ELEMENT_CAPACITY ((GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - sizeof (struct GNUNET_SCALARPRODUCT_multipart_message)) / sizeof (struct GNUNET_CRYPTO_PaillierCiphertext))
+GNUNET_NETWORK_STRUCT_BEGIN
/**
* Log an error message at log-level 'level' that indicates
*/
#define LOG_GCRY(level, cmd, rc) do { LOG(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, gcry_strerror(rc)); } while(0)
-///////////////////////////////////////////////////////////////////////////////
-// Scalar Product Message Types
-///////////////////////////////////////////////////////////////////////////////
/**
* Message type passed from client to service
* to initiate a request or responder role
*/
-struct GNUNET_SCALARPRODUCT_computation_message
+struct ComputationMessage
{
/**
* GNUNET message header
* how many elements the vector in payload contains
*/
uint32_t element_count_total GNUNET_PACKED;
-
+
/**
* contained elements the vector in payload contains
*/
uint32_t element_count_contained GNUNET_PACKED;
+ /**
+ * Always zero.
+ */
+ uint32_t reserved GNUNET_PACKED;
+
/**
* the transaction/session key used to identify a session
*/
*/
};
+
/**
- * multipart messages following GNUNET_SCALARPRODUCT_client_request
+ * multipart messages following `struct ComputationMessage`
*/
-struct GNUNET_SCALARPRODUCT_computation_message_multipart
+struct ComputationMultipartMessage
{
/**
* GNUNET message header
*/
struct GNUNET_MessageHeader header;
-
+
/**
* contained elements the vector in payload contains
*/
};
-/**
- * Message type passed from requesting service Alice to responding service Bob
- * to initiate a request and make bob participate in our protocol
- */
-struct GNUNET_SCALARPRODUCT_service_request {
- /**
- * GNUNET message header
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * the transaction/session key used to identify a session
- */
- struct GNUNET_HashCode session_id;
-
- /**
- * Alice's public key
- */
- struct GNUNET_CRYPTO_PaillierPublicKey public_key;
-
-};
-
-
-/**
- * Message type passed from requesting service Alice to responding service Bob
- * to initiate a request and make bob participate in our protocol
- */
-struct GNUNET_SCALARPRODUCT_alices_cryptodata_message {
- /**
- * GNUNET message header
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * how many elements we appended to this message
- */
- uint32_t contained_element_count GNUNET_PACKED;
-
- /**
- * struct GNUNET_CRYPTO_PaillierCiphertext[contained_element_count]
- */
-};
-
-/**
- * Multipart Message type passed between to supply additional elements for the peer
- */
-struct GNUNET_SCALARPRODUCT_multipart_message {
- /**
- * GNUNET message header
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * how many elements we supply within this message
- */
- uint32_t contained_element_count GNUNET_PACKED;
-
- // struct GNUNET_CRYPTO_PaillierCiphertext[multipart_element_count]
-};
-
-/**
- * Message type passed from responding service Bob to responding service Alice
- * to complete a request and allow Alice to compute the result
- */
-struct GNUNET_SCALARPRODUCT_service_response {
- /**
- * GNUNET message header
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * how many elements the session input had
- */
- uint32_t total_element_count GNUNET_PACKED;
-
- /**
- * how many elements were included after the mask was applied including all multipart msgs.
- */
- uint32_t used_element_count GNUNET_PACKED;
-
- /**
- * how many elements this individual message delivers
- */
- uint32_t contained_element_count GNUNET_PACKED;
-
- /**
- * the transaction/session key used to identify a session
- */
- struct GNUNET_HashCode key;
-
- /**
- * followed by s | s' | k[i][perm]
- */
-};
-
/**
* Message type passed from service client
* to finalize a session as requester or responder
*/
-struct GNUNET_SCALARPRODUCT_client_response
+struct ClientResponseMessage
{
/**
* GNUNET message header
*/
uint32_t product_length GNUNET_PACKED;
- /**
- * the transaction/session key used to identify a session
- */
- struct GNUNET_HashCode key;
-
- /**
- * the identity of a remote peer we want to communicate with
- */
- struct GNUNET_PeerIdentity peer;
-
/**
* status information about the outcome of this session
*/
- int32_t status;
-
+ int32_t status GNUNET_PACKED;
+
/**
* Workaround for libgcrypt: -1 if negative, 0 if zero, else 1
*/
- int8_t range;
+ int32_t range GNUNET_PACKED;
/**
* followed by product of length product_length (or nothing)
*/
};
+GNUNET_NETWORK_STRUCT_END
+
#ifdef __cplusplus
}
#endif
/*
This file is part of GNUnet.
- (C) 2013 Christian Grothoff (and other contributing authors)
+ (C) 2013, 2014 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
* @brief API for the scalarproduct
* @author Christian Fuchs
* @author Gaurav Kukreja
- *
+ * @author Christian Grothoff
*/
#include "platform.h"
#include "gnunet_util_lib.h"
#define LOG(kind,...) GNUNET_log_from (kind, "scalarproduct-api",__VA_ARGS__)
-/**************************************************************
- *** Datatype Declarations **********
- **************************************************************/
/**
- * the abstraction function for our internal callback
+ * The abstraction function for our internal callback
+ *
+ * @param h computation handle
+ * @param msg response we got, NULL on errors
+ * @param status processing status code
*/
-typedef void (*GNUNET_SCALARPRODUCT_ResponseMessageHandler) (void *cls,
- const struct GNUNET_MessageHeader *msg,
- enum GNUNET_SCALARPRODUCT_ResponseStatus status);
+typedef void
+(*GNUNET_SCALARPRODUCT_ResponseMessageHandler) (struct GNUNET_SCALARPRODUCT_ComputationHandle *h,
+ const struct ClientResponseMessage *msg,
+ enum GNUNET_SCALARPRODUCT_ResponseStatus status);
+
/**
* A handle returned for each computation
*/
struct GNUNET_CLIENT_Connection *client;
- /**
- * Handle for statistics.
- */
- struct GNUNET_STATISTICS_Handle *stats;
-
/**
* The shared session key identifying this computation
*/
struct GNUNET_CLIENT_TransmitHandle *th;
/**
- * count of all elements we offer for computation
+ * count of all @e elements we offer for computation
*/
uint32_t element_count_total;
/**
- * count of the transfered elements we offer for computation
+ * count of the transfered @e elements we offer for computation
*/
uint32_t element_count_transfered;
-
+
/**
- * the client's elements which
+ * the client's elements which
*/
- struct GNUNET_SCALARPRODUCT_Element * elements;
-
+ struct GNUNET_SCALARPRODUCT_Element *elements;
+
/**
* Message to be sent to the scalarproduct service
*/
- void * msg;
+ struct GNUNET_MessageHeader *msg;
- /**
- * The client's msg handler callback
- */
- union
- {
/**
* Function to call after transmission of the request (Bob).
*/
* Function to call after transmission of the request (Alice).
*/
GNUNET_SCALARPRODUCT_DatumProcessor cont_datum;
- };
/**
- * Closure for 'cont'.
+ * Closure for @e cont_status or @e cont_datum.
*/
void *cont_cls;
/**
- * API internal callback for results and failures to be forwarded to the client
+ * API internal callback for results and failures to be forwarded to
+ * the client.
*/
GNUNET_SCALARPRODUCT_ResponseMessageHandler response_proc;
-
- /**
- *
- */
- GNUNET_SCHEDULER_TaskIdentifier cont_multipart;
-};
-
-/**************************************************************
- *** Forward Function Declarations **********
- **************************************************************/
-
-void
-GNUNET_SCALARPRODUCT_cancel (struct GNUNET_SCALARPRODUCT_ComputationHandle * h);
-static size_t do_send_message (void *cls, size_t size, void *buf);
-/**************************************************************
- *** Static Function Declarations **********
- **************************************************************/
+};
/**
- * Handles the STATUS received from the service for a response, does not contain a payload
+ * Handles the STATUS received from the service for a response, does
+ * not contain a payload.
*
- * @param cls our Handle
+ * @param h our Handle
* @param msg Pointer to the response received
* @param status the condition the request was terminated with (eg: disconnect)
*/
static void
-process_status_message (void *cls,
- const struct GNUNET_MessageHeader *msg,
+process_status_message (struct GNUNET_SCALARPRODUCT_ComputationHandle *h,
+ const struct ClientResponseMessage *msg,
enum GNUNET_SCALARPRODUCT_ResponseStatus status)
{
- struct GNUNET_SCALARPRODUCT_ComputationHandle *qe = cls;
-
- qe->cont_status (qe->cont_cls, status);
+ if (NULL != h->cont_status)
+ h->cont_status (h->cont_cls,
+ status);
+ GNUNET_SCALARPRODUCT_cancel (h);
}
/**
- * Handles the RESULT received from the service for a request, should contain a result MPI value
+ * Handles the RESULT received from the service for a request, should
+ * contain a result MPI value
*
- * @param cls our Handle
+ * @param h our Handle
* @param msg Pointer to the response received
* @param status the condition the request was terminated with (eg: disconnect)
*/
static void
-process_result_message (void *cls,
- const struct GNUNET_MessageHeader *msg,
+process_result_message (struct GNUNET_SCALARPRODUCT_ComputationHandle *h,
+ const struct ClientResponseMessage *msg,
enum GNUNET_SCALARPRODUCT_ResponseStatus status)
{
- struct GNUNET_SCALARPRODUCT_ComputationHandle *qe = cls;
- const struct GNUNET_SCALARPRODUCT_client_response *message =
- (const struct GNUNET_SCALARPRODUCT_client_response *) msg;
+ size_t product_len = ntohl (msg->product_length);
gcry_mpi_t result = NULL;
gcry_error_t rc;
+ gcry_mpi_t num;
+ size_t rsize;
+ if (ntohs (msg->header.size) - sizeof (struct ClientResponseMessage)
+ != product_len)
+ {
+ GNUNET_break (0);
+ status = GNUNET_SCALARPRODUCT_Status_InvalidResponse;
+ }
if (GNUNET_SCALARPRODUCT_Status_Success == status)
+ {
+ result = gcry_mpi_new (0);
+
+ if (0 < product_len)
{
- size_t product_len = ntohl (message->product_length);
- result = gcry_mpi_new (0);
-
- if (0 < product_len)
- {
- gcry_mpi_t num;
- size_t read = 0;
-
- if (0 != (rc = gcry_mpi_scan (&num, GCRYMPI_FMT_STD, &message[1], product_len, &read)))
- {
- LOG_GCRY(GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
- gcry_mpi_release (result);
- result = NULL;
- status = GNUNET_SCALARPRODUCT_Status_InvalidResponse;
- }
- else
- {
- if (0 < message->range)
- gcry_mpi_add (result, result, num);
- else if (0 > message->range)
- gcry_mpi_sub (result, result, num);
- gcry_mpi_release (num);
- }
- }
+ rsize = 0;
+ if (0 != (rc = gcry_mpi_scan (&num, GCRYMPI_FMT_STD,
+ &msg[1],
+ product_len,
+ &rsize)))
+ {
+ LOG_GCRY (GNUNET_ERROR_TYPE_ERROR,
+ "gcry_mpi_scan",
+ rc);
+ gcry_mpi_release (result);
+ result = NULL;
+ status = GNUNET_SCALARPRODUCT_Status_InvalidResponse;
+ }
+ else
+ {
+ if (0 < ntohl (msg->range))
+ gcry_mpi_add (result, result, num);
+ else if (0 > ntohl (msg->range))
+ gcry_mpi_sub (result, result, num);
+ gcry_mpi_release (num);
+ }
}
- qe->cont_datum (qe->cont_cls, status, result);
+ }
+ h->cont_datum (h->cont_cls, status, result);
+ if (NULL != result)
+ gcry_mpi_release (result);
+ GNUNET_SCALARPRODUCT_cancel (h);
}
* @param msg Pointer to the data received in response
*/
static void
-receive_cb (void *cls, const struct GNUNET_MessageHeader *msg)
+receive_cb (void *cls,
+ const struct GNUNET_MessageHeader *msg)
{
struct GNUNET_SCALARPRODUCT_ComputationHandle *h = cls;
- const struct GNUNET_SCALARPRODUCT_client_response *message =
- (const struct GNUNET_SCALARPRODUCT_client_response *) msg;
- enum GNUNET_SCALARPRODUCT_ResponseStatus status = GNUNET_SCALARPRODUCT_Status_InvalidResponse;
+ const struct ClientResponseMessage *message;
if (NULL == msg)
- {
- LOG (GNUNET_ERROR_TYPE_WARNING, "Disconnected by Service.\n");
- status = GNUNET_SCALARPRODUCT_Status_ServiceDisconnected;
- }
- else if ((GNUNET_SYSERR != message->status) && (0 < message->product_length ))
- {
- // response for the responder client, successful
- GNUNET_STATISTICS_update (h->stats,
- gettext_noop ("# SUC responder result messages received"), 1,
- GNUNET_NO);
-
- status = GNUNET_SCALARPRODUCT_Status_Success;
- }
- else if (message->status == GNUNET_SYSERR){
- // service signaled an error
- status = GNUNET_SCALARPRODUCT_Status_Failure;
+ {
+ LOG (GNUNET_ERROR_TYPE_INFO,
+ "Disconnected from SCALARPRODUCT service.\n");
+ h->response_proc (h,
+ NULL,
+ GNUNET_SCALARPRODUCT_Status_ServiceDisconnected);
+ return;
}
-
- if (h->cont_status != NULL)
- h->response_proc (h, msg, status);
-
- GNUNET_free (h);
-}
-
-
-static void
-send_multipart (void * cls, const struct GNUNET_SCHEDULER_TaskContext * tc)
-{
- struct GNUNET_SCALARPRODUCT_ComputationHandle *h = (struct GNUNET_SCALARPRODUCT_ComputationHandle *) cls;
- struct GNUNET_SCALARPRODUCT_computation_message_multipart *msg;
- uint32_t size;
- uint32_t todo;
-
- h->cont_multipart = GNUNET_SCHEDULER_NO_TASK;
-
- todo = h->element_count_total - h->element_count_transfered;
- size = sizeof (struct GNUNET_SCALARPRODUCT_computation_message_multipart) +todo * sizeof (struct GNUNET_SCALARPRODUCT_Element);
- if (GNUNET_SERVER_MAX_MESSAGE_SIZE <= size) {
- //create a multipart msg, first we calculate a new msg size for the head msg
- todo = (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - sizeof (struct GNUNET_SCALARPRODUCT_computation_message_multipart)) / sizeof (struct GNUNET_SCALARPRODUCT_Element);
- size = sizeof (struct GNUNET_SCALARPRODUCT_computation_message_multipart) +todo * sizeof (struct GNUNET_SCALARPRODUCT_Element);
+ if (ntohs (msg->size) != sizeof (struct ClientResponseMessage))
+ {
+ GNUNET_break (0);
+ h->response_proc (h,
+ NULL,
+ GNUNET_SCALARPRODUCT_Status_InvalidResponse);
+ return;
}
-
- msg = (struct GNUNET_SCALARPRODUCT_computation_message_multipart*) GNUNET_malloc (size);
- h->msg = msg;
- msg->header.size = htons (size);
- msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_MUTLIPART);
- msg->element_count_contained = htonl (todo);
-
- memcpy (&msg[1], &h->elements[h->element_count_transfered], todo * sizeof (struct GNUNET_SCALARPRODUCT_Element));
- h->element_count_transfered += todo;
-
- h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, size,
- GNUNET_TIME_UNIT_FOREVER_REL,
- GNUNET_YES, // retry is OK in the initial stage
- &do_send_message, h);
-
- if (!h->th) {
- LOG (GNUNET_ERROR_TYPE_ERROR,
- _ ("Failed to send a multipart message to the scalarproduct service\n"));
- GNUNET_STATISTICS_update (h->stats,
- gettext_noop ("# transmission request failures"),
- 1, GNUNET_NO);
- GNUNET_STATISTICS_destroy (h->stats, GNUNET_YES);
- GNUNET_CLIENT_disconnect (h->client);
- GNUNET_free (h->msg);
- h->msg = NULL;
- if (h->cont_status != NULL)
- h->response_proc (h, NULL, GNUNET_SCALARPRODUCT_Status_Failure);
-
- GNUNET_SCALARPRODUCT_cancel (cls);
+ message = (const struct ClientResponseMessage *) msg;
+ if (GNUNET_SYSERR == ntohl (message->status))
+ {
+ h->response_proc (h,
+ NULL,
+ GNUNET_SCALARPRODUCT_Status_Failure);
+ return;
}
+ h->response_proc (h,
+ message,
+ GNUNET_SCALARPRODUCT_Status_Success);
}
+
/**
- * Transmits the request to the VectorProduct Service
+ * Transmits the request to the SCALARPRODUCT service
*
- * @param cls Closure
- * @param size Size of the buffer
+ * @param cls Closure with the `struct GNUNET_SCALARPRODUCT_ComputationHandle`
+ * @param size Size of the buffer @a buf
* @param buf Pointer to the buffer
- *
* @return Size of the message sent
*/
static size_t
-do_send_message (void *cls, size_t size,
+do_send_message (void *cls,
+ size_t size,
void *buf)
{
struct GNUNET_SCALARPRODUCT_ComputationHandle *h = cls;
+ struct ComputationMultipartMessage *msg;
+ size_t ret;
+ uint32_t nsize;
+ uint32_t todo;
- if (NULL == buf) {
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Failed to transmit request to SCALARPRODUCT.\n");
- GNUNET_STATISTICS_update (h->stats,
- gettext_noop ("# transmission request failures"),
- 1, GNUNET_NO);
-
- // notify caller about the error, done here.
- if (h->cont_status != NULL)
- h->response_proc (h, NULL, GNUNET_SCALARPRODUCT_Status_Failure);
-
- GNUNET_SCALARPRODUCT_cancel (cls);
+ h->th = NULL;
+ if (NULL == buf)
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Failed to transmit request to SCALARPRODUCT.\n");
+ /* notify caller about the error, done here */
+ h->response_proc (h, NULL,
+ GNUNET_SCALARPRODUCT_Status_Failure);
return 0;
}
- memcpy (buf, h->msg, size);
-
+ ret = ntohs (h->msg->size);
+ memcpy (buf, h->msg, ret);
GNUNET_free (h->msg);
h->msg = NULL;
- h->th = NULL;
-
-#if INSANE_STATISTICS
- GNUNET_STATISTICS_update (h->stats,
- gettext_noop ("# bytes sent to scalarproduct"), 1,
- GNUNET_NO);
-#endif
- /* done sending */
- if (h->element_count_total == h->element_count_transfered) {
- GNUNET_CLIENT_receive (h->client, &receive_cb, h,
+ /* done sending? */
+ if (h->element_count_total == h->element_count_transfered)
+ {
+ GNUNET_CLIENT_receive (h->client,
+ &receive_cb, h,
GNUNET_TIME_UNIT_FOREVER_REL);
- return size;
+ return ret;
}
-
- h->cont_multipart = GNUNET_SCHEDULER_add_now (&send_multipart, h);
-
- return size;
-}
+ todo = h->element_count_total - h->element_count_transfered;
+ nsize = sizeof (struct ComputationMultipartMessage)
+ + todo * sizeof (struct GNUNET_SCALARPRODUCT_Element);
+ if (GNUNET_SERVER_MAX_MESSAGE_SIZE <= size)
+ {
+ /* cannot do all of them, limit to what is possible in one message */
+ todo = (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - sizeof (struct ComputationMultipartMessage))
+ / sizeof (struct GNUNET_SCALARPRODUCT_Element);
+ nsize = sizeof (struct ComputationMultipartMessage)
+ + todo * sizeof (struct GNUNET_SCALARPRODUCT_Element);
+ }
-/**************************************************************
- *** API **********
- **************************************************************/
+ msg = GNUNET_malloc (nsize);
+ h->msg = &msg->header;
+ msg->header.size = htons (nsize);
+ msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_MUTLIPART);
+ msg->element_count_contained = htonl (todo);
+ memcpy (&msg[1],
+ &h->elements[h->element_count_transfered],
+ todo * sizeof (struct GNUNET_SCALARPRODUCT_Element));
+ h->element_count_transfered += todo;
+ h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, nsize,
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ GNUNET_NO,
+ &do_send_message, h);
+ GNUNET_assert (NULL != h->th);
+ return ret;
+}
/**
* @param cfg the gnunet configuration handle
* @param key Session key unique to the requesting client
* @param elements Array of elements of the vector
- * @param element_count Number of elements in the vector
+ * @param element_count Number of elements in the @a elements vector
* @param cont Callback function
- * @param cont_cls Closure for the callback function
- *
+ * @param cont_cls Closure for @a cont
* @return a new handle for this computation
*/
struct GNUNET_SCALARPRODUCT_ComputationHandle *
-GNUNET_SCALARPRODUCT_accept_computation (const struct GNUNET_CONFIGURATION_Handle * cfg,
- const struct GNUNET_HashCode * session_key,
- const struct GNUNET_SCALARPRODUCT_Element * elements,
- uint32_t element_count,
- GNUNET_SCALARPRODUCT_ContinuationWithStatus cont,
- void * cont_cls)
+GNUNET_SCALARPRODUCT_accept_computation (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const struct GNUNET_HashCode *session_key,
+ const struct GNUNET_SCALARPRODUCT_Element *elements,
+ uint32_t element_count,
+ GNUNET_SCALARPRODUCT_ContinuationWithStatus cont,
+ void *cont_cls)
{
struct GNUNET_SCALARPRODUCT_ComputationHandle *h;
- struct GNUNET_SCALARPRODUCT_computation_message *msg;
+ struct ComputationMessage *msg;
uint32_t size;
uint16_t possible;
- GNUNET_assert (GNUNET_SERVER_MAX_MESSAGE_SIZE >= sizeof (struct GNUNET_SCALARPRODUCT_computation_message)
- + element_count * sizeof (int32_t));
h = GNUNET_new (struct GNUNET_SCALARPRODUCT_ComputationHandle);
+ h->cont_status = cont;
+ h->cont_cls = cont_cls;
+ h->response_proc = &process_status_message;
+ h->cfg = cfg;
+ h->key = *session_key;
h->client = GNUNET_CLIENT_connect ("scalarproduct", cfg);
- if (!h->client)
- {
- LOG (GNUNET_ERROR_TYPE_ERROR,
- _ ("Failed to connect to the scalarproduct service\n"));
- GNUNET_free (h);
- return NULL;
- }
- h->stats = GNUNET_STATISTICS_create ("scalarproduct-api", cfg);
- if (!h->stats)
- {
- LOG (GNUNET_ERROR_TYPE_ERROR,
- _ ("Failed to send a message to the statistics service\n"));
- GNUNET_CLIENT_disconnect (h->client);
- GNUNET_free (h);
- return NULL;
- }
-
h->element_count_total = element_count;
- size = sizeof (struct GNUNET_SCALARPRODUCT_computation_message) + element_count * sizeof (struct GNUNET_SCALARPRODUCT_Element);
- if (GNUNET_SERVER_MAX_MESSAGE_SIZE > size) {
+ if (NULL == h->client)
+ {
+ /* scalarproduct configuration error */
+ GNUNET_break (0);
+ GNUNET_free (h);
+ return NULL;
+ }
+ size = sizeof (struct ComputationMessage)
+ + element_count * sizeof (struct GNUNET_SCALARPRODUCT_Element);
+ if (GNUNET_SERVER_MAX_MESSAGE_SIZE > size)
+ {
possible = element_count;
h->element_count_transfered = element_count;
}
- else {
- //create a multipart msg, first we calculate a new msg size for the head msg
- possible = (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - sizeof (struct GNUNET_SCALARPRODUCT_computation_message)) / sizeof (struct GNUNET_SCALARPRODUCT_Element);
+ else
+ {
+ /* create a multipart msg, first we calculate a new msg size for the head msg */
+ possible = (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - sizeof (struct ComputationMessage))
+ / sizeof (struct GNUNET_SCALARPRODUCT_Element);
h->element_count_transfered = possible;
- size = sizeof (struct GNUNET_SCALARPRODUCT_computation_message) + possible*sizeof (struct GNUNET_SCALARPRODUCT_Element);
- h->elements = (struct GNUNET_SCALARPRODUCT_Element*)
- GNUNET_malloc (sizeof(struct GNUNET_SCALARPRODUCT_Element) * element_count);
- memcpy (h->elements, elements, sizeof (struct GNUNET_SCALARPRODUCT_Element)*element_count);
+ size = sizeof (struct ComputationMessage)
+ + possible * sizeof (struct GNUNET_SCALARPRODUCT_Element);
+ h->elements = GNUNET_malloc (sizeof(struct GNUNET_SCALARPRODUCT_Element) * element_count);
+ memcpy (h->elements,
+ elements,
+ sizeof (struct GNUNET_SCALARPRODUCT_Element) * element_count);
}
- h->cont_status = cont;
- h->cont_cls = cont_cls;
- h->response_proc = &process_status_message;
- h->cfg = cfg;
- memcpy (&h->key, session_key, sizeof (struct GNUNET_HashCode));
-
- msg = (struct GNUNET_SCALARPRODUCT_computation_message*) GNUNET_malloc (size);
- h->msg = msg;
+ msg = GNUNET_malloc (size);
+ h->msg = &msg->header;
msg->header.size = htons (size);
msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_TO_BOB);
msg->element_count_total = htonl (element_count);
msg->element_count_contained = htonl (possible);
-
- memcpy (&msg->session_key, session_key, sizeof (struct GNUNET_HashCode));
- memcpy (&msg[1], elements, possible);
-
+ msg->session_key = *session_key;
+ memcpy (&msg[1],
+ elements,
+ possible);
h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, size,
GNUNET_TIME_UNIT_FOREVER_REL,
- GNUNET_YES, // retry is OK in the initial stage
+ GNUNET_YES, /* retry is OK in the initial stage */
&do_send_message, h);
- if (!h->th)
- {
- LOG (GNUNET_ERROR_TYPE_ERROR,
- _ ("Failed to send a message to the scalarproduct service\n"));
- GNUNET_STATISTICS_update (h->stats,
- gettext_noop ("# transmission request failures"),
- 1, GNUNET_NO);
- GNUNET_STATISTICS_destroy (h->stats, GNUNET_YES);
- GNUNET_CLIENT_disconnect (h->client);
- GNUNET_free (h->msg);
- GNUNET_free_non_null (h->elements);
- GNUNET_free (h);
- return NULL;
- }
+ GNUNET_assert (NULL != h->th);
return h;
}
* @param session_key Session key should be unique to the requesting client
* @param peer PeerID of the other peer
* @param elements Array of elements of the vector
- * @param element_count Number of elements in the vector
+ * @param element_count Number of elements in the @a elements vector
* @param cont Callback function
- * @param cont_cls Closure for the callback function
- *
+ * @param cont_cls Closure for @a cont
* @return a new handle for this computation
*/
struct GNUNET_SCALARPRODUCT_ComputationHandle *
-GNUNET_SCALARPRODUCT_start_computation (const struct GNUNET_CONFIGURATION_Handle * cfg,
- const struct GNUNET_HashCode * session_key,
- const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_SCALARPRODUCT_Element * elements,
- uint32_t element_count,
- GNUNET_SCALARPRODUCT_DatumProcessor cont,
- void * cont_cls)
+GNUNET_SCALARPRODUCT_start_computation (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const struct GNUNET_HashCode *session_key,
+ const struct GNUNET_PeerIdentity *peer,
+ const struct GNUNET_SCALARPRODUCT_Element *elements,
+ uint32_t element_count,
+ GNUNET_SCALARPRODUCT_DatumProcessor cont,
+ void *cont_cls)
{
struct GNUNET_SCALARPRODUCT_ComputationHandle *h;
- struct GNUNET_SCALARPRODUCT_computation_message *msg;
+ struct ComputationMessage *msg;
uint32_t size;
- uint16_t possible;
+ uint32_t possible;
h = GNUNET_new (struct GNUNET_SCALARPRODUCT_ComputationHandle);
h->client = GNUNET_CLIENT_connect ("scalarproduct", cfg);
- if (!h->client)
- {
- LOG (GNUNET_ERROR_TYPE_ERROR,
- _ ("Failed to connect to the scalarproduct service\n"));
- GNUNET_free (h);
- return NULL;
- }
- h->stats = GNUNET_STATISTICS_create ("scalarproduct-api", cfg);
- if (!h->stats)
- {
- LOG (GNUNET_ERROR_TYPE_ERROR,
- _ ("Failed to send a message to the statistics service\n"));
- GNUNET_CLIENT_disconnect (h->client);
- GNUNET_free (h);
- return NULL;
- }
-
+ if (NULL == h->client)
+ {
+ /* missconfigured scalarproduct service */
+ GNUNET_break (0);
+ GNUNET_free (h);
+ return NULL;
+ }
h->element_count_total = element_count;
- size = sizeof (struct GNUNET_SCALARPRODUCT_computation_message) + element_count * sizeof (struct GNUNET_SCALARPRODUCT_Element);
- if (GNUNET_SERVER_MAX_MESSAGE_SIZE > size) {
+ h->cont_datum = cont;
+ h->cont_cls = cont_cls;
+ h->response_proc = &process_result_message;
+ h->cfg = cfg;
+ h->key = *session_key;
+ size = sizeof (struct ComputationMessage)
+ + element_count * sizeof (struct GNUNET_SCALARPRODUCT_Element);
+ if (GNUNET_SERVER_MAX_MESSAGE_SIZE > size)
+ {
possible = element_count;
h->element_count_transfered = element_count;
}
- else {
- //create a multipart msg, first we calculate a new msg size for the head msg
- possible = (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - sizeof (struct GNUNET_SCALARPRODUCT_computation_message)) / sizeof (struct GNUNET_SCALARPRODUCT_Element);
+ else
+ {
+ /* create a multipart msg, first we calculate a new msg size for the head msg */
+ possible = (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - sizeof (struct ComputationMessage))
+ / sizeof (struct GNUNET_SCALARPRODUCT_Element);
h->element_count_transfered = possible;
- size = sizeof (struct GNUNET_SCALARPRODUCT_computation_message) + possible*sizeof (struct GNUNET_SCALARPRODUCT_Element);
- h->elements = (struct GNUNET_SCALARPRODUCT_Element*)
- GNUNET_malloc (sizeof(struct GNUNET_SCALARPRODUCT_Element) * element_count);
- memcpy (h->elements, elements, sizeof (struct GNUNET_SCALARPRODUCT_Element) * element_count);
+ size = sizeof (struct ComputationMessage)
+ + possible * sizeof (struct GNUNET_SCALARPRODUCT_Element);
+ h->elements = GNUNET_malloc (sizeof(struct GNUNET_SCALARPRODUCT_Element) * element_count);
+ memcpy (h->elements,
+ elements,
+ sizeof (struct GNUNET_SCALARPRODUCT_Element) * element_count);
}
-
- h->cont_datum = cont;
- h->cont_cls = cont_cls;
- h->response_proc = &process_result_message;
- h->cfg = cfg;
- memcpy (&h->key, session_key, sizeof (struct GNUNET_HashCode));
- msg = (struct GNUNET_SCALARPRODUCT_computation_message*) GNUNET_malloc (size);
- h->msg = msg;
+ msg = GNUNET_malloc (size);
+ h->msg = &msg->header;
msg->header.size = htons (size);
msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_TO_ALICE);
msg->element_count_total = htonl (element_count);
msg->element_count_contained = htonl (possible);
-
- memcpy (&msg->peer, peer, sizeof (struct GNUNET_PeerIdentity));
- memcpy (&msg->session_key, session_key, sizeof (struct GNUNET_HashCode));
- memcpy (&msg[1], elements, sizeof (struct GNUNET_SCALARPRODUCT_Element) * possible);
-
+ msg->reserved = htonl (0);
+ msg->peer = *peer;
+ msg->session_key = *session_key;
+ memcpy (&msg[1],
+ elements,
+ sizeof (struct GNUNET_SCALARPRODUCT_Element) * possible);
h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, size,
GNUNET_TIME_UNIT_FOREVER_REL,
- GNUNET_YES, // retry is OK in the initial stage
+ GNUNET_YES, /* retry is OK in the initial stage */
&do_send_message, h);
- if (!h->th)
- {
- LOG (GNUNET_ERROR_TYPE_ERROR,
- _ ("Failed to send a message to the scalarproduct service\n"));
- GNUNET_STATISTICS_update (h->stats,
- gettext_noop ("# transmission request failures"),
- 1, GNUNET_NO);
- GNUNET_STATISTICS_destroy (h->stats, GNUNET_YES);
- GNUNET_CLIENT_disconnect (h->client);
- GNUNET_free (h->msg);
- GNUNET_free_non_null (h->elements);
- GNUNET_free (h);
- return NULL;
- }
+ GNUNET_assert (NULL != h->th);
return h;
}
+
/**
* Cancel an ongoing computation or revoke our collaboration offer.
* Closes the connection to the service
* @param h computation handle to terminate
*/
void
-GNUNET_SCALARPRODUCT_cancel (struct GNUNET_SCALARPRODUCT_ComputationHandle * h)
+GNUNET_SCALARPRODUCT_cancel (struct GNUNET_SCALARPRODUCT_ComputationHandle *h)
{
if (NULL != h->th)
+ {
GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
- if (GNUNET_SCHEDULER_NO_TASK != h->cont_multipart)
- GNUNET_SCHEDULER_cancel (h->cont_multipart);
+ h->th = NULL;
+ }
GNUNET_free_non_null (h->elements);
GNUNET_free_non_null (h->msg);
- GNUNET_CLIENT_disconnect (h->client);
- GNUNET_STATISTICS_destroy (h->stats, GNUNET_YES);
+ if (NULL != h->client)
+ {
+ GNUNET_CLIENT_disconnect (h->client);
+ h->client = NULL;
+ }
GNUNET_free (h);
}