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 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 {
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 
129  uint32_t msg_options;
130 
135 };
136 
137 
142 {
147 
152 
157 
162 
166  int16_t get;
167 
171  int16_t get_resp;
172 
176  uint16_t put;
177 
181  struct ClientHandle *ch;
182 };
183 
184 
191 {
196 
201 
206 
211 };
212 
217 
222 
227 
232 
237 
242 
247 
252 
257 
258 
264 static void
266 {
267  struct ClientHandle *ch = record->ch;
268 
270  ch->cqr_tail,
271  record);
274  &record->key,
275  record));
276  if (NULL != record->hnode)
279  record->seen_replies_count,
280  0);
281  GNUNET_free (record);
282 }
283 
284 
294 static void *
295 client_connect_cb (void *cls,
297  struct GNUNET_MQ_Handle *mq)
298 {
299  struct ClientHandle *ch;
300 
301  ch = GNUNET_new (struct ClientHandle);
302  ch->client = client;
303  ch->mq = mq;
304  return ch;
305 }
306 
307 
316 static void
319  void *app_ctx)
320 {
321  struct ClientHandle *ch = app_ctx;
322  struct ClientQueryRecord *cqr;
324 
326  "Local client %p disconnects\n",
327  ch);
328  monitor = monitor_head;
329  while (NULL != monitor)
330  {
331  if (monitor->ch == ch)
332  {
333  struct ClientMonitorRecord *next;
334 
335  next = monitor->next;
336  GNUNET_free_non_null (monitor->key);
337  GNUNET_CONTAINER_DLL_remove (monitor_head,
338  monitor_tail,
339  monitor);
340  GNUNET_free (monitor);
341  monitor = next;
342  }
343  else
344  {
345  monitor = monitor->next;
346  }
347  }
348  while (NULL != (cqr = ch->cqr_head))
349  remove_client_record (cqr);
350  GNUNET_free (ch);
351 }
352 
353 
359 static void
361 {
362  struct GNUNET_BLOCK_Group *bg;
363  struct GNUNET_CONTAINER_BloomFilter *peer_bf;
364 
365  GNUNET_STATISTICS_update (GDS_stats,
366  gettext_noop (
367  "# GET requests from clients injected"),
368  1,
369  GNUNET_NO);
370  bg = GNUNET_BLOCK_group_create (GDS_block_context,
371  cqr->type,
374  UINT32_MAX),
375  NULL,
376  0,
377  "seen-set-size",
378  cqr->seen_replies_count,
379  NULL);
381  cqr->seen_replies,
382  cqr->seen_replies_count);
383  peer_bf
388  "Initiating GET for %s, replication %u, already have %u replies\n",
389  GNUNET_h2s (&cqr->key),
390  cqr->replication,
391  cqr->seen_replies_count);
393  cqr->msg_options,
394  cqr->replication,
395  0 /* hop count */,
396  &cqr->key,
397  cqr->xquery,
398  cqr->xquery_size,
399  bg,
400  peer_bf);
403 
404  /* exponential back-off for retries.
405  * max GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD (15 min) */
408 }
409 
410 
418 static void
420 {
421  struct ClientQueryRecord *cqr;
422  struct GNUNET_TIME_Relative delay;
423 
424  retry_task = NULL;
425  while (NULL != (cqr = GNUNET_CONTAINER_heap_remove_root (retry_heap)))
426  {
427  cqr->hnode = NULL;
429  if (delay.rel_value_us > 0)
430  {
431  cqr->hnode
432  = GNUNET_CONTAINER_heap_insert (retry_heap,
433  cqr,
434  cqr->retry_time.abs_value_us);
435  retry_task
438  NULL);
439  return;
440  }
441  transmit_request (cqr);
442  cqr->hnode
443  = GNUNET_CONTAINER_heap_insert (retry_heap,
444  cqr,
445  cqr->retry_time.abs_value_us);
446  }
447 }
448 
449 
457 static int
459  const struct GNUNET_DHT_ClientPutMessage *dht_msg)
460 {
461  /* always well-formed */
462  return GNUNET_OK;
463 }
464 
465 
472 static void
474  const struct GNUNET_DHT_ClientPutMessage *dht_msg)
475 {
476  struct ClientHandle *ch = cls;
477  struct GNUNET_CONTAINER_BloomFilter *peer_bf;
478  uint16_t size;
479 
480  size = ntohs (dht_msg->header.size);
481  GNUNET_STATISTICS_update (GDS_stats,
482  gettext_noop (
483  "# PUT requests received from clients"),
484  1,
485  GNUNET_NO);
487  "CLIENT-PUT %s\n",
488  GNUNET_h2s_full (&dht_msg->key));
489  /* give to local clients */
491  "Handling local PUT of %u-bytes for query %s\n",
492  size - sizeof(struct GNUNET_DHT_ClientPutMessage),
493  GNUNET_h2s (&dht_msg->key));
495  &dht_msg->key,
496  0,
497  NULL,
498  0,
499  NULL,
500  ntohl (dht_msg->type),
501  size - sizeof(struct GNUNET_DHT_ClientPutMessage),
502  &dht_msg[1]);
503  /* store locally */
505  &dht_msg->key,
506  0,
507  NULL,
508  ntohl (dht_msg->type),
509  size - sizeof(struct GNUNET_DHT_ClientPutMessage),
510  &dht_msg[1]);
511  /* route to other peers */
512  peer_bf
516  GDS_NEIGHBOURS_handle_put (ntohl (dht_msg->type),
517  ntohl (dht_msg->options),
518  ntohl (dht_msg->desired_replication_level),
520  0 /* hop count */,
521  peer_bf,
522  &dht_msg->key,
523  0,
524  NULL,
525  &dht_msg[1],
526  size - sizeof(struct GNUNET_DHT_ClientPutMessage));
527  GDS_CLIENTS_process_put (ntohl (dht_msg->options),
528  ntohl (dht_msg->type),
529  0,
530  ntohl (dht_msg->desired_replication_level),
531  1,
534  &dht_msg->key,
535  &dht_msg[1],
536  size - sizeof(struct GNUNET_DHT_ClientPutMessage));
539 }
540 
541 
549 static int
551  const struct GNUNET_DHT_ClientGetMessage *get)
552 {
553  /* always well-formed */
554  return GNUNET_OK;
555 }
556 
557 
572 static void
574  enum GNUNET_BLOCK_Type type,
575  struct GNUNET_TIME_Absolute expiration_time,
576  const struct GNUNET_HashCode *key,
577  unsigned int put_path_length,
578  const struct GNUNET_PeerIdentity *put_path,
579  unsigned int get_path_length,
580  const struct GNUNET_PeerIdentity *get_path,
581  const void *data,
582  size_t data_size)
583 {
584  // FIXME: this needs some clean up: inline the function,
585  // possibly avoid even looking up the client!
586  GDS_CLIENTS_handle_reply (expiration_time,
587  key,
588  0, NULL,
589  put_path_length, put_path,
590  type,
591  data_size, data);
592 }
593 
594 
601 static void
603  const struct GNUNET_DHT_ClientGetMessage *get)
604 {
605  struct ClientHandle *ch = cls;
606  struct ClientQueryRecord *cqr;
607  size_t xquery_size;
608  const char *xquery;
609  uint16_t size;
610 
611  size = ntohs (get->header.size);
612  xquery_size = size - sizeof(struct GNUNET_DHT_ClientGetMessage);
613  xquery = (const char *) &get[1];
614  GNUNET_STATISTICS_update (GDS_stats,
616  ("# GET requests received from clients"), 1,
617  GNUNET_NO);
619  "Received GET request for %s from local client %p, xq: %.*s\n",
620  GNUNET_h2s (&get->key),
621  ch->client,
622  xquery_size,
623  xquery);
625  "CLIENT-GET %s\n",
626  GNUNET_h2s_full (&get->key));
627 
628  cqr = GNUNET_malloc (sizeof(struct ClientQueryRecord) + xquery_size);
629  cqr->key = get->key;
630  cqr->ch = ch;
631  cqr->xquery = (void *) &cqr[1];
632  GNUNET_memcpy (&cqr[1], xquery, xquery_size);
633  cqr->hnode = GNUNET_CONTAINER_heap_insert (retry_heap, cqr, 0);
636  cqr->unique_id = get->unique_id;
637  cqr->xquery_size = xquery_size;
638  cqr->replication = ntohl (get->desired_replication_level);
639  cqr->msg_options = ntohl (get->options);
640  cqr->type = ntohl (get->type);
642  ch->cqr_tail,
643  cqr);
645  &cqr->key,
646  cqr,
648  GDS_CLIENTS_process_get (ntohl (get->options),
649  ntohl (get->type),
650  0,
651  ntohl (get->desired_replication_level),
652  1,
654  &get->key);
655  /* start remote requests */
656  if (NULL != retry_task)
657  GNUNET_SCHEDULER_cancel (retry_task);
659  NULL);
660  /* perform local lookup */
661  GDS_DATACACHE_handle_get (&get->key,
662  cqr->type,
663  cqr->xquery,
664  xquery_size,
665  NULL,
667  ch);
669 }
670 
671 
676 {
681 
682  uint64_t unique_id;
683 };
684 
685 
696 static int
697 find_by_unique_id (void *cls,
698  const struct GNUNET_HashCode *key,
699  void *value)
700 {
701  struct FindByUniqueIdContext *fui_ctx = cls;
702  struct ClientQueryRecord *cqr = value;
703 
704  if (cqr->unique_id != fui_ctx->unique_id)
705  return GNUNET_YES;
706  fui_ctx->cqr = cqr;
707  return GNUNET_NO;
708 }
709 
710 
718 static int
720  const struct
722 {
723  uint16_t size;
724  unsigned int hash_count;
725 
726  size = ntohs (seen->header.size);
727  hash_count = (size - sizeof(struct GNUNET_DHT_ClientGetResultSeenMessage))
728  / sizeof(struct GNUNET_HashCode);
729  if (size != sizeof(struct GNUNET_DHT_ClientGetResultSeenMessage)
730  + hash_count * sizeof(struct GNUNET_HashCode))
731  {
732  GNUNET_break (0);
733  return GNUNET_SYSERR;
734  }
735  return GNUNET_OK;
736 }
737 
738 
745 static void
747  const struct
749 {
750  struct ClientHandle *ch = cls;
751  uint16_t size;
752  unsigned int hash_count;
753  unsigned int old_count;
754  const struct GNUNET_HashCode *hc;
755  struct FindByUniqueIdContext fui_ctx;
756  struct ClientQueryRecord *cqr;
757 
758  size = ntohs (seen->header.size);
759  hash_count = (size - sizeof(struct GNUNET_DHT_ClientGetResultSeenMessage))
760  / sizeof(struct GNUNET_HashCode);
761  hc = (const struct GNUNET_HashCode*) &seen[1];
762  fui_ctx.unique_id = seen->unique_id;
763  fui_ctx.cqr = NULL;
765  &seen->key,
767  &fui_ctx);
768  if (NULL == (cqr = fui_ctx.cqr))
769  {
770  GNUNET_break (0);
772  return;
773  }
774  /* finally, update 'seen' list */
775  old_count = cqr->seen_replies_count;
777  cqr->seen_replies_count,
778  cqr->seen_replies_count + hash_count);
779  GNUNET_memcpy (&cqr->seen_replies[old_count],
780  hc,
781  sizeof(struct GNUNET_HashCode) * hash_count);
782 }
783 
784 
789 {
793  struct ClientHandle *ch;
794 
798  uint64_t unique_id;
799 };
800 
801 
811 static int
813  const struct GNUNET_HashCode *key,
814  void *value)
815 {
816  const struct RemoveByUniqueIdContext *ctx = cls;
817  struct ClientQueryRecord *cqr = value;
818 
819  if (cqr->unique_id != ctx->unique_id)
820  return GNUNET_YES;
822  "Removing client %p's record for key %s (by unique id)\n",
823  ctx->ch->client,
824  GNUNET_h2s (key));
825  remove_client_record (cqr);
826  return GNUNET_YES;
827 }
828 
829 
838 static void
840  const struct
841  GNUNET_DHT_ClientGetStopMessage *dht_stop_msg)
842 {
843  struct ClientHandle *ch = cls;
844  struct RemoveByUniqueIdContext ctx;
845 
846  GNUNET_STATISTICS_update (GDS_stats,
848  ("# GET STOP requests received from clients"), 1,
849  GNUNET_NO);
851  "Received GET STOP request for %s from local client %p\n",
852  GNUNET_h2s (&dht_stop_msg->key),
853  ch->client);
854  ctx.ch = ch;
855  ctx.unique_id = dht_stop_msg->unique_id;
857  &dht_stop_msg->key,
859  &ctx);
861 }
862 
863 
871 static void
874 {
875  struct ClientHandle *ch = cls;
876  struct ClientMonitorRecord *r;
877 
878  r = GNUNET_new (struct ClientMonitorRecord);
879  r->ch = ch;
880  r->type = ntohl (msg->type);
881  r->get = ntohs (msg->get);
882  r->get_resp = ntohs (msg->get_resp);
883  r->put = ntohs (msg->put);
884  if (0 == ntohs (msg->filter_key))
885  {
886  r->key = NULL;
887  }
888  else
889  {
890  r->key = GNUNET_new (struct GNUNET_HashCode);
891  GNUNET_memcpy (r->key,
892  &msg->key,
893  sizeof(struct GNUNET_HashCode));
894  }
895  GNUNET_CONTAINER_DLL_insert (monitor_head,
896  monitor_tail,
897  r);
899 }
900 
901 
908 static void
910  const struct
912 {
913  struct ClientHandle *ch = cls;
914  struct ClientMonitorRecord *r;
915  int keys_match;
916 
918  for (r = monitor_head; NULL != r; r = r->next)
919  {
920  if (NULL == r->key)
921  {
922  keys_match = (0 == ntohs (msg->filter_key));
923  }
924  else
925  {
926  keys_match = ((0 != ntohs (msg->filter_key)) &&
927  (! memcmp (r->key,
928  &msg->key,
929  sizeof(struct GNUNET_HashCode))));
930  }
931  if ((ch == r->ch) &&
932  (ntohl (msg->type) == r->type) &&
933  (r->get == msg->get) &&
934  (r->get_resp == msg->get_resp) &&
935  (r->put == msg->put) &&
936  keys_match)
937  {
938  GNUNET_CONTAINER_DLL_remove (monitor_head,
939  monitor_tail,
940  r);
942  GNUNET_free (r);
943  return; /* Delete only ONE entry */
944  }
945  }
946 }
947 
948 
953 {
958 
963 
968 
972  const void *data;
973 
977  size_t data_size;
978 
982  unsigned int get_path_length;
983 
987  unsigned int put_path_length;
988 
993 };
994 
995 
1007 static int
1008 forward_reply (void *cls,
1009  const struct GNUNET_HashCode *key,
1010  void *value)
1011 {
1012  struct ForwardReplyContext *frc = cls;
1013  struct ClientQueryRecord *record = value;
1014  struct GNUNET_MQ_Envelope *env;
1015  struct GNUNET_DHT_ClientResultMessage *reply;
1017  int do_free;
1018  struct GNUNET_HashCode ch;
1019  struct GNUNET_PeerIdentity *paths;
1020 
1022  "CLIENT-RESULT %s\n",
1023  GNUNET_h2s_full (key));
1024  if ((record->type != GNUNET_BLOCK_TYPE_ANY) &&
1025  (record->type != frc->type))
1026  {
1028  "Record type mismatch, not passing request for key %s to local client\n",
1029  GNUNET_h2s (key));
1030  GNUNET_STATISTICS_update (GDS_stats,
1031  gettext_noop
1032  (
1033  "# Key match, type mismatches in REPLY to CLIENT"),
1034  1, GNUNET_NO);
1035  return GNUNET_YES; /* type mismatch */
1036  }
1037  GNUNET_CRYPTO_hash (frc->data, frc->data_size, &ch);
1038  for (unsigned int i = 0; i < record->seen_replies_count; i++)
1039  if (0 == memcmp (&record->seen_replies[i],
1040  &ch,
1041  sizeof(struct GNUNET_HashCode)))
1042  {
1044  "Duplicate reply, not passing request for key %s to local client\n",
1045  GNUNET_h2s (key));
1046  GNUNET_STATISTICS_update (GDS_stats,
1047  gettext_noop
1048  (
1049  "# Duplicate REPLIES to CLIENT request dropped"),
1050  1, GNUNET_NO);
1051  return GNUNET_YES; /* duplicate */
1052  }
1053  eval
1054  = GNUNET_BLOCK_evaluate (GDS_block_context,
1055  record->type,
1056  NULL,
1058  key,
1059  record->xquery,
1060  record->xquery_size,
1061  frc->data,
1062  frc->data_size);
1064  "Evaluation result is %d for key %s for local client's query\n",
1065  (int) eval,
1066  GNUNET_h2s (key));
1067  switch (eval)
1068  {
1070  do_free = GNUNET_YES;
1071  break;
1072 
1075  record->seen_replies_count,
1076  ch);
1077  do_free = GNUNET_NO;
1078  break;
1079 
1081  /* should be impossible to encounter here */
1082  GNUNET_break (0);
1083  return GNUNET_YES;
1084 
1086  GNUNET_break_op (0);
1087  return GNUNET_NO;
1088 
1090  GNUNET_break (0);
1091  return GNUNET_NO;
1092 
1094  GNUNET_break (0);
1095  return GNUNET_NO;
1096 
1098  return GNUNET_YES;
1099 
1102  _ ("Unsupported block type (%u) in request!\n"), record->type);
1103  return GNUNET_NO;
1104 
1105  default:
1106  GNUNET_break (0);
1107  return GNUNET_NO;
1108  }
1109  GNUNET_STATISTICS_update (GDS_stats,
1110  gettext_noop ("# RESULTS queued for clients"),
1111  1,
1112  GNUNET_NO);
1113  env = GNUNET_MQ_msg_extra (reply,
1114  frc->data_size
1115  + (frc->get_path_length + frc->put_path_length)
1116  * sizeof(struct GNUNET_PeerIdentity),
1118  reply->type = htonl (frc->type);
1119  reply->get_path_length = htonl (frc->get_path_length);
1120  reply->put_path_length = htonl (frc->put_path_length);
1121  reply->unique_id = record->unique_id;
1123  reply->key = *key;
1124  paths = (struct GNUNET_PeerIdentity *) &reply[1];
1125  GNUNET_memcpy (paths,
1126  frc->put_path,
1127  sizeof(struct GNUNET_PeerIdentity) * frc->put_path_length);
1128  GNUNET_memcpy (&paths[frc->put_path_length],
1129  frc->get_path,
1130  sizeof(struct GNUNET_PeerIdentity) * frc->get_path_length);
1131  GNUNET_memcpy (&paths[frc->get_path_length + frc->put_path_length],
1132  frc->data,
1133  frc->data_size);
1135  "Sending reply to query %s for client %p\n",
1136  GNUNET_h2s (key),
1137  record->ch->client);
1138  GNUNET_MQ_send (record->ch->mq,
1139  env);
1140  if (GNUNET_YES == do_free)
1141  remove_client_record (record);
1142  return GNUNET_YES;
1143 }
1144 
1145 
1161 void
1163  const struct GNUNET_HashCode *key,
1164  unsigned int get_path_length,
1165  const struct GNUNET_PeerIdentity *get_path,
1166  unsigned int put_path_length,
1167  const struct GNUNET_PeerIdentity *put_path,
1168  enum GNUNET_BLOCK_Type type,
1169  size_t data_size,
1170  const void *data)
1171 {
1172  struct ForwardReplyContext frc;
1173  size_t msize;
1174 
1175  msize = sizeof(struct GNUNET_DHT_ClientResultMessage) + data_size
1176  + (get_path_length + put_path_length) * sizeof(struct
1178  if (msize >= GNUNET_MAX_MESSAGE_SIZE)
1179  {
1180  GNUNET_break (0);
1181  return;
1182  }
1183  if (NULL == GNUNET_CONTAINER_multihashmap_get (forward_map,
1184  key))
1185  {
1187  "No matching client for reply for key %s\n",
1188  GNUNET_h2s (key));
1189  GNUNET_STATISTICS_update (GDS_stats,
1190  gettext_noop (
1191  "# REPLIES ignored for CLIENTS (no match)"),
1192  1,
1193  GNUNET_NO);
1194  return; /* no matching request, fast exit! */
1195  }
1196  frc.expiration = expiration;
1197  frc.get_path = get_path;
1198  frc.put_path = put_path;
1199  frc.data = data;
1200  frc.data_size = data_size;
1203  frc.type = type;
1205  "Forwarding reply for key %s to client\n",
1206  GNUNET_h2s (key));
1208  key,
1209  &forward_reply,
1210  &frc);
1211 }
1212 
1213 
1226 void
1228  enum GNUNET_BLOCK_Type type,
1229  uint32_t hop_count,
1230  uint32_t desired_replication_level,
1231  unsigned int path_length,
1232  const struct GNUNET_PeerIdentity *path,
1233  const struct GNUNET_HashCode *key)
1234 {
1235  struct ClientMonitorRecord *m;
1236  struct ClientHandle **cl;
1237  unsigned int cl_size;
1238 
1239  cl = NULL;
1240  cl_size = 0;
1241  for (m = monitor_head; NULL != m; m = m->next)
1242  {
1243  if (((GNUNET_BLOCK_TYPE_ANY == m->type) ||
1244  (m->type == type)) &&
1245  ((NULL == m->key) ||
1246  (0 == memcmp (key,
1247  m->key,
1248  sizeof(struct GNUNET_HashCode)))))
1249  {
1250  struct GNUNET_MQ_Envelope *env;
1251  struct GNUNET_DHT_MonitorGetMessage *mmsg;
1252  struct GNUNET_PeerIdentity *msg_path;
1253  size_t msize;
1254  unsigned int i;
1255 
1256  /* Don't send duplicates */
1257  for (i = 0; i < cl_size; i++)
1258  if (cl[i] == m->ch)
1259  break;
1260  if (i < cl_size)
1261  continue;
1262  GNUNET_array_append (cl,
1263  cl_size,
1264  m->ch);
1265 
1266  msize = path_length * sizeof(struct GNUNET_PeerIdentity);
1267  env = GNUNET_MQ_msg_extra (mmsg,
1268  msize,
1270  mmsg->options = htonl (options);
1271  mmsg->type = htonl (type);
1272  mmsg->hop_count = htonl (hop_count);
1273  mmsg->desired_replication_level = htonl (desired_replication_level);
1274  mmsg->get_path_length = htonl (path_length);
1275  mmsg->key = *key;
1276  msg_path = (struct GNUNET_PeerIdentity *) &mmsg[1];
1277  GNUNET_memcpy (msg_path,
1278  path,
1279  path_length * sizeof(struct GNUNET_PeerIdentity));
1280  GNUNET_MQ_send (m->ch->mq,
1281  env);
1282  }
1283  }
1284  GNUNET_free_non_null (cl);
1285 }
1286 
1287 
1302 void
1304  const struct GNUNET_PeerIdentity *get_path,
1305  unsigned int get_path_length,
1306  const struct GNUNET_PeerIdentity *put_path,
1307  unsigned int put_path_length,
1308  struct GNUNET_TIME_Absolute exp,
1309  const struct GNUNET_HashCode *key,
1310  const void *data,
1311  size_t size)
1312 {
1313  struct ClientMonitorRecord *m;
1314  struct ClientHandle **cl;
1315  unsigned int cl_size;
1316 
1317  cl = NULL;
1318  cl_size = 0;
1319  for (m = monitor_head; NULL != m; m = m->next)
1320  {
1321  if (((GNUNET_BLOCK_TYPE_ANY == m->type) || (m->type == type) ) &&
1322  ((NULL == m->key) ||
1323  (memcmp (key, m->key, sizeof(struct GNUNET_HashCode)) == 0) ))
1324  {
1325  struct GNUNET_MQ_Envelope *env;
1326  struct GNUNET_DHT_MonitorGetRespMessage *mmsg;
1327  struct GNUNET_PeerIdentity *path;
1328  size_t msize;
1329  unsigned int i;
1330 
1331  /* Don't send duplicates */
1332  for (i = 0; i < cl_size; i++)
1333  if (cl[i] == m->ch)
1334  break;
1335  if (i < cl_size)
1336  continue;
1337  GNUNET_array_append (cl,
1338  cl_size,
1339  m->ch);
1340 
1341  msize = size;
1342  msize += (get_path_length + put_path_length)
1343  * sizeof(struct GNUNET_PeerIdentity);
1344  env = GNUNET_MQ_msg_extra (mmsg,
1345  msize,
1347  mmsg->type = htonl (type);
1348  mmsg->put_path_length = htonl (put_path_length);
1349  mmsg->get_path_length = htonl (get_path_length);
1351  mmsg->key = *key;
1352  path = (struct GNUNET_PeerIdentity *) &mmsg[1];
1353  GNUNET_memcpy (path,
1354  put_path,
1355  put_path_length * sizeof(struct GNUNET_PeerIdentity));
1356  GNUNET_memcpy (path,
1357  get_path,
1358  get_path_length * sizeof(struct GNUNET_PeerIdentity));
1359  GNUNET_memcpy (&path[get_path_length],
1360  data,
1361  size);
1362  GNUNET_MQ_send (m->ch->mq,
1363  env);
1364  }
1365  }
1366  GNUNET_free_non_null (cl);
1367 }
1368 
1369 
1385 void
1387  enum GNUNET_BLOCK_Type type,
1388  uint32_t hop_count,
1389  uint32_t desired_replication_level,
1390  unsigned int path_length,
1391  const struct GNUNET_PeerIdentity *path,
1392  struct GNUNET_TIME_Absolute exp,
1393  const struct GNUNET_HashCode *key,
1394  const void *data,
1395  size_t size)
1396 {
1397  struct ClientMonitorRecord *m;
1398  struct ClientHandle **cl;
1399  unsigned int cl_size;
1400 
1401  cl = NULL;
1402  cl_size = 0;
1403  for (m = monitor_head; NULL != m; m = m->next)
1404  {
1405  if (((GNUNET_BLOCK_TYPE_ANY == m->type) || (m->type == type) ) &&
1406  ((NULL == m->key) ||
1407  (memcmp (key, m->key, sizeof(struct GNUNET_HashCode)) == 0) ))
1408  {
1409  struct GNUNET_MQ_Envelope *env;
1410  struct GNUNET_DHT_MonitorPutMessage *mmsg;
1411  struct GNUNET_PeerIdentity *msg_path;
1412  size_t msize;
1413  unsigned int i;
1414 
1415  /* Don't send duplicates */
1416  for (i = 0; i < cl_size; i++)
1417  if (cl[i] == m->ch)
1418  break;
1419  if (i < cl_size)
1420  continue;
1421  GNUNET_array_append (cl,
1422  cl_size,
1423  m->ch);
1424 
1425  msize = size;
1426  msize += path_length * sizeof(struct GNUNET_PeerIdentity);
1427  env = GNUNET_MQ_msg_extra (mmsg,
1428  msize,
1430  mmsg->options = htonl (options);
1431  mmsg->type = htonl (type);
1432  mmsg->hop_count = htonl (hop_count);
1433  mmsg->desired_replication_level = htonl (desired_replication_level);
1434  mmsg->put_path_length = htonl (path_length);
1435  mmsg->key = *key;
1437  msg_path = (struct GNUNET_PeerIdentity *) &mmsg[1];
1438  GNUNET_memcpy (msg_path,
1439  path,
1440  path_length * sizeof(struct GNUNET_PeerIdentity));
1441  GNUNET_memcpy (&msg_path[path_length],
1442  data,
1443  size);
1444  GNUNET_MQ_send (m->ch->mq,
1445  env);
1446  }
1447  }
1448  GNUNET_free_non_null (cl);
1449 }
1450 
1451 
1457 static void
1459 {
1460  forward_map
1462  GNUNET_YES);
1463  retry_heap
1465 }
1466 
1467 
1471 static void
1473 {
1474  if (NULL != retry_task)
1475  {
1476  GNUNET_SCHEDULER_cancel (retry_task);
1477  retry_task = NULL;
1478  }
1479 }
1480 
1481 
1488 #define GDS_DHT_SERVICE_INIT(name, run) \
1489  GNUNET_SERVICE_MAIN \
1490  (name, \
1491  GNUNET_SERVICE_OPTION_NONE, \
1492  run, \
1493  &client_connect_cb, \
1494  &client_disconnect_cb, \
1495  NULL, \
1496  GNUNET_MQ_hd_var_size (dht_local_put, \
1497  GNUNET_MESSAGE_TYPE_DHT_CLIENT_PUT, \
1498  struct GNUNET_DHT_ClientPutMessage, \
1499  NULL), \
1500  GNUNET_MQ_hd_var_size (dht_local_get, \
1501  GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET, \
1502  struct GNUNET_DHT_ClientGetMessage, \
1503  NULL), \
1504  GNUNET_MQ_hd_fixed_size (dht_local_get_stop, \
1505  GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_STOP, \
1506  struct GNUNET_DHT_ClientGetStopMessage, \
1507  NULL), \
1508  GNUNET_MQ_hd_fixed_size (dht_local_monitor, \
1509  GNUNET_MESSAGE_TYPE_DHT_MONITOR_START, \
1510  struct GNUNET_DHT_MonitorStartStopMessage, \
1511  NULL), \
1512  GNUNET_MQ_hd_fixed_size (dht_local_monitor_stop, \
1513  GNUNET_MESSAGE_TYPE_DHT_MONITOR_STOP, \
1514  struct GNUNET_DHT_MonitorStartStopMessage, \
1515  NULL), \
1516  GNUNET_MQ_hd_var_size (dht_local_get_result_seen, \
1517  GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_RESULTS_KNOWN, \
1518  struct GNUNET_DHT_ClientGetResultSeenMessage, \
1519  NULL), \
1520  GNUNET_MQ_handler_end ())
1521 
1522 
1526 void __attribute__ ((destructor))
1527 GDS_CLIENTS_done ()
1528 {
1529  if (NULL != retry_heap)
1530  {
1531  GNUNET_assert (0 == GNUNET_CONTAINER_heap_get_size (retry_heap));
1532  GNUNET_CONTAINER_heap_destroy (retry_heap);
1533  retry_heap = NULL;
1534  }
1535  if (NULL != forward_map)
1536  {
1539  forward_map = NULL;
1540  }
1541 }
1542 
1543 
1544 /* end of gnunet-service-dht_clients.c */
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
Block does not match query (invalid result)
uint64_t unique_id
The unique identifier of this request.
struct GNUNET_CONTAINER_BloomFilter * GNUNET_CONTAINER_bloomfilter_init(const char *data, size_t size, unsigned int k)
Create a Bloom filter from raw bits.
struct GNUNET_PeerIdentity * GDS_NEIGHBOURS_get_id()
Get the ID of the local node.
struct ClientQueryRecord * cqr_tail
Linked list of active queries of this client.
#define GNUNET_MESSAGE_TYPE_DHT_CLIENT_RESULT
Service returns result to client.
Closure for forward_reply()
GNUnet DHT globals.
const struct GNUNET_PeerIdentity * put_path
PUT path taken.
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...
struct ClientHandle * ch
Client to notify of these requests.
uint32_t options
Message options, actually an &#39;enum GNUNET_DHT_RouteOption&#39; value.
Definition: dht.h:333
Handle to an initialized block library.
Definition: block.c:54
uint64_t unique_id
Unique ID of the matching GET request.
Definition: dht.h:170
static int check_dht_local_put(void *cls, const struct GNUNET_DHT_ClientPutMessage *dht_msg)
Check DHT PUT messages from the client.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
uint32_t hop_count
Hop count so far.
Definition: dht.h:248
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:673
uint64_t rel_value_us
The actual value.
struct GNUNET_HashCode * key
Key of data of interest, NULL for all.
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT
Receive information about transiting PUTs.
DHT GET RESULTS KNOWN message sent from clients to service.
Definition: dht.h:113
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
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
Any type of block, used as a wildcard when searching.
static struct ClientMonitorRecord * monitor_head
List of active monitoring requests.
uint32_t get_path_length
Length of the GET path that follows (if tracked).
Definition: dht.h:387
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.
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
Handle to a service.
Definition: service.c:116
static void handle_local_result(void *cls, enum GNUNET_BLOCK_Type type, struct GNUNET_TIME_Absolute expiration_time, const struct GNUNET_HashCode *key, unsigned int put_path_length, const struct GNUNET_PeerIdentity *put_path, unsigned int get_path_length, const struct GNUNET_PeerIdentity *get_path, const void *data, size_t data_size)
Handle a result from local datacache for a GET operation.
GNUNET_BLOCK_Type
Blocks in the datastore and the datacache must have a unique type.
uint32_t desired_replication_level
Replication level for this message.
Definition: dht.h:253
static struct GNUNET_SCHEDULER_Task * retry_task
Task that re-transmits requests (using retry_heap).
struct GNUNET_STATISTICS_Handle * GDS_stats
Handle for the statistics service.
#define DHT_BLOOM_SIZE
Size of the bloom filter the DHT uses to filter peers.
Definition: dht.h:34
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:246
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
static struct GNUNET_CONTAINER_MultiHashMap * forward_map
Hashmap for fast key based lookup, maps keys to struct ClientQueryRecord entries. ...
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_CONSTANTS_BLOOMFILTER_K
K-value that must be used for the bloom filters in &#39;GET&#39; queries.
void __attribute__((destructor))
MINIMIZE heap size (way below 128k) since this process doesn&#39;t need much.
#define GNUNET_TIME_UNIT_SECONDS
One second.
uint32_t type
The type of data desired, GNUNET_BLOCK_TYPE_ANY for all.
Definition: dht.h:291
struct ClientQueryRecord * next
Kept in a DLL with client.
struct GNUNET_HashCode key
The key of the corresponding GET request.
Definition: dht.h:397
enum GNUNET_BLOCK_Type type
The type for the data for the GET request.
Message to insert data into the DHT, sent from clients to DHT service.
Definition: dht.h:189
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.
struct ClientQueryRecord * prev
Kept in a DLL with client.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
struct ClientMonitorRecord * next
Next element in DLL.
void GDS_CLIENTS_process_get_resp(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)
Check if some client is monitoring GET RESP messages and notify them in that case.
Block does not match xquery (valid result, not relevant for the request)
uint32_t type
The type of data in the request.
Definition: dht.h:243
#define GNUNET_NO
Definition: gnunet_common.h:78
enum GNUNET_BLOCK_Type type
Type of the data.
int16_t get_resp
Flag whether to notify about GET_REPONSE messages.
Definition: dht.h:301
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
uint16_t put
Flag whether to notify about PUT messages.
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Default behavior.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct GNUNET_SERVICE_Handle * GDS_service
Handle for the service.
Handle for the service.
uint64_t abs_value_us
The actual value.
unsigned int get_path_length
Number of entries in get_path.
Internal representation of the hash map.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
void GDS_CLIENTS_handle_reply(struct GNUNET_TIME_Absolute expiration, const struct GNUNET_HashCode *key, unsigned int get_path_length, const struct GNUNET_PeerIdentity *get_path, unsigned int put_path_length, const struct GNUNET_PeerIdentity *put_path, enum GNUNET_BLOCK_Type type, size_t data_size, const void *data)
Handle a reply we&#39;ve received from another peer.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
static int check_dht_local_get(void *cls, const struct GNUNET_DHT_ClientGetMessage *get)
Check DHT GET messages from the client.
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
uint32_t desired_replication_level
Replication level for this message.
Definition: dht.h:209
Handle to a client that is connected to a service.
Definition: service.c:250
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...
struct ClientQueryRecord * cqr_head
Linked list of active queries of this client.
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:104
struct GNUNET_TIME_Relative retry_frequency
What&#39;s the delay between re-try operations that we currently use for this request?
Closure for remove_by_unique_id().
static void handle_dht_local_monitor_stop(void *cls, const struct GNUNET_DHT_MonitorStartStopMessage *msg)
Handler for monitor stop messages.
uint32_t replication
Desired replication level.
struct ClientHandle * ch
Client responsible for the request.
uint64_t unique_id
Unique ID identifying this request.
Definition: dht.h:58
uint32_t put_path_length
Length of the PUT path that follows (if tracked).
Definition: dht.h:382
#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
void GDS_CLIENTS_process_get(uint32_t 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)
Check if some client is monitoring GET messages and notify them in that case.
enum GNUNET_BLOCK_Type type
Type of blocks that are of interest.
uint32_t type
The type of data to insert.
Definition: dht.h:199
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
Message to monitor put requests going through peer, DHT service -> clients.
Definition: dht.h:228
static char * value
Value of the record to add/remove.
Valid result, but suppressed because it is a duplicate.
int16_t filter_key
Flag whether to use the provided key to filter messages.
Definition: dht.h:311
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
uint64_t unique_id
Unique ID identifying this request.
Definition: dht.h:134
int16_t put
Flag whether to notify about PUT messages.
Definition: dht.h:306
struct GNUNET_TIME_AbsoluteNBO expiration_time
How long should this data persist?
Definition: dht.h:264
unsigned int put_path_length
Number of entries in put_path.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
Message to request monitoring messages, clients -> DHT service.
Definition: dht.h:280
struct GNUNET_HashCode key
The key that was searched for.
Definition: dht.h:180
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:1280
enum GNUNET_BLOCK_EvaluationResult GNUNET_BLOCK_evaluate(struct GNUNET_BLOCK_Context *ctx, enum GNUNET_BLOCK_Type type, struct GNUNET_BLOCK_Group *group, enum GNUNET_BLOCK_EvaluationOptions eo, 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 or a request.
Definition: block.c:338
void GDS_DATACACHE_handle_put(struct GNUNET_TIME_Absolute expiration, const struct GNUNET_HashCode *key, unsigned int put_path_length, const struct GNUNET_PeerIdentity *put_path, enum GNUNET_BLOCK_Type type, size_t data_size, const void *data)
Handle a datum we&#39;ve received from another peer.
Last possible valid result.
Closure for find_by_unique_id().
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.
Handle to a node in a heap.
uint64_t unique_id
Unique ID of the request.
void GDS_CLIENTS_process_put(uint32_t 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)
Check if some client is monitoring PUT messages and notify them in that case.
struct GNUNET_TIME_AbsoluteNBO expiration
When does this entry expire?
Definition: dht.h:175
uint32_t options
Message options, actually an &#39;enum GNUNET_DHT_RouteOption&#39; value.
Definition: dht.h:204
uint32_t type
The type for the data.
Definition: dht.h:153
static void handle_dht_local_put(void *cls, const struct GNUNET_DHT_ClientPutMessage *dht_msg)
Handler for PUT messages.
Heap with the minimum cost at the root.
struct GNUNET_HashCode key
The key to store the value under.
Definition: dht.h:359
void GNUNET_CONTAINER_heap_destroy(struct GNUNET_CONTAINER_Heap *heap)
Destroys the heap.
A 512-bit hashcode.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2324
static char * expiration
Credential TTL.
Definition: gnunet-abd.c:96
#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET
Receive information about transiting GETs.
struct GNUNET_SERVICE_Client * client
The handle to this client.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
Entry in the local forwarding map for a client&#39;s GET request.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_DHT_CLIENT_PUT.
Definition: dht.h:194
Node in the heap.
unsigned int GNUNET_CONTAINER_heap_get_size(const struct GNUNET_CONTAINER_Heap *heap)
Get the current size of the heap.
Valid result, and there may be more.
Struct containing information about a client, handle to connect to it, and any pending messages that ...
struct GNUNET_TIME_AbsoluteNBO expiration
How long should this data persist?
Definition: dht.h:214
uint32_t msg_options
Any message options for this request.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static unsigned int size
Size of the "table".
Definition: peer.c:67
struct ClientHandle * ch
Client that issued the removal request.
#define LOG(kind,...)
size_t xquery_size
Number of bytes in xquery.
static struct ClientMonitorRecord * monitor_tail
List of active monitoring requests.
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
static void transmit_request(struct ClientQueryRecord *cqr)
Route the given request via the DHT.
static void GDS_CLIENTS_stop()
Shutdown client subsystem.
GNUNET_BLOCK_EvaluationResult
Possible ways for how a block may relate to a query.
static int find_by_unique_id(void *cls, const struct GNUNET_HashCode *key, void *value)
Function called for each existing DHT record for the given query.
const char * GNUNET_h2s_full(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_RESULTS_KNOWN.
Definition: dht.h:118
struct GNUNET_MQ_Handle * mq
The message queue to this client.
static void remove_client_record(struct ClientQueryRecord *record)
Free data structures associated with the given query.
GNUnet DHT routing code.
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
const struct GNUNET_CONFIGURATION_Handle * GDS_cfg
The configuration the DHT service is running with.
struct GNUNET_HashCode * seen_replies
Replies we have already seen for this request.
struct ClientMonitorRecord * prev
Previous element in DLL.
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.
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:289
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
struct GNUNET_CONTAINER_Heap * GNUNET_CONTAINER_heap_create(enum GNUNET_CONTAINER_HeapOrder order)
Create a new heap.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
int16_t get_resp
Flag whether to notify about GET_REPONSE messages.
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.
int 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.
static struct GNUNET_CONTAINER_Heap * retry_heap
Heap with all of our client&#39;s request, sorted by retry time (earliest on top).
Specified block type not supported by this plugin.
uint32_t desired_replication_level
Replication level for this message.
Definition: dht.h:348
Allow multiple values with the same key.
Handle to a message queue.
Definition: mq.c:85
struct ClientQueryRecord * cqr
Where to store the result, if found.
int16_t get
Flag whether to notify about GET messages.
Definition: dht.h:296
#define GNUNET_array_append(arr, size, element)
Append an element to a list (growing the list by one).
struct GNUNET_HashCode key
The key to store the value under.
Definition: dht.h:219
GNUnet DHT service&#39;s datacache integration.
The identity of the host (wraps the signing key of the peer).
#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET_RESP
Receive information about transiting GET responses.
int16_t get
Flag whether to notify about GET messages.
uint32_t get_path_length
The number of peer identities recorded from the storage location to this peer.
Definition: dht.h:165
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.
struct GNUNET_HashCode key
Key of this request.
Definition: dht.h:63
static int monitor
Monitor ARM activity.
Definition: gnunet-arm.c:64
static void handle_dht_local_get(void *cls, const struct GNUNET_DHT_ClientGetMessage *get)
Handler for DHT GET messages from the client.
Struct containing paremeters of monitoring requests.
unsigned int seen_replies_count
Number of entries in &#39;seen_replies&#39;.
configuration data
Definition: configuration.c:85
#define LOG_TRAFFIC(kind,...)
Should routing details be logged to stderr (for debugging)?
DHT GET message sent from clients to service.
Definition: dht.h:71
Query format does not match block type (invalid query).
static int forward_reply(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator over hash map entries that send a given reply to each of the matching clients.
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:134
void * GNUNET_CONTAINER_heap_remove_root(struct GNUNET_CONTAINER_Heap *heap)
Remove root of the heap.
static void GDS_CLIENTS_init()
Initialize client subsystem.
size_t data_size
Number of bytes in data.
Block group data.
static int check_dht_local_get_result_seen(void *cls, const struct GNUNET_DHT_ClientGetResultSeenMessage *seen)
Check "GET result seen" messages from the client.
static void record(void *cls, size_t data_size, const void *data)
Process recorded audio data.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
uint32_t type
The type of data in the request.
Definition: dht.h:338
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&#39;ve received from another peer.
struct GNUNET_HashCode key
The key to filter messages by.
Definition: dht.h:316
const struct GNUNET_PeerIdentity * get_path
GET path taken.
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:331
Message which indicates the DHT should cancel outstanding requests and discard any state...
Definition: dht.h:43
static void handle_dht_local_monitor(void *cls, const struct GNUNET_DHT_MonitorStartStopMessage *msg)
Handler for monitor start messages.
uint32_t type
Content type.
Definition: dht.h:377
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:77
Message to monitor get requests going through peer, DHT service -> clients.
Definition: dht.h:323
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:353
uint32_t hop_count
Hop count.
Definition: dht.h:343
struct GNUNET_BLOCK_Context * GDS_block_context
Our handle to the BLOCK library.
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the content expire?
Definition: dht.h:392
static int 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...
uint32_t options
Message options, actually an &#39;enum GNUNET_DHT_RouteOption&#39; value.
Definition: dht.h:238
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:1230
uint32_t data
The data value.
void * GNUNET_CONTAINER_heap_remove_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from the heap.
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:657
struct GNUNET_HashCode key
The key this request was about.
Query is valid, no reply given.
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...
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2243
void GNUNET_CONTAINER_bloomfilter_free(struct GNUNET_CONTAINER_BloomFilter *bf)
Free the space associcated with a filter in memory, flush to drive if needed (do not free the space o...
Message to monitor get results going through peer, DHT service -> clients.
Definition: dht.h:367
struct GNUNET_TIME_Absolute retry_time
What&#39;s the next time we should re-try this request?
struct GNUNET_TIME_Absolute expiration
Expiration time of the reply.
struct GNUNET_HashCode key
The key to store the value under.
Definition: dht.h:269
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
#define GNUNET_malloc(size)
Wrapper around malloc.
struct GNUNET_CONTAINER_HeapNode * hnode
Pointer to this nodes heap location in the retry-heap (for fast removal)
Reply to a GET send from the service to a client.
Definition: dht.h:143
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
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
void GNUNET_BLOCK_group_destroy(struct GNUNET_BLOCK_Group *bg)
Destroy resources used by a block group.
Definition: block.c:205
const void * xquery
Extended query (see gnunet_block_lib.h), allocated at the end of this struct.
int 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:409
#define gettext_noop(String)
Definition: gettext.h:69
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966
const void * data
Embedded payload.
int GDS_NEIGHBOURS_handle_put(enum GNUNET_BLOCK_Type type, enum GNUNET_DHT_RouteOption options, uint32_t desired_replication_level, struct GNUNET_TIME_Absolute expiration_time, uint32_t hop_count, struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *key, unsigned int put_path_length, struct GNUNET_PeerIdentity *put_path, const void *data, size_t data_size)
Perform a PUT operation.