GNUnet 0.28.0-dev.2-27-gc87478450
 
Loading...
Searching...
No Matches
gnunet-service-fs_pe.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2011 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-service-fs.h"
31
35#define INSANE_STATISTICS GNUNET_NO
36
41struct PendingRequestList;
42
46struct PeerPlan;
47
48
100
101
162
163
202
203
208
212static unsigned long long total_delay;
213
217static unsigned long long plan_count;
218
219
232static const struct GNUNET_HashCode *
234{
235 return &GSF_pending_request_get_data_ (rp->pe_head->pr)->query;
236}
237
238
245static void
246plan (struct PeerPlan *pp,
247 struct GSF_RequestPlan *rp)
248{
249#define N ((double) 128.0)
253 static double avg_delay;
254
255 struct GSF_PendingRequestData *prd;
256 struct GNUNET_TIME_Relative delay;
257
258 GNUNET_assert (rp->pp == pp);
260 gettext_noop ("# average retransmission delay (ms)"),
261 total_delay * 1000LL / plan_count, GNUNET_NO);
262 prd = GSF_pending_request_get_data_ (rp->pe_head->pr);
263
264 if (rp->transmission_counter < 8)
265 delay =
267 rp->transmission_counter);
268 else if (rp->transmission_counter < 32)
269 delay =
271 8
272 + (1LL << (rp->transmission_counter - 8)));
273 else
274 delay =
276 8 + (1LL << 24));
277 delay.rel_value_us =
279 /* Add 0.01 to avg_delay to avoid division-by-zero later */
280 avg_delay = (((avg_delay * (N - 1.0)) + delay.rel_value_us) / N) + 0.01;
281
282 /*
283 * For the priority, we need to consider a few basic rules:
284 * 1) if we just started requesting (delay is small), we should
285 * virtually always have a priority of zero.
286 * 2) for requests with average latency, our priority should match
287 * the average priority observed on the network
288 * 3) even the longest-running requests should not be WAY out of
289 * the observed average (thus we bound by a factor of 2)
290 * 4) we add +1 to the observed average priority to avoid everyone
291 * staying put at zero (2 * 0 = 0...).
292 *
293 * Using the specific calculation below, we get:
294 *
295 * delay = 0 => priority = 0;
296 * delay = avg delay => priority = running-average-observed-priority;
297 * delay >> avg_delay => priority = 2 * running-average-observed-priority;
298 *
299 * which satisfies all of the rules above.
300 *
301 * Note: M_PI_4 = PI/4 = arctan(1)
302 */rp->priority =
304 + 1.0) * atan (delay.rel_value_us / avg_delay)) / M_PI_4;
305 /* Note: usage of 'round' and 'atan' requires -lm */
306
307 if (rp->transmission_counter != 0)
308 delay.rel_value_us += TTL_DECREMENT * 1000;
310 "Considering (re)transmission number %u in %s\n",
311 (unsigned int) rp->transmission_counter,
313 GNUNET_YES));
314 rp->earliest_transmission = GNUNET_TIME_relative_to_absolute (delay);
316 "Earliest (re)transmission for `%s' in %us\n",
317 GNUNET_h2s (&prd->query),
318 rp->transmission_counter);
319 GNUNET_assert (rp->hn == NULL);
321 rp->earliest_transmission).rel_value_us)
323 rp,
324 rp->priority);
325 else
326 rp->hn =
328 rp,
329 rp->earliest_transmission.abs_value_us);
332 get_rp_key (rp),
333 rp));
334#undef N
335}
336
337
344static struct GSF_PendingRequest *
346{
347 struct GSF_PendingRequest *ret;
349 const struct GSF_PendingRequestData *rprd;
350 const struct GSF_PendingRequestData *prd;
351
352 bi = rp->pe_head;
353 if (NULL == bi)
354 return NULL; /* should never happen */
355 ret = bi->pr;
357 for (bi = bi->next_PE; NULL != bi; bi = bi->next_PE)
358 {
362 if (prd->ttl.abs_value_us > rprd->ttl.abs_value_us)
363 {
364 ret = bi->pr;
365 rprd = prd;
366 }
367 }
368 return ret;
369}
370
371
377static void
379{
380 struct PeerPlan *pp = cls;
381 struct GSF_RequestPlan *rp;
382 struct GNUNET_TIME_Relative delay;
383
384 if (NULL != pp->task)
385 {
386 pp->task = NULL;
387 }
388 else
389 {
390 GNUNET_assert (NULL != pp->env);
391 pp->env = NULL;
392 }
393 /* move ready requests to priority queue */
394 while ((NULL != (rp = GNUNET_CONTAINER_heap_peek (pp->delay_heap))) &&
396 (rp->earliest_transmission).rel_value_us))
397 {
400 rp,
401 rp->priority);
402 }
404 {
405 /* priority heap (still) empty, check for delay... */
407 if (NULL == rp)
408 {
410 "No active requests for plan %p.\n",
411 pp);
412 return; /* both queues empty */
413 }
414 delay = GNUNET_TIME_absolute_get_remaining (rp->earliest_transmission);
416 "Sleeping for %s before retrying requests on plan %p.\n",
418 GNUNET_YES),
419 pp);
421 gettext_noop ("# delay heap timeout (ms)"),
422 delay.rel_value_us / 1000LL, GNUNET_NO);
423
424 pp->task
425 = GNUNET_SCHEDULER_add_at (rp->earliest_transmission,
427 pp);
428 return;
429 }
430#if INSANE_STATISTICS
432 gettext_noop ("# query plans executed"),
433 1,
434 GNUNET_NO);
435#endif
436 /* process from priority heap */
439 "Executing query plan %p\n",
440 rp);
441 GNUNET_assert (NULL != rp);
442 rp->hn = NULL;
443 rp->last_transmission = GNUNET_TIME_absolute_get ();
444 rp->transmission_counter++;
445 total_delay++;
447 "Executing plan %p executed %u times, planning retransmission\n",
448 rp,
449 rp->transmission_counter);
450 GNUNET_assert (NULL == pp->env);
454 pp);
457 rp->priority,
458 pp->env);
461 "# query messages sent to other peers"),
462 1,
463 GNUNET_NO);
464 plan (pp,
465 rp);
466}
467
468
473{
478
483};
484
485
496static int
497merge_pr (void *cls,
498 const struct GNUNET_HashCode *query,
499 void *element)
500{
501 struct MergeContext *mpr = cls;
502 struct GSF_RequestPlan *rp = element;
503 struct GSF_PendingRequestData *prd;
505 struct GSF_PendingRequest *latest;
506
509 if (GNUNET_OK !=
511 rp->pe_head->pr))
512 return GNUNET_YES;
513 /* merge new request with existing request plan */
515 bi->rp = rp;
516 bi->pr = mpr->pr;
519 prd->pr_head,
520 prd->pr_tail,
521 bi);
523 rp->pe_head,
524 rp->pe_tail,
525 bi);
526 mpr->merged = GNUNET_YES;
527#if INSANE_STATISTICS
529 gettext_noop ("# requests merged"),
530 1,
531 GNUNET_NO);
532#endif
533 latest = get_latest (rp);
534 if (GSF_pending_request_get_data_ (latest)->ttl.abs_value_us <
535 prd->ttl.abs_value_us)
536 {
537#if INSANE_STATISTICS
539 gettext_noop ("# requests refreshed"),
540 1,
541 GNUNET_NO);
542#endif
543 rp->transmission_counter = 0; /* reset */
544 }
545 return GNUNET_NO;
546}
547
548
555void
557 struct GSF_PendingRequest *pr)
558{
559 const struct GNUNET_PeerIdentity *id;
560 struct PeerPlan *pp;
561 struct GSF_PendingRequestData *prd;
562 struct GSF_RequestPlan *rp;
564 struct MergeContext mpc;
565
568 GNUNET_assert (NULL != cp);
571 if (NULL == pp)
572 {
573 pp = GNUNET_new (struct PeerPlan);
575 pp->priority_heap =
577 pp->delay_heap =
579 pp->cp = cp;
582 id,
583 pp,
586 pp);
587 }
588 mpc.merged = GNUNET_NO;
589 mpc.pr = pr;
592 &prd->query,
593 &merge_pr,
594 &mpc);
595 if (GNUNET_NO != mpc.merged)
596 return;
597 plan_count++;
599 gettext_noop ("# query plan entries"),
600 1,
601 GNUNET_NO);
603 "Planning transmission of query `%s' to peer `%s'\n",
604 GNUNET_h2s (&prd->query),
605 GNUNET_i2s (id));
606 rp = GNUNET_new (struct GSF_RequestPlan);
608 bi->rp = rp;
609 bi->pr = pr;
611 prd->pr_head,
612 prd->pr_tail,
613 bi);
615 rp->pe_head,
616 rp->pe_tail,
617 bi);
618 rp->pp = pp;
621 get_rp_key (rp),
622 rp,
624 plan (pp,
625 rp);
626}
627
628
635void
637{
638 const struct GNUNET_PeerIdentity *id;
639 struct PeerPlan *pp;
640 struct GSF_RequestPlan *rp;
641 struct GSF_PendingRequestData *prd;
643
646 if (NULL == pp)
647 return; /* nothing was ever planned for this peer */
650 pp));
651 if (NULL != pp->task)
652 {
654 pp->task = NULL;
655 }
656 while (NULL != (rp = GNUNET_CONTAINER_heap_remove_root (pp->priority_heap)))
657 {
660 get_rp_key (rp),
661 rp));
662 while (NULL != (bi = rp->pe_head))
663 {
665 rp->pe_head,
666 rp->pe_tail,
667 bi);
670 prd->pr_head,
671 prd->pr_tail,
672 bi);
673 GNUNET_free (bi);
674 }
675 plan_count--;
676 GNUNET_free (rp);
677 }
679 while (NULL != (rp = GNUNET_CONTAINER_heap_remove_root (pp->delay_heap)))
680 {
683 get_rp_key (rp),
684 rp));
685 while (NULL != (bi = rp->pe_head))
686 {
689 rp->pe_head,
690 rp->pe_tail,
691 bi);
693 prd->pr_head,
694 prd->pr_tail,
695 bi);
696 GNUNET_free (bi);
697 }
698 plan_count--;
699 GNUNET_free (rp);
700 }
702 gettext_noop ("# query plan entries"),
704 GNUNET_NO);
707 GNUNET_free (pp);
708}
709
710
720int
723 *pr_head,
724 struct GSF_ConnectedPeer *
725 sender,
726 struct GNUNET_TIME_Absolute *
727 result)
728{
730
731 for (bi = pr_head; NULL != bi; bi = bi->next_PR)
732 {
733 if (bi->rp->pp->cp == sender)
734 {
735 if (0 == bi->rp->last_transmission.abs_value_us)
737 else
739 return GNUNET_YES;
740 }
741 }
742 return GNUNET_NO;
743}
744
745
752void
754{
755 struct GSF_RequestPlan *rp;
756 struct GSF_PendingRequestData *prd;
758
760 while (NULL != (bi = prd->pr_head))
761 {
762 rp = bi->rp;
764 prd->pr_head,
765 prd->pr_tail,
766 bi);
768 rp->pe_head,
769 rp->pe_tail,
770 bi);
771 GNUNET_assert (bi->pr == pr);
772 if (NULL == rp->pe_head)
773 {
775 plan_count--;
778 &prd->query,
779 rp));
780 GNUNET_free (rp);
781 }
782 GNUNET_free (bi);
783 }
785 gettext_noop ("# query plan entries"),
787 GNUNET_NO);
788}
789
790
794void
800
801
805void
811
812
813/* end of gnunet-service-fs_pe.h */
#define gettext_noop(String)
Definition gettext.h:74
static int ret
Final status code.
Definition gnunet-arm.c:93
static struct GNUNET_TIME_Relative ttl
Current record $TTL to use.
static struct GNUNET_IDENTITY_Handle * id
Handle to IDENTITY.
static char * rp
Relying party.
static int result
Global testing status.
struct GNUNET_STATISTICS_Handle * GSF_stats
Handle for reporting statistics.
double GSF_current_priorities
Typical priorities we're seeing from other peers right now.
shared data structures of gnunet-service-fs.c
#define TTL_DECREMENT
By which amount do we decrement the TTL for simple forwarding / indirection of the query; in milli-se...
const struct GNUNET_PeerIdentity * GSF_connected_peer_get_identity2_(const struct GSF_ConnectedPeer *cp)
Obtain the identity of a connected peer.
void GSF_peer_transmit_(struct GSF_ConnectedPeer *cp, int is_query, uint32_t priority, struct GNUNET_MQ_Envelope *env)
Transmit a message to the given peer as soon as possible.
API to handle 'connected peers'.
#define N
static unsigned long long plan_count
Number of plan entries.
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_peer_disconnect_(const struct GSF_ConnectedPeer *cp)
Notify the plan about a peer being no longer available; destroy all entries associated with this peer...
static int merge_pr(void *cls, const struct GNUNET_HashCode *query, void *element)
Iterator that checks if an equivalent request is already present for this peer.
void GSF_plan_init()
Initialize plan subsystem.
static void schedule_peer_transmission(void *cls)
Figure out when and how to transmit to the given peer.
static struct GNUNET_CONTAINER_MultiPeerMap * plans
Hash map from peer identities to PeerPlans.
static void plan(struct PeerPlan *pp, struct GSF_RequestPlan *rp)
Insert the given request plan into the heap with the appropriate weight.
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.
void GSF_plan_add_(struct GSF_ConnectedPeer *cp, struct GSF_PendingRequest *pr)
Create a new query plan entry.
void GSF_plan_done()
Shutdown plan subsystem.
static struct GSF_PendingRequest * get_latest(const struct GSF_RequestPlan *rp)
Get the pending request with the highest TTL from the given plan.
static unsigned long long total_delay
Sum of all transmission counters (equals total delay for all plan entries).
static const struct GNUNET_HashCode * get_rp_key(struct GSF_RequestPlan *rp)
Return the query (key in the plan_map) for the given request plan.
API to manage query plan.
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 ...
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.
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.
API to handle pending requests.
uint32_t GNUNET_CRYPTO_random_u32(uint32_t i)
Produce a random value.
#define GNUNET_CONTAINER_MDLL_remove(mdll, head, tail, element)
Remove an element from a MDLL.
#define GNUNET_CONTAINER_MDLL_insert(mdll, head, tail, element)
Insert an element at the head of a MDLL.
void * GNUNET_CONTAINER_multipeermap_get(const struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key)
Given a key find a value in the map matching the key.
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_contains_value(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Check if the map contains the given value under the given key.
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.
struct GNUNET_CONTAINER_MultiPeerMap * GNUNET_CONTAINER_multipeermap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
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.
unsigned int GNUNET_CONTAINER_multipeermap_size(const struct GNUNET_CONTAINER_MultiPeerMap *map)
Get the number of key-value pairs in the map.
int GNUNET_CONTAINER_multipeermap_put(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multipeermap_remove(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, const void *value)
Remove the given key-value pair from the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE
Allow multiple values with the same key.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
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.
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.
@ GNUNET_CONTAINER_HEAP_ORDER_MAX
Heap with the maximum cost at the root.
#define GNUNET_log(kind,...)
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
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).
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_MQ_notify_sent(struct GNUNET_MQ_Envelope *ev, GNUNET_SCHEDULER_TaskCallback cb, void *cb_cls)
Call a callback once the envelope has been sent, that is, sending it can not be canceled anymore.
Definition mq.c:655
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_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
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_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
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition time.c:111
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
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
Handle to a node in a heap.
Internal representation of the hash map.
Internal representation of the hash map.
A 512-bit hashcode.
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.
Public data (in the sense of not encapsulated within 'gnunet-service-fs_pr', not in the sense of netw...
struct GNUNET_TIME_Absolute ttl
Current TTL for the request.
struct GSF_PendingRequestPlanBijection * pr_head
Fields for the plan module to track a DLL with the request.
struct GSF_PendingRequestPlanBijection * pr_tail
Fields for the plan module to track a DLL with the request.
struct GNUNET_HashCode query
Primary query hash for this request.
M:N binding of plans to pending requests.
struct GSF_PendingRequestPlanBijection * prev_PR
This is a doubly-linked list.
struct GSF_PendingRequest * pr
Associated pending request (identifies request details and one of the origins of the request).
struct GSF_PendingRequestPlanBijection * next_PE
This is a doubly-linked list.
struct GSF_PendingRequestPlanBijection * next_PR
This is a doubly-linked list.
struct GSF_RequestPlan * rp
Associated request plan (tells us one of the peers that we plan to forward the request to).
struct GSF_PendingRequestPlanBijection * prev_PE
This is a doubly-linked list.
An active request.
Information we keep per request per peer.
uint64_t priority
Current priority for this request for this target.
struct GNUNET_TIME_Absolute earliest_transmission
Earliest time we'd be happy to (re)transmit this request.
unsigned int transmission_counter
How often did we transmit this request to this peer?
struct GSF_RequestPlan * next
This is a doubly-linked list.
struct PeerPlan * pp
The transmission plan for a peer that this request is associated with.
struct GSF_PendingRequestPlanBijection * pe_head
Head of list of associated pending requests.
struct GNUNET_CONTAINER_HeapNode * hn
Heap node associated with this request and this peer.
struct GNUNET_TIME_Absolute last_transmission
When was the last time we transmitted this request to this peer? 0 for never.
struct GSF_PendingRequestPlanBijection * pe_tail
Tail of list of associated pending requests.
struct GSF_RequestPlan * prev
This is a doubly-linked list.
Closure for merge_pr().
int merged
Set to GNUNET_YES if we succeeded to merge.
struct GSF_PendingRequest * pr
Request we are trying to merge.
Transmission plan for a peer.
struct GNUNET_SCHEDULER_Task * task
Current task for executing the plan.
struct GNUNET_CONTAINER_Heap * priority_heap
Heap with pending queries (struct GSF_RequestPlan), higher weights mean higher priority.
struct GNUNET_CONTAINER_MultiHashMap * plan_map
Map of queries to plan entries.
struct GNUNET_CONTAINER_Heap * delay_heap
Heap with pending queries (struct GSF_RequestPlan), by transmission time, lowest first.
struct GSF_ConnectedPeer * cp
Peer for which this is the plan.
struct GNUNET_MQ_Envelope * env
Current message under transmission for the plan.