GNUnet  0.17.6
dht_api.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2009-2012, 2016, 2018, 2022 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  */
20 
28 #include "platform.h"
29 #include "gnunet_util_lib.h"
30 #include "gnunet_constants.h"
31 #include "gnunet_signatures.h"
32 #include "gnunet_arm_service.h"
33 #include "gnunet_hello_lib.h"
34 #include "gnunet_protocols.h"
35 #include "gnunet_dht_service.h"
36 #include "dht.h"
37 
38 #define LOG(kind, ...) GNUNET_log_from (kind, "dht-api", __VA_ARGS__)
39 
40 
45 {
50 
55 
60 
65 
69  void *cont_cls;
70 
75 };
76 
81 {
86 
90  void *iter_cls;
91 
96 
102 
106  struct GNUNET_HashCode key;
107 
111  uint64_t unique_id;
112 
116  size_t xquery_size;
117 
122 
126  enum GNUNET_BLOCK_Type type;
127 
132 
137  unsigned int seen_results_size;
138 
143  unsigned int seen_results_end;
144 };
145 
146 
151 {
156 
161 
166 
170  enum GNUNET_BLOCK_Type type;
171 
176 
181 
186 
191 
195  void *cb_cls;
196 };
197 
198 
203 {
204 
209 
214 
219 
223  void *cb_cls;
224 
229 
230 };
231 
232 
237 {
242 
247 
252 
257 
262 
267 
272 
277 
283 
288 
294 
298  uint64_t uid_gen;
299 };
300 
301 
308 static enum GNUNET_GenericReturnValue
310 
311 
317 static void
319 {
320  struct GNUNET_DHT_Handle *h = gh->dht_handle;
321  struct GNUNET_MQ_Envelope *env;
322  struct GNUNET_DHT_ClientGetMessage *get_msg;
323 
324  env = GNUNET_MQ_msg_extra (get_msg,
325  gh->xquery_size,
327  get_msg->options = htonl ((uint32_t) gh->options);
328  get_msg->desired_replication_level = htonl (gh->desired_replication_level);
329  get_msg->type = htonl (gh->type);
330  get_msg->key = gh->key;
331  get_msg->unique_id = gh->unique_id;
332  GNUNET_memcpy (&get_msg[1],
333  &gh[1],
334  gh->xquery_size);
335  GNUNET_MQ_send (h->mq,
336  env);
337 }
338 
339 
349 static void
351  unsigned int transmission_offset_start)
352 {
353  struct GNUNET_DHT_Handle *h = gh->dht_handle;
354  struct GNUNET_MQ_Envelope *env;
356  unsigned int delta;
357  unsigned int max;
358  unsigned int transmission_offset;
359 
360  max = (GNUNET_MAX_MESSAGE_SIZE - sizeof(*msg))
361  / sizeof(struct GNUNET_HashCode);
362  transmission_offset = transmission_offset_start;
363  while (transmission_offset < gh->seen_results_end)
364  {
365  delta = gh->seen_results_end - transmission_offset;
366  if (delta > max)
367  delta = max;
369  delta * sizeof(struct GNUNET_HashCode),
371  msg->key = gh->key;
372  msg->unique_id = gh->unique_id;
373  GNUNET_memcpy (&msg[1],
374  &gh->seen_results[transmission_offset],
375  sizeof(struct GNUNET_HashCode) * delta);
376  GNUNET_MQ_send (h->mq,
377  env);
378  transmission_offset += delta;
379  }
380 }
381 
382 
392 static enum GNUNET_GenericReturnValue
393 add_get_request_to_pending (void *cls,
394  const struct GNUNET_HashCode *key,
395  void *value)
396 {
397  struct GNUNET_DHT_Handle *handle = cls;
398  struct GNUNET_DHT_GetHandle *gh = value;
399 
401  "Retransmitting request related to %s to DHT %p\n",
402  GNUNET_h2s (key),
403  handle);
404  send_get (gh);
406  return GNUNET_YES;
407 }
408 
409 
415 static void
417 {
418  struct GNUNET_DHT_Handle *h = mh->dht_handle;
419  struct GNUNET_MQ_Envelope *env;
421 
422  env = GNUNET_MQ_msg (m,
424  m->type = htonl (mh->type);
425  m->get = htons (NULL != mh->get_cb);
426  m->get_resp = htons (NULL != mh->get_resp_cb);
427  m->put = htons (NULL != mh->put_cb);
428  if (NULL != mh->key)
429  {
430  m->filter_key = htons (1);
431  m->key = *mh->key;
432  }
433  GNUNET_MQ_send (h->mq,
434  env);
435 }
436 
437 
443 static void
444 try_reconnect (void *cls)
445 {
446  struct GNUNET_DHT_Handle *h = cls;
448 
450  "Reconnecting with DHT %p\n",
451  h);
452  h->retry_time = GNUNET_TIME_STD_BACKOFF (h->retry_time);
453  h->reconnect_task = NULL;
454  if (GNUNET_YES != try_connect (h))
455  {
457  "DHT reconnect failed!\n");
459  = GNUNET_SCHEDULER_add_delayed (h->retry_time,
460  &try_reconnect,
461  h);
462  return;
463  }
464  GNUNET_CONTAINER_multihashmap_iterate (h->active_requests,
466  h);
467  for (mh = h->monitor_head; NULL != mh; mh = mh->next)
469 }
470 
471 
477 static void
479 {
480  struct GNUNET_DHT_PutHandle *ph;
482  void *cont_cls;
483 
484  if (NULL == h->mq)
485  return;
487  h->mq = NULL;
489  "Disconnecting from DHT service, will try to reconnect in %s\n",
491  GNUNET_YES));
492  /* notify client about all PUTs that (may) have failed due to disconnect */
493  while (NULL != (ph = h->put_head))
494  {
495  cont = ph->cont;
496  cont_cls = ph->cont_cls;
497  ph->env = NULL;
499  if (NULL != cont)
500  cont (cont_cls);
501  }
502  GNUNET_assert (NULL == h->reconnect_task);
504  = GNUNET_SCHEDULER_add_delayed (h->retry_time,
505  &try_reconnect,
506  h);
507 }
508 
509 
518 static void
519 mq_error_handler (void *cls,
520  enum GNUNET_MQ_Error error)
521 {
522  struct GNUNET_DHT_Handle *h = cls;
523 
524  do_disconnect (h);
525 }
526 
527 
534 static void
536  const struct GNUNET_DHT_MonitorGetMessage *msg)
537 {
538  struct GNUNET_DHT_Handle *handle = cls;
539  enum GNUNET_DHT_RouteOption ro
540  = (enum GNUNET_DHT_RouteOption) ntohl (msg->options);
541 
542  for (struct GNUNET_DHT_MonitorHandle *mh = handle->monitor_head;
543  NULL != mh;
544  mh = mh->next)
545  {
546  if (NULL == mh->get_cb)
547  continue;
548  if ( (GNUNET_BLOCK_TYPE_ANY != mh->type) &&
549  (mh->type != ntohl (msg->type)))
550  continue;
551  if ( (NULL != mh->key) &&
552  (0 != GNUNET_memcmp (mh->key,
553  &msg->key)) )
554  continue;
555  mh->get_cb (mh->cb_cls,
556  ro,
557  (enum GNUNET_BLOCK_Type) ntohl (msg->type),
558  ntohl (msg->hop_count),
559  ntohl (msg->desired_replication_level),
560  &msg->key);
561  }
562 }
563 
564 
573 static enum GNUNET_GenericReturnValue
574 check_monitor_get_resp (void *cls,
576 {
577  size_t msize = ntohs (msg->header.size) - sizeof(*msg);
578  uint32_t getl = ntohl (msg->get_path_length);
579  uint32_t putl = ntohl (msg->put_path_length);
580  enum GNUNET_DHT_RouteOption ro
581  = (enum GNUNET_DHT_RouteOption) ntohl (msg->options);
582  bool truncated = (0 != (ro & GNUNET_DHT_RO_TRUNCATED));
583 
584  if (truncated)
585  {
586  if (msize < sizeof (struct GNUNET_PeerIdentity))
587  {
588  GNUNET_break (0);
589  return GNUNET_SYSERR;
590  }
591  msize -= sizeof (struct GNUNET_PeerIdentity);
592  }
593  if ((getl + putl < getl) ||
594  ((msize / sizeof(struct GNUNET_DHT_PathElement)) < getl + putl))
595  {
596  GNUNET_break (0);
597  return GNUNET_SYSERR;
598  }
599  return GNUNET_OK;
600 }
601 
602 
609 static void
612 {
613  struct GNUNET_DHT_Handle *handle = cls;
614  size_t msize = ntohs (msg->header.size) - sizeof(*msg);
615  enum GNUNET_DHT_RouteOption ro
616  = (enum GNUNET_DHT_RouteOption) ntohl (msg->options);
617  uint32_t getl = ntohl (msg->get_path_length);
618  uint32_t putl = ntohl (msg->put_path_length);
619  bool truncated = (0 != (ro & GNUNET_DHT_RO_TRUNCATED));
620  const struct GNUNET_PeerIdentity *trunc_peer
621  = truncated
622  ? (const struct GNUNET_PeerIdentity *) &msg[1]
623  : NULL;
624  const struct GNUNET_DHT_PathElement *path
625  = truncated
626  ? (const struct GNUNET_DHT_PathElement *) &trunc_peer[1]
627  : (const struct GNUNET_DHT_PathElement *) &msg[1];
628 
629  if (truncated)
630  msize -= sizeof (struct GNUNET_PeerIdentity);
631  msize -= sizeof(struct GNUNET_DHT_PathElement) * (putl + getl);
632  for (struct GNUNET_DHT_MonitorHandle *mh = handle->monitor_head;
633  NULL != mh;
634  mh = mh->next)
635  {
636  if (NULL == mh->get_resp_cb)
637  continue;
638  if ( (GNUNET_BLOCK_TYPE_ANY != mh->type) &&
639  (mh->type != ntohl (msg->type)) )
640  continue;
641  if ( (NULL != mh->key) &&
642  (0 != GNUNET_memcmp (mh->key,
643  &msg->key)) )
644  continue;
645  mh->get_resp_cb (mh->cb_cls,
646  (enum GNUNET_BLOCK_Type) ntohl (msg->type),
647  trunc_peer,
648  &path[putl],
649  getl,
650  path,
651  putl,
652  GNUNET_TIME_absolute_ntoh (msg->expiration_time),
653  &msg->key,
654  (const void *) &path[getl + putl],
655  msize);
656  }
657 }
658 
659 
668 static enum GNUNET_GenericReturnValue
669 check_monitor_put (void *cls,
670  const struct GNUNET_DHT_MonitorPutMessage *msg)
671 {
672  size_t msize = ntohs (msg->header.size) - sizeof(*msg);
673  uint32_t putl = ntohl (msg->put_path_length);
674  enum GNUNET_DHT_RouteOption ro
675  = (enum GNUNET_DHT_RouteOption) ntohl (msg->options);
676  bool truncated = (0 != (ro & GNUNET_DHT_RO_TRUNCATED));
677 
678  if (truncated)
679  {
680  if (msize < sizeof (struct GNUNET_PeerIdentity))
681  {
682  GNUNET_break (0);
683  return GNUNET_SYSERR;
684  }
685  msize -= sizeof (struct GNUNET_PeerIdentity);
686  }
687  if ((msize / sizeof(struct GNUNET_DHT_PathElement)) < putl)
688  {
689  GNUNET_break (0);
690  return GNUNET_SYSERR;
691  }
692  return GNUNET_OK;
693 }
694 
695 
702 static void
704  const struct GNUNET_DHT_MonitorPutMessage *msg)
705 {
706  struct GNUNET_DHT_Handle *handle = cls;
707  size_t msize = ntohs (msg->header.size) - sizeof(*msg);
708  uint32_t putl = ntohl (msg->put_path_length);
709  enum GNUNET_DHT_RouteOption ro
710  = (enum GNUNET_DHT_RouteOption) ntohl (msg->options);
711  bool truncated = (0 != (ro & GNUNET_DHT_RO_TRUNCATED));
712  const struct GNUNET_PeerIdentity *trunc_peer
713  = truncated
714  ? (const struct GNUNET_PeerIdentity *) &msg[1]
715  : NULL;
716  const struct GNUNET_DHT_PathElement *path
717  = truncated
718  ? (const struct GNUNET_DHT_PathElement *) &trunc_peer[1]
719  : (const struct GNUNET_DHT_PathElement *) &msg[1];
720 
721  if (truncated)
722  msize -= sizeof (struct GNUNET_PeerIdentity);
723  msize -= sizeof(struct GNUNET_DHT_PathElement) * putl;
724  for (struct GNUNET_DHT_MonitorHandle *mh = handle->monitor_head;
725  NULL != mh;
726  mh = mh->next)
727  {
728  if (NULL == mh->put_cb)
729  continue;
730  if ( (GNUNET_BLOCK_TYPE_ANY != mh->type) &&
731  (mh->type != ntohl (msg->type)) )
732  continue;
733  if ( (NULL != mh->key) &&
734  (0 != GNUNET_memcmp (mh->key,
735  &msg->key)) )
736  continue;
737  mh->put_cb (mh->cb_cls,
738  ro,
739  (enum GNUNET_BLOCK_Type) ntohl (msg->type),
740  ntohl (msg->hop_count),
741  ntohl (msg->desired_replication_level),
742  trunc_peer,
743  putl,
744  path,
745  GNUNET_TIME_absolute_ntoh (msg->expiration_time),
746  &msg->key,
747  (const void *) &path[putl],
748  msize);
749  }
750 }
751 
752 
761 static enum GNUNET_GenericReturnValue
762 check_client_result (void *cls,
763  const struct GNUNET_DHT_ClientResultMessage *msg)
764 {
765  size_t msize = ntohs (msg->header.size) - sizeof(*msg);
766  uint32_t put_path_length = ntohl (msg->put_path_length);
767  uint32_t get_path_length = ntohl (msg->get_path_length);
768  enum GNUNET_DHT_RouteOption ro
769  = (enum GNUNET_DHT_RouteOption) ntohl (msg->options);
770  bool truncated = (0 != (ro & GNUNET_DHT_RO_TRUNCATED));
771  size_t meta_length;
772 
773  if (truncated)
774  {
775  if (msize < sizeof (struct GNUNET_PeerIdentity))
776  {
777  GNUNET_break (0);
778  return GNUNET_SYSERR;
779  }
780  msize -= sizeof (struct GNUNET_PeerIdentity);
781  }
782  meta_length = msize / sizeof(struct GNUNET_DHT_PathElement);
783  if ( (get_path_length + put_path_length >
784  meta_length) ||
785  (get_path_length + put_path_length <
786  get_path_length) )
787  {
788  GNUNET_break (0);
789  return GNUNET_SYSERR;
790  }
791  return GNUNET_OK;
792 }
793 
794 
803 static enum GNUNET_GenericReturnValue
804 process_client_result (void *cls,
805  const struct GNUNET_HashCode *key,
806  void *value)
807 {
808  const struct GNUNET_DHT_ClientResultMessage *crm = cls;
810  size_t msize = ntohs (crm->header.size) - sizeof(*crm);
811  uint16_t type = ntohl (crm->type);
812  enum GNUNET_DHT_RouteOption ro
813  = (enum GNUNET_DHT_RouteOption) ntohl (crm->options);
814  bool truncated
815  = (0 != (ro & GNUNET_DHT_RO_TRUNCATED));
816  uint32_t put_path_length
817  = ntohl (crm->put_path_length);
818  uint32_t get_path_length
819  = ntohl (crm->get_path_length);
820  const struct GNUNET_PeerIdentity *trunc_peer
821  = truncated
822  ? (const struct GNUNET_PeerIdentity *) &crm[1]
823  : NULL;
824  const struct GNUNET_DHT_PathElement *put_path
825  = truncated
826  ? (const struct GNUNET_DHT_PathElement *) &trunc_peer[1]
827  : (const struct GNUNET_DHT_PathElement *) &crm[1];
828  const struct GNUNET_DHT_PathElement *get_path
829  = &put_path[put_path_length];
830  const void *data
831  = &get_path[get_path_length];
832  size_t meta_length
833  = sizeof(struct GNUNET_DHT_PathElement)
834  * (get_path_length + put_path_length);
835  size_t data_length
836  = msize - meta_length;
837  struct GNUNET_HashCode hc;
838 
839  if (truncated)
840  data_length -= sizeof (struct GNUNET_PeerIdentity);
841  if (crm->unique_id != get_handle->unique_id)
842  {
843  /* UID mismatch */
845  "Ignoring reply for %s: UID mismatch: %llu/%llu\n",
846  GNUNET_h2s (key),
847  (unsigned long long) crm->unique_id,
848  (unsigned long long) get_handle->unique_id);
849  return GNUNET_YES;
850  }
852  (get_handle->type != type) )
853  {
854  /* type mismatch */
855  GNUNET_break (0);
856  return GNUNET_YES;
857  }
858 
859  {
860  char *pp;
861  char *gp;
862 
863  gp = GNUNET_DHT_pp2s (get_path,
864  get_path_length);
865  pp = GNUNET_DHT_pp2s (put_path,
866  put_path_length);
868  "Giving %u byte reply for %s to application (GP: %s, PP: %s)\n",
869  (unsigned int) data_length,
870  GNUNET_h2s (key),
871  gp,
872  pp);
873  GNUNET_free (gp);
874  GNUNET_free (pp);
875  }
876  /* remember that we've seen this result */
878  data_length,
879  &hc);
883  get_handle->seen_results_size * 2 + 1);
885  /* no need to block it explicitly, service already knows about it! */
888  key,
889  trunc_peer,
890  get_path,
891  get_path_length,
892  put_path,
893  put_path_length,
894  type,
895  data_length,
896  data);
897  return GNUNET_YES;
898 }
899 
900 
907 static void
909  const struct GNUNET_DHT_ClientResultMessage *msg)
910 {
911  struct GNUNET_DHT_Handle *handle = cls;
912 
914  &msg->key,
916  (void *) msg);
917 }
918 
919 
927 static enum GNUNET_GenericReturnValue
928 check_client_hello (void *cls,
929  const struct GNUNET_MessageHeader *hdr)
930 {
931  uint16_t len = ntohs (hdr->size);
932  const char *buf = (const char *) &hdr[1];
933 
934  (void) cls;
935  if ('\0' != buf[len - sizeof (*hdr) - 1])
936  {
937  GNUNET_break (0);
938  return GNUNET_SYSERR;
939  }
940  return GNUNET_OK;
941 }
942 
943 
950 static void
952  const struct GNUNET_MessageHeader *hdr)
953 {
954  struct GNUNET_DHT_Handle *handle = cls;
955  const char *url = (const char *) &hdr[1];
956  struct GNUNET_DHT_HelloGetHandle *hgh;
957 
958  while (NULL != (hgh = handle->hgh_head))
959  {
960  hgh->cb (hgh->cb_cls,
961  url);
963  }
964 }
965 
966 
972 static void
973 handle_put_cont (void *cls)
974 {
975  struct GNUNET_DHT_PutHandle *ph = cls;
977  void *cont_cls;
978 
979  cont = ph->cont;
980  cont_cls = ph->cont_cls;
981  ph->env = NULL;
983  if (NULL != cont)
984  cont (cont_cls);
985 }
986 
987 
994 static enum GNUNET_GenericReturnValue
996 {
998  GNUNET_MQ_hd_fixed_size (monitor_get,
1001  h),
1002  GNUNET_MQ_hd_var_size (monitor_get_resp,
1005  h),
1006  GNUNET_MQ_hd_var_size (monitor_put,
1009  h),
1010  GNUNET_MQ_hd_var_size (client_result,
1013  h),
1014  GNUNET_MQ_hd_var_size (client_hello,
1016  struct GNUNET_MessageHeader,
1017  h),
1019  };
1020 
1021  if (NULL != h->mq)
1022  return GNUNET_OK;
1024  "dht",
1025  handlers,
1027  h);
1028  if (NULL == h->mq)
1029  {
1031  "Failed to connect to the DHT service!\n");
1032  return GNUNET_NO;
1033  }
1034  return GNUNET_YES;
1035 }
1036 
1037 
1038 struct GNUNET_DHT_Handle *
1040  unsigned int ht_len)
1041 {
1042  struct GNUNET_DHT_Handle *handle;
1043 
1044  handle = GNUNET_new (struct GNUNET_DHT_Handle);
1045  handle->cfg = cfg;
1046  handle->uid_gen
1048  UINT64_MAX);
1049  handle->active_requests
1051  GNUNET_YES);
1052  if (GNUNET_NO == try_connect (handle))
1053  {
1055  return NULL;
1056  }
1057  return handle;
1058 }
1059 
1060 
1061 void
1063 {
1064  struct GNUNET_DHT_PutHandle *ph;
1065 
1066  GNUNET_assert (0 ==
1067  GNUNET_CONTAINER_multihashmap_size (handle->active_requests));
1068  while (NULL != (ph = handle->put_head))
1069  {
1070  if (NULL != ph->cont)
1071  ph->cont (ph->cont_cls);
1073  }
1074  if (NULL != handle->mq)
1075  {
1077  handle->mq = NULL;
1078  }
1079  if (NULL != handle->reconnect_task)
1080  {
1082  handle->reconnect_task = NULL;
1083  }
1084  GNUNET_CONTAINER_multihashmap_destroy (handle->active_requests);
1085  GNUNET_free (handle);
1086 }
1087 
1088 
1089 struct GNUNET_DHT_PutHandle *
1091  const struct GNUNET_HashCode *key,
1092  uint32_t desired_replication_level,
1094  enum GNUNET_BLOCK_Type type,
1095  size_t size,
1096  const void *data,
1097  struct GNUNET_TIME_Absolute exp,
1099  void *cont_cls)
1100 {
1101  struct GNUNET_MQ_Envelope *env;
1102  struct GNUNET_DHT_ClientPutMessage *put_msg;
1103  size_t msize;
1104  struct GNUNET_DHT_PutHandle *ph;
1105 
1106  msize = sizeof(struct GNUNET_DHT_ClientPutMessage) + size;
1107  if ((msize >= GNUNET_MAX_MESSAGE_SIZE) ||
1109  {
1110  GNUNET_break (0);
1111  return NULL;
1112  }
1113  if (NULL == handle->mq)
1114  return NULL;
1116  "Sending PUT for %s to DHT via %p\n",
1117  GNUNET_h2s (key),
1118  handle);
1119  ph = GNUNET_new (struct GNUNET_DHT_PutHandle);
1120  ph->dht_handle = handle;
1121  ph->cont = cont;
1122  ph->cont_cls = cont_cls;
1124  handle->put_tail,
1125  ph);
1126  env = GNUNET_MQ_msg_extra (put_msg,
1127  size,
1130  &handle_put_cont,
1131  ph);
1132  ph->env = env;
1133  put_msg->type = htonl ((uint32_t) type);
1134  put_msg->options = htonl ((uint32_t) options);
1136  put_msg->expiration = GNUNET_TIME_absolute_hton (exp);
1137  put_msg->key = *key;
1138  GNUNET_memcpy (&put_msg[1],
1139  data,
1140  size);
1142  env);
1143  return ph;
1144 }
1145 
1146 
1147 void
1149 {
1150  struct GNUNET_DHT_Handle *handle = ph->dht_handle;
1151 
1152  if (NULL != ph->env)
1153  GNUNET_MQ_notify_sent (ph->env,
1154  NULL,
1155  NULL);
1157  handle->put_tail,
1158  ph);
1159  GNUNET_free (ph);
1160 }
1161 
1162 
1163 struct GNUNET_DHT_GetHandle *
1165  enum GNUNET_BLOCK_Type type,
1166  const struct GNUNET_HashCode *key,
1167  uint32_t desired_replication_level,
1169  const void *xquery,
1170  size_t xquery_size,
1172  void *iter_cls)
1173 {
1174  struct GNUNET_DHT_GetHandle *gh;
1175  size_t msize;
1176 
1177  msize = sizeof(struct GNUNET_DHT_ClientGetMessage) + xquery_size;
1178  if ((msize >= GNUNET_MAX_MESSAGE_SIZE) ||
1179  (xquery_size >= GNUNET_MAX_MESSAGE_SIZE))
1180  {
1181  GNUNET_break (0);
1182  return NULL;
1183  }
1185  "Sending query for %s to DHT %p\n",
1186  GNUNET_h2s (key),
1187  handle);
1188  gh = GNUNET_malloc (sizeof(struct GNUNET_DHT_GetHandle)
1189  + xquery_size);
1190  gh->iter = iter;
1191  gh->iter_cls = iter_cls;
1192  gh->dht_handle = handle;
1193  gh->key = *key;
1194  gh->unique_id = ++handle->uid_gen;
1195  gh->xquery_size = xquery_size;
1196  gh->desired_replication_level = desired_replication_level;
1197  gh->type = type;
1198  gh->options = options;
1199  GNUNET_memcpy (&gh[1],
1200  xquery,
1201  xquery_size);
1202  GNUNET_CONTAINER_multihashmap_put (handle->active_requests,
1203  &gh->key,
1204  gh,
1206  if (NULL != handle->mq)
1207  send_get (gh);
1208  return gh;
1209 }
1210 
1211 
1212 void
1214  unsigned int num_results,
1215  const struct GNUNET_HashCode *results)
1216 {
1217  unsigned int needed;
1218  unsigned int had;
1219 
1221  needed = had + num_results;
1222  if (needed > get_handle->seen_results_size)
1225  needed);
1227  results,
1228  num_results * sizeof(struct GNUNET_HashCode));
1229  get_handle->seen_results_end += num_results;
1230  if (NULL != get_handle->dht_handle->mq)
1232  had);
1233 }
1234 
1235 
1236 void
1238 {
1240 
1242  "Sending STOP for %s to DHT via %p\n",
1244  handle);
1245  if (NULL != handle->mq)
1246  {
1247  struct GNUNET_MQ_Envelope *env;
1248  struct GNUNET_DHT_ClientGetStopMessage *stop_msg;
1249 
1250  env = GNUNET_MQ_msg (stop_msg,
1252  stop_msg->reserved = htonl (0);
1253  stop_msg->unique_id = get_handle->unique_id;
1254  stop_msg->key = get_handle->key;
1256  env);
1257  }
1259  GNUNET_CONTAINER_multihashmap_remove (handle->active_requests,
1260  &get_handle->key,
1261  get_handle));
1264  0);
1266 }
1267 
1268 
1269 struct GNUNET_DHT_MonitorHandle *
1271  enum GNUNET_BLOCK_Type type,
1272  const struct GNUNET_HashCode *key,
1276  void *cb_cls)
1277 {
1278  struct GNUNET_DHT_MonitorHandle *mh;
1279 
1281  mh->get_cb = get_cb;
1282  mh->get_resp_cb = get_resp_cb;
1283  mh->put_cb = put_cb;
1284  mh->cb_cls = cb_cls;
1285  mh->type = type;
1286  mh->dht_handle = handle;
1287  if (NULL != key)
1288  {
1289  mh->key = GNUNET_new (struct GNUNET_HashCode);
1290  *mh->key = *key;
1291  }
1292  GNUNET_CONTAINER_DLL_insert (handle->monitor_head,
1293  handle->monitor_tail,
1294  mh);
1295  if (NULL != handle->mq)
1297  return mh;
1298 }
1299 
1300 
1301 void
1303 {
1304  struct GNUNET_DHT_Handle *handle = mh->dht_handle;
1306  struct GNUNET_MQ_Envelope *env;
1307 
1308  GNUNET_CONTAINER_DLL_remove (handle->monitor_head,
1309  handle->monitor_tail,
1310  mh);
1311  env = GNUNET_MQ_msg (m,
1313  m->type = htonl (mh->type);
1314  m->get = htons (NULL != mh->get_cb);
1315  m->get_resp = htons (NULL != mh->get_resp_cb);
1316  m->put = htons (NULL != mh->put_cb);
1317  if (NULL != mh->key)
1318  {
1319  m->filter_key = htons (1);
1320  m->key = *mh->key;
1321  }
1323  env);
1324  GNUNET_free (mh->key);
1325  GNUNET_free (mh);
1326 }
1327 
1328 
1329 char *
1331  unsigned int path_len)
1332 {
1333  char *buf;
1334  size_t off;
1335  size_t plen = path_len * 5 + 1;
1336 
1337  GNUNET_assert (path_len < UINT32_MAX / 5);
1338  off = 0;
1339  buf = GNUNET_malloc (plen);
1340  for (unsigned int i = 0; i < path_len; i++)
1341  {
1342  off += GNUNET_snprintf (&buf[off],
1343  plen - off,
1344  "%s%s",
1345  GNUNET_i2s (&path[i].pred),
1346  (i == path_len - 1) ? "" : "-");
1347  }
1348  return buf;
1349 }
1350 
1351 
1352 unsigned int
1354  size_t data_size,
1355  struct GNUNET_TIME_Absolute exp_time,
1356  const struct GNUNET_PeerIdentity *bpid,
1357  const struct GNUNET_DHT_PathElement *put_path,
1358  unsigned int put_path_len,
1359  const struct GNUNET_DHT_PathElement *get_path,
1360  unsigned int get_path_len,
1361  const struct GNUNET_PeerIdentity *me)
1362 {
1363  static struct GNUNET_PeerIdentity zero;
1364  struct GNUNET_DHT_HopSignature hs = {
1366  .purpose.size = htonl (sizeof (hs)),
1367  .expiration_time = GNUNET_TIME_absolute_hton (exp_time)
1368  };
1369  unsigned int i;
1370 
1371  if (0 == get_path_len + put_path_len)
1372  return 0;
1374  "%s is verifying signatures with GPL: %u PPL: %u!\n",
1375  GNUNET_i2s (me),
1376  get_path_len,
1377  put_path_len);
1378  for (unsigned int j = 0; j<put_path_len; j++)
1380  "PP%u=%s\n",
1381  j,
1382  GNUNET_i2s (&put_path[j].pred));
1383  for (unsigned int j = 0; j<get_path_len; j++)
1385  "GP%u=%s\n",
1386  j,
1387  GNUNET_i2s (&get_path[j].pred));
1389  data_size,
1390  &hs.h_data);
1391  i = put_path_len + get_path_len;
1392  while (i > 0)
1393  {
1394  const struct GNUNET_PeerIdentity *pred;
1395  const struct GNUNET_PeerIdentity *succ;
1396  const struct GNUNET_DHT_PathElement *pe;
1397 
1398  i--;
1399  if (0 == i)
1400  {
1401  pred = (NULL == bpid) ? &zero : bpid;
1402  }
1403  else
1404  {
1405  unsigned int off = i - 1;
1406 
1407  pred = (off >= put_path_len)
1408  ? &get_path[off - put_path_len].pred
1409  : &put_path[off].pred;
1410  }
1411  if (i == get_path_len + put_path_len - 1)
1412  {
1413  succ = me;
1414  }
1415  else
1416  {
1417  unsigned int off = i + 1;
1418 
1419  succ = (off >= put_path_len)
1420  ? &get_path[off - put_path_len].pred
1421  : &put_path[off].pred;
1422  }
1423  hs.pred = *pred;
1424  hs.succ = *succ;
1425  pe = (i >= put_path_len)
1426  ? &get_path[i - put_path_len]
1427  : &put_path[i];
1428  if (GNUNET_OK !=
1431  &hs,
1432  &pe->sig,
1433  &pe->pred.public_key))
1434  {
1435  GNUNET_break_op (0);
1436  return i + 1;
1437  }
1438  }
1439  return i;
1440 }
1441 
1442 
1446  void *cb_cls)
1447 {
1448  struct GNUNET_DHT_HelloGetHandle *hgh;
1449  struct GNUNET_MessageHeader *hdr;
1450  struct GNUNET_MQ_Envelope *env;
1451 
1452  hgh = GNUNET_new (struct GNUNET_DHT_HelloGetHandle);
1453  hgh->cb = cb;
1454  hgh->cb_cls = cb_cls;
1455  hgh->dht_handle = dht_handle;
1457  dht_handle->hgh_tail,
1458  hgh);
1459  env = GNUNET_MQ_msg (hdr,
1462  env);
1463  return hgh;
1464 }
1465 
1466 
1467 void
1469 {
1470  struct GNUNET_DHT_Handle *dht_handle = hgh->dht_handle;
1471 
1473  dht_handle->hgh_tail,
1474  hgh);
1475  GNUNET_free (hgh);
1476 }
1477 
1478 
1479 void
1481  const char *url,
1483  void *cb_cls)
1484 {
1485  struct GNUNET_MessageHeader *hdr;
1486  size_t slen = strlen (url) + 1;
1487  struct GNUNET_MQ_Envelope *env;
1488 
1489  env = GNUNET_MQ_msg_extra (hdr,
1490  slen,
1492  memcpy (&hdr[1],
1493  url,
1494  slen);
1496  cb,
1497  cb_cls);
1499  env);
1500 }
1501 
1502 
1503 /* end of dht_api.c */
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
dht_handle
Definition: 018.c:1
GNUNET_BLOCK_Type
WARNING: This header is generated! In order to add DHT block types, you must register them in GANA,...
@ GNUNET_BLOCK_TYPE_ANY
Identifier for any block.
#define GNUNET_SIGNATURE_PURPOSE_DHT_HOP
Signature by which a peer affirms that it forwarded a message in the DHT.
static void send_get(struct GNUNET_DHT_GetHandle *gh)
Send GET message for a get_handle to DHT.
Definition: dht_api.c:318
static void handle_monitor_get_resp(void *cls, const struct GNUNET_DHT_MonitorGetRespMessage *msg)
Process a get response monitor message from the service.
Definition: dht_api.c:610
static enum GNUNET_GenericReturnValue try_connect(struct GNUNET_DHT_Handle *h)
Try to (re)connect to the DHT service.
Definition: dht_api.c:995
static void handle_client_result(void *cls, const struct GNUNET_DHT_ClientResultMessage *msg)
Process a client result message received from the service.
Definition: dht_api.c:908
static void handle_client_hello(void *cls, const struct GNUNET_MessageHeader *hdr)
Process a client HELLO message received from the service.
Definition: dht_api.c:951
static void try_reconnect(void *cls)
Try reconnecting to the dht service.
Definition: dht_api.c:444
static enum GNUNET_GenericReturnValue process_client_result(void *cls, const struct GNUNET_HashCode *key, void *value)
Process a given reply that might match the given request.
Definition: dht_api.c:804
static enum GNUNET_GenericReturnValue check_monitor_get_resp(void *cls, const struct GNUNET_DHT_MonitorGetRespMessage *msg)
Validate a get response monitor message from the service.
Definition: dht_api.c:574
static void mq_error_handler(void *cls, enum GNUNET_MQ_Error error)
Generic error handler, called with the appropriate error code and the same closure specified at the c...
Definition: dht_api.c:519
static void handle_monitor_get(void *cls, const struct GNUNET_DHT_MonitorGetMessage *msg)
Process a get monitor message from the service.
Definition: dht_api.c:535
static enum GNUNET_GenericReturnValue check_client_result(void *cls, const struct GNUNET_DHT_ClientResultMessage *msg)
Verify that client result message received from the service is well-formed.
Definition: dht_api.c:762
static enum GNUNET_GenericReturnValue check_client_hello(void *cls, const struct GNUNET_MessageHeader *hdr)
Process a client HELLO message received from the service.
Definition: dht_api.c:928
static void do_disconnect(struct GNUNET_DHT_Handle *h)
Try reconnecting to the DHT service.
Definition: dht_api.c:478
static void handle_put_cont(void *cls)
Process a MQ PUT transmission notification.
Definition: dht_api.c:973
static enum GNUNET_GenericReturnValue add_get_request_to_pending(void *cls, const struct GNUNET_HashCode *key, void *value)
Add the GET request corresponding to the given route handle to the pending queue (if it is not alread...
Definition: dht_api.c:393
static void send_get_known_results(struct GNUNET_DHT_GetHandle *gh, unsigned int transmission_offset_start)
Send GET message(s) for indicating which results are already known for a get_handle to DHT.
Definition: dht_api.c:350
static void handle_monitor_put(void *cls, const struct GNUNET_DHT_MonitorPutMessage *msg)
Process a put monitor message from the service.
Definition: dht_api.c:703
#define LOG(kind,...)
Definition: dht_api.c:38
static enum GNUNET_GenericReturnValue check_monitor_put(void *cls, const struct GNUNET_DHT_MonitorPutMessage *msg)
Check validity of a put monitor message from the service.
Definition: dht_api.c:669
static void send_monitor_start(struct GNUNET_DHT_MonitorHandle *mh)
Send GNUNET_MESSAGE_TYPE_DHT_MONITOR_START message.
Definition: dht_api.c:416
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:104
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:99
static struct GNUNET_ATS_PerformanceHandle * ph
ATS performance handle used.
Definition: gnunet-ats.c:116
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
static struct GNUNET_CADET_Handle * mh
Cadet handle.
Definition: gnunet-cadet.c:92
static GNUNET_NETWORK_STRUCT_END struct GNUNET_PeerIdentity me
Our own peer identity.
static struct GNUNET_DHT_GetHandle * get_handle
Handle for the get request.
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
uint32_t data
The data value.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
static char * value
Value of the record to add/remove.
static struct GNUNET_TRANSPORT_HelloGetHandle * gh
Pending GNUNET_TRANSPORT_hello_get() operation.
static unsigned int results
static const struct GNUNET_IDENTITY_PrivateKey zero
Public key of all zeros.
static char buf[2048]
API to the DHT service.
Helper library for handling HELLOs.
Constants for network protocols.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
struct GNUNET_MQ_Handle * GNUNET_CLIENT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *service_name, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *error_handler_cls)
Create a message queue to connect to a GNUnet service.
Definition: client.c:1055
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Generate a random unsigned 64-bit value.
#define GNUNET_CRYPTO_eddsa_verify(purp, ps, sig, pub)
Verify EdDSA signature.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
void GNUNET_DHT_put_cancel(struct GNUNET_DHT_PutHandle *ph)
Cancels a DHT PUT operation.
Definition: dht_api.c:1148
GNUNET_DHT_RouteOption
Options for routing.
char * GNUNET_DHT_pp2s(const struct GNUNET_DHT_PathElement *path, unsigned int path_len)
Convert a peer path to a human-readable string.
Definition: dht_api.c:1330
struct GNUNET_DHT_MonitorHandle * GNUNET_DHT_monitor_start(struct GNUNET_DHT_Handle *handle, enum GNUNET_BLOCK_Type type, const struct GNUNET_HashCode *key, GNUNET_DHT_MonitorGetCB get_cb, GNUNET_DHT_MonitorGetRespCB get_resp_cb, GNUNET_DHT_MonitorPutCB put_cb, void *cb_cls)
Start monitoring the local DHT service.
Definition: dht_api.c:1270
void GNUNET_DHT_hello_get_cancel(struct GNUNET_DHT_HelloGetHandle *hgh)
Cancel hello get operation.
Definition: dht_api.c:1468
void GNUNET_DHT_get_stop(struct GNUNET_DHT_GetHandle *get_handle)
Stop async DHT-get.
Definition: dht_api.c:1237
void GNUNET_DHT_get_filter_known_results(struct GNUNET_DHT_GetHandle *get_handle, unsigned int num_results, const struct GNUNET_HashCode *results)
Tell the DHT not to return any of the following known results to this client.
Definition: dht_api.c:1213
void(* GNUNET_DHT_GetIterator)(void *cls, struct GNUNET_TIME_Absolute exp, const struct GNUNET_HashCode *query_hash, const struct GNUNET_PeerIdentity *trunc_peer, const struct GNUNET_DHT_PathElement *get_path, unsigned int get_path_length, const struct GNUNET_DHT_PathElement *put_path, unsigned int put_path_length, enum GNUNET_BLOCK_Type type, size_t size, const void *data)
Iterator called on each result obtained for a DHT operation that expects a reply.
struct GNUNET_DHT_Handle * GNUNET_DHT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, unsigned int ht_len)
Initialize the connection with the DHT service.
Definition: dht_api.c:1039
void(* GNUNET_DHT_MonitorGetRespCB)(void *cls, enum GNUNET_BLOCK_Type type, const struct GNUNET_PeerIdentity *trunc_peer, const struct GNUNET_DHT_PathElement *get_path, unsigned int get_path_length, const struct GNUNET_DHT_PathElement *put_path, unsigned int put_path_length, struct GNUNET_TIME_Absolute exp, const struct GNUNET_HashCode *key, const void *data, size_t size)
Callback called on each GET reply going through the DHT.
void(* GNUNET_DHT_MonitorGetCB)(void *cls, enum GNUNET_DHT_RouteOption options, enum GNUNET_BLOCK_Type type, uint32_t hop_count, uint32_t desired_replication_level, const struct GNUNET_HashCode *key)
Callback called on each GET request going through the DHT.
void(* GNUNET_DHT_HelloGetCallback)(void *cls, const char *hello_url)
Signature called with the result of a HELLO GET operation.
struct GNUNET_DHT_PutHandle * GNUNET_DHT_put(struct GNUNET_DHT_Handle *handle, const struct GNUNET_HashCode *key, uint32_t desired_replication_level, enum GNUNET_DHT_RouteOption options, enum GNUNET_BLOCK_Type type, size_t size, const void *data, struct GNUNET_TIME_Absolute exp, GNUNET_SCHEDULER_TaskCallback cont, void *cont_cls)
Perform a PUT operation storing data in the DHT.
Definition: dht_api.c:1090
struct GNUNET_DHT_HelloGetHandle * GNUNET_DHT_hello_get(struct GNUNET_DHT_Handle *dht_handle, GNUNET_DHT_HelloGetCallback cb, void *cb_cls)
Obtain HELLO URL of the DHT identified by dht_handle.
Definition: dht_api.c:1444
void GNUNET_DHT_disconnect(struct GNUNET_DHT_Handle *handle)
Shutdown connection with the DHT service.
Definition: dht_api.c:1062
void GNUNET_DHT_hello_offer(struct GNUNET_DHT_Handle *dht_handle, const char *url, GNUNET_SCHEDULER_TaskCallback cb, void *cb_cls)
Offer HELLO URL of the DHT identified by dht_handle.
Definition: dht_api.c:1480
void(* GNUNET_DHT_MonitorPutCB)(void *cls, enum GNUNET_DHT_RouteOption options, enum GNUNET_BLOCK_Type type, uint32_t hop_count, uint32_t desired_replication_level, const struct GNUNET_PeerIdentity *trunc_peer, unsigned int path_length, const struct GNUNET_DHT_PathElement *path, struct GNUNET_TIME_Absolute exp, const struct GNUNET_HashCode *key, const void *data, size_t size)
Callback called on each PUT request going through the DHT.
struct GNUNET_DHT_GetHandle * GNUNET_DHT_get_start(struct GNUNET_DHT_Handle *handle, enum GNUNET_BLOCK_Type type, const struct GNUNET_HashCode *key, uint32_t desired_replication_level, enum GNUNET_DHT_RouteOption options, const void *xquery, size_t xquery_size, GNUNET_DHT_GetIterator iter, void *iter_cls)
Perform an asynchronous GET operation on the DHT identified.
Definition: dht_api.c:1164
unsigned int GNUNET_DHT_verify_path(const void *data, size_t data_size, struct GNUNET_TIME_Absolute exp_time, const struct GNUNET_PeerIdentity *bpid, const struct GNUNET_DHT_PathElement *put_path, unsigned int put_path_len, const struct GNUNET_DHT_PathElement *get_path, unsigned int get_path_len, const struct GNUNET_PeerIdentity *me)
Verify signatures on a path consisting of put_path and get_path in reverse order (starting at the las...
Definition: dht_api.c:1353
void GNUNET_DHT_monitor_stop(struct GNUNET_DHT_MonitorHandle *mh)
Stop monitoring.
Definition: dht_api.c:1302
@ GNUNET_DHT_RO_TRUNCATED
Flag set if the path was truncated.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
int GNUNET_CONTAINER_multihashmap_get_multiple(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map that match a particular key.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
enum GNUNET_GenericReturnValue 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.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE
Allow multiple values with the same key.
#define GNUNET_log(kind,...)
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
Definition: gnunet_common.h:96
@ GNUNET_OK
Definition: gnunet_common.h:99
@ GNUNET_YES
@ GNUNET_NO
Definition: gnunet_common.h:98
@ GNUNET_SYSERR
Definition: gnunet_common.h:97
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
GNUNET_MQ_Error
Error codes for the queue.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:302
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#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:56
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:71
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
void GNUNET_MQ_notify_sent(struct GNUNET_MQ_Envelope *ev, GNUNET_SCHEDULER_TaskCallback cb, void *cb_cls)
Call a callback once the envelope has been sent, that is, sending it can not be canceled anymore.
Definition: mq.c:640
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:685
#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET
Receive information about transiting GETs.
#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET_RESP
Receive information about transiting GET responses.
#define GNUNET_MESSAGE_TYPE_DHT_CLIENT_PUT
Client wants to store item in DHT.
#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_START
Request information about transiting messages.
#define GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_RESULTS_KNOWN
Certain results are already known to the client, filter those.
#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT
Receive information about transiting PUTs.
#define GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_STOP
Client wants to stop search in DHT.
#define GNUNET_MESSAGE_TYPE_DHT_CLIENT_RESULT
Service returns result to client.
#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_STOP
Stop information about transiting messages.
#define GNUNET_MESSAGE_TYPE_DHT_CLIENT_HELLO_GET
Client requests DHT service's HELLO URL.
#define GNUNET_MESSAGE_TYPE_DHT_CLIENT_HELLO_URL
HELLO URL send between client and service (in either direction).
#define GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET
Client wants to lookup item in DHT.
void(* GNUNET_SCHEDULER_TaskCallback)(void *cls)
Signature of the main function of a task.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:957
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:1254
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:736
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:570
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:637
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
#define max(x, y)
static unsigned int size
Size of the "table".
Definition: peer.c:67
static enum GNUNET_GenericReturnValue get_cb(void *cls, const struct GNUNET_HashCode *key, void *value)
Function called during GET to find matching blocks.
static enum GNUNET_GenericReturnValue put_cb(void *cls, const struct GNUNET_HashCode *key, void *value)
Function called during PUT to detect if an equivalent block already exists.
static struct GNUNET_TIME_Relative delta
Definition: speedup.c:35
struct GNUNET_MQ_Handle * mq
Our connection to the ARM service.
Definition: arm_api.c:107
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration that we are using.
Definition: arm_api.c:112
struct GNUNET_SCHEDULER_Task * reconnect_task
ID of the reconnect task (if any).
Definition: arm_api.c:147
Internal representation of the hash map.
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
DHT GET message sent from clients to service.
Definition: dht.h:72
uint64_t unique_id
Unique ID identifying this request, if 0 then the client will not expect a response.
Definition: dht.h:103
uint32_t options
Message options, actually an 'enum GNUNET_DHT_RouteOption' value.
Definition: dht.h:81
struct GNUNET_HashCode key
The key to search for.
Definition: dht.h:97
uint32_t type
The type for the data for the GET request; actually an 'enum GNUNET_BLOCK_Type'.
Definition: dht.h:92
uint32_t desired_replication_level
Replication level for this message.
Definition: dht.h:86
DHT GET RESULTS KNOWN message sent from clients to service.
Definition: dht.h:114
Message which indicates the DHT should cancel outstanding requests and discard any state.
Definition: dht.h:44
uint64_t unique_id
Unique ID identifying this request.
Definition: dht.h:58
struct GNUNET_HashCode key
Key of this request.
Definition: dht.h:63
uint32_t reserved
Always zero.
Definition: dht.h:53
Message to insert data into the DHT, sent from clients to DHT service.
Definition: dht.h:200
struct GNUNET_HashCode key
The key to store the value under.
Definition: dht.h:229
uint32_t type
The type of data to insert.
Definition: dht.h:209
uint32_t options
Message options, actually an 'enum GNUNET_DHT_RouteOption' value.
Definition: dht.h:214
uint32_t desired_replication_level
Replication level for this message.
Definition: dht.h:219
struct GNUNET_TIME_AbsoluteNBO expiration
How long should this data persist?
Definition: dht.h:224
Reply to a GET send from the service to a client.
Definition: dht.h:144
uint32_t put_path_length
Number of peers recorded in the outgoing path from source to the storgage location of this message.
Definition: dht.h:169
uint64_t unique_id
Unique ID of the matching GET request.
Definition: dht.h:180
struct GNUNET_TIME_AbsoluteNBO expiration
When does this entry expire?
Definition: dht.h:185
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_DHT_CLIENT_RESULT.
Definition: dht.h:148
uint32_t type
The type for the data.
Definition: dht.h:153
uint32_t options
Message options, actually an 'enum GNUNET_DHT_RouteOption' value.
Definition: dht.h:163
uint32_t get_path_length
The number of peer identities recorded from the storage location to this peer.
Definition: dht.h:175
Handle to a GET request.
Definition: dht_api.c:81
GNUNET_DHT_GetIterator iter
Iterator to call on data receipt.
Definition: dht_api.c:85
enum GNUNET_BLOCK_Type type
Type of the block we are looking for.
Definition: dht_api.c:126
void * iter_cls
Closure for iter.
Definition: dht_api.c:90
unsigned int seen_results_end
Offset into the seen_results array marking the end of the positions that are actually used.
Definition: dht_api.c:143
struct GNUNET_HashCode * seen_results
Array of hash codes over the results that we have already seen.
Definition: dht_api.c:101
size_t xquery_size
Size of the extended query, allocated at the end of this struct.
Definition: dht_api.c:116
uint32_t desired_replication_level
Desired replication level.
Definition: dht_api.c:121
struct GNUNET_HashCode key
Key that this get request is for.
Definition: dht_api.c:106
uint64_t unique_id
Unique identifier for this request (for key collisions).
Definition: dht_api.c:111
struct GNUNET_DHT_Handle * dht_handle
Main handle to this DHT api.
Definition: dht_api.c:95
enum GNUNET_DHT_RouteOption options
Routing options.
Definition: dht_api.c:131
unsigned int seen_results_size
Size of the seen_results array.
Definition: dht_api.c:137
Connection to the DHT service.
Definition: dht_api.c:237
struct GNUNET_CONTAINER_MultiHashMap * active_requests
Hash map containing the current outstanding unique GET requests (values are of type struct GNUNET_DHT...
Definition: dht_api.c:282
struct GNUNET_TIME_Relative retry_time
How quickly should we retry? Used for exponential back-off on connect-errors.
Definition: dht_api.c:293
struct GNUNET_SCHEDULER_Task * reconnect_task
Task for trying to reconnect.
Definition: dht_api.c:287
struct GNUNET_DHT_PutHandle * put_tail
Tail of active PUT requests.
Definition: dht_api.c:266
struct GNUNET_DHT_MonitorHandle * monitor_tail
Tail of linked list of messages we would like to monitor.
Definition: dht_api.c:256
struct GNUNET_MQ_Handle * mq
Connection to DHT service.
Definition: dht_api.c:246
struct GNUNET_DHT_PutHandle * put_head
Head of active PUT requests.
Definition: dht_api.c:261
struct GNUNET_DHT_MonitorHandle * monitor_head
Head of linked list of messages we would like to monitor.
Definition: dht_api.c:251
struct GNUNET_DHT_HelloGetHandle * hgh_tail
DLL.
Definition: dht_api.c:276
uint64_t uid_gen
Generator for unique ids.
Definition: dht_api.c:298
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration to use.
Definition: dht_api.c:241
struct GNUNET_DHT_HelloGetHandle * hgh_head
DLL.
Definition: dht_api.c:271
Handle to get a HELLO URL from the DHT for manual bootstrapping.
Definition: dht_api.c:203
struct GNUNET_DHT_Handle * dht_handle
Connection to the DHT service.
Definition: dht_api.c:228
GNUNET_DHT_HelloGetCallback cb
Function to call with the result.
Definition: dht_api.c:218
void * cb_cls
Closure for cb.
Definition: dht_api.c:223
struct GNUNET_DHT_HelloGetHandle * prev
DLL.
Definition: dht_api.c:213
struct GNUNET_DHT_HelloGetHandle * next
DLL.
Definition: dht_api.c:208
Message signed by a peer when doing path tracking.
struct GNUNET_HashCode h_data
Hash over the payload of the block.
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Must be GNUNET_SIGNATURE_PURPOSE_DHT_HOP.
struct GNUNET_PeerIdentity pred
Previous hop the message was received from.
struct GNUNET_PeerIdentity succ
Next hop the message was forwarded to.
Message to monitor get requests going through peer, DHT service -> clients.
Definition: dht.h:334
Message to monitor get results going through peer, DHT service -> clients.
Definition: dht.h:377
Handle to a monitoring request.
Definition: dht_api.c:151
GNUNET_DHT_MonitorGetRespCB get_resp_cb
Callback for each received message of type get response.
Definition: dht_api.c:185
struct GNUNET_HashCode * key
Key being looked for, NULL == all.
Definition: dht_api.c:175
struct GNUNET_DHT_MonitorHandle * prev
DLL.
Definition: dht_api.c:160
struct GNUNET_DHT_MonitorHandle * next
DLL.
Definition: dht_api.c:155
GNUNET_DHT_MonitorPutCB put_cb
Callback for each received message of type put.
Definition: dht_api.c:190
struct GNUNET_DHT_Handle * dht_handle
Main handle to this DHT api.
Definition: dht_api.c:165
GNUNET_DHT_MonitorGetCB get_cb
Callback for each received message of type get.
Definition: dht_api.c:180
void * cb_cls
Closure for get_cb, put_cb and get_resp_cb.
Definition: dht_api.c:195
enum GNUNET_BLOCK_Type type
Type of block looked for.
Definition: dht_api.c:170
Message to monitor put requests going through peer, DHT service -> clients.
Definition: dht.h:239
Message to request monitoring messages, clients -> DHT service.
Definition: dht.h:291
A (signed) path tracking a block's flow through the DHT is represented by an array of path elements,...
struct GNUNET_PeerIdentity pred
Previous peer on the path (matches "pred" in the signed field).
struct GNUNET_CRYPTO_EddsaSignature sig
Signature affirming the hop of type GNUNET_SIGNATURE_PURPOSE_DHT_HOP.
Handle to a PUT request.
Definition: dht_api.c:45
struct GNUNET_DHT_Handle * dht_handle
Main handle to this DHT api.
Definition: dht_api.c:64
struct GNUNET_DHT_PutHandle * prev
Kept in a DLL.
Definition: dht_api.c:54
void * cont_cls
Closure for cont.
Definition: dht_api.c:69
struct GNUNET_MQ_Envelope * env
Envelope from the PUT operation.
Definition: dht_api.c:74
struct GNUNET_DHT_PutHandle * next
Kept in a DLL.
Definition: dht_api.c:49
GNUNET_SCHEDULER_TaskCallback cont
Continuation to call when done.
Definition: dht_api.c:59
struct GNUNET_SCHEDULER_Task * reconnect_task
Task to reconnect to the service.
Definition: dns_api.c:81
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration to use.
Definition: dns_api.c:66
struct GNUNET_MQ_Handle * mq
Connection to DNS service, or NULL.
Definition: dns_api.c:61
A 512-bit hashcode.
Handle to a message queue.
Definition: mq.c:86
Message handler for a specific message type.
Header for all communications.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
The identity of the host (wraps the signing key of the peer).
struct GNUNET_CRYPTO_EddsaPublicKey public_key
Entry in list of pending tasks.
Definition: scheduler.c:135
Time for absolute times used by GNUnet, in microseconds.
Time for relative time used by GNUnet, in microseconds.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model