GNUnet  0.10.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",__VA_ARGS__)
42 
43 #define LOG(kind,...) GNUNET_log_from (kind, "dht-clients",__VA_ARGS__)
44 
45 
51 struct ClientHandle;
52 
53 
58 {
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 
138 
143 {
144 
149 
154 
159 
164 
168  int16_t get;
169 
173  int16_t get_resp;
174 
178  uint16_t put;
179 
183  struct ClientHandle *ch;
184 };
185 
186 
193 {
198 
203 
208 
213 
214 };
215 
220 
225 
230 
235 
240 
245 
250 
255 
260 
261 
267 static void
269 {
270  struct ClientHandle *ch = record->ch;
271 
273  ch->cqr_tail,
274  record);
277  &record->key,
278  record));
279  if (NULL != record->hnode)
282  record->seen_replies_count,
283  0);
284  GNUNET_free (record);
285 }
286 
287 
297 static void *
298 client_connect_cb (void *cls,
300  struct GNUNET_MQ_Handle *mq)
301 {
302  struct ClientHandle *ch;
303 
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  struct ClientQueryRecord *cqr;
327 
329  "Local client %p disconnects\n",
330  ch);
331  monitor = monitor_head;
332  while (NULL != monitor)
333  {
334  if (monitor->ch == ch)
335  {
336  struct ClientMonitorRecord *next;
337 
338  next = monitor->next;
339  GNUNET_free_non_null (monitor->key);
340  GNUNET_CONTAINER_DLL_remove (monitor_head,
341  monitor_tail,
342  monitor);
343  GNUNET_free (monitor);
344  monitor = next;
345  }
346  else
347  {
348  monitor = monitor->next;
349  }
350  }
351  while (NULL != (cqr = ch->cqr_head))
352  remove_client_record (cqr);
353  GNUNET_free (ch);
354 }
355 
356 
362 static void
364 {
365  struct GNUNET_BLOCK_Group *bg;
366  struct GNUNET_CONTAINER_BloomFilter *peer_bf;
367 
368  GNUNET_STATISTICS_update (GDS_stats,
369  gettext_noop ("# GET requests from clients injected"),
370  1,
371  GNUNET_NO);
372  bg = GNUNET_BLOCK_group_create (GDS_block_context,
373  cqr->type,
375  UINT32_MAX),
376  NULL,
377  0,
378  "seen-set-size",
379  cqr->seen_replies_count,
380  NULL);
382  cqr->seen_replies,
383  cqr->seen_replies_count);
384  peer_bf
389  "Initiating GET for %s, replication %u, already have %u replies\n",
390  GNUNET_h2s (&cqr->key),
391  cqr->replication,
392  cqr->seen_replies_count);
394  cqr->msg_options,
395  cqr->replication,
396  0 /* hop count */ ,
397  &cqr->key,
398  cqr->xquery,
399  cqr->xquery_size,
400  bg,
401  peer_bf);
404 
405  /* exponential back-off for retries.
406  * max GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD (15 min) */
409 }
410 
411 
419 static void
421 {
422  struct ClientQueryRecord *cqr;
423  struct GNUNET_TIME_Relative delay;
424 
425  retry_task = NULL;
426  while (NULL != (cqr = GNUNET_CONTAINER_heap_remove_root (retry_heap)))
427  {
428  cqr->hnode = NULL;
430  if (delay.rel_value_us > 0)
431  {
432  cqr->hnode
433  = GNUNET_CONTAINER_heap_insert (retry_heap,
434  cqr,
435  cqr->retry_time.abs_value_us);
436  retry_task
439  NULL);
440  return;
441  }
442  transmit_request (cqr);
443  cqr->hnode
444  = GNUNET_CONTAINER_heap_insert (retry_heap,
445  cqr,
446  cqr->retry_time.abs_value_us);
447  }
448 }
449 
450 
458 static int
460  const struct GNUNET_DHT_ClientPutMessage *dht_msg)
461 {
462  /* always well-formed */
463  return GNUNET_OK;
464 }
465 
466 
473 static void
475  const struct GNUNET_DHT_ClientPutMessage *dht_msg)
476 {
477  struct ClientHandle *ch = cls;
478  struct GNUNET_CONTAINER_BloomFilter *peer_bf;
479  uint16_t size;
480 
481  size = ntohs (dht_msg->header.size);
482  GNUNET_STATISTICS_update (GDS_stats,
483  gettext_noop ("# 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 GNUNET_DHT_ClientGetResultSeenMessage *seen)
721 {
722  uint16_t size;
723  unsigned int hash_count;
724 
725  size = ntohs (seen->header.size);
726  hash_count = (size - sizeof (struct GNUNET_DHT_ClientGetResultSeenMessage)) / sizeof (struct GNUNET_HashCode);
727  if (size != sizeof (struct GNUNET_DHT_ClientGetResultSeenMessage) + hash_count * sizeof (struct GNUNET_HashCode))
728  {
729  GNUNET_break (0);
730  return GNUNET_SYSERR;
731  }
732  return GNUNET_OK;
733 }
734 
735 
742 static void
744  const struct GNUNET_DHT_ClientGetResultSeenMessage *seen)
745 {
746  struct ClientHandle *ch = cls;
747  uint16_t size;
748  unsigned int hash_count;
749  unsigned int old_count;
750  const struct GNUNET_HashCode *hc;
751  struct FindByUniqueIdContext fui_ctx;
752  struct ClientQueryRecord *cqr;
753 
754  size = ntohs (seen->header.size);
755  hash_count = (size - sizeof (struct GNUNET_DHT_ClientGetResultSeenMessage)) / sizeof (struct GNUNET_HashCode);
756  hc = (const struct GNUNET_HashCode*) &seen[1];
757  fui_ctx.unique_id = seen->unique_id;
758  fui_ctx.cqr = NULL;
760  &seen->key,
762  &fui_ctx);
763  if (NULL == (cqr = fui_ctx.cqr))
764  {
765  GNUNET_break (0);
767  return;
768  }
769  /* finally, update 'seen' list */
770  old_count = cqr->seen_replies_count;
772  cqr->seen_replies_count,
773  cqr->seen_replies_count + hash_count);
774  GNUNET_memcpy (&cqr->seen_replies[old_count],
775  hc,
776  sizeof (struct GNUNET_HashCode) * hash_count);
777 }
778 
779 
784 {
788  struct ClientHandle *ch;
789 
793  uint64_t unique_id;
794 };
795 
796 
806 static int
808  const struct GNUNET_HashCode *key,
809  void *value)
810 {
811  const struct RemoveByUniqueIdContext *ctx = cls;
812  struct ClientQueryRecord *cqr = value;
813 
814  if (cqr->unique_id != ctx->unique_id)
815  return GNUNET_YES;
817  "Removing client %p's record for key %s (by unique id)\n",
818  ctx->ch->client,
819  GNUNET_h2s (key));
820  remove_client_record (cqr);
821  return GNUNET_YES;
822 }
823 
824 
833 static void
835  const struct GNUNET_DHT_ClientGetStopMessage *dht_stop_msg)
836 {
837  struct ClientHandle *ch = cls;
838  struct RemoveByUniqueIdContext ctx;
839 
840  GNUNET_STATISTICS_update (GDS_stats,
842  ("# GET STOP requests received from clients"), 1,
843  GNUNET_NO);
845  "Received GET STOP request for %s from local client %p\n",
846  GNUNET_h2s (&dht_stop_msg->key),
847  ch->client);
848  ctx.ch = ch;
849  ctx.unique_id = dht_stop_msg->unique_id;
851  &dht_stop_msg->key,
853  &ctx);
855 }
856 
857 
865 static void
868 {
869  struct ClientHandle *ch = cls;
870  struct ClientMonitorRecord *r;
871 
872  r = GNUNET_new (struct ClientMonitorRecord);
873  r->ch = ch;
874  r->type = ntohl (msg->type);
875  r->get = ntohs (msg->get);
876  r->get_resp = ntohs (msg->get_resp);
877  r->put = ntohs (msg->put);
878  if (0 == ntohs (msg->filter_key))
879  {
880  r->key = NULL;
881  }
882  else
883  {
884  r->key = GNUNET_new (struct GNUNET_HashCode);
885  GNUNET_memcpy (r->key,
886  &msg->key,
887  sizeof (struct GNUNET_HashCode));
888  }
889  GNUNET_CONTAINER_DLL_insert (monitor_head,
890  monitor_tail,
891  r);
893 }
894 
895 
902 static void
905 {
906  struct ClientHandle *ch = cls;
907  struct ClientMonitorRecord *r;
908  int keys_match;
909 
911  for (r = monitor_head; NULL != r; r = r->next)
912  {
913  if (NULL == r->key)
914  {
915  keys_match = (0 == ntohs(msg->filter_key));
916  }
917  else
918  {
919  keys_match = ( (0 != ntohs(msg->filter_key)) &&
920  (! memcmp (r->key,
921  &msg->key,
922  sizeof(struct GNUNET_HashCode))) );
923  }
924  if ( (ch == r->ch) &&
925  (ntohl(msg->type) == r->type) &&
926  (r->get == msg->get) &&
927  (r->get_resp == msg->get_resp) &&
928  (r->put == msg->put) &&
929  keys_match )
930  {
931  GNUNET_CONTAINER_DLL_remove (monitor_head,
932  monitor_tail,
933  r);
935  GNUNET_free (r);
936  return; /* Delete only ONE entry */
937  }
938  }
939 }
940 
941 
946 {
947 
952 
957 
962 
966  const void *data;
967 
971  size_t data_size;
972 
976  unsigned int get_path_length;
977 
981  unsigned int put_path_length;
982 
987 
988 };
989 
990 
1002 static int
1003 forward_reply (void *cls,
1004  const struct GNUNET_HashCode *key,
1005  void *value)
1006 {
1007  struct ForwardReplyContext *frc = cls;
1008  struct ClientQueryRecord *record = value;
1009  struct GNUNET_MQ_Envelope *env;
1010  struct GNUNET_DHT_ClientResultMessage *reply;
1012  int do_free;
1013  struct GNUNET_HashCode ch;
1014  struct GNUNET_PeerIdentity *paths;
1015 
1017  "CLIENT-RESULT %s\n",
1018  GNUNET_h2s_full (key));
1019  if ( (record->type != GNUNET_BLOCK_TYPE_ANY) &&
1020  (record->type != frc->type))
1021  {
1023  "Record type mismatch, not passing request for key %s to local client\n",
1024  GNUNET_h2s (key));
1025  GNUNET_STATISTICS_update (GDS_stats,
1026  gettext_noop
1027  ("# Key match, type mismatches in REPLY to CLIENT"),
1028  1, GNUNET_NO);
1029  return GNUNET_YES; /* type mismatch */
1030  }
1031  GNUNET_CRYPTO_hash (frc->data, frc->data_size, &ch);
1032  for (unsigned int i = 0; i < record->seen_replies_count; i++)
1033  if (0 == memcmp (&record->seen_replies[i],
1034  &ch,
1035  sizeof (struct GNUNET_HashCode)))
1036  {
1038  "Duplicate reply, not passing request for key %s to local client\n",
1039  GNUNET_h2s (key));
1040  GNUNET_STATISTICS_update (GDS_stats,
1041  gettext_noop
1042  ("# Duplicate REPLIES to CLIENT request dropped"),
1043  1, GNUNET_NO);
1044  return GNUNET_YES; /* duplicate */
1045  }
1046  eval
1047  = GNUNET_BLOCK_evaluate (GDS_block_context,
1048  record->type,
1049  NULL,
1051  key,
1052  record->xquery,
1053  record->xquery_size,
1054  frc->data,
1055  frc->data_size);
1057  "Evaluation result is %d for key %s for local client's query\n",
1058  (int) eval,
1059  GNUNET_h2s (key));
1060  switch (eval)
1061  {
1063  do_free = GNUNET_YES;
1064  break;
1067  record->seen_replies_count,
1068  ch);
1069  do_free = GNUNET_NO;
1070  break;
1072  /* should be impossible to encounter here */
1073  GNUNET_break (0);
1074  return GNUNET_YES;
1076  GNUNET_break_op (0);
1077  return GNUNET_NO;
1079  GNUNET_break (0);
1080  return GNUNET_NO;
1082  GNUNET_break (0);
1083  return GNUNET_NO;
1085  return GNUNET_YES;
1088  _("Unsupported block type (%u) in request!\n"), record->type);
1089  return GNUNET_NO;
1090  default:
1091  GNUNET_break (0);
1092  return GNUNET_NO;
1093  }
1094  GNUNET_STATISTICS_update (GDS_stats,
1095  gettext_noop ("# RESULTS queued for clients"),
1096  1,
1097  GNUNET_NO);
1098  env = GNUNET_MQ_msg_extra (reply,
1099  frc->data_size +
1100  (frc->get_path_length + frc->put_path_length) * sizeof (struct GNUNET_PeerIdentity),
1102  reply->type = htonl (frc->type);
1103  reply->get_path_length = htonl (frc->get_path_length);
1104  reply->put_path_length = htonl (frc->put_path_length);
1105  reply->unique_id = record->unique_id;
1107  reply->key = *key;
1108  paths = (struct GNUNET_PeerIdentity *) &reply[1];
1109  GNUNET_memcpy (paths,
1110  frc->put_path,
1111  sizeof (struct GNUNET_PeerIdentity) * frc->put_path_length);
1112  GNUNET_memcpy (&paths[frc->put_path_length],
1113  frc->get_path,
1114  sizeof (struct GNUNET_PeerIdentity) * frc->get_path_length);
1115  GNUNET_memcpy (&paths[frc->get_path_length + frc->put_path_length],
1116  frc->data,
1117  frc->data_size);
1119  "Sending reply to query %s for client %p\n",
1120  GNUNET_h2s (key),
1121  record->ch->client);
1122  GNUNET_MQ_send (record->ch->mq,
1123  env);
1124  if (GNUNET_YES == do_free)
1125  remove_client_record (record);
1126  return GNUNET_YES;
1127 }
1128 
1129 
1145 void
1147  const struct GNUNET_HashCode *key,
1148  unsigned int get_path_length,
1149  const struct GNUNET_PeerIdentity *get_path,
1150  unsigned int put_path_length,
1151  const struct GNUNET_PeerIdentity *put_path,
1152  enum GNUNET_BLOCK_Type type,
1153  size_t data_size,
1154  const void *data)
1155 {
1156  struct ForwardReplyContext frc;
1157  size_t msize;
1158 
1159  msize = sizeof (struct GNUNET_DHT_ClientResultMessage) + data_size +
1160  (get_path_length + put_path_length) * sizeof (struct GNUNET_PeerIdentity);
1161  if (msize >= GNUNET_MAX_MESSAGE_SIZE)
1162  {
1163  GNUNET_break (0);
1164  return;
1165  }
1166  if (NULL == GNUNET_CONTAINER_multihashmap_get (forward_map,
1167  key))
1168  {
1170  "No matching client for reply for key %s\n",
1171  GNUNET_h2s (key));
1172  GNUNET_STATISTICS_update (GDS_stats,
1173  gettext_noop ("# REPLIES ignored for CLIENTS (no match)"),
1174  1,
1175  GNUNET_NO);
1176  return; /* no matching request, fast exit! */
1177  }
1178  frc.expiration = expiration;
1179  frc.get_path = get_path;
1180  frc.put_path = put_path;
1181  frc.data = data;
1182  frc.data_size = data_size;
1183  frc.get_path_length = get_path_length;
1184  frc.put_path_length = put_path_length;
1185  frc.type = type;
1187  "Forwarding reply for key %s to client\n",
1188  GNUNET_h2s (key));
1190  key,
1191  &forward_reply,
1192  &frc);
1193 
1194 }
1195 
1196 
1209 void
1211  enum GNUNET_BLOCK_Type type,
1212  uint32_t hop_count,
1213  uint32_t desired_replication_level,
1214  unsigned int path_length,
1215  const struct GNUNET_PeerIdentity *path,
1216  const struct GNUNET_HashCode * key)
1217 {
1218  struct ClientMonitorRecord *m;
1219  struct ClientHandle **cl;
1220  unsigned int cl_size;
1221 
1222  cl = NULL;
1223  cl_size = 0;
1224  for (m = monitor_head; NULL != m; m = m->next)
1225  {
1226  if ( ( (GNUNET_BLOCK_TYPE_ANY == m->type) ||
1227  (m->type == type) ) &&
1228  ( (NULL == m->key) ||
1229  (0 == memcmp (key,
1230  m->key,
1231  sizeof(struct GNUNET_HashCode))) ) )
1232  {
1233  struct GNUNET_MQ_Envelope *env;
1234  struct GNUNET_DHT_MonitorGetMessage *mmsg;
1235  struct GNUNET_PeerIdentity *msg_path;
1236  size_t msize;
1237  unsigned int i;
1238 
1239  /* Don't send duplicates */
1240  for (i = 0; i < cl_size; i++)
1241  if (cl[i] == m->ch)
1242  break;
1243  if (i < cl_size)
1244  continue;
1245  GNUNET_array_append (cl,
1246  cl_size,
1247  m->ch);
1248 
1249  msize = path_length * sizeof (struct GNUNET_PeerIdentity);
1250  env = GNUNET_MQ_msg_extra (mmsg,
1251  msize,
1253  mmsg->options = htonl(options);
1254  mmsg->type = htonl(type);
1255  mmsg->hop_count = htonl(hop_count);
1256  mmsg->desired_replication_level = htonl(desired_replication_level);
1257  mmsg->get_path_length = htonl(path_length);
1258  mmsg->key = *key;
1259  msg_path = (struct GNUNET_PeerIdentity *) &mmsg[1];
1260  GNUNET_memcpy (msg_path,
1261  path,
1262  path_length * sizeof (struct GNUNET_PeerIdentity));
1263  GNUNET_MQ_send (m->ch->mq,
1264  env);
1265  }
1266  }
1267  GNUNET_free_non_null (cl);
1268 }
1269 
1270 
1285 void
1287  const struct GNUNET_PeerIdentity *get_path,
1288  unsigned int get_path_length,
1289  const struct GNUNET_PeerIdentity *put_path,
1290  unsigned int put_path_length,
1291  struct GNUNET_TIME_Absolute exp,
1292  const struct GNUNET_HashCode * key,
1293  const void *data,
1294  size_t size)
1295 {
1296  struct ClientMonitorRecord *m;
1297  struct ClientHandle **cl;
1298  unsigned int cl_size;
1299 
1300  cl = NULL;
1301  cl_size = 0;
1302  for (m = monitor_head; NULL != m; m = m->next)
1303  {
1304  if ((GNUNET_BLOCK_TYPE_ANY == m->type || m->type == type) &&
1305  (NULL == m->key ||
1306  memcmp (key, m->key, sizeof(struct GNUNET_HashCode)) == 0))
1307  {
1308  struct GNUNET_MQ_Envelope *env;
1309  struct GNUNET_DHT_MonitorGetRespMessage *mmsg;
1310  struct GNUNET_PeerIdentity *path;
1311  size_t msize;
1312  unsigned int i;
1313 
1314  /* Don't send duplicates */
1315  for (i = 0; i < cl_size; i++)
1316  if (cl[i] == m->ch)
1317  break;
1318  if (i < cl_size)
1319  continue;
1320  GNUNET_array_append (cl,
1321  cl_size,
1322  m->ch);
1323 
1324  msize = size;
1325  msize += (get_path_length + put_path_length)
1326  * sizeof (struct GNUNET_PeerIdentity);
1327  env = GNUNET_MQ_msg_extra (mmsg,
1328  msize,
1330  mmsg->type = htonl(type);
1331  mmsg->put_path_length = htonl(put_path_length);
1332  mmsg->get_path_length = htonl(get_path_length);
1334  mmsg->key = *key;
1335  path = (struct GNUNET_PeerIdentity *) &mmsg[1];
1336  GNUNET_memcpy (path,
1337  put_path,
1338  put_path_length * sizeof (struct GNUNET_PeerIdentity));
1339  GNUNET_memcpy (path,
1340  get_path,
1341  get_path_length * sizeof (struct GNUNET_PeerIdentity));
1342  GNUNET_memcpy (&path[get_path_length],
1343  data,
1344  size);
1345  GNUNET_MQ_send (m->ch->mq,
1346  env);
1347  }
1348  }
1349  GNUNET_free_non_null (cl);
1350 }
1351 
1352 
1368 void
1370  enum GNUNET_BLOCK_Type type,
1371  uint32_t hop_count,
1372  uint32_t desired_replication_level,
1373  unsigned int path_length,
1374  const struct GNUNET_PeerIdentity *path,
1375  struct GNUNET_TIME_Absolute exp,
1376  const struct GNUNET_HashCode *key,
1377  const void *data,
1378  size_t size)
1379 {
1380  struct ClientMonitorRecord *m;
1381  struct ClientHandle **cl;
1382  unsigned int cl_size;
1383 
1384  cl = NULL;
1385  cl_size = 0;
1386  for (m = monitor_head; NULL != m; m = m->next)
1387  {
1388  if ((GNUNET_BLOCK_TYPE_ANY == m->type || m->type == type) &&
1389  (NULL == m->key ||
1390  memcmp (key, m->key, sizeof(struct GNUNET_HashCode)) == 0))
1391  {
1392  struct GNUNET_MQ_Envelope *env;
1393  struct GNUNET_DHT_MonitorPutMessage *mmsg;
1394  struct GNUNET_PeerIdentity *msg_path;
1395  size_t msize;
1396  unsigned int i;
1397 
1398  /* Don't send duplicates */
1399  for (i = 0; i < cl_size; i++)
1400  if (cl[i] == m->ch)
1401  break;
1402  if (i < cl_size)
1403  continue;
1404  GNUNET_array_append (cl,
1405  cl_size,
1406  m->ch);
1407 
1408  msize = size;
1409  msize += path_length * sizeof (struct GNUNET_PeerIdentity);
1410  env = GNUNET_MQ_msg_extra (mmsg,
1411  msize,
1413  mmsg->options = htonl(options);
1414  mmsg->type = htonl(type);
1415  mmsg->hop_count = htonl(hop_count);
1416  mmsg->desired_replication_level = htonl (desired_replication_level);
1417  mmsg->put_path_length = htonl (path_length);
1418  mmsg->key = *key;
1420  msg_path = (struct GNUNET_PeerIdentity *) &mmsg[1];
1421  GNUNET_memcpy (msg_path,
1422  path,
1423  path_length * sizeof (struct GNUNET_PeerIdentity));
1424  GNUNET_memcpy (&msg_path[path_length],
1425  data,
1426  size);
1427  GNUNET_MQ_send (m->ch->mq,
1428  env);
1429  }
1430  }
1431  GNUNET_free_non_null (cl);
1432 }
1433 
1434 
1440 static void
1442 {
1443  forward_map
1445  GNUNET_YES);
1446  retry_heap
1448 }
1449 
1450 
1454 static void
1456 {
1457  if (NULL != retry_task)
1458  {
1459  GNUNET_SCHEDULER_cancel (retry_task);
1460  retry_task = NULL;
1461  }
1462 }
1463 
1464 
1471 #define GDS_DHT_SERVICE_INIT(name,run) \
1472  GNUNET_SERVICE_MAIN \
1473  (name, \
1474  GNUNET_SERVICE_OPTION_NONE, \
1475  run, \
1476  &client_connect_cb, \
1477  &client_disconnect_cb, \
1478  NULL, \
1479  GNUNET_MQ_hd_var_size (dht_local_put, \
1480  GNUNET_MESSAGE_TYPE_DHT_CLIENT_PUT, \
1481  struct GNUNET_DHT_ClientPutMessage, \
1482  NULL), \
1483  GNUNET_MQ_hd_var_size (dht_local_get, \
1484  GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET, \
1485  struct GNUNET_DHT_ClientGetMessage, \
1486  NULL), \
1487  GNUNET_MQ_hd_fixed_size (dht_local_get_stop, \
1488  GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_STOP, \
1489  struct GNUNET_DHT_ClientGetStopMessage, \
1490  NULL), \
1491  GNUNET_MQ_hd_fixed_size (dht_local_monitor, \
1492  GNUNET_MESSAGE_TYPE_DHT_MONITOR_START, \
1493  struct GNUNET_DHT_MonitorStartStopMessage, \
1494  NULL), \
1495  GNUNET_MQ_hd_fixed_size (dht_local_monitor_stop, \
1496  GNUNET_MESSAGE_TYPE_DHT_MONITOR_STOP, \
1497  struct GNUNET_DHT_MonitorStartStopMessage, \
1498  NULL), \
1499  GNUNET_MQ_hd_var_size (dht_local_get_result_seen, \
1500  GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_RESULTS_KNOWN, \
1501  struct GNUNET_DHT_ClientGetResultSeenMessage , \
1502  NULL), \
1503  GNUNET_MQ_handler_end ())
1504 
1505 
1509 void __attribute__ ((destructor))
1510 GDS_CLIENTS_done ()
1511 {
1512  if (NULL != retry_heap)
1513  {
1514  GNUNET_assert (0 == GNUNET_CONTAINER_heap_get_size (retry_heap));
1515  GNUNET_CONTAINER_heap_destroy (retry_heap);
1516  retry_heap = NULL;
1517  }
1518  if (NULL != forward_map)
1519  {
1522  forward_map = NULL;
1523  }
1524 }
1525 
1526 /* 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:340
Handle to an initialized block library.
Definition: block.c:54
uint64_t unique_id
Unique ID of the matching GET request.
Definition: dht.h:174
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:254
static char * expiration
Credential TTL.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:670
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:115
#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:163
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:395
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
Definition: w32nsp.c:83
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:259
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:245
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:298
struct ClientQueryRecord * next
Kept in a DLL with client.
struct GNUNET_HashCode key
The key of the corresponding GET request.
Definition: dht.h:405
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:194
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.
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:249
#define GNUNET_NO
Definition: gnunet_common.h:81
enum GNUNET_BLOCK_Type type
Type of the data.
int16_t get_resp
Flag whether to notify about GET_REPONSE messages.
Definition: dht.h:308
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
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:208
uint32_t desired_replication_level
Replication level for this message.
Definition: dht.h:214
Handle to a client that is connected to a service.
Definition: service.c:249
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:99
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:390
#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:204
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
#define GNUNET_memcpy(dst, src, n)
Message to monitor put requests going through peer, DHT service -> clients.
Definition: dht.h:234
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:318
#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:44
uint64_t unique_id
Unique ID identifying this request.
Definition: dht.h:136
int16_t put
Flag whether to notify about PUT messages.
Definition: dht.h:313
struct GNUNET_TIME_AbsoluteNBO expiration_time
How long should this data persist?
Definition: dht.h:270
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:287
struct GNUNET_HashCode key
The key that was searched for.
Definition: dht.h:184
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:1273
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:339
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:179
uint32_t options
Message options, actually an &#39;enum GNUNET_DHT_RouteOption&#39; value.
Definition: dht.h:209
uint32_t type
The type for the data.
Definition: dht.h:157
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:366
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:2618
#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:199
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:219
uint32_t msg_options
Any message options for this request.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
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:361
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:120
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:290
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:265
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:355
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:303
#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:224
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:169
struct GNUNET_HashCode key
Key of this request.
Definition: dht.h:63
static int monitor
Monitor ARM activity.
Definition: gnunet-arm.c:59
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:72
int GNUNET_CONTAINER_multihashmap_get_multiple(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, GNUNET_CONTAINER_HashMapIterator it, void *it_cls)
Iterate over all entries in the map that match a particular key.
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.
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:345
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:323
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:385
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:80
Message to monitor get requests going through peer, DHT service -> clients.
Definition: dht.h:330
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:350
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:400
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:244
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:1223
uint32_t data
The data value.
void * GNUNET_CONTAINER_heap_remove_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from the heap.
static size_t data_size
Number of bytes in data.
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:654
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:2533
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:375
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:275
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:147
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:131
#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:206
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:410
#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:965
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.