GNUnet 0.28.0-dev.5-89-ga1e177ed4
 
Loading...
Searching...
No Matches
gnunet-service-dht_clients.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009-2011, 2016-2017, 2022, 2026 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 "gnunet_pils_service.h"
29#include "gnunet_util_lib.h"
30
37#define SANITY_CHECKS 0
38
42#define LOG_TRAFFIC(kind, ...) GNUNET_log_from (kind, "dht-traffic", \
43 __VA_ARGS__)
44
45#define LOG(kind, ...) GNUNET_log_from (kind, "dht-clients", __VA_ARGS__)
46
47
53struct ClientHandle;
54
55
137
138
143{
148
153
158
163
168
172 int16_t get;
173
177 int16_t get_resp;
178
182 uint16_t put;
183
184};
185
186
214
215
220
225
230
235
240
245
250
255
260
265
266
272static void
274{
275 struct ClientHandle *ch = record->ch;
276
278 ch->cqr_tail,
279 record);
282 &record->key,
283 record));
284 if (NULL != record->hnode)
286 GNUNET_array_grow (record->seen_replies,
287 record->seen_replies_count,
288 0);
290}
291
292
302static void *
305 struct GNUNET_MQ_Handle *mq)
306{
307 struct ClientHandle *ch;
308
309 (void) cls;
310 ch = GNUNET_new (struct ClientHandle);
311 ch->client = client;
312 ch->mq = mq;
313 return ch;
314}
315
316
325static void
328 void *app_ctx)
329{
330 struct ClientHandle *ch = app_ctx;
331
332 (void) cls;
333 (void) client;
335 "Local client %p disconnects\n",
336 ch);
337 {
339
341 NULL != monitor;
342 monitor = next)
343 {
344 next = monitor->next;
345 if (monitor->ch != ch)
346 continue;
349 monitor);
351 }
352 }
353
354 {
355 struct ClientQueryRecord *cqr;
356
357 while (NULL != (cqr = ch->cqr_head))
359 }
360 GNUNET_free (ch);
361}
362
363
371static void
373{
374 struct GNUNET_BLOCK_Group *bg;
375 struct GNUNET_CONTAINER_BloomFilter *peer_bf;
376
378 "# GET requests from clients injected",
379 1,
380 GNUNET_NO);
382 cqr->type,
383 NULL, /* raw data */
384 0, /* raw data size */
385 "seen-set-size",
387 NULL);
389 cqr->seen_replies,
390 cqr->seen_replies_count);
391 peer_bf
396 "Initiating GET for %s, replication %u, already have %u replies\n",
397 GNUNET_h2s (&cqr->key),
398 cqr->replication,
399 cqr->seen_replies_count);
401 cqr->msg_options,
402 cqr->replication,
403 0 /* hop count */,
404 &cqr->key,
405 cqr->xquery,
406 cqr->xquery_size,
407 bg,
408 peer_bf);
411
412 /* Exponential back-off for retries.
413 * max. is #GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD (15 min) */
416}
417
418
426static void
428{
429 struct ClientQueryRecord *cqr;
430
431 (void) cls;
432 retry_task = NULL;
433 while (NULL != (cqr = GNUNET_CONTAINER_heap_remove_root (retry_heap)))
434 {
435 cqr->hnode = NULL;
437 {
438 cqr->hnode
440 cqr,
445 NULL);
446 return;
447 }
448 transmit_request (cqr);
449 cqr->hnode
451 cqr,
453 }
454}
455
456
466 const struct GNUNET_DHT_ClientPutMessage *dht_msg)
467{
468 uint32_t replication_level = ntohl (dht_msg->desired_replication_level);
469
470 (void) cls;
472 {
473 GNUNET_break_op (0);
474 return GNUNET_SYSERR;
475 }
476 return GNUNET_OK;
477}
478
479
480static void
482 enum GNUNET_GenericReturnValue forwarded)
483{
484 if (GNUNET_OK != forwarded)
485 {
487 "# Local PUT requests not routed",
488 1,
489 GNUNET_NO);
490 }
491}
492
493
500static void
502 const struct GNUNET_DHT_ClientPutMessage *dht_msg)
503{
504 struct ClientHandle *ch = cls;
505 uint16_t size = ntohs (dht_msg->header.size);
506 uint32_t replication_level
507 = ntohl (dht_msg->desired_replication_level);
508 struct GNUNET_DATACACHE_Block bd = {
509 .key = dht_msg->key,
510 .expiration_time = GNUNET_TIME_absolute_ntoh (dht_msg->expiration),
511 .data = &dht_msg[1],
512 .data_size = size - sizeof (*dht_msg),
513 .type = ntohl (dht_msg->type),
514 .ro = ntohl (dht_msg->options)
515 };
516
518 "Handling local PUT of %lu-bytes for query %s of type %u\n",
519 (unsigned long) (size - sizeof(struct GNUNET_DHT_ClientPutMessage)),
520 GNUNET_h2s (&dht_msg->key),
521 (unsigned int) bd.type);
523 {
524 /* Without our own identity we can neither decide whether to store
525 this block nor route it: GDS_am_closest_peer(),
526 GDS_DATACACHE_handle_put() and GDS_NEIGHBOURS_handle_put() all
527 require it. Should not happen -- the service stays suspended
528 until PILS answers -- but drop the request rather than abort. */
529 GNUNET_break (0);
531 "# PUT requests dropped (no identity yet)",
532 1,
533 GNUNET_NO);
535 return;
536 }
537#if SANITY_CHECKS > 0
538 if (GNUNET_OK !=
540 bd.type,
541 bd.data,
542 bd.data_size))
543 {
544 GNUNET_break (0);
545 return;
546 }
547#endif
549 "# PUT requests received from clients",
550 1,
551 GNUNET_NO);
553 "CLIENT-PUT %s\n",
554 GNUNET_h2s_full (&dht_msg->key));
555 /* give to local clients */
557 &bd.key,
558 0, NULL /* get path */));
559
560 {
561 struct GNUNET_CONTAINER_BloomFilter *peer_bf;
562
563 peer_bf
567 /* store locally */
568 if ( (0 != (bd.ro & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) ||
569 (GDS_am_closest_peer (&dht_msg->key,
570 peer_bf)))
572 /* route to other peers */
575 0 /* hop count */,
576 peer_bf,
578 NULL);
580 }
582 &bd,
583 0, /* hop count */
586}
587
588
595static void
597 const struct GNUNET_DATACACHE_Block *bd)
598{
600 "Datacache provided result for query key %s\n",
601 GNUNET_h2s (&bd->key));
603 &bd->key,
604 0, NULL /* get_path */));
605}
606
607
617 const struct GNUNET_DHT_ClientGetMessage *get)
618{
619 (void) cls;
620 (void) get;
621 /* always well-formed */
622 return GNUNET_OK;
623}
624
625
632static void
634 const struct GNUNET_DHT_ClientGetMessage *get)
635{
636 struct ClientHandle *ch = cls;
637 struct ClientQueryRecord *cqr;
638 uint16_t size = ntohs (get->header.size);
639 const char *xquery = (const char *) &get[1];
640 size_t xquery_size = size - sizeof(struct GNUNET_DHT_ClientGetMessage);
641
643 "Received GET request for %s from local client %p, xq: %.*s\n",
644 GNUNET_h2s (&get->key),
645 ch->client,
646 (int) xquery_size,
647 xquery);
649 "# GET requests received from clients",
650 1,
651 GNUNET_NO);
653 "CLIENT-GET %s\n",
654 GNUNET_h2s_full (&get->key));
656 {
657 /* GDS_NEIGHBOURS_handle_get() requires our identity. Should not
658 happen -- the service stays suspended until PILS answers -- but
659 drop the request rather than abort. */
660 GNUNET_break (0);
662 "# GET requests dropped (no identity yet)",
663 1,
664 GNUNET_NO);
666 return;
667 }
668
669 cqr = GNUNET_malloc (sizeof(struct ClientQueryRecord) + xquery_size);
670 cqr->key = get->key;
671 cqr->ch = ch;
672 cqr->xquery = (const void *) &cqr[1];
673 GNUNET_memcpy (&cqr[1],
674 xquery,
675 xquery_size);
677 cqr,
678 0);
681 cqr->unique_id = get->unique_id;
682 cqr->xquery_size = xquery_size;
683 cqr->replication = ntohl (get->desired_replication_level);
684 cqr->msg_options = ntohl (get->options);
685 cqr->type = ntohl (get->type);
687 ch->cqr_tail,
688 cqr);
690 &cqr->key,
691 cqr,
694 cqr->type,
695 0, /* hop count */
696 cqr->replication,
697 &get->key);
698 /* start remote requests */
699 if (NULL != retry_task)
702 NULL);
703 /* perform local lookup */
705 cqr->type,
706 cqr->xquery,
707 xquery_size,
708 NULL,
710 ch);
712}
713
714
719{
724
728 uint64_t unique_id;
729};
730
731
744 const struct GNUNET_HashCode *key,
745 void *value)
746{
747 struct FindByUniqueIdContext *fui_ctx = cls;
748 struct ClientQueryRecord *cqr = value;
749
750 if (cqr->unique_id != fui_ctx->unique_id)
751 return GNUNET_YES;
752 fui_ctx->cqr = cqr;
753 return GNUNET_NO;
754}
755
756
766 void *cls,
767 const struct GNUNET_DHT_ClientGetResultSeenMessage *seen)
768{
769 uint16_t size = ntohs (seen->header.size);
770 unsigned int hash_count =
771 (size - sizeof(*seen))
772 / sizeof(struct GNUNET_HashCode);
773
774 if (size != sizeof(*seen) + hash_count * sizeof(struct GNUNET_HashCode))
775 {
776 GNUNET_break (0);
777 return GNUNET_SYSERR;
778 }
779 return GNUNET_OK;
780}
781
782
789static void
791 void *cls,
792 const struct GNUNET_DHT_ClientGetResultSeenMessage *seen)
793{
794 struct ClientHandle *ch = cls;
795 uint16_t size = ntohs (seen->header.size);
796 unsigned int hash_count = (size - sizeof(*seen))
797 / sizeof(struct GNUNET_HashCode);
798 const struct GNUNET_HashCode *hc = (const struct GNUNET_HashCode*) &seen[1];
799 struct FindByUniqueIdContext fui_ctx = {
800 .unique_id = seen->unique_id
801 };
802 unsigned int old_count;
803 struct ClientQueryRecord *cqr;
804
806 &seen->key,
808 &fui_ctx);
809 if (NULL == (cqr = fui_ctx.cqr))
810 {
811 GNUNET_break (0);
813 return;
814 }
815 /* finally, update 'seen' list */
816 old_count = cqr->seen_replies_count;
819 cqr->seen_replies_count + hash_count);
820 GNUNET_memcpy (&cqr->seen_replies[old_count],
821 hc,
822 sizeof(struct GNUNET_HashCode) * hash_count);
823}
824
825
830{
835
839 uint64_t unique_id;
840};
841
842
854 const struct GNUNET_HashCode *key,
855 void *value)
856{
857 const struct RemoveByUniqueIdContext *ctx = cls;
858 struct ClientQueryRecord *cqr = value;
859
860 if (cqr->unique_id != ctx->unique_id)
861 return GNUNET_YES;
863 "Removing client %p's record for key %s (by unique id)\n",
864 ctx->ch->client,
865 GNUNET_h2s (key));
867 return GNUNET_YES;
868}
869
870
879static void
881 void *cls,
882 const struct GNUNET_DHT_ClientGetStopMessage *dht_stop_msg)
883{
884 struct ClientHandle *ch = cls;
886
888 "# GET STOP requests received from clients",
889 1,
890 GNUNET_NO);
892 "Received GET STOP request for %s from local client %p\n",
893 GNUNET_h2s (&dht_stop_msg->key),
894 ch->client);
895 ctx.ch = ch;
896 ctx.unique_id = dht_stop_msg->unique_id;
898 &dht_stop_msg->key,
900 &ctx);
902}
903
904
909{
914
919
923 unsigned int get_path_length;
924
925};
926
927
940forward_reply (void *cls,
941 const struct GNUNET_HashCode *query_hash,
942 void *value)
943{
944 struct ForwardReplyContext *frc = cls;
946 const struct GNUNET_DATACACHE_Block *bd = frc->bd;
947 struct GNUNET_MQ_Envelope *env;
948 struct GNUNET_DHT_ClientResultMessage *reply;
950 bool do_free;
951 struct GNUNET_HashCode ch;
952 struct GNUNET_DHT_PathElement *paths;
953 bool truncated = (0 != (bd->ro & GNUNET_DHT_RO_TRUNCATED));
954 size_t xsize = bd->data_size;
955
957 "CLIENT-RESULT %s\n",
958 GNUNET_h2s_full (&bd->key));
959 if ( (record->type != GNUNET_BLOCK_TYPE_ANY) &&
960 (record->type != bd->type) )
961 {
963 "Record type mismatch, not passing request for key %s to local client\n",
964 GNUNET_h2s (&bd->key));
966 "# Key match, type mismatches in REPLY to CLIENT",
967 1,
968 GNUNET_NO);
969 return GNUNET_YES; /* type mismatch */
970 }
971 if ( (0 == (record->msg_options & GNUNET_DHT_RO_FIND_APPROXIMATE)) &&
972 (0 != GNUNET_memcmp (&bd->key,
973 query_hash)) )
974 {
976 "# Inexact key match, but exact match required",
977 1,
978 GNUNET_NO);
979 return GNUNET_YES; /* type mismatch */
980 }
982 bd->data_size,
983 &ch);
984 for (unsigned int i = 0; i < record->seen_replies_count; i++)
985 if (0 ==
986 GNUNET_memcmp (&record->seen_replies[i],
987 &ch))
988 {
990 "Duplicate reply, not passing request for key %s to local client\n",
991 GNUNET_h2s (&bd->key));
993 "# Duplicate REPLIES to CLIENT request dropped",
994 1,
995 GNUNET_NO);
996 return GNUNET_YES; /* duplicate */
997 }
998 eval
1000 record->type,
1001 NULL,
1002 &bd->key,
1003 record->xquery,
1004 record->xquery_size,
1005 bd->data,
1006 bd->data_size);
1008 "Evaluation result is %d for key %s for local client's query\n",
1009 (int) eval,
1010 GNUNET_h2s (&bd->key));
1011 switch (eval)
1012 {
1014 do_free = true;
1015 break;
1018 GNUNET_array_append (record->seen_replies,
1019 record->seen_replies_count,
1020 ch);
1021 do_free = false;
1022 break;
1024 /* should be impossible to encounter here */
1025 GNUNET_break (0);
1026 return GNUNET_YES;
1028 return GNUNET_YES;
1029 default:
1030 GNUNET_break (0);
1031 return GNUNET_NO;
1032 }
1034 "# RESULTS queued for clients",
1035 1,
1036 GNUNET_NO);
1037 xsize += (frc->get_path_length + bd->put_path_length)
1038 * sizeof(struct GNUNET_DHT_PathElement);
1039 if (truncated)
1040 xsize += sizeof (struct GNUNET_PeerIdentity);
1041
1042#if SUPER_REDUNDANT_CHECK
1043 {
1044 const struct GNUNET_PeerIdentity *my_identity;
1046 GNUNET_assert (NULL != my_identity);
1047 GNUNET_break (0 ==
1049 bd->data_size,
1050 bd->expiration_time,
1051 truncated
1052 ? &bd->trunc_peer
1053 : NULL,
1054 bd->put_path,
1055 bd->put_path_length,
1056 frc->get_path,
1057 frc->get_path_length,
1058 my_identity));
1059 }
1060#endif
1061
1062 env = GNUNET_MQ_msg_extra (reply,
1063 xsize,
1065 reply->type = htonl (bd->type);
1066 reply->options = htonl (bd->ro);
1067 reply->get_path_length = htonl (frc->get_path_length);
1068 reply->put_path_length = htonl (bd->put_path_length);
1069 reply->unique_id = record->unique_id;
1071 reply->key = *query_hash;
1072 if (truncated)
1073 {
1074 void *tgt = &reply[1];
1075
1076 GNUNET_memcpy (tgt,
1077 &bd->trunc_peer,
1078 sizeof (struct GNUNET_PeerIdentity));
1079 paths = (struct GNUNET_DHT_PathElement *)
1080 (tgt + sizeof (struct GNUNET_PeerIdentity));
1081 }
1082 else
1083 {
1084 paths = (struct GNUNET_DHT_PathElement *) &reply[1];
1085 }
1086 GNUNET_memcpy (paths,
1087 bd->put_path,
1088 sizeof(struct GNUNET_DHT_PathElement)
1089 * bd->put_path_length);
1090 GNUNET_memcpy (&paths[bd->put_path_length],
1091 frc->get_path,
1092 sizeof(struct GNUNET_DHT_PathElement)
1093 * frc->get_path_length);
1094 GNUNET_memcpy (&paths[frc->get_path_length + bd->put_path_length],
1095 bd->data,
1096 bd->data_size);
1098 "Sending reply to query %s for client %p\n",
1099 GNUNET_h2s (query_hash),
1100 record->ch->client);
1101 GNUNET_MQ_send (record->ch->mq,
1102 env);
1103 if (GNUNET_YES == do_free)
1105 return GNUNET_YES;
1106}
1107
1108
1109bool
1111 const struct GNUNET_HashCode *query_hash,
1112 unsigned int get_path_length,
1113 const struct GNUNET_DHT_PathElement *get_path)
1114{
1115 struct ForwardReplyContext frc;
1116 size_t msize = sizeof (struct GNUNET_DHT_ClientResultMessage)
1117 + bd->data_size
1119 * sizeof(struct GNUNET_DHT_PathElement);
1120#if SANITY_CHECKS > 1
1121 bool truncated = (0 != (bd->ro & GNUNET_DHT_RO_TRUNCATED));
1122#endif
1123
1124 if (msize >= GNUNET_MAX_MESSAGE_SIZE)
1125 {
1126 GNUNET_break (0);
1127 return false;
1128 }
1129#if SANITY_CHECKS > 1
1130 {
1131 const struct GNUNET_PeerIdentity *my_identity;
1133 GNUNET_assert (NULL != my_identity);
1134 if (0 !=
1136 bd->data_size,
1137 bd->expiration_time,
1138 truncated
1139 ? &bd->trunc_peer
1140 : NULL,
1141 bd->put_path,
1142 bd->put_path_length,
1143 get_path,
1144 get_path_length,
1145 my_identity))
1146 {
1147 GNUNET_break (0);
1148 return false;
1149 }
1150 }
1151#endif
1152 frc.bd = bd;
1153 frc.get_path = get_path;
1154 frc.get_path_length = get_path_length;
1156 "Forwarding reply for query hash %s with GPL %u and PPL %u to client\n",
1157 GNUNET_h2s (query_hash),
1158 get_path_length,
1159 bd->put_path_length);
1160 if (0 ==
1162 query_hash,
1164 &frc))
1165 {
1167 "No matching client for reply for query %s\n",
1168 GNUNET_h2s (query_hash));
1170 "# REPLIES ignored for CLIENTS (no match)",
1171 1,
1172 GNUNET_NO);
1173 }
1174 return true;
1175}
1176
1177
1178/* **************** HELLO logic ***************** */
1179
1180
1189static void
1191 const struct GNUNET_MessageHeader *msg)
1192{
1193 struct ClientHandle *ch = cls;
1194 const struct GNUNET_PeerIdentity *my_identity;
1195 struct GNUNET_HELLO_Parser *p;
1196 struct GNUNET_MessageHeader *hdr;
1197 struct GNUNET_MQ_Envelope *env;
1198
1200
1201 if (NULL != GDS_my_hello)
1203 else
1204 p = NULL;
1205
1207 "Handling request from local client for my HELLO\n");
1208
1209 if (NULL != p)
1210 {
1211 char *url;
1212 size_t slen;
1213
1215 slen = strlen (url) + 1;
1216
1217 env = GNUNET_MQ_msg_extra (hdr,
1218 slen,
1220 memcpy (&hdr[1],
1221 url,
1222 slen);
1223 GNUNET_free (url);
1225 }
1226 else
1227 {
1229 ;
1230 }
1231
1233 env);
1235}
1236
1237
1245static enum GNUNET_GenericReturnValue
1247 const struct GNUNET_MessageHeader *hdr)
1248{
1249 uint16_t len = ntohs (hdr->size);
1250 const char *buf = (const char *) &hdr[1];
1251
1252 (void) cls;
1253 if ('\0' != buf[len - sizeof (*hdr) - 1])
1254 {
1255 GNUNET_break (0);
1256 return GNUNET_SYSERR;
1257 }
1258 return GNUNET_OK;
1259}
1260
1261
1269static void
1271 const struct GNUNET_MessageHeader *msg)
1272{
1273 struct ClientHandle *ch = cls;
1274 const char *url = (const char *) &msg[1];
1275 struct GNUNET_HELLO_Parser *b;
1276
1278 "Local client provided HELLO URL %s\n",
1279 url);
1281 if (NULL == b)
1282 {
1283 GNUNET_break (0);
1285 return;
1286 }
1290 NULL);
1292}
1293
1294
1295/* ************* logic for monitors ************** */
1296
1297
1305static void
1308{
1309 struct ClientHandle *ch = cls;
1310 struct ClientMonitorRecord *r;
1311
1312 r = GNUNET_new (struct ClientMonitorRecord);
1313 r->ch = ch;
1314 r->type = ntohl (msg->type);
1315 r->get = ntohs (msg->get);
1316 r->get_resp = ntohs (msg->get_resp);
1317 r->put = ntohs (msg->put);
1318 if (0 != ntohs (msg->filter_key))
1319 r->key = msg->key;
1322 r);
1324}
1325
1326
1333static void
1335 void *cls,
1337{
1338 struct ClientHandle *ch = cls;
1339
1341 for (struct ClientMonitorRecord *r = monitor_head;
1342 NULL != r;
1343 r = r->next)
1344 {
1345 bool keys_match;
1346
1347 keys_match =
1348 (GNUNET_is_zero (&r->key))
1349 ? (0 == ntohs (msg->filter_key))
1350 : ( (0 != ntohs (msg->filter_key)) &&
1351 (! GNUNET_memcmp (&r->key,
1352 &msg->key)) );
1353 if ( (ch == r->ch) &&
1354 (ntohl (msg->type) == r->type) &&
1355 (r->get == msg->get) &&
1356 (r->get_resp == msg->get_resp) &&
1357 (r->put == msg->put) &&
1358 keys_match)
1359 {
1362 r);
1363 GNUNET_free (r);
1364 return; /* Delete only ONE entry */
1365 }
1366 }
1367}
1368
1369
1376typedef void
1377(*MonitorAction)(void *cls,
1378 struct ClientMonitorRecord *m);
1379
1380
1390static void
1392 const struct GNUNET_HashCode *key,
1393 MonitorAction cb,
1394 void *cb_cls)
1395{
1396 struct ClientHandle **cl = NULL;
1397 unsigned int cl_size = 0;
1398
1399 for (struct ClientMonitorRecord *m = monitor_head;
1400 NULL != m;
1401 m = m->next)
1402 {
1403 bool found = false;
1404
1405 if ( (GNUNET_BLOCK_TYPE_ANY != m->type) &&
1406 (m->type != type) )
1407 continue;
1408 if ( (! GNUNET_is_zero (&m->key)) &&
1409 (0 ==
1411 &m->key)) )
1412 continue;
1413 /* Don't send duplicates */
1414 for (unsigned i = 0; i < cl_size; i++)
1415 if (cl[i] == m->ch)
1416 {
1417 found = true;
1418 break;
1419 }
1420 if (found)
1421 continue;
1423 cl_size,
1424 m->ch);
1425 cb (cb_cls,
1426 m);
1427 }
1428 GNUNET_free (cl);
1429}
1430
1431
1444
1445
1453static void
1454get_action (void *cls,
1455 struct ClientMonitorRecord *m)
1456{
1457 struct GetActionContext *gac = cls;
1458 struct GNUNET_MQ_Envelope *env;
1459 struct GNUNET_DHT_MonitorGetMessage *mmsg;
1460
1461 env = GNUNET_MQ_msg (mmsg,
1463 mmsg->options = htonl (gac->options);
1464 mmsg->type = htonl (gac->type);
1465 mmsg->hop_count = htonl (gac->hop_count);
1467 mmsg->key = *gac->key;
1468 GNUNET_MQ_send (m->ch->mq,
1469 env);
1470}
1471
1472
1473void
1476 uint32_t hop_count,
1478 const struct GNUNET_HashCode *key)
1479{
1480 struct GetActionContext gac = {
1481 .options = options,
1482 .type = type,
1483 .hop_count = hop_count,
1484 .desired_replication_level = desired_replication_level,
1485 .key = key
1486 };
1487
1489 key,
1490 &get_action,
1491 &gac);
1492}
1493
1494
1504
1505
1513static void
1515 struct ClientMonitorRecord *m)
1516{
1517 const struct ResponseActionContext *resp_ctx = cls;
1518 const struct GNUNET_DATACACHE_Block *bd = resp_ctx->bd;
1519 bool truncated = (0 != (bd->ro & GNUNET_DHT_RO_TRUNCATED));
1520 struct GNUNET_MQ_Envelope *env;
1522 struct GNUNET_DHT_PathElement *path;
1523 size_t msize;
1524
1525 msize = bd->data_size;
1526 msize += (resp_ctx->get_path_length + bd->put_path_length)
1527 * sizeof(struct GNUNET_DHT_PathElement);
1528 if (truncated)
1529 msize += sizeof (struct GNUNET_PeerIdentity);
1530 env = GNUNET_MQ_msg_extra (mmsg,
1531 msize,
1533 mmsg->type = htonl (bd->type);
1534 mmsg->put_path_length = htonl (bd->put_path_length);
1535 mmsg->get_path_length = htonl (resp_ctx->get_path_length);
1537 mmsg->key = bd->key;
1538 if (truncated)
1539 {
1540 void *tgt = &mmsg[1];
1541
1542 GNUNET_memcpy (tgt,
1543 &bd->trunc_peer,
1544 sizeof (struct GNUNET_PeerIdentity));
1545 path = (struct GNUNET_DHT_PathElement *)
1546 (tgt + sizeof (struct GNUNET_PeerIdentity));
1547 }
1548 else
1549 {
1550 path = (struct GNUNET_DHT_PathElement *) &mmsg[1];
1551 }
1552 GNUNET_memcpy (path,
1553 bd->put_path,
1554 bd->put_path_length * sizeof(struct GNUNET_DHT_PathElement));
1555 GNUNET_memcpy (path,
1556 resp_ctx->get_path,
1557 resp_ctx->get_path_length
1558 * sizeof(struct GNUNET_DHT_PathElement));
1559 GNUNET_memcpy (&path[resp_ctx->get_path_length],
1560 bd->data,
1561 bd->data_size);
1562 GNUNET_MQ_send (m->ch->mq,
1563 env);
1564}
1565
1566
1567void
1569 const struct GNUNET_DHT_PathElement *get_path,
1570 unsigned int get_path_length)
1571{
1572 struct ResponseActionContext rac = {
1573 .bd = bd,
1574 .get_path = get_path,
1575 .get_path_length = get_path_length
1576 };
1577
1579 &bd->key,
1581 &rac);
1582}
1583
1584
1594
1595
1603static void
1604put_action (void *cls,
1605 struct ClientMonitorRecord *m)
1606{
1607 const struct PutActionContext *put_ctx = cls;
1608 const struct GNUNET_DATACACHE_Block *bd = put_ctx->bd;
1609 bool truncated = (0 != (bd->ro & GNUNET_DHT_RO_TRUNCATED));
1610 struct GNUNET_MQ_Envelope *env;
1611 struct GNUNET_DHT_MonitorPutMessage *mmsg;
1612 struct GNUNET_DHT_PathElement *msg_path;
1613 size_t msize;
1614
1615 msize = bd->data_size
1616 + bd->put_path_length
1617 * sizeof(struct GNUNET_DHT_PathElement);
1618 if (truncated)
1619 msize += sizeof (struct GNUNET_PeerIdentity);
1620 env = GNUNET_MQ_msg_extra (mmsg,
1621 msize,
1623 mmsg->options = htonl (bd->ro);
1624 mmsg->type = htonl (bd->type);
1625 mmsg->hop_count = htonl (put_ctx->hop_count);
1627 mmsg->put_path_length = htonl (bd->put_path_length);
1628 mmsg->key = bd->key;
1630 if (truncated)
1631 {
1632 void *tgt = &mmsg[1];
1633
1634 GNUNET_memcpy (tgt,
1635 &bd->trunc_peer,
1636 sizeof (struct GNUNET_PeerIdentity));
1637 msg_path = (struct GNUNET_DHT_PathElement *)
1638 (tgt + sizeof (struct GNUNET_PeerIdentity));
1639 }
1640 else
1641 {
1642 msg_path = (struct GNUNET_DHT_PathElement *) &mmsg[1];
1643 }
1644 GNUNET_memcpy (msg_path,
1645 bd->put_path,
1646 bd->put_path_length * sizeof(struct GNUNET_DHT_PathElement));
1647 GNUNET_memcpy (&msg_path[bd->put_path_length],
1648 bd->data,
1649 bd->data_size);
1650 GNUNET_MQ_send (m->ch->mq,
1651 env);
1652}
1653
1654
1655void
1657 uint32_t hop_count,
1658 uint32_t desired_replication_level)
1659{
1660 struct PutActionContext put_ctx = {
1661 .bd = bd,
1662 .hop_count = hop_count,
1663 .desired_replication_level = desired_replication_level
1664 };
1665
1667 &bd->key,
1668 &put_action,
1669 &put_ctx);
1670}
1671
1672
1673/* ********************** Initialization logic ***************** */
1674
1675
1679void
1688
1689
1693void
1695{
1696 if (NULL != retry_task)
1697 {
1699 retry_task = NULL;
1700 }
1701}
1702
1703
1710#define GDS_DHT_SERVICE_INIT(name, run) \
1711 GNUNET_SERVICE_MAIN \
1712 (GNUNET_OS_project_data_gnunet (), \
1713 name, \
1714 GNUNET_SERVICE_OPTION_NONE, \
1715 run, \
1716 &client_connect_cb, \
1717 &client_disconnect_cb, \
1718 NULL, \
1719 GNUNET_MQ_hd_var_size (dht_local_put, \
1720 GNUNET_MESSAGE_TYPE_DHT_CLIENT_PUT, \
1721 struct GNUNET_DHT_ClientPutMessage, \
1722 NULL), \
1723 GNUNET_MQ_hd_var_size (dht_local_get, \
1724 GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET, \
1725 struct GNUNET_DHT_ClientGetMessage, \
1726 NULL), \
1727 GNUNET_MQ_hd_fixed_size (dht_local_get_stop, \
1728 GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_STOP, \
1729 struct GNUNET_DHT_ClientGetStopMessage, \
1730 NULL), \
1731 GNUNET_MQ_hd_fixed_size (dht_local_monitor, \
1732 GNUNET_MESSAGE_TYPE_DHT_MONITOR_START, \
1733 struct GNUNET_DHT_MonitorStartStopMessage, \
1734 NULL), \
1735 GNUNET_MQ_hd_fixed_size (dht_local_monitor_stop, \
1736 GNUNET_MESSAGE_TYPE_DHT_MONITOR_STOP, \
1737 struct GNUNET_DHT_MonitorStartStopMessage, \
1738 NULL), \
1739 GNUNET_MQ_hd_var_size (dht_local_get_result_seen, \
1740 GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_RESULTS_KNOWN, \
1741 struct GNUNET_DHT_ClientGetResultSeenMessage, \
1742 NULL), \
1743 GNUNET_MQ_hd_fixed_size (dht_local_hello_get, \
1744 GNUNET_MESSAGE_TYPE_DHT_CLIENT_HELLO_GET, \
1745 struct GNUNET_MessageHeader, \
1746 NULL), \
1747 GNUNET_MQ_hd_var_size (dht_local_hello_offer, \
1748 GNUNET_MESSAGE_TYPE_DHT_CLIENT_HELLO_URL, \
1749 struct GNUNET_MessageHeader, \
1750 NULL), \
1751 GNUNET_MQ_handler_end ())
1752
1754
1758void __attribute__ ((destructor))
1759GDS_CLIENTS_done (void)
1760{
1761 if (NULL != retry_heap)
1762 {
1765 retry_heap = NULL;
1766 }
1767 if (NULL != forward_map)
1768 {
1771 forward_map = NULL;
1772 }
1773}
1774
1775
1776/* end of gnunet-service-dht_clients.c */
struct GNUNET_GETOPT_CommandLineOption options[]
Definition 002.c:5
struct GNUNET_MessageHeader * msg
Definition 005.c:2
struct GNUNET_MQ_Envelope * env
Definition 005.c:1
#define DHT_BLOOM_SIZE
Size of the bloom filter the DHT uses to filter peers.
Definition dht.h:34
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition gnunet-arm.c:103
static int monitor
Monitor ARM activity.
Definition gnunet-arm.c:63
static unsigned int replication_level
Replication level option to use for publishing.
static struct GNUNET_CADET_Channel * ch
Channel handle.
static void record(void *cls, size_t data_size, const void *data)
Process recorded audio data.
struct GNUNET_HashCode key
The key used in the DHT.
static int get
Get DID Documement for DID Flag.
Definition gnunet-did.c:63
static struct GNUNET_FS_Handle * ctx
static char * value
Value of the record to add/remove.
static uint32_t type
Type string converted to DNS type value.
static size_t data_size
Number of bytes in data.
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
struct GNUNET_MessageHeader * GDS_my_hello
Our HELLO.
static void transmit_request(struct ClientQueryRecord *cqr)
Route the given request via the DHT.
void GDS_CLIENTS_process_get(enum GNUNET_DHT_RouteOption options, enum GNUNET_BLOCK_Type type, uint32_t hop_count, uint32_t desired_replication_level, const struct GNUNET_HashCode *key)
Check if some client is monitoring GET messages and notify them in that case.
static void handle_dht_local_get_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...
struct GNUNET_PILS_Handle * GDS_pils
Handle for the pils service.
void GDS_CLIENTS_process_get_resp(const struct GNUNET_DATACACHE_Block *bd, const struct GNUNET_DHT_PathElement *get_path, unsigned int get_path_length)
Check if some client is monitoring GET RESP messages and notify them in that case.
static struct ClientMonitorRecord * monitor_head
List of active monitoring requests.
static enum GNUNET_GenericReturnValue forward_reply(void *cls, const struct GNUNET_HashCode *query_hash, void *value)
Iterator over hash map entries that send a given reply to each of the matching clients.
static void handle_dht_local_get(void *cls, const struct GNUNET_DHT_ClientGetMessage *get)
Handler for DHT GET messages from the client.
static enum GNUNET_GenericReturnValue find_by_unique_id(void *cls, const struct GNUNET_HashCode *key, void *value)
Function called for each existing DHT record for the given query.
static enum GNUNET_GenericReturnValue remove_by_unique_id(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator over hash map entries that frees all entries that match the given client and unique ID.
static void response_action(void *cls, struct ClientMonitorRecord *m)
Function called on monitors that match a response.
void GDS_CLIENTS_init(void)
Initialize client subsystem.
static struct GNUNET_CONTAINER_Heap * retry_heap
Heap with all of our client's request, sorted by retry time (earliest on top).
struct GNUNET_STATISTICS_Handle * GDS_stats
Handle for the statistics service.
static struct GNUNET_SCHEDULER_Task * retry_task
Task that re-transmits requests (using retry_heap).
static void handle_dht_local_hello_get(void *cls, const struct GNUNET_MessageHeader *msg)
Handler for HELLO GET message.
static void handle_dht_local_monitor_stop(void *cls, const struct GNUNET_DHT_MonitorStartStopMessage *msg)
Handler for monitor stop messages.
static void handle_dht_local_get_result_seen(void *cls, const struct GNUNET_DHT_ClientGetResultSeenMessage *seen)
Handler for "GET result seen" messages from the client.
static void cb_forwarded_dht_local_put(void *cls, enum GNUNET_GenericReturnValue forwarded)
static struct GNUNET_CONTAINER_MultiHashMap * forward_map
Hashmap for fast key based lookup, maps keys to struct ClientQueryRecord entries.
static void handle_dht_local_monitor(void *cls, const struct GNUNET_DHT_MonitorStartStopMessage *msg)
Handler for monitor start messages.
void GDS_CLIENTS_done(void)
static void handle_local_result(void *cls, const struct GNUNET_DATACACHE_Block *bd)
Handle a result from local datacache for a GET operation.
struct GNUNET_BLOCK_Context * GDS_block_context
Our handle to the BLOCK library.
struct GNUNET_SERVICE_Handle * GDS_service
Handle for the service.
static void * 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.
void GDS_CLIENTS_process_put(const struct GNUNET_DATACACHE_Block *bd, uint32_t hop_count, uint32_t desired_replication_level)
Check if some client is monitoring PUT messages and notify them in that case.
static enum GNUNET_GenericReturnValue check_dht_local_hello_offer(void *cls, const struct GNUNET_MessageHeader *hdr)
Process a client HELLO message received from the service.
static enum GNUNET_GenericReturnValue check_dht_local_put(void *cls, const struct GNUNET_DHT_ClientPutMessage *dht_msg)
Check DHT PUT messages from the client.
static void for_matching_monitors(enum GNUNET_BLOCK_Type type, const struct GNUNET_HashCode *key, MonitorAction cb, void *cb_cls)
Call cb on all monitors that watch for blocks of type and key key.
bool GDS_CLIENTS_handle_reply(const struct GNUNET_DATACACHE_Block *bd, const struct GNUNET_HashCode *query_hash, unsigned int get_path_length, const struct GNUNET_DHT_PathElement *get_path)
Handle a reply we've received from another peer.
static void handle_dht_local_put(void *cls, const struct GNUNET_DHT_ClientPutMessage *dht_msg)
Handler for PUT messages.
static struct ClientMonitorRecord * monitor_tail
List of active monitoring requests.
#define LOG(kind,...)
void GDS_CLIENTS_stop(void)
Shutdown client subsystem.
static enum GNUNET_GenericReturnValue check_dht_local_get(void *cls, const struct GNUNET_DHT_ClientGetMessage *get)
Check DHT GET messages from the client.
static void handle_dht_local_hello_offer(void *cls, const struct GNUNET_MessageHeader *msg)
Handler for HELLO OFFER message.
#define LOG_TRAFFIC(kind,...)
Should routing details be logged to stderr (for debugging)?
static enum GNUNET_GenericReturnValue check_dht_local_get_result_seen(void *cls, const struct GNUNET_DHT_ClientGetResultSeenMessage *seen)
Check "GET result seen" messages from the client.
static void transmit_next_request_task(void *cls)
Task that looks at the retry_heap and transmits all of the requests on the heap that are ready for tr...
static void client_disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *client, void *app_ctx)
Functions with this signature are called whenever a client is disconnected on the network level.
static void put_action(void *cls, struct ClientMonitorRecord *m)
Function called on monitors that match a PUT.
static void remove_client_query_record(struct ClientQueryRecord *record)
Free data structures associated with the given query.
static void get_action(void *cls, struct ClientMonitorRecord *m)
Function called on monitors that match a GET.
const struct GNUNET_CONFIGURATION_Handle * GDS_cfg
The configuration the DHT service is running with.
void(* MonitorAction)(void *cls, struct ClientMonitorRecord *m)
Function to call by for_matching_monitors().
enum GNUNET_BLOCK_ReplyEvaluationResult GDS_DATACACHE_handle_get(const struct GNUNET_HashCode *key, enum GNUNET_BLOCK_Type type, const void *xquery, size_t xquery_size, struct GNUNET_BLOCK_Group *bg, GDS_DATACACHE_GetCallback gc, void *gc_cls)
Handle a GET request we've received from another peer.
void GDS_DATACACHE_handle_put(const struct GNUNET_DATACACHE_Block *bd)
Handle a datum we've received from another peer.
void GDS_try_connect(void *cls, const struct GNUNET_PeerIdentity *pid, const char *uri)
Callback function used to extract URIs from a builder.
enum GNUNET_GenericReturnValue GDS_am_closest_peer(const struct GNUNET_HashCode *key, const struct GNUNET_CONTAINER_BloomFilter *bloom)
Check whether my identity is closer than any known peers.
enum GNUNET_GenericReturnValue GDS_NEIGHBOURS_handle_get(enum GNUNET_BLOCK_Type type, enum GNUNET_DHT_RouteOption options, uint16_t desired_replication_level, uint16_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.
void GDS_NEIGHBOURS_handle_put(const struct GNUNET_DATACACHE_Block *bd, uint16_t desired_replication_level, uint16_t hop_count, struct GNUNET_CONTAINER_BloomFilter *bf, GDS_PutOperationCallback cb, void *cb_cls)
Perform a PUT operation.
static struct GNUNET_Process * p
Helper process we started.
Definition gnunet-uri.c:38
GNUNET_BLOCK_Type
WARNING: This header is generated! In order to add DHT block types, you must register them in GANA,...
@ GNUNET_BLOCK_TYPE_ANY
Identifier for any block.
const struct GNUNET_PeerIdentity * GNUNET_PILS_get_identity(const struct GNUNET_PILS_Handle *handle)
Return the current peer identity of a given handle.
Definition pils_api.c:875
struct GNUNET_PQ_ResultSpec __attribute__
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
enum GNUNET_GenericReturnValue GNUNET_BLOCK_group_set_seen(struct GNUNET_BLOCK_Group *bg, const struct GNUNET_HashCode *seen_results, unsigned int seen_results_count)
Update block group to filter out the given results.
Definition block.c:365
enum GNUNET_BLOCK_ReplyEvaluationResult GNUNET_BLOCK_check_reply(struct GNUNET_BLOCK_Context *ctx, enum GNUNET_BLOCK_Type type, struct GNUNET_BLOCK_Group *group, const struct GNUNET_HashCode *query, const void *xquery, size_t xquery_size, const void *reply_block, size_t reply_block_size)
Function called to validate if a reply is good for a particular query.
Definition block.c:339
enum GNUNET_GenericReturnValue GNUNET_BLOCK_check_block(struct GNUNET_BLOCK_Context *ctx, enum GNUNET_BLOCK_Type type, const void *block, size_t block_size)
Function called to validate a block.
Definition block.c:321
GNUNET_BLOCK_ReplyEvaluationResult
Possible ways for how a block may relate to a query.
void GNUNET_BLOCK_group_destroy(struct GNUNET_BLOCK_Group *bg)
Destroy resources used by a block group.
Definition block.c:194
struct GNUNET_BLOCK_Group * GNUNET_BLOCK_group_create(struct GNUNET_BLOCK_Context *ctx, enum GNUNET_BLOCK_Type type, const void *raw_data, size_t raw_data_size,...)
Create a new block group.
Definition block.c:249
@ GNUNET_BLOCK_REPLY_OK_MORE
Valid result, and there may be more.
@ GNUNET_BLOCK_REPLY_OK_DUPLICATE
Valid result, but suppressed because it is a duplicate.
@ GNUNET_BLOCK_REPLY_OK_LAST
Last possible valid result.
@ GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED
Specified block type not supported by any plugin.
@ GNUNET_BLOCK_REPLY_IRRELEVANT
Block does not match xquery (valid result, not relevant for the 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.
void GNUNET_CONTAINER_bloomfilter_free(struct GNUNET_CONTAINER_BloomFilter *bf)
Free the space associated with a filter in memory, flush to drive if needed (do not free the space on...
#define GNUNET_CONSTANTS_BLOOMFILTER_K
K-value that must be used for the bloom filters in 'GET' queries.
GNUNET_DHT_RouteOption
Options for routing.
#define GNUNET_DHT_MAXIMUM_REPLICATION_LEVEL
Maximum allowed replication level for all requests.
unsigned int GNUNET_DHT_verify_path(const void *data, size_t data_size, struct GNUNET_TIME_Absolute exp_time, const struct GNUNET_PeerIdentity *trunc_peer, const struct GNUNET_DHT_PathElement *put_path, unsigned int put_path_len, const struct GNUNET_DHT_PathElement *get_path, unsigned int get_path_len, const struct GNUNET_PeerIdentity *me)
Verify signatures on a path consisting of put_path and get_path in reverse order (starting at the las...
Definition dht_api.c:1354
@ GNUNET_DHT_RO_TRUNCATED
Flag set if the path was truncated.
@ GNUNET_DHT_RO_FIND_APPROXIMATE
Approximate results are fine.
@ GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE
Each peer along the way should process the request (otherwise only peers locally closest to the key w...
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition crypto_hash.c:40
enum GNUNET_GenericReturnValue 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.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_get_multiple(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map that match a particular key.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE
Allow multiple values with the same key.
void * GNUNET_CONTAINER_heap_remove_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from the heap.
void * GNUNET_CONTAINER_heap_remove_root(struct GNUNET_CONTAINER_Heap *heap)
Remove root of the heap.
struct GNUNET_CONTAINER_HeapNode * GNUNET_CONTAINER_heap_insert(struct GNUNET_CONTAINER_Heap *heap, void *element, GNUNET_CONTAINER_HeapCostType cost)
Inserts a new element into the heap.
unsigned int GNUNET_CONTAINER_heap_get_size(const struct GNUNET_CONTAINER_Heap *heap)
Get the current size of the heap.
struct GNUNET_CONTAINER_Heap * GNUNET_CONTAINER_heap_create(enum GNUNET_CONTAINER_HeapOrder order)
Create a new heap.
void GNUNET_CONTAINER_heap_destroy(struct GNUNET_CONTAINER_Heap *heap)
Destroys the heap.
@ GNUNET_CONTAINER_HEAP_ORDER_MIN
Heap with the minimum cost at the root.
void GNUNET_HELLO_parser_free(struct GNUNET_HELLO_Parser *parser)
Release resources of a builder.
Definition hello-uri.c:380
char * GNUNET_HELLO_parser_to_url(const struct GNUNET_HELLO_Parser *parser)
Generate GNUnet HELLO URI from a parser.
Definition hello-uri.c:859
const struct GNUNET_PeerIdentity * GNUNET_HELLO_parser_iterate(const struct GNUNET_HELLO_Parser *parser, GNUNET_HELLO_UriCallback uc, void *uc_cls)
Iterate over URIs in a parser.
Definition hello-uri.c:1031
struct GNUNET_HELLO_Parser * GNUNET_HELLO_parser_from_msg(const struct GNUNET_MessageHeader *msg, const struct GNUNET_PeerIdentity *pid)
Parse msg.
Definition hello-uri.c:416
struct GNUNET_HELLO_Parser * GNUNET_HELLO_parser_from_url(const char *url)
Parse GNUnet HELLO url.
Definition hello-uri.c:719
#define GNUNET_is_zero(a)
Check that memory in a is all zeros.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_log(kind,...)
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
const char * GNUNET_h2s_full(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_array_append(arr, len, element)
Append an element to an array (growing the array by one).
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition mq.c:337
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET
Receive information about transiting GETs.
#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET_RESP
Receive information about transiting GET responses.
#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT
Receive information about transiting PUTs.
#define GNUNET_MESSAGE_TYPE_DHT_CLIENT_RESULT
Service returns result to client.
#define GNUNET_MESSAGE_TYPE_DHT_CLIENT_HELLO_URL
HELLO URL send between client and service (in either direction).
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:1260
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:986
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:1310
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition service.c:2463
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition service.c:2434
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
#define GNUNET_TIME_UNIT_SECONDS
One second.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition time.c:111
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition time.c:737
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:316
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition time.c:636
bool GNUNET_TIME_absolute_is_past(struct GNUNET_TIME_Absolute abs)
Test if abs is truly in the past (excluding now).
Definition time.c:667
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
static unsigned int size
Size of the "table".
Definition peer.c:68
static struct GNUNET_MQ_Handle * mq
Our connection to the resolver service, created on-demand, but then persists until error or shutdown.
Struct containing information about a client, handle to connect to it, and any pending messages that ...
struct ClientQueryRecord * cqr_tail
Linked list of active queries of this client.
struct GNUNET_SERVICE_Client * client
The handle to this client.
struct GNUNET_MQ_Handle * mq
The message queue to this client.
struct ClientQueryRecord * cqr_head
Linked list of active queries of this client.
Struct containing parameters of monitoring requests.
struct ClientMonitorRecord * next
Next element in DLL.
uint16_t put
Flag whether to notify about PUT messages.
struct ClientMonitorRecord * prev
Previous element in DLL.
struct ClientHandle * ch
Client to notify of these requests.
enum GNUNET_BLOCK_Type type
Type of blocks that are of interest.
int16_t get
Flag whether to notify about GET messages.
struct GNUNET_HashCode key
Key of data of interest.
int16_t get_resp
Flag whether to notify about GET_REPONSE messages.
Entry in the local forwarding map for a client's GET request.
unsigned int seen_replies_count
Number of entries in seen_replies.
size_t xquery_size
Number of bytes in xquery.
struct GNUNET_TIME_Relative retry_frequency
What's the delay between re-try operations that we currently use for this request?
struct ClientQueryRecord * prev
Kept in a DLL with client.
struct GNUNET_CONTAINER_HeapNode * hnode
Pointer to this nodes heap location in the retry-heap (for fast removal)
struct ClientHandle * ch
Client responsible for the request.
struct GNUNET_HashCode * seen_replies
Array of (hashes of) replies we have already seen for this request.
uint64_t unique_id
The unique identifier of this request.
enum GNUNET_DHT_RouteOption msg_options
Any message options for this request.
struct GNUNET_HashCode key
The key this request was about.
enum GNUNET_BLOCK_Type type
The type for the data for the GET request.
const void * xquery
Extended query (see gnunet_block_lib.h), allocated at the end of this struct.
struct GNUNET_TIME_Absolute retry_time
What's the next time we should re-try this request?
struct ClientQueryRecord * next
Kept in a DLL with client.
uint32_t replication
Desired replication level.
Closure for find_by_unique_id().
uint64_t unique_id
Unique ID to look for.
struct ClientQueryRecord * cqr
Where to store the result, if found.
Closure for forward_reply()
const struct GNUNET_DATACACHE_Block * bd
Block details.
const struct GNUNET_DHT_PathElement * get_path
GET path taken.
unsigned int get_path_length
Number of entries in get_path.
struct GNUNET_MQ_Handle * mq
Our control connection to the ARM service.
Handle to an initialized block library.
Definition block.c:55
struct GNUNET_MQ_Handle * mq
Message Queue for the channel (which we are implementing).
Definition cadet.h:142
Handle to a node in a heap.
Internal representation of the hash map.
Information about a block stored in the datacache.
const struct GNUNET_DHT_PathElement * put_path
PUT path taken by the block, array of peer identities.
enum GNUNET_BLOCK_Type type
Type of the block.
const void * data
Actual block data.
enum GNUNET_DHT_RouteOption ro
Options for routing for the block.
struct GNUNET_PeerIdentity trunc_peer
If the path was truncated, this is the peer ID at which the path was truncated.
struct GNUNET_HashCode key
Key of the block.
size_t data_size
Number of bytes in data.
unsigned int put_path_length
Length of the put_path array.
struct GNUNET_TIME_Absolute expiration_time
When does the block expire?
DHT GET message sent from clients to service.
Definition dht.h:72
DHT GET RESULTS KNOWN message sent from clients to service.
Definition dht.h:114
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_RESULTS_KNOWN.
Definition dht.h:118
struct GNUNET_HashCode key
The key we are searching for (to make it easy to find the corresponding GET inside the service).
Definition dht.h:129
uint64_t unique_id
Unique ID identifying this request.
Definition dht.h:134
Message which indicates the DHT should cancel outstanding requests and discard any state.
Definition dht.h:44
uint64_t unique_id
Unique ID identifying this request.
Definition dht.h:58
struct GNUNET_HashCode key
Key of this request.
Definition dht.h:63
Message to insert data into the DHT, sent from clients to DHT service.
Definition dht.h:200
struct GNUNET_HashCode key
The key to store the value under.
Definition dht.h:229
uint32_t type
The type of data to insert.
Definition dht.h:209
uint32_t options
Message options, actually an 'enum GNUNET_DHT_RouteOption' value.
Definition dht.h:214
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_DHT_CLIENT_PUT.
Definition dht.h:204
uint32_t desired_replication_level
Replication level for this message.
Definition dht.h:219
struct GNUNET_TIME_AbsoluteNBO expiration
How long should this data persist?
Definition dht.h:224
Reply to a GET send from the service to a client.
Definition dht.h:144
uint32_t put_path_length
Number of peers recorded in the outgoing path from source to the storgage location of this message.
Definition dht.h:169
uint64_t unique_id
Unique ID of the matching GET request.
Definition dht.h:180
struct GNUNET_TIME_AbsoluteNBO expiration
When does this entry expire?
Definition dht.h:185
struct GNUNET_HashCode key
The key that was searched for.
Definition dht.h:190
uint32_t type
The type for the data.
Definition dht.h:153
uint32_t options
Message options, actually an 'enum GNUNET_DHT_RouteOption' value.
Definition dht.h:163
uint32_t get_path_length
The number of peer identities recorded from the storage location to this peer.
Definition dht.h:175
Message to monitor get requests going through peer, DHT service -> clients.
Definition dht.h:334
uint32_t hop_count
Hop count.
Definition dht.h:353
uint32_t options
Message options, actually an 'enum GNUNET_DHT_RouteOption' value.
Definition dht.h:343
uint32_t desired_replication_level
Replication level for this message.
Definition dht.h:358
struct GNUNET_HashCode key
The key to store the value under.
Definition dht.h:368
uint32_t type
The type of data in the request.
Definition dht.h:348
Message to monitor get results going through peer, DHT service -> clients.
Definition dht.h:377
struct GNUNET_HashCode key
The key of the corresponding GET request.
Definition dht.h:416
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the content expire?
Definition dht.h:411
uint32_t type
Content type.
Definition dht.h:386
uint32_t get_path_length
Length of the GET path that follows (if tracked).
Definition dht.h:406
uint32_t put_path_length
Length of the PUT path that follows (if tracked).
Definition dht.h:401
Message to monitor put requests going through peer, DHT service -> clients.
Definition dht.h:239
uint32_t options
Message options, actually an 'enum GNUNET_DHT_RouteOption' value.
Definition dht.h:248
struct GNUNET_TIME_AbsoluteNBO expiration_time
How long should this data persist?
Definition dht.h:274
uint32_t desired_replication_level
Replication level for this message.
Definition dht.h:263
struct GNUNET_HashCode key
The key to store the value under.
Definition dht.h:279
uint32_t hop_count
Hop count so far.
Definition dht.h:258
uint32_t type
The type of data in the request.
Definition dht.h:253
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:269
Message to request monitoring messages, clients -> DHT service.
Definition dht.h:291
A (signed) path tracking a block's flow through the DHT is represented by an array of path elements,...
Context for parsing HELLOs.
Definition hello-uri.c:233
A 512-bit hashcode.
Handle to a message queue.
Definition mq.c:87
Header for all communications.
A handle for the PILS service.
Definition pils_api.c:86
The identity of the host (wraps the signing key of the peer).
Entry in list of pending tasks.
Definition scheduler.c:141
Handle to a client that is connected to a service.
Definition service.c:249
Handle to a service.
Definition service.c:116
Handle for the service.
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.
Time for relative time used by GNUnet, in microseconds.
Closure for get_action();.
const struct GNUNET_HashCode * key
enum GNUNET_DHT_RouteOption options
struct GNUNET_PeerIdentity trunc_peer
enum GNUNET_BLOCK_Type type
Closure for put_action().
const struct GNUNET_DATACACHE_Block * bd
Closure for remove_by_unique_id().
struct ClientHandle * ch
Client that issued the removal request.
uint64_t unique_id
Unique ID of the request.
Closure for response_action().
const struct GNUNET_DHT_PathElement * get_path
const struct GNUNET_DATACACHE_Block * bd