GNUnet 0.28.0-dev.3-7-g31e20e2e6
 
Loading...
Searching...
No Matches
gnunet-service-fs_pr.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009-2013 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
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_load_lib.h"
29#include "gnunet-service-fs.h"
35
36
40#define DHT_GET_REPLICATION 5
41
47#define MAX_DATASTORE_QUEUE (16 * MAX_QUEUE_PER_PEER)
48
55#define CONTENT_BANDWIDTH_VALUE 800
56
60#define MAX_RESULTS (100 * 1024)
61
65#define INSANE_STATISTICS GNUNET_NO
66
71#define CADET_RETRY_MAX 3
72
73
199
200
206
207
212
213
218
219
229
230
236static unsigned long long max_pending_requests = (32 * 1024);
237
238
249static void
251 struct GSF_PendingRequest *pr)
252{
253 if (NULL != pr->bg)
254 {
256 pr->bg = NULL;
257 }
259 return; /* no need */
260 pr->bg =
262 type,
263 NULL,
264 0,
265 "seen-set-size",
267 NULL);
268 if (NULL == pr->bg)
269 return;
272 pr->replies_seen,
273 pr->replies_seen_count));
274}
275
276
277struct GSF_PendingRequest *
280 const struct GNUNET_HashCode *query,
281 const struct GNUNET_PeerIdentity *target,
282 const char *bf_data,
283 size_t bf_size,
284 uint32_t anonymity_level,
285 uint32_t priority,
286 int32_t ttl,
289 const struct GNUNET_HashCode *replies_seen,
290 unsigned int replies_seen_count,
292 void *rh_cls)
293{
294 struct GSF_PendingRequest *pr;
295 struct GSF_PendingRequest *dpr;
296 size_t extra;
297 struct GNUNET_HashCode *eptr;
298
300 "Creating request handle for `%s' of type %d\n",
301 GNUNET_h2s (query),
302 type);
303#if INSANE_STATISTICS
305 gettext_noop ("# Pending requests created"),
306 1,
307 GNUNET_NO);
308#endif
309 extra = 0;
310 if (NULL != target)
311 extra += sizeof(struct GNUNET_PeerIdentity);
312 pr = GNUNET_malloc (sizeof(struct GSF_PendingRequest) + extra);
313 pr->public_data.query = *query;
314 eptr = (struct GNUNET_HashCode *) &pr[1];
315 if (NULL != target)
316 {
317 pr->public_data.target = (struct GNUNET_PeerIdentity *) eptr;
318 GNUNET_memcpy (eptr, target, sizeof(struct GNUNET_PeerIdentity));
319 }
321 pr->public_data.priority = priority;
322 pr->public_data.original_priority = priority;
324 pr->public_data.type = type;
326 pr->sender_pid = sender_pid;
327 pr->origin_pid = origin_pid;
328 pr->rh = rh;
329 pr->rh_cls = rh_cls;
330 GNUNET_assert ((sender_pid != 0) || (0 == (options & GSF_PRO_FORWARD_ONLY)));
331 if (ttl >= 0)
334 else
338 (uint32_t) (-ttl)));
339 if (replies_seen_count > 0)
340 {
341 pr->replies_seen_size = replies_seen_count;
342 pr->replies_seen =
345 replies_seen,
346 replies_seen_count * sizeof(struct GNUNET_HashCode));
347 pr->replies_seen_count = replies_seen_count;
348 }
349 if ((NULL != bf_data) &&
351 {
353 pr->public_data.type,
354 bf_data,
355 bf_size,
356 "seen-set-size",
357 0,
358 NULL);
359 }
360 else if ((replies_seen_count > 0) &&
362 {
364 }
366 &pr->public_data.query,
367 pr,
370 {
372 pr,
374 /* make sure we don't track too many requests */
377 {
379 GNUNET_assert (NULL != dpr);
380 if (pr == dpr)
381 break; /* let the request live briefly... */
382 if (NULL != dpr->rh)
383 dpr->rh (dpr->rh_cls,
385 dpr,
386 UINT32_MAX,
390 NULL,
391 0);
393 }
394 }
396 gettext_noop ("# Pending requests active"),
397 1,
398 GNUNET_NO);
399 return pr;
400}
401
402
411{
412 return &pr->public_data;
413}
414
415
425int
427 struct GSF_PendingRequest *prb)
428{
429 if ((pra->public_data.type != prb->public_data.type) ||
430 (0 != memcmp (&pra->public_data.query,
431 &prb->public_data.query,
432 sizeof(struct GNUNET_HashCode))))
433 return GNUNET_NO;
434 return GNUNET_OK;
435}
436
437
438void
440 const struct GNUNET_HashCode *replies_seen,
441 unsigned int replies_seen_count)
442{
443 if (replies_seen_count + pr->replies_seen_count < pr->replies_seen_count)
444 return; /* integer overflow */
446 {
447 /* we're responsible for the BF, full refresh */
448 if (replies_seen_count + pr->replies_seen_count > pr->replies_seen_size)
451 replies_seen_count + pr->replies_seen_count);
453 replies_seen,
454 sizeof(struct GNUNET_HashCode) * replies_seen_count);
455 pr->replies_seen_count += replies_seen_count;
457 }
458 else
459 {
460 if (NULL == pr->bg)
461 {
462 /* we're not the initiator, but the initiator did not give us
463 * any bloom-filter, so we need to create one on-the-fly */
465 }
466 else
467 {
470 replies_seen,
471 pr->replies_seen_count));
472 }
473 }
474 if (NULL != pr->gh)
476 replies_seen_count,
477 replies_seen);
478}
479
480
488struct GNUNET_MQ_Envelope *
490{
491 struct GNUNET_MQ_Envelope *env;
492 struct GetMessage *gm;
493 struct GNUNET_PeerIdentity *ext;
494 unsigned int k;
495 uint32_t bm;
496 uint32_t prio;
497 size_t bf_size;
498 struct GNUNET_TIME_Absolute now;
499 int64_t ttl;
500 int do_route;
501 void *bf_data;
502
504 "Building request message for `%s' of type %d\n",
506 pr->public_data.type);
507 k = 0;
508 bm = 0;
509 do_route = (0 == (pr->public_data.options & GSF_PRO_FORWARD_ONLY));
510 if ((! do_route) && (pr->sender_pid == 0))
511 {
512 GNUNET_break (0);
513 do_route = GNUNET_YES;
514 }
515 if (! do_route)
516 {
518 k++;
519 }
520 if (NULL != pr->public_data.target)
521 {
523 k++;
524 }
525 if (GNUNET_OK !=
527 &bf_data,
528 &bf_size))
529 {
530 bf_size = 0;
531 bf_data = NULL;
532 }
534 bf_size + k * sizeof(struct GNUNET_PeerIdentity),
536 gm->type = htonl (pr->public_data.type);
537 if (do_route)
539 else
540 prio = 0;
541 pr->public_data.priority -= prio;
543 pr->public_data.respect_offered += prio;
544 gm->priority = htonl (prio);
546 ttl = (int64_t) (pr->public_data.ttl.abs_value_us - now.abs_value_us);
547 gm->ttl = htonl (ttl / 1000LL / 1000LL);
548 gm->reserved = htonl (0);
549 gm->hash_bitmap = htonl (bm);
550 gm->query = pr->public_data.query;
551 ext = (struct GNUNET_PeerIdentity *) &gm[1];
552 k = 0;
553 if (! do_route)
554 GNUNET_PEER_resolve (pr->sender_pid, &ext[k++]);
555 if (NULL != pr->public_data.target)
556 ext[k++] = *pr->public_data.target;
557 GNUNET_memcpy (&ext[k], bf_data, bf_size);
558 GNUNET_free (bf_data);
559 return env;
560}
561
562
571static int
572clean_request (void *cls, const struct GNUNET_HashCode *key, void *value)
573{
574 struct GSF_PendingRequest *pr = value;
576
578 "Cleaning up pending request for `%s'.\n",
579 GNUNET_h2s (key));
580 if (NULL != pr->cadet_request)
581 {
584 pr->cadet_request = NULL;
585 }
586 if (NULL != (cont = pr->llc_cont))
587 {
588 pr->llc_cont = NULL;
589 cont (pr->llc_cont_cls,
590 pr,
591 pr->local_result);
592 }
596 pr->bg = NULL;
598 pr->sender_pid = 0;
600 pr->origin_pid = 0;
601 if (NULL != pr->hnode)
602 {
604 pr->hnode = NULL;
605 }
606 if (NULL != pr->qe)
607 {
609 pr->qe = NULL;
610 }
611 if (NULL != pr->gh)
612 {
614 pr->gh = NULL;
615 }
616 if (NULL != pr->warn_task)
617 {
619 pr->warn_task = NULL;
620 }
622 GNUNET_OK ==
625 gettext_noop ("# Pending requests active"),
626 -1,
627 GNUNET_NO);
628 GNUNET_free (pr);
629 return GNUNET_YES;
630}
631
632
639void
641{
643
644 if (NULL == pr_map)
645 return; /* already cleaned up! */
646 if (GNUNET_NO == full_cleanup)
647 {
648 /* make request inactive (we're no longer interested in more results),
649 * but do NOT remove from our data-structures, we still need it there
650 * to prevent the request from looping */
651 pr->rh = NULL;
652 if (NULL != pr->cadet_request)
653 {
656 pr->cadet_request = NULL;
657 }
658 if (NULL != (cont = pr->llc_cont))
659 {
660 pr->llc_cont = NULL;
661 cont (pr->llc_cont_cls,
662 pr,
663 pr->local_result);
664 }
666 if (NULL != pr->qe)
667 {
669 pr->qe = NULL;
670 }
671 if (NULL != pr->gh)
672 {
674 pr->gh = NULL;
675 }
676 if (NULL != pr->warn_task)
677 {
679 pr->warn_task = NULL;
680 }
681 return;
682 }
684 clean_request (NULL, &pr->public_data.query, pr));
685}
686
687
688void
696
697
748
749
757static void
759 struct GSF_PendingRequest *pr)
760{
761 if (prq->sender == NULL)
762 return;
765 prq->priority);
766}
767
768
778process_reply (void *cls,
779 const struct GNUNET_HashCode *key,
780 void *value)
781{
782 struct ProcessReplyClosure *prq = cls;
783 struct GSF_PendingRequest *pr = value;
784 struct GNUNET_HashCode chash;
785 struct GNUNET_TIME_Absolute last_transmission;
786
787 if (NULL == pr->rh)
788 return GNUNET_YES;
790 "Matched result (type %u) for query `%s' with pending request\n",
791 (unsigned int) prq->type,
792 GNUNET_h2s (key));
794 gettext_noop ("# replies received and matched"),
795 1,
796 GNUNET_NO);
798 prq->type,
799 pr->bg,
800 key,
801 NULL, 0,
802 prq->data,
803 prq->size);
804 switch (prq->eval)
805 {
808 break;
810 /* short cut: stop processing early, no BF-update, etc. */
815 .rel_value_us);
816 if (GNUNET_YES !=
818 .pr_head,
819 prq->sender,
820 &last_transmission))
821 last_transmission = GNUNET_TIME_UNIT_FOREVER_ABS;
822 /* pass on to other peers / local clients */
823 pr->rh (pr->rh_cls,
824 prq->eval,
825 pr,
826 prq->anonymity_level,
827 prq->expiration,
828 last_transmission,
829 prq->type,
830 prq->data,
831 prq->size);
832 return GNUNET_YES;
834#if INSANE_STATISTICS
836 "# duplicate replies discarded (bloomfilter)",
837 1,
838 GNUNET_NO);
839#endif
841 "Duplicate response, discarding.\n");
842 return GNUNET_YES; /* duplicate */
845 "# irrelevant replies discarded",
846 1,
847 GNUNET_NO);
849 "Irrelevant response, ignoring.\n");
850 return GNUNET_YES;
852 GNUNET_break (0); /* bad installation? */
853 return GNUNET_NO;
854 }
855 /* update bloomfilter */
857 prq->size,
858 &chash);
860 &chash,
861 1);
862 if (NULL == prq->sender)
863 {
865 "Found result for query `%s' in local datastore\n",
866 GNUNET_h2s (key));
868 gettext_noop ("# results found locally"),
869 1,
870 GNUNET_NO);
871 }
872 else
873 {
874 GSF_dht_lookup_ (pr);
875 }
877 pr->public_data.priority = 0;
881 /* finally, pass on to other peer / local client */
883 .pr_head,
884 prq->sender,
885 &last_transmission))
886 last_transmission = GNUNET_TIME_UNIT_FOREVER_ABS;
887 pr->rh (pr->rh_cls,
888 prq->eval,
889 pr,
890 prq->anonymity_level,
891 prq->expiration,
892 last_transmission,
893 prq->type,
894 prq->data,
895 prq->size);
896 return GNUNET_YES;
897}
898
899
921
922
932static void
934 int success,
936 const char *msg)
937{
938 struct PutMigrationContext *pmc = cls;
939 struct GSF_ConnectedPeer *cp;
940 struct GNUNET_TIME_Relative mig_pause;
941 struct GSF_PeerPerformanceData *ppd;
942
943 if (NULL != datastore_put_load)
944 {
945 if (GNUNET_SYSERR != success)
946 {
949 .rel_value_us);
950 }
951 else
952 {
953 /* on queue failure / timeout, increase the put load dramatically */
955 GNUNET_TIME_UNIT_MINUTES.rel_value_us);
956 }
957 }
958 cp = GSF_peer_get_ (&pmc->origin);
959 if (GNUNET_OK == success)
960 {
961 if (NULL != cp)
962 {
965 }
966 GNUNET_free (pmc);
967 return;
968 }
969 if ((GNUNET_NO == success) && (GNUNET_NO == pmc->requested) && (NULL != cp))
970 {
973 {
975 "Asking to stop migration for %s because datastore is full\n",
978 GNUNET_YES));
980 }
981 else
982 {
984 ppd->migration_delay);
985 ppd->migration_delay =
987 mig_pause.rel_value_us =
989 ppd->migration_delay =
991 GNUNET_log (
993 "Replicated content already exists locally, asking to stop migration for %s\n",
997 }
998 }
999 GNUNET_free (pmc);
1001 gettext_noop ("# Datastore `PUT' failures"),
1002 1,
1003 GNUNET_NO);
1004}
1005
1006
1016static int
1017test_put_load_too_high (uint32_t priority)
1018{
1019 double ld;
1020
1021 if (NULL == datastore_put_load)
1022 return GNUNET_NO;
1024 return GNUNET_NO; /* very fast */
1026 if (ld < 2.0 * (1 + priority))
1027 return GNUNET_NO;
1029 gettext_noop (
1030 "# storage requests dropped due to high load"),
1031 1,
1032 GNUNET_NO);
1033 return GNUNET_YES;
1034}
1035
1036
1053static void
1055 struct GNUNET_TIME_Absolute exp,
1056 const struct GNUNET_HashCode *key,
1057 const struct GNUNET_PeerIdentity *trunc_peer,
1058 const struct GNUNET_DHT_PathElement *get_path,
1059 unsigned int get_path_length,
1060 const struct GNUNET_DHT_PathElement *put_path,
1061 unsigned int put_path_length,
1063 size_t size,
1064 const void *data)
1065{
1066 struct GSF_PendingRequest *pr = cls;
1067 struct ProcessReplyClosure prq;
1068 struct PutMigrationContext *pmc;
1069
1071 gettext_noop ("# Replies received from DHT"),
1072 1,
1073 GNUNET_NO);
1074 memset (&prq, 0, sizeof(prq));
1075 prq.data = data;
1076 prq.expiration = exp;
1077 /* do not allow migrated content to live longer than 1 year */
1080 prq.expiration);
1081 prq.size = size;
1082 prq.type = type;
1083 process_reply (&prq,
1084 key,
1085 pr);
1088 {
1090 "Replicating result for query `%s' with priority %u\n",
1091 GNUNET_h2s (key),
1092 prq.priority);
1093 pmc = GNUNET_new (struct PutMigrationContext);
1095 pmc->requested = GNUNET_YES;
1096 if (NULL == GNUNET_DATASTORE_put (GSF_dsh,
1097 0,
1098 key,
1099 size,
1100 data,
1101 type,
1102 prq.priority,
1103 1 /* anonymity */,
1104 0 /* replication */,
1105 exp,
1106 1 + prq.priority,
1109 pmc))
1110 {
1114 NULL);
1115 }
1116 }
1117}
1118
1119
1125void
1127{
1128 const void *xquery;
1129 size_t xquery_size;
1130 struct GNUNET_PeerIdentity pi;
1131 char buf[sizeof(struct GNUNET_HashCode) * 2] GNUNET_ALIGN;
1132
1133 if (0 != pr->public_data.anonymity_level)
1134 return;
1135 if (NULL != pr->gh)
1136 {
1137 GNUNET_DHT_get_stop (pr->gh);
1138 pr->gh = NULL;
1139 }
1140 xquery = NULL;
1141 xquery_size = 0;
1142 if (0 != (pr->public_data.options & GSF_PRO_FORWARD_ONLY))
1143 {
1144 GNUNET_assert (0 != pr->sender_pid);
1146 GNUNET_memcpy (&buf[xquery_size], &pi, sizeof(struct GNUNET_PeerIdentity));
1147 xquery_size += sizeof(struct GNUNET_PeerIdentity);
1148 }
1150 pr->public_data.type,
1151 &pr->public_data.query,
1154 xquery,
1155 xquery_size,
1157 pr);
1158 if ((NULL != pr->gh) && (0 != pr->replies_seen_count))
1161 pr->replies_seen);
1162}
1163
1164
1174static void
1178 size_t data_size,
1179 const void *data)
1180{
1181 struct GSF_PendingRequest *pr = cls;
1182 struct ProcessReplyClosure prq;
1183 struct GNUNET_HashCode query;
1184
1185 pr->cadet_request = NULL;
1186 if (GNUNET_OK !=
1188 type,
1189 data,
1190 data_size))
1191 {
1192 GNUNET_break_op (0);
1193 return;
1194 }
1196 {
1197 GNUNET_break (NULL == data);
1198 GNUNET_break (0 == data_size);
1199 pr->cadet_retry_count++;
1201 return; /* give up on cadet */
1202 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Error retrieiving block via cadet\n");
1203 /* retry -- without delay, as this is non-anonymous
1204 and cadet/cadet connect will take some time anyway */
1206 &pr->public_data.query,
1207 pr->public_data.type,
1209 pr);
1210 return;
1211 }
1212 if (GNUNET_YES !=
1214 type,
1215 data,
1216 data_size,
1217 &query))
1218 {
1220 "Failed to derive key for block of type %d\n",
1221 (int) type);
1222 GNUNET_break_op (0);
1223 return;
1224 }
1226 gettext_noop ("# Replies received from CADET"),
1227 1,
1228 GNUNET_NO);
1229 memset (&prq, 0, sizeof(prq));
1230 prq.data = data;
1231 prq.expiration = expiration;
1232 /* do not allow migrated content to live longer than 1 year */
1235 prq.expiration);
1236 prq.size = data_size;
1237 prq.type = type;
1238 process_reply (&prq,
1239 &query,
1240 pr);
1241}
1242
1243
1249void
1251{
1252 if (0 != pr->public_data.anonymity_level)
1253 return;
1254 if (0 == pr->public_data.target)
1255 {
1257 "Cannot do cadet-based download, target peer not known\n");
1258 return;
1259 }
1260 if (NULL != pr->cadet_request)
1261 return;
1263 &pr->public_data.query,
1264 pr->public_data.type,
1266 pr);
1267}
1268
1269
1275static void
1277{
1278 struct GSF_PendingRequest *pr = cls;
1279
1281 _ ("Datastore lookup already took %s!\n"),
1284 GNUNET_YES));
1287 pr);
1288}
1289
1290
1296static void
1298{
1299 struct GSF_PendingRequest *pr = cls;
1300
1302 _ ("On-demand lookup already took %s!\n"),
1305 GNUNET_YES));
1308 pr);
1309}
1310
1311
1312/* Call our continuation (if we have any) */
1313static void
1315{
1317
1318 GNUNET_assert (NULL == pr->qe);
1319 if (NULL != pr->warn_task)
1320 {
1322 pr->warn_task = NULL;
1323 }
1324 if (NULL == cont)
1325 return; /* no continuation */
1326 pr->llc_cont = NULL;
1327 if (0 != (GSF_PRO_LOCAL_ONLY & pr->public_data.options))
1328 {
1330 {
1331 /* Signal that we are done and that there won't be any
1332 additional results to allow client to clean up state. */
1333 pr->rh (pr->rh_cls,
1335 pr,
1336 UINT32_MAX,
1340 NULL,
1341 0);
1342 }
1343 /* Finally, call our continuation to signal that we are
1344 done with local processing of this request; i.e. to
1345 start reading again from the client. */
1346 cont (pr->llc_cont_cls,
1347 NULL,
1349 return;
1350 }
1351
1352 cont (pr->llc_cont_cls,
1353 pr,
1354 pr->local_result);
1355}
1356
1357
1358/* Update stats and call continuation */
1359static void
1361{
1363 "No further local responses available.\n");
1364#if INSANE_STATISTICS
1368 gettext_noop (
1369 "# requested DBLOCK or IBLOCK not found"),
1370 1,
1371 GNUNET_NO);
1372#endif
1373 call_continuation (pr);
1374}
1375
1376
1377/* forward declaration */
1378static void
1379process_local_reply (void *cls,
1380 const struct GNUNET_HashCode *key,
1381 size_t size,
1382 const void *data,
1384 uint32_t priority,
1385 uint32_t anonymity,
1386 uint32_t replication,
1388 uint64_t uid);
1389
1390
1391/* Start a local query */
1392static void
1394 uint64_t next_uid,
1395 bool random)
1396{
1400 pr);
1402 next_uid,
1403 random,
1404 &pr->public_data.query,
1405 pr->public_data.type ==
1408 : pr->public_data.type,
1410 & pr->public_data.options))
1411 ? UINT_MAX
1412 : 1
1413 /* queue priority */,
1415 & pr->public_data.options))
1416 ? UINT_MAX
1418 /* max queue size */,
1420 pr);
1421 if (NULL != pr->qe)
1422 return;
1423 GNUNET_log (
1425 "ERROR Requesting `%s' of type %d with next_uid %llu from datastore.\n",
1427 pr->public_data.type,
1428 (unsigned long long) next_uid);
1430 gettext_noop (
1431 "# Datastore lookups concluded (error queueing)"),
1432 1,
1433 GNUNET_NO);
1434 call_continuation (pr);
1435}
1436
1437
1456static void
1458 const struct GNUNET_HashCode *key,
1459 size_t size,
1460 const void *data,
1462 uint32_t priority,
1463 uint32_t anonymity,
1464 uint32_t replication,
1466 uint64_t uid)
1467{
1468 struct GSF_PendingRequest *pr = cls;
1469 struct ProcessReplyClosure prq;
1470 struct GNUNET_HashCode query;
1471 unsigned int old_rf;
1472
1474 pr->warn_task = NULL;
1475 if (NULL == pr->qe)
1476 goto called_from_on_demand;
1477 pr->qe = NULL;
1478 if (
1479 (NULL == key) && pr->seen_null &&
1480 ! pr->have_first_uid) /* We have hit the end for the 2nd time with no results */
1481 {
1482 /* No results */
1483#if INSANE_STATISTICS
1485 gettext_noop (
1486 "# Datastore lookups concluded (no results)"),
1487 1,
1488 GNUNET_NO);
1489#endif
1491 return;
1492 }
1493 if (((NULL == key) &&
1494 pr->seen_null) || /* We have hit the end for the 2nd time OR */
1495 (pr->seen_null && pr->have_first_uid &&
1496 (uid >= pr->first_uid))) /* We have hit the end and past first UID */
1497 {
1498 /* Seen all results */
1500 gettext_noop (
1501 "# Datastore lookups concluded (seen all)"),
1502 1,
1503 GNUNET_NO);
1505 return;
1506 }
1507 if (NULL == key)
1508 {
1509 GNUNET_assert (! pr->seen_null);
1510 pr->seen_null = true;
1511 start_local_query (pr, 0 /* next_uid */, false /* random */);
1512 return;
1513 }
1514 if (! pr->have_first_uid)
1515 {
1516 pr->first_uid = uid;
1517 pr->have_first_uid = true;
1518 }
1519 pr->result_count++;
1520 if (pr->result_count > MAX_RESULTS)
1521 {
1523 GSF_stats,
1524 gettext_noop ("# Datastore lookups aborted (more than MAX_RESULTS)"),
1525 1,
1526 GNUNET_NO);
1528 return;
1529 }
1531 "Received reply for `%s' of type %d with UID %llu from datastore.\n",
1532 GNUNET_h2s (key),
1533 type,
1534 (unsigned long long) uid);
1536 {
1538 "Found ONDEMAND block, performing on-demand encoding\n");
1540 gettext_noop (
1541 "# on-demand blocks matched requests"),
1542 1,
1543 GNUNET_NO);
1547 pr);
1549 size,
1550 data,
1551 type,
1552 priority,
1553 anonymity,
1555 expiration,
1556 uid,
1558 pr))
1559 {
1561 gettext_noop (
1562 "# on-demand lookups performed successfully"),
1563 1,
1564 GNUNET_NO);
1565 return; /* we're done */
1566 }
1568 gettext_noop ("# on-demand lookups failed"),
1569 1,
1570 GNUNET_NO);
1572 start_local_query (pr, uid + 1 /* next_uid */, false /* random */);
1573 return;
1574 }
1575called_from_on_demand:
1576 old_rf = pr->public_data.results_found;
1577 memset (&prq, 0, sizeof(prq));
1578 prq.data = data;
1579 prq.expiration = expiration;
1580 prq.size = size;
1581 if (GNUNET_OK !=
1583 type,
1584 data,
1585 size,
1586 &query))
1587 {
1588 GNUNET_break (0);
1590 key,
1591 size,
1592 data,
1593 UINT_MAX,
1594 UINT_MAX,
1595 NULL,
1596 NULL);
1597 start_local_query (pr, uid + 1 /* next_uid */, false /* random */);
1598 return;
1599 }
1600 prq.type = type;
1601 prq.priority = priority;
1604 if ((0 == old_rf) && (0 == pr->public_data.results_found))
1606 process_reply (&prq,
1607 key,
1608 pr);
1609 pr->local_result = prq.eval;
1611 {
1613 GSF_stats,
1614 gettext_noop ("# Datastore lookups concluded (found last result)"),
1615 1,
1616 GNUNET_NO);
1617 call_continuation (pr);
1618 return;
1619 }
1620 if ((0 == (GSF_PRO_PRIORITY_UNLIMITED & pr->public_data.options)) &&
1622 (pr->public_data.results_found > 5 + 2 * pr->public_data.priority)))
1623 {
1624 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Load too high, done with request\n");
1626 gettext_noop (
1627 "# Datastore lookups concluded (load too high)")
1628 ,
1629 1,
1630 GNUNET_NO);
1631 call_continuation (pr);
1632 return;
1633 }
1634 start_local_query (pr, uid + 1 /* next_uid */, false /* random */);
1635}
1636
1637
1645int
1647 const struct GNUNET_PeerIdentity *target)
1648{
1649 struct GNUNET_PeerIdentity pi;
1650
1651 if (0 == pr->origin_pid)
1652 return GNUNET_YES;
1654 return (0 == memcmp (&pi, target, sizeof(struct GNUNET_PeerIdentity)))
1655 ? GNUNET_NO
1656 : GNUNET_YES;
1657}
1658
1659
1667void
1670 void *cont_cls)
1671{
1672 GNUNET_assert (NULL == pr->gh);
1673 GNUNET_assert (NULL == pr->cadet_request);
1674 GNUNET_assert (NULL == pr->llc_cont);
1675 pr->llc_cont = cont;
1676 pr->llc_cont_cls = cont_cls;
1677#if INSANE_STATISTICS
1679 gettext_noop ("# Datastore lookups initiated"),
1680 1,
1681 GNUNET_NO);
1682#endif
1683 start_local_query (pr, 0 /* next_uid */, true /* random */);
1684}
1685
1686
1696void
1698 const struct PutMessage *put)
1699{
1700 struct GSF_ConnectedPeer *cp = cls;
1701 uint16_t msize;
1702 size_t dsize;
1705 struct GNUNET_HashCode query;
1706 struct ProcessReplyClosure prq;
1707 struct GNUNET_TIME_Relative block_time;
1708 double putl;
1709 struct PutMigrationContext *pmc;
1710
1712 "Received P2P PUT from %s\n",
1715 msize = ntohs (put->header.size);
1716 dsize = msize - sizeof(struct PutMessage);
1717 type = ntohl (put->type);
1719 /* do not allow migrated content to live longer than 1 year */
1722 expiration);
1723 if (GNUNET_OK !=
1725 type,
1726 &put[1],
1727 dsize))
1728 {
1729 GNUNET_break_op (0);
1730 return;
1731 }
1732 if (GNUNET_OK !=
1734 type,
1735 &put[1],
1736 dsize,
1737 &query))
1738 {
1739 GNUNET_break_op (0);
1740 return;
1741 }
1743 gettext_noop ("# GAP PUT messages received"),
1744 1,
1745 GNUNET_NO);
1746 /* now, lookup 'query' */
1747 prq.data = (const void *) &put[1];
1748 prq.sender = cp;
1749 prq.size = dsize;
1750 prq.type = type;
1751 prq.expiration = expiration;
1752 prq.priority = 0;
1753 prq.anonymity_level = UINT32_MAX;
1756 &query,
1758 &prq);
1759 if (NULL != cp)
1760 {
1763 + 1000 * prq.priority);
1765 }
1766 if ((GNUNET_YES == active_to_migration) && (NULL != cp) &&
1768 {
1770 "Replicating result for query `%s' with priority %u\n",
1771 GNUNET_h2s (&query),
1772 prq.priority);
1773 pmc = GNUNET_new (struct PutMigrationContext);
1775 pmc->requested = prq.request_found;
1778 &pmc->origin);
1779 if (NULL == GNUNET_DATASTORE_put (GSF_dsh,
1780 0,
1781 &query,
1782 dsize,
1783 &put[1],
1784 type,
1785 prq.priority,
1786 1 /* anonymity */,
1787 0 /* replication */,
1788 expiration,
1789 1 + prq.priority,
1792 pmc))
1793 {
1797 NULL);
1798 }
1799 }
1800 else if (NULL != cp)
1801 {
1803 "Choosing not to keep content `%s' (%d/%d)\n",
1804 GNUNET_h2s (&query),
1807 }
1809 if ((NULL != cp) && (GNUNET_NO == prq.request_found) &&
1811 (putl > 2.5 * (1 + prq.priority))))
1812 {
1814 putl = 1.0 + GNUNET_CRYPTO_random_u32 (5);
1815 block_time = GNUNET_TIME_relative_multiply (
1817 5000 + GNUNET_CRYPTO_random_u32 ((unsigned int) (60000 * putl * putl)));
1818 GNUNET_log (
1820 "Asking to stop migration for %s because of load %f and events %d/%d\n",
1822 putl,
1824 (GNUNET_NO == prq.request_found));
1827 }
1828}
1829
1830
1837int
1839{
1840 return (NULL != pr->rh) ? GNUNET_YES : GNUNET_NO;
1841}
1842
1843
1847void
1867
1868
1872void
1883
1884
1885/* end of gnunet-service-fs_pr.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 gettext_noop(String)
Definition gettext.h:74
static unsigned int anonymity_level
Anonymity level option to use for publishing.
static unsigned int replication
Desired replication level.
static char * data
The data to insert into the dht.
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_TIME_Relative expiration
User supplied expiration value.
static unsigned int anonymity
static struct GNUNET_TIME_Relative ttl
Current record $TTL to use.
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_TIME_Absolute min_expiration
Minimum time that content should have to not be discarded instantly (time stamp of any content that w...
void GSF_update_datastore_delay_(struct GNUNET_TIME_Absolute start)
We've just now completed a datastore request.
struct GNUNET_BLOCK_Context * GSF_block_ctx
Our block context.
struct GNUNET_DHT_Handle * GSF_dht
Handle for DHT operations.
int GSF_test_get_load_too_high_(uint32_t priority)
Test if the DATABASE (GET) load on this peer is too high to even consider processing the query at all...
struct GNUNET_STATISTICS_Handle * GSF_stats
Handle for reporting statistics.
const struct GNUNET_CONFIGURATION_Handle * GSF_cfg
Our configuration.
unsigned int GSF_cover_content_count
How many content messages have we received 'recently' that have not yet been claimed as cover traffic...
struct GNUNET_LOAD_Value * GSF_rt_entry_lifetime
How long do requests typically stay in the routing table?
struct GNUNET_DATASTORE_Handle * GSF_dsh
Our connection to the datastore.
unsigned int GSF_datastore_queue_size
Size of the datastore queue we assume for common requests.
shared data structures of gnunet-service-fs.c
#define GET_MESSAGE_BIT_TRANSMIT_TO
The peer identity of a peer that had claimed to have the content previously is included (can be used ...
#define DATASTORE_LOAD_AUTODECLINE
At what frequency should our datastore load decrease automatically (since if we don't use it,...
#define GET_MESSAGE_BIT_RETURN_TO
The peer identity of a peer waiting for the reply is included (used if the response should be transmi...
non-anonymous file-transfer
struct GSF_CadetRequest * GSF_cadet_query(const struct GNUNET_PeerIdentity *target, const struct GNUNET_HashCode *query, enum GNUNET_BLOCK_Type type, GSF_CadetReplyProcessor proc, void *proc_cls)
Look for a block by directly contacting a particular peer.
void GSF_cadet_query_cancel(struct GSF_CadetRequest *sr)
Cancel an active request; must not be called after 'proc' was called.
struct GSF_PeerPerformanceData * GSF_get_peer_performance_data_(struct GSF_ConnectedPeer *cp)
Return the performance data record for the given peer.
struct GSF_ConnectedPeer * GSF_peer_get_(const struct GNUNET_PeerIdentity *peer)
Get a handle for a connected peer.
void GSF_block_peer_migration_(struct GSF_ConnectedPeer *cp, struct GNUNET_TIME_Absolute block_time)
Ask a peer to stop migrating data to us until the given point in time.
void GSF_peer_update_performance_(struct GSF_ConnectedPeer *cp, struct GNUNET_TIME_Absolute request_time, uint32_t request_priority)
Report on receiving a reply; update the performance record of the given peer.
void GSF_connected_peer_change_preference_(struct GSF_ConnectedPeer *cp, uint64_t pref)
Notify core about a preference we have for the given peer (to allocate more resources towards it).
API to handle 'connected peers'.
int GNUNET_FS_handle_on_demand_block(const struct GNUNET_HashCode *key, uint32_t size, const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, uint32_t anonymity, uint32_t replication, struct GNUNET_TIME_Absolute expiration, uint64_t uid, GNUNET_DATASTORE_DatumProcessor cont, void *cont_cls)
We've received an on-demand encoded block from the datastore.
indexing for the file-sharing service
int GSF_request_plan_reference_get_last_transmission_(struct GSF_PendingRequestPlanBijection *pr_head, struct GSF_ConnectedPeer *sender, struct GNUNET_TIME_Absolute *result)
Get the last transmission attempt time for the request plan list referenced by pr_head,...
void GSF_plan_notify_request_done_(struct GSF_PendingRequest *pr)
Notify the plan about a request being done; destroy all entries associated with this request.
API to manage query plan.
int GSF_pending_request_test_target_(struct GSF_PendingRequest *pr, const struct GNUNET_PeerIdentity *target)
Is the given target a legitimate peer for forwarding the given request?
static void update_request_performance_data(struct ProcessReplyClosure *prq, struct GSF_PendingRequest *pr)
Update the performance data for the sender (if any) since the sender successfully answered one of our...
static void put_migration_continuation(void *cls, int success, struct GNUNET_TIME_Absolute min_expiration, const char *msg)
Continuation called to notify client about result of the operation.
#define MAX_RESULTS
Hard limit on the number of results we may get from the datastore per query.
static void handle_dht_reply(void *cls, struct GNUNET_TIME_Absolute exp, const struct GNUNET_HashCode *key, const struct GNUNET_PeerIdentity *trunc_peer, const struct GNUNET_DHT_PathElement *get_path, unsigned int get_path_length, const struct GNUNET_DHT_PathElement *put_path, unsigned int put_path_length, enum GNUNET_BLOCK_Type type, size_t size, const void *data)
Iterator called on each result obtained for a DHT operation that expects a reply.
struct GSF_PendingRequest * GSF_pending_request_create_(enum GSF_PendingRequestOptions options, enum GNUNET_BLOCK_Type type, const struct GNUNET_HashCode *query, const struct GNUNET_PeerIdentity *target, const char *bf_data, size_t bf_size, uint32_t anonymity_level, uint32_t priority, int32_t ttl, GNUNET_PEER_Id sender_pid, GNUNET_PEER_Id origin_pid, const struct GNUNET_HashCode *replies_seen, unsigned int replies_seen_count, GSF_PendingRequestReplyHandler rh, void *rh_cls)
Create a new pending request.
#define MAX_DATASTORE_QUEUE
Maximum size of the datastore queue for P2P operations.
static unsigned long long max_pending_requests
Maximum number of requests (from other peers, overall) that we're willing to have pending at any give...
static int active_to_migration
Are we allowed to migrate content to this peer.
#define CONTENT_BANDWIDTH_VALUE
Bandwidth value of a 0-priority content (must be fairly high compared to query since content is typic...
void GSF_cadet_lookup_(struct GSF_PendingRequest *pr)
Consider downloading via cadet (if possible)
#define DHT_GET_REPLICATION
Desired replication level for GETs.
static int test_put_load_too_high(uint32_t priority)
Test if the DATABASE (PUT) load on this peer is too high to even consider processing the query at all...
int GSF_pending_request_is_compatible_(struct GSF_PendingRequest *pra, struct GSF_PendingRequest *prb)
Test if two pending requests are compatible (would generate the same query modulo filters and should ...
static void no_more_local_results(struct GSF_PendingRequest *pr)
void GSF_dht_lookup_(struct GSF_PendingRequest *pr)
Consider looking up the data in the DHT (anonymity-level permitting).
void GSF_iterate_pending_requests_(GSF_PendingRequestIterator it, void *cls)
Iterate over all pending requests.
static void process_local_reply(void *cls, const struct GNUNET_HashCode *key, size_t size, const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, uint32_t anonymity, uint32_t replication, struct GNUNET_TIME_Absolute expiration, uint64_t uid)
We're processing (local) results for a search request from another peer.
void GSF_local_lookup_(struct GSF_PendingRequest *pr, GSF_LocalLookupContinuation cont, void *cont_cls)
Look up the request in the local datastore.
static void odc_warn_delay_task(void *cls)
Task that issues a warning if the datastore lookup takes too long.
static void call_continuation(struct GSF_PendingRequest *pr)
void GSF_pending_request_init_()
Setup the subsystem.
void handle_p2p_put(void *cls, const struct PutMessage *put)
Handle P2P "CONTENT" message.
struct GSF_PendingRequestData * GSF_pending_request_get_data_(struct GSF_PendingRequest *pr)
Obtain the public data associated with a pending request.
int GSF_pending_request_test_active_(struct GSF_PendingRequest *pr)
Check if the given request is still active.
static void refresh_bloomfilter(enum GNUNET_BLOCK_Type type, struct GSF_PendingRequest *pr)
Recalculate our bloom filter for filtering replies.
static void warn_delay_task(void *cls)
Task that issues a warning if the datastore lookup takes too long.
void GSF_pending_request_done_()
Shutdown the subsystem.
#define CADET_RETRY_MAX
If obtaining a block via cadet fails, how often do we retry it before giving up for good (and stickin...
static enum GNUNET_GenericReturnValue process_reply(void *cls, const struct GNUNET_HashCode *key, void *value)
We have received a reply; handle it!
static struct GNUNET_LOAD_Value * datastore_put_load
Datastore 'PUT' load tracking.
struct GNUNET_MQ_Envelope * GSF_pending_request_get_message_(struct GSF_PendingRequest *pr)
Generate the message corresponding to the given pending request for transmission to other peers.
static struct GNUNET_CONTAINER_Heap * requests_by_expiration_heap
Heap with the request that will expire next at the top.
static struct GNUNET_CONTAINER_MultiHashMap * pr_map
All pending requests, ordered by the query.
static int clean_request(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator to free pending requests.
static void cadet_reply_proc(void *cls, enum GNUNET_BLOCK_Type type, struct GNUNET_TIME_Absolute expiration, size_t data_size, const void *data)
Function called with a reply from the cadet.
static void start_local_query(struct GSF_PendingRequest *pr, uint64_t next_uid, bool random)
void GSF_pending_request_cancel_(struct GSF_PendingRequest *pr, int full_cleanup)
Explicitly cancel a pending request.
void GSF_pending_request_update_(struct GSF_PendingRequest *pr, const struct GNUNET_HashCode *replies_seen, unsigned int replies_seen_count)
Update a given pending request with additional replies that have been seen.
API to handle pending requests.
void(* GSF_PendingRequestReplyHandler)(void *cls, enum GNUNET_BLOCK_ReplyEvaluationResult eval, struct GSF_PendingRequest *pr, uint32_t reply_anonymity_level, struct GNUNET_TIME_Absolute expiration, struct GNUNET_TIME_Absolute last_transmission, enum GNUNET_BLOCK_Type type, const void *data, size_t data_len)
Handle a reply to a pending request.
GSF_PendingRequestOptions
Options for pending requests (bits to be ORed).
@ GSF_PRO_LOCAL_ONLY
Request must only be processed locally.
@ GSF_PRO_PRIORITY_UNLIMITED
Request priority is allowed to be exceeded.
@ GSF_PRO_FORWARD_ONLY
Request must only be forwarded (no routing)
@ GSF_PRO_BLOOMFILTER_FULL_REFRESH
Request is allowed to refresh bloomfilter and change mingle value.
@ GSF_PRO_REQUEST_NEVER_EXPIRES
Request persists indefinitely (no expiration).
void(* GSF_LocalLookupContinuation)(void *cls, struct GSF_PendingRequest *pr, enum GNUNET_BLOCK_ReplyEvaluationResult result)
Function to be called after we're done processing replies from the local lookup.
int(* GSF_PendingRequestIterator)(void *cls, const struct GNUNET_HashCode *key, struct GSF_PendingRequest *pr)
Signature of function called on each request.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
GNUNET_BLOCK_Type
WARNING: This header is generated! In order to add DHT block types, you must register them in GANA,...
@ GNUNET_BLOCK_TYPE_FS_DBLOCK
Data block (leaf) in the CHK tree.
@ GNUNET_BLOCK_TYPE_FS_ONDEMAND
Type of a block representing a block to be encoded on demand from disk.
@ GNUNET_BLOCK_TYPE_FS_IBLOCK
Inner block in the CHK tree.
@ GNUNET_BLOCK_TYPE_ANY
Identifier for any block.
@ GNUNET_BLOCK_TYPE_FS_UBLOCK
Type of a block representing any type of search result (universal).
Functions related to load calculations.
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
enum GNUNET_GenericReturnValue GNUNET_BLOCK_group_serialize(struct GNUNET_BLOCK_Group *bg, void **raw_data, size_t *raw_data_size)
Serialize state of a block group.
Definition block.c:177
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
enum GNUNET_GenericReturnValue GNUNET_BLOCK_get_key(struct GNUNET_BLOCK_Context *ctx, enum GNUNET_BLOCK_Type type, const void *block, size_t block_size, struct GNUNET_HashCode *key)
Function called to obtain the key for a block.
Definition block.c:278
@ 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)
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
uint64_t GNUNET_CRYPTO_random_u64(uint64_t max)
Generate a random unsigned 64-bit value.
uint32_t GNUNET_CRYPTO_random_u32(uint32_t i)
Produce a random value.
void GNUNET_DATASTORE_cancel(struct GNUNET_DATASTORE_QueueEntry *qe)
Cancel a datastore operation.
struct GNUNET_DATASTORE_QueueEntry * GNUNET_DATASTORE_put(struct GNUNET_DATASTORE_Handle *h, uint32_t rid, const struct GNUNET_HashCode *key, size_t size, const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, uint32_t anonymity, uint32_t replication, struct GNUNET_TIME_Absolute expiration, unsigned int queue_priority, unsigned int max_queue_size, GNUNET_DATASTORE_ContinuationWithStatus cont, void *cont_cls)
Store an item in the datastore.
struct GNUNET_DATASTORE_QueueEntry * GNUNET_DATASTORE_remove(struct GNUNET_DATASTORE_Handle *h, const struct GNUNET_HashCode *key, size_t size, const void *data, unsigned int queue_priority, unsigned int max_queue_size, GNUNET_DATASTORE_ContinuationWithStatus cont, void *cont_cls)
Explicitly remove some content from the database.
struct GNUNET_DATASTORE_QueueEntry * GNUNET_DATASTORE_get_key(struct GNUNET_DATASTORE_Handle *h, uint64_t next_uid, bool random, const struct GNUNET_HashCode *key, enum GNUNET_BLOCK_Type type, unsigned int queue_priority, unsigned int max_queue_size, GNUNET_DATASTORE_DatumProcessor proc, void *proc_cls)
Get a result for a particular key from the datastore.
void GNUNET_DHT_get_stop(struct GNUNET_DHT_GetHandle *get_handle)
Stop async DHT-get.
Definition dht_api.c:1238
void GNUNET_DHT_get_filter_known_results(struct GNUNET_DHT_GetHandle *get_handle, unsigned int num_results, const struct GNUNET_HashCode *results)
Tell the DHT not to return any of the following known results to this client.
Definition dht_api.c:1214
struct GNUNET_DHT_GetHandle * GNUNET_DHT_get_start(struct GNUNET_DHT_Handle *handle, enum GNUNET_BLOCK_Type type, const struct GNUNET_HashCode *key, uint32_t desired_replication_level, enum GNUNET_DHT_RouteOption options, const void *xquery, size_t xquery_size, GNUNET_DHT_GetIterator iter, void *iter_cls)
Perform an asynchronous GET operation on the DHT identified.
Definition dht_api.c:1165
@ GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE
Each peer along the way should process the request (otherwise only peers locally closest to the key w...
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
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
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.
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.
enum GNUNET_GenericReturnValue(* GNUNET_CONTAINER_MultiHashMapIteratorCallback)(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator over hash map entries.
@ 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_peek(const struct GNUNET_CONTAINER_Heap *heap)
Get element stored at the root of heap.
struct GNUNET_CONTAINER_HeapNode * GNUNET_CONTAINER_heap_insert(struct GNUNET_CONTAINER_Heap *heap, void *element, GNUNET_CONTAINER_HeapCostType cost)
Inserts a new element into the heap.
unsigned int GNUNET_CONTAINER_heap_get_size(const struct GNUNET_CONTAINER_Heap *heap)
Get the current size of the heap.
struct GNUNET_CONTAINER_Heap * GNUNET_CONTAINER_heap_create(enum GNUNET_CONTAINER_HeapOrder order)
Create a new heap.
void GNUNET_CONTAINER_heap_destroy(struct GNUNET_CONTAINER_Heap *heap)
Destroys the heap.
@ GNUNET_CONTAINER_HEAP_ORDER_MIN
Heap with the minimum cost at the root.
#define GNUNET_log(kind,...)
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to 'struct's.
#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
double GNUNET_LOAD_get_average(struct GNUNET_LOAD_Value *load)
Get the average value given to update so far.
Definition load.c:215
struct GNUNET_LOAD_Value * GNUNET_LOAD_value_init(struct GNUNET_TIME_Relative autodecline)
Create a new load value.
Definition load.c:124
void GNUNET_LOAD_update(struct GNUNET_LOAD_Value *load, uint64_t data)
Update the current load.
Definition load.c:236
double GNUNET_LOAD_get_load(struct GNUNET_LOAD_Value *load)
Get the current load.
Definition load.c:200
#define GNUNET_LOAD_value_free(lv)
Free a load value.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity 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).
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_BULK
@ 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_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
unsigned int GNUNET_PEER_Id
A GNUNET_PEER_Id is simply a shorter version of a "struct GNUNET_PeerIdentifier" that can be used ins...
void GNUNET_PEER_change_rc(GNUNET_PEER_Id id, int delta)
Change the reference counter of an interned PID.
Definition peer.c:192
void GNUNET_PEER_resolve(GNUNET_PEER_Id id, struct GNUNET_PeerIdentity *pid)
Convert an interned PID to a normal peer identity.
Definition peer.c:220
#define GNUNET_MESSAGE_TYPE_FS_GET
P2P request for content (one FS to another).
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_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition scheduler.c:1283
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_TIME_Relative GNUNET_TIME_relative_min(struct GNUNET_TIME_Relative t1, struct GNUNET_TIME_Relative t2)
Return the minimum of two relative time values.
Definition time.c:344
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition time.c:438
struct GNUNET_TIME_Relative GNUNET_TIME_relative_saturating_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Saturating multiply relative time by a given factor.
Definition time.c:529
struct GNUNET_TIME_Relative GNUNET_TIME_relative_max(struct GNUNET_TIME_Relative t1, struct GNUNET_TIME_Relative t2)
Return the maximum of two relative time values.
Definition time.c:352
#define GNUNET_TIME_UNIT_HOURS
One hour.
#define GNUNET_TIME_UNIT_SECONDS
One second.
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:406
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition strings.c:610
#define GNUNET_TIME_UNIT_MILLISECONDS
One millisecond.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition time.c:111
#define GNUNET_TIME_UNIT_MINUTES
One minute.
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_absolute_subtract(struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Relative duration)
Subtract a given relative duration from the given start time.
Definition time.c:471
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_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition time.c:486
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_min(struct GNUNET_TIME_Absolute t1, struct GNUNET_TIME_Absolute t2)
Return the minimum of two absolute time values.
Definition time.c:360
#define GNUNET_TIME_UNIT_ZERO_ABS
Absolute time zero.
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
#define GNUNET_TIME_UNIT_YEARS
One year (365 days).
static unsigned int size
Size of the "table".
Definition peer.c:68
#define _(String)
GNU gettext support macro.
Definition platform.h:179
Handle to a node in a heap.
Internal representation of the hash map.
Entry in our priority queue.
Handle to a GET request.
Definition dht_api.c:79
A (signed) path tracking a block's flow through the DHT is represented by an array of path elements,...
A 512-bit hashcode.
Values we track for load calculations.
Definition load.c:36
The identity of the host (wraps the signing key of the peer).
Entry in list of pending tasks.
Definition scheduler.c:141
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.
uint64_t rel_value_us
The actual value.
Handle for a request that is going out via cadet API.
Performance data kept for a peer.
uint32_t respect
Respect rating for this peer.
struct GNUNET_TIME_Relative migration_delay
If we get content we already have from this peer, for how long do we block it? Adjusted based on the ...
Public data (in the sense of not encapsulated within 'gnunet-service-fs_pr', not in the sense of netw...
const struct GNUNET_PeerIdentity * target
Identity of a peer hosting the content, otherwise NULl.
struct GNUNET_TIME_Absolute ttl
Current TTL for the request.
uint32_t respect_offered
How much respect did we (in total) offer for this request so far (estimate, because we might have the...
enum GNUNET_BLOCK_Type type
Type of the requested block.
struct GSF_PendingRequestPlanBijection * pr_head
Fields for the plan module to track a DLL with the request.
uint32_t num_transmissions
Counter for how often this request has been transmitted (estimate, because we might have the same req...
enum GSF_PendingRequestOptions options
Options for the request.
unsigned int results_found
Number of results we have found for this request so far.
uint32_t anonymity_level
Desired anonymity level.
struct GNUNET_HashCode query
Primary query hash for this request.
struct GNUNET_TIME_Absolute start_time
When did we start with the request.
uint32_t priority
Priority that this request (still) has for us.
uint32_t original_priority
Priority that this request (originally) had for us.
An active request.
unsigned int replies_seen_size
Length of the 'replies_seen' array.
enum GNUNET_BLOCK_ReplyEvaluationResult local_result
Last result from the local datastore lookup evaluation.
struct GNUNET_BLOCK_Group * bg
Block group for filtering replies we've already seen.
struct GNUNET_DATASTORE_QueueEntry * qe
Datastore queue entry for this request (or NULL for none).
size_t result_count
Result count.
uint64_t first_uid
Unique ID of the first result from the local datastore; used to terminate the loop.
unsigned int replies_seen_count
Number of valid entries in the 'replies_seen' array.
GNUNET_PEER_Id sender_pid
Identity of the peer that we should use for the 'sender' (recipient of the response) when forwarding ...
void * llc_cont_cls
Closure for llc_cont.
unsigned int cadet_retry_count
How often have we retried this request via 'cadet'? (used to bound overall retries).
GSF_PendingRequestReplyHandler rh
Function to call if we encounter a reply.
struct GSF_CadetRequest * cadet_request
Cadet request handle for this request (or NULL for none).
void * rh_cls
Closure for rh.
bool seen_null
Have we seen a NULL result yet?
struct GSF_PendingRequestData public_data
Public data for the request.
GSF_LocalLookupContinuation llc_cont
Function to call upon completion of the local get request, or NULL for none.
struct GNUNET_CONTAINER_HeapNode * hnode
Entry for this pending request in the expiration heap, or NULL.
struct GNUNET_DHT_GetHandle * gh
DHT request handle for this request (or NULL for none).
GNUNET_PEER_Id origin_pid
Identity of the peer that we should never forward this query to since it originated this query (0 for...
struct GNUNET_HashCode * replies_seen
Array of hash codes of replies we've already seen.
bool have_first_uid
Do we have a first UID yet?
struct GNUNET_SCHEDULER_Task * warn_task
Task that warns us if the local datastore lookup takes too long.
struct GNUNET_TIME_Absolute qe_start
Time we started the last datastore lookup.
Message to the datastore service asking about specific content.
Definition datastore.h:141
uint32_t type
Desired content type.
Definition datastore.h:150
uint32_t priority
How important is this request (network byte order)
struct GNUNET_HashCode query
Hashcodes of the file(s) we're looking for.
uint32_t reserved
These days not used.
int32_t ttl
Relative time to live in MILLISECONDS (network byte order)
uint32_t hash_bitmap
Which of the optional hash codes are present at the end of the message? See GET_MESSAGE_BIT_xx consta...
Closure for process_reply() function.
size_t size
Size of data.
struct GNUNET_TIME_Absolute expiration
When the reply expires.
enum GNUNET_BLOCK_ReplyEvaluationResult eval
Evaluation result (returned).
uint32_t priority
How much was this reply worth to us?
const void * data
The data for the reply.
struct GSF_ConnectedPeer * sender
Who gave us this reply? NULL for local host (or DHT)
int request_found
Did we find a matching request?
enum GNUNET_BLOCK_Type type
Type of the block.
uint32_t anonymity_level
Anonymity requirements for this reply.
Response from FS service with a result for a previous FS search.
Definition fs.h:330
struct GNUNET_MessageHeader header
Message type will be GNUNET_MESSAGE_TYPE_FS_PUT.
Definition fs.h:334
uint32_t type
Type of the block (in big endian).
Definition fs.h:339
struct GNUNET_TIME_AbsoluteNBO expiration
When does this result expire?
Definition fs.h:344
Context for put_migration_continuation().
struct GNUNET_PeerIdentity origin
Request origin.
struct GNUNET_TIME_Absolute start
Start time for the operation.
int requested
GNUNET_YES if we had a matching request for this block, GNUNET_NO if not.