GNUnet  0.10.x
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"
28 #include "gnunet-service-fs_cp.h"
29 #include "gnunet-service-fs_pe.h"
30 #include "gnunet-service-fs_pr.h"
31 
35 #define INSANE_STATISTICS GNUNET_NO
36 
41 struct PendingRequestList;
42 
46 struct PeerPlan;
47 
48 
67 {
68 
73 
78 
83 
88 
94 
100 
101 };
102 
103 
111 {
112 
117 
122 
127 
131  struct PeerPlan *pp;
132 
139 
144 
148  struct GNUNET_TIME_Absolute earliest_transmission;
149 
154 
158  uint64_t priority;
159 
163  unsigned int transmission_counter;
164 
165 };
166 
167 
171 struct PeerPlan
172 {
177 
182 
190 
195 
200 
205 
206 };
207 
208 
213 
217 static unsigned long long total_delay;
218 
222 static unsigned long long plan_count;
223 
224 
237 static const struct GNUNET_HashCode *
239 {
241 }
242 
243 
250 static void
251 plan (struct PeerPlan *pp,
252  struct GSF_RequestPlan *rp)
253 {
254 #define N ((double)128.0)
255 
258  static double avg_delay;
259 
260  struct GSF_PendingRequestData *prd;
261  struct GNUNET_TIME_Relative delay;
262 
263  GNUNET_assert (rp->pp == pp);
265  gettext_noop ("# average retransmission delay (ms)"),
266  total_delay * 1000LL / plan_count, GNUNET_NO);
268 
269  if (rp->transmission_counter < 8)
270  delay =
273  else if (rp->transmission_counter < 32)
274  delay =
276  8 +
277  (1LL << (rp->transmission_counter - 8)));
278  else
279  delay =
281  8 + (1LL << 24));
282  delay.rel_value_us =
284  delay.rel_value_us + 1);
285  /* Add 0.01 to avg_delay to avoid division-by-zero later */
286  avg_delay = (((avg_delay * (N - 1.0)) + delay.rel_value_us) / N) + 0.01;
287 
288  /*
289  * For the priority, we need to consider a few basic rules:
290  * 1) if we just started requesting (delay is small), we should
291  * virtually always have a priority of zero.
292  * 2) for requests with average latency, our priority should match
293  * the average priority observed on the network
294  * 3) even the longest-running requests should not be WAY out of
295  * the observed average (thus we bound by a factor of 2)
296  * 4) we add +1 to the observed average priority to avoid everyone
297  * staying put at zero (2 * 0 = 0...).
298  *
299  * Using the specific calculation below, we get:
300  *
301  * delay = 0 => priority = 0;
302  * delay = avg delay => priority = running-average-observed-priority;
303  * delay >> avg_delay => priority = 2 * running-average-observed-priority;
304  *
305  * which satisfies all of the rules above.
306  *
307  * Note: M_PI_4 = PI/4 = arctan(1)
308  */
309  rp->priority =
310  round ((GSF_current_priorities +
311  1.0) * atan (delay.rel_value_us / avg_delay)) / M_PI_4;
312  /* Note: usage of 'round' and 'atan' requires -lm */
313 
314  if (rp->transmission_counter != 0)
315  delay.rel_value_us += TTL_DECREMENT * 1000;
317  "Considering (re)transmission number %u in %s\n",
318  (unsigned int) rp->transmission_counter,
320  GNUNET_YES));
323  "Earliest (re)transmission for `%s' in %us\n",
324  GNUNET_h2s (&prd->query),
326  GNUNET_assert (rp->hn == NULL);
329  rp,
330  rp->priority);
331  else
332  rp->hn =
334  rp,
338  get_rp_key (rp),
339  rp));
340 #undef N
341 }
342 
343 
350 struct GSF_PendingRequest *
352 {
353  struct GSF_PendingRequest *ret;
355  const struct GSF_PendingRequestData *rprd;
356  const struct GSF_PendingRequestData *prd;
357 
358  bi = rp->pe_head;
359  if (NULL == bi)
360  return NULL; /* should never happen */
361  ret = bi->pr;
362  rprd = GSF_pending_request_get_data_ (ret);
363  for (bi = bi->next_PE; NULL != bi; bi = bi->next_PE)
364  {
367  prd = GSF_pending_request_get_data_ (bi->pr);
368  if (prd->ttl.abs_value_us > rprd->ttl.abs_value_us)
369  {
370  ret = bi->pr;
371  rprd = prd;
372  }
373  }
374  return ret;
375 }
376 
377 
383 static void
385 {
386  struct PeerPlan *pp = cls;
387  struct GSF_RequestPlan *rp;
388  struct GNUNET_TIME_Relative delay;
389 
390  if (NULL != pp->task)
391  {
392  pp->task = NULL;
393  }
394  else
395  {
396  GNUNET_assert (NULL != pp->env);
397  pp->env = NULL;
398  }
399  /* move ready requests to priority queue */
400  while ((NULL != (rp = GNUNET_CONTAINER_heap_peek (pp->delay_heap))) &&
403  {
406  rp,
407  rp->priority);
408  }
410  {
411  /* priority heap (still) empty, check for delay... */
413  if (NULL == rp)
414  {
416  "No active requests for plan %p.\n",
417  pp);
418  return; /* both queues empty */
419  }
422  "Sleeping for %s before retrying requests on plan %p.\n",
424  GNUNET_YES),
425  pp);
427  gettext_noop ("# delay heap timeout (ms)"),
428  delay.rel_value_us / 1000LL, GNUNET_NO);
429 
430  pp->task
433  pp);
434  return;
435  }
436 #if INSANE_STATISTICS
438  gettext_noop ("# query plans executed"),
439  1,
440  GNUNET_NO);
441 #endif
442  /* process from priority heap */
445  "Executing query plan %p\n",
446  rp);
447  GNUNET_assert (NULL != rp);
448  rp->hn = NULL;
450  rp->transmission_counter++;
451  total_delay++;
453  "Executing plan %p executed %u times, planning retransmission\n",
454  rp,
456  GNUNET_assert (NULL == pp->env);
460  pp);
461  GSF_peer_transmit_ (pp->cp,
462  GNUNET_YES,
463  rp->priority,
464  pp->env);
466  gettext_noop ("# query messages sent to other peers"),
467  1,
468  GNUNET_NO);
469  plan (pp,
470  rp);
471 }
472 
473 
478 {
479 
484 
488  int merged;
489 
490 };
491 
492 
503 static int
504 merge_pr (void *cls,
505  const struct GNUNET_HashCode *query,
506  void *element)
507 {
508  struct MergeContext *mpr = cls;
509  struct GSF_RequestPlan *rp = element;
510  struct GSF_PendingRequestData *prd;
512  struct GSF_PendingRequest *latest;
513 
516  if (GNUNET_OK !=
518  rp->pe_head->pr))
519  return GNUNET_YES;
520  /* merge new request with existing request plan */
522  bi->rp = rp;
523  bi->pr = mpr->pr;
524  prd = GSF_pending_request_get_data_ (mpr->pr);
526  prd->pr_head,
527  prd->pr_tail,
528  bi);
530  rp->pe_head,
531  rp->pe_tail,
532  bi);
533  mpr->merged = GNUNET_YES;
534 #if INSANE_STATISTICS
536  gettext_noop ("# requests merged"),
537  1,
538  GNUNET_NO);
539 #endif
540  latest = get_latest (rp);
541  if (GSF_pending_request_get_data_ (latest)->ttl.abs_value_us <
542  prd->ttl.abs_value_us)
543  {
544 #if INSANE_STATISTICS
546  gettext_noop ("# requests refreshed"),
547  1,
548  GNUNET_NO);
549 #endif
550  rp->transmission_counter = 0; /* reset */
551  }
552  return GNUNET_NO;
553 }
554 
555 
562 void
564  struct GSF_PendingRequest *pr)
565 {
566  const struct GNUNET_PeerIdentity *id;
567  struct PeerPlan *pp;
568  struct GSF_PendingRequestData *prd;
569  struct GSF_RequestPlan *rp;
571  struct MergeContext mpc;
572 
575  GNUNET_assert (NULL != cp);
577  pp = GNUNET_CONTAINER_multipeermap_get (plans, id);
578  if (NULL == pp)
579  {
580  pp = GNUNET_new (struct PeerPlan);
582  pp->priority_heap =
584  pp->delay_heap =
586  pp->cp = cp;
589  id,
590  pp,
593  pp);
594  }
595  mpc.merged = GNUNET_NO;
596  mpc.pr = pr;
599  &prd->query,
600  &merge_pr,
601  &mpc);
602  if (GNUNET_NO != mpc.merged)
603  return;
604  plan_count++;
606  gettext_noop ("# query plan entries"),
607  1,
608  GNUNET_NO);
610  "Planning transmission of query `%s' to peer `%s'\n",
611  GNUNET_h2s (&prd->query),
612  GNUNET_i2s (id));
613  rp = GNUNET_new (struct GSF_RequestPlan);
615  bi->rp = rp;
616  bi->pr = pr;
618  prd->pr_head,
619  prd->pr_tail,
620  bi);
622  rp->pe_head,
623  rp->pe_tail,
624  bi);
625  rp->pp = pp;
628  get_rp_key (rp),
629  rp,
631  plan (pp,
632  rp);
633 }
634 
635 
642 void
644 {
645  const struct GNUNET_PeerIdentity *id;
646  struct PeerPlan *pp;
647  struct GSF_RequestPlan *rp;
648  struct GSF_PendingRequestData *prd;
650 
652  pp = GNUNET_CONTAINER_multipeermap_get (plans, id);
653  if (NULL == pp)
654  return; /* nothing was ever planned for this peer */
657  pp));
658  if (NULL != pp->task)
659  {
661  pp->task = NULL;
662  }
663  while (NULL != (rp = GNUNET_CONTAINER_heap_remove_root (pp->priority_heap)))
664  {
667  get_rp_key (rp),
668  rp));
669  while (NULL != (bi = rp->pe_head))
670  {
672  rp->pe_head,
673  rp->pe_tail,
674  bi);
675  prd = GSF_pending_request_get_data_ (bi->pr);
677  prd->pr_head,
678  prd->pr_tail,
679  bi);
680  GNUNET_free (bi);
681  }
682  plan_count--;
683  GNUNET_free (rp);
684  }
686  while (NULL != (rp = GNUNET_CONTAINER_heap_remove_root (pp->delay_heap)))
687  {
690  get_rp_key (rp),
691  rp));
692  while (NULL != (bi = rp->pe_head))
693  {
694  prd = GSF_pending_request_get_data_ (bi->pr);
696  rp->pe_head,
697  rp->pe_tail,
698  bi);
700  prd->pr_head,
701  prd->pr_tail,
702  bi);
703  GNUNET_free (bi);
704  }
705  plan_count--;
706  GNUNET_free (rp);
707  }
709  gettext_noop ("# query plan entries"),
710  plan_count,
711  GNUNET_NO);
714  GNUNET_free (pp);
715 }
716 
717 
727 int
729  struct GSF_ConnectedPeer *sender,
731 {
733 
734  for (bi = pr_head; NULL != bi; bi = bi->next_PR)
735  {
736  if (bi->rp->pp->cp == sender)
737  {
738  if (0 == bi->rp->last_transmission.abs_value_us)
740  else
741  *result = bi->rp->last_transmission;
742  return GNUNET_YES;
743  }
744  }
745  return GNUNET_NO;
746 }
747 
748 
755 void
757 {
758  struct GSF_RequestPlan *rp;
759  struct GSF_PendingRequestData *prd;
761 
763  while (NULL != (bi = prd->pr_head))
764  {
765  rp = bi->rp;
767  prd->pr_head,
768  prd->pr_tail,
769  bi);
771  rp->pe_head,
772  rp->pe_tail,
773  bi);
774  GNUNET_assert (bi->pr == pr);
775  if (NULL == rp->pe_head)
776  {
778  plan_count--;
781  &prd->query,
782  rp));
783  GNUNET_free (rp);
784  }
785  GNUNET_free (bi);
786  }
788  gettext_noop ("# query plan entries"),
789  plan_count,
790  GNUNET_NO);
791 }
792 
793 
797 void
799 {
801  GNUNET_YES);
802 }
803 
804 
808 void
810 {
813 }
814 
815 
816 
817 /* end of gnunet-service-fs_pe.h */
API to handle &#39;connected peers&#39;.
Closure for merge_pr().
void GSF_plan_add_(struct GSF_ConnectedPeer *cp, struct GSF_PendingRequest *pr)
Create a new query plan entry.
uint64_t rel_value_us
The actual value.
static unsigned long long total_delay
Sum of all transmission counters (equals total delay for all plan entries).
void GSF_plan_done()
Shutdown plan subsystem.
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, that was sent to sender.
struct GSF_RequestPlan * next
This is a doubly-linked list.
static GNUNET_CronTime last_transmission
struct GNUNET_CONTAINER_MultiHashMap * plan_map
Map of queries to plan entries.
struct GSF_PendingRequestPlanBijection * next_PE
This is a doubly-linked list.
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.
double GSF_current_priorities
Typical priorities we&#39;re seeing from other peers right now.
struct GNUNET_TIME_Absolute ttl
Current TTL for the request.
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:245
Transmission plan for a peer.
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
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.
#define GNUNET_TIME_UNIT_SECONDS
One second.
struct GNUNET_MQ_Envelope * env
Current message under transmission for the plan.
static unsigned long long plan_count
Number of plan entries.
struct GSF_PendingRequestPlanBijection * pr_head
Fields for the plan module to track a DLL with the request.
struct GNUNET_STATISTICS_Handle * GSF_stats
Handle for reporting statistics.
int 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.
#define GNUNET_NO
Definition: gnunet_common.h:81
shared data structures of gnunet-service-fs.c
struct GSF_PendingRequestPlanBijection * next_PR
This is a doubly-linked list.
static struct GNUNET_IDENTITY_Handle * id
Handle to identity service.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_new(type)
Allocate a struct or union of the given type.
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 ...
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_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).
static int ret
Final status code.
Definition: gnunet-arm.c:89
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.
#define N
uint64_t abs_value_us
The actual value.
Internal representation of the hash map.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
struct GSF_ConnectedPeer * cp
Peer for which this is the plan.
struct GSF_RequestPlan * rp
Associated request plan (tells us one of the peers that we plan to forward the request to)...
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
struct GNUNET_HashCode query
Primary query hash for this request.
struct GSF_PendingRequestPlanBijection * pe_head
Head of list of associated pending requests.
struct GSF_PendingRequestPlanBijection * pe_tail
Tail of list of associated pending requests.
API to handle pending requests.
struct GNUNET_CONTAINER_Heap * delay_heap
Heap with pending queries (struct GSF_RequestPlan), by transmission time, lowest first.
Public data (in the sense of not encapsulated within &#39;gnunet-service-fs_pr&#39;, not in the sense of netw...
int merged
Set to GNUNET_YES if we succeeded to merge.
API to manage query plan.
static void schedule_peer_transmission(void *cls)
Figure out when and how to transmit to the given peer.
#define GNUNET_CONTAINER_MDLL_insert(mdll, head, tail, element)
Insert an element at the head of a MDLL.
struct GNUNET_TIME_Absolute earliest_transmission
Earliest time we&#39;d be happy to (re)transmit this request.
struct PeerPlan * pp
The transmission plan for a peer that this request is associated with.
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:774
unsigned int transmission_counter
How often did we transmit this request to this peer?
int GSF_pending_request_test_active_(struct GSF_PendingRequest *pr)
Check if the given request is still active.
void GSF_plan_init()
Initialize plan subsystem.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
#define GNUNET_CONTAINER_MDLL_remove(mdll, head, tail, element)
Remove an element from a MDLL.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1273
void * GNUNET_CONTAINER_heap_peek(const struct GNUNET_CONTAINER_Heap *heap)
Get element stored at the root of heap.
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:727
int GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
static int result
Global testing status.
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:439
static void plan(struct PeerPlan *pp, struct GSF_RequestPlan *rp)
Insert the given request plan into the heap with the appropriate weight.
Handle to a node in a heap.
Internal representation of the hash map.
Heap with the minimum cost at the root.
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_CONTAINER_heap_destroy(struct GNUNET_CONTAINER_Heap *heap)
Destroys the heap.
A 512-bit hashcode.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
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...
Node in the heap.
struct GSF_PendingRequest * pr
Associated pending request (identifies request details and one of the origins of the request)...
unsigned int GNUNET_CONTAINER_heap_get_size(const struct GNUNET_CONTAINER_Heap *heap)
Get the current size of the heap.
There must only be one value per key; storing a value should fail if a value under the same key alrea...
struct GSF_PendingRequestPlanBijection * pr_tail
Fields for the plan module to track a DLL with the request.
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.
int 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.
Information we keep per request per peer.
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
struct GNUNET_CONTAINER_Heap * GNUNET_CONTAINER_heap_create(enum GNUNET_CONTAINER_HeapOrder order)
Create a new heap.
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...
Allow multiple values with the same key.
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.
The identity of the host (wraps the signing key of the peer).
struct GSF_PendingRequestData * GSF_pending_request_get_data_(struct GSF_PendingRequest *pr)
Obtain the public data associated with a pending request.
const struct GNUNET_PeerIdentity * GSF_connected_peer_get_identity2_(const struct GSF_ConnectedPeer *cp)
Obtain the identity of a connected peer.
int GNUNET_CONTAINER_multihashmap_get_multiple(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, GNUNET_CONTAINER_HashMapIterator it, void *it_cls)
Iterate over all entries in the map that match a particular key.
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.
Heap with the maximum cost at the root.
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:134
void * GNUNET_CONTAINER_heap_remove_root(struct GNUNET_CONTAINER_Heap *heap)
Remove root of the heap.
#define TTL_DECREMENT
By which amount do we decrement the TTL for simple forwarding / indirection of the query; in milli-se...
struct GSF_PendingRequest * pr
Request we are trying to merge.
A connected peer.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
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...
struct GSF_RequestPlan * prev
This is a doubly-linked list.
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:331
Time for absolute times used by GNUnet, in microseconds.
struct GSF_PendingRequestPlanBijection * prev_PR
This is a doubly-linked list.
#define GNUNET_YES
Definition: gnunet_common.h:80
struct GNUNET_SCHEDULER_Task * task
Current task for executing the plan.
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.
unsigned int GNUNET_CONTAINER_multipeermap_size(const struct GNUNET_CONTAINER_MultiPeerMap *map)
Get the number of key-value pairs in the map.
An active request.
uint64_t priority
Current priority for this request for this target.
static struct GNUNET_CONTAINER_MultiPeerMap * plans
Hash map from peer identities to PeerPlans.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_at(struct GNUNET_TIME_Absolute at, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run at the specified time.
Definition: scheduler.c:1223
void * GNUNET_CONTAINER_heap_remove_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from the heap.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
struct GSF_PendingRequestPlanBijection * prev_PE
This is a doubly-linked list.
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
struct GSF_PendingRequest * get_latest(const struct GSF_RequestPlan *rp)
Get the pending request with the highest TTL from the given plan.
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
M:N binding of plans to pending requests.
#define gettext_noop(String)
Definition: gettext.h:69
struct GNUNET_CONTAINER_Heap * priority_heap
Heap with pending queries (struct GSF_RequestPlan), higher weights mean higher priority.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965