GNUnet  0.10.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 
66 
71 struct Listener
72 {
76  struct Listener *next;
77 
81  struct Listener *prev;
82 
88  struct Operation *op_head;
89 
95  struct Operation *op_tail;
96 
101  struct ClientState *cs;
102 
107 
113 
117  enum GNUNET_SET_OperationType operation;
118 };
119 
120 
125 static struct GNUNET_CADET_Handle *cadet;
126 
131 
136 
140 static uint32_t lazy_copy_cookie;
141 
146 
150 static struct Listener *listener_head;
151 
155 static struct Listener *listener_tail;
156 
160 static unsigned int num_clients;
161 
166 static int in_shutdown;
167 
174 static uint32_t suggest_id;
175 
176 
185 static struct Operation *
186 get_incoming (uint32_t id)
187 {
188  for (struct Listener *listener = listener_head;
189  NULL != listener;
191  {
192  for (struct Operation *op = listener->op_head; NULL != op; op = op->next)
193  if (op->suggest_id == id)
194  return op;
195  }
196  return NULL;
197 }
198 
199 
205 static void
207 {
208  struct Listener *listener;
209 
211  "Destroying incoming operation %p\n",
212  op);
213  if (NULL != (listener = op->listener))
214  {
216  listener->op_tail,
217  op);
218  op->listener = NULL;
219  }
220  if (NULL != op->timeout_task)
221  {
223  op->timeout_task = NULL;
224  }
226 }
227 
228 
233 {
234 
239 
243  unsigned int min_op_generation;
244 
248  unsigned int max_op_generation;
249 
250 };
251 
252 
262 static int
264  const struct GNUNET_HashCode *key,
265  void *value)
266 {
267  //struct GarbageContext *gc = cls;
268  //struct ElementEntry *ee = value;
269 
270  //if (GNUNET_YES != ee->removed)
271  // return GNUNET_OK;
272  //if ( (gc->max_op_generation < ee->generation_added) ||
273  // (ee->generation_removed > gc->min_op_generation) )
274  //{
275  // GNUNET_assert (GNUNET_YES ==
276  // GNUNET_CONTAINER_multihashmap_remove (gc->map,
277  // key,
278  // ee));
279  // GNUNET_free (ee);
280  //}
281  return GNUNET_OK;
282 }
283 
284 
292 static void
294 {
295  struct GarbageContext gc;
296 
297  gc.min_op_generation = UINT_MAX;
298  gc.max_op_generation = 0;
299  for (struct Operation *op = set->ops_head; NULL != op; op = op->next)
300  {
302  op->generation_created);
304  op->generation_created);
305  }
306  gc.map = set->content->elements;
307  GNUNET_CONTAINER_multihashmap_iterate (set->content->elements,
309  &gc);
310 }
311 
312 
321 static int
322 is_excluded_generation (unsigned int generation,
323  struct GenerationRange *excluded,
324  unsigned int excluded_size)
325 {
326  for (unsigned int i = 0; i < excluded_size; i++)
327  if ( (generation >= excluded[i].start) &&
328  (generation < excluded[i].end) )
329  return GNUNET_YES;
330  return GNUNET_NO;
331 }
332 
333 
343 static int
345  unsigned int query_generation,
346  struct GenerationRange *excluded,
347  unsigned int excluded_size)
348 {
349  struct MutationEvent *mut;
350  int is_present;
351 
352  GNUNET_assert (NULL != ee->mutations);
353  if (GNUNET_YES ==
354  is_excluded_generation (query_generation,
355  excluded,
356  excluded_size))
357  {
358  GNUNET_break (0);
359  return GNUNET_NO;
360  }
361 
362  is_present = GNUNET_NO;
363 
364  /* Could be made faster with binary search, but lists
365  are small, so why bother. */
366  for (unsigned int i = 0; i < ee->mutations_size; i++)
367  {
368  mut = &ee->mutations[i];
369 
370  if (mut->generation > query_generation)
371  {
372  /* The mutation doesn't apply to our generation
373  anymore. We can'b break here, since mutations aren't
374  sorted by generation. */
375  continue;
376  }
377 
378  if (GNUNET_YES ==
380  excluded,
381  excluded_size))
382  {
383  /* The generation is excluded (because it belongs to another
384  fork via a lazy copy) and thus mutations aren't considered
385  for membership testing. */
386  continue;
387  }
388 
389  /* This would be an inconsistency in how we manage mutations. */
390  if ( (GNUNET_YES == is_present) &&
391  (GNUNET_YES == mut->added) )
392  GNUNET_assert (0);
393  /* Likewise. */
394  if ( (GNUNET_NO == is_present) &&
395  (GNUNET_NO == mut->added) )
396  GNUNET_assert (0);
397 
398  is_present = mut->added;
399  }
400 
401  return is_present;
402 }
403 
404 
412 int
414  struct Operation *op)
415 {
416  return is_element_of_generation (ee,
417  op->generation_created,
420 }
421 
422 
436 void
438  int gc)
439 {
440  struct Set *set = op->set;
441  struct GNUNET_CADET_Channel *channel;
442 
444  "Destroying operation %p\n",
445  op);
446  GNUNET_assert (NULL == op->listener);
447  if (NULL != op->state)
448  {
449  set->vt->cancel (op);
450  op->state = NULL;
451  }
452  if (NULL != set)
453  {
454  GNUNET_CONTAINER_DLL_remove (set->ops_head,
455  set->ops_tail,
456  op);
457  op->set = NULL;
458  }
459  if (NULL != op->context_msg)
460  {
461  GNUNET_free (op->context_msg);
462  op->context_msg = NULL;
463  }
464  if (NULL != (channel = op->channel))
465  {
466  /* This will free op; called conditionally as this helper function
467  is also called from within the channel disconnect handler. */
468  op->channel = NULL;
470  }
471  if ( (NULL != set) &&
472  (GNUNET_YES == gc) )
474  /* We rely on the channel end handler to free 'op'. When 'op->channel' was NULL,
475  * there was a channel end handler that will free 'op' on the call stack. */
476 }
477 
478 
487 static void *
488 client_connect_cb (void *cls,
489  struct GNUNET_SERVICE_Client *c,
490  struct GNUNET_MQ_Handle *mq)
491 {
492  struct ClientState *cs;
493 
494  num_clients++;
495  cs = GNUNET_new (struct ClientState);
496  cs->client = c;
497  cs->mq = mq;
498  return cs;
499 }
500 
501 
510 static int
512  const struct GNUNET_HashCode *key,
513  void *value)
514 {
515  struct ElementEntry *ee = value;
516 
518  GNUNET_free (ee);
519  return GNUNET_YES;
520 }
521 
522 
530 static void
532  struct GNUNET_SERVICE_Client *client,
533  void *internal_cls)
534 {
535  struct ClientState *cs = internal_cls;
536  struct Operation *op;
537  struct Listener *listener;
538  struct Set *set;
539 
541  "Client disconnected, cleaning up\n");
542  if (NULL != (set = cs->set))
543  {
544  struct SetContent *content = set->content;
545  struct PendingMutation *pm;
546  struct PendingMutation *pm_current;
547  struct LazyCopyRequest *lcr;
548 
550  "Destroying client's set\n");
551  /* Destroy pending set operations */
552  while (NULL != set->ops_head)
553  _GSS_operation_destroy (set->ops_head,
554  GNUNET_NO);
555 
556  /* Destroy operation-specific state */
557  GNUNET_assert (NULL != set->state);
558  set->vt->destroy_set (set->state);
559  set->state = NULL;
560 
561  /* Clean up ongoing iterations */
562  if (NULL != set->iter)
563  {
565  set->iter = NULL;
566  set->iteration_id++;
567  }
568 
569  /* discard any pending mutations that reference this set */
570  pm = content->pending_mutations_head;
571  while (NULL != pm)
572  {
573  pm_current = pm;
574  pm = pm->next;
575  if (pm_current->set == set)
576  {
578  content->pending_mutations_tail,
579  pm_current);
580  GNUNET_free (pm_current);
581  }
582  }
583 
584  /* free set content (or at least decrement RC) */
585  set->content = NULL;
586  GNUNET_assert (0 != content->refcount);
587  content->refcount--;
588  if (0 == content->refcount)
589  {
590  GNUNET_assert (NULL != content->elements);
593  NULL);
595  content->elements = NULL;
596  GNUNET_free (content);
597  }
598  GNUNET_free_non_null (set->excluded_generations);
599  set->excluded_generations = NULL;
600 
601  /* remove set from pending copy requests */
602  lcr = lazy_copy_head;
603  while (NULL != lcr)
604  {
605  struct LazyCopyRequest *lcr_current = lcr;
606 
607  lcr = lcr->next;
608  if (lcr_current->source_set == set)
609  {
610  GNUNET_CONTAINER_DLL_remove (lazy_copy_head,
611  lazy_copy_tail,
612  lcr_current);
613  GNUNET_free (lcr_current);
614  }
615  }
616  GNUNET_free (set);
617  }
618 
619  if (NULL != (listener = cs->listener))
620  {
622  "Destroying client's listener\n");
624  listener->open_port = NULL;
625  while (NULL != (op = listener->op_head))
626  {
628  "Destroying incoming operation `%u' from peer `%s'\n",
629  (unsigned int) op->client_request_id,
630  GNUNET_i2s (&op->peer));
631  incoming_destroy (op);
632  }
633  GNUNET_CONTAINER_DLL_remove (listener_head,
634  listener_tail,
635  listener);
636  GNUNET_free (listener);
637  }
638  GNUNET_free (cs);
639  num_clients--;
640  if ( (GNUNET_YES == in_shutdown) &&
641  (0 == num_clients) )
642  {
643  if (NULL != cadet)
644  {
645  GNUNET_CADET_disconnect (cadet);
646  cadet = NULL;
647  }
648  }
649 }
650 
651 
660 static int
662  const struct OperationRequestMessage *msg)
663 {
664  struct Operation *op = cls;
665  struct Listener *listener = op->listener;
666  const struct GNUNET_MessageHeader *nested_context;
667 
668  /* double operation request */
669  if (0 != op->suggest_id)
670  {
671  GNUNET_break_op (0);
672  return GNUNET_SYSERR;
673  }
674  /* This should be equivalent to the previous condition, but can't hurt to check twice */
675  if (NULL == op->listener)
676  {
677  GNUNET_break (0);
678  return GNUNET_SYSERR;
679  }
680  if (listener->operation != (enum GNUNET_SET_OperationType) ntohl (msg->operation))
681  {
682  GNUNET_break_op (0);
683  return GNUNET_SYSERR;
684  }
685  nested_context = GNUNET_MQ_extract_nested_mh (msg);
686  if ( (NULL != nested_context) &&
687  (ntohs (nested_context->size) > GNUNET_SET_CONTEXT_MESSAGE_MAX_SIZE) )
688  {
689  GNUNET_break_op (0);
690  return GNUNET_SYSERR;
691  }
692  return GNUNET_OK;
693 }
694 
695 
713 static void
715  const struct OperationRequestMessage *msg)
716 {
717  struct Operation *op = cls;
718  struct Listener *listener = op->listener;
719  const struct GNUNET_MessageHeader *nested_context;
720  struct GNUNET_MQ_Envelope *env;
721  struct GNUNET_SET_RequestMessage *cmsg;
722 
723  nested_context = GNUNET_MQ_extract_nested_mh (msg);
724  /* Make a copy of the nested_context (application-specific context
725  information that is opaque to set) so we can pass it to the
726  listener later on */
727  if (NULL != nested_context)
728  op->context_msg = GNUNET_copy_message (nested_context);
729  op->remote_element_count = ntohl (msg->element_count);
731  "Received P2P operation request (op %u, port %s) for active listener\n",
732  (uint32_t) ntohl (msg->operation),
733  GNUNET_h2s (&op->listener->app_id));
734  GNUNET_assert (0 == op->suggest_id);
735  if (0 == suggest_id)
736  suggest_id++;
737  op->suggest_id = suggest_id++;
738  GNUNET_assert (NULL != op->timeout_task);
740  op->timeout_task = NULL;
741  env = GNUNET_MQ_msg_nested_mh (cmsg,
743  op->context_msg);
745  "Suggesting incoming request with accept id %u to listener %p of client %p\n",
746  op->suggest_id,
747  listener,
748  listener->cs);
749  cmsg->accept_id = htonl (op->suggest_id);
750  cmsg->peer_id = op->peer;
751  GNUNET_MQ_send (listener->cs->mq,
752  env);
753  /* NOTE: GNUNET_CADET_receive_done() will be called in
754  #handle_client_accept() */
755 }
756 
757 
764 static void
765 execute_add (struct Set *set,
766  const struct GNUNET_SET_ElementMessage *msg)
767 {
768  struct GNUNET_SET_Element el;
769  struct ElementEntry *ee;
770  struct GNUNET_HashCode hash;
771 
773  el.size = ntohs (msg->header.size) - sizeof (*msg);
774  el.data = &msg[1];
775  el.element_type = ntohs (msg->element_type);
777  &hash);
778  ee = GNUNET_CONTAINER_multihashmap_get (set->content->elements,
779  &hash);
780  if (NULL == ee)
781  {
783  "Client inserts element %s of size %u\n",
784  GNUNET_h2s (&hash),
785  el.size);
786  ee = GNUNET_malloc (el.size + sizeof (*ee));
787  ee->element.size = el.size;
788  GNUNET_memcpy (&ee[1],
789  el.data,
790  el.size);
791  ee->element.data = &ee[1];
793  ee->remote = GNUNET_NO;
794  ee->mutations = NULL;
795  ee->mutations_size = 0;
796  ee->element_hash = hash;
798  GNUNET_CONTAINER_multihashmap_put (set->content->elements,
799  &ee->element_hash,
800  ee,
802  }
803  else if (GNUNET_YES ==
805  set->current_generation,
806  set->excluded_generations,
807  set->excluded_generations_size))
808  {
810  "Client inserted element %s of size %u twice (ignored)\n",
811  GNUNET_h2s (&hash),
812  el.size);
813 
814  /* same element inserted twice */
815  return;
816  }
817 
818  {
819  struct MutationEvent mut = {
820  .generation = set->current_generation,
821  .added = GNUNET_YES
822  };
824  ee->mutations_size,
825  mut);
826  }
827  set->vt->add (set->state,
828  ee);
829 }
830 
831 
838 static void
839 execute_remove (struct Set *set,
840  const struct GNUNET_SET_ElementMessage *msg)
841 {
842  struct GNUNET_SET_Element el;
843  struct ElementEntry *ee;
844  struct GNUNET_HashCode hash;
845 
847  el.size = ntohs (msg->header.size) - sizeof (*msg);
848  el.data = &msg[1];
849  el.element_type = ntohs (msg->element_type);
850  GNUNET_SET_element_hash (&el, &hash);
851  ee = GNUNET_CONTAINER_multihashmap_get (set->content->elements,
852  &hash);
853  if (NULL == ee)
854  {
855  /* Client tried to remove non-existing element. */
857  "Client removes non-existing element of size %u\n",
858  el.size);
859  return;
860  }
861  if (GNUNET_NO ==
863  set->current_generation,
864  set->excluded_generations,
865  set->excluded_generations_size))
866  {
867  /* Client tried to remove element twice */
869  "Client removed element of size %u twice (ignored)\n",
870  el.size);
871  return;
872  }
873  else
874  {
875  struct MutationEvent mut = {
876  .generation = set->current_generation,
877  .added = GNUNET_NO
878  };
879 
881  "Client removes element of size %u\n",
882  el.size);
883 
885  ee->mutations_size,
886  mut);
887  }
888  set->vt->remove (set->state,
889  ee);
890 }
891 
892 
899 static void
900 execute_mutation (struct Set *set,
901  const struct GNUNET_SET_ElementMessage *msg)
902 {
903  switch (ntohs (msg->header.type))
904  {
906  execute_add (set, msg);
907  break;
909  execute_remove (set, msg);
910  break;
911  default:
912  GNUNET_break (0);
913  }
914 }
915 
916 
923 static void
925 {
926  struct PendingMutation *pm;
927 
928  if (0 != set->content->iterator_count)
929  return; /* still cannot do this */
930  while (NULL != (pm = set->content->pending_mutations_head))
931  {
934  pm);
936  "Executing pending mutation on %p.\n",
937  pm->set);
938  execute_mutation (pm->set,
939  pm->msg);
940  GNUNET_free (pm->msg);
941  GNUNET_free (pm);
942  }
943 }
944 
945 
959 static void
961 {
962  int ret;
963  struct ElementEntry *ee;
964  struct GNUNET_MQ_Envelope *ev;
966 
967  GNUNET_assert (NULL != set->iter);
968  do {
970  NULL,
971  (const void **) &ee);
972  if (GNUNET_NO == ret)
973  {
975  "Iteration on %p done.\n",
976  set);
979  set->iter = NULL;
980  set->iteration_id++;
981  GNUNET_assert (set->content->iterator_count > 0);
982  set->content->iterator_count--;
984  GNUNET_MQ_send (set->cs->mq,
985  ev);
986  return;
987  }
988  GNUNET_assert (NULL != ee);
989  } while (GNUNET_NO ==
991  set->iter_generation,
992  set->excluded_generations,
993  set->excluded_generations_size));
995  "Sending iteration element on %p.\n",
996  set);
997  ev = GNUNET_MQ_msg_extra (msg,
998  ee->element.size,
1000  GNUNET_memcpy (&msg[1],
1001  ee->element.data,
1002  ee->element.size);
1003  msg->element_type = htons (ee->element.element_type);
1004  msg->iteration_id = htons (set->iteration_id);
1005  GNUNET_MQ_send (set->cs->mq,
1006  ev);
1007 }
1008 
1009 
1019 static void
1021  const struct GNUNET_MessageHeader *m)
1022 {
1023  struct ClientState *cs = cls;
1024  struct Set *set;
1025 
1026  if (NULL == (set = cs->set))
1027  {
1028  /* attempt to iterate over a non existing set */
1029  GNUNET_break (0);
1031  return;
1032  }
1033  if (NULL != set->iter)
1034  {
1035  /* Only one concurrent iterate-action allowed per set */
1036  GNUNET_break (0);
1038  return;
1039  }
1041  "Iterating set %p in gen %u with %u content elements\n",
1042  (void *) set,
1043  set->current_generation,
1044  GNUNET_CONTAINER_multihashmap_size (set->content->elements));
1046  set->content->iterator_count++;
1047  set->iter = GNUNET_CONTAINER_multihashmap_iterator_create (set->content->elements);
1048  set->iter_generation = set->current_generation;
1049  send_client_element (set);
1050 }
1051 
1052 
1061 static void
1063  const struct GNUNET_SET_CreateMessage *msg)
1064 {
1065  struct ClientState *cs = cls;
1066  struct Set *set;
1067 
1069  "Client created new set (operation %u)\n",
1070  (uint32_t) ntohl (msg->operation));
1071  if (NULL != cs->set)
1072  {
1073  /* There can only be one set per client */
1074  GNUNET_break (0);
1076  return;
1077  }
1078  set = GNUNET_new (struct Set);
1079  switch (ntohl (msg->operation))
1080  {
1082  set->vt = _GSS_intersection_vt ();
1083  break;
1085  set->vt = _GSS_union_vt ();
1086  break;
1087  default:
1088  GNUNET_free (set);
1089  GNUNET_break (0);
1091  return;
1092  }
1093  set->operation = (enum GNUNET_SET_OperationType) ntohl (msg->operation);
1094  set->state = set->vt->create ();
1095  if (NULL == set->state)
1096  {
1097  /* initialization failed (i.e. out of memory) */
1098  GNUNET_free (set);
1100  return;
1101  }
1102  set->content = GNUNET_new (struct SetContent);
1103  set->content->refcount = 1;
1104  set->content->elements = GNUNET_CONTAINER_multihashmap_create (1,
1105  GNUNET_YES);
1106  set->cs = cs;
1107  cs->set = set;
1109 }
1110 
1111 
1121 static void
1123 {
1124  struct Operation *op = cls;
1125 
1126  op->timeout_task = NULL;
1128  "Remote peer's incoming request timed out\n");
1129  incoming_destroy (op);
1130 }
1131 
1132 
1149 static void *
1150 channel_new_cb (void *cls,
1151  struct GNUNET_CADET_Channel *channel,
1152  const struct GNUNET_PeerIdentity *source)
1153 {
1154  struct Listener *listener = cls;
1155  struct Operation *op;
1156 
1158  "New incoming channel\n");
1159  op = GNUNET_new (struct Operation);
1160  op->listener = listener;
1161  op->peer = *source;
1162  op->channel = channel;
1163  op->mq = GNUNET_CADET_get_mq (op->channel);
1165  UINT32_MAX);
1166  op->timeout_task
1169  op);
1171  listener->op_tail,
1172  op);
1173  return op;
1174 }
1175 
1176 
1193 static void
1194 channel_end_cb (void *channel_ctx,
1195  const struct GNUNET_CADET_Channel *channel)
1196 {
1197  struct Operation *op = channel_ctx;
1198 
1199  op->channel = NULL;
1201 }
1202 
1203 
1209 void
1211 {
1212  struct GNUNET_CADET_Channel *channel;
1213 
1215  "channel_end_cb called\n");
1216  if (NULL != (channel = op->channel))
1217  {
1218  /* This will free op; called conditionally as this helper function
1219  is also called from within the channel disconnect handler. */
1220  op->channel = NULL;
1221  GNUNET_CADET_channel_destroy (channel);
1222  }
1223  if (NULL != op->listener)
1224  {
1225  incoming_destroy (op);
1226  return;
1227  }
1228  if (NULL != op->set)
1229  op->set->vt->channel_death (op);
1230  else
1232  GNUNET_YES);
1233  GNUNET_free (op);
1234 }
1235 
1236 
1251 static void
1253  const struct GNUNET_CADET_Channel *channel,
1254  int window_size)
1255 {
1256  /* FIXME: not implemented, we could do flow control here... */
1257 }
1258 
1259 
1266 static void
1268  const struct GNUNET_SET_ListenMessage *msg)
1269 {
1270  struct ClientState *cs = cls;
1271  struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
1272  GNUNET_MQ_hd_var_size (incoming_msg,
1274  struct OperationRequestMessage,
1275  NULL),
1276  GNUNET_MQ_hd_var_size (union_p2p_ibf,
1278  struct IBFMessage,
1279  NULL),
1280  GNUNET_MQ_hd_var_size (union_p2p_elements,
1283  NULL),
1284  GNUNET_MQ_hd_var_size (union_p2p_offer,
1286  struct GNUNET_MessageHeader,
1287  NULL),
1288  GNUNET_MQ_hd_var_size (union_p2p_inquiry,
1290  struct InquiryMessage,
1291  NULL),
1292  GNUNET_MQ_hd_var_size (union_p2p_demand,
1294  struct GNUNET_MessageHeader,
1295  NULL),
1296  GNUNET_MQ_hd_fixed_size (union_p2p_done,
1298  struct GNUNET_MessageHeader,
1299  NULL),
1300  GNUNET_MQ_hd_fixed_size (union_p2p_over,
1302  struct GNUNET_MessageHeader,
1303  NULL),
1304  GNUNET_MQ_hd_fixed_size (union_p2p_full_done,
1306  struct GNUNET_MessageHeader,
1307  NULL),
1308  GNUNET_MQ_hd_fixed_size (union_p2p_request_full,
1310  struct GNUNET_MessageHeader,
1311  NULL),
1312  GNUNET_MQ_hd_var_size (union_p2p_strata_estimator,
1314  struct StrataEstimatorMessage,
1315  NULL),
1316  GNUNET_MQ_hd_var_size (union_p2p_strata_estimator,
1318  struct StrataEstimatorMessage,
1319  NULL),
1320  GNUNET_MQ_hd_var_size (union_p2p_full_element,
1323  NULL),
1324  GNUNET_MQ_hd_fixed_size (intersection_p2p_element_info,
1327  NULL),
1328  GNUNET_MQ_hd_var_size (intersection_p2p_bf,
1330  struct BFMessage,
1331  NULL),
1332  GNUNET_MQ_hd_fixed_size (intersection_p2p_done,
1334  struct IntersectionDoneMessage,
1335  NULL),
1337  };
1338  struct Listener *listener;
1339 
1340  if (NULL != cs->listener)
1341  {
1342  /* max. one active listener per client! */
1343  GNUNET_break (0);
1345  return;
1346  }
1347  listener = GNUNET_new (struct Listener);
1348  listener->cs = cs;
1349  cs->listener = listener;
1350  listener->app_id = msg->app_id;
1351  listener->operation = (enum GNUNET_SET_OperationType) ntohl (msg->operation);
1352  GNUNET_CONTAINER_DLL_insert (listener_head,
1353  listener_tail,
1354  listener);
1356  "New listener created (op %u, port %s)\n",
1357  listener->operation,
1358  GNUNET_h2s (&listener->app_id));
1359  listener->open_port
1360  = GNUNET_CADET_open_port (cadet,
1361  &msg->app_id,
1362  &channel_new_cb,
1363  listener,
1365  &channel_end_cb,
1366  cadet_handlers);
1368 }
1369 
1370 
1378 static void
1380  const struct GNUNET_SET_RejectMessage *msg)
1381 {
1382  struct ClientState *cs = cls;
1383  struct Operation *op;
1384 
1385  op = get_incoming (ntohl (msg->accept_reject_id));
1386  if (NULL == op)
1387  {
1388  /* no matching incoming operation for this reject;
1389  could be that the other peer already disconnected... */
1391  "Client rejected unknown operation %u\n",
1392  (unsigned int) ntohl (msg->accept_reject_id));
1394  return;
1395  }
1397  "Peer request (op %u, app %s) rejected by client\n",
1398  op->listener->operation,
1399  GNUNET_h2s (&cs->listener->app_id));
1402 }
1403 
1404 
1411 static int
1413  const struct GNUNET_SET_ElementMessage *msg)
1414 {
1415  /* NOTE: Technically, we should probably check with the
1416  block library whether the element we are given is well-formed */
1417  return GNUNET_OK;
1418 }
1419 
1420 
1427 static void
1429  const struct GNUNET_SET_ElementMessage *msg)
1430 {
1431  struct ClientState *cs = cls;
1432  struct Set *set;
1433 
1434  if (NULL == (set = cs->set))
1435  {
1436  /* client without a set requested an operation */
1437  GNUNET_break (0);
1439  return;
1440  }
1442 
1443  if (0 != set->content->iterator_count)
1444  {
1445  struct PendingMutation *pm;
1446 
1448  "Scheduling mutation on set\n");
1449  pm = GNUNET_new (struct PendingMutation);
1450  pm->msg = (struct GNUNET_SET_ElementMessage *) GNUNET_copy_message (&msg->header);
1451  pm->set = set;
1452  GNUNET_CONTAINER_DLL_insert_tail (set->content->pending_mutations_head,
1453  set->content->pending_mutations_tail,
1454  pm);
1455  return;
1456  }
1458  "Executing mutation on set\n");
1459  execute_mutation (set,
1460  msg);
1461 }
1462 
1463 
1470 static void
1472 {
1473  struct GenerationRange r;
1474 
1475  if (set->current_generation == set->content->latest_generation)
1476  {
1477  set->content->latest_generation++;
1478  set->current_generation++;
1479  return;
1480  }
1481 
1482  GNUNET_assert (set->current_generation < set->content->latest_generation);
1483 
1484  r.start = set->current_generation + 1;
1485  r.end = set->content->latest_generation + 1;
1486  set->content->latest_generation = r.end;
1487  set->current_generation = r.end;
1488  GNUNET_array_append (set->excluded_generations,
1489  set->excluded_generations_size,
1490  r);
1491 }
1492 
1493 
1503 static int
1505  const struct GNUNET_SET_EvaluateMessage *msg)
1506 {
1507  /* FIXME: suboptimal, even if the context below could be NULL,
1508  there are malformed messages this does not check for... */
1509  return GNUNET_OK;
1510 }
1511 
1512 
1521 static void
1523  const struct GNUNET_SET_EvaluateMessage *msg)
1524 {
1525  struct ClientState *cs = cls;
1526  struct Operation *op = GNUNET_new (struct Operation);
1527  const struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
1528  GNUNET_MQ_hd_var_size (incoming_msg,
1530  struct OperationRequestMessage,
1531  op),
1532  GNUNET_MQ_hd_var_size (union_p2p_ibf,
1534  struct IBFMessage,
1535  op),
1536  GNUNET_MQ_hd_var_size (union_p2p_elements,
1539  op),
1540  GNUNET_MQ_hd_var_size (union_p2p_offer,
1542  struct GNUNET_MessageHeader,
1543  op),
1544  GNUNET_MQ_hd_var_size (union_p2p_inquiry,
1546  struct InquiryMessage,
1547  op),
1548  GNUNET_MQ_hd_var_size (union_p2p_demand,
1550  struct GNUNET_MessageHeader,
1551  op),
1552  GNUNET_MQ_hd_fixed_size (union_p2p_done,
1554  struct GNUNET_MessageHeader,
1555  op),
1556  GNUNET_MQ_hd_fixed_size (union_p2p_over,
1558  struct GNUNET_MessageHeader,
1559  op),
1560  GNUNET_MQ_hd_fixed_size (union_p2p_full_done,
1562  struct GNUNET_MessageHeader,
1563  op),
1564  GNUNET_MQ_hd_fixed_size (union_p2p_request_full,
1566  struct GNUNET_MessageHeader,
1567  op),
1568  GNUNET_MQ_hd_var_size (union_p2p_strata_estimator,
1570  struct StrataEstimatorMessage,
1571  op),
1572  GNUNET_MQ_hd_var_size (union_p2p_strata_estimator,
1574  struct StrataEstimatorMessage,
1575  op),
1576  GNUNET_MQ_hd_var_size (union_p2p_full_element,
1579  op),
1580  GNUNET_MQ_hd_fixed_size (intersection_p2p_element_info,
1583  op),
1584  GNUNET_MQ_hd_var_size (intersection_p2p_bf,
1586  struct BFMessage,
1587  op),
1588  GNUNET_MQ_hd_fixed_size (intersection_p2p_done,
1590  struct IntersectionDoneMessage,
1591  op),
1593  };
1594  struct Set *set;
1595  const struct GNUNET_MessageHeader *context;
1596 
1597  if (NULL == (set = cs->set))
1598  {
1599  GNUNET_break (0);
1600  GNUNET_free (op);
1602  return;
1603  }
1605  UINT32_MAX);
1606  op->peer = msg->target_peer;
1607  op->result_mode = ntohl (msg->result_mode);
1608  op->client_request_id = ntohl (msg->request_id);
1609  op->byzantine = msg->byzantine;
1611  op->force_full = msg->force_full;
1612  op->force_delta = msg->force_delta;
1613  context = GNUNET_MQ_extract_nested_mh (msg);
1614 
1615  /* Advance generation values, so that
1616  mutations won't interfer with the running operation. */
1617  op->set = set;
1618  op->generation_created = set->current_generation;
1619  advance_generation (set);
1620  GNUNET_CONTAINER_DLL_insert (set->ops_head,
1621  set->ops_tail,
1622  op);
1624  "Creating new CADET channel to port %s for set operation type %u\n",
1625  GNUNET_h2s (&msg->app_id),
1626  set->operation);
1627  op->channel = GNUNET_CADET_channel_create (cadet,
1628  op,
1629  &msg->target_peer,
1630  &msg->app_id,
1633  &channel_end_cb,
1634  cadet_handlers);
1635  op->mq = GNUNET_CADET_get_mq (op->channel);
1636  op->state = set->vt->evaluate (op,
1637  context);
1638  if (NULL == op->state)
1639  {
1640  GNUNET_break (0);
1642  return;
1643  }
1645 }
1646 
1647 
1656 static void
1658  const struct GNUNET_SET_IterAckMessage *ack)
1659 {
1660  struct ClientState *cs = cls;
1661  struct Set *set;
1662 
1663  if (NULL == (set = cs->set))
1664  {
1665  /* client without a set acknowledged receiving a value */
1666  GNUNET_break (0);
1668  return;
1669  }
1670  if (NULL == set->iter)
1671  {
1672  /* client sent an ack, but we were not expecting one (as
1673  set iteration has finished) */
1674  GNUNET_break (0);
1676  return;
1677  }
1679  if (ntohl (ack->send_more))
1680  {
1681  send_client_element (set);
1682  }
1683  else
1684  {
1686  set->iter = NULL;
1687  set->iteration_id++;
1688  }
1689 }
1690 
1691 
1698 static void
1700  const struct GNUNET_MessageHeader *mh)
1701 {
1702  struct ClientState *cs = cls;
1703  struct Set *set;
1704  struct LazyCopyRequest *cr;
1705  struct GNUNET_MQ_Envelope *ev;
1706  struct GNUNET_SET_CopyLazyResponseMessage *resp_msg;
1707 
1708  if (NULL == (set = cs->set))
1709  {
1710  /* client without a set requested an operation */
1711  GNUNET_break (0);
1713  return;
1714  }
1716  "Client requested creation of lazy copy\n");
1717  cr = GNUNET_new (struct LazyCopyRequest);
1718  cr->cookie = ++lazy_copy_cookie;
1719  cr->source_set = set;
1720  GNUNET_CONTAINER_DLL_insert (lazy_copy_head,
1721  lazy_copy_tail,
1722  cr);
1723  ev = GNUNET_MQ_msg (resp_msg,
1725  resp_msg->cookie = cr->cookie;
1726  GNUNET_MQ_send (set->cs->mq,
1727  ev);
1729 }
1730 
1731 
1738 static void
1740  const struct GNUNET_SET_CopyLazyConnectMessage *msg)
1741 {
1742  struct ClientState *cs = cls;
1743  struct LazyCopyRequest *cr;
1744  struct Set *set;
1745  int found;
1746 
1747  if (NULL != cs->set)
1748  {
1749  /* There can only be one set per client */
1750  GNUNET_break (0);
1752  return;
1753  }
1754  found = GNUNET_NO;
1755  for (cr = lazy_copy_head; NULL != cr; cr = cr->next)
1756  {
1757  if (cr->cookie == msg->cookie)
1758  {
1759  found = GNUNET_YES;
1760  break;
1761  }
1762  }
1763  if (GNUNET_NO == found)
1764  {
1765  /* client asked for copy with cookie we don't know */
1766  GNUNET_break (0);
1768  return;
1769  }
1770  GNUNET_CONTAINER_DLL_remove (lazy_copy_head,
1771  lazy_copy_tail,
1772  cr);
1774  "Client %p requested use of lazy copy\n",
1775  cs);
1776  set = GNUNET_new (struct Set);
1777  switch (cr->source_set->operation)
1778  {
1780  set->vt = _GSS_intersection_vt ();
1781  break;
1783  set->vt = _GSS_union_vt ();
1784  break;
1785  default:
1786  GNUNET_assert (0);
1787  return;
1788  }
1789 
1790  if (NULL == set->vt->copy_state)
1791  {
1792  /* Lazy copy not supported for this set operation */
1793  GNUNET_break (0);
1794  GNUNET_free (set);
1795  GNUNET_free (cr);
1797  return;
1798  }
1799 
1800  set->operation = cr->source_set->operation;
1801  set->state = set->vt->copy_state (cr->source_set->state);
1802  set->content = cr->source_set->content;
1803  set->content->refcount++;
1804 
1805  set->current_generation = cr->source_set->current_generation;
1806  set->excluded_generations_size = cr->source_set->excluded_generations_size;
1807  set->excluded_generations
1809  set->excluded_generations_size * sizeof (struct GenerationRange));
1810 
1811  /* Advance the generation of the new set, so that mutations to the
1812  of the cloned set and the source set are independent. */
1813  advance_generation (set);
1814  set->cs = cs;
1815  cs->set = set;
1816  GNUNET_free (cr);
1818 }
1819 
1820 
1827 static void
1829  const struct GNUNET_SET_CancelMessage *msg)
1830 {
1831  struct ClientState *cs = cls;
1832  struct Set *set;
1833  struct Operation *op;
1834  int found;
1835 
1836  if (NULL == (set = cs->set))
1837  {
1838  /* client without a set requested an operation */
1839  GNUNET_break (0);
1841  return;
1842  }
1843  found = GNUNET_NO;
1844  for (op = set->ops_head; NULL != op; op = op->next)
1845  {
1846  if (op->client_request_id == ntohl (msg->request_id))
1847  {
1848  found = GNUNET_YES;
1849  break;
1850  }
1851  }
1852  if (GNUNET_NO == found)
1853  {
1854  /* It may happen that the operation was already destroyed due to
1855  * the other peer disconnecting. The client may not know about this
1856  * yet and try to cancel the (just barely non-existent) operation.
1857  * So this is not a hard error.
1858  */
1860  "Client canceled non-existent op %u\n",
1861  (uint32_t) ntohl (msg->request_id));
1862  }
1863  else
1864  {
1866  "Client requested cancel for op %u\n",
1867  (uint32_t) ntohl (msg->request_id));
1869  GNUNET_YES);
1870  }
1872 }
1873 
1874 
1883 static void
1885  const struct GNUNET_SET_AcceptMessage *msg)
1886 {
1887  struct ClientState *cs = cls;
1888  struct Set *set;
1889  struct Operation *op;
1890  struct GNUNET_SET_ResultMessage *result_message;
1891  struct GNUNET_MQ_Envelope *ev;
1892  struct Listener *listener;
1893 
1894  if (NULL == (set = cs->set))
1895  {
1896  /* client without a set requested to accept */
1897  GNUNET_break (0);
1899  return;
1900  }
1901  op = get_incoming (ntohl (msg->accept_reject_id));
1902  if (NULL == op)
1903  {
1904  /* It is not an error if the set op does not exist -- it may
1905  * have been destroyed when the partner peer disconnected. */
1907  "Client %p accepted request %u of listener %p that is no longer active\n",
1908  cs,
1909  ntohl (msg->accept_reject_id),
1910  cs->listener);
1911  ev = GNUNET_MQ_msg (result_message,
1913  result_message->request_id = msg->request_id;
1914  result_message->result_status = htons (GNUNET_SET_STATUS_FAILURE);
1915  GNUNET_MQ_send (set->cs->mq,
1916  ev);
1918  return;
1919  }
1921  "Client accepting request %u\n",
1922  (uint32_t) ntohl (msg->accept_reject_id));
1923  listener = op->listener;
1924  op->listener = NULL;
1926  listener->op_tail,
1927  op);
1928  op->set = set;
1929  GNUNET_CONTAINER_DLL_insert (set->ops_head,
1930  set->ops_tail,
1931  op);
1932  op->client_request_id = ntohl (msg->request_id);
1933  op->result_mode = ntohl (msg->result_mode);
1934  op->byzantine = msg->byzantine;
1936  op->force_full = msg->force_full;
1937  op->force_delta = msg->force_delta;
1938 
1939  /* Advance generation values, so that future mutations do not
1940  interfer with the running operation. */
1941  op->generation_created = set->current_generation;
1942  advance_generation (set);
1943  GNUNET_assert (NULL == op->state);
1944  op->state = set->vt->accept (op);
1945  if (NULL == op->state)
1946  {
1947  GNUNET_break (0);
1949  return;
1950  }
1951  /* Now allow CADET to continue, as we did not do this in
1952  #handle_incoming_msg (as we wanted to first see if the
1953  local client would accept the request). */
1956 }
1957 
1958 
1964 static void
1965 shutdown_task (void *cls)
1966 {
1967  /* Delay actual shutdown to allow service to disconnect clients */
1969  if (0 == num_clients)
1970  {
1971  if (NULL != cadet)
1972  {
1973  GNUNET_CADET_disconnect (cadet);
1974  cadet = NULL;
1975  }
1976  }
1977  GNUNET_STATISTICS_destroy (_GSS_statistics,
1978  GNUNET_YES);
1980  "handled shutdown request\n");
1981 }
1982 
1983 
1992 static void
1993 run (void *cls,
1994  const struct GNUNET_CONFIGURATION_Handle *cfg,
1996 {
1997  /* FIXME: need to modify SERVICE (!) API to allow
1998  us to run a shutdown task *after* clients were
1999  forcefully disconnected! */
2001  NULL);
2002  _GSS_statistics = GNUNET_STATISTICS_create ("set",
2003  cfg);
2004  cadet = GNUNET_CADET_connect (cfg);
2005  if (NULL == cadet)
2006  {
2008  _("Could not connect to CADET service\n"));
2010  return;
2011  }
2012 }
2013 
2014 
2019 ("set",
2021  &run,
2024  NULL,
2025  GNUNET_MQ_hd_fixed_size (client_accept,
2027  struct GNUNET_SET_AcceptMessage,
2028  NULL),
2029  GNUNET_MQ_hd_fixed_size (client_iter_ack,
2032  NULL),
2033  GNUNET_MQ_hd_var_size (client_mutation,
2036  NULL),
2037  GNUNET_MQ_hd_fixed_size (client_create_set,
2039  struct GNUNET_SET_CreateMessage,
2040  NULL),
2041  GNUNET_MQ_hd_fixed_size (client_iterate,
2043  struct GNUNET_MessageHeader,
2044  NULL),
2045  GNUNET_MQ_hd_var_size (client_evaluate,
2048  NULL),
2049  GNUNET_MQ_hd_fixed_size (client_listen,
2051  struct GNUNET_SET_ListenMessage,
2052  NULL),
2053  GNUNET_MQ_hd_fixed_size (client_reject,
2055  struct GNUNET_SET_RejectMessage,
2056  NULL),
2057  GNUNET_MQ_hd_var_size (client_mutation,
2060  NULL),
2061  GNUNET_MQ_hd_fixed_size (client_cancel,
2063  struct GNUNET_SET_CancelMessage,
2064  NULL),
2065  GNUNET_MQ_hd_fixed_size (client_copy_lazy_prepare,
2067  struct GNUNET_MessageHeader,
2068  NULL),
2069  GNUNET_MQ_hd_fixed_size (client_copy_lazy_connect,
2072  NULL),
2074 
2075 
2076 /* 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:198
#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 Set * set
Set, if associated with the client, otherwise NULL.
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:849
const struct SetVT * _GSS_intersection_vt(void)
Get the table with implementing functions for set intersection.
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 Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
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:246
uint32_t request_id
Request ID to identify responses.
Definition: set.h:98
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:1293
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:116
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.
#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:110
static void execute_delayed_mutations(struct Set *set)
Execute mutations that were delayed on a set because of pending operations.
struct GNUNET_CADET_Channel * channel
Channel to the peer.
#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:288
#define GNUNET_MESSAGE_TYPE_SET_RESULT
Create an empty set.
A request for an operation with another client.
Definition: set.h:154
#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.
uint32_t request_id
id the result belongs to
Definition: set.h:261
Enable channel reliability, lost messages will be retransmitted.
#define GNUNET_MESSAGE_TYPE_SET_ACCEPT
Accept a set request.
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)
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
#define GNUNET_NO
Definition: gnunet_common.h:81
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_api.c:80
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).
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
struct Operation * ops_head
Evaluate operations are held in a linked list.
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
Set element transmitted by service to client in response to a set iteration request.
Definition: set.h:326
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:193
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:524
enum GNUNET_SET_OperationType operation
The type of the operation.
static int ret
Final status code.
Definition: gnunet-arm.c:89
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:128
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:221
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:1242
#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:293
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:995
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.
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:208
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:249
struct GNUNET_PeerIdentity peer
The identity of the requesting peer.
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:99
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:1246
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:1029
#define GNUNET_memcpy(dst, src, n)
#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:85
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.
struct Listener * listener
Port this operation runs on.
uint8_t force_delta
Always use delta operation instead of sending full sets, even it it&#39;s less efficient.
Definition: set.h:215
#define GNUNET_MIN(a, b)
Definition: gnunet_common.h:83
#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:267
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...
uint32_t request_id
Id of our set to evaluate, chosen implicitly by the client when it calls GNUNET_SET_commit().
Definition: set.h:209
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DONE
Set operation is done.
struct Listener * prev
Listeners are held in a doubly linked list.
struct Operation * op_tail
Tail of DLL of operations this listener is responsible for.
#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:2618
struct Operation * op_head
Head of DLL of operations this listener is responsible for.
Message handler for a specific message type.
struct GNUNET_CADET_Port * open_port
The port we are listening on with CADET.
Client connects to a lazily copied set.
Definition: set.h:386
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.
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:104
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.
struct Listener * listener
Listener, if associated with the client, otherwise NULL.
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:227
MutationEvent gives information about changes to an element (removal / addition) in a set content...
struct GNUNET_HashCode key
The key used in the DHT.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
uint32_t result_mode
How should results be sent to us? See enum GNUNET_SET_ResultMode.
Definition: set.h:104
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:233
#define GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO
Information about the element count for intersection.
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:308
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:182
Client acknowledges receiving element in iteration.
Definition: set.h:352
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:93
struct Listener * next
Listeners are held in a doubly linked list.
#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:396
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.
struct Operation * next
Kept in a DLL of the listener, if listener is non-NULL.
struct GNUNET_SCHEDULER_Task * timeout_task
Timeout task, if the incoming peer has not been accepted after the timeout, it will be disconnected...
During intersection, the first (and possibly second) message send it the number of elements in the se...
#define GNUNET_array_append(arr, size, element)
Append an element to a list (growing the list by one).
#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:146
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:973
struct GNUNET_HashCode app_id
application id
Definition: set.h:74
struct Set * set
Set this mutation is about.
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
#define GNUNET_SET_CONTEXT_MESSAGE_MAX_SIZE
Maximum size of a context message for set operation requests.
configuration data
Definition: configuration.c:85
struct GNUNET_HashCode app_id
Application id.
Definition: set.h:203
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:165
#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.
struct GNUNET_MessageHeader * context_msg
Context message, may be NULL.
Server responds to a lazy copy request.
Definition: set.h:369
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:282
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:151
uint32_t operation
Operation to request, values from enum GNUNET_SET_OperationType
struct GNUNET_PeerIdentity peer_id
Identity of the requesting peer.
Definition: set.h:170
struct GNUNET_CONTAINER_MultiHashMap * elements
Maps struct GNUNET_HashCode * to struct ElementEntry *.
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:122
uint32_t cookie
Temporary name for the copied set.
Definition: set.h:379
void _GSS_operation_destroy2(struct Operation *op)
This function probably should not exist and be replaced by inlining more specific logic in the variou...
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:882
#define GNUNET_YES
Definition: gnunet_common.h:80
#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:353
const struct SetVT * vt
Virtual table for this set.
struct ClientState * cs
Client that owns the 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:318
#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 ...
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 OperationState * state
Operation-specific operation state.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
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.
struct ClientState * cs
Client that owns the listener.
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:136
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:911
static int destroy_elements_iterator(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator over hash map entries to free element entries.
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:2533
Message sent by a listening client to the service to accept performing the operation with the other p...
Definition: set.h:83
#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:343
uint16_t iteration_id
To which set iteration does this reponse belong to? First iteration (per client) has counter zero...
Definition: set.h:337
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:362
#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.
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, enum GNUNET_CADET_ChannelOption options, 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:1088
static struct GNUNET_TRANSPORT_PluginMonitor * pm
Handle if we are monitoring plugin session activity.
struct SetContent * content
Content, possibly shared by multiple sets, and thus reference counted.
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:1142
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:965
unsigned int min_op_generation
Lowest generation for which an operation is still pending.