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 
62 
67 
72 
76  struct ClientHandle *ch;
77 
81  const void *xquery;
82 
87 
92 
98 
103 
107  uint64_t unique_id;
108 
112  size_t xquery_size;
113 
117  unsigned int seen_replies_count;
118 
122  uint32_t replication;
123 
127  uint32_t msg_options;
128 
133 };
134 
135 
144 
149 
154 
159 
163  int16_t get;
164 
168  int16_t get_resp;
169 
173  uint16_t put;
174 
178  struct ClientHandle *ch;
179 };
180 
181 
187 struct ClientHandle {
192 
197 
202 
207 };
208 
213 
218 
223 
228 
233 
238 
243 
248 
253 
254 
260 static void
262 {
263  struct ClientHandle *ch = record->ch;
264 
266  ch->cqr_tail,
267  record);
270  &record->key,
271  record));
272  if (NULL != record->hnode)
275  record->seen_replies_count,
276  0);
277  GNUNET_free(record);
278 }
279 
280 
290 static void *
293  struct GNUNET_MQ_Handle *mq)
294 {
295  struct ClientHandle *ch;
296 
297  ch = GNUNET_new(struct ClientHandle);
298  ch->client = client;
299  ch->mq = mq;
300  return ch;
301 }
302 
303 
312 static void
315  void *app_ctx)
316 {
317  struct ClientHandle *ch = app_ctx;
318  struct ClientQueryRecord *cqr;
320 
322  "Local client %p disconnects\n",
323  ch);
324  monitor = monitor_head;
325  while (NULL != monitor)
326  {
327  if (monitor->ch == ch)
328  {
329  struct ClientMonitorRecord *next;
330 
331  next = monitor->next;
332  GNUNET_free_non_null(monitor->key);
333  GNUNET_CONTAINER_DLL_remove(monitor_head,
334  monitor_tail,
335  monitor);
336  GNUNET_free(monitor);
337  monitor = next;
338  }
339  else
340  {
341  monitor = monitor->next;
342  }
343  }
344  while (NULL != (cqr = ch->cqr_head))
346  GNUNET_free(ch);
347 }
348 
349 
355 static void
357 {
358  struct GNUNET_BLOCK_Group *bg;
359  struct GNUNET_CONTAINER_BloomFilter *peer_bf;
360 
361  GNUNET_STATISTICS_update(GDS_stats,
362  gettext_noop("# GET requests from clients injected"),
363  1,
364  GNUNET_NO);
365  bg = GNUNET_BLOCK_group_create(GDS_block_context,
366  cqr->type,
368  UINT32_MAX),
369  NULL,
370  0,
371  "seen-set-size",
372  cqr->seen_replies_count,
373  NULL);
375  cqr->seen_replies,
376  cqr->seen_replies_count);
377  peer_bf
382  "Initiating GET for %s, replication %u, already have %u replies\n",
383  GNUNET_h2s(&cqr->key),
384  cqr->replication,
385  cqr->seen_replies_count);
387  cqr->msg_options,
388  cqr->replication,
389  0 /* hop count */,
390  &cqr->key,
391  cqr->xquery,
392  cqr->xquery_size,
393  bg,
394  peer_bf);
397 
398  /* exponential back-off for retries.
399  * max GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD (15 min) */
402 }
403 
404 
412 static void
414 {
415  struct ClientQueryRecord *cqr;
416  struct GNUNET_TIME_Relative delay;
417 
418  retry_task = NULL;
419  while (NULL != (cqr = GNUNET_CONTAINER_heap_remove_root(retry_heap)))
420  {
421  cqr->hnode = NULL;
423  if (delay.rel_value_us > 0)
424  {
425  cqr->hnode
426  = GNUNET_CONTAINER_heap_insert(retry_heap,
427  cqr,
428  cqr->retry_time.abs_value_us);
429  retry_task
432  NULL);
433  return;
434  }
435  transmit_request(cqr);
436  cqr->hnode
437  = GNUNET_CONTAINER_heap_insert(retry_heap,
438  cqr,
439  cqr->retry_time.abs_value_us);
440  }
441 }
442 
443 
451 static int
453  const struct GNUNET_DHT_ClientPutMessage *dht_msg)
454 {
455  /* always well-formed */
456  return GNUNET_OK;
457 }
458 
459 
466 static void
468  const struct GNUNET_DHT_ClientPutMessage *dht_msg)
469 {
470  struct ClientHandle *ch = cls;
471  struct GNUNET_CONTAINER_BloomFilter *peer_bf;
472  uint16_t size;
473 
474  size = ntohs(dht_msg->header.size);
475  GNUNET_STATISTICS_update(GDS_stats,
476  gettext_noop("# PUT requests received from clients"),
477  1,
478  GNUNET_NO);
480  "CLIENT-PUT %s\n",
481  GNUNET_h2s_full(&dht_msg->key));
482  /* give to local clients */
484  "Handling local PUT of %u-bytes for query %s\n",
485  size - sizeof(struct GNUNET_DHT_ClientPutMessage),
486  GNUNET_h2s(&dht_msg->key));
488  &dht_msg->key,
489  0,
490  NULL,
491  0,
492  NULL,
493  ntohl(dht_msg->type),
494  size - sizeof(struct GNUNET_DHT_ClientPutMessage),
495  &dht_msg[1]);
496  /* store locally */
498  &dht_msg->key,
499  0,
500  NULL,
501  ntohl(dht_msg->type),
502  size - sizeof(struct GNUNET_DHT_ClientPutMessage),
503  &dht_msg[1]);
504  /* route to other peers */
505  peer_bf
509  GDS_NEIGHBOURS_handle_put(ntohl(dht_msg->type),
510  ntohl(dht_msg->options),
511  ntohl(dht_msg->desired_replication_level),
513  0 /* hop count */,
514  peer_bf,
515  &dht_msg->key,
516  0,
517  NULL,
518  &dht_msg[1],
519  size - sizeof(struct GNUNET_DHT_ClientPutMessage));
520  GDS_CLIENTS_process_put(ntohl(dht_msg->options),
521  ntohl(dht_msg->type),
522  0,
523  ntohl(dht_msg->desired_replication_level),
524  1,
527  &dht_msg->key,
528  &dht_msg[1],
529  size - sizeof(struct GNUNET_DHT_ClientPutMessage));
532 }
533 
534 
542 static int
544  const struct GNUNET_DHT_ClientGetMessage *get)
545 {
546  /* always well-formed */
547  return GNUNET_OK;
548 }
549 
550 
565 static void
567  enum GNUNET_BLOCK_Type type,
568  struct GNUNET_TIME_Absolute expiration_time,
569  const struct GNUNET_HashCode *key,
570  unsigned int put_path_length,
571  const struct GNUNET_PeerIdentity *put_path,
572  unsigned int get_path_length,
573  const struct GNUNET_PeerIdentity *get_path,
574  const void *data,
575  size_t data_size)
576 {
577  // FIXME: this needs some clean up: inline the function,
578  // possibly avoid even looking up the client!
579  GDS_CLIENTS_handle_reply(expiration_time,
580  key,
581  0, NULL,
582  put_path_length, put_path,
583  type,
584  data_size, data);
585 }
586 
587 
594 static void
596  const struct GNUNET_DHT_ClientGetMessage *get)
597 {
598  struct ClientHandle *ch = cls;
599  struct ClientQueryRecord *cqr;
600  size_t xquery_size;
601  const char *xquery;
602  uint16_t size;
603 
604  size = ntohs(get->header.size);
605  xquery_size = size - sizeof(struct GNUNET_DHT_ClientGetMessage);
606  xquery = (const char *)&get[1];
607  GNUNET_STATISTICS_update(GDS_stats,
609  ("# GET requests received from clients"), 1,
610  GNUNET_NO);
612  "Received GET request for %s from local client %p, xq: %.*s\n",
613  GNUNET_h2s(&get->key),
614  ch->client,
615  xquery_size,
616  xquery);
618  "CLIENT-GET %s\n",
619  GNUNET_h2s_full(&get->key));
620 
621  cqr = GNUNET_malloc(sizeof(struct ClientQueryRecord) + xquery_size);
622  cqr->key = get->key;
623  cqr->ch = ch;
624  cqr->xquery = (void *)&cqr[1];
625  GNUNET_memcpy(&cqr[1], xquery, xquery_size);
626  cqr->hnode = GNUNET_CONTAINER_heap_insert(retry_heap, cqr, 0);
629  cqr->unique_id = get->unique_id;
630  cqr->xquery_size = xquery_size;
631  cqr->replication = ntohl(get->desired_replication_level);
632  cqr->msg_options = ntohl(get->options);
633  cqr->type = ntohl(get->type);
635  ch->cqr_tail,
636  cqr);
638  &cqr->key,
639  cqr,
641  GDS_CLIENTS_process_get(ntohl(get->options),
642  ntohl(get->type),
643  0,
644  ntohl(get->desired_replication_level),
645  1,
647  &get->key);
648  /* start remote requests */
649  if (NULL != retry_task)
650  GNUNET_SCHEDULER_cancel(retry_task);
652  NULL);
653  /* perform local lookup */
654  GDS_DATACACHE_handle_get(&get->key,
655  cqr->type,
656  cqr->xquery,
657  xquery_size,
658  NULL,
660  ch);
662 }
663 
664 
673 
674  uint64_t unique_id;
675 };
676 
677 
688 static int
690  const struct GNUNET_HashCode *key,
691  void *value)
692 {
693  struct FindByUniqueIdContext *fui_ctx = cls;
694  struct ClientQueryRecord *cqr = value;
695 
696  if (cqr->unique_id != fui_ctx->unique_id)
697  return GNUNET_YES;
698  fui_ctx->cqr = cqr;
699  return GNUNET_NO;
700 }
701 
702 
710 static int
712  const struct GNUNET_DHT_ClientGetResultSeenMessage *seen)
713 {
714  uint16_t size;
715  unsigned int hash_count;
716 
717  size = ntohs(seen->header.size);
718  hash_count = (size - sizeof(struct GNUNET_DHT_ClientGetResultSeenMessage)) / sizeof(struct GNUNET_HashCode);
719  if (size != sizeof(struct GNUNET_DHT_ClientGetResultSeenMessage) + hash_count * sizeof(struct GNUNET_HashCode))
720  {
721  GNUNET_break(0);
722  return GNUNET_SYSERR;
723  }
724  return GNUNET_OK;
725 }
726 
727 
734 static void
736  const struct GNUNET_DHT_ClientGetResultSeenMessage *seen)
737 {
738  struct ClientHandle *ch = cls;
739  uint16_t size;
740  unsigned int hash_count;
741  unsigned int old_count;
742  const struct GNUNET_HashCode *hc;
743  struct FindByUniqueIdContext fui_ctx;
744  struct ClientQueryRecord *cqr;
745 
746  size = ntohs(seen->header.size);
747  hash_count = (size - sizeof(struct GNUNET_DHT_ClientGetResultSeenMessage)) / sizeof(struct GNUNET_HashCode);
748  hc = (const struct GNUNET_HashCode*)&seen[1];
749  fui_ctx.unique_id = seen->unique_id;
750  fui_ctx.cqr = NULL;
752  &seen->key,
754  &fui_ctx);
755  if (NULL == (cqr = fui_ctx.cqr))
756  {
757  GNUNET_break(0);
759  return;
760  }
761  /* finally, update 'seen' list */
762  old_count = cqr->seen_replies_count;
764  cqr->seen_replies_count,
765  cqr->seen_replies_count + hash_count);
766  GNUNET_memcpy(&cqr->seen_replies[old_count],
767  hc,
768  sizeof(struct GNUNET_HashCode) * hash_count);
769 }
770 
771 
779  struct ClientHandle *ch;
780 
784  uint64_t unique_id;
785 };
786 
787 
797 static int
799  const struct GNUNET_HashCode *key,
800  void *value)
801 {
802  const struct RemoveByUniqueIdContext *ctx = cls;
803  struct ClientQueryRecord *cqr = value;
804 
805  if (cqr->unique_id != ctx->unique_id)
806  return GNUNET_YES;
808  "Removing client %p's record for key %s (by unique id)\n",
809  ctx->ch->client,
810  GNUNET_h2s(key));
812  return GNUNET_YES;
813 }
814 
815 
824 static void
826  const struct GNUNET_DHT_ClientGetStopMessage *dht_stop_msg)
827 {
828  struct ClientHandle *ch = cls;
829  struct RemoveByUniqueIdContext ctx;
830 
831  GNUNET_STATISTICS_update(GDS_stats,
833  ("# GET STOP requests received from clients"), 1,
834  GNUNET_NO);
836  "Received GET STOP request for %s from local client %p\n",
837  GNUNET_h2s(&dht_stop_msg->key),
838  ch->client);
839  ctx.ch = ch;
840  ctx.unique_id = dht_stop_msg->unique_id;
842  &dht_stop_msg->key,
844  &ctx);
846 }
847 
848 
856 static void
859 {
860  struct ClientHandle *ch = cls;
861  struct ClientMonitorRecord *r;
862 
863  r = GNUNET_new(struct ClientMonitorRecord);
864  r->ch = ch;
865  r->type = ntohl(msg->type);
866  r->get = ntohs(msg->get);
867  r->get_resp = ntohs(msg->get_resp);
868  r->put = ntohs(msg->put);
869  if (0 == ntohs(msg->filter_key))
870  {
871  r->key = NULL;
872  }
873  else
874  {
875  r->key = GNUNET_new(struct GNUNET_HashCode);
876  GNUNET_memcpy(r->key,
877  &msg->key,
878  sizeof(struct GNUNET_HashCode));
879  }
880  GNUNET_CONTAINER_DLL_insert(monitor_head,
881  monitor_tail,
882  r);
884 }
885 
886 
893 static void
896 {
897  struct ClientHandle *ch = cls;
898  struct ClientMonitorRecord *r;
899  int keys_match;
900 
902  for (r = monitor_head; NULL != r; r = r->next)
903  {
904  if (NULL == r->key)
905  {
906  keys_match = (0 == ntohs(msg->filter_key));
907  }
908  else
909  {
910  keys_match = ((0 != ntohs(msg->filter_key)) &&
911  (!memcmp(r->key,
912  &msg->key,
913  sizeof(struct GNUNET_HashCode))));
914  }
915  if ((ch == r->ch) &&
916  (ntohl(msg->type) == r->type) &&
917  (r->get == msg->get) &&
918  (r->get_resp == msg->get_resp) &&
919  (r->put == msg->put) &&
920  keys_match)
921  {
922  GNUNET_CONTAINER_DLL_remove(monitor_head,
923  monitor_tail,
924  r);
926  GNUNET_free(r);
927  return; /* Delete only ONE entry */
928  }
929  }
930 }
931 
932 
941 
946 
951 
955  const void *data;
956 
960  size_t data_size;
961 
965  unsigned int get_path_length;
966 
970  unsigned int put_path_length;
971 
976 };
977 
978 
990 static int
991 forward_reply(void *cls,
992  const struct GNUNET_HashCode *key,
993  void *value)
994 {
995  struct ForwardReplyContext *frc = cls;
996  struct ClientQueryRecord *record = value;
997  struct GNUNET_MQ_Envelope *env;
998  struct GNUNET_DHT_ClientResultMessage *reply;
1000  int do_free;
1001  struct GNUNET_HashCode ch;
1002  struct GNUNET_PeerIdentity *paths;
1003 
1005  "CLIENT-RESULT %s\n",
1006  GNUNET_h2s_full(key));
1007  if ((record->type != GNUNET_BLOCK_TYPE_ANY) &&
1008  (record->type != frc->type))
1009  {
1011  "Record type mismatch, not passing request for key %s to local client\n",
1012  GNUNET_h2s(key));
1013  GNUNET_STATISTICS_update(GDS_stats,
1014  gettext_noop
1015  ("# Key match, type mismatches in REPLY to CLIENT"),
1016  1, GNUNET_NO);
1017  return GNUNET_YES; /* type mismatch */
1018  }
1019  GNUNET_CRYPTO_hash(frc->data, frc->data_size, &ch);
1020  for (unsigned int i = 0; i < record->seen_replies_count; i++)
1021  if (0 == memcmp(&record->seen_replies[i],
1022  &ch,
1023  sizeof(struct GNUNET_HashCode)))
1024  {
1026  "Duplicate reply, not passing request for key %s to local client\n",
1027  GNUNET_h2s(key));
1028  GNUNET_STATISTICS_update(GDS_stats,
1029  gettext_noop
1030  ("# Duplicate REPLIES to CLIENT request dropped"),
1031  1, GNUNET_NO);
1032  return GNUNET_YES; /* duplicate */
1033  }
1034  eval
1035  = GNUNET_BLOCK_evaluate(GDS_block_context,
1036  record->type,
1037  NULL,
1039  key,
1040  record->xquery,
1041  record->xquery_size,
1042  frc->data,
1043  frc->data_size);
1045  "Evaluation result is %d for key %s for local client's query\n",
1046  (int)eval,
1047  GNUNET_h2s(key));
1048  switch (eval)
1049  {
1051  do_free = GNUNET_YES;
1052  break;
1053 
1056  record->seen_replies_count,
1057  ch);
1058  do_free = GNUNET_NO;
1059  break;
1060 
1062  /* should be impossible to encounter here */
1063  GNUNET_break(0);
1064  return GNUNET_YES;
1065 
1067  GNUNET_break_op(0);
1068  return GNUNET_NO;
1069 
1071  GNUNET_break(0);
1072  return GNUNET_NO;
1073 
1075  GNUNET_break(0);
1076  return GNUNET_NO;
1077 
1079  return GNUNET_YES;
1080 
1083  _("Unsupported block type (%u) in request!\n"), record->type);
1084  return GNUNET_NO;
1085 
1086  default:
1087  GNUNET_break(0);
1088  return GNUNET_NO;
1089  }
1090  GNUNET_STATISTICS_update(GDS_stats,
1091  gettext_noop("# RESULTS queued for clients"),
1092  1,
1093  GNUNET_NO);
1094  env = GNUNET_MQ_msg_extra(reply,
1095  frc->data_size +
1096  (frc->get_path_length + frc->put_path_length) * sizeof(struct GNUNET_PeerIdentity),
1098  reply->type = htonl(frc->type);
1099  reply->get_path_length = htonl(frc->get_path_length);
1100  reply->put_path_length = htonl(frc->put_path_length);
1101  reply->unique_id = record->unique_id;
1103  reply->key = *key;
1104  paths = (struct GNUNET_PeerIdentity *)&reply[1];
1105  GNUNET_memcpy(paths,
1106  frc->put_path,
1107  sizeof(struct GNUNET_PeerIdentity) * frc->put_path_length);
1108  GNUNET_memcpy(&paths[frc->put_path_length],
1109  frc->get_path,
1110  sizeof(struct GNUNET_PeerIdentity) * frc->get_path_length);
1111  GNUNET_memcpy(&paths[frc->get_path_length + frc->put_path_length],
1112  frc->data,
1113  frc->data_size);
1115  "Sending reply to query %s for client %p\n",
1116  GNUNET_h2s(key),
1117  record->ch->client);
1118  GNUNET_MQ_send(record->ch->mq,
1119  env);
1120  if (GNUNET_YES == do_free)
1121  remove_client_record(record);
1122  return GNUNET_YES;
1123 }
1124 
1125 
1141 void
1143  const struct GNUNET_HashCode *key,
1144  unsigned int get_path_length,
1145  const struct GNUNET_PeerIdentity *get_path,
1146  unsigned int put_path_length,
1147  const struct GNUNET_PeerIdentity *put_path,
1148  enum GNUNET_BLOCK_Type type,
1149  size_t data_size,
1150  const void *data)
1151 {
1152  struct ForwardReplyContext frc;
1153  size_t msize;
1154 
1155  msize = sizeof(struct GNUNET_DHT_ClientResultMessage) + data_size +
1156  (get_path_length + put_path_length) * sizeof(struct GNUNET_PeerIdentity);
1157  if (msize >= GNUNET_MAX_MESSAGE_SIZE)
1158  {
1159  GNUNET_break(0);
1160  return;
1161  }
1162  if (NULL == GNUNET_CONTAINER_multihashmap_get(forward_map,
1163  key))
1164  {
1166  "No matching client for reply for key %s\n",
1167  GNUNET_h2s(key));
1168  GNUNET_STATISTICS_update(GDS_stats,
1169  gettext_noop("# REPLIES ignored for CLIENTS (no match)"),
1170  1,
1171  GNUNET_NO);
1172  return; /* no matching request, fast exit! */
1173  }
1174  frc.expiration = expiration;
1175  frc.get_path = get_path;
1176  frc.put_path = put_path;
1177  frc.data = data;
1178  frc.data_size = data_size;
1179  frc.get_path_length = get_path_length;
1180  frc.put_path_length = put_path_length;
1181  frc.type = type;
1183  "Forwarding reply for key %s to client\n",
1184  GNUNET_h2s(key));
1186  key,
1187  &forward_reply,
1188  &frc);
1189 }
1190 
1191 
1204 void
1206  enum GNUNET_BLOCK_Type type,
1207  uint32_t hop_count,
1208  uint32_t desired_replication_level,
1209  unsigned int path_length,
1210  const struct GNUNET_PeerIdentity *path,
1211  const struct GNUNET_HashCode * key)
1212 {
1213  struct ClientMonitorRecord *m;
1214  struct ClientHandle **cl;
1215  unsigned int cl_size;
1216 
1217  cl = NULL;
1218  cl_size = 0;
1219  for (m = monitor_head; NULL != m; m = m->next)
1220  {
1221  if (((GNUNET_BLOCK_TYPE_ANY == m->type) ||
1222  (m->type == type)) &&
1223  ((NULL == m->key) ||
1224  (0 == memcmp(key,
1225  m->key,
1226  sizeof(struct GNUNET_HashCode)))))
1227  {
1228  struct GNUNET_MQ_Envelope *env;
1229  struct GNUNET_DHT_MonitorGetMessage *mmsg;
1230  struct GNUNET_PeerIdentity *msg_path;
1231  size_t msize;
1232  unsigned int i;
1233 
1234  /* Don't send duplicates */
1235  for (i = 0; i < cl_size; i++)
1236  if (cl[i] == m->ch)
1237  break;
1238  if (i < cl_size)
1239  continue;
1241  cl_size,
1242  m->ch);
1243 
1244  msize = path_length * sizeof(struct GNUNET_PeerIdentity);
1245  env = GNUNET_MQ_msg_extra(mmsg,
1246  msize,
1248  mmsg->options = htonl(options);
1249  mmsg->type = htonl(type);
1250  mmsg->hop_count = htonl(hop_count);
1251  mmsg->desired_replication_level = htonl(desired_replication_level);
1252  mmsg->get_path_length = htonl(path_length);
1253  mmsg->key = *key;
1254  msg_path = (struct GNUNET_PeerIdentity *)&mmsg[1];
1255  GNUNET_memcpy(msg_path,
1256  path,
1257  path_length * sizeof(struct GNUNET_PeerIdentity));
1258  GNUNET_MQ_send(m->ch->mq,
1259  env);
1260  }
1261  }
1263 }
1264 
1265 
1280 void
1282  const struct GNUNET_PeerIdentity *get_path,
1283  unsigned int get_path_length,
1284  const struct GNUNET_PeerIdentity *put_path,
1285  unsigned int put_path_length,
1286  struct GNUNET_TIME_Absolute exp,
1287  const struct GNUNET_HashCode * key,
1288  const void *data,
1289  size_t size)
1290 {
1291  struct ClientMonitorRecord *m;
1292  struct ClientHandle **cl;
1293  unsigned int cl_size;
1294 
1295  cl = NULL;
1296  cl_size = 0;
1297  for (m = monitor_head; NULL != m; m = m->next)
1298  {
1299  if ((GNUNET_BLOCK_TYPE_ANY == m->type || m->type == type) &&
1300  (NULL == m->key ||
1301  memcmp(key, m->key, sizeof(struct GNUNET_HashCode)) == 0))
1302  {
1303  struct GNUNET_MQ_Envelope *env;
1304  struct GNUNET_DHT_MonitorGetRespMessage *mmsg;
1305  struct GNUNET_PeerIdentity *path;
1306  size_t msize;
1307  unsigned int i;
1308 
1309  /* Don't send duplicates */
1310  for (i = 0; i < cl_size; i++)
1311  if (cl[i] == m->ch)
1312  break;
1313  if (i < cl_size)
1314  continue;
1316  cl_size,
1317  m->ch);
1318 
1319  msize = size;
1320  msize += (get_path_length + put_path_length)
1321  * sizeof(struct GNUNET_PeerIdentity);
1322  env = GNUNET_MQ_msg_extra(mmsg,
1323  msize,
1325  mmsg->type = htonl(type);
1326  mmsg->put_path_length = htonl(put_path_length);
1327  mmsg->get_path_length = htonl(get_path_length);
1329  mmsg->key = *key;
1330  path = (struct GNUNET_PeerIdentity *)&mmsg[1];
1331  GNUNET_memcpy(path,
1332  put_path,
1333  put_path_length * sizeof(struct GNUNET_PeerIdentity));
1334  GNUNET_memcpy(path,
1335  get_path,
1336  get_path_length * sizeof(struct GNUNET_PeerIdentity));
1337  GNUNET_memcpy(&path[get_path_length],
1338  data,
1339  size);
1340  GNUNET_MQ_send(m->ch->mq,
1341  env);
1342  }
1343  }
1345 }
1346 
1347 
1363 void
1365  enum GNUNET_BLOCK_Type type,
1366  uint32_t hop_count,
1367  uint32_t desired_replication_level,
1368  unsigned int path_length,
1369  const struct GNUNET_PeerIdentity *path,
1370  struct GNUNET_TIME_Absolute exp,
1371  const struct GNUNET_HashCode *key,
1372  const void *data,
1373  size_t size)
1374 {
1375  struct ClientMonitorRecord *m;
1376  struct ClientHandle **cl;
1377  unsigned int cl_size;
1378 
1379  cl = NULL;
1380  cl_size = 0;
1381  for (m = monitor_head; NULL != m; m = m->next)
1382  {
1383  if ((GNUNET_BLOCK_TYPE_ANY == m->type || m->type == type) &&
1384  (NULL == m->key ||
1385  memcmp(key, m->key, sizeof(struct GNUNET_HashCode)) == 0))
1386  {
1387  struct GNUNET_MQ_Envelope *env;
1388  struct GNUNET_DHT_MonitorPutMessage *mmsg;
1389  struct GNUNET_PeerIdentity *msg_path;
1390  size_t msize;
1391  unsigned int i;
1392 
1393  /* Don't send duplicates */
1394  for (i = 0; i < cl_size; i++)
1395  if (cl[i] == m->ch)
1396  break;
1397  if (i < cl_size)
1398  continue;
1400  cl_size,
1401  m->ch);
1402 
1403  msize = size;
1404  msize += path_length * sizeof(struct GNUNET_PeerIdentity);
1405  env = GNUNET_MQ_msg_extra(mmsg,
1406  msize,
1408  mmsg->options = htonl(options);
1409  mmsg->type = htonl(type);
1410  mmsg->hop_count = htonl(hop_count);
1411  mmsg->desired_replication_level = htonl(desired_replication_level);
1412  mmsg->put_path_length = htonl(path_length);
1413  mmsg->key = *key;
1415  msg_path = (struct GNUNET_PeerIdentity *)&mmsg[1];
1416  GNUNET_memcpy(msg_path,
1417  path,
1418  path_length * sizeof(struct GNUNET_PeerIdentity));
1419  GNUNET_memcpy(&msg_path[path_length],
1420  data,
1421  size);
1422  GNUNET_MQ_send(m->ch->mq,
1423  env);
1424  }
1425  }
1427 }
1428 
1429 
1435 static void
1437 {
1438  forward_map
1440  GNUNET_YES);
1441  retry_heap
1443 }
1444 
1445 
1449 static void
1451 {
1452  if (NULL != retry_task)
1453  {
1454  GNUNET_SCHEDULER_cancel(retry_task);
1455  retry_task = NULL;
1456  }
1457 }
1458 
1459 
1466 #define GDS_DHT_SERVICE_INIT(name, run) \
1467  GNUNET_SERVICE_MAIN \
1468  (name, \
1469  GNUNET_SERVICE_OPTION_NONE, \
1470  run, \
1471  &client_connect_cb, \
1472  &client_disconnect_cb, \
1473  NULL, \
1474  GNUNET_MQ_hd_var_size(dht_local_put, \
1475  GNUNET_MESSAGE_TYPE_DHT_CLIENT_PUT, \
1476  struct GNUNET_DHT_ClientPutMessage, \
1477  NULL), \
1478  GNUNET_MQ_hd_var_size(dht_local_get, \
1479  GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET, \
1480  struct GNUNET_DHT_ClientGetMessage, \
1481  NULL), \
1482  GNUNET_MQ_hd_fixed_size(dht_local_get_stop, \
1483  GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_STOP, \
1484  struct GNUNET_DHT_ClientGetStopMessage, \
1485  NULL), \
1486  GNUNET_MQ_hd_fixed_size(dht_local_monitor, \
1487  GNUNET_MESSAGE_TYPE_DHT_MONITOR_START, \
1488  struct GNUNET_DHT_MonitorStartStopMessage, \
1489  NULL), \
1490  GNUNET_MQ_hd_fixed_size(dht_local_monitor_stop, \
1491  GNUNET_MESSAGE_TYPE_DHT_MONITOR_STOP, \
1492  struct GNUNET_DHT_MonitorStartStopMessage, \
1493  NULL), \
1494  GNUNET_MQ_hd_var_size(dht_local_get_result_seen, \
1495  GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_RESULTS_KNOWN, \
1496  struct GNUNET_DHT_ClientGetResultSeenMessage, \
1497  NULL), \
1498  GNUNET_MQ_handler_end())
1499 
1500 
1504 void __attribute__ ((destructor))
1505 GDS_CLIENTS_done()
1506 {
1507  if (NULL != retry_heap)
1508  {
1510  GNUNET_CONTAINER_heap_destroy(retry_heap);
1511  retry_heap = NULL;
1512  }
1513  if (NULL != forward_map)
1514  {
1517  forward_map = NULL;
1518  }
1519 }
1520 
1521 /* 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:326
Handle to an initialized block library.
Definition: block.c:53
uint64_t unique_id
Unique ID of the matching GET request.
Definition: dht.h:167
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:243
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:671
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:111
#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:156
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:379
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:114
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:248
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 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:285
struct ClientQueryRecord * next
Kept in a DLL with client.
struct GNUNET_HashCode key
The key of the corresponding GET request.
Definition: dht.h:389
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:186
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:238
#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:295
#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:205
Handle to a client that is connected to a service.
Definition: service.c:246
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:57
uint32_t put_path_length
Length of the PUT path that follows (if tracked).
Definition: dht.h:374
#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:195
#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:224
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:305
#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:131
int16_t put
Flag whether to notify about PUT messages.
Definition: dht.h:300
struct GNUNET_TIME_AbsoluteNBO expiration_time
How long should this data persist?
Definition: dht.h:259
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:275
struct GNUNET_HashCode key
The key that was searched for.
Definition: dht.h:177
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:1264
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:337
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:172
uint32_t options
Message options, actually an &#39;enum GNUNET_DHT_RouteOption&#39; value.
Definition: dht.h:200
uint32_t type
The type for the data.
Definition: dht.h:150
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:352
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:2315
#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:190
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:210
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:66
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:347
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:115
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:288
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:254
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:341
Allow multiple values with the same key.
Handle to a message queue.
Definition: mq.c:84
struct ClientQueryRecord * cqr
Where to store the result, if found.
int16_t get
Flag whether to notify about GET messages.
Definition: dht.h:290
#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:215
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:162
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:62
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:83
#define LOG_TRAFFIC(kind,...)
Should routing details be logged to stderr (for debugging)?
DHT GET message sent from clients to service.
Definition: dht.h:70
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:131
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:331
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:310
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:369
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:317
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:351
uint32_t hop_count
Hop count.
Definition: dht.h:336
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:384
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:233
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:1214
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:655
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:2234
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:360
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:264
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:141
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:126
#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:204
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:408
#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:956
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.