GNUnet  0.11.x
set_api.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2012-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  */
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28 #include "gnunet_protocols.h"
29 #include "gnunet_set_service.h"
30 #include "set.h"
31 
32 
33 #define LOG(kind, ...) GNUNET_log_from (kind, "set-api", __VA_ARGS__)
34 
36 {
38 
40 
41  void *cls;
42 
44 };
45 
50 {
55 
60 
65 
71 
75  void *iterator_cls;
76 
83 
87  int invalid;
88 
93  uint16_t iteration_id;
94 
99 
104 
109 };
110 
111 
116 {
121  uint32_t accept_id;
122 
127  int accepted;
128 };
129 
130 
136 {
142 
146  void *result_cls;
147 
152  struct GNUNET_SET_Handle *set;
153 
159 
164  uint32_t *request_id_addr;
165 
170 
175 
179  uint32_t request_id;
180 };
181 
182 
187 {
192 
199 
205 
209  void *listen_cls;
210 
215 
219  struct GNUNET_TIME_Relative reconnect_backoff;
220 
225 
229  enum GNUNET_SET_OperationType operation;
230 };
231 
232 
233 /* mutual recursion with handle_copy_lazy */
234 static struct GNUNET_SET_Handle *
237  const uint32_t *cookie);
238 
239 
247 static void
250 {
251  struct GNUNET_SET_Handle *set = cls;
252  struct SetCopyRequest *req;
253  struct GNUNET_SET_Handle *new_set;
254 
255  req = set->copy_req_head;
256  if (NULL == req)
257  {
258  /* Service sent us unsolicited lazy copy response */
259  GNUNET_break (0);
260  return;
261  }
262 
264  "Handling response to lazy copy\n");
265  GNUNET_CONTAINER_DLL_remove (set->copy_req_head,
266  set->copy_req_tail,
267  req);
268  // We pass none as operation here, since it doesn't matter when
269  // cloning.
270  new_set = create_internal (set->cfg,
272  &msg->cookie);
273  req->cb (req->cls, new_set);
274  GNUNET_free (req);
275 }
276 
277 
285 static int
287  const struct GNUNET_SET_IterResponseMessage *msg)
288 {
289  /* minimum size was already checked, everything else is OK! */
290  return GNUNET_OK;
291 }
292 
293 
301 static void
303  const struct GNUNET_SET_IterResponseMessage *msg)
304 {
305  struct GNUNET_SET_Handle *set = cls;
306  GNUNET_SET_ElementIterator iter = set->iterator;
307  struct GNUNET_SET_Element element;
308  struct GNUNET_SET_IterAckMessage *ack_msg;
309  struct GNUNET_MQ_Envelope *ev;
310  uint16_t msize;
311 
313  "Received element in set iteration\n");
314  msize = ntohs (msg->header.size);
315  if (set->iteration_id != ntohs (msg->iteration_id))
316  {
317  /* element from a previous iteration, skip! */
318  iter = NULL;
319  }
320  if (NULL != iter)
321  {
322  element.size = msize - sizeof(struct GNUNET_SET_IterResponseMessage);
323  element.element_type = ntohs (msg->element_type);
324  element.data = &msg[1];
325  iter (set->iterator_cls,
326  &element);
327  }
328  ev = GNUNET_MQ_msg (ack_msg,
330  ack_msg->send_more = htonl ((NULL != iter));
331  GNUNET_MQ_send (set->mq, ev);
332 }
333 
334 
342 static void
344  const struct GNUNET_MessageHeader *mh)
345 {
346  struct GNUNET_SET_Handle *set = cls;
347  GNUNET_SET_ElementIterator iter = set->iterator;
348 
349  if (NULL == iter)
350  {
351  /* FIXME: if this is true, could cancel+start a fresh one
352  cause elements to go to the wrong iteration? */
354  "Service completed set iteration that was already cancelled\n");
355  return;
356  }
358  "Set iteration completed\n");
359  set->destroy_requested = GNUNET_SYSERR;
360  set->iterator = NULL;
361  set->iteration_id++;
362  iter (set->iterator_cls,
363  NULL);
364  if (GNUNET_SYSERR == set->destroy_requested)
365  set->destroy_requested = GNUNET_NO;
366  if (GNUNET_YES == set->destroy_requested)
367  GNUNET_SET_destroy (set);
368 }
369 
370 
378 static int
380  const struct GNUNET_SET_ResultMessage *msg)
381 {
382  /* minimum size was already checked, everything else is OK! */
383  return GNUNET_OK;
384 }
385 
386 
393 static void
395  const struct GNUNET_SET_ResultMessage *msg)
396 {
397  struct GNUNET_SET_Handle *set = cls;
399  struct GNUNET_SET_Element e;
400  enum GNUNET_SET_Status result_status;
401  int destroy_set;
402 
403  GNUNET_assert (NULL != set->mq);
404  result_status = (enum GNUNET_SET_Status) ntohs (msg->result_status);
406  "Got result message with status %d\n",
407  result_status);
408 
409  oh = GNUNET_MQ_assoc_get (set->mq,
410  ntohl (msg->request_id));
411  if (NULL == oh)
412  {
413  /* 'oh' can be NULL if we canceled the operation, but the service
414  did not get the cancel message yet. */
416  "Ignoring result from canceled operation\n");
417  return;
418  }
419 
420  switch (result_status)
421  {
425  goto do_element;
426 
429  goto do_final;
430 
432  /* not used anymore */
433  GNUNET_assert (0);
434  }
435 
436 do_final:
438  "Treating result as final status\n");
439  GNUNET_MQ_assoc_remove (set->mq,
440  ntohl (msg->request_id));
441  GNUNET_CONTAINER_DLL_remove (set->ops_head,
442  set->ops_tail,
443  oh);
444  /* Need to do this calculation _before_ the result callback,
445  as IF the application still has a valid set handle, it
446  may trigger destruction of the set during the callback. */
447  destroy_set = (GNUNET_YES == set->destroy_requested) &&
448  (NULL == set->ops_head);
449  if (NULL != oh->result_cb)
450  {
451  oh->result_cb (oh->result_cls,
452  NULL,
454  result_status);
455  }
456  else
457  {
459  "No callback for final status\n");
460  }
461  if (destroy_set)
462  GNUNET_SET_destroy (set);
463  GNUNET_free (oh);
464  return;
465 
466 do_element:
468  "Treating result as element\n");
469  e.data = &msg[1];
470  e.size = ntohs (msg->header.size) - sizeof(struct GNUNET_SET_ResultMessage);
471  e.element_type = ntohs (msg->element_type);
472  if (NULL != oh->result_cb)
473  oh->result_cb (oh->result_cls,
474  &e,
476  result_status);
477 }
478 
479 
485 static void
487 {
488  struct GNUNET_SET_Handle *set = oh->set;
489  struct GNUNET_SET_OperationHandle *h_assoc;
490 
491  if (NULL != oh->conclude_mqm)
493  /* is the operation already commited? */
494  if (NULL != set)
495  {
497  set->ops_tail,
498  oh);
499  h_assoc = GNUNET_MQ_assoc_remove (set->mq,
500  oh->request_id);
501  GNUNET_assert ((NULL == h_assoc) ||
502  (h_assoc == oh));
503  }
504  GNUNET_free (oh);
505 }
506 
507 
515 void
517 {
518  struct GNUNET_SET_Handle *set = oh->set;
519  struct GNUNET_SET_CancelMessage *m;
520  struct GNUNET_MQ_Envelope *mqm;
521 
523  "Cancelling SET operation\n");
524  if (NULL != set)
525  {
527  m->request_id = htonl (oh->request_id);
528  GNUNET_MQ_send (set->mq, mqm);
529  }
531  if ((NULL != set) &&
532  (GNUNET_YES == set->destroy_requested) &&
533  (NULL == set->ops_head))
534  {
536  "Destroying set after operation cancel\n");
537  GNUNET_SET_destroy (set);
538  }
539 }
540 
541 
549 static void
551  enum GNUNET_MQ_Error error)
552 {
553  struct GNUNET_SET_Handle *set = cls;
554  GNUNET_SET_ElementIterator iter = set->iterator;
555 
557  "Handling client set error %d\n",
558  error);
559  while (NULL != set->ops_head)
560  {
561  if ((NULL != set->ops_head->result_cb) &&
562  (GNUNET_NO == set->destroy_requested))
563  set->ops_head->result_cb (set->ops_head->result_cls,
564  NULL,
565  0,
567  set_operation_destroy (set->ops_head);
568  }
569  set->iterator = NULL;
570  set->iteration_id++;
571  set->invalid = GNUNET_YES;
572  if (NULL != iter)
573  iter (set->iterator_cls,
574  NULL);
575 }
576 
577 
581 static struct GNUNET_SET_Handle *
584  const uint32_t *cookie)
585 {
586  struct GNUNET_SET_Handle *set = GNUNET_new (struct GNUNET_SET_Handle);
587  struct GNUNET_MQ_MessageHandler mq_handlers[] = {
591  set),
592  GNUNET_MQ_hd_var_size (iter_element,
595  set),
596  GNUNET_MQ_hd_fixed_size (iter_done,
598  struct GNUNET_MessageHeader,
599  set),
600  GNUNET_MQ_hd_fixed_size (copy_lazy,
603  set),
605  };
606  struct GNUNET_MQ_Envelope *mqm;
607  struct GNUNET_SET_CreateMessage *create_msg;
608  struct GNUNET_SET_CopyLazyConnectMessage *copy_msg;
609 
610  set->cfg = cfg;
611  set->mq = GNUNET_CLIENT_connect (cfg,
612  "set",
613  mq_handlers,
615  set);
616  if (NULL == set->mq)
617  {
618  GNUNET_free (set);
619  return NULL;
620  }
621  if (NULL == cookie)
622  {
624  "Creating new set (operation %u)\n",
625  op);
626  mqm = GNUNET_MQ_msg (create_msg,
628  create_msg->operation = htonl (op);
629  }
630  else
631  {
633  "Creating new set (lazy copy)\n",
634  op);
635  mqm = GNUNET_MQ_msg (copy_msg,
637  copy_msg->cookie = *cookie;
638  }
639  GNUNET_MQ_send (set->mq,
640  mqm);
641  return set;
642 }
643 
644 
656 struct GNUNET_SET_Handle *
659 {
660  struct GNUNET_SET_Handle *set;
661 
662  set = create_internal (cfg,
663  op,
664  NULL);
666  "Creating set %p for operation %d\n",
667  set,
668  op);
669  return set;
670 }
671 
672 
686 int
688  const struct GNUNET_SET_Element *element,
690  void *cont_cls)
691 {
692  struct GNUNET_MQ_Envelope *mqm;
694 
696  "adding element of type %u to set %p\n",
697  (unsigned int) element->element_type,
698  set);
699  GNUNET_assert (NULL != set);
700  if (GNUNET_YES == set->invalid)
701  {
702  if (NULL != cont)
703  cont (cont_cls);
704  return GNUNET_SYSERR;
705  }
706  mqm = GNUNET_MQ_msg_extra (msg,
707  element->size,
709  msg->element_type = htons (element->element_type);
710  GNUNET_memcpy (&msg[1],
711  element->data,
712  element->size);
714  cont, cont_cls);
715  GNUNET_MQ_send (set->mq, mqm);
716  return GNUNET_OK;
717 }
718 
719 
733 int
735  const struct GNUNET_SET_Element *element,
737  void *cont_cls)
738 {
739  struct GNUNET_MQ_Envelope *mqm;
741 
743  "Removing element from set %p\n",
744  set);
745  if (GNUNET_YES == set->invalid)
746  {
747  if (NULL != cont)
748  cont (cont_cls);
749  return GNUNET_SYSERR;
750  }
751  mqm = GNUNET_MQ_msg_extra (msg,
752  element->size,
754  msg->element_type = htons (element->element_type);
755  GNUNET_memcpy (&msg[1],
756  element->data,
757  element->size);
759  cont, cont_cls);
760  GNUNET_MQ_send (set->mq, mqm);
761  return GNUNET_OK;
762 }
763 
764 
771 void
773 {
774  /* destroying set while iterator is active is currently
775  not supported; we should expand the API to allow
776  clients to explicitly cancel the iteration! */
777  GNUNET_assert (NULL != set);
778  if ((NULL != set->ops_head) ||
779  (NULL != set->iterator) ||
780  (GNUNET_SYSERR == set->destroy_requested))
781  {
783  "Set operations are pending, delaying set destruction\n");
784  set->destroy_requested = GNUNET_YES;
785  return;
786  }
788  "Really destroying set\n");
789  if (NULL != set->mq)
790  {
791  GNUNET_MQ_destroy (set->mq);
792  set->mq = NULL;
793  }
794  GNUNET_free (set);
795 }
796 
797 
813 GNUNET_SET_prepare (const struct GNUNET_PeerIdentity *other_peer,
814  const struct GNUNET_HashCode *app_id,
815  const struct GNUNET_MessageHeader *context_msg,
816  enum GNUNET_SET_ResultMode result_mode,
817  struct GNUNET_SET_Option options[],
819  void *result_cls)
820 {
821  struct GNUNET_MQ_Envelope *mqm;
824  struct GNUNET_SET_Option *opt;
825 
827  "Client prepares set operation (%d)\n",
828  result_mode);
830  oh->result_cb = result_cb;
831  oh->result_cls = result_cls;
832  mqm = GNUNET_MQ_msg_nested_mh (msg,
834  context_msg);
835  msg->app_id = *app_id;
836  msg->result_mode = htonl (result_mode);
837  msg->target_peer = *other_peer;
838  for (opt = options; opt->type != 0; opt++)
839  {
840  switch (opt->type)
841  {
843  msg->byzantine = GNUNET_YES;
844  msg->byzantine_lower_bound = opt->v.num;
845  break;
846 
848  msg->force_full = GNUNET_YES;
849  break;
850 
852  msg->force_delta = GNUNET_YES;
853  break;
854 
855  default:
857  "Option with type %d not recognized\n", (int) opt->type);
858  }
859  }
860  oh->conclude_mqm = mqm;
861  oh->request_id_addr = &msg->request_id;
862 
863  return oh;
864 }
865 
866 
872 static void
873 listen_connect (void *cls);
874 
875 
883 static int
885  const struct GNUNET_SET_RequestMessage *msg)
886 {
887  const struct GNUNET_MessageHeader *context_msg;
888 
889  if (ntohs (msg->header.size) == sizeof(*msg))
890  return GNUNET_OK; /* no context message is OK */
891  context_msg = GNUNET_MQ_extract_nested_mh (msg);
892  if (NULL == context_msg)
893  {
894  /* malformed context message is NOT ok */
895  GNUNET_break_op (0);
896  return GNUNET_SYSERR;
897  }
898  return GNUNET_OK;
899 }
900 
901 
908 static void
910  const struct GNUNET_SET_RequestMessage *msg)
911 {
912  struct GNUNET_SET_ListenHandle *lh = cls;
913  struct GNUNET_SET_Request req;
914  const struct GNUNET_MessageHeader *context_msg;
915  struct GNUNET_MQ_Envelope *mqm;
916  struct GNUNET_SET_RejectMessage *rmsg;
917 
919  "Processing incoming operation request with id %u\n",
920  ntohl (msg->accept_id));
921  /* we got another valid request => reset the backoff */
923  req.accept_id = ntohl (msg->accept_id);
924  req.accepted = GNUNET_NO;
925  context_msg = GNUNET_MQ_extract_nested_mh (msg);
926  /* calling #GNUNET_SET_accept() in the listen cb will set req->accepted */
927  lh->listen_cb (lh->listen_cls,
928  &msg->peer_id,
929  context_msg,
930  &req);
931  if (GNUNET_YES == req.accepted)
932  return; /* the accept-case is handled in #GNUNET_SET_accept() */
934  "Rejected request %u\n",
935  ntohl (msg->accept_id));
936  mqm = GNUNET_MQ_msg (rmsg,
938  rmsg->accept_reject_id = msg->accept_id;
939  GNUNET_MQ_send (lh->mq, mqm);
940 }
941 
942 
950 static void
952  enum GNUNET_MQ_Error error)
953 {
954  struct GNUNET_SET_ListenHandle *lh = cls;
955 
957  "Listener broke down (%d), re-connecting\n",
958  (int) error);
959  GNUNET_MQ_destroy (lh->mq);
960  lh->mq = NULL;
963  lh);
965 }
966 
967 
973 static void
975 {
976  struct GNUNET_SET_ListenHandle *lh = cls;
977  struct GNUNET_MQ_MessageHandler mq_handlers[] = {
981  lh),
983  };
984  struct GNUNET_MQ_Envelope *mqm;
986 
987  lh->reconnect_task = NULL;
988  GNUNET_assert (NULL == lh->mq);
989  lh->mq = GNUNET_CLIENT_connect (lh->cfg,
990  "set",
991  mq_handlers,
993  lh);
994  if (NULL == lh->mq)
995  return;
997  msg->operation = htonl (lh->operation);
998  msg->app_id = lh->app_id;
999  GNUNET_MQ_send (lh->mq,
1000  mqm);
1001 }
1002 
1003 
1016 struct GNUNET_SET_ListenHandle *
1019  const struct GNUNET_HashCode *app_id,
1021  void *listen_cls)
1022 {
1023  struct GNUNET_SET_ListenHandle *lh;
1024 
1026  "Starting listener for app %s\n",
1027  GNUNET_h2s (app_id));
1028  lh = GNUNET_new (struct GNUNET_SET_ListenHandle);
1029  lh->listen_cb = listen_cb;
1030  lh->listen_cls = listen_cls;
1031  lh->cfg = cfg;
1032  lh->operation = operation;
1033  lh->app_id = *app_id;
1035  listen_connect (lh);
1036  if (NULL == lh->mq)
1037  {
1038  GNUNET_free (lh);
1039  return NULL;
1040  }
1041  return lh;
1042 }
1043 
1044 
1050 void
1052 {
1054  "Canceling listener %s\n",
1055  GNUNET_h2s (&lh->app_id));
1056  if (NULL != lh->mq)
1057  {
1058  GNUNET_MQ_destroy (lh->mq);
1059  lh->mq = NULL;
1060  }
1061  if (NULL != lh->reconnect_task)
1062  {
1064  lh->reconnect_task = NULL;
1065  }
1066  GNUNET_free (lh);
1067 }
1068 
1069 
1086  enum GNUNET_SET_ResultMode result_mode,
1087  struct GNUNET_SET_Option options[],
1089  void *result_cls)
1090 {
1091  struct GNUNET_MQ_Envelope *mqm;
1093  struct GNUNET_SET_AcceptMessage *msg;
1094 
1095  GNUNET_assert (GNUNET_NO == request->accepted);
1097  "Client accepts set operation (%d) with id %u\n",
1098  result_mode,
1099  request->accept_id);
1100  request->accepted = GNUNET_YES;
1101  mqm = GNUNET_MQ_msg (msg,
1103  msg->accept_reject_id = htonl (request->accept_id);
1104  msg->result_mode = htonl (result_mode);
1105  oh = GNUNET_new (struct GNUNET_SET_OperationHandle);
1106  oh->result_cb = result_cb;
1107  oh->result_cls = result_cls;
1108  oh->conclude_mqm = mqm;
1109  oh->request_id_addr = &msg->request_id;
1110  return oh;
1111 }
1112 
1113 
1127 int
1129  struct GNUNET_SET_Handle *set)
1130 {
1131  if (NULL != oh->set)
1132  {
1133  /* Some other set was already committed for this
1134  * operation, there is a logic bug in the client of this API */
1135  GNUNET_break (0);
1136  return GNUNET_OK;
1137  }
1138  GNUNET_assert (NULL != set);
1139  if (GNUNET_YES == set->invalid)
1140  return GNUNET_SYSERR;
1142  "Client commits to SET\n");
1143  GNUNET_assert (NULL != oh->conclude_mqm);
1144  oh->set = set;
1145  GNUNET_CONTAINER_DLL_insert (set->ops_head,
1146  set->ops_tail,
1147  oh);
1148  oh->request_id = GNUNET_MQ_assoc_add (set->mq,
1149  oh);
1150  *oh->request_id_addr = htonl (oh->request_id);
1151  GNUNET_MQ_send (set->mq,
1152  oh->conclude_mqm);
1153  oh->conclude_mqm = NULL;
1154  oh->request_id_addr = NULL;
1155  return GNUNET_OK;
1156 }
1157 
1158 
1171 int
1174  void *iter_cls)
1175 {
1176  struct GNUNET_MQ_Envelope *ev;
1177 
1178  GNUNET_assert (NULL != iter);
1179  if (GNUNET_YES == set->invalid)
1180  return GNUNET_SYSERR;
1181  if (NULL != set->iterator)
1182  return GNUNET_NO;
1184  "Iterating over set\n");
1185  set->iterator = iter;
1186  set->iterator_cls = iter_cls;
1188  GNUNET_MQ_send (set->mq, ev);
1189  return GNUNET_YES;
1190 }
1191 
1192 
1193 void
1196  void *cls)
1197 {
1198  struct GNUNET_MQ_Envelope *ev;
1199  struct SetCopyRequest *req;
1200 
1202  "Creating lazy copy of set\n");
1204  GNUNET_MQ_send (set->mq, ev);
1205 
1206  req = GNUNET_new (struct SetCopyRequest);
1207  req->cb = cb;
1208  req->cls = cls;
1209  GNUNET_CONTAINER_DLL_insert (set->copy_req_head,
1210  set->copy_req_tail,
1211  req);
1212 }
1213 
1214 
1222 struct GNUNET_SET_Element *
1224 {
1225  struct GNUNET_SET_Element *copy;
1226 
1227  copy = GNUNET_malloc (element->size + sizeof(struct GNUNET_SET_Element));
1228  copy->size = element->size;
1229  copy->element_type = element->element_type;
1230  copy->data = &copy[1];
1231  GNUNET_memcpy (&copy[1],
1232  element->data,
1233  copy->size);
1234  return copy;
1235 }
1236 
1237 
1245 void
1247  struct GNUNET_HashCode *ret_hash)
1248 {
1250 
1251  /* It's not guaranteed that the element data is always after the element header,
1252  so we need to hash the chunks separately. */
1253  GNUNET_CRYPTO_hash_context_read (ctx, &element->size, sizeof(uint16_t));
1255  sizeof(uint16_t));
1256  GNUNET_CRYPTO_hash_context_read (ctx, element->data, element->size);
1257  GNUNET_CRYPTO_hash_context_finish (ctx, ret_hash);
1258 }
1259 
1260 
1261 /* end of set_api.c */
struct GNUNET_PeerIdentity target_peer
Peer to evaluate the operation with.
Definition: set.h:196
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
static void listen_cb(void *cls)
We have been notified that our listen socket has something to read.
#define GNUNET_MESSAGE_TYPE_SET_CANCEL
Cancel a set operation.
struct GNUNET_SET_Handle * set
Local set used for the operation, NULL if no set has been provided by conclude yet.
Definition: set_api.c:152
struct SetCopyRequest * next
Definition: set_api.c:37
A purely local set that does not support any operation.
struct GNUNET_SET_ListenHandle * GNUNET_SET_listen(const struct GNUNET_CONFIGURATION_Handle *cfg, enum GNUNET_SET_OperationType operation, const struct GNUNET_HashCode *app_id, GNUNET_SET_ListenCallback listen_cb, void *listen_cls)
Wait for set operation requests for the given application id.
Definition: set_api.c:1017
void * result_cls
Closure for result_cb.
Definition: set_api.c:146
union GNUNET_SET_Option::@54 v
Value for the option, only used with some options.
int GNUNET_SET_remove_element(struct GNUNET_SET_Handle *set, const struct GNUNET_SET_Element *element, GNUNET_SET_Continuation cont, void *cont_cls)
Remove an element to the given set.
Definition: set_api.c:734
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static struct GNUNET_VPN_RedirectionRequest * request
Opaque redirection request handle.
Definition: gnunet-vpn.c:41
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
static void handle_iter_element(void *cls, const struct GNUNET_SET_IterResponseMessage *msg)
Handle element for iteration over the set.
Definition: set_api.c:302
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
int GNUNET_SET_add_element(struct GNUNET_SET_Handle *set, const struct GNUNET_SET_Element *element, GNUNET_SET_Continuation cont, void *cont_cls)
Add an element to the given set.
Definition: set_api.c:687
#define GNUNET_MESSAGE_TYPE_SET_ADD
Add element to set.
Handle for a set operation request from another peer.
Definition: set_api.c:115
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
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:1057
void(* GNUNET_SET_ResultIterator)(void *cls, const struct GNUNET_SET_Element *element, uint64_t current_size, enum GNUNET_SET_Status status)
Callback for set operation results.
#define GNUNET_MESSAGE_TYPE_SET_ITER_ELEMENT
Element result for the iterating client.
#define GNUNET_MQ_msg_nested_mh(mvar, type, mh)
Allocate a GNUNET_MQ_Envelope, and append a payload message after the given message struct...
struct GNUNET_MQ_Handle * mq
Message queue for the client.
Definition: set_api.c:191
void * iterator_cls
Closure for iterator.
Definition: set_api.c:75
Element should be added to the result set of the remote peer, i.e.
uint32_t GNUNET_MQ_assoc_add(struct GNUNET_MQ_Handle *mq, void *assoc_data)
Associate the assoc_data in mq with a unique request id.
Definition: mq.c:708
#define GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_RESPONSE
Give the client an ID for connecting to the set&#39;s copy.
Message sent by the service to the client to indicate an element that is removed (set intersection) o...
Definition: set.h:244
messages used for the set api
GNUNET_MQ_Error
Error codes for the queue.
uint32_t request_id
Request ID to identify responses.
Definition: set.h:97
Element stored in a set.
static int check_request(void *cls, const struct GNUNET_SET_RequestMessage *msg)
Check validity of request message for a listen operation.
Definition: set_api.c:884
static void handle_request(void *cls, const struct GNUNET_SET_RequestMessage *msg)
Handle request message for a listen operation.
Definition: set_api.c:909
struct GNUNET_SET_Handle * GNUNET_SET_create(const struct GNUNET_CONFIGURATION_Handle *cfg, enum GNUNET_SET_OperationType op)
Create an empty set, supporting the specified operation.
Definition: set_api.c:657
#define GNUNET_MQ_extract_nested_mh(var)
Return a pointer to the message at the end of the given message.
Element should be added to the result set of the local peer, i.e.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static struct GNUNET_CADET_Handle * mh
Cadet handle.
Definition: gnunet-cadet.c:92
Do not use the optimized set operation, but send full sets.
void * listen_cls
Closure for listen_cb.
Definition: set_api.c:209
struct GNUNET_SET_OperationHandle * ops_tail
Linked list of operations on the set.
Definition: set_api.c:64
#define GNUNET_MESSAGE_TYPE_SET_EVALUATE
Evaluate a set operation.
void(* GNUNET_SET_CopyReadyCallback)(void *cls, struct GNUNET_SET_Handle *copy)
#define GNUNET_MESSAGE_TYPE_SET_RESULT
Create an empty set.
A request for an operation with another client.
Definition: set.h:152
#define GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_PREPARE
Ask the set service to prepare a copy of a set.
struct SetCopyRequest * prev
Definition: set_api.c:39
uint32_t request_id
id the result belongs to
Definition: set.h:259
#define GNUNET_MESSAGE_TYPE_SET_ACCEPT
Accept a set request.
struct SetCopyRequest * copy_req_head
Doubly linked list of copy requests.
Definition: set_api.c:103
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
#define GNUNET_NO
Definition: gnunet_common.h:78
GNUNET_SET_ListenCallback listen_cb
Function to call on a new incoming request, or on error.
Definition: set_api.c:204
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
struct GNUNET_HashContext * GNUNET_CRYPTO_hash_context_start(void)
Start incremental hashing operation.
Definition: crypto_hash.c:466
Set element transmitted by service to client in response to a set iteration request.
Definition: set.h:324
static struct GNUNET_HashCode app_id
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct GNUNET_SET_OperationHandle * GNUNET_SET_prepare(const struct GNUNET_PeerIdentity *other_peer, const struct GNUNET_HashCode *app_id, const struct GNUNET_MessageHeader *context_msg, enum GNUNET_SET_ResultMode result_mode, struct GNUNET_SET_Option options[], GNUNET_SET_ResultIterator result_cb, void *result_cls)
Prepare a set operation to be evaluated with another peer.
Definition: set_api.c:813
Context for cummulative hashing.
Definition: crypto_hash.c:451
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
static void handle_result(void *cls, const struct GNUNET_SET_ResultMessage *msg)
Handle result message for a set operation.
Definition: set_api.c:394
void(* GNUNET_SET_Continuation)(void *cls)
Continuation used for some of the set operations.
uint32_t result_mode
How should results be sent to us? See enum GNUNET_SET_ResultMode.
Definition: set.h:191
uint16_t iteration_id
Both client and service count the number of iterators created so far to match replies with iterators...
Definition: set_api.c:93
void * cls
Definition: set_api.c:41
uint32_t request_id
Request ID to identify the operation within the set.
Definition: set_api.c:179
void GNUNET_SET_copy_lazy(struct GNUNET_SET_Handle *set, GNUNET_SET_CopyReadyCallback cb, void *cls)
Definition: set_api.c:1194
uint8_t force_full
Always send full sets, even if delta operations would be more efficient.
Definition: set.h:219
Success, all elements have been sent (and received).
int(* GNUNET_SET_ElementIterator)(void *cls, const struct GNUNET_SET_Element *element)
Iterator for set elements.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static void handle_copy_lazy(void *cls, const struct GNUNET_SET_CopyLazyResponseMessage *msg)
Handle element for iteration over the set.
Definition: set_api.c:248
#define GNUNET_MESSAGE_TYPE_SET_CREATE
Create a new local set.
void GNUNET_SET_element_hash(const struct GNUNET_SET_Element *element, struct GNUNET_HashCode *ret_hash)
Hash a set element.
Definition: set_api.c:1246
#define GNUNET_MESSAGE_TYPE_SET_REJECT
Reject a set request.
uint16_t element_type
Type of the element to add or remove.
Definition: set.h:291
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
const void * data
Actual data of the element.
enum GNUNET_SET_OptionType type
Type of the option.
uint32_t operation
Operation type, values of enum GNUNET_SET_OperationType
Definition: set.h:69
void GNUNET_SET_destroy(struct GNUNET_SET_Handle *set)
Destroy the set handle if no operations are left, mark the set for destruction otherwise.
Definition: set_api.c:772
uint64_t current_size
Current set size.
Definition: set.h:254
#define LOG(kind,...)
Definition: set_api.c:33
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:104
int accepted
Has the request been accepted already? GNUNET_YES/GNUNET_NO.
Definition: set_api.c:127
struct GNUNET_MQ_Handle * mq
Message queue for client.
Definition: set_api.c:54
#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
int invalid
Has the set become invalid (e.g.
Definition: set_api.c:87
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1253
#define GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_CONNECT
Sent by the client to the server to connect to an existing, lazily copied set.
GNUNET_SET_ResultIterator result_cb
Function to be called when we have a result, or an error.
Definition: set_api.c:141
Only use optimized set operations, even though for this particular set operation they might be much s...
Message sent by the client to the service to ask starting a new set to perform operations with...
Definition: set.h:40
static void handle_iter_done(void *cls, const struct GNUNET_MessageHeader *mh)
Handle message signalling conclusion of iteration over the set.
Definition: set_api.c:343
void GNUNET_MQ_notify_sent(struct GNUNET_MQ_Envelope *ev, GNUNET_SCHEDULER_TaskCallback cb, void *cb_cls)
Call a callback once the envelope has been sent, that is, sending it can not be canceled anymore...
Definition: mq.c:774
The other peer refused to to the operation with us, or something went wrong.
Success, all elements have been returned (but the other peer might still be receiving some from us...
static struct GNUNET_TRANSPORT_OfferHelloHandle * oh
Active HELLO offering to transport service.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
Everything went ok, we are transmitting an element of the result (in set, or to be removed from set...
Message sent by the client to the service to start listening for incoming requests to perform a certa...
Definition: set.h:59
struct GNUNET_TIME_Relative reconnect_backoff
Time to wait until we try to reconnect on failure.
Definition: set_api.c:219
GNUNET_SET_Status
Status for the result callback.
uint8_t force_delta
Always use delta operation instead of sending full sets, even it it&#39;s less efficient.
Definition: set.h:213
uint16_t result_status
Was the evaluation successful? Contains an enum GNUNET_SET_Status in NBO.
Definition: set.h:265
GNUNET_SET_ResultMode
The way results are given to the client.
uint32_t request_id
Id of our set to evaluate, chosen implicitly by the client when it calls GNUNET_SET_commit().
Definition: set.h:207
static int result
Global testing status.
static void listen_connect(void *cls)
Connect to the set service in order to listen for requests.
Definition: set_api.c:974
#define GNUNET_MESSAGE_TYPE_SET_LISTEN
Listen for operation requests.
uint32_t operation
Operation type, values of enum GNUNET_SET_OperationType
Definition: set.h:50
GNUNET_SET_CopyReadyCallback cb
Definition: set_api.c:43
int destroy_requested
Should the set be destroyed once all operations are gone? GNUNET_SYSERR if GNUNET_SET_destroy() must ...
Definition: set_api.c:82
#define GNUNET_MESSAGE_TYPE_SET_ITER_REQUEST
Start iteration over set elements.
A 512-bit hashcode.
#define GNUNET_TIME_UNIT_MILLISECONDS
One millisecond.
Message handler for a specific message type.
Client connects to a lazily copied set.
Definition: set.h:384
Opaque handle to a set.
Definition: set_api.c:49
uint32_t * request_id_addr
Address of the request if in the conclude message, used to patch the request id into the message when...
Definition: set_api.c:164
uint32_t accept_id
Id of the request, used to identify the request when accepting/rejecting it.
Definition: set_api.c:121
struct GNUNET_HashCode app_id
Application ID we listen for.
Definition: set_api.c:214
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition: mq.c:321
static int check_iter_element(void *cls, const struct GNUNET_SET_IterResponseMessage *msg)
Check that the given msg is well-formed.
Definition: set_api.c:286
uint16_t element_type
Type of the element attachted to the message, if any.
Definition: set.h:270
uint8_t byzantine
GNUNET_YES to fail operations where Byzantine faults are suspected
Definition: set.h:225
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
uint32_t result_mode
How should results be sent to us? See enum GNUNET_SET_ResultMode.
Definition: set.h:103
void GNUNET_CRYPTO_hash_context_read(struct GNUNET_HashContext *hc, const void *buf, size_t size)
Add data to be hashed.
Definition: crypto_hash.c:492
uint8_t byzantine_lower_bound
Lower bound for the set size, used only when byzantine mode is enabled.
Definition: set.h:231
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SET_REQUEST.
Definition: set.h:157
Sent to the service by the client in order to cancel a set operation.
Definition: set.h:306
void GNUNET_SET_listen_cancel(struct GNUNET_SET_ListenHandle *lh)
Cancel the given listen operation.
Definition: set_api.c:1051
Message sent by client to service to initiate a set operation as a client (not as listener)...
Definition: set.h:180
Client acknowledges receiving element in iteration.
Definition: set.h:350
GNUNET_SET_ElementIterator iterator
Callback for the current iteration over the set, NULL if no iterator is active.
Definition: set_api.c:70
GNUNET_SET_OperationType
The operation that a set set supports.
Option for set operations.
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
struct GNUNET_SET_OperationHandle * prev
Handles are kept in a linked list.
Definition: set_api.c:169
static int check_result(void *cls, const struct GNUNET_SET_ResultMessage *msg)
Check that the given msg is well-formed.
Definition: set_api.c:379
uint32_t accept_reject_id
ID of the incoming request we want to accept.
Definition: set.h:92
struct SetCopyRequest * copy_req_tail
Doubly linked list of copy requests.
Definition: set_api.c:108
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SET_RESULT.
Definition: set.h:249
#define GNUNET_MESSAGE_TYPE_SET_ITER_ACK
Acknowledge result from iteration.
uint32_t cookie
Temporary name for the copied set.
Definition: set.h:394
Handle to an operation.
Definition: set_api.c:135
Handle to a message queue.
Definition: mq.c:85
struct GNUNET_SET_OperationHandle * ops_head
Linked list of operations on the set.
Definition: set_api.c:59
#define GNUNET_MQ_msg_header(type)
Allocate a GNUNET_MQ_Envelope, where the message only consists of a header.
Definition: gnunet_mq_lib.h:76
The identity of the host (wraps the signing key of the peer).
int GNUNET_SET_commit(struct GNUNET_SET_OperationHandle *oh, struct GNUNET_SET_Handle *set)
Commit a set to be used with a set operation.
Definition: set_api.c:1128
uint32_t accept_reject_id
ID of the incoming request we want to reject.
Definition: set.h:145
static void set_operation_destroy(struct GNUNET_SET_OperationHandle *oh)
Destroy the given set operation.
Definition: set_api.c:486
struct GNUNET_HashCode app_id
application id
Definition: set.h:74
enum GNUNET_SET_OperationType operation
Operation we listen for.
Definition: set_api.c:229
struct GNUNET_MQ_Envelope * conclude_mqm
Message sent to the server on calling conclude, NULL if conclude has been called. ...
Definition: set_api.c:158
configuration data
Definition: configuration.c:85
struct GNUNET_HashCode app_id
Application id.
Definition: set.h:201
uint32_t accept_id
ID of the to identify the request when accepting or rejecting it.
Definition: set.h:163
#define GNUNET_MESSAGE_TYPE_SET_REMOVE
Remove element from set.
void * GNUNET_MQ_assoc_remove(struct GNUNET_MQ_Handle *mq, uint32_t request_id)
Remove the association for a request_id.
Definition: mq.c:752
#define GNUNET_MESSAGE_TYPE_SET_REQUEST
Notify the client of a request from a remote peer.
#define GNUNET_MESSAGE_TYPE_SET_ITER_DONE
Iteration end marker for the client.
Server responds to a lazy copy request.
Definition: set.h:367
uint16_t size
Number of bytes in the buffer pointed to by data.
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:134
Message sent by client to the service to add or remove an element to/from the set.
Definition: set.h:280
struct GNUNET_SET_OperationHandle * next
Handles are kept in a linked list.
Definition: set_api.c:174
Opaque handle to a listen operation.
Definition: set_api.c:186
struct GNUNET_PeerIdentity peer_id
Identity of the requesting peer.
Definition: set.h:168
void GNUNET_SET_operation_cancel(struct GNUNET_SET_OperationHandle *oh)
Cancel the given set operation.
Definition: set_api.c:516
struct GNUNET_SET_Element * GNUNET_SET_element_dup(const struct GNUNET_SET_Element *element)
Create a copy of an element.
Definition: set_api.c:1223
uint32_t cookie
Temporary name for the copied set.
Definition: set.h:377
Header for all communications.
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:824
#define GNUNET_YES
Definition: gnunet_common.h:77
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
static struct GNUNET_SET_Handle * create_internal(const struct GNUNET_CONFIGURATION_Handle *cfg, enum GNUNET_SET_OperationType op, const uint32_t *cookie)
FIXME.
Definition: set_api.c:582
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SET_ITER_ELEMENT.
Definition: set.h:329
uint32_t request_id
ID of the request we want to cancel.
Definition: set.h:316
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
int GNUNET_SET_iterate(struct GNUNET_SET_Handle *set, GNUNET_SET_ElementIterator iter, void *iter_cls)
Iterate over all elements in the given set.
Definition: set_api.c:1172
static void handle_client_listener_error(void *cls, enum GNUNET_MQ_Error error)
Our connection with the set service encountered an error, re-initialize with exponential back-off...
Definition: set_api.c:951
Message sent by a listening client to the service to reject performing the operation with the other p...
Definition: set.h:135
static void handle_client_set_error(void *cls, enum GNUNET_MQ_Error error)
We encountered an error communicating with the set service while performing a set operation...
Definition: set_api.c:550
Message sent by a listening client to the service to accept performing the operation with the other p...
Definition: set.h:82
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration, needed when creating (lazy) copies.
Definition: set_api.c:98
void GNUNET_CRYPTO_hash_context_finish(struct GNUNET_HashContext *hc, struct GNUNET_HashCode *r_hash)
Finish the hash computation.
Definition: crypto_hash.c:509
#define GNUNET_malloc(size)
Wrapper around malloc.
uint16_t element_type
Type of the element attachted to the message, if any.
Definition: set.h:341
void(* GNUNET_SET_ListenCallback)(void *cls, const struct GNUNET_PeerIdentity *other_peer, const struct GNUNET_MessageHeader *context_msg, struct GNUNET_SET_Request *request)
Called when another peer wants to do a set operation with the local peer.
uint16_t iteration_id
To which set iteration does this reponse belong to? First iteration (per client) has counter zero...
Definition: set.h:335
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:48
struct GNUNET_SCHEDULER_Task * reconnect_task
Task for reconnecting when the listener fails.
Definition: set_api.c:224
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
uint16_t element_type
Application-specific element type.
uint32_t send_more
Non-zero if the service should continue sending elements.
Definition: set.h:360
struct GNUNET_SET_OperationHandle * GNUNET_SET_accept(struct GNUNET_SET_Request *request, enum GNUNET_SET_ResultMode result_mode, struct GNUNET_SET_Option options[], GNUNET_SET_ResultIterator result_cb, void *result_cls)
Accept a request we got via GNUNET_SET_listen.
Definition: set_api.c:1085
void * GNUNET_MQ_assoc_get(struct GNUNET_MQ_Handle *mq, uint32_t request_id)
Get the data associated with a request_id in a queue.
Definition: mq.c:736
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966
Fail set operations when the other peer shows weird behavior that might by a Byzantine fault...
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration handle for the listener, stored here to be able to reconnect transparently on connectio...
Definition: set_api.c:198