GNUnet  0.11.x
gnunet-service-dht_clients.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2009, 2010, 2011, 2016, 2017, 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_constants.h"
30 #include "gnunet_protocols.h"
32 #include "gnunet-service-dht.h"
35 #include "dht.h"
36 
37 
41 #define LOG_TRAFFIC(kind, ...) GNUNET_log_from (kind, "dht-traffic", \
42  __VA_ARGS__)
43 
44 #define LOG(kind, ...) GNUNET_log_from (kind, "dht-clients", __VA_ARGS__)
45 
46 
52 struct ClientHandle;
53 
54 
59 {
63  struct GNUNET_HashCode key;
64 
69 
74 
78  struct ClientHandle *ch;
79 
83  const void *xquery;
84 
89 
94 
100 
105 
109  uint64_t unique_id;
110 
114  size_t xquery_size;
115 
119  unsigned int seen_replies_count;
120 
124  uint32_t replication;
125 
130 
134  enum GNUNET_BLOCK_Type type;
135 };
136 
137 
142 {
147 
152 
156  struct ClientHandle *ch;
157 
161  struct GNUNET_HashCode key;
162 
166  enum GNUNET_BLOCK_Type type;
167 
171  int16_t get;
172 
176  int16_t get_resp;
177 
181  uint16_t put;
182 
183 };
184 
185 
192 {
197 
202 
207 
212 };
213 
214 
219 
224 
229 
234 
239 
244 
249 
254 
259 
260 
266 static void
268 {
269  struct ClientHandle *ch = record->ch;
270 
271  GNUNET_CONTAINER_DLL_remove (ch->cqr_head,
272  ch->cqr_tail,
273  record);
276  &record->key,
277  record));
278  if (NULL != record->hnode)
280  GNUNET_array_grow (record->seen_replies,
281  record->seen_replies_count,
282  0);
284 }
285 
286 
296 static void *
297 client_connect_cb (void *cls,
299  struct GNUNET_MQ_Handle *mq)
300 {
301  struct ClientHandle *ch;
302 
303  (void) cls;
304  ch = GNUNET_new (struct ClientHandle);
305  ch->client = client;
306  ch->mq = mq;
307  return ch;
308 }
309 
310 
319 static void
322  void *app_ctx)
323 {
324  struct ClientHandle *ch = app_ctx;
325 
326  (void) cls;
327  (void) client;
329  "Local client %p disconnects\n",
330  ch);
331  {
332  struct ClientMonitorRecord *next;
333 
335  NULL != monitor;
336  monitor = next)
337  {
338  next = monitor->next;
339  if (monitor->ch != ch)
340  continue;
342  monitor_tail,
343  monitor);
345  }
346  }
347 
348  {
349  struct ClientQueryRecord *cqr;
350 
351  while (NULL != (cqr = ch->cqr_head))
353  }
354  GNUNET_free (ch);
355 }
356 
357 
365 static void
367 {
368  struct GNUNET_BLOCK_Group *bg;
369  struct GNUNET_CONTAINER_BloomFilter *peer_bf;
370 
372  "# GET requests from clients injected",
373  1,
374  GNUNET_NO);
376  cqr->type,
379  UINT32_MAX),
380  NULL, /* raw data */
381  0, /* raw data size */
382  "seen-set-size",
383  cqr->seen_replies_count,
384  NULL);
386  cqr->seen_replies,
387  cqr->seen_replies_count);
388  peer_bf
393  "Initiating GET for %s, replication %u, already have %u replies\n",
394  GNUNET_h2s (&cqr->key),
395  cqr->replication,
396  cqr->seen_replies_count);
398  cqr->msg_options,
399  cqr->replication,
400  0 /* hop count */,
401  &cqr->key,
402  cqr->xquery,
403  cqr->xquery_size,
404  bg,
405  peer_bf);
408 
409  /* Exponential back-off for retries.
410  * max. is #GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD (15 min) */
413 }
414 
415 
423 static void
425 {
426  struct ClientQueryRecord *cqr;
427 
428  (void) cls;
429  retry_task = NULL;
430  while (NULL != (cqr = GNUNET_CONTAINER_heap_remove_root (retry_heap)))
431  {
432  cqr->hnode = NULL;
434  {
435  cqr->hnode
437  cqr,
438  cqr->retry_time.abs_value_us);
439  retry_task
442  NULL);
443  return;
444  }
445  transmit_request (cqr);
446  cqr->hnode
448  cqr,
449  cqr->retry_time.abs_value_us);
450  }
451 }
452 
453 
461 static enum GNUNET_GenericReturnValue
462 check_dht_local_put (void *cls,
463  const struct GNUNET_DHT_ClientPutMessage *dht_msg)
464 {
465  uint32_t replication_level = ntohl (dht_msg->desired_replication_level);
466 
467  (void) cls;
469  {
470  GNUNET_break_op (0);
471  return GNUNET_SYSERR;
472  }
473  return GNUNET_OK;
474 }
475 
476 
483 static void
485  const struct GNUNET_DHT_ClientPutMessage *dht_msg)
486 {
487  struct ClientHandle *ch = cls;
488  uint16_t size = ntohs (dht_msg->header.size);
490  = (enum GNUNET_DHT_RouteOption) ntohl (dht_msg->options);
491  uint32_t replication_level
492  = ntohl (dht_msg->desired_replication_level);
493  struct GDS_DATACACHE_BlockData bd = {
494  .key = dht_msg->key,
495  .expiration_time = GNUNET_TIME_absolute_ntoh (dht_msg->expiration),
496  .data = &dht_msg[1],
497  .data_size = size - sizeof (*dht_msg),
498  .type = ntohl (dht_msg->type)
499  };
500 
502  "Handling local PUT of %lu-bytes for query %s of type %u\n",
503  (unsigned long) (size - sizeof(struct GNUNET_DHT_ClientPutMessage)),
504  GNUNET_h2s (&dht_msg->key),
505  (unsigned int) bd.type);
507  "# PUT requests received from clients",
508  1,
509  GNUNET_NO);
511  "CLIENT-PUT %s\n",
512  GNUNET_h2s_full (&dht_msg->key));
513  /* give to local clients */
515  &bd.key,
516  0, NULL /* get path */);
517 
518  {
519  struct GNUNET_CONTAINER_BloomFilter *peer_bf;
520 
521  peer_bf
525  /* store locally */
527  (GDS_am_closest_peer (&dht_msg->key,
528  peer_bf)))
530  /* route to other peers */
531  if (GNUNET_OK !=
533  options,
535  0 /* hop count */,
536  peer_bf))
537  {
539  "# Local PUT requests not routed",
540  1,
541  GNUNET_NO);
542  }
544  }
546  options,
547  &bd,
548  0, /* hop count */
551 }
552 
553 
560 static void
562  const struct GDS_DATACACHE_BlockData *bd)
563 {
564  /* FIXME: use 'cls' instead of looking up the client? */
566  &bd->key,
567  0, NULL /* get_path */);
568 }
569 
570 
578 static enum GNUNET_GenericReturnValue
579 check_dht_local_get (void *cls,
580  const struct GNUNET_DHT_ClientGetMessage *get)
581 {
582  (void) cls;
583  (void) get;
584  /* always well-formed */
585  return GNUNET_OK;
586 }
587 
588 
595 static void
597  const struct GNUNET_DHT_ClientGetMessage *get)
598 {
599  struct ClientHandle *ch = cls;
600  struct ClientQueryRecord *cqr;
601  uint16_t size = ntohs (get->header.size);
602  const char *xquery = (const char *) &get[1];
603  size_t xquery_size = size - sizeof(struct GNUNET_DHT_ClientGetMessage);
604 
606  "Received GET request for %s from local client %p, xq: %.*s\n",
607  GNUNET_h2s (&get->key),
608  ch->client,
609  (int) xquery_size,
610  xquery);
612  "# GET requests received from clients",
613  1,
614  GNUNET_NO);
616  "CLIENT-GET %s\n",
617  GNUNET_h2s_full (&get->key));
618 
619  cqr = GNUNET_malloc (sizeof(struct ClientQueryRecord) + xquery_size);
620  cqr->key = get->key;
621  cqr->ch = ch;
622  cqr->xquery = (const void *) &cqr[1];
623  GNUNET_memcpy (&cqr[1],
624  xquery,
625  xquery_size);
627  cqr,
628  0);
631  cqr->unique_id = get->unique_id;
632  cqr->xquery_size = xquery_size;
633  cqr->replication = ntohl (get->desired_replication_level);
634  cqr->msg_options = (enum GNUNET_DHT_RouteOption) ntohl (get->options);
635  cqr->type = ntohl (get->type);
636  GNUNET_CONTAINER_DLL_insert (ch->cqr_head,
637  ch->cqr_tail,
638  cqr);
640  &cqr->key,
641  cqr,
644  cqr->type,
645  0, /* hop count */
646  cqr->replication,
647  0, /* path length */
648  NULL,
649  &get->key);
650  /* start remote requests */
651  if (NULL != retry_task)
654  NULL);
655  /* perform local lookup */
657  cqr->type,
658  cqr->xquery,
659  xquery_size,
660  NULL,
662  ch);
664 }
665 
666 
671 {
676 
680  uint64_t unique_id;
681 };
682 
683 
694 static enum GNUNET_GenericReturnValue
695 find_by_unique_id (void *cls,
696  const struct GNUNET_HashCode *key,
697  void *value)
698 {
699  struct FindByUniqueIdContext *fui_ctx = cls;
700  struct ClientQueryRecord *cqr = value;
701 
702  if (cqr->unique_id != fui_ctx->unique_id)
703  return GNUNET_YES;
704  fui_ctx->cqr = cqr;
705  return GNUNET_NO;
706 }
707 
708 
716 static enum GNUNET_GenericReturnValue
718  void *cls,
719  const struct GNUNET_DHT_ClientGetResultSeenMessage *seen)
720 {
721  uint16_t size = ntohs (seen->header.size);
722  unsigned int hash_count =
723  (size - sizeof(*seen))
724  / sizeof(struct GNUNET_HashCode);
725 
726  if (size != sizeof(*seen) + hash_count * sizeof(struct GNUNET_HashCode))
727  {
728  GNUNET_break (0);
729  return GNUNET_SYSERR;
730  }
731  return GNUNET_OK;
732 }
733 
734 
741 static void
743  void *cls,
744  const struct GNUNET_DHT_ClientGetResultSeenMessage *seen)
745 {
746  struct ClientHandle *ch = cls;
747  uint16_t size = ntohs (seen->header.size);
748  unsigned int hash_count = (size - sizeof(*seen))
749  / sizeof(struct GNUNET_HashCode);
750  const struct GNUNET_HashCode *hc = (const struct GNUNET_HashCode*) &seen[1];
751  struct FindByUniqueIdContext fui_ctx = {
752  .unique_id = seen->unique_id
753  };
754  unsigned int old_count;
755  struct ClientQueryRecord *cqr;
756 
758  &seen->key,
760  &fui_ctx);
761  if (NULL == (cqr = fui_ctx.cqr))
762  {
763  GNUNET_break (0);
764  GNUNET_SERVICE_client_drop (ch->client);
765  return;
766  }
767  /* finally, update 'seen' list */
768  old_count = cqr->seen_replies_count;
770  cqr->seen_replies_count,
771  cqr->seen_replies_count + hash_count);
772  GNUNET_memcpy (&cqr->seen_replies[old_count],
773  hc,
774  sizeof(struct GNUNET_HashCode) * hash_count);
775 }
776 
777 
782 {
786  struct ClientHandle *ch;
787 
791  uint64_t unique_id;
792 };
793 
794 
804 static enum GNUNET_GenericReturnValue
805 remove_by_unique_id (void *cls,
806  const struct GNUNET_HashCode *key,
807  void *value)
808 {
809  const struct RemoveByUniqueIdContext *ctx = cls;
810  struct ClientQueryRecord *cqr = value;
811 
812  if (cqr->unique_id != ctx->unique_id)
813  return GNUNET_YES;
815  "Removing client %p's record for key %s (by unique id)\n",
816  ctx->ch->client,
817  GNUNET_h2s (key));
819  return GNUNET_YES;
820 }
821 
822 
831 static void
833  void *cls,
834  const struct GNUNET_DHT_ClientGetStopMessage *dht_stop_msg)
835 {
836  struct ClientHandle *ch = cls;
838 
840  "# GET STOP requests received from clients",
841  1,
842  GNUNET_NO);
844  "Received GET STOP request for %s from local client %p\n",
845  GNUNET_h2s (&dht_stop_msg->key),
846  ch->client);
847  ctx.ch = ch;
848  ctx.unique_id = dht_stop_msg->unique_id;
850  &dht_stop_msg->key,
852  &ctx);
854 }
855 
856 
861 {
866 
871 
875  unsigned int get_path_length;
876 
877 };
878 
879 
891 static enum GNUNET_GenericReturnValue
892 forward_reply (void *cls,
893  const struct GNUNET_HashCode *query_hash,
894  void *value)
895 {
896  struct ForwardReplyContext *frc = cls;
897  struct ClientQueryRecord *record = value;
898  struct GNUNET_MQ_Envelope *env;
899  struct GNUNET_DHT_ClientResultMessage *reply;
901  bool do_free;
902  struct GNUNET_HashCode ch;
903  struct GNUNET_DHT_PathElement *paths;
904 
906  "CLIENT-RESULT %s\n",
907  GNUNET_h2s_full (&frc->bd->key));
908  if ( (record->type != GNUNET_BLOCK_TYPE_ANY) &&
909  (record->type != frc->bd->type) )
910  {
912  "Record type mismatch, not passing request for key %s to local client\n",
913  GNUNET_h2s (&frc->bd->key));
915  "# Key match, type mismatches in REPLY to CLIENT",
916  1,
917  GNUNET_NO);
918  return GNUNET_YES; /* type mismatch */
919  }
920  if ( (0 == (record->msg_options & GNUNET_DHT_RO_FIND_PEER)) &&
921  (0 != GNUNET_memcmp (&frc->bd->key,
922  query_hash)) )
923  {
925  "# Inexact key match, but exact match required",
926  1,
927  GNUNET_NO);
928  return GNUNET_YES; /* type mismatch */
929  }
930  GNUNET_CRYPTO_hash (frc->bd->data,
931  frc->bd->data_size,
932  &ch);
933  for (unsigned int i = 0; i < record->seen_replies_count; i++)
934  if (0 ==
935  GNUNET_memcmp (&record->seen_replies[i],
936  &ch))
937  {
939  "Duplicate reply, not passing request for key %s to local client\n",
940  GNUNET_h2s (&frc->bd->key));
942  "# Duplicate REPLIES to CLIENT request dropped",
943  1,
944  GNUNET_NO);
945  return GNUNET_YES; /* duplicate */
946  }
947  eval
949  record->type,
950  NULL,
951  &frc->bd->key,
952  record->xquery,
953  record->xquery_size,
954  frc->bd->data,
955  frc->bd->data_size);
957  "Evaluation result is %d for key %s for local client's query\n",
958  (int) eval,
959  GNUNET_h2s (&frc->bd->key));
960  switch (eval)
961  {
963  do_free = true;
964  break;
967  GNUNET_array_append (record->seen_replies,
968  record->seen_replies_count,
969  ch);
970  do_free = false;
971  break;
973  /* should be impossible to encounter here */
974  GNUNET_break (0);
975  return GNUNET_YES;
977  GNUNET_break_op (0);
978  return GNUNET_NO;
980  return GNUNET_YES;
981  default:
982  GNUNET_break (0);
983  return GNUNET_NO;
984  }
986  "# RESULTS queued for clients",
987  1,
988  GNUNET_NO);
989  env = GNUNET_MQ_msg_extra (reply,
990  frc->bd->data_size
991  + (frc->get_path_length + frc->bd->put_path_length)
992  * sizeof(struct GNUNET_DHT_PathElement),
994  reply->type = htonl (frc->bd->type);
995  reply->get_path_length = htonl (frc->get_path_length);
996  reply->put_path_length = htonl (frc->bd->put_path_length);
997  reply->unique_id = record->unique_id;
999  reply->key = frc->bd->key;
1000  paths = (struct GNUNET_DHT_PathElement *) &reply[1];
1001  GNUNET_memcpy (paths,
1002  frc->bd->put_path,
1003  sizeof(struct GNUNET_DHT_PathElement)
1004  * frc->bd->put_path_length);
1005  GNUNET_memcpy (&paths[frc->bd->put_path_length],
1006  frc->get_path,
1007  sizeof(struct GNUNET_DHT_PathElement) * frc->get_path_length);
1008  GNUNET_memcpy (&paths[frc->get_path_length + frc->bd->put_path_length],
1009  frc->bd->data,
1010  frc->bd->data_size);
1012  "Sending reply to query %s for client %p\n",
1013  GNUNET_h2s (query_hash),
1014  record->ch->client);
1015  GNUNET_MQ_send (record->ch->mq,
1016  env);
1017  if (GNUNET_YES == do_free)
1019  return GNUNET_YES;
1020 }
1021 
1022 
1023 void
1025  const struct GNUNET_HashCode *query_hash,
1026  unsigned int get_path_length,
1027  const struct GNUNET_DHT_PathElement *get_path)
1028 {
1029  struct ForwardReplyContext frc;
1030  size_t msize = sizeof (struct GNUNET_DHT_ClientResultMessage)
1031  + bd->data_size
1033  * sizeof(struct GNUNET_DHT_PathElement);
1034 
1035  if (msize >= GNUNET_MAX_MESSAGE_SIZE)
1036  {
1037  GNUNET_break (0);
1038  return;
1039  }
1040  frc.bd = bd;
1041  frc.get_path = get_path;
1042  frc.get_path_length = get_path_length;
1044  "Forwarding reply for query hash %s to client\n",
1045  GNUNET_h2s (query_hash));
1046  if (0 ==
1048  query_hash,
1049  &forward_reply,
1050  &frc))
1051  {
1053  "No matching client for reply for query %s\n",
1054  GNUNET_h2s (query_hash));
1056  "# REPLIES ignored for CLIENTS (no match)",
1057  1,
1058  GNUNET_NO);
1059  }
1060 }
1061 
1062 
1063 /* ************* logic for monitors ************** */
1064 
1065 
1073 static void
1076 {
1077  struct ClientHandle *ch = cls;
1078  struct ClientMonitorRecord *r;
1079 
1080  r = GNUNET_new (struct ClientMonitorRecord);
1081  r->ch = ch;
1082  r->type = ntohl (msg->type);
1083  r->get = ntohs (msg->get);
1084  r->get_resp = ntohs (msg->get_resp);
1085  r->put = ntohs (msg->put);
1086  if (0 != ntohs (msg->filter_key))
1087  r->key = msg->key;
1089  monitor_tail,
1090  r);
1092 }
1093 
1094 
1101 static void
1103  void *cls,
1105 {
1106  struct ClientHandle *ch = cls;
1107 
1109  for (struct ClientMonitorRecord *r = monitor_head;
1110  NULL != r;
1111  r = r->next)
1112  {
1113  bool keys_match;
1114 
1115  keys_match =
1116  (GNUNET_is_zero (&r->key))
1117  ? (0 == ntohs (msg->filter_key))
1118  : ( (0 != ntohs (msg->filter_key)) &&
1119  (! GNUNET_memcmp (&r->key,
1120  &msg->key)) );
1121  if ( (ch == r->ch) &&
1122  (ntohl (msg->type) == r->type) &&
1123  (r->get == msg->get) &&
1124  (r->get_resp == msg->get_resp) &&
1125  (r->put == msg->put) &&
1126  keys_match)
1127  {
1129  monitor_tail,
1130  r);
1131  GNUNET_free (r);
1132  return; /* Delete only ONE entry */
1133  }
1134  }
1135 }
1136 
1137 
1144 typedef void
1145 (*MonitorAction)(void *cls,
1146  struct ClientMonitorRecord *m);
1147 
1148 
1158 static void
1160  const struct GNUNET_HashCode *key,
1161  MonitorAction cb,
1162  void *cb_cls)
1163 {
1164  struct ClientHandle **cl = NULL;
1165  unsigned int cl_size = 0;
1166 
1167  for (struct ClientMonitorRecord *m = monitor_head;
1168  NULL != m;
1169  m = m->next)
1170  {
1171  if ( ( (GNUNET_BLOCK_TYPE_ANY == m->type) ||
1172  (m->type == type) ) &&
1173  ( (GNUNET_is_zero (&m->key)) ||
1174  (0 ==
1175  GNUNET_memcmp (key,
1176  &m->key)) ) )
1177  {
1178  unsigned int i;
1179 
1180  /* Don't send duplicates */
1181  for (i = 0; i < cl_size; i++)
1182  if (cl[i] == m->ch)
1183  break;
1184  if (i < cl_size)
1185  continue;
1186  GNUNET_array_append (cl,
1187  cl_size,
1188  m->ch);
1189  cb (cb_cls,
1190  m);
1191  }
1192  }
1193  GNUNET_free (cl);
1194 }
1195 
1196 
1201 {
1203  enum GNUNET_BLOCK_Type type;
1204  uint32_t hop_count;
1206  unsigned int get_path_length;
1208  const struct GNUNET_HashCode *key;
1209 };
1210 
1211 
1219 static void
1220 get_action (void *cls,
1221  struct ClientMonitorRecord *m)
1222 {
1223  struct GetActionContext *gac = cls;
1224  struct GNUNET_MQ_Envelope *env;
1225  struct GNUNET_DHT_MonitorGetMessage *mmsg;
1226  struct GNUNET_DHT_PathElement *msg_path;
1227  size_t msize;
1228 
1229  msize = gac->get_path_length * sizeof(struct GNUNET_DHT_PathElement);
1230  env = GNUNET_MQ_msg_extra (mmsg,
1231  msize,
1233  mmsg->options = htonl (gac->options);
1234  mmsg->type = htonl (gac->type);
1235  mmsg->hop_count = htonl (gac->hop_count);
1237  mmsg->get_path_length = htonl (gac->get_path_length);
1238  mmsg->key = *gac->key;
1239  msg_path = (struct GNUNET_DHT_PathElement *) &mmsg[1];
1240  GNUNET_memcpy (msg_path,
1241  gac->get_path,
1242  gac->get_path_length * sizeof(struct GNUNET_DHT_PathElement));
1243  GNUNET_MQ_send (m->ch->mq,
1244  env);
1245 }
1246 
1247 
1260 void
1262  enum GNUNET_BLOCK_Type type,
1263  uint32_t hop_count,
1264  uint32_t desired_replication_level,
1265  unsigned int path_length,
1266  const struct GNUNET_DHT_PathElement *path,
1267  const struct GNUNET_HashCode *key)
1268 {
1269  struct GetActionContext gac = {
1270  .options = options,
1271  .type = type,
1272  .hop_count = hop_count,
1273  .desired_replication_level = desired_replication_level,
1274  .get_path_length = path_length,
1275  .get_path = path,
1276  .key = key
1277  };
1278 
1280  key,
1281  &get_action,
1282  &gac);
1283 }
1284 
1285 
1290 {
1293  unsigned int get_path_length;
1294 };
1295 
1296 
1304 static void
1305 response_action (void *cls,
1306  struct ClientMonitorRecord *m)
1307 {
1308  const struct ResponseActionContext *resp_ctx = cls;
1309  const struct GDS_DATACACHE_BlockData *bd = resp_ctx->bd;
1310 
1311  struct GNUNET_MQ_Envelope *env;
1312  struct GNUNET_DHT_MonitorGetRespMessage *mmsg;
1313  struct GNUNET_DHT_PathElement *path;
1314  size_t msize;
1315 
1316  msize = bd->data_size;
1317  msize += (resp_ctx->get_path_length + bd->put_path_length)
1318  * sizeof(struct GNUNET_DHT_PathElement);
1319  env = GNUNET_MQ_msg_extra (mmsg,
1320  msize,
1322  mmsg->type = htonl (bd->type);
1323  mmsg->put_path_length = htonl (bd->put_path_length);
1324  mmsg->get_path_length = htonl (resp_ctx->get_path_length);
1326  mmsg->key = bd->key;
1327  path = (struct GNUNET_DHT_PathElement *) &mmsg[1];
1328  GNUNET_memcpy (path,
1329  bd->put_path,
1330  bd->put_path_length * sizeof(struct GNUNET_DHT_PathElement));
1331  GNUNET_memcpy (path,
1332  resp_ctx->get_path,
1333  resp_ctx->get_path_length * sizeof(struct
1335  GNUNET_memcpy (&path[resp_ctx->get_path_length],
1336  bd->data,
1337  bd->data_size);
1338  GNUNET_MQ_send (m->ch->mq,
1339  env);
1340 }
1341 
1342 
1343 void
1345  const struct GNUNET_DHT_PathElement *get_path,
1346  unsigned int get_path_length)
1347 {
1348  struct ResponseActionContext rac = {
1349  .bd = bd,
1350  .get_path = get_path,
1351  .get_path_length = get_path_length
1352  };
1353 
1355  &bd->key,
1356  &response_action,
1357  &rac);
1358 }
1359 
1360 
1365 {
1368  uint32_t hop_count;
1370 };
1371 
1372 
1380 static void
1381 put_action (void *cls,
1382  struct ClientMonitorRecord *m)
1383 {
1384  const struct PutActionContext *put_ctx = cls;
1385  const struct GDS_DATACACHE_BlockData *bd = put_ctx->bd;
1386  struct GNUNET_MQ_Envelope *env;
1387  struct GNUNET_DHT_MonitorPutMessage *mmsg;
1388  struct GNUNET_DHT_PathElement *msg_path;
1389  size_t msize;
1390 
1391  msize = bd->data_size
1392  + bd->put_path_length
1393  * sizeof(struct GNUNET_DHT_PathElement);
1394  env = GNUNET_MQ_msg_extra (mmsg,
1395  msize,
1397  mmsg->options = htonl (put_ctx->options);
1398  mmsg->type = htonl (bd->type);
1399  mmsg->hop_count = htonl (put_ctx->hop_count);
1400  mmsg->desired_replication_level = htonl (put_ctx->desired_replication_level);
1401  mmsg->put_path_length = htonl (bd->put_path_length);
1402  mmsg->key = bd->key;
1404  msg_path = (struct GNUNET_DHT_PathElement *) &mmsg[1];
1405  GNUNET_memcpy (msg_path,
1406  bd->put_path,
1407  bd->put_path_length * sizeof(struct GNUNET_DHT_PathElement));
1408  GNUNET_memcpy (&msg_path[bd->put_path_length],
1409  bd->data,
1410  bd->data_size);
1411  GNUNET_MQ_send (m->ch->mq,
1412  env);
1413 }
1414 
1415 
1416 void
1418  const struct GDS_DATACACHE_BlockData *bd,
1419  uint32_t hop_count,
1420  uint32_t desired_replication_level)
1421 {
1422  struct PutActionContext put_ctx = {
1423  .bd = bd,
1424  .hop_count = hop_count,
1425  .desired_replication_level = desired_replication_level,
1426  .options = options
1427  };
1428 
1430  &bd->key,
1431  &put_action,
1432  &put_ctx);
1433 }
1434 
1435 
1436 /* ********************** Initialization logic ***************** */
1437 
1438 
1444 static void
1446 {
1447  forward_map
1449  GNUNET_YES);
1450  retry_heap
1452 }
1453 
1454 
1458 static void
1460 {
1461  if (NULL != retry_task)
1462  {
1464  retry_task = NULL;
1465  }
1466 }
1467 
1468 
1475 #define GDS_DHT_SERVICE_INIT(name, run) \
1476  GNUNET_SERVICE_MAIN \
1477  (name, \
1478  GNUNET_SERVICE_OPTION_NONE, \
1479  run, \
1480  &client_connect_cb, \
1481  &client_disconnect_cb, \
1482  NULL, \
1483  GNUNET_MQ_hd_var_size (dht_local_put, \
1484  GNUNET_MESSAGE_TYPE_DHT_CLIENT_PUT, \
1485  struct GNUNET_DHT_ClientPutMessage, \
1486  NULL), \
1487  GNUNET_MQ_hd_var_size (dht_local_get, \
1488  GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET, \
1489  struct GNUNET_DHT_ClientGetMessage, \
1490  NULL), \
1491  GNUNET_MQ_hd_fixed_size (dht_local_get_stop, \
1492  GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_STOP, \
1493  struct GNUNET_DHT_ClientGetStopMessage, \
1494  NULL), \
1495  GNUNET_MQ_hd_fixed_size (dht_local_monitor, \
1496  GNUNET_MESSAGE_TYPE_DHT_MONITOR_START, \
1497  struct GNUNET_DHT_MonitorStartStopMessage, \
1498  NULL), \
1499  GNUNET_MQ_hd_fixed_size (dht_local_monitor_stop, \
1500  GNUNET_MESSAGE_TYPE_DHT_MONITOR_STOP, \
1501  struct GNUNET_DHT_MonitorStartStopMessage, \
1502  NULL), \
1503  GNUNET_MQ_hd_var_size (dht_local_get_result_seen, \
1504  GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_RESULTS_KNOWN, \
1505  struct GNUNET_DHT_ClientGetResultSeenMessage, \
1506  NULL), \
1507  GNUNET_MQ_handler_end ())
1508 
1509 
1513 void __attribute__ ((destructor))
1514 GDS_CLIENTS_done ()
1515 {
1516  if (NULL != retry_heap)
1517  {
1520  retry_heap = NULL;
1521  }
1522  if (NULL != forward_map)
1523  {
1526  forward_map = NULL;
1527  }
1528 }
1529 
1530 
1531 /* end of gnunet-service-dht_clients.c */
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
#define DHT_BLOOM_SIZE
Size of the bloom filter the DHT uses to filter peers.
Definition: dht.h:34
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 int monitor
Monitor ARM activity.
Definition: gnunet-arm.c:64
static unsigned int replication_level
Replication level option to use for publishing.
static struct GNUNET_CADET_Channel * ch
Channel handle.
Definition: gnunet-cadet.c:117
static void record(void *cls, size_t data_size, const void *data)
Process recorded audio data.
struct GNUNET_HashCode key
The key used in the DHT.
static int get
Get DID Documement for DID Flag.
Definition: gnunet-did.c:64
static char * value
Value of the record to add/remove.
GNUnet DHT globals.
static void transmit_request(struct ClientQueryRecord *cqr)
Route the given request via the DHT.
static void handle_dht_local_get_stop(void *cls, const struct GNUNET_DHT_ClientGetStopMessage *dht_stop_msg)
Handler for any generic DHT stop messages, calls the appropriate handler depending on message type (i...
static void handle_local_result(void *cls, const struct GDS_DATACACHE_BlockData *bd)
Handle a result from local datacache for a GET operation.
static struct ClientMonitorRecord * monitor_head
List of active monitoring requests.
static enum GNUNET_GenericReturnValue forward_reply(void *cls, const struct GNUNET_HashCode *query_hash, void *value)
Iterator over hash map entries that send a given reply to each of the matching clients.
void GDS_CLIENTS_process_get(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_DHT_PathElement *path, const struct GNUNET_HashCode *key)
Check if some client is monitoring GET messages and notify them in that case.
static void handle_dht_local_get(void *cls, const struct GNUNET_DHT_ClientGetMessage *get)
Handler for DHT GET messages from the client.
static enum GNUNET_GenericReturnValue find_by_unique_id(void *cls, const struct GNUNET_HashCode *key, void *value)
Function called for each existing DHT record for the given query.
static enum GNUNET_GenericReturnValue remove_by_unique_id(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator over hash map entries that frees all entries that match the given client and unique ID.
static void response_action(void *cls, struct ClientMonitorRecord *m)
Function called on monitors that match a response.
void GDS_CLIENTS_handle_reply(const struct GDS_DATACACHE_BlockData *bd, const struct GNUNET_HashCode *query_hash, unsigned int get_path_length, const struct GNUNET_DHT_PathElement *get_path)
Handle a reply we've received from another peer.
static struct GNUNET_CONTAINER_Heap * retry_heap
Heap with all of our client's request, sorted by retry time (earliest on top).
struct GNUNET_STATISTICS_Handle * GDS_stats
Handle for the statistics service.
static struct GNUNET_SCHEDULER_Task * retry_task
Task that re-transmits requests (using retry_heap).
void GDS_CLIENTS_process_put(enum GNUNET_DHT_RouteOption options, const struct GDS_DATACACHE_BlockData *bd, uint32_t hop_count, uint32_t desired_replication_level)
Check if some client is monitoring PUT messages and notify them in that case.
static void handle_dht_local_monitor_stop(void *cls, const struct GNUNET_DHT_MonitorStartStopMessage *msg)
Handler for monitor stop messages.
static void handle_dht_local_get_result_seen(void *cls, const struct GNUNET_DHT_ClientGetResultSeenMessage *seen)
Handler for "GET result seen" messages from the client.
static struct GNUNET_CONTAINER_MultiHashMap * forward_map
Hashmap for fast key based lookup, maps keys to struct ClientQueryRecord entries.
static void handle_dht_local_monitor(void *cls, const struct GNUNET_DHT_MonitorStartStopMessage *msg)
Handler for monitor start messages.
struct GNUNET_BLOCK_Context * GDS_block_context
Our handle to the BLOCK library.
struct GNUNET_SERVICE_Handle * GDS_service
Handle for the service.
static void GDS_CLIENTS_init(void)
Initialize client subsystem.
static enum GNUNET_GenericReturnValue check_dht_local_put(void *cls, const struct GNUNET_DHT_ClientPutMessage *dht_msg)
Check DHT PUT messages from the client.
static void for_matching_monitors(enum GNUNET_BLOCK_Type type, const struct GNUNET_HashCode *key, MonitorAction cb, void *cb_cls)
Call cb on all monitors that watch for blocks of type and key key.
static void handle_dht_local_put(void *cls, const struct GNUNET_DHT_ClientPutMessage *dht_msg)
Handler for PUT messages.
static struct ClientMonitorRecord * monitor_tail
List of active monitoring requests.
static void GDS_CLIENTS_stop(void)
Shutdown client subsystem.
void GDS_CLIENTS_process_get_resp(const struct GDS_DATACACHE_BlockData *bd, const struct GNUNET_DHT_PathElement *get_path, unsigned int get_path_length)
Check if some client is monitoring GET RESP messages and notify them in that case.
static void * client_connect_cb(void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq)
Functions with this signature are called whenever a local client is connects to us.
#define LOG(kind,...)
static enum GNUNET_GenericReturnValue check_dht_local_get(void *cls, const struct GNUNET_DHT_ClientGetMessage *get)
Check DHT GET messages from the client.
#define LOG_TRAFFIC(kind,...)
Should routing details be logged to stderr (for debugging)?
void __attribute__((destructor))
MINIMIZE heap size (way below 128k) since this process doesn't need much.
static enum GNUNET_GenericReturnValue check_dht_local_get_result_seen(void *cls, const struct GNUNET_DHT_ClientGetResultSeenMessage *seen)
Check "GET result seen" messages from the client.
static void transmit_next_request_task(void *cls)
Task that looks at the retry_heap and transmits all of the requests on the heap that are ready for tr...
static void client_disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *client, void *app_ctx)
Functions with this signature are called whenever a client is disconnected on the network level.
static void put_action(void *cls, struct ClientMonitorRecord *m)
Function called on monitors that match a PUT.
static void remove_client_query_record(struct ClientQueryRecord *record)
Free data structures associated with the given query.
static void get_action(void *cls, struct ClientMonitorRecord *m)
Function called on monitors that match a GET.
const struct GNUNET_CONFIGURATION_Handle * GDS_cfg
The configuration the DHT service is running with.
void(* MonitorAction)(void *cls, struct ClientMonitorRecord *m)
Function to call by for_matching_monitors().
enum GNUNET_BLOCK_EvaluationResult GDS_DATACACHE_handle_get(const struct GNUNET_HashCode *key, enum GNUNET_BLOCK_Type type, const void *xquery, size_t xquery_size, struct GNUNET_BLOCK_Group *bg, GDS_DATACACHE_GetCallback gc, void *gc_cls)
Handle a GET request we've received from another peer.
void GDS_DATACACHE_handle_put(const struct GDS_DATACACHE_BlockData *bd)
Handle a datum we've received from another peer.
GNUnet DHT service's datacache integration.
enum GNUNET_GenericReturnValue GDS_NEIGHBOURS_handle_get(enum GNUNET_BLOCK_Type type, enum GNUNET_DHT_RouteOption options, uint32_t desired_replication_level, uint32_t hop_count, const struct GNUNET_HashCode *key, const void *xquery, size_t xquery_size, struct GNUNET_BLOCK_Group *bg, struct GNUNET_CONTAINER_BloomFilter *peer_bf)
Perform a GET operation.
enum GNUNET_GenericReturnValue GDS_NEIGHBOURS_handle_put(const struct GDS_DATACACHE_BlockData *bd, enum GNUNET_DHT_RouteOption options, uint32_t desired_replication_level, uint32_t hop_count, struct GNUNET_CONTAINER_BloomFilter *bf)
Perform a PUT operation.
enum GNUNET_GenericReturnValue GDS_am_closest_peer(const struct GNUNET_HashCode *key, const struct GNUNET_CONTAINER_BloomFilter *bloom)
Check whether my identity is closer than any known peers.
GNUnet DHT routing code.
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
#define GNUNET_is_zero(a)
Check that memory in a is all zeros.
#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:92
@ 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,...
enum GNUNET_GenericReturnValue GNUNET_BLOCK_group_set_seen(struct GNUNET_BLOCK_Group *bg, const struct GNUNET_HashCode *seen_results, unsigned int seen_results_count)
Update block group to filter out the given results.
Definition: block.c:374
enum GNUNET_BLOCK_ReplyEvaluationResult GNUNET_BLOCK_check_reply(struct GNUNET_BLOCK_Context *ctx, enum GNUNET_BLOCK_Type type, struct GNUNET_BLOCK_Group *group, const struct GNUNET_HashCode *query, const void *xquery, size_t xquery_size, const void *reply_block, size_t reply_block_size)
Function called to validate a reply.
Definition: block.c:348
GNUNET_BLOCK_ReplyEvaluationResult
Possible ways for how a block may relate to a query.
void GNUNET_BLOCK_group_destroy(struct GNUNET_BLOCK_Group *bg)
Destroy resources used by a block group.
Definition: block.c:173
struct GNUNET_BLOCK_Group * GNUNET_BLOCK_group_create(struct GNUNET_BLOCK_Context *ctx, enum GNUNET_BLOCK_Type type, uint32_t nonce, const void *raw_data, size_t raw_data_size,...)
Create a new block group.
Definition: block.c:228
GNUNET_BLOCK_Type
Blocks in the datastore and the datacache must have a unique type.
@ GNUNET_BLOCK_REPLY_OK_MORE
Valid result, and there may be more.
@ GNUNET_BLOCK_REPLY_OK_DUPLICATE
Valid result, but suppressed because it is a duplicate.
@ GNUNET_BLOCK_REPLY_OK_LAST
Last possible valid result.
@ GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED
Specified block type not supported by any plugin.
@ GNUNET_BLOCK_REPLY_INVALID
Block does not match query (invalid result)
@ GNUNET_BLOCK_REPLY_IRRELEVANT
Block does not match xquery (valid result, not relevant for the request)
@ GNUNET_BLOCK_TYPE_ANY
Any type of block, used as a wildcard when searching.
struct GNUNET_CONTAINER_BloomFilter * GNUNET_CONTAINER_bloomfilter_init(const char *data, size_t size, unsigned int k)
Create a Bloom filter from raw bits.
void GNUNET_CONTAINER_bloomfilter_free(struct GNUNET_CONTAINER_BloomFilter *bf)
Free the space associated with a filter in memory, flush to drive if needed (do not free the space on...
#define GNUNET_CONSTANTS_BLOOMFILTER_K
K-value that must be used for the bloom filters in 'GET' queries.
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
GNUNET_DHT_RouteOption
Options for routing.
#define GNUNET_DHT_MAXIMUM_REPLICATION_LEVEL
Maximum allowed replication level for all requests.
@ GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE
Each peer along the way should process the request (otherwise only peers locally closest to the key w...
@ GNUNET_DHT_RO_FIND_PEER
This is a 'FIND-PEER' request, so approximate results are fine.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
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.
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.
void * GNUNET_CONTAINER_heap_remove_root(struct GNUNET_CONTAINER_Heap *heap)
Remove root of the heap.
void * GNUNET_CONTAINER_heap_remove_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from the heap.
struct GNUNET_CONTAINER_HeapNode * GNUNET_CONTAINER_heap_insert(struct GNUNET_CONTAINER_Heap *heap, void *element, GNUNET_CONTAINER_HeapCostType cost)
Inserts a new element into the heap.
unsigned int GNUNET_CONTAINER_heap_get_size(const struct GNUNET_CONTAINER_Heap *heap)
Get the current size of the heap.
struct GNUNET_CONTAINER_Heap * GNUNET_CONTAINER_heap_create(enum GNUNET_CONTAINER_HeapOrder order)
Create a new heap.
void GNUNET_CONTAINER_heap_destroy(struct GNUNET_CONTAINER_Heap *heap)
Destroys the heap.
@ GNUNET_CONTAINER_HEAP_ORDER_MIN
Heap with the minimum cost at the root.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
const char * GNUNET_h2s_full(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#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_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_array_append(arr, len, element)
Append an element to an array (growing the array by one).
#define GNUNET_free(ptr)
Wrapper around free.
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_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_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_MONITOR_PUT
Receive information about transiting PUTs.
#define GNUNET_MESSAGE_TYPE_DHT_CLIENT_RESULT
Service returns result to client.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1296
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_at(struct GNUNET_TIME_Absolute at, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run at the specified time.
Definition: scheduler.c:1246
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2329
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2248
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
#define GNUNET_TIME_UNIT_SECONDS
One second.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:94
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:699
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:299
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:607
bool GNUNET_TIME_absolute_is_past(struct GNUNET_TIME_Absolute abs)
Test if abs is truly in the past (excluding now).
Definition: time.c:638
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
static unsigned int size
Size of the "table".
Definition: peer.c:67
Struct containing information about a client, handle to connect to it, and any pending messages that ...
struct ClientQueryRecord * cqr_tail
Linked list of active queries of this client.
struct GNUNET_SERVICE_Client * client
The handle to this client.
struct GNUNET_MQ_Handle * mq
The message queue to this client.
struct ClientQueryRecord * cqr_head
Linked list of active queries of this client.
Struct containing parameters of monitoring requests.
struct ClientMonitorRecord * next
Next element in DLL.
uint16_t put
Flag whether to notify about PUT messages.
struct ClientMonitorRecord * prev
Previous element in DLL.
struct ClientHandle * ch
Client to notify of these requests.
enum GNUNET_BLOCK_Type type
Type of blocks that are of interest.
int16_t get
Flag whether to notify about GET messages.
struct GNUNET_HashCode key
Key of data of interest.
int16_t get_resp
Flag whether to notify about GET_REPONSE messages.
Entry in the local forwarding map for a client's GET request.
unsigned int seen_replies_count
Number of entries in seen_replies.
size_t xquery_size
Number of bytes in xquery.
struct GNUNET_TIME_Relative retry_frequency
What's the delay between re-try operations that we currently use for this request?
struct ClientQueryRecord * prev
Kept in a DLL with client.
struct GNUNET_CONTAINER_HeapNode * hnode
Pointer to this nodes heap location in the retry-heap (for fast removal)
struct ClientHandle * ch
Client responsible for the request.
struct GNUNET_HashCode * seen_replies
Array of (hashes of) replies we have already seen for this request.
uint64_t unique_id
The unique identifier of this request.
enum GNUNET_DHT_RouteOption msg_options
Any message options for this request.
struct GNUNET_HashCode key
The key this request was about.
enum GNUNET_BLOCK_Type type
The type for the data for the GET request.
const void * xquery
Extended query (see gnunet_block_lib.h), allocated at the end of this struct.
struct GNUNET_TIME_Absolute retry_time
What's the next time we should re-try this request?
struct ClientQueryRecord * next
Kept in a DLL with client.
uint32_t replication
Desired replication level.
Closure for find_by_unique_id().
uint64_t unique_id
Unique ID to look for.
struct ClientQueryRecord * cqr
Where to store the result, if found.
Closure for forward_reply()
const struct GNUNET_DHT_PathElement * get_path
GET path taken.
const struct GDS_DATACACHE_BlockData * bd
Block details.
unsigned int get_path_length
Number of entries in get_path.
Information about a block stored in the datacache.
const void * data
Actual block data.
size_t data_size
Number of bytes in data.
const struct GNUNET_DHT_PathElement * put_path
PUT path taken by the block, array of peer identities.
enum GNUNET_BLOCK_Type type
Type of the block.
struct GNUNET_TIME_Absolute expiration_time
When does the block expire?
unsigned int put_path_length
Length of the put_path array.
struct GNUNET_HashCode key
Key of the block.
struct GNUNET_MQ_Handle * mq
Our control connection to the ARM service.
Handle to an initialized block library.
Definition: block.c:55
Block group data.
struct GNUNET_MQ_Handle * mq
Message Queue for the channel (which we are implementing).
Definition: cadet.h:143
Handle to a node in a heap.
Internal representation of the hash map.
DHT GET message sent from clients to service.
Definition: dht.h:72
DHT GET RESULTS KNOWN message sent from clients to service.
Definition: dht.h:114
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_RESULTS_KNOWN.
Definition: dht.h:118
struct GNUNET_HashCode key
The key we are searching for (to make it easy to find the corresponding GET inside the service).
Definition: dht.h:129
uint64_t unique_id
Unique ID identifying this request.
Definition: dht.h:134
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
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
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_DHT_CLIENT_PUT.
Definition: dht.h:194
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_HashCode key
The key that was searched for.
Definition: dht.h:180
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
Message to monitor get requests going through peer, DHT service -> clients.
Definition: dht.h:324
uint32_t hop_count
Hop count.
Definition: dht.h:343
uint32_t options
Message options, actually an 'enum GNUNET_DHT_RouteOption' value.
Definition: dht.h:333
uint32_t desired_replication_level
Replication level for this message.
Definition: dht.h:348
struct GNUNET_HashCode key
The key to store the value under.
Definition: dht.h:359
uint32_t type
The type of data in the request.
Definition: dht.h:338
uint32_t get_path_length
Number of peers recorded in the outgoing path from source to the storage location of this message.
Definition: dht.h:354
Message to monitor get results going through peer, DHT service -> clients.
Definition: dht.h:368
struct GNUNET_HashCode key
The key of the corresponding GET request.
Definition: dht.h:397
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the content expire?
Definition: dht.h:392
uint32_t type
Content type.
Definition: dht.h:377
uint32_t get_path_length
Length of the GET path that follows (if tracked).
Definition: dht.h:387
uint32_t put_path_length
Length of the PUT path that follows (if tracked).
Definition: dht.h:382
Message to monitor put requests going through peer, DHT service -> clients.
Definition: dht.h:229
uint32_t options
Message options, actually an 'enum GNUNET_DHT_RouteOption' value.
Definition: dht.h:238
struct GNUNET_TIME_AbsoluteNBO expiration_time
How long should this data persist?
Definition: dht.h:264
uint32_t desired_replication_level
Replication level for this message.
Definition: dht.h:253
struct GNUNET_HashCode key
The key to store the value under.
Definition: dht.h:269
uint32_t hop_count
Hop count so far.
Definition: dht.h:248
uint32_t type
The type of data in the request.
Definition: dht.h:243
uint32_t put_path_length
Number of peers recorded in the outgoing path from source to the storage location of this message.
Definition: dht.h:259
Message to request monitoring messages, clients -> DHT service.
Definition: dht.h:281
A (signed) path tracking a block's flow through the DHT is represented by an array of path elements,...
A 512-bit hashcode.
Handle to a message queue.
Definition: mq.c:86
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.
Entry in list of pending tasks.
Definition: scheduler.c:135
Handle to a client that is connected to a service.
Definition: service.c:251
Handle to a service.
Definition: service.c:117
Handle for the service.
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.
Time for relative time used by GNUnet, in microseconds.
Closure for get_action();.
const struct GNUNET_HashCode * key
enum GNUNET_DHT_RouteOption options
const struct GNUNET_DHT_PathElement * get_path
enum GNUNET_BLOCK_Type type
Closure for put_action().
enum GNUNET_DHT_RouteOption options
const struct GDS_DATACACHE_BlockData * bd
Closure for remove_by_unique_id().
struct ClientHandle * ch
Client that issued the removal request.
uint64_t unique_id
Unique ID of the request.
Closure for response_action().
const struct GDS_DATACACHE_BlockData * bd
const struct GNUNET_DHT_PathElement * get_path
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model