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 
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 
214  struct GNUNET_HashCode app_id;
215 
220 
225 
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
248 handle_copy_lazy (void *cls,
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");
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;
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
343 handle_iter_done (void *cls,
344  const struct GNUNET_MessageHeader *mh)
345 {
346  struct GNUNET_SET_Handle *set = cls;
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");
360  set->iterator = NULL;
361  set->iteration_id++;
362  iter (set->iterator_cls,
363  NULL);
364  if (GNUNET_SYSERR == set->destroy_requested)
366  if (GNUNET_YES == set->destroy_requested)
367  GNUNET_SET_destroy (set);
368 }
369 
370 
378 static int
379 check_result (void *cls,
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
394 handle_result (void *cls,
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");
440  ntohl (msg->request_id));
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,
453  GNUNET_ntohll (msg->current_size),
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,
475  GNUNET_ntohll (msg->current_size),
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)
492  GNUNET_MQ_discard (oh->conclude_mqm);
493  /* is the operation already committed? */
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;
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,
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  mqm = GNUNET_MQ_msg (copy_msg,
636  copy_msg->cookie = *cookie;
637  }
638  GNUNET_MQ_send (set->mq,
639  mqm);
640  return set;
641 }
642 
643 
655 struct GNUNET_SET_Handle *
658 {
659  struct GNUNET_SET_Handle *set;
660 
661  set = create_internal (cfg,
662  op,
663  NULL);
665  "Creating set %p for operation %d\n",
666  set,
667  op);
668  return set;
669 }
670 
671 
685 int
687  const struct GNUNET_SET_Element *element,
689  void *cont_cls)
690 {
691  struct GNUNET_MQ_Envelope *mqm;
693 
695  "adding element of type %u to set %p\n",
696  (unsigned int) element->element_type,
697  set);
698  GNUNET_assert (NULL != set);
699  if (GNUNET_YES == set->invalid)
700  {
701  if (NULL != cont)
702  cont (cont_cls);
703  return GNUNET_SYSERR;
704  }
705  mqm = GNUNET_MQ_msg_extra (msg,
706  element->size,
708  msg->element_type = htons (element->element_type);
709  GNUNET_memcpy (&msg[1],
710  element->data,
711  element->size);
713  cont, cont_cls);
714  GNUNET_MQ_send (set->mq, mqm);
715  return GNUNET_OK;
716 }
717 
718 
732 int
734  const struct GNUNET_SET_Element *element,
736  void *cont_cls)
737 {
738  struct GNUNET_MQ_Envelope *mqm;
740 
742  "Removing element from set %p\n",
743  set);
744  if (GNUNET_YES == set->invalid)
745  {
746  if (NULL != cont)
747  cont (cont_cls);
748  return GNUNET_SYSERR;
749  }
750  mqm = GNUNET_MQ_msg_extra (msg,
751  element->size,
753  msg->element_type = htons (element->element_type);
754  GNUNET_memcpy (&msg[1],
755  element->data,
756  element->size);
758  cont, cont_cls);
759  GNUNET_MQ_send (set->mq, mqm);
760  return GNUNET_OK;
761 }
762 
763 
770 void
772 {
773  /* destroying set while iterator is active is currently
774  not supported; we should expand the API to allow
775  clients to explicitly cancel the iteration! */
776  GNUNET_assert (NULL != set);
777  if ((NULL != set->ops_head) ||
778  (NULL != set->iterator) ||
780  {
782  "Set operations are pending, delaying set destruction\n");
784  return;
785  }
787  "Really destroying set\n");
788  if (NULL != set->mq)
789  {
790  GNUNET_MQ_destroy (set->mq);
791  set->mq = NULL;
792  }
793  GNUNET_free (set);
794 }
795 
796 
812 GNUNET_SET_prepare (const struct GNUNET_PeerIdentity *other_peer,
813  const struct GNUNET_HashCode *app_id,
814  const struct GNUNET_MessageHeader *context_msg,
815  enum GNUNET_SET_ResultMode result_mode,
816  struct GNUNET_SET_Option options[],
818  void *result_cls)
819 {
820  struct GNUNET_MQ_Envelope *mqm;
823  struct GNUNET_SET_Option *opt;
824 
826  "Client prepares set operation (%d)\n",
827  result_mode);
829  oh->result_cb = result_cb;
830  oh->result_cls = result_cls;
833  context_msg);
834  msg->app_id = *app_id;
835  msg->result_mode = htonl (result_mode);
836  msg->target_peer = *other_peer;
837  for (opt = options; opt->type != 0; opt++)
838  {
839  switch (opt->type)
840  {
842  msg->byzantine = GNUNET_YES;
843  msg->byzantine_lower_bound = opt->v.num;
844  break;
845 
847  msg->force_full = GNUNET_YES;
848  break;
849 
851  msg->force_delta = GNUNET_YES;
852  break;
853 
854  default:
856  "Option with type %d not recognized\n", (int) opt->type);
857  }
858  }
859  oh->conclude_mqm = mqm;
860  oh->request_id_addr = &msg->request_id;
861 
862  return oh;
863 }
864 
865 
871 static void
872 listen_connect (void *cls);
873 
874 
882 static int
883 check_request (void *cls,
884  const struct GNUNET_SET_RequestMessage *msg)
885 {
886  const struct GNUNET_MessageHeader *context_msg;
887 
888  if (ntohs (msg->header.size) == sizeof(*msg))
889  return GNUNET_OK; /* no context message is OK */
890  context_msg = GNUNET_MQ_extract_nested_mh (msg);
891  if (NULL == context_msg)
892  {
893  /* malformed context message is NOT ok */
894  GNUNET_break_op (0);
895  return GNUNET_SYSERR;
896  }
897  return GNUNET_OK;
898 }
899 
900 
907 static void
908 handle_request (void *cls,
909  const struct GNUNET_SET_RequestMessage *msg)
910 {
911  struct GNUNET_SET_ListenHandle *lh = cls;
912  struct GNUNET_SET_Request req;
913  const struct GNUNET_MessageHeader *context_msg;
914  struct GNUNET_MQ_Envelope *mqm;
915  struct GNUNET_SET_RejectMessage *rmsg;
916 
918  "Processing incoming operation request with id %u\n",
919  ntohl (msg->accept_id));
920  /* we got another valid request => reset the backoff */
922  req.accept_id = ntohl (msg->accept_id);
923  req.accepted = GNUNET_NO;
924  context_msg = GNUNET_MQ_extract_nested_mh (msg);
925  /* calling #GNUNET_SET_accept() in the listen cb will set req->accepted */
926  lh->listen_cb (lh->listen_cls,
927  &msg->peer_id,
928  context_msg,
929  &req);
930  if (GNUNET_YES == req.accepted)
931  return; /* the accept-case is handled in #GNUNET_SET_accept() */
933  "Rejected request %u\n",
934  ntohl (msg->accept_id));
935  mqm = GNUNET_MQ_msg (rmsg,
937  rmsg->accept_reject_id = msg->accept_id;
938  GNUNET_MQ_send (lh->mq, mqm);
939 }
940 
941 
949 static void
951  enum GNUNET_MQ_Error error)
952 {
953  struct GNUNET_SET_ListenHandle *lh = cls;
954 
956  "Listener broke down (%d), re-connecting\n",
957  (int) error);
958  GNUNET_MQ_destroy (lh->mq);
959  lh->mq = NULL;
962  lh);
964 }
965 
966 
972 static void
973 listen_connect (void *cls)
974 {
975  struct GNUNET_SET_ListenHandle *lh = cls;
976  struct GNUNET_MQ_MessageHandler mq_handlers[] = {
980  lh),
982  };
983  struct GNUNET_MQ_Envelope *mqm;
985 
986  lh->reconnect_task = NULL;
987  GNUNET_assert (NULL == lh->mq);
988  lh->mq = GNUNET_CLIENT_connect (lh->cfg,
989  "set",
990  mq_handlers,
992  lh);
993  if (NULL == lh->mq)
994  return;
996  msg->operation = htonl (lh->operation);
997  msg->app_id = lh->app_id;
998  GNUNET_MQ_send (lh->mq,
999  mqm);
1000 }
1001 
1002 
1015 struct GNUNET_SET_ListenHandle *
1018  const struct GNUNET_HashCode *app_id,
1020  void *listen_cls)
1021 {
1022  struct GNUNET_SET_ListenHandle *lh;
1023 
1025  "Starting listener for app %s\n",
1026  GNUNET_h2s (app_id));
1027  lh = GNUNET_new (struct GNUNET_SET_ListenHandle);
1028  lh->listen_cb = listen_cb;
1029  lh->listen_cls = listen_cls;
1030  lh->cfg = cfg;
1031  lh->operation = operation;
1032  lh->app_id = *app_id;
1034  listen_connect (lh);
1035  if (NULL == lh->mq)
1036  {
1037  GNUNET_free (lh);
1038  return NULL;
1039  }
1040  return lh;
1041 }
1042 
1043 
1049 void
1051 {
1053  "Canceling listener %s\n",
1054  GNUNET_h2s (&lh->app_id));
1055  if (NULL != lh->mq)
1056  {
1057  GNUNET_MQ_destroy (lh->mq);
1058  lh->mq = NULL;
1059  }
1060  if (NULL != lh->reconnect_task)
1061  {
1063  lh->reconnect_task = NULL;
1064  }
1065  GNUNET_free (lh);
1066 }
1067 
1068 
1085  enum GNUNET_SET_ResultMode result_mode,
1086  struct GNUNET_SET_Option options[],
1088  void *result_cls)
1089 {
1090  struct GNUNET_MQ_Envelope *mqm;
1092  struct GNUNET_SET_AcceptMessage *msg;
1093 
1094  GNUNET_assert (GNUNET_NO == request->accepted);
1096  "Client accepts set operation (%d) with id %u\n",
1097  result_mode,
1098  request->accept_id);
1099  request->accepted = GNUNET_YES;
1100  mqm = GNUNET_MQ_msg (msg,
1102  msg->accept_reject_id = htonl (request->accept_id);
1103  msg->result_mode = htonl (result_mode);
1105  oh->result_cb = result_cb;
1106  oh->result_cls = result_cls;
1107  oh->conclude_mqm = mqm;
1108  oh->request_id_addr = &msg->request_id;
1109  return oh;
1110 }
1111 
1112 
1126 int
1128  struct GNUNET_SET_Handle *set)
1129 {
1130  if (NULL != oh->set)
1131  {
1132  /* Some other set was already committed for this
1133  * operation, there is a logic bug in the client of this API */
1134  GNUNET_break (0);
1135  return GNUNET_OK;
1136  }
1137  GNUNET_assert (NULL != set);
1138  if (GNUNET_YES == set->invalid)
1139  return GNUNET_SYSERR;
1141  "Client commits to SET\n");
1142  GNUNET_assert (NULL != oh->conclude_mqm);
1143  oh->set = set;
1145  set->ops_tail,
1146  oh);
1147  oh->request_id = GNUNET_MQ_assoc_add (set->mq,
1148  oh);
1149  *oh->request_id_addr = htonl (oh->request_id);
1150  GNUNET_MQ_send (set->mq,
1151  oh->conclude_mqm);
1152  oh->conclude_mqm = NULL;
1153  oh->request_id_addr = NULL;
1154  return GNUNET_OK;
1155 }
1156 
1157 
1170 int
1173  void *iter_cls)
1174 {
1175  struct GNUNET_MQ_Envelope *ev;
1176 
1177  GNUNET_assert (NULL != iter);
1178  if (GNUNET_YES == set->invalid)
1179  return GNUNET_SYSERR;
1180  if (NULL != set->iterator)
1181  return GNUNET_NO;
1183  "Iterating over set\n");
1184  set->iterator = iter;
1185  set->iterator_cls = iter_cls;
1187  GNUNET_MQ_send (set->mq, ev);
1188  return GNUNET_YES;
1189 }
1190 
1191 
1192 void
1195  void *cls)
1196 {
1197  struct GNUNET_MQ_Envelope *ev;
1198  struct SetCopyRequest *req;
1199 
1201  "Creating lazy copy of set\n");
1203  GNUNET_MQ_send (set->mq, ev);
1204 
1205  req = GNUNET_new (struct SetCopyRequest);
1206  req->cb = cb;
1207  req->cls = cls;
1209  set->copy_req_tail,
1210  req);
1211 }
1212 
1213 
1221 struct GNUNET_SET_Element *
1223 {
1224  struct GNUNET_SET_Element *copy;
1225 
1226  copy = GNUNET_malloc (element->size + sizeof(struct GNUNET_SET_Element));
1227  copy->size = element->size;
1228  copy->element_type = element->element_type;
1229  copy->data = &copy[1];
1230  GNUNET_memcpy (&copy[1],
1231  element->data,
1232  copy->size);
1233  return copy;
1234 }
1235 
1236 
1244 void
1246  struct GNUNET_HashCode *ret_hash)
1247 {
1249 
1250  /* It's not guaranteed that the element data is always after the element header,
1251  so we need to hash the chunks separately. */
1252  GNUNET_CRYPTO_hash_context_read (ctx, &element->size, sizeof(uint16_t));
1254  sizeof(uint16_t));
1255  GNUNET_CRYPTO_hash_context_read (ctx, element->data, element->size);
1257 }
1258 
1259 
1260 /* end of set_api.c */
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:104
static struct Experiment * e
static struct GNUNET_CADET_Handle * mh
Cadet handle.
Definition: gnunet-cadet.c:92
static void listen_cb(void *cls)
We have been notified that our listen socket has something to read.
static struct GNUNET_TRANSPORT_OfferHelloHandle * oh
Active HELLO offering to transport service.
static int result
Global testing status.
static struct GNUNET_HashCode app_id
static struct GNUNET_VPN_RedirectionRequest * request
Opaque redirection request handle.
Definition: gnunet-vpn.c:41
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
#define GNUNET_log(kind,...)
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:53
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
Definition: gnunet_common.h:95
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_NO
Definition: gnunet_common.h:94
@ GNUNET_SYSERR
Definition: gnunet_common.h:93
struct GNUNET_HashContext * GNUNET_CRYPTO_hash_context_start(void)
Start incremental hashing operation.
Definition: crypto_hash.c:321
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:340
void GNUNET_CRYPTO_hash_context_finish(struct GNUNET_HashContext *hc, struct GNUNET_HashCode *r_hash)
Finish the hash computation.
Definition: crypto_hash.c:364
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:1064
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
GNUNET_MQ_Error
Error codes for the queue.
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:355
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition: mq.c:323
#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_MQ_msg_nested_mh(mvar, type, mh)
Allocate a GNUNET_MQ_Envelope, and append a payload message after the given message struct.
#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
void * GNUNET_MQ_assoc_remove(struct GNUNET_MQ_Handle *mq, uint32_t request_id)
Remove the association for a request_id.
Definition: mq.c:765
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
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:787
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:721
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:749
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:837
#define GNUNET_MQ_extract_nested_mh(var)
Return a pointer to the message at the end of the given message.
#define GNUNET_MESSAGE_TYPE_SET_EVALUATE
Evaluate a set operation.
#define GNUNET_MESSAGE_TYPE_SET_CANCEL
Cancel a set operation.
#define GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_RESPONSE
Give the client an ID for connecting to the set's copy.
#define GNUNET_MESSAGE_TYPE_SET_ADD
Add element to set.
#define GNUNET_MESSAGE_TYPE_SET_REQUEST
Notify the client of a request from a remote peer.
#define GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_PREPARE
Ask the set service to prepare a copy of a set.
#define GNUNET_MESSAGE_TYPE_SET_REJECT
Reject a set request.
#define GNUNET_MESSAGE_TYPE_SET_LISTEN
Listen for operation requests.
#define GNUNET_MESSAGE_TYPE_SET_ITER_ELEMENT
Element result for the iterating client.
#define GNUNET_MESSAGE_TYPE_SET_ACCEPT
Accept a set request.
#define GNUNET_MESSAGE_TYPE_SET_RESULT
Create an empty set.
#define GNUNET_MESSAGE_TYPE_SET_REMOVE
Remove element from set.
#define GNUNET_MESSAGE_TYPE_SET_ITER_REQUEST
Start iteration over set elements.
#define GNUNET_MESSAGE_TYPE_SET_ITER_ACK
Acknowledge result from iteration.
#define GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_CONNECT
Sent by the client to the server to connect to an existing, lazily copied set.
#define GNUNET_MESSAGE_TYPE_SET_ITER_DONE
Iteration end marker for the client.
#define GNUNET_MESSAGE_TYPE_SET_CREATE
Create a new local set.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972
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:1269
GNUNET_SET_Status
Status for the result callback.
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:771
void GNUNET_SET_copy_lazy(struct GNUNET_SET_Handle *set, GNUNET_SET_CopyReadyCallback cb, void *cls)
Definition: set_api.c:1193
void GNUNET_SET_listen_cancel(struct GNUNET_SET_ListenHandle *lh)
Cancel the given listen operation.
Definition: set_api.c:1050
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:733
struct GNUNET_SET_Element * GNUNET_SET_element_dup(const struct GNUNET_SET_Element *element)
Create a copy of an element.
Definition: set_api.c:1222
void(* GNUNET_SET_Continuation)(void *cls)
Continuation used for some of the set operations.
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:656
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:1171
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.
void GNUNET_SET_operation_cancel(struct GNUNET_SET_OperationHandle *oh)
Cancel the given set operation.
Definition: set_api.c:516
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.
GNUNET_SET_ResultMode
The way results are given to the client.
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:812
int(* GNUNET_SET_ElementIterator)(void *cls, const struct GNUNET_SET_Element *element)
Iterator for set elements.
void(* GNUNET_SET_CopyReadyCallback)(void *cls, struct GNUNET_SET_Handle *copy)
GNUNET_SET_OperationType
The operation that a set set supports.
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:1127
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:1084
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:1016
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:686
void GNUNET_SET_element_hash(const struct GNUNET_SET_Element *element, struct GNUNET_HashCode *ret_hash)
Hash a set element.
Definition: set_api.c:1245
@ GNUNET_SET_STATUS_OK
Everything went ok, we are transmitting an element of the result (in set, or to be removed from set,...
@ GNUNET_SET_STATUS_FAILURE
The other peer refused to to the operation with us, or something went wrong.
@ GNUNET_SET_STATUS_ADD_REMOTE
Element should be added to the result set of the remote peer, i.e.
@ GNUNET_SET_STATUS_HALF_DONE
Success, all elements have been returned (but the other peer might still be receiving some from us,...
@ GNUNET_SET_STATUS_DONE
Success, all elements have been sent (and received).
@ GNUNET_SET_STATUS_ADD_LOCAL
Element should be added to the result set of the local peer, i.e.
@ GNUNET_SET_OPTION_FORCE_DELTA
Only use optimized set operations, even though for this particular set operation they might be much s...
@ GNUNET_SET_OPTION_BYZANTINE
Fail set operations when the other peer shows weird behavior that might by a Byzantine fault.
@ GNUNET_SET_OPTION_FORCE_FULL
Do not use the optimized set operation, but send full sets.
@ GNUNET_SET_OPERATION_NONE
A purely local set that does not support any operation.
#define GNUNET_TIME_UNIT_MILLISECONDS
One millisecond.
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
messages used for the set api
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
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
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
static void handle_request(void *cls, const struct GNUNET_SET_RequestMessage *msg)
Handle request message for a listen operation.
Definition: set_api.c:908
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:950
static void handle_result(void *cls, const struct GNUNET_SET_ResultMessage *msg)
Handle result message for a set operation.
Definition: set_api.c:394
static void set_operation_destroy(struct GNUNET_SET_OperationHandle *oh)
Destroy the given set operation.
Definition: set_api.c:486
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
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
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
static void listen_connect(void *cls)
Connect to the set service in order to listen for requests.
Definition: set_api.c:973
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:883
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 LOG(kind,...)
Definition: set_api.c:33
A 512-bit hashcode.
Handle to a message queue.
Definition: mq.c:86
Message handler for a specific message type.
Header for all communications.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
The identity of the host (wraps the signing key of the peer).
Entry in list of pending tasks.
Definition: scheduler.c:135
Message sent by a listening client to the service to accept performing the operation with the other p...
Definition: set.h:83
uint32_t result_mode
How should results be sent to us? See enum GNUNET_SET_ResultMode.
Definition: set.h:103
Sent to the service by the client in order to cancel a set operation.
Definition: set.h:307
Client connects to a lazily copied set.
Definition: set.h:385
uint32_t cookie
Temporary name for the copied set.
Definition: set.h:394
Server responds to a lazy copy request.
Definition: set.h:368
Message sent by the client to the service to ask starting a new set to perform operations with.
Definition: set.h:41
uint32_t operation
Operation type, values of enum GNUNET_SET_OperationType
Definition: set.h:50
Message sent by client to the service to add or remove an element to/from the set.
Definition: set.h:281
Element stored in a set.
uint16_t size
Number of bytes in the buffer pointed to by data.
const void * data
Actual data of the element.
uint16_t element_type
Application-specific element type.
Message sent by client to service to initiate a set operation as a client (not as listener).
Definition: set.h:181
Opaque handle to a set.
Definition: set_api.c:50
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
struct GNUNET_SET_OperationHandle * ops_head
Linked list of operations on the set.
Definition: set_api.c:59
int invalid
Has the set become invalid (e.g.
Definition: set_api.c:87
struct GNUNET_SET_OperationHandle * ops_tail
Linked list of operations on the set.
Definition: set_api.c:64
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
struct GNUNET_MQ_Handle * mq
Message queue for client.
Definition: set_api.c:54
GNUNET_SET_ElementIterator iterator
Callback for the current iteration over the set, NULL if no iterator is active.
Definition: set_api.c:70
struct SetCopyRequest * copy_req_head
Doubly linked list of copy requests.
Definition: set_api.c:103
void * iterator_cls
Closure for iterator.
Definition: set_api.c:75
struct SetCopyRequest * copy_req_tail
Doubly linked list of copy requests.
Definition: set_api.c:108
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration, needed when creating (lazy) copies.
Definition: set_api.c:98
Client acknowledges receiving element in iteration.
Definition: set.h:351
uint32_t send_more
Non-zero if the service should continue sending elements.
Definition: set.h:360
Set element transmitted by service to client in response to a set iteration request.
Definition: set.h:325
Opaque handle to a listen operation.
Definition: set_api.c:187
struct GNUNET_TIME_Relative reconnect_backoff
Time to wait until we try to reconnect on failure.
Definition: set_api.c:219
void * listen_cls
Closure for listen_cb.
Definition: set_api.c:209
struct GNUNET_SCHEDULER_Task * reconnect_task
Task for reconnecting when the listener fails.
Definition: set_api.c:224
struct GNUNET_HashCode app_id
Application ID we listen for.
Definition: set_api.c:214
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
enum GNUNET_SET_OperationType operation
Operation we listen for.
Definition: set_api.c:229
struct GNUNET_MQ_Handle * mq
Message queue for the client.
Definition: set_api.c:191
GNUNET_SET_ListenCallback listen_cb
Function to call on a new incoming request, or on error.
Definition: set_api.c:204
Message sent by the client to the service to start listening for incoming requests to perform a certa...
Definition: set.h:60
Handle to an operation.
Definition: set_api.c:136
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
GNUNET_SET_ResultIterator result_cb
Function to be called when we have a result, or an error.
Definition: set_api.c:141
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
void * result_cls
Closure for result_cb.
Definition: set_api.c:146
struct GNUNET_SET_OperationHandle * prev
Handles are kept in a linked list.
Definition: set_api.c:169
uint32_t request_id
Request ID to identify the operation within the set.
Definition: set_api.c:179
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
struct GNUNET_SET_OperationHandle * next
Handles are kept in a linked list.
Definition: set_api.c:174
Option for set operations.
enum GNUNET_SET_OptionType type
Type of the option.
union GNUNET_SET_Option::@40 v
Value for the option, only used with some options.
Message sent by a listening client to the service to reject performing the operation with the other p...
Definition: set.h:136
uint32_t accept_reject_id
ID of the incoming request we want to reject.
Definition: set.h:145
A request for an operation with another client.
Definition: set.h:153
Handle for a set operation request from another peer.
Definition: set_api.c:116
int accepted
Has the request been accepted already? GNUNET_YES/GNUNET_NO.
Definition: set_api.c:127
uint32_t accept_id
Id of the request, used to identify the request when accepting/rejecting it.
Definition: set_api.c:121
Message sent by the service to the client to indicate an element that is removed (set intersection) o...
Definition: set.h:245
uint16_t result_status
Was the evaluation successful? Contains an enum GNUNET_SET_Status in NBO.
Definition: set.h:265
Time for relative time used by GNUnet, in microseconds.
struct SetCopyRequest * prev
Definition: set_api.c:39
struct SetCopyRequest * next
Definition: set_api.c:37
void * cls
Definition: set_api.c:41
GNUNET_SET_CopyReadyCallback cb
Definition: set_api.c:43