GNUnet  0.11.x
dht_api.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2009, 2010, 2011, 2012, 2016, 2018 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_arm_service.h"
32 #include "gnunet_hello_lib.h"
33 #include "gnunet_protocols.h"
34 #include "gnunet_dht_service.h"
35 #include "dht.h"
36 
37 #define LOG(kind, ...) GNUNET_log_from (kind, "dht-api", __VA_ARGS__)
38 
39 
44 {
49 
54 
59 
64 
68  void *cont_cls;
69 
74 };
75 
80 {
85 
89  void *iter_cls;
90 
95 
101 
105  struct GNUNET_HashCode key;
106 
110  uint64_t unique_id;
111 
115  size_t xquery_size;
116 
121 
125  enum GNUNET_BLOCK_Type type;
126 
131 
136  unsigned int seen_results_size;
137 
142  unsigned int seen_results_end;
143 };
144 
145 
150 {
155 
160 
165 
169  enum GNUNET_BLOCK_Type type;
170 
175 
180 
185 
190 
194  void *cb_cls;
195 };
196 
197 
202 {
207 
212 
217 
222 
227 
232 
238 
243 
249 
253  uint64_t uid_gen;
254 };
255 
256 
263 static int
265 
266 
272 static void
274 {
275  struct GNUNET_DHT_Handle *h = gh->dht_handle;
276  struct GNUNET_MQ_Envelope *env;
277  struct GNUNET_DHT_ClientGetMessage *get_msg;
278 
279  env = GNUNET_MQ_msg_extra (get_msg,
280  gh->xquery_size,
282  get_msg->options = htonl ((uint32_t) gh->options);
283  get_msg->desired_replication_level = htonl (gh->desired_replication_level);
284  get_msg->type = htonl (gh->type);
285  get_msg->key = gh->key;
286  get_msg->unique_id = gh->unique_id;
287  GNUNET_memcpy (&get_msg[1],
288  &gh[1],
289  gh->xquery_size);
290  GNUNET_MQ_send (h->mq,
291  env);
292 }
293 
294 
304 static void
306  unsigned int transmission_offset_start)
307 {
308  struct GNUNET_DHT_Handle *h = gh->dht_handle;
309  struct GNUNET_MQ_Envelope *env;
311  unsigned int delta;
312  unsigned int max;
313  unsigned int transmission_offset;
314 
315  max = (GNUNET_MAX_MESSAGE_SIZE - sizeof(*msg))
316  / sizeof(struct GNUNET_HashCode);
317  transmission_offset = transmission_offset_start;
318  while (transmission_offset < gh->seen_results_end)
319  {
320  delta = gh->seen_results_end - transmission_offset;
321  if (delta > max)
322  delta = max;
324  delta * sizeof(struct GNUNET_HashCode),
326  msg->key = gh->key;
327  msg->unique_id = gh->unique_id;
328  GNUNET_memcpy (&msg[1],
329  &gh->seen_results[transmission_offset],
330  sizeof(struct GNUNET_HashCode) * delta);
331  GNUNET_MQ_send (h->mq,
332  env);
333  transmission_offset += delta;
334  }
335 }
336 
337 
347 static int
349  const struct GNUNET_HashCode *key,
350  void *value)
351 {
352  struct GNUNET_DHT_Handle *handle = cls;
353  struct GNUNET_DHT_GetHandle *gh = value;
354 
356  "Retransmitting request related to %s to DHT %p\n",
357  GNUNET_h2s (key),
358  handle);
359  send_get (gh);
361  return GNUNET_YES;
362 }
363 
364 
370 static void
372 {
373  struct GNUNET_DHT_Handle *h = mh->dht_handle;
374  struct GNUNET_MQ_Envelope *env;
376 
377  env = GNUNET_MQ_msg (m,
379  m->type = htonl (mh->type);
380  m->get = htons (NULL != mh->get_cb);
381  m->get_resp = htons (NULL != mh->get_resp_cb);
382  m->put = htons (NULL != mh->put_cb);
383  if (NULL != mh->key)
384  {
385  m->filter_key = htons (1);
386  m->key = *mh->key;
387  }
388  GNUNET_MQ_send (h->mq,
389  env);
390 }
391 
392 
398 static void
399 try_reconnect (void *cls)
400 {
401  struct GNUNET_DHT_Handle *h = cls;
403 
405  "Reconnecting with DHT %p\n",
406  h);
407  h->retry_time = GNUNET_TIME_STD_BACKOFF (h->retry_time);
408  h->reconnect_task = NULL;
409  if (GNUNET_YES != try_connect (h))
410  {
412  "DHT reconnect failed!\n");
414  = GNUNET_SCHEDULER_add_delayed (h->retry_time,
415  &try_reconnect,
416  h);
417  return;
418  }
419  GNUNET_CONTAINER_multihashmap_iterate (h->active_requests,
421  h);
422  for (mh = h->monitor_head; NULL != mh; mh = mh->next)
424 }
425 
426 
432 static void
434 {
435  struct GNUNET_DHT_PutHandle *ph;
437  void *cont_cls;
438 
439  if (NULL == h->mq)
440  return;
442  h->mq = NULL;
444  "Disconnecting from DHT service, will try to reconnect in %s\n",
446  GNUNET_YES));
447  /* notify client about all PUTs that (may) have failed due to disconnect */
448  while (NULL != (ph = h->put_head))
449  {
450  cont = ph->cont;
451  cont_cls = ph->cont_cls;
452  ph->env = NULL;
454  if (NULL != cont)
455  cont (cont_cls);
456  }
457  GNUNET_assert (NULL == h->reconnect_task);
459  = GNUNET_SCHEDULER_add_delayed (h->retry_time,
460  &try_reconnect,
461  h);
462 }
463 
464 
473 static void
474 mq_error_handler (void *cls,
475  enum GNUNET_MQ_Error error)
476 {
477  struct GNUNET_DHT_Handle *h = cls;
478 
479  do_disconnect (h);
480 }
481 
482 
491 static int
492 check_monitor_get (void *cls,
493  const struct GNUNET_DHT_MonitorGetMessage *msg)
494 {
495  uint32_t plen = ntohl (msg->get_path_length);
496  uint16_t msize = ntohs (msg->header.size) - sizeof(*msg);
497 
498  if ((plen > UINT16_MAX) ||
499  (plen * sizeof(struct GNUNET_PeerIdentity) != msize))
500  {
501  GNUNET_break (0);
502  return GNUNET_SYSERR;
503  }
504  return GNUNET_OK;
505 }
506 
507 
514 static void
516  const struct GNUNET_DHT_MonitorGetMessage *msg)
517 {
518  struct GNUNET_DHT_Handle *handle = cls;
520 
521  for (mh = handle->monitor_head; NULL != mh; mh = mh->next)
522  {
523  if (NULL == mh->get_cb)
524  continue;
525  if (((GNUNET_BLOCK_TYPE_ANY == mh->type) ||
526  (mh->type == ntohl (msg->type))) &&
527  ((NULL == mh->key) ||
528  (0 == memcmp (mh->key,
529  &msg->key,
530  sizeof(struct GNUNET_HashCode)))))
531  mh->get_cb (mh->cb_cls,
532  ntohl (msg->options),
533  (enum GNUNET_BLOCK_Type) ntohl (msg->type),
534  ntohl (msg->hop_count),
535  ntohl (msg->desired_replication_level),
536  ntohl (msg->get_path_length),
537  (struct GNUNET_PeerIdentity *) &msg[1],
538  &msg->key);
539  }
540 }
541 
542 
551 static int
554 {
555  size_t msize = ntohs (msg->header.size) - sizeof(*msg);
556  uint32_t getl = ntohl (msg->get_path_length);
557  uint32_t putl = ntohl (msg->put_path_length);
558 
559  if ((getl + putl < getl) ||
560  ((msize / sizeof(struct GNUNET_PeerIdentity)) < getl + putl))
561  {
562  GNUNET_break (0);
563  return GNUNET_SYSERR;
564  }
565  return GNUNET_OK;
566 }
567 
568 
575 static void
578 {
579  struct GNUNET_DHT_Handle *handle = cls;
580  size_t msize = ntohs (msg->header.size) - sizeof(*msg);
581  const struct GNUNET_PeerIdentity *path;
582  uint32_t getl = ntohl (msg->get_path_length);
583  uint32_t putl = ntohl (msg->put_path_length);
585 
586  path = (const struct GNUNET_PeerIdentity *) &msg[1];
587  for (mh = handle->monitor_head; NULL != mh; mh = mh->next)
588  {
589  if (NULL == mh->get_resp_cb)
590  continue;
591  if (((GNUNET_BLOCK_TYPE_ANY == mh->type) ||
592  (mh->type == ntohl (msg->type))) &&
593  ((NULL == mh->key) ||
594  (0 == memcmp (mh->key,
595  &msg->key,
596  sizeof(struct GNUNET_HashCode)))))
597  mh->get_resp_cb (mh->cb_cls,
598  (enum GNUNET_BLOCK_Type) ntohl (msg->type),
599  path,
600  getl,
601  &path[getl],
602  putl,
603  GNUNET_TIME_absolute_ntoh (msg->expiration_time),
604  &msg->key,
605  (const void *) &path[getl + putl],
606  msize - sizeof(struct GNUNET_PeerIdentity) * (putl
607  + getl));
608  }
609 }
610 
611 
620 static int
621 check_monitor_put (void *cls,
622  const struct GNUNET_DHT_MonitorPutMessage *msg)
623 {
624  size_t msize;
625  uint32_t putl;
626 
627  msize = ntohs (msg->header.size) - sizeof(*msg);
628  putl = ntohl (msg->put_path_length);
629  if ((msize / sizeof(struct GNUNET_PeerIdentity)) < putl)
630  {
631  GNUNET_break (0);
632  return GNUNET_SYSERR;
633  }
634  return GNUNET_OK;
635 }
636 
637 
644 static void
646  const struct GNUNET_DHT_MonitorPutMessage *msg)
647 {
648  struct GNUNET_DHT_Handle *handle = cls;
649  size_t msize = ntohs (msg->header.size) - sizeof(*msg);
650  uint32_t putl = ntohl (msg->put_path_length);
651  const struct GNUNET_PeerIdentity *path;
653 
654  path = (const struct GNUNET_PeerIdentity *) &msg[1];
655  for (mh = handle->monitor_head; NULL != mh; mh = mh->next)
656  {
657  if (NULL == mh->put_cb)
658  continue;
659  if (((GNUNET_BLOCK_TYPE_ANY == mh->type) ||
660  (mh->type == ntohl (msg->type))) &&
661  ((NULL == mh->key) ||
662  (0 == memcmp (mh->key,
663  &msg->key,
664  sizeof(struct GNUNET_HashCode)))))
665  mh->put_cb (mh->cb_cls,
666  ntohl (msg->options),
667  (enum GNUNET_BLOCK_Type) ntohl (msg->type),
668  ntohl (msg->hop_count),
669  ntohl (msg->desired_replication_level),
670  putl,
671  path,
672  GNUNET_TIME_absolute_ntoh (msg->expiration_time),
673  &msg->key,
674  (const void *) &path[putl],
675  msize - sizeof(struct GNUNET_PeerIdentity) * putl);
676  }
677 }
678 
679 
688 static int
690  const struct GNUNET_DHT_ClientResultMessage *msg)
691 {
692  size_t msize = ntohs (msg->header.size) - sizeof(*msg);
693  uint32_t put_path_length = ntohl (msg->put_path_length);
694  uint32_t get_path_length = ntohl (msg->get_path_length);
695  size_t meta_length;
696 
697  meta_length =
698  sizeof(struct GNUNET_PeerIdentity) * (get_path_length + put_path_length);
699  if ((msize < meta_length) ||
700  (get_path_length >
701  GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)) ||
702  (put_path_length >
704  {
705  GNUNET_break (0);
706  return GNUNET_SYSERR;
707  }
708  return GNUNET_OK;
709 }
710 
711 
720 static int
722  const struct GNUNET_HashCode *key,
723  void *value)
724 {
725  const struct GNUNET_DHT_ClientResultMessage *crm = cls;
727  size_t msize = ntohs (crm->header.size) - sizeof(*crm);
728  uint32_t put_path_length = ntohl (crm->put_path_length);
729  uint32_t get_path_length = ntohl (crm->get_path_length);
730  const struct GNUNET_PeerIdentity *put_path;
731  const struct GNUNET_PeerIdentity *get_path;
732  struct GNUNET_HashCode hc;
733  size_t data_length;
734  size_t meta_length;
735  const void *data;
736 
737  if (crm->unique_id != get_handle->unique_id)
738  {
739  /* UID mismatch */
741  "Ignoring reply for %s: UID mismatch: %llu/%llu\n",
742  GNUNET_h2s (key),
743  (unsigned long long) crm->unique_id,
744  (unsigned long long) get_handle->unique_id);
745  return GNUNET_YES;
746  }
747  /* FIXME: might want to check that type matches */
748  meta_length =
749  sizeof(struct GNUNET_PeerIdentity) * (get_path_length + put_path_length);
750  data_length = msize - meta_length;
751  put_path = (const struct GNUNET_PeerIdentity *) &crm[1];
752  get_path = &put_path[put_path_length];
753  {
754  char *pp;
755  char *gp;
756 
757  gp = GNUNET_STRINGS_pp2s (get_path,
758  get_path_length);
759  pp = GNUNET_STRINGS_pp2s (put_path,
760  put_path_length);
762  "Giving %u byte reply for %s to application (GP: %s, PP: %s)\n",
763  (unsigned int) data_length,
764  GNUNET_h2s (key),
765  gp,
766  pp);
767  GNUNET_free (gp);
768  GNUNET_free (pp);
769  }
770  data = &get_path[get_path_length];
771  /* remember that we've seen this result */
773  data_length,
774  &hc);
778  get_handle->seen_results_size * 2 + 1);
780  /* no need to block it explicitly, service already knows about it! */
783  key,
784  get_path,
785  get_path_length,
786  put_path,
787  put_path_length,
788  ntohl (crm->type),
789  data_length,
790  data);
791  return GNUNET_YES;
792 }
793 
794 
801 static void
803  const struct GNUNET_DHT_ClientResultMessage *msg)
804 {
805  struct GNUNET_DHT_Handle *handle = cls;
806 
808  &msg->key,
810  (void *) msg);
811 }
812 
813 
819 static void
820 handle_put_cont (void *cls)
821 {
822  struct GNUNET_DHT_PutHandle *ph = cls;
824  void *cont_cls;
825 
826  cont = ph->cont;
827  cont_cls = ph->cont_cls;
828  ph->env = NULL;
830  if (NULL != cont)
831  cont (cont_cls);
832 }
833 
834 
841 static int
843 {
845  GNUNET_MQ_hd_var_size (monitor_get,
848  h),
849  GNUNET_MQ_hd_var_size (monitor_get_resp,
852  h),
853  GNUNET_MQ_hd_var_size (monitor_put,
856  h),
857  GNUNET_MQ_hd_var_size (client_result,
860  h),
862  };
863 
864  if (NULL != h->mq)
865  return GNUNET_OK;
867  "dht",
868  handlers,
870  h);
871  if (NULL == h->mq)
872  {
874  "Failed to connect to the DHT service!\n");
875  return GNUNET_NO;
876  }
877  return GNUNET_YES;
878 }
879 
880 
889 struct GNUNET_DHT_Handle *
891  unsigned int ht_len)
892 {
893  struct GNUNET_DHT_Handle *handle;
894 
896  handle->cfg = cfg;
897  handle->uid_gen
899  UINT64_MAX);
900  handle->active_requests
902  GNUNET_YES);
903  if (GNUNET_NO == try_connect (handle))
904  {
906  return NULL;
907  }
908  return handle;
909 }
910 
911 
917 void
919 {
920  struct GNUNET_DHT_PutHandle *ph;
921 
922  GNUNET_assert (0 ==
923  GNUNET_CONTAINER_multihashmap_size (handle->active_requests));
924  while (NULL != (ph = handle->put_head))
925  {
926  if (NULL != ph->cont)
927  ph->cont (ph->cont_cls);
929  }
930  if (NULL != handle->mq)
931  {
933  handle->mq = NULL;
934  }
935  if (NULL != handle->reconnect_task)
936  {
938  handle->reconnect_task = NULL;
939  }
942 }
943 
944 
965 struct GNUNET_DHT_PutHandle *
967  const struct GNUNET_HashCode *key,
968  uint32_t desired_replication_level,
970  enum GNUNET_BLOCK_Type type,
971  size_t size,
972  const void *data,
973  struct GNUNET_TIME_Absolute exp,
975  void *cont_cls)
976 {
977  struct GNUNET_MQ_Envelope *env;
978  struct GNUNET_DHT_ClientPutMessage *put_msg;
979  size_t msize;
980  struct GNUNET_DHT_PutHandle *ph;
981 
982  msize = sizeof(struct GNUNET_DHT_ClientPutMessage) + size;
983  if ((msize >= GNUNET_MAX_MESSAGE_SIZE) ||
985  {
986  GNUNET_break (0);
987  return NULL;
988  }
989  if (NULL == handle->mq)
990  return NULL;
992  "Sending PUT for %s to DHT via %p\n",
993  GNUNET_h2s (key),
994  handle);
996  ph->dht_handle = handle;
997  ph->cont = cont;
998  ph->cont_cls = cont_cls;
1000  handle->put_tail,
1001  ph);
1002  env = GNUNET_MQ_msg_extra (put_msg,
1003  size,
1006  &handle_put_cont,
1007  ph);
1008  ph->env = env;
1009  put_msg->type = htonl ((uint32_t) type);
1010  put_msg->options = htonl ((uint32_t) options);
1012  put_msg->expiration = GNUNET_TIME_absolute_hton (exp);
1013  put_msg->key = *key;
1014  GNUNET_memcpy (&put_msg[1],
1015  data,
1016  size);
1018  env);
1019  return ph;
1020 }
1021 
1022 
1034 void
1036 {
1037  struct GNUNET_DHT_Handle *handle = ph->dht_handle;
1038 
1039  if (NULL != ph->env)
1040  GNUNET_MQ_notify_sent (ph->env,
1041  NULL,
1042  NULL);
1044  handle->put_tail,
1045  ph);
1046  GNUNET_free (ph);
1047 }
1048 
1049 
1066 struct GNUNET_DHT_GetHandle *
1068  enum GNUNET_BLOCK_Type type,
1069  const struct GNUNET_HashCode *key,
1070  uint32_t desired_replication_level,
1072  const void *xquery,
1073  size_t xquery_size,
1075  void *iter_cls)
1076 {
1077  struct GNUNET_DHT_GetHandle *gh;
1078  size_t msize;
1079 
1080  msize = sizeof(struct GNUNET_DHT_ClientGetMessage) + xquery_size;
1081  if ((msize >= GNUNET_MAX_MESSAGE_SIZE) ||
1082  (xquery_size >= GNUNET_MAX_MESSAGE_SIZE))
1083  {
1084  GNUNET_break (0);
1085  return NULL;
1086  }
1088  "Sending query for %s to DHT %p\n",
1089  GNUNET_h2s (key),
1090  handle);
1091  gh = GNUNET_malloc (sizeof(struct GNUNET_DHT_GetHandle)
1092  + xquery_size);
1093  gh->iter = iter;
1094  gh->iter_cls = iter_cls;
1095  gh->dht_handle = handle;
1096  gh->key = *key;
1097  gh->unique_id = ++handle->uid_gen;
1098  gh->xquery_size = xquery_size;
1099  gh->desired_replication_level = desired_replication_level;
1100  gh->type = type;
1101  gh->options = options;
1102  GNUNET_memcpy (&gh[1],
1103  xquery,
1104  xquery_size);
1105  GNUNET_CONTAINER_multihashmap_put (handle->active_requests,
1106  &gh->key,
1107  gh,
1109  if (NULL != handle->mq)
1110  send_get (gh);
1111  return gh;
1112 }
1113 
1114 
1125 void
1127  unsigned int num_results,
1128  const struct GNUNET_HashCode *results)
1129 {
1130  unsigned int needed;
1131  unsigned int had;
1132 
1134  needed = had + num_results;
1135  if (needed > get_handle->seen_results_size)
1138  needed);
1140  results,
1141  num_results * sizeof(struct GNUNET_HashCode));
1142  get_handle->seen_results_end += num_results;
1143  if (NULL != get_handle->dht_handle->mq)
1145  had);
1146 }
1147 
1148 
1154 void
1156 {
1158 
1160  "Sending STOP for %s to DHT via %p\n",
1162  handle);
1163  if (NULL != handle->mq)
1164  {
1165  struct GNUNET_MQ_Envelope *env;
1166  struct GNUNET_DHT_ClientGetStopMessage *stop_msg;
1167 
1168  env = GNUNET_MQ_msg (stop_msg,
1170  stop_msg->reserved = htonl (0);
1171  stop_msg->unique_id = get_handle->unique_id;
1172  stop_msg->key = get_handle->key;
1174  env);
1175  }
1177  GNUNET_CONTAINER_multihashmap_remove (handle->active_requests,
1178  &get_handle->key,
1179  get_handle));
1182  0);
1184 }
1185 
1186 
1199 struct GNUNET_DHT_MonitorHandle *
1201  enum GNUNET_BLOCK_Type type,
1202  const struct GNUNET_HashCode *key,
1206  void *cb_cls)
1207 {
1208  struct GNUNET_DHT_MonitorHandle *mh;
1209 
1211  mh->get_cb = get_cb;
1212  mh->get_resp_cb = get_resp_cb;
1213  mh->put_cb = put_cb;
1214  mh->cb_cls = cb_cls;
1215  mh->type = type;
1216  mh->dht_handle = handle;
1217  if (NULL != key)
1218  {
1219  mh->key = GNUNET_new (struct GNUNET_HashCode);
1220  *mh->key = *key;
1221  }
1222  GNUNET_CONTAINER_DLL_insert (handle->monitor_head,
1223  handle->monitor_tail,
1224  mh);
1225  if (NULL != handle->mq)
1227  return mh;
1228 }
1229 
1230 
1238 void
1240 {
1241  struct GNUNET_DHT_Handle *handle = mh->dht_handle;
1243  struct GNUNET_MQ_Envelope *env;
1244 
1245  GNUNET_CONTAINER_DLL_remove (handle->monitor_head,
1246  handle->monitor_tail,
1247  mh);
1248  env = GNUNET_MQ_msg (m,
1250  m->type = htonl (mh->type);
1251  m->get = htons (NULL != mh->get_cb);
1252  m->get_resp = htons (NULL != mh->get_resp_cb);
1253  m->put = htons (NULL != mh->put_cb);
1254  if (NULL != mh->key)
1255  {
1256  m->filter_key = htons (1);
1257  m->key = *mh->key;
1258  }
1260  env);
1261  GNUNET_free (mh->key);
1262  GNUNET_free (mh);
1263 }
1264 
1265 
1266 /* 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
static int check_monitor_get(void *cls, const struct GNUNET_DHT_MonitorGetMessage *msg)
Verify integrity of a get monitor message from the service.
Definition: dht_api.c:492
static int 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:689
static void send_get(struct GNUNET_DHT_GetHandle *gh)
Send GET message for a get_handle to DHT.
Definition: dht_api.c:273
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:576
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:802
static int 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:621
static int 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:721
static void try_reconnect(void *cls)
Try reconnecting to the dht service.
Definition: dht_api.c:399
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:474
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:515
static int 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:348
static void do_disconnect(struct GNUNET_DHT_Handle *h)
Try reconnecting to the DHT service.
Definition: dht_api.c:433
static void handle_put_cont(void *cls)
Process a MQ PUT transmission notification.
Definition: dht_api.c:820
static int 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:552
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:305
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:645
#define LOG(kind,...)
Definition: dht_api.c:37
static int try_connect(struct GNUNET_DHT_Handle *h)
Try to (re)connect to the DHT service.
Definition: dht_api.c:842
static void send_monitor_start(struct GNUNET_DHT_MonitorHandle *mh)
Send GNUNET_MESSAGE_TYPE_DHT_MONITOR_START message.
Definition: dht_api.c:371
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
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 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.
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
Definition: gnunet-search.c:52
#define GNUNET_log(kind,...)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
Definition: gnunet_common.h:95
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_NO
Definition: gnunet_common.h:94
@ GNUNET_SYSERR
Definition: gnunet_common.h:93
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
GNUNET_BLOCK_Type
Blocks in the datastore and the datacache must have a unique type.
@ GNUNET_BLOCK_TYPE_ANY
Any type of block, used as a wildcard when searching.
struct GNUNET_MQ_Handle * GNUNET_CLIENT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *service_name, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *error_handler_cls)
Create a message queue to connect to a GNUnet service.
Definition: client.c:1064
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Random on unsigned 64-bit values.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
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, unsigned int path_length, const struct GNUNET_PeerIdentity *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.
void GNUNET_DHT_put_cancel(struct GNUNET_DHT_PutHandle *ph)
Cancels a DHT PUT operation.
Definition: dht_api.c:1035
GNUNET_DHT_RouteOption
Options for routing.
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:1200
void GNUNET_DHT_get_stop(struct GNUNET_DHT_GetHandle *get_handle)
Stop async DHT-get.
Definition: dht_api.c:1155
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, unsigned int path_length, const struct GNUNET_PeerIdentity *path, const struct GNUNET_HashCode *key)
Callback called on each GET request going through the DHT.
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:1126
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:890
void(* GNUNET_DHT_MonitorGetRespCB)(void *cls, enum GNUNET_BLOCK_Type type, const struct GNUNET_PeerIdentity *get_path, unsigned int get_path_length, const struct GNUNET_PeerIdentity *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.
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:966
void GNUNET_DHT_disconnect(struct GNUNET_DHT_Handle *handle)
Shutdown connection with the DHT service.
Definition: dht_api.c:918
void(* GNUNET_DHT_GetIterator)(void *cls, struct GNUNET_TIME_Absolute exp, const struct GNUNET_HashCode *key, const struct GNUNET_PeerIdentity *get_path, unsigned int get_path_length, const struct GNUNET_PeerIdentity *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_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:1067
void GNUNET_DHT_monitor_stop(struct GNUNET_DHT_MonitorHandle *mh)
Stop monitoring.
Definition: dht_api.c:1239
#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.
int 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.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
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.
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_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.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
GNUNET_MQ_Error
Error codes for the queue.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
Definition: gnunet_mq_lib.h:52
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
void GNUNET_MQ_notify_sent(struct GNUNET_MQ_Envelope *ev, GNUNET_SCHEDULER_TaskCallback cb, void *cb_cls)
Call a callback once the envelope has been sent, that is, sending it can not be canceled anymore.
Definition: mq.c:787
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:837
#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_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:972
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1269
char * GNUNET_STRINGS_pp2s(const struct GNUNET_PeerIdentity *pids, unsigned int num_pids)
Convert a peer path to a human-readable string.
Definition: strings.c:73
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:542
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:557
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:464
#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 int put_cb(void *cls, const struct GNUNET_HashCode *key, void *value)
Function called during PUT to detect if an equivalent block already exists.
static int get_cb(void *cls, const struct GNUNET_HashCode *key, void *value)
Function called during GET to find matching blocks.
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.
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:190
struct GNUNET_HashCode key
The key to store the value under.
Definition: dht.h:219
uint32_t type
The type of data to insert.
Definition: dht.h:199
uint32_t options
Message options, actually an 'enum GNUNET_DHT_RouteOption' value.
Definition: dht.h:204
uint32_t desired_replication_level
Replication level for this message.
Definition: dht.h:209
struct GNUNET_TIME_AbsoluteNBO expiration
How long should this data persist?
Definition: dht.h:214
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:159
uint64_t unique_id
Unique ID of the matching GET request.
Definition: dht.h:170
struct GNUNET_TIME_AbsoluteNBO expiration
When does this entry expire?
Definition: dht.h:175
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 get_path_length
The number of peer identities recorded from the storage location to this peer.
Definition: dht.h:165
Handle to a GET request.
Definition: dht_api.c:80
GNUNET_DHT_GetIterator iter
Iterator to call on data receipt.
Definition: dht_api.c:84
enum GNUNET_BLOCK_Type type
Type of the block we are looking for.
Definition: dht_api.c:125
void * iter_cls
Closure for iter.
Definition: dht_api.c:89
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:142
struct GNUNET_HashCode * seen_results
Array of hash codes over the results that we have already seen.
Definition: dht_api.c:100
size_t xquery_size
Size of the extended query, allocated at the end of this struct.
Definition: dht_api.c:115
uint32_t desired_replication_level
Desired replication level.
Definition: dht_api.c:120
struct GNUNET_HashCode key
Key that this get request is for.
Definition: dht_api.c:105
uint64_t unique_id
Unique identifier for this request (for key collisions).
Definition: dht_api.c:110
struct GNUNET_DHT_Handle * dht_handle
Main handle to this DHT api.
Definition: dht_api.c:94
enum GNUNET_DHT_RouteOption options
Routing options.
Definition: dht_api.c:130
unsigned int seen_results_size
Size of the seen_results array.
Definition: dht_api.c:136
Connection to the DHT service.
Definition: dht_api.c:202
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:237
struct GNUNET_TIME_Relative retry_time
How quickly should we retry? Used for exponential back-off on connect-errors.
Definition: dht_api.c:248
struct GNUNET_SCHEDULER_Task * reconnect_task
Task for trying to reconnect.
Definition: dht_api.c:242
struct GNUNET_DHT_PutHandle * put_tail
Tail of active PUT requests.
Definition: dht_api.c:231
struct GNUNET_DHT_MonitorHandle * monitor_tail
Tail of linked list of messages we would like to monitor.
Definition: dht_api.c:221
struct GNUNET_MQ_Handle * mq
Connection to DHT service.
Definition: dht_api.c:211
struct GNUNET_DHT_PutHandle * put_head
Head of active PUT requests.
Definition: dht_api.c:226
struct GNUNET_DHT_MonitorHandle * monitor_head
Head of linked list of messages we would like to monitor.
Definition: dht_api.c:216
uint64_t uid_gen
Generator for unique ids.
Definition: dht_api.c:253
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration to use.
Definition: dht_api.c:206
Message to monitor get requests going through peer, DHT service -> clients.
Definition: dht.h:324
Message to monitor get results going through peer, DHT service -> clients.
Definition: dht.h:368
Handle to a monitoring request.
Definition: dht_api.c:150
GNUNET_DHT_MonitorGetRespCB get_resp_cb
Callback for each received message of type get response.
Definition: dht_api.c:184
struct GNUNET_HashCode * key
Key being looked for, NULL == all.
Definition: dht_api.c:174
struct GNUNET_DHT_MonitorHandle * prev
DLL.
Definition: dht_api.c:159
struct GNUNET_DHT_MonitorHandle * next
DLL.
Definition: dht_api.c:154
GNUNET_DHT_MonitorPutCB put_cb
Callback for each received message of type put.
Definition: dht_api.c:189
struct GNUNET_DHT_Handle * dht_handle
Main handle to this DHT api.
Definition: dht_api.c:164
GNUNET_DHT_MonitorGetCB get_cb
Callback for each received message of type get.
Definition: dht_api.c:179
void * cb_cls
Closure for get_cb, put_cb and get_resp_cb.
Definition: dht_api.c:194
enum GNUNET_BLOCK_Type type
Type of block looked for.
Definition: dht_api.c:169
Message to monitor put requests going through peer, DHT service -> clients.
Definition: dht.h:229
Message to request monitoring messages, clients -> DHT service.
Definition: dht.h:281
Handle to a PUT request.
Definition: dht_api.c:44
struct GNUNET_DHT_Handle * dht_handle
Main handle to this DHT api.
Definition: dht_api.c:63
struct GNUNET_DHT_PutHandle * prev
Kept in a DLL.
Definition: dht_api.c:53
void * cont_cls
Closure for cont.
Definition: dht_api.c:68
struct GNUNET_MQ_Envelope * env
Envelope from the PUT operation.
Definition: dht_api.c:73
struct GNUNET_DHT_PutHandle * next
Kept in a DLL.
Definition: dht_api.c:48
GNUNET_SCHEDULER_TaskCallback cont
Continuation to call when done.
Definition: dht_api.c:58
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.
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).
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