GNUnet  0.11.x
gnunet-service-set.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet
3  Copyright (C) 2013-2017 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 "gnunet-service-set.h"
31 
36 #define INCOMING_CHANNEL_TIMEOUT GNUNET_TIME_UNIT_MINUTES
37 
38 
43 {
48 
53 
57  struct Set *source_set;
58 
62  uint32_t cookie;
63 };
64 
65 
70 struct Listener
71 {
75  struct Listener *next;
76 
80  struct Listener *prev;
81 
87  struct Operation *op_head;
88 
94  struct Operation *op_tail;
95 
100  struct ClientState *cs;
101 
106 
112 
116  enum GNUNET_SET_OperationType operation;
117 };
118 
119 
124 static struct GNUNET_CADET_Handle *cadet;
125 
130 
135 
139 static uint32_t lazy_copy_cookie;
140 
145 
149 static struct Listener *listener_head;
150 
154 static struct Listener *listener_tail;
155 
159 static unsigned int num_clients;
160 
165 static int in_shutdown;
166 
173 static uint32_t suggest_id;
174 
175 
184 static struct Operation *
185 get_incoming (uint32_t id)
186 {
187  for (struct Listener *listener = listener_head; NULL != listener;
189  {
190  for (struct Operation *op = listener->op_head; NULL != op; op = op->next)
191  if (op->suggest_id == id)
192  return op;
193  }
194  return NULL;
195 }
196 
197 
203 static void
205 {
206  struct Listener *listener;
207 
209  "Destroying incoming operation %p\n",
210  op);
211  if (NULL != (listener = op->listener))
212  {
213  GNUNET_CONTAINER_DLL_remove (listener->op_head, listener->op_tail, op);
214  op->listener = NULL;
215  }
216  if (NULL != op->timeout_task)
217  {
219  op->timeout_task = NULL;
220  }
222 }
223 
224 
229 {
234 
238  unsigned int min_op_generation;
239 
243  unsigned int max_op_generation;
244 };
245 
246 
256 static int
257 garbage_collect_cb (void *cls, const struct GNUNET_HashCode *key, void *value)
258 {
259  // struct GarbageContext *gc = cls;
260  // struct ElementEntry *ee = value;
261 
262  // if (GNUNET_YES != ee->removed)
263  // return GNUNET_OK;
264  // if ( (gc->max_op_generation < ee->generation_added) ||
265  // (ee->generation_removed > gc->min_op_generation) )
266  // {
267  // GNUNET_assert (GNUNET_YES ==
268  // GNUNET_CONTAINER_multihashmap_remove (gc->map,
269  // key,
270  // ee));
271  // GNUNET_free (ee);
272  // }
273  return GNUNET_OK;
274 }
275 
276 
284 static void
286 {
287  struct GarbageContext gc;
288 
289  gc.min_op_generation = UINT_MAX;
290  gc.max_op_generation = 0;
291  for (struct Operation *op = set->ops_head; NULL != op; op = op->next)
292  {
293  gc.min_op_generation =
294  GNUNET_MIN (gc.min_op_generation, op->generation_created);
295  gc.max_op_generation =
296  GNUNET_MAX (gc.max_op_generation, op->generation_created);
297  }
298  gc.map = set->content->elements;
299  GNUNET_CONTAINER_multihashmap_iterate (set->content->elements,
301  &gc);
302 }
303 
304 
313 static int
314 is_excluded_generation (unsigned int generation,
315  struct GenerationRange *excluded,
316  unsigned int excluded_size)
317 {
318  for (unsigned int i = 0; i < excluded_size; i++)
319  if ((generation >= excluded[i].start) && (generation < excluded[i].end))
320  return GNUNET_YES;
321  return GNUNET_NO;
322 }
323 
324 
334 static int
336  unsigned int query_generation,
337  struct GenerationRange *excluded,
338  unsigned int excluded_size)
339 {
340  struct MutationEvent *mut;
341  int is_present;
342 
343  GNUNET_assert (NULL != ee->mutations);
344  if (GNUNET_YES ==
345  is_excluded_generation (query_generation, excluded, excluded_size))
346  {
347  GNUNET_break (0);
348  return GNUNET_NO;
349  }
350 
351  is_present = GNUNET_NO;
352 
353  /* Could be made faster with binary search, but lists
354  are small, so why bother. */
355  for (unsigned int i = 0; i < ee->mutations_size; i++)
356  {
357  mut = &ee->mutations[i];
358 
359  if (mut->generation > query_generation)
360  {
361  /* The mutation doesn't apply to our generation
362  anymore. We can'b break here, since mutations aren't
363  sorted by generation. */
364  continue;
365  }
366 
367  if (GNUNET_YES ==
368  is_excluded_generation (mut->generation, excluded, excluded_size))
369  {
370  /* The generation is excluded (because it belongs to another
371  fork via a lazy copy) and thus mutations aren't considered
372  for membership testing. */
373  continue;
374  }
375 
376  /* This would be an inconsistency in how we manage mutations. */
377  if ((GNUNET_YES == is_present) && (GNUNET_YES == mut->added))
378  GNUNET_assert (0);
379  /* Likewise. */
380  if ((GNUNET_NO == is_present) && (GNUNET_NO == mut->added))
381  GNUNET_assert (0);
382 
383  is_present = mut->added;
384  }
385 
386  return is_present;
387 }
388 
389 
397 int
399 {
400  return is_element_of_generation (ee,
401  op->generation_created,
404 }
405 
406 
420 void
422 {
423  struct Set *set = op->set;
424  struct GNUNET_CADET_Channel *channel;
425 
426  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Destroying operation %p\n", op);
427  GNUNET_assert (NULL == op->listener);
428  if (NULL != op->state)
429  {
430  set->vt->cancel (op);
431  op->state = NULL;
432  }
433  if (NULL != set)
434  {
435  GNUNET_CONTAINER_DLL_remove (set->ops_head, set->ops_tail, op);
436  op->set = NULL;
437  }
438  if (NULL != op->context_msg)
439  {
440  GNUNET_free (op->context_msg);
441  op->context_msg = NULL;
442  }
443  if (NULL != (channel = op->channel))
444  {
445  /* This will free op; called conditionally as this helper function
446  is also called from within the channel disconnect handler. */
447  op->channel = NULL;
449  }
450  if ((NULL != set) && (GNUNET_YES == gc))
452  /* We rely on the channel end handler to free 'op'. When 'op->channel' was NULL,
453  * there was a channel end handler that will free 'op' on the call stack. */
454 }
455 
456 
465 static void *
466 client_connect_cb (void *cls,
467  struct GNUNET_SERVICE_Client *c,
468  struct GNUNET_MQ_Handle *mq)
469 {
470  struct ClientState *cs;
471 
472  num_clients++;
473  cs = GNUNET_new (struct ClientState);
474  cs->client = c;
475  cs->mq = mq;
476  return cs;
477 }
478 
479 
488 static int
490  const struct GNUNET_HashCode *key,
491  void *value)
492 {
493  struct ElementEntry *ee = value;
494 
495  GNUNET_free (ee->mutations);
496  GNUNET_free (ee);
497  return GNUNET_YES;
498 }
499 
500 
508 static void
510  struct GNUNET_SERVICE_Client *client,
511  void *internal_cls)
512 {
513  struct ClientState *cs = internal_cls;
514  struct Operation *op;
515  struct Listener *listener;
516  struct Set *set;
517 
518  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client disconnected, cleaning up\n");
519  if (NULL != (set = cs->set))
520  {
521  struct SetContent *content = set->content;
522  struct PendingMutation *pm;
523  struct PendingMutation *pm_current;
524  struct LazyCopyRequest *lcr;
525 
526  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Destroying client's set\n");
527  /* Destroy pending set operations */
528  while (NULL != set->ops_head)
529  _GSS_operation_destroy (set->ops_head, GNUNET_NO);
530 
531  /* Destroy operation-specific state */
532  GNUNET_assert (NULL != set->state);
533  set->vt->destroy_set (set->state);
534  set->state = NULL;
535 
536  /* Clean up ongoing iterations */
537  if (NULL != set->iter)
538  {
540  set->iter = NULL;
541  set->iteration_id++;
542  }
543 
544  /* discard any pending mutations that reference this set */
545  pm = content->pending_mutations_head;
546  while (NULL != pm)
547  {
548  pm_current = pm;
549  pm = pm->next;
550  if (pm_current->set == set)
551  {
553  content->pending_mutations_tail,
554  pm_current);
555  GNUNET_free (pm_current);
556  }
557  }
558 
559  /* free set content (or at least decrement RC) */
560  set->content = NULL;
561  GNUNET_assert (0 != content->refcount);
562  content->refcount--;
563  if (0 == content->refcount)
564  {
565  GNUNET_assert (NULL != content->elements);
568  NULL);
570  content->elements = NULL;
571  GNUNET_free (content);
572  }
573  GNUNET_free (set->excluded_generations);
574  set->excluded_generations = NULL;
575 
576  /* remove set from pending copy requests */
577  lcr = lazy_copy_head;
578  while (NULL != lcr)
579  {
580  struct LazyCopyRequest *lcr_current = lcr;
581 
582  lcr = lcr->next;
583  if (lcr_current->source_set == set)
584  {
585  GNUNET_CONTAINER_DLL_remove (lazy_copy_head,
586  lazy_copy_tail,
587  lcr_current);
588  GNUNET_free (lcr_current);
589  }
590  }
591  GNUNET_free (set);
592  }
593 
594  if (NULL != (listener = cs->listener))
595  {
596  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Destroying client's listener\n");
598  listener->open_port = NULL;
599  while (NULL != (op = listener->op_head))
600  {
602  "Destroying incoming operation `%u' from peer `%s'\n",
603  (unsigned int) op->client_request_id,
604  GNUNET_i2s (&op->peer));
605  incoming_destroy (op);
606  }
607  GNUNET_CONTAINER_DLL_remove (listener_head, listener_tail, listener);
608  GNUNET_free (listener);
609  }
610  GNUNET_free (cs);
611  num_clients--;
612  if ((GNUNET_YES == in_shutdown) && (0 == num_clients))
613  {
614  if (NULL != cadet)
615  {
616  GNUNET_CADET_disconnect (cadet);
617  cadet = NULL;
618  }
619  }
620 }
621 
622 
631 static int
633 {
634  struct Operation *op = cls;
635  struct Listener *listener = op->listener;
636  const struct GNUNET_MessageHeader *nested_context;
637 
638  /* double operation request */
639  if (0 != op->suggest_id)
640  {
641  GNUNET_break_op (0);
642  return GNUNET_SYSERR;
643  }
644  /* This should be equivalent to the previous condition, but can't hurt to check twice */
645  if (NULL == op->listener)
646  {
647  GNUNET_break (0);
648  return GNUNET_SYSERR;
649  }
650  if (listener->operation !=
651  (enum GNUNET_SET_OperationType) ntohl (msg->operation))
652  {
653  GNUNET_break_op (0);
654  return GNUNET_SYSERR;
655  }
656  nested_context = GNUNET_MQ_extract_nested_mh (msg);
657  if ((NULL != nested_context) &&
658  (ntohs (nested_context->size) > GNUNET_SET_CONTEXT_MESSAGE_MAX_SIZE))
659  {
660  GNUNET_break_op (0);
661  return GNUNET_SYSERR;
662  }
663  return GNUNET_OK;
664 }
665 
666 
684 static void
686 {
687  struct Operation *op = cls;
688  struct Listener *listener = op->listener;
689  const struct GNUNET_MessageHeader *nested_context;
690  struct GNUNET_MQ_Envelope *env;
691  struct GNUNET_SET_RequestMessage *cmsg;
692 
693  nested_context = GNUNET_MQ_extract_nested_mh (msg);
694  /* Make a copy of the nested_context (application-specific context
695  information that is opaque to set) so we can pass it to the
696  listener later on */
697  if (NULL != nested_context)
698  op->context_msg = GNUNET_copy_message (nested_context);
699  op->remote_element_count = ntohl (msg->element_count);
700  GNUNET_log (
702  "Received P2P operation request (op %u, port %s) for active listener\n",
703  (uint32_t) ntohl (msg->operation),
704  GNUNET_h2s (&op->listener->app_id));
705  GNUNET_assert (0 == op->suggest_id);
706  if (0 == suggest_id)
707  suggest_id++;
708  op->suggest_id = suggest_id++;
709  GNUNET_assert (NULL != op->timeout_task);
711  op->timeout_task = NULL;
712  env = GNUNET_MQ_msg_nested_mh (cmsg,
714  op->context_msg);
715  GNUNET_log (
717  "Suggesting incoming request with accept id %u to listener %p of client %p\n",
718  op->suggest_id,
719  listener,
720  listener->cs);
721  cmsg->accept_id = htonl (op->suggest_id);
722  cmsg->peer_id = op->peer;
723  GNUNET_MQ_send (listener->cs->mq, env);
724  /* NOTE: GNUNET_CADET_receive_done() will be called in
725  #handle_client_accept() */
726 }
727 
728 
735 static void
736 execute_add (struct Set *set, const struct GNUNET_SET_ElementMessage *msg)
737 {
738  struct GNUNET_SET_Element el;
739  struct ElementEntry *ee;
740  struct GNUNET_HashCode hash;
741 
743  el.size = ntohs (msg->header.size) - sizeof(*msg);
744  el.data = &msg[1];
745  el.element_type = ntohs (msg->element_type);
746  GNUNET_SET_element_hash (&el, &hash);
747  ee = GNUNET_CONTAINER_multihashmap_get (set->content->elements, &hash);
748  if (NULL == ee)
749  {
751  "Client inserts element %s of size %u\n",
752  GNUNET_h2s (&hash),
753  el.size);
754  ee = GNUNET_malloc (el.size + sizeof(*ee));
755  ee->element.size = el.size;
756  GNUNET_memcpy (&ee[1], el.data, el.size);
757  ee->element.data = &ee[1];
759  ee->remote = GNUNET_NO;
760  ee->mutations = NULL;
761  ee->mutations_size = 0;
762  ee->element_hash = hash;
765  set->content->elements,
766  &ee->element_hash,
767  ee,
769  }
770  else if (GNUNET_YES ==
772  set->current_generation,
773  set->excluded_generations,
774  set->excluded_generations_size))
775  {
777  "Client inserted element %s of size %u twice (ignored)\n",
778  GNUNET_h2s (&hash),
779  el.size);
780 
781  /* same element inserted twice */
782  return;
783  }
784 
785  {
786  struct MutationEvent mut = { .generation = set->current_generation,
787  .added = GNUNET_YES };
789  }
790  set->vt->add (set->state, ee);
791 }
792 
793 
800 static void
801 execute_remove (struct Set *set, const struct GNUNET_SET_ElementMessage *msg)
802 {
803  struct GNUNET_SET_Element el;
804  struct ElementEntry *ee;
805  struct GNUNET_HashCode hash;
806 
808  el.size = ntohs (msg->header.size) - sizeof(*msg);
809  el.data = &msg[1];
810  el.element_type = ntohs (msg->element_type);
811  GNUNET_SET_element_hash (&el, &hash);
812  ee = GNUNET_CONTAINER_multihashmap_get (set->content->elements, &hash);
813  if (NULL == ee)
814  {
815  /* Client tried to remove non-existing element. */
817  "Client removes non-existing element of size %u\n",
818  el.size);
819  return;
820  }
822  set->current_generation,
823  set->excluded_generations,
824  set->excluded_generations_size))
825  {
826  /* Client tried to remove element twice */
828  "Client removed element of size %u twice (ignored)\n",
829  el.size);
830  return;
831  }
832  else
833  {
834  struct MutationEvent mut = { .generation = set->current_generation,
835  .added = GNUNET_NO };
836 
838  "Client removes element of size %u\n",
839  el.size);
840 
842  }
843  set->vt->remove (set->state, ee);
844 }
845 
846 
853 static void
854 execute_mutation (struct Set *set, const struct GNUNET_SET_ElementMessage *msg)
855 {
856  switch (ntohs (msg->header.type))
857  {
859  execute_add (set, msg);
860  break;
861 
863  execute_remove (set, msg);
864  break;
865 
866  default:
867  GNUNET_break (0);
868  }
869 }
870 
871 
878 static void
880 {
881  struct PendingMutation *pm;
882 
883  if (0 != set->content->iterator_count)
884  return; /* still cannot do this */
885  while (NULL != (pm = set->content->pending_mutations_head))
886  {
889  pm);
891  "Executing pending mutation on %p.\n",
892  pm->set);
893  execute_mutation (pm->set, pm->msg);
894  GNUNET_free (pm->msg);
895  GNUNET_free (pm);
896  }
897 }
898 
899 
913 static void
915 {
916  int ret;
917  struct ElementEntry *ee;
918  struct GNUNET_MQ_Envelope *ev;
920 
921  GNUNET_assert (NULL != set->iter);
922  do
923  {
925  NULL,
926  (const void **) &ee);
927  if (GNUNET_NO == ret)
928  {
929  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Iteration on %p done.\n", set);
932  set->iter = NULL;
933  set->iteration_id++;
934  GNUNET_assert (set->content->iterator_count > 0);
935  set->content->iterator_count--;
937  GNUNET_MQ_send (set->cs->mq, ev);
938  return;
939  }
940  GNUNET_assert (NULL != ee);
941  }
942  while (GNUNET_NO ==
944  set->iter_generation,
945  set->excluded_generations,
946  set->excluded_generations_size));
948  "Sending iteration element on %p.\n",
949  set);
950  ev = GNUNET_MQ_msg_extra (msg,
951  ee->element.size,
953  GNUNET_memcpy (&msg[1], ee->element.data, ee->element.size);
954  msg->element_type = htons (ee->element.element_type);
955  msg->iteration_id = htons (set->iteration_id);
956  GNUNET_MQ_send (set->cs->mq, ev);
957 }
958 
959 
969 static void
970 handle_client_iterate (void *cls, const struct GNUNET_MessageHeader *m)
971 {
972  struct ClientState *cs = cls;
973  struct Set *set;
974 
975  if (NULL == (set = cs->set))
976  {
977  /* attempt to iterate over a non existing set */
978  GNUNET_break (0);
980  return;
981  }
982  if (NULL != set->iter)
983  {
984  /* Only one concurrent iterate-action allowed per set */
985  GNUNET_break (0);
987  return;
988  }
990  "Iterating set %p in gen %u with %u content elements\n",
991  (void *) set,
992  set->current_generation,
993  GNUNET_CONTAINER_multihashmap_size (set->content->elements));
995  set->content->iterator_count++;
996  set->iter =
997  GNUNET_CONTAINER_multihashmap_iterator_create (set->content->elements);
998  set->iter_generation = set->current_generation;
999  send_client_element (set);
1000 }
1001 
1002 
1011 static void
1013 {
1014  struct ClientState *cs = cls;
1015  struct Set *set;
1016 
1018  "Client created new set (operation %u)\n",
1019  (uint32_t) ntohl (msg->operation));
1020  if (NULL != cs->set)
1021  {
1022  /* There can only be one set per client */
1023  GNUNET_break (0);
1025  return;
1026  }
1027  set = GNUNET_new (struct Set);
1028  switch (ntohl (msg->operation))
1029  {
1031  set->vt = _GSS_intersection_vt ();
1032  break;
1033 
1035  set->vt = _GSS_union_vt ();
1036  break;
1037 
1038  default:
1039  GNUNET_free (set);
1040  GNUNET_break (0);
1042  return;
1043  }
1044  set->operation = (enum GNUNET_SET_OperationType) ntohl (msg->operation);
1045  set->state = set->vt->create ();
1046  if (NULL == set->state)
1047  {
1048  /* initialization failed (i.e. out of memory) */
1049  GNUNET_free (set);
1051  return;
1052  }
1053  set->content = GNUNET_new (struct SetContent);
1054  set->content->refcount = 1;
1055  set->content->elements = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES);
1056  set->cs = cs;
1057  cs->set = set;
1059 }
1060 
1061 
1071 static void
1073 {
1074  struct Operation *op = cls;
1075 
1076  op->timeout_task = NULL;
1078  "Remote peer's incoming request timed out\n");
1079  incoming_destroy (op);
1080 }
1081 
1082 
1099 static void *
1100 channel_new_cb (void *cls,
1101  struct GNUNET_CADET_Channel *channel,
1102  const struct GNUNET_PeerIdentity *source)
1103 {
1104  struct Listener *listener = cls;
1105  struct Operation *op;
1106 
1107  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New incoming channel\n");
1108  op = GNUNET_new (struct Operation);
1109  op->listener = listener;
1110  op->peer = *source;
1111  op->channel = channel;
1112  op->mq = GNUNET_CADET_get_mq (op->channel);
1116  op);
1117  GNUNET_CONTAINER_DLL_insert (listener->op_head, listener->op_tail, op);
1118  return op;
1119 }
1120 
1121 
1138 static void
1139 channel_end_cb (void *channel_ctx, const struct GNUNET_CADET_Channel *channel)
1140 {
1141  struct Operation *op = channel_ctx;
1142 
1143  op->channel = NULL;
1145 }
1146 
1147 
1153 void
1155 {
1156  struct GNUNET_CADET_Channel *channel;
1157 
1158  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "channel_end_cb called\n");
1159  if (NULL != (channel = op->channel))
1160  {
1161  /* This will free op; called conditionally as this helper function
1162  is also called from within the channel disconnect handler. */
1163  op->channel = NULL;
1164  GNUNET_CADET_channel_destroy (channel);
1165  }
1166  if (NULL != op->listener)
1167  {
1168  incoming_destroy (op);
1169  return;
1170  }
1171  if (NULL != op->set)
1172  op->set->vt->channel_death (op);
1173  else
1175  GNUNET_free (op);
1176 }
1177 
1178 
1193 static void
1195  const struct GNUNET_CADET_Channel *channel,
1196  int window_size)
1197 {
1198  /* FIXME: not implemented, we could do flow control here... */
1199 }
1200 
1201 
1208 static void
1210 {
1211  struct ClientState *cs = cls;
1212  struct GNUNET_MQ_MessageHandler cadet_handlers[] =
1213  { GNUNET_MQ_hd_var_size (incoming_msg,
1215  struct OperationRequestMessage,
1216  NULL),
1217  GNUNET_MQ_hd_var_size (union_p2p_ibf,
1219  struct IBFMessage,
1220  NULL),
1221  GNUNET_MQ_hd_var_size (union_p2p_elements,
1224  NULL),
1225  GNUNET_MQ_hd_var_size (union_p2p_offer,
1227  struct GNUNET_MessageHeader,
1228  NULL),
1229  GNUNET_MQ_hd_var_size (union_p2p_inquiry,
1231  struct InquiryMessage,
1232  NULL),
1233  GNUNET_MQ_hd_var_size (union_p2p_demand,
1235  struct GNUNET_MessageHeader,
1236  NULL),
1237  GNUNET_MQ_hd_fixed_size (union_p2p_done,
1239  struct GNUNET_MessageHeader,
1240  NULL),
1241  GNUNET_MQ_hd_fixed_size (union_p2p_over,
1243  struct GNUNET_MessageHeader,
1244  NULL),
1245  GNUNET_MQ_hd_fixed_size (union_p2p_full_done,
1247  struct GNUNET_MessageHeader,
1248  NULL),
1249  GNUNET_MQ_hd_fixed_size (union_p2p_request_full,
1251  struct GNUNET_MessageHeader,
1252  NULL),
1253  GNUNET_MQ_hd_var_size (union_p2p_strata_estimator,
1255  struct StrataEstimatorMessage,
1256  NULL),
1257  GNUNET_MQ_hd_var_size (union_p2p_strata_estimator,
1259  struct StrataEstimatorMessage,
1260  NULL),
1261  GNUNET_MQ_hd_var_size (union_p2p_full_element,
1264  NULL),
1265  GNUNET_MQ_hd_fixed_size (intersection_p2p_element_info,
1268  NULL),
1269  GNUNET_MQ_hd_var_size (intersection_p2p_bf,
1271  struct BFMessage,
1272  NULL),
1273  GNUNET_MQ_hd_fixed_size (intersection_p2p_done,
1275  struct IntersectionDoneMessage,
1276  NULL),
1277  GNUNET_MQ_handler_end () };
1278  struct Listener *listener;
1279 
1280  if (NULL != cs->listener)
1281  {
1282  /* max. one active listener per client! */
1283  GNUNET_break (0);
1285  return;
1286  }
1287  listener = GNUNET_new (struct Listener);
1288  listener->cs = cs;
1289  cs->listener = listener;
1290  listener->app_id = msg->app_id;
1291  listener->operation = (enum GNUNET_SET_OperationType) ntohl (msg->operation);
1292  GNUNET_CONTAINER_DLL_insert (listener_head, listener_tail, listener);
1294  "New listener created (op %u, port %s)\n",
1295  listener->operation,
1296  GNUNET_h2s (&listener->app_id));
1297  listener->open_port = GNUNET_CADET_open_port (cadet,
1298  &msg->app_id,
1299  &channel_new_cb,
1300  listener,
1302  &channel_end_cb,
1303  cadet_handlers);
1305 }
1306 
1307 
1315 static void
1317 {
1318  struct ClientState *cs = cls;
1319  struct Operation *op;
1320 
1321  op = get_incoming (ntohl (msg->accept_reject_id));
1322  if (NULL == op)
1323  {
1324  /* no matching incoming operation for this reject;
1325  could be that the other peer already disconnected... */
1327  "Client rejected unknown operation %u\n",
1328  (unsigned int) ntohl (msg->accept_reject_id));
1330  return;
1331  }
1333  "Peer request (op %u, app %s) rejected by client\n",
1334  op->listener->operation,
1335  GNUNET_h2s (&cs->listener->app_id));
1338 }
1339 
1340 
1347 static int
1349 {
1350  /* NOTE: Technically, we should probably check with the
1351  block library whether the element we are given is well-formed */
1352  return GNUNET_OK;
1353 }
1354 
1355 
1362 static void
1364 {
1365  struct ClientState *cs = cls;
1366  struct Set *set;
1367 
1368  if (NULL == (set = cs->set))
1369  {
1370  /* client without a set requested an operation */
1371  GNUNET_break (0);
1373  return;
1374  }
1376 
1377  if (0 != set->content->iterator_count)
1378  {
1379  struct PendingMutation *pm;
1380 
1381  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Scheduling mutation on set\n");
1382  pm = GNUNET_new (struct PendingMutation);
1383  pm->msg =
1385  pm->set = set;
1386  GNUNET_CONTAINER_DLL_insert_tail (set->content->pending_mutations_head,
1387  set->content->pending_mutations_tail,
1388  pm);
1389  return;
1390  }
1391  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing mutation on set\n");
1392  execute_mutation (set, msg);
1393 }
1394 
1395 
1402 static void
1404 {
1405  struct GenerationRange r;
1406 
1407  if (set->current_generation == set->content->latest_generation)
1408  {
1409  set->content->latest_generation++;
1410  set->current_generation++;
1411  return;
1412  }
1413 
1414  GNUNET_assert (set->current_generation < set->content->latest_generation);
1415 
1416  r.start = set->current_generation + 1;
1417  r.end = set->content->latest_generation + 1;
1418  set->content->latest_generation = r.end;
1419  set->current_generation = r.end;
1420  GNUNET_array_append (set->excluded_generations,
1421  set->excluded_generations_size,
1422  r);
1423 }
1424 
1425 
1435 static int
1437 {
1438  /* FIXME: suboptimal, even if the context below could be NULL,
1439  there are malformed messages this does not check for... */
1440  return GNUNET_OK;
1441 }
1442 
1443 
1452 static void
1454 {
1455  struct ClientState *cs = cls;
1456  struct Operation *op = GNUNET_new (struct Operation);
1457  const struct GNUNET_MQ_MessageHandler cadet_handlers[] =
1458  { GNUNET_MQ_hd_var_size (incoming_msg,
1460  struct OperationRequestMessage,
1461  op),
1462  GNUNET_MQ_hd_var_size (union_p2p_ibf,
1464  struct IBFMessage,
1465  op),
1466  GNUNET_MQ_hd_var_size (union_p2p_elements,
1469  op),
1470  GNUNET_MQ_hd_var_size (union_p2p_offer,
1472  struct GNUNET_MessageHeader,
1473  op),
1474  GNUNET_MQ_hd_var_size (union_p2p_inquiry,
1476  struct InquiryMessage,
1477  op),
1478  GNUNET_MQ_hd_var_size (union_p2p_demand,
1480  struct GNUNET_MessageHeader,
1481  op),
1482  GNUNET_MQ_hd_fixed_size (union_p2p_done,
1484  struct GNUNET_MessageHeader,
1485  op),
1486  GNUNET_MQ_hd_fixed_size (union_p2p_over,
1488  struct GNUNET_MessageHeader,
1489  op),
1490  GNUNET_MQ_hd_fixed_size (union_p2p_full_done,
1492  struct GNUNET_MessageHeader,
1493  op),
1494  GNUNET_MQ_hd_fixed_size (union_p2p_request_full,
1496  struct GNUNET_MessageHeader,
1497  op),
1498  GNUNET_MQ_hd_var_size (union_p2p_strata_estimator,
1500  struct StrataEstimatorMessage,
1501  op),
1502  GNUNET_MQ_hd_var_size (union_p2p_strata_estimator,
1504  struct StrataEstimatorMessage,
1505  op),
1506  GNUNET_MQ_hd_var_size (union_p2p_full_element,
1509  op),
1510  GNUNET_MQ_hd_fixed_size (intersection_p2p_element_info,
1513  op),
1514  GNUNET_MQ_hd_var_size (intersection_p2p_bf,
1516  struct BFMessage,
1517  op),
1518  GNUNET_MQ_hd_fixed_size (intersection_p2p_done,
1520  struct IntersectionDoneMessage,
1521  op),
1522  GNUNET_MQ_handler_end () };
1523  struct Set *set;
1524  const struct GNUNET_MessageHeader *context;
1525 
1526  if (NULL == (set = cs->set))
1527  {
1528  GNUNET_break (0);
1529  GNUNET_free (op);
1531  return;
1532  }
1534  op->peer = msg->target_peer;
1535  op->result_mode = ntohl (msg->result_mode);
1536  op->client_request_id = ntohl (msg->request_id);
1537  op->byzantine = msg->byzantine;
1539  op->force_full = msg->force_full;
1540  op->force_delta = msg->force_delta;
1541  context = GNUNET_MQ_extract_nested_mh (msg);
1542 
1543  /* Advance generation values, so that
1544  mutations won't interfer with the running operation. */
1545  op->set = set;
1546  op->generation_created = set->current_generation;
1547  advance_generation (set);
1548  GNUNET_CONTAINER_DLL_insert (set->ops_head, set->ops_tail, op);
1550  "Creating new CADET channel to port %s for set operation type %u\n",
1551  GNUNET_h2s (&msg->app_id),
1552  set->operation);
1553  op->channel = GNUNET_CADET_channel_create (cadet,
1554  op,
1555  &msg->target_peer,
1556  &msg->app_id,
1558  &channel_end_cb,
1559  cadet_handlers);
1560  op->mq = GNUNET_CADET_get_mq (op->channel);
1561  op->state = set->vt->evaluate (op, context);
1562  if (NULL == op->state)
1563  {
1564  GNUNET_break (0);
1566  return;
1567  }
1569 }
1570 
1571 
1580 static void
1582 {
1583  struct ClientState *cs = cls;
1584  struct Set *set;
1585 
1586  if (NULL == (set = cs->set))
1587  {
1588  /* client without a set acknowledged receiving a value */
1589  GNUNET_break (0);
1591  return;
1592  }
1593  if (NULL == set->iter)
1594  {
1595  /* client sent an ack, but we were not expecting one (as
1596  set iteration has finished) */
1597  GNUNET_break (0);
1599  return;
1600  }
1602  if (ntohl (ack->send_more))
1603  {
1604  send_client_element (set);
1605  }
1606  else
1607  {
1609  set->iter = NULL;
1610  set->iteration_id++;
1611  }
1612 }
1613 
1614 
1621 static void
1623  const struct GNUNET_MessageHeader *mh)
1624 {
1625  struct ClientState *cs = cls;
1626  struct Set *set;
1627  struct LazyCopyRequest *cr;
1628  struct GNUNET_MQ_Envelope *ev;
1629  struct GNUNET_SET_CopyLazyResponseMessage *resp_msg;
1630 
1631  if (NULL == (set = cs->set))
1632  {
1633  /* client without a set requested an operation */
1634  GNUNET_break (0);
1636  return;
1637  }
1639  "Client requested creation of lazy copy\n");
1640  cr = GNUNET_new (struct LazyCopyRequest);
1641  cr->cookie = ++lazy_copy_cookie;
1642  cr->source_set = set;
1643  GNUNET_CONTAINER_DLL_insert (lazy_copy_head, lazy_copy_tail, cr);
1645  resp_msg->cookie = cr->cookie;
1646  GNUNET_MQ_send (set->cs->mq, ev);
1648 }
1649 
1650 
1657 static void
1659  void *cls,
1660  const struct GNUNET_SET_CopyLazyConnectMessage *msg)
1661 {
1662  struct ClientState *cs = cls;
1663  struct LazyCopyRequest *cr;
1664  struct Set *set;
1665  int found;
1666 
1667  if (NULL != cs->set)
1668  {
1669  /* There can only be one set per client */
1670  GNUNET_break (0);
1672  return;
1673  }
1674  found = GNUNET_NO;
1675  for (cr = lazy_copy_head; NULL != cr; cr = cr->next)
1676  {
1677  if (cr->cookie == msg->cookie)
1678  {
1679  found = GNUNET_YES;
1680  break;
1681  }
1682  }
1683  if (GNUNET_NO == found)
1684  {
1685  /* client asked for copy with cookie we don't know */
1686  GNUNET_break (0);
1688  return;
1689  }
1690  GNUNET_CONTAINER_DLL_remove (lazy_copy_head, lazy_copy_tail, cr);
1692  "Client %p requested use of lazy copy\n",
1693  cs);
1694  set = GNUNET_new (struct Set);
1695  switch (cr->source_set->operation)
1696  {
1698  set->vt = _GSS_intersection_vt ();
1699  break;
1700 
1702  set->vt = _GSS_union_vt ();
1703  break;
1704 
1705  default:
1706  GNUNET_assert (0);
1707  return;
1708  }
1709 
1710  if (NULL == set->vt->copy_state)
1711  {
1712  /* Lazy copy not supported for this set operation */
1713  GNUNET_break (0);
1714  GNUNET_free (set);
1715  GNUNET_free (cr);
1717  return;
1718  }
1719 
1720  set->operation = cr->source_set->operation;
1721  set->state = set->vt->copy_state (cr->source_set->state);
1722  set->content = cr->source_set->content;
1723  set->content->refcount++;
1724 
1725  set->current_generation = cr->source_set->current_generation;
1726  set->excluded_generations_size = cr->source_set->excluded_generations_size;
1727  set->excluded_generations =
1729  set->excluded_generations_size
1730  * sizeof(struct GenerationRange));
1731 
1732  /* Advance the generation of the new set, so that mutations to the
1733  of the cloned set and the source set are independent. */
1734  advance_generation (set);
1735  set->cs = cs;
1736  cs->set = set;
1737  GNUNET_free (cr);
1739 }
1740 
1741 
1748 static void
1750 {
1751  struct ClientState *cs = cls;
1752  struct Set *set;
1753  struct Operation *op;
1754  int found;
1755 
1756  if (NULL == (set = cs->set))
1757  {
1758  /* client without a set requested an operation */
1759  GNUNET_break (0);
1761  return;
1762  }
1763  found = GNUNET_NO;
1764  for (op = set->ops_head; NULL != op; op = op->next)
1765  {
1766  if (op->client_request_id == ntohl (msg->request_id))
1767  {
1768  found = GNUNET_YES;
1769  break;
1770  }
1771  }
1772  if (GNUNET_NO == found)
1773  {
1774  /* It may happen that the operation was already destroyed due to
1775  * the other peer disconnecting. The client may not know about this
1776  * yet and try to cancel the (just barely non-existent) operation.
1777  * So this is not a hard error.
1779  "Client canceled non-existent op %u\n",
1780  (uint32_t) ntohl (msg->request_id));
1781  }
1782  else
1783  {
1785  "Client requested cancel for op %u\n",
1786  (uint32_t) ntohl (msg->request_id));
1788  }
1790 }
1791 
1792 
1801 static void
1803 {
1804  struct ClientState *cs = cls;
1805  struct Set *set;
1806  struct Operation *op;
1807  struct GNUNET_SET_ResultMessage *result_message;
1808  struct GNUNET_MQ_Envelope *ev;
1809  struct Listener *listener;
1810 
1811  if (NULL == (set = cs->set))
1812  {
1813  /* client without a set requested to accept */
1814  GNUNET_break (0);
1816  return;
1817  }
1818  op = get_incoming (ntohl (msg->accept_reject_id));
1819  if (NULL == op)
1820  {
1821  /* It is not an error if the set op does not exist -- it may
1822  * have been destroyed when the partner peer disconnected. */
1823  GNUNET_log (
1825  "Client %p accepted request %u of listener %p that is no longer active\n",
1826  cs,
1827  ntohl (msg->accept_reject_id),
1828  cs->listener);
1829  ev = GNUNET_MQ_msg (result_message, GNUNET_MESSAGE_TYPE_SET_RESULT);
1830  result_message->request_id = msg->request_id;
1831  result_message->result_status = htons (GNUNET_SET_STATUS_FAILURE);
1832  GNUNET_MQ_send (set->cs->mq, ev);
1834  return;
1835  }
1837  "Client accepting request %u\n",
1838  (uint32_t) ntohl (msg->accept_reject_id));
1839  listener = op->listener;
1840  op->listener = NULL;
1841  GNUNET_CONTAINER_DLL_remove (listener->op_head, listener->op_tail, op);
1842  op->set = set;
1843  GNUNET_CONTAINER_DLL_insert (set->ops_head, set->ops_tail, op);
1844  op->client_request_id = ntohl (msg->request_id);
1845  op->result_mode = ntohl (msg->result_mode);
1846  op->byzantine = msg->byzantine;
1848  op->force_full = msg->force_full;
1849  op->force_delta = msg->force_delta;
1850 
1851  /* Advance generation values, so that future mutations do not
1852  interfer with the running operation. */
1853  op->generation_created = set->current_generation;
1854  advance_generation (set);
1855  GNUNET_assert (NULL == op->state);
1856  op->state = set->vt->accept (op);
1857  if (NULL == op->state)
1858  {
1859  GNUNET_break (0);
1861  return;
1862  }
1863  /* Now allow CADET to continue, as we did not do this in
1864  #handle_incoming_msg (as we wanted to first see if the
1865  local client would accept the request). */
1868 }
1869 
1870 
1876 static void
1877 shutdown_task (void *cls)
1878 {
1879  /* Delay actual shutdown to allow service to disconnect clients */
1881  if (0 == num_clients)
1882  {
1883  if (NULL != cadet)
1884  {
1885  GNUNET_CADET_disconnect (cadet);
1886  cadet = NULL;
1887  }
1888  }
1889  GNUNET_STATISTICS_destroy (_GSS_statistics, GNUNET_YES);
1890  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "handled shutdown request\n");
1891 }
1892 
1893 
1902 static void
1903 run (void *cls,
1904  const struct GNUNET_CONFIGURATION_Handle *cfg,
1906 {
1907  /* FIXME: need to modify SERVICE (!) API to allow
1908  us to run a shutdown task *after* clients were
1909  forcefully disconnected! */
1911  _GSS_statistics = GNUNET_STATISTICS_create ("set", cfg);
1912  cadet = GNUNET_CADET_connect (cfg);
1913  if (NULL == cadet)
1914  {
1916  _ ("Could not connect to CADET service\n"));
1918  return;
1919  }
1920 }
1921 
1922 
1927  "set",
1929  &run,
1932  NULL,
1933  GNUNET_MQ_hd_fixed_size (client_accept,
1935  struct GNUNET_SET_AcceptMessage,
1936  NULL),
1937  GNUNET_MQ_hd_fixed_size (client_iter_ack,
1940  NULL),
1941  GNUNET_MQ_hd_var_size (client_mutation,
1944  NULL),
1945  GNUNET_MQ_hd_fixed_size (client_create_set,
1947  struct GNUNET_SET_CreateMessage,
1948  NULL),
1949  GNUNET_MQ_hd_fixed_size (client_iterate,
1951  struct GNUNET_MessageHeader,
1952  NULL),
1953  GNUNET_MQ_hd_var_size (client_evaluate,
1956  NULL),
1957  GNUNET_MQ_hd_fixed_size (client_listen,
1959  struct GNUNET_SET_ListenMessage,
1960  NULL),
1961  GNUNET_MQ_hd_fixed_size (client_reject,
1963  struct GNUNET_SET_RejectMessage,
1964  NULL),
1965  GNUNET_MQ_hd_var_size (client_mutation,
1968  NULL),
1969  GNUNET_MQ_hd_fixed_size (client_cancel,
1971  struct GNUNET_SET_CancelMessage,
1972  NULL),
1973  GNUNET_MQ_hd_fixed_size (client_copy_lazy_prepare,
1975  struct GNUNET_MessageHeader,
1976  NULL),
1977  GNUNET_MQ_hd_fixed_size (client_copy_lazy_connect,
1980  NULL),
1982 
1983 
1984 /* end of gnunet-service-set.c */
static void handle_client_create_set(void *cls, const struct GNUNET_SET_CreateMessage *msg)
Called when a client wants to create a new set.
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.
void GNUNET_CONTAINER_multihashmap_iterator_destroy(struct GNUNET_CONTAINER_MultiHashMapIterator *iter)
Destroy a multihashmap iterator.
#define GNUNET_MESSAGE_TYPE_SET_CANCEL
Cancel a set operation.
static uint32_t suggest_id
Counter for allocating unique IDs for clients, used to identify incoming operation requests from remo...
struct GNUNET_ARM_Operation * next
This is a doubly-linked list.
Definition: arm_api.c:45
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition: cadet_api.c:775
const struct SetVT * _GSS_intersection_vt(void)
Get the table with implementing functions for set intersection.
struct Set * set
Set, if associated with the client, otherwise NULL.
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
int GNUNET_CONTAINER_multihashmap_iterator_next(struct GNUNET_CONTAINER_MultiHashMapIterator *iter, struct GNUNET_HashCode *key, const void **value)
Retrieve the next element from the hash map at the iterator&#39;s position.
static struct Listener * listener_tail
Listeners are held in a doubly linked list.
static void handle_client_listen(void *cls, const struct GNUNET_SET_ListenMessage *msg)
Called when a client wants to create a new listener.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
#define GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENTS
Actual set elements.
enum GNUNET_SET_ResultMode result_mode
When are elements sent to the client, and which elements are sent?
State we keep per client.
struct GNUNET_MessageHeader * context_msg
Context message, may be NULL.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
#define GNUNET_array_append(arr, len, element)
Append an element to an array (growing the array by one).
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
struct GenerationRange * excluded_generations
List of generations we have to exclude, due to lazy copies.
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
uint32_t suggest_id
Unique request id for the request from a remote peer, sent to the client, which will accept or reject...
int _GSS_is_element_of_operation(struct ElementEntry *ee, struct Operation *op)
Is element ee part of the set used by op?
#define GNUNET_MESSAGE_TYPE_SET_ADD
Add element to set.
static void handle_client_mutation(void *cls, const struct GNUNET_SET_ElementMessage *msg)
Called when a client wants to add or remove an element to a set it inhabits.
uint32_t element_count
For Intersection: my element count.
struct MutationEvent * mutations
If mutations is not NULL, it contains a list of mutations, ordered by increasing generation.
Opaque handle to the service.
Definition: cadet_api.c:38
Handle to a service.
Definition: service.c:116
#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...
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_OFFER
Tell the other peer which hashes match a given IBF key.
int byzantine_lower_bound
Lower bound for the set size, used only when byzantine mode is enabled.
struct GNUNET_MQ_Handle * mq
MQ to talk to client.
struct PendingMutation * pending_mutations_head
Mutations requested by the client that we&#39;re unable to execute right now because we&#39;re iterating over...
struct GNUNET_CONTAINER_MultiHashMapIterator * GNUNET_CONTAINER_multihashmap_iterator_create(const struct GNUNET_CONTAINER_MultiHashMap *map)
Create an iterator for a multihashmap.
struct SetState * state
Implementation-specific state.
#define GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_RESPONSE
Give the client an ID for connecting to the set&#39;s copy.
#define GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF
Bloom filter message for intersection exchange started by Bob.
Message sent by the service to the client to indicate an element that is removed (set intersection) o...
Definition: set.h:244
uint32_t request_id
Request ID to identify responses.
Definition: set.h:97
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1331
static int check_client_evaluate(void *cls, const struct GNUNET_SET_EvaluateMessage *msg)
Called when a client wants to initiate a set operation with another peer.
Element stored in a set.
struct GNUNET_HashCode element_hash
Hash of the element.
unsigned int refcount
Number of references to the content.
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
uint8_t force_full
Always send full sets, even if delta operations would be more efficient.
Definition: set.h:115
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:39
static void client_disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *client, void *internal_cls)
Clean up after a client has disconnected.
static int check_incoming_msg(void *cls, const struct OperationRequestMessage *msg)
Check a request for a set operation from another peer.
Message containing buckets of an invertible bloom filter.
struct Listener * next
Listeners are held in a doubly linked list.
#define GNUNET_MQ_extract_nested_mh(var)
Return a pointer to the message at the end of the given message.
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
int added
If added is GNUNET_YES, then this is a remove event, otherwise it is an add event.
static uint32_t lazy_copy_cookie
Generator for unique cookie we set per lazy copy request.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
uint32_t cookie
Cookie identifying the request.
static struct GNUNET_CADET_Handle * mh
Cadet handle.
Definition: gnunet-cadet.c:92
uint8_t force_delta
Always use delta operation instead of sending full sets, even it it&#39;s less efficient.
Definition: set.h:109
static void execute_delayed_mutations(struct Set *set)
Execute mutations that were delayed on a set because of pending operations.
#define GNUNET_MESSAGE_TYPE_SET_EVALUATE
Evaluate a set operation.
#define INCOMING_CHANNEL_TIMEOUT
How long do we hold on to an incoming channel if there is no local listener before giving up...
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SET_ADD or GNUNET_MESSAGE_TYPE_SET_REMOVE.
Definition: set.h:286
#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.
unsigned int excluded_generations_size
Number of elements in array excluded_generations.
struct Operation * op_head
Head of DLL of operations this listener is responsible for.
uint32_t request_id
id the result belongs to
Definition: set.h:259
#define GNUNET_MESSAGE_TYPE_SET_ACCEPT
Accept a set request.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
static void shutdown_task(void *cls)
Called to clean up, after a shutdown has been requested.
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
struct GNUNET_CONTAINER_MultiHashMap * elements
Maps struct GNUNET_HashCode * to struct ElementEntry *.
void _GSS_operation_destroy(struct Operation *op, int gc)
Destroy the given operation.
#define GNUNET_memdup(buf, size)
Allocate and initialize a block of memory.
Opaque handle to a channel.
Definition: cadet.h:116
static int is_excluded_generation(unsigned int generation, struct GenerationRange *excluded, unsigned int excluded_size)
Is generation in the range of exclusions?
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
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.
static void handle_client_evaluate(void *cls, const struct GNUNET_SET_EvaluateMessage *msg)
Called when a client wants to initiate a set operation with another peer.
A listener is inhabited by a client, and waits for evaluation requests from remote peers...
static void execute_mutation(struct Set *set, const struct GNUNET_SET_ElementMessage *msg)
Perform a mutation on a set as specified by the msg.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
static int garbage_collect_cb(void *cls, const struct GNUNET_HashCode *key, void *value)
Function invoked to check if an element can be removed from the set&#39;s history because it is no longer...
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
Information about a mutation to apply to a set.
uint32_t result_mode
How should results be sent to us? See enum GNUNET_SET_ResultMode.
Definition: set.h:191
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:531
enum GNUNET_SET_OperationType operation
The type of the operation.
Handle for the service.
static void send_client_element(struct Set *set)
Send the next element of a set to the set&#39;s client.
uint8_t byzantine_lower_bound
Lower bound for the set size, used only when byzantine mode is enabled.
Definition: set.h:127
static int check_client_mutation(void *cls, const struct GNUNET_SET_ElementMessage *msg)
Called when a client wants to add or remove an element to a set it inhabits.
uint8_t force_full
Always send full sets, even if delta operations would be more efficient.
Definition: set.h:219
struct LazyCopyRequest * prev
Kept in a DLL.
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...
#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.
unsigned int generation_created
Generation in which the operation handle was created.
uint16_t element_type
Type of the element to add or remove.
Definition: set.h:291
struct GNUNET_SCHEDULER_Task * timeout_task
Timeout task, if the incoming peer has not been accepted after the timeout, it will be disconnected...
static pa_context * context
Pulseaudio context.
const void * data
Actual data of the element.
struct GNUNET_CADET_Handle * GNUNET_CADET_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the MQ-based cadet service.
Definition: cadet_api.c:910
static void channel_window_cb(void *cls, const struct GNUNET_CADET_Channel *channel, int window_size)
Function called whenever an MQ-channel&#39;s transmission window size changes.
struct Operation * next
Kept in a DLL of the listener, if listener is non-NULL.
uint32_t operation
Operation type, values of enum GNUNET_SET_OperationType
Definition: set.h:69
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
#define _(String)
GNU gettext support macro.
Definition: platform.h:184
struct PendingMutation * next
Mutations are kept in a DLL.
struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
Handle to a client that is connected to a service.
Definition: service.c:250
struct GNUNET_PeerIdentity peer
The identity of the requesting peer.
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:104
GNUNET_SERVICE_MAIN("set", GNUNET_SERVICE_OPTION_NONE, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_fixed_size(client_accept, GNUNET_MESSAGE_TYPE_SET_ACCEPT, struct GNUNET_SET_AcceptMessage, NULL), GNUNET_MQ_hd_fixed_size(client_iter_ack, GNUNET_MESSAGE_TYPE_SET_ITER_ACK, struct GNUNET_SET_IterAckMessage, NULL), GNUNET_MQ_hd_var_size(client_mutation, GNUNET_MESSAGE_TYPE_SET_ADD, struct GNUNET_SET_ElementMessage, NULL), GNUNET_MQ_hd_fixed_size(client_create_set, GNUNET_MESSAGE_TYPE_SET_CREATE, struct GNUNET_SET_CreateMessage, NULL), GNUNET_MQ_hd_fixed_size(client_iterate, GNUNET_MESSAGE_TYPE_SET_ITER_REQUEST, struct GNUNET_MessageHeader, NULL), GNUNET_MQ_hd_var_size(client_evaluate, GNUNET_MESSAGE_TYPE_SET_EVALUATE, struct GNUNET_SET_EvaluateMessage, NULL), GNUNET_MQ_hd_fixed_size(client_listen, GNUNET_MESSAGE_TYPE_SET_LISTEN, struct GNUNET_SET_ListenMessage, NULL), GNUNET_MQ_hd_fixed_size(client_reject, GNUNET_MESSAGE_TYPE_SET_REJECT, struct GNUNET_SET_RejectMessage, NULL), GNUNET_MQ_hd_var_size(client_mutation, GNUNET_MESSAGE_TYPE_SET_REMOVE, struct GNUNET_SET_ElementMessage, NULL), GNUNET_MQ_hd_fixed_size(client_cancel, GNUNET_MESSAGE_TYPE_SET_CANCEL, struct GNUNET_SET_CancelMessage, NULL), GNUNET_MQ_hd_fixed_size(client_copy_lazy_prepare, GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_PREPARE, struct GNUNET_MessageHeader, NULL), GNUNET_MQ_hd_fixed_size(client_copy_lazy_connect, GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_CONNECT, struct GNUNET_SET_CopyLazyConnectMessage, NULL), GNUNET_MQ_handler_end())
Define "main" method using service macro.
#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
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
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#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_P2P_OPERATION_REQUEST
Request a set operation from a remote peer.
struct GNUNET_CADET_Port * GNUNET_CADET_open_port(struct GNUNET_CADET_Handle *h, const struct GNUNET_HashCode *port, GNUNET_CADET_ConnectEventHandler connects, void *connects_cls, GNUNET_CADET_WindowSizeEventHandler window_changes, GNUNET_CADET_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers)
Open a port to receive incomming MQ-based channels.
Definition: cadet_api.c:970
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC
Compressed strata estimator.
Message sent by the client to the service to ask starting a new set to perform operations with...
Definition: set.h:40
static unsigned int num_clients
Number of active clients.
static char * value
Value of the record to add/remove.
Information about an element element in the set.
The other peer refused to to the operation with us, or something went wrong.
unsigned int current_generation
Current generation, that is, number of previously executed operations and lazy copies on the underlyi...
#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.
int remote
GNUNET_YES if the element is a remote element, and does not belong to the operation&#39;s set...
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
#define GNUNET_MAX(a, b)
Definition: gnunet_common.h:95
Message sent by the client to the service to start listening for incoming requests to perform a certa...
Definition: set.h:59
unsigned int max_op_generation
Largest generation for which an operation is still pending.
uint8_t force_delta
Always use delta operation instead of sending full sets, even it it&#39;s less efficient.
Definition: set.h:213
#define GNUNET_MIN(a, b)
Definition: gnunet_common.h:93
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE
Strata estimator.
uint16_t result_status
Was the evaluation successful? Contains an enum GNUNET_SET_Status in NBO.
Definition: set.h:265
A set that supports a specific operation with other peers.
static void handle_client_copy_lazy_prepare(void *cls, const struct GNUNET_MessageHeader *mh)
Handle a request from the client to copy a set.
static int is_element_of_generation(struct ElementEntry *ee, unsigned int query_generation, struct GenerationRange *excluded, unsigned int excluded_size)
Is element ee part of the set during query_generation?
Randomness for IVs etc.
OpChannelDeathImpl channel_death
Callback called in case the CADET channel died.
static void handle_client_cancel(void *cls, const struct GNUNET_SET_CancelMessage *msg)
Handle a request from the client to cancel a running set operation.
static int in_shutdown
Are we in shutdown? if GNUNET_YES and the number of clients drops to zero, disconnect from CADET...
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
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
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DONE
Set operation is done.
#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
static void handle_client_iterate(void *cls, const struct GNUNET_MessageHeader *m)
Called when a client wants to iterate the elements of a set.
struct PendingMutation * pending_mutations_tail
Mutations requested by the client that we&#39;re unable to execute right now because we&#39;re iterating over...
static struct GNUNET_CADET_Handle * cadet
Handle to the cadet service, used to listen for and connect to remote peers.
#define GNUNET_MESSAGE_TYPE_SET_ITER_REQUEST
Start iteration over set elements.
A 512-bit hashcode.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2323
Message handler for a specific message type.
Client connects to a lazily copied set.
Definition: set.h:384
static void incoming_timeout_cb(void *cls)
Timeout happens iff:
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_REQUEST_FULL
Demand the whole element from the other peer, given only the hash code.
Bloom filter messages exchanged for set intersection calculation.
static GstElement * source
Appsrc instance into which we write data for the pipeline.
int force_delta
Always use delta operation instead of sending full sets, even it it&#39;s less efficient.
There must only be one value per key; storing a value should fail if a value under the same key alrea...
static void * channel_new_cb(void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *source)
Method called whenever another peer has added us to a channel the other peer initiated.
uint8_t byzantine
GNUNET_YES to fail operations where Byzantine faults are suspected
Definition: set.h:225
MutationEvent gives information about changes to an element (removal / addition) in a set content...
struct GNUNET_HashCode key
The key used in the DHT.
struct GNUNET_CADET_Port * open_port
The port we are listening on with CADET.
uint32_t result_mode
How should results be sent to us? See enum GNUNET_SET_ResultMode.
Definition: set.h:103
int byzantine
GNUNET_YES to fail operations where Byzantine faults are suspected
uint8_t byzantine_lower_bound
Lower bound for the set size, used only when byzantine mode is enabled.
Definition: set.h:231
#define GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO
Information about the element count for intersection.
struct ClientState * cs
Client that owns the set.
static void handle_incoming_msg(void *cls, const struct OperationRequestMessage *msg)
Handle a request for a set operation from another peer.
Sent to the service by the client in order to cancel a set operation.
Definition: set.h:306
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
Strata estimator together with the peer&#39;s overall set size.
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_OperationType
The operation that a set set supports.
enum GNUNET_SET_OperationType operation
Type of operation supported for this set.
Operation context used to execute a set operation.
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.
static void handle_client_reject(void *cls, const struct GNUNET_SET_RejectMessage *msg)
Called when the listening client rejects an operation request by another peer.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_IBF
Invertible bloom filter.
SetContent stores the actual set elements, which may be shared by multiple generations derived from o...
static void channel_end_cb(void *channel_ctx, const struct GNUNET_CADET_Channel *channel)
Function called whenever a channel is destroyed.
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_SERVICE_Handle *service)
Function called by the service&#39;s run method to run service-specific setup code.
uint32_t accept_reject_id
ID of the incoming request we want to accept.
Definition: set.h:92
#define GNUNET_MESSAGE_TYPE_SET_ITER_ACK
Acknowledge result from iteration.
unsigned int generation
First generation affected by this mutation event.
uint32_t cookie
Temporary name for the copied set.
Definition: set.h:394
struct Set * source_set
Which set are we supposed to copy?
Handle to a message queue.
Definition: mq.c:85
static void handle_client_copy_lazy_connect(void *cls, const struct GNUNET_SET_CopyLazyConnectMessage *msg)
Handle a request from the client to connect to a copy of a set.
static struct LazyCopyRequest * lazy_copy_tail
DLL of lazy copy requests by this client.
static void incoming_destroy(struct Operation *op)
Destroy an incoming request from a remote peer.
During intersection, the first (and possibly second) message send it the number of elements in the se...
#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).
uint32_t accept_reject_id
ID of the incoming request we want to reject.
Definition: set.h:145
struct LazyCopyRequest * next
Kept in a DLL.
two-peer set operations
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Send an ack on the channel to confirm the processing of a message.
Definition: cadet_api.c:888
struct GNUNET_CADET_Channel * GNUNET_CADET_channel_create(struct GNUNET_CADET_Handle *h, void *channel_cls, const struct GNUNET_PeerIdentity *destination, const struct GNUNET_HashCode *port, GNUNET_CADET_WindowSizeEventHandler window_changes, GNUNET_CADET_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers)
Create a new channel towards a remote peer.
Definition: cadet_api.c:1031
struct GNUNET_CADET_Channel * channel
Channel to the peer.
struct GNUNET_HashCode app_id
application id
Definition: set.h:74
struct Set * set
Set this mutation is about.
struct Operation * ops_head
Evaluate operations are held in a linked list.
#define GNUNET_SET_CONTEXT_MESSAGE_MAX_SIZE
Maximum size of a context message for set operation requests.
configuration data
Definition: configuration.c:84
struct GNUNET_HashCode app_id
Application id.
Definition: set.h:201
uint32_t salt
Salt to use for the operation.
struct GNUNET_SERVICE_Client * client
Client this is about.
static void handle_client_accept(void *cls, const struct GNUNET_SET_AcceptMessage *msg)
Handle a request from the client to accept a set operation that came from a remote peer...
uint32_t client_request_id
ID used to identify an operation between service and client.
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.
#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
struct SetContent * content
Content, possibly shared by multiple sets, and thus reference counted.
const struct SetVT * _GSS_union_vt(void)
Get the table with implementing functions for set union.
unsigned int end
Generation after the last excluded generation.
static void execute_add(struct Set *set, const struct GNUNET_SET_ElementMessage *msg)
Add an element to set as specified by msg.
uint16_t size
Number of bytes in the buffer pointed to by data.
common components for the implementation the different set operations
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
#define GNUNET_log(kind,...)
#define GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_DONE
Intersection operation is done.
two-peer set operations
static struct Operation * get_incoming(uint32_t id)
Get the incoming socket associated with the given id.
Message sent by client to the service to add or remove an element to/from the set.
Definition: set.h:280
int iterator_count
Number of concurrently active iterators.
struct GNUNET_SET_Element element
The actual element.
Opaque handle to a port.
Definition: cadet_api.c:79
uint32_t operation
Operation to request, values from enum GNUNET_SET_OperationType
struct Listener * prev
Listeners are held in a doubly linked list.
struct GNUNET_PeerIdentity peer_id
Identity of the requesting peer.
Definition: set.h:168
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE
Request all missing elements from the other peer, based on their sets and the elements we previously ...
uint8_t byzantine
GNUNET_YES to fail operations where Byzantine faults are suspected
Definition: set.h:121
uint32_t cookie
Temporary name for the copied set.
Definition: set.h:377
struct GNUNET_HashCode app_id
Application ID for the operation, used to distinguish multiple operations of the same type with the s...
Header for all communications.
static void handle_client_iter_ack(void *cls, const struct GNUNET_SET_IterAckMessage *ack)
Handle an ack from a client, and send the next element.
void GNUNET_CADET_close_port(struct GNUNET_CADET_Port *p)
Close a port opened with GNUNET_CADET_open_port().
Definition: cadet_api.c:808
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_ELEMENT
Send a set element, not as response to a demand but because we&#39;re sending the full set...
Last message, send to confirm the final set.
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
const struct SetVT * vt
Virtual table for this set.
struct GNUNET_CONTAINER_MultiHashMap * map
Map for which we are garbage collecting removed elements.
Set intersection, only return elements that are in both sets.
static void execute_remove(struct Set *set, const struct GNUNET_SET_ElementMessage *msg)
Remove an element from set as specified by msg.
uint32_t request_id
ID of the request we want to cancel.
Definition: set.h:316
struct ClientState * cs
Client that owns the listener.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_OVER
Request all missing elements from the other peer, based on their sets and the elements we previously ...
struct Listener * listener
Listener, if associated with the client, otherwise NULL.
uint32_t remote_element_count
Remote peers element count.
static void collect_generation_garbage(struct Set *set)
Collect and destroy elements that are not needed anymore, because their lifetime (as determined by th...
struct Operation * op_tail
Tail of DLL of operations this listener is responsible for.
struct OperationState * state
Operation-specific operation state.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
unsigned int start
First generation that is excluded.
static void advance_generation(struct Set *set)
Advance the current generation of a set, adding exclusion ranges if necessary.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
unsigned int mutations_size
Number of elements in the array mutations.
Set union, return all elements that are in at least one of the sets.
static struct LazyCopyRequest * lazy_copy_head
DLL of lazy copy requests by this client.
Message sent by a listening client to the service to reject performing the operation with the other p...
Definition: set.h:135
Lazy copy requests made by a client.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_INQUIRY
Tell the other peer to send us a list of hashes that match an IBF key.
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:837
static int destroy_elements_iterator(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator over hash map entries to free element entries.
struct Listener * listener
Port this operation runs on.
struct GNUNET_SET_ElementMessage * msg
Message that describes the desired mutation.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2242
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
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.
Peer-to-Peer messages for gnunet set.
#define GNUNET_malloc(size)
Wrapper around malloc.
Context for the garbage_collect_cb().
uint16_t element_type
Type of the element attachted to the message, if any.
Definition: set.h:341
void _GSS_operation_destroy2(struct Operation *op)
This function probably should not exist and be replaced by inlining more specific logic in the variou...
uint16_t iteration_id
To which set iteration does this reponse belong to? First iteration (per client) has counter zero...
Definition: set.h:335
static struct Listener * listener_head
Listeners are held in a doubly linked list.
#define GNUNET_free(ptr)
Wrapper around free.
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
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DEMAND
Demand the whole element from the other peer, given only the hash code.
struct GNUNET_MessageHeader * GNUNET_copy_message(const struct GNUNET_MessageHeader *msg)
Create a copy of the given message.
static struct GNUNET_TRANSPORT_PluginMonitor * pm
Handle if we are monitoring plugin session activity.
static void * client_connect_cb(void *cls, struct GNUNET_SERVICE_Client *c, struct GNUNET_MQ_Handle *mq)
Callback called when a client connects to the service.
struct GNUNET_MQ_Handle * GNUNET_CADET_get_mq(const struct GNUNET_CADET_Channel *channel)
Obtain the message queue for a connected peer.
Definition: cadet_api.c:1082
int force_full
Always send full sets, even if delta operations would be more efficient.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972
unsigned int min_op_generation
Lowest generation for which an operation is still pending.