GNUnet  0.10.x
scalarproduct_api.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2013, 2014, 2016 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
31 #include "gnunet_protocols.h"
32 #include "scalarproduct.h"
33 
34 #define LOG(kind,...) GNUNET_log_from (kind, "scalarproduct-api",__VA_ARGS__)
35 
36 
44 typedef void
46  const struct ClientResponseMessage *msg,
48 
49 
54 {
59 
64 
69 
74 
78  void *cont_cls;
79 
85 
90 
91 };
92 
93 
102 static int
103 check_response (void *cls,
104  const struct ClientResponseMessage *message)
105 {
106  if (ntohs (message->header.size) !=
107  ntohl (message->product_length) + sizeof (struct ClientResponseMessage))
108  {
109  GNUNET_break (0);
110  return GNUNET_SYSERR;
111  }
112  return GNUNET_OK;
113 }
114 
115 
125 static void
127  const struct ClientResponseMessage *msg,
129 {
130  if (NULL != h->cont_status)
131  h->cont_status (h->cont_cls,
132  status);
134 }
135 
136 
145 static void
146 handle_response (void *cls,
147  const struct ClientResponseMessage *message)
148 {
151 
152  status = (enum GNUNET_SCALARPRODUCT_ResponseStatus) ntohl (message->status);
153  h->response_proc (h,
154  message,
155  status);
156 }
157 
158 
166 static int
168  uint32_t element_count)
169 {
171  uint32_t i;
172  int ok;
173 
174  ok = GNUNET_OK;
175  map = GNUNET_CONTAINER_multihashmap_create (2 * element_count,
176  GNUNET_YES);
177  for (i=0;i<element_count;i++)
178  if (GNUNET_OK !=
180  &elements[i].key,
181  map,
183  {
185  _("Keys given to SCALARPRODUCT not unique!\n"));
186  ok = GNUNET_SYSERR;
187  }
189  return ok;
190 }
191 
192 
200 static void
201 mq_error_handler (void *cls,
202  enum GNUNET_MQ_Error error)
203 {
205 
207  "Disconnected from SCALARPRODUCT service.\n");
208  h->response_proc (h,
209  NULL,
211 }
212 
213 
227  const struct GNUNET_HashCode *session_key,
228  const struct GNUNET_SCALARPRODUCT_Element *elements,
229  uint32_t element_count,
231  void *cont_cls)
232 {
235  struct GNUNET_MQ_MessageHandler handlers[] = {
238  struct ClientResponseMessage,
239  h),
241  };
242  struct GNUNET_MQ_Envelope *env;
243  struct BobComputationMessage *msg;
245  uint32_t size;
246  uint16_t possible;
247  uint16_t todo;
248  uint32_t element_count_transfered;
249 
250 
251  if (GNUNET_SYSERR == check_unique (elements,
252  element_count))
253  return NULL;
254  h->cont_status = cont;
255  h->cont_cls = cont_cls;
257  h->cfg = cfg;
258  h->key = *session_key;
259  h->mq = GNUNET_CLIENT_connect (cfg,
260  "scalarproduct-bob",
261  handlers,
263  h);
264  if (NULL == h->mq)
265  {
266  /* scalarproduct configuration error */
267  GNUNET_break (0);
268  GNUNET_free (h);
269  return NULL;
270  }
271  possible = (GNUNET_MAX_MESSAGE_SIZE - 1 - sizeof (struct BobComputationMessage))
272  / sizeof (struct GNUNET_SCALARPRODUCT_Element);
273  todo = GNUNET_MIN (possible,
274  element_count);
275  size = todo * sizeof (struct GNUNET_SCALARPRODUCT_Element);
276  env = GNUNET_MQ_msg_extra (msg,
277  size,
279  msg->element_count_total = htonl (element_count);
280  msg->element_count_contained = htonl (todo);
281  msg->session_key = *session_key;
282  GNUNET_memcpy (&msg[1],
283  elements,
284  size);
285  element_count_transfered = todo;
286  GNUNET_MQ_send (h->mq,
287  env);
288  possible = (GNUNET_MAX_MESSAGE_SIZE - 1 - sizeof (*mmsg))
289  / sizeof (struct GNUNET_SCALARPRODUCT_Element);
290  while (element_count_transfered < element_count)
291  {
292  todo = GNUNET_MIN (possible,
293  element_count - element_count_transfered);
294  size = todo * sizeof (struct GNUNET_SCALARPRODUCT_Element);
295  env = GNUNET_MQ_msg_extra (mmsg,
296  size,
298  mmsg->element_count_contained = htonl (todo);
299  GNUNET_memcpy (&mmsg[1],
300  &elements[element_count_transfered],
301  size);
302  element_count_transfered += todo;
303  GNUNET_MQ_send (h->mq,
304  env);
305  }
306  return h;
307 }
308 
309 
319 static void
321  const struct ClientResponseMessage *msg,
323 {
324  uint32_t product_len;
325  gcry_mpi_t result = NULL;
326  gcry_error_t rc;
327  gcry_mpi_t num;
328  size_t rsize;
329 
331  {
332  result = gcry_mpi_new (0);
333 
334  product_len = ntohl (msg->product_length);
335  if (0 < product_len)
336  {
337  rsize = 0;
338  if (0 != (rc = gcry_mpi_scan (&num, GCRYMPI_FMT_STD,
339  &msg[1],
340  product_len,
341  &rsize)))
342  {
344  "gcry_mpi_scan",
345  rc);
346  gcry_mpi_release (result);
347  result = NULL;
349  }
350  else
351  {
352  if (0 < (int32_t) ntohl (msg->range))
353  gcry_mpi_add (result, result, num);
354  else
355  gcry_mpi_sub (result, result, num);
356  gcry_mpi_release (num);
357  }
358  }
359  }
360  if (NULL != h->cont_datum)
361  h->cont_datum (h->cont_cls,
362  status,
363  result);
364  if (NULL != result)
365  gcry_mpi_release (result);
367 }
368 
369 
384  const struct GNUNET_HashCode *session_key,
385  const struct GNUNET_PeerIdentity *peer,
386  const struct GNUNET_SCALARPRODUCT_Element *elements,
387  uint32_t element_count,
389  void *cont_cls)
390 {
393  struct GNUNET_MQ_MessageHandler handlers[] = {
396  struct ClientResponseMessage,
397  h),
399  };
400  struct GNUNET_MQ_Envelope *env;
403  uint32_t size;
404  uint16_t possible;
405  uint16_t todo;
406  uint32_t element_count_transfered;
407 
408  if (GNUNET_SYSERR == check_unique (elements,
409  element_count))
410  return NULL;
411  h->mq = GNUNET_CLIENT_connect (cfg,
412  "scalarproduct-alice",
413  handlers,
415  h);
416  if (NULL == h->mq)
417  {
418  /* missconfigured scalarproduct service */
419  GNUNET_break (0);
420  GNUNET_free (h);
421  return NULL;
422  }
423  h->cont_datum = cont;
424  h->cont_cls = cont_cls;
426  h->cfg = cfg;
427  h->key = *session_key;
428 
429  possible = (GNUNET_MAX_MESSAGE_SIZE - 1 - sizeof (struct AliceComputationMessage))
430  / sizeof (struct GNUNET_SCALARPRODUCT_Element);
431  todo = GNUNET_MIN (possible,
432  element_count);
433  size = todo * sizeof (struct GNUNET_SCALARPRODUCT_Element);
434  env = GNUNET_MQ_msg_extra (msg,
435  size,
437  msg->element_count_total = htonl (element_count);
438  msg->element_count_contained = htonl (todo);
439  msg->reserved = htonl (0);
440  msg->peer = *peer;
441  msg->session_key = *session_key;
442  GNUNET_memcpy (&msg[1],
443  elements,
444  size);
445  GNUNET_MQ_send (h->mq,
446  env);
447  element_count_transfered = todo;
448  possible = (GNUNET_MAX_MESSAGE_SIZE - 1 - sizeof (*mmsg))
449  / sizeof (struct GNUNET_SCALARPRODUCT_Element);
450  while (element_count_transfered < element_count)
451  {
452  todo = GNUNET_MIN (possible,
453  element_count - element_count_transfered);
454  size = todo * sizeof (struct GNUNET_SCALARPRODUCT_Element);
455  env = GNUNET_MQ_msg_extra (mmsg,
456  size,
458  mmsg->element_count_contained = htonl (todo);
459  GNUNET_memcpy (&mmsg[1],
460  &elements[element_count_transfered],
461  size);
462  element_count_transfered += todo;
463  GNUNET_MQ_send (h->mq,
464  env);
465  }
466  return h;
467 }
468 
469 
476 void
478 {
479  if (NULL != h->mq)
480  {
481  GNUNET_MQ_destroy (h->mq);
482  h->mq = NULL;
483  }
484  GNUNET_free (h);
485 }
486 
487 
488 /* end of scalarproduct_api.c */
A handle returned for each computation.
Message type passed from service client to finalize a session as requester or responder.
static int check_response(void *cls, const struct ClientResponseMessage *message)
Called when a response is received from the service.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_MULTIPART_ALICE
Client -> Alice multipart.
struct GNUNET_HashCode key
The shared session key identifying this computation.
struct GNUNET_MQ_Handle * GNUNET_CLIENT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *service_name, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *error_handler_cls)
Create a message queue to connect to a GNUnet service.
Definition: client.c:901
GNUNET_SCALARPRODUCT_DatumProcessor cont_datum
Function to call after transmission of the request (Alice).
uint32_t element_count_total
how many elements the vector in payload contains
Definition: scalarproduct.h:96
GNUNET_MQ_Error
Error codes for the queue.
static void handle_response(void *cls, const struct ClientResponseMessage *message)
Called when a response is received from the service.
int32_t range
Workaround for libgcrypt: -1 if negative, 0 if zero, else 1.
#define LOG_GCRY(level, cmd, rc)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
Definition: scalarproduct.h:35
static void process_result_message(struct GNUNET_SCALARPRODUCT_ComputationHandle *h, const struct ClientResponseMessage *msg, enum GNUNET_SCALARPRODUCT_ResponseStatus status)
Handles the RESULT received from the service for a request, should contain a result MPI value...
static int ok
Return value from &#39;main&#39; (0 == success)
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)
Used by Bob&#39;s client to cooperate with Alice,.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_TO_BOB
Client -> Bob.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
uint32_t reserved
Always zero.
Definition: scalarproduct.h:63
Internal representation of the hash map.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
Message type passed from client to service to initiate a request or responder role.
Definition: scalarproduct.h:42
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:94
struct GNUNET_HashCode session_key
the transaction/session key used to identify a session
Definition: scalarproduct.h:68
static struct GNUNET_CONTAINER_MultiPeerMap * map
Handle to the map used to store old latency values for peers.
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
void GNUNET_SCALARPRODUCT_cancel(struct GNUNET_SCALARPRODUCT_ComputationHandle *h)
Cancel an ongoing computation or revoke our collaboration offer.
uint32_t status
Status information about the outcome of this session, An enum GNUNET_SCALARPRODUCT_ResponseStatus (in...
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
#define GNUNET_memcpy(dst, src, n)
static struct GNUNET_HashCode session_key
the session key identifying this computation
struct GNUNET_MessageHeader header
GNUNET message header.
struct GNUNET_PeerIdentity peer
the identity of a remote peer we want to communicate with
Definition: scalarproduct.h:73
Scalar Product API Message Types.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
#define GNUNET_MIN(a, b)
Definition: gnunet_common.h:83
uint32_t element_count_total
how many elements the vector in payload contains
Definition: scalarproduct.h:53
uint16_t status
See PRISM_STATUS_*-constants.
void(* GNUNET_SCALARPRODUCT_ResponseMessageHandler)(struct GNUNET_SCALARPRODUCT_ComputationHandle *h, const struct ClientResponseMessage *msg, enum GNUNET_SCALARPRODUCT_ResponseStatus status)
The abstraction function for our internal callback.
static int result
Global testing status.
static void process_status_message(struct GNUNET_SCALARPRODUCT_ComputationHandle *h, const struct ClientResponseMessage *msg, enum GNUNET_SCALARPRODUCT_ResponseStatus status)
Handles the STATUS received from the service for a response, does not contain a payload.
We got disconnected from the SCALARPRODUCT service.
A 512-bit hashcode.
static void mq_error_handler(void *cls, enum GNUNET_MQ_Error error)
We encountered an error communicating with the set service while performing a set operation...
Message handler for a specific message type.
void(* GNUNET_SCALARPRODUCT_DatumProcessor)(void *cls, enum GNUNET_SCALARPRODUCT_ResponseStatus status, gcry_mpi_t result)
Process a datum that was stored in the scalarproduct.
There must only be one value per key; storing a value should fail if a value under the same key alrea...
#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_TO_ALICE
Client -> Alice.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
static unsigned int size
Size of the "table".
Definition: peer.c:67
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
uint32_t product_length
0 if no product attached
GNUNET_SCALARPRODUCT_ContinuationWithStatus cont_status
Function to call after transmission of the request (Bob).
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
uint32_t element_count_contained
contained elements the vector in payload contains
Handle to a message queue.
Definition: mq.c:85
The identity of the host (wraps the signing key of the peer).
configuration data
Definition: configuration.c:85
#define GNUNET_log(kind,...)
uint32_t element_count_contained
contained elements the vector in payload contains
Definition: scalarproduct.h:58
#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_MULTIPART_BOB
Client -> Bob multipart.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
static struct MHD_Response * response
Our canonical response.
uint32_t element_count_contained
contained elements the vector in payload contains
multipart messages following struct ComputationMessage
Message type passed from client to service to initiate a request or responder role.
Definition: scalarproduct.h:85
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:824
#define GNUNET_YES
Definition: gnunet_common.h:80
void * cont_cls
Closure for cont_status or cont_datum.
struct GNUNET_HashCode session_key
the transaction/session key used to identify a session
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:353
#define LOG(kind,...)
GNUNET_SCALARPRODUCT_ResponseStatus
Result status values for the computation.
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
GNUNET_SCALARPRODUCT_ResponseMessageHandler response_proc
API internal callback for results and failures to be forwarded to the client.
GNUNET_NETWORK_STRUCT_END typedef void(* GNUNET_SCALARPRODUCT_ContinuationWithStatus)(void *cls, enum GNUNET_SCALARPRODUCT_ResponseStatus status)
Continuation called to notify client about result of the operation.
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)
Request by Alice&#39;s client for computing a scalar product.
struct GNUNET_MQ_Handle * mq
Current connection to the scalarproduct service.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
static int check_unique(const struct GNUNET_SCALARPRODUCT_Element *elements, uint32_t element_count)
Check if the keys for all given elements are unique.
An element key-value pair for scalarproduct.
#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_RESULT
Alice/Bob -> Client Result.
#define GNUNET_free(ptr)
Wrapper around free.