GNUnet  0.10.x
Data Structures | Macros | Functions
plugin_ats2_simple.c File Reference

ATS simple solver. More...

#include "platform.h"
#include "gnunet_ats_plugin_new.h"
#include "gnunet_hello_lib.h"
#include "gnunet_peerstore_service.h"
#include "plugin_ats2_common.c"
Include dependency graph for plugin_ats2_simple.c:

Go to the source code of this file.

Data Structures

struct  Hello
 Entry in list of addresses we could try per peer. More...
 
struct  GNUNET_ATS_SessionHandle
 Internal representation of a session by the plugin. More...
 
struct  Peer
 Information about preferences and sessions we track per peer. More...
 
struct  Network
 Representation of a network (to be expanded...) More...
 
struct  SimpleHandle
 A handle for the proportional solver. More...
 
struct  Counters
 Closure for update_counters and update_allocation. More...
 

Macros

#define LOG(kind, ...)   GNUNET_log_from (kind, "ats-simple", __VA_ARGS__)
 
#define SUGGEST_FREQ   GNUNET_TIME_UNIT_SECONDS
 Base frequency at which we suggest addresses to transport. More...
 
#define MIN_BANDWIDTH_PER_SESSION   1024
 What is the minimum bandwidth we always try to allocate for any session that is up? (May still be scaled down lower if the number of sessions is so high that the total bandwidth is insufficient to allow for this value to be granted.) More...
 

Functions

struct Peerlookup_peer (struct SimpleHandle *h, const struct GNUNET_PeerIdentity *pid)
 Lookup peer in the peers map. More...
 
static int peer_test_dead (struct Peer *p)
 Check if there is any interesting information left we store about the peer in p. More...
 
static void suggest_hello (struct Hello *hello)
 Contact the transport service and suggest to it to try connecting to the address of hello. More...
 
static void suggest_start_cb (void *cls)
 Consider suggesting a HELLO (without a session) to transport. More...
 
static void watch_cb (void *cls, const struct GNUNET_PEERSTORE_Record *record, const char *emsg)
 Function called by PEERSTORE for each matching record. More...
 
static struct Peerpeer_add (struct SimpleHandle *h, const struct GNUNET_PeerIdentity *pid)
 Find or add peer if necessary. More...
 
static void peer_free (struct Peer *p)
 Free the entry (and associated tasks) of peer p. More...
 
static void consider_notify_transport (struct GNUNET_ATS_SessionHandle *sh)
 Check if the new allocation for sh is significantly different from the last one, and if so, tell transport. More...
 
static int update_counters (void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
 Function used to iterate over all peers and collect counter data. More...
 
static int update_allocation (void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
 Function used to iterate over all peers and collect counter data. More...
 
static void update (struct SimpleHandle *h)
 The world changed, recalculate our allocations. More...
 
static struct GNUNET_ATS_PreferenceHandle * simple_preference_add (void *cls, const struct GNUNET_ATS_Preference *pref)
 The plugin should begin to respect a new preference. More...
 
static void simple_preference_del (void *cls, struct GNUNET_ATS_PreferenceHandle *ph, const struct GNUNET_ATS_Preference *pref)
 The plugin should end respecting a preference. More...
 
static struct GNUNET_ATS_SessionHandlesimple_session_add (void *cls, const struct GNUNET_ATS_SessionData *data, const char *address)
 Transport established a new session with performance characteristics given in data. More...
 
static void simple_session_update (void *cls, struct GNUNET_ATS_SessionHandle *sh, const struct GNUNET_ATS_SessionData *data)
 data changed for a given sh, solver should consider the updated performance characteristics. More...
 
static void simple_session_del (void *cls, struct GNUNET_ATS_SessionHandle *sh, const struct GNUNET_ATS_SessionData *data)
 A session went away. More...
 
void * libgnunet_plugin_ats2_simple_init (void *cls)
 Function invoked when the plugin is loaded. More...
 
void * libgnunet_plugin_ats2_simple_done (void *cls)
 Function used to unload the plugin. More...
 

Detailed Description

ATS simple solver.

Author
Matthias Wachs
Christian Grothoff

TODO:

Definition in file plugin_ats2_simple.c.

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from (kind, "ats-simple", __VA_ARGS__)

Definition at line 34 of file plugin_ats2_simple.c.

◆ SUGGEST_FREQ

#define SUGGEST_FREQ   GNUNET_TIME_UNIT_SECONDS

Base frequency at which we suggest addresses to transport.

Multiplied by the square of the number of active connections (and randomized) to calculate the actual frequency at which we will suggest addresses to the transport. Furthermore, each address is also bounded by an exponential back-off.

Definition at line 44 of file plugin_ats2_simple.c.

Referenced by suggest_start_cb().

◆ MIN_BANDWIDTH_PER_SESSION

#define MIN_BANDWIDTH_PER_SESSION   1024

What is the minimum bandwidth we always try to allocate for any session that is up? (May still be scaled down lower if the number of sessions is so high that the total bandwidth is insufficient to allow for this value to be granted.)

Definition at line 52 of file plugin_ats2_simple.c.

Referenced by update_counters().

Function Documentation

◆ lookup_peer()

struct Peer* lookup_peer ( struct SimpleHandle h,
const struct GNUNET_PeerIdentity pid 
)

Lookup peer in the peers map.

Parameters
hhandle to look up in
pidpeer identity to look up by
Returns
NULL for not found

Definition at line 314 of file plugin_ats2_simple.c.

References GNUNET_CONTAINER_multipeermap_get(), and SimpleHandle::peers.

Referenced by peer_add(), and simple_preference_del().

315 {
316  return GNUNET_CONTAINER_multipeermap_get (h->peers, pid);
317 }
struct GNUNET_CONTAINER_MultiPeerMap * peers
Information we track for each peer.
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.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ peer_test_dead()

static int peer_test_dead ( struct Peer p)
static

Check if there is any interesting information left we store about the peer in p.

Parameters
ppeer to test if we can drop the data structure
Returns
GNUNET_YES if no information is left in p

Definition at line 328 of file plugin_ats2_simple.c.

References Peer::bw_by_pk, GNUNET_MQ_PREFERENCE_COUNT, GNUNET_NO, GNUNET_YES, pk, and Peer::sh_head.

Referenced by simple_preference_del(), and simple_session_del().

329 {
331  pk++)
332  if (0 != p->bw_by_pk[pk])
333  return GNUNET_NO;
334  if (NULL != p->sh_head)
335  return GNUNET_NO;
336  return GNUNET_YES;
337 }
uint64_t bw_by_pk[GNUNET_MQ_PREFERENCE_COUNT]
Array where we sum up the bandwidth requests received indexed by preference kind (see enum GNUNET_MQ_...
static struct GNUNET_CRYPTO_EddsaPrivateKey * pk
Private key of this peer.
#define GNUNET_NO
Definition: gnunet_common.h:78
struct GNUNET_ATS_SessionHandle * sh_head
Kept in DLL per peer.
GNUNET_MQ_PreferenceKind
Enum defining all known preference categories.
#define GNUNET_MQ_PREFERENCE_COUNT
#define GNUNET_YES
Definition: gnunet_common.h:77
Here is the caller graph for this function:

◆ suggest_hello()

static void suggest_hello ( struct Hello hello)
static

Contact the transport service and suggest to it to try connecting to the address of hello.

Updates backoff and timestamp values in the hello.

Parameters
hello[in,out]address suggestion to make

Definition at line 348 of file plugin_ats2_simple.c.

References Hello::address, Hello::backoff, GNUNET_ATS_PluginEnvironment::cls, SimpleHandle::env, Hello::expiration, GNUNET_TIME_absolute_get(), GNUNET_TIME_absolute_get_remaining(), GNUNET_TIME_randomized_backoff(), h, Peer::h, Hello::last_attempt, Peer::last_suggestion, p, Hello::peer, Peer::pid, and GNUNET_ATS_PluginEnvironment::suggest_cb.

Referenced by suggest_start_cb().

349 {
350  struct Peer *p = hello->peer;
351  struct SimpleHandle *h = p->h;
352 
354  hello->backoff =
357  hello->expiration));
358  h->env->suggest_cb (h->env->cls, &p->pid, hello->address);
359 }
struct GNUNET_TIME_Absolute last_suggestion
When did we last suggest an address to connect to for this peer?
struct GNUNET_TIME_Absolute last_attempt
When did we try it last?
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:99
struct GNUNET_ATS_PluginEnvironment * env
Our execution environment.
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
struct GNUNET_TIME_Absolute expiration
When does the HELLO expire?
struct SimpleHandle * h
The handle for the proportional solver.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
struct Peer * peer
Peer this hello belongs to.
struct GNUNET_PeerIdentity pid
Which peer is this for?
void(* suggest_cb)(void *cls, const struct GNUNET_PeerIdentity *pid, const char *address)
Suggest to the transport that it should try establishing a connection using the given address...
struct GNUNET_TIME_Relative backoff
Current exponential backoff value.
Information about preferences and sessions we track per peer.
const char * address
The address we could try.
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
void * cls
Closure to pass to all callbacks in this struct.
A handle for the proportional solver.
struct GNUNET_TIME_Relative GNUNET_TIME_randomized_backoff(struct GNUNET_TIME_Relative rt, struct GNUNET_TIME_Relative threshold)
Randomized exponential back-off, starting at 1 ms and going up by a factor of 2+r, where 0 <= r <= 0.5, up to a maximum of the given threshold.
Definition: time.c:758
Here is the call graph for this function:
Here is the caller graph for this function:

◆ suggest_start_cb()

static void suggest_start_cb ( void *  cls)
static

Consider suggesting a HELLO (without a session) to transport.

We look at how many active sessions we have for the peer, and if there are many, reduce the frequency of trying new addresses. Also, for each address we consider when we last tried it, and its exponential backoff if the attempt failed. Note that it is possible that this function is called when no suggestion is to be made.

In this case, we only calculate the time until we make the next suggestion.

Parameters
clsa struct Peer

Definition at line 377 of file plugin_ats2_simple.c.

References GNUNET_TIME_Absolute::abs_value_us, GNUNET_break, GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_SCHEDULER_add_delayed(), GNUNET_TIME_absolute_add(), GNUNET_TIME_absolute_get_remaining(), GNUNET_TIME_absolute_max(), GNUNET_TIME_randomized_backoff(), GNUNET_TIME_relative_multiply(), GNUNET_TIME_relative_to_absolute(), GNUNET_TIME_UNIT_FOREVER_ABS, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_TIME_UNIT_ZERO, Peer::h_head, Peer::h_tail, Hello::next, GNUNET_ATS_SessionHandle::next, p, GNUNET_TIME_Relative::rel_value_us, Hello::sh, Peer::sh_head, SUGGEST_FREQ, suggest_hello(), and Peer::task.

Referenced by simple_session_del(), and watch_cb().

378 {
379  struct Peer *p = cls;
381  struct Hello *hello = NULL;
383  struct GNUNET_TIME_Relative xdelay;
384  struct GNUNET_TIME_Absolute xnext;
385  unsigned int num_sessions = 0;
386  uint32_t sq;
387 
388  /* count number of active sessions */
389  for (struct GNUNET_ATS_SessionHandle *sh = p->sh_head; NULL != sh;
390  sh = sh->next)
391  num_sessions++;
392  /* calculate square of number of sessions */
393  num_sessions++; /* start with 1, even if we have zero sessions */
394  if (num_sessions < UINT16_MAX)
395  sq = num_sessions * (uint32_t) num_sessions;
396  else
397  sq = UINT32_MAX;
398  xdelay =
400  sq),
402  xnext = GNUNET_TIME_relative_to_absolute (xdelay);
403 
404  p->task = NULL;
405  while (0 == delay.rel_value_us)
406  {
407  struct Hello *next;
408  struct GNUNET_TIME_Absolute xmax;
409 
410  if (NULL != hello)
411  {
412  /* We went through the loop already once and found
413  a HELLO that is due *now*, so make a suggestion! */
414  GNUNET_break (NULL == hello->sh);
415  suggest_hello (hello);
416  hello = NULL;
418  }
419  for (struct Hello *pos = p->h_head; NULL != pos; pos = next)
420  {
421  struct GNUNET_TIME_Absolute pt;
422 
423  next = pos->next;
424  if (NULL != pos->sh)
425  continue;
426  if (0 ==
428  {
429  /* expired, remove! */
431  GNUNET_free (pos);
432  continue;
433  }
434  pt = GNUNET_TIME_absolute_add (pos->last_attempt, pos->backoff);
435  if ((NULL == hello) || (pt.abs_value_us < hpt.abs_value_us))
436  {
437  hello = pos;
438  hpt = pt;
439  }
440  }
441  if (NULL == hello)
442  return; /* no HELLOs that could still be tried */
443 
444  /* hpt is now the *earliest* possible time for any HELLO
445  but we might not want to go for as early as possible for
446  this peer. So the actual time is the max of the earliest
447  HELLO and the 'xnext' */
448  xmax = GNUNET_TIME_absolute_max (hpt, xnext);
449  delay = GNUNET_TIME_absolute_get_remaining (xmax);
450  }
452 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
uint64_t rel_value_us
The actual value.
static void suggest_hello(struct Hello *hello)
Contact the transport service and suggest to it to try connecting to the address of hello...
Internal representation of a session by the plugin.
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:246
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_add(struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Relative duration)
Add a given relative duration to the given start time.
Definition: time.c:393
uint64_t abs_value_us
The actual value.
#define SUGGEST_FREQ
Base frequency at which we suggest addresses to transport.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
struct Hello * h_tail
Kept in a DLL.
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:1253
struct GNUNET_ATS_SessionHandle * sh_head
Kept in DLL per peer.
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
static struct SolverHandle * sh
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_max(struct GNUNET_TIME_Absolute t1, struct GNUNET_TIME_Absolute t2)
Return the maximum of two absolute time values.
Definition: time.c:317
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:440
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
struct Hello * h_head
Kept in a DLL.
Entry in list of addresses we could try per peer.
static struct GNUNET_TIME_Relative delay
When should dkg communication start?
#define GNUNET_TIME_UNIT_ZERO
Relative time zero.
struct GNUNET_SCHEDULER_Task * task
Task used to try again to suggest an address for this peer.
Information about preferences and sessions we track per peer.
static void suggest_start_cb(void *cls)
Consider suggesting a HELLO (without a session) to transport.
struct Hello * next
Kept in a DLL.
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 GNUNET_ATS_SessionHandle * sh
Is a session with this address already up? If not, set to NULL.
struct GNUNET_TIME_Relative GNUNET_TIME_randomized_backoff(struct GNUNET_TIME_Relative rt, struct GNUNET_TIME_Relative threshold)
Randomized exponential back-off, starting at 1 ms and going up by a factor of 2+r, where 0 <= r <= 0.5, up to a maximum of the given threshold.
Definition: time.c:758
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ watch_cb()

static void watch_cb ( void *  cls,
const struct GNUNET_PEERSTORE_Record record,
const char *  emsg 
)
static

Function called by PEERSTORE for each matching record.

Parameters
clsclosure with a struct Peer
recordpeerstore record information
emsgerror message, or NULL if no errors

Definition at line 463 of file plugin_ats2_simple.c.

References GNUNET_TIME_Absolute::abs_value_us, Hello::address, GNUNET_ATS_SessionHandle::address, Hello::expiration, GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_DLL_insert, GNUNET_free, GNUNET_HELLO_extract_address(), GNUNET_malloc, GNUNET_memcmp, GNUNET_PEERSTORE_TRANSPORT_URLADDRESS_KEY, GNUNET_SCHEDULER_add_now(), GNUNET_TIME_absolute_get_remaining(), Peer::h_head, Peer::h_tail, GNUNET_ATS_SessionHandle::hello, GNUNET_PEERSTORE_Record::key, Hello::next, GNUNET_ATS_SessionHandle::next, Hello::nt, p, Hello::peer, GNUNET_PEERSTORE_Record::peer, Peer::pid, Hello::sh, Peer::sh_head, suggest_start_cb(), Peer::task, GNUNET_PEERSTORE_Record::value, and GNUNET_PEERSTORE_Record::value_size.

Referenced by peer_add().

466 {
467  struct Peer *p = cls;
468  char *addr;
469  size_t alen;
470  enum GNUNET_NetworkType nt;
472  struct Hello *hello;
473 
474  if (0 != GNUNET_memcmp (&p->pid, &record->peer))
475  {
476  GNUNET_break (0);
477  return;
478  }
479  if (0 != strcmp (record->key, GNUNET_PEERSTORE_TRANSPORT_URLADDRESS_KEY))
480  {
481  GNUNET_break (0);
482  return;
483  }
484  addr = GNUNET_HELLO_extract_address (record->value,
485  record->value_size,
486  &p->pid,
487  &nt,
488  &expiration);
489  if (NULL == addr)
490  return; /* invalid hello, bad signature, other problem */
491  if (0 == GNUNET_TIME_absolute_get_remaining (expiration).rel_value_us)
492  {
493  /* expired, ignore */
494  GNUNET_free (addr);
495  return;
496  }
497  /* check if addr is already known */
498  for (struct Hello *he = p->h_head; NULL != he; he = he->next)
499  {
500  if (0 != strcmp (he->address, addr))
501  continue;
502  if (he->expiration.abs_value_us < expiration.abs_value_us)
503  {
504  he->expiration = expiration;
505  he->nt = nt;
506  }
507  GNUNET_free (addr);
508  return;
509  }
510  /* create new HELLO */
511  alen = strlen (addr) + 1;
512  hello = GNUNET_malloc (sizeof(struct Hello) + alen);
513  hello->address = (const char *) &hello[1];
514  hello->expiration = expiration;
515  hello->nt = nt;
516  hello->peer = p;
517  memcpy (&hello[1], addr, alen);
518  GNUNET_CONTAINER_DLL_insert (p->h_head, p->h_tail, hello);
519  /* check if sh for this HELLO already exists */
520  for (struct GNUNET_ATS_SessionHandle *sh = p->sh_head; NULL != sh;
521  sh = sh->next)
522  {
523  if ((NULL == sh->address) || (0 != strcmp (sh->address, addr)))
524  continue;
525  GNUNET_assert (NULL == sh->hello);
526  sh->hello = hello;
527  hello->sh = sh;
528  break;
529  }
530  GNUNET_free (addr);
531  if (NULL == p->task)
533 }
enum GNUNET_NetworkType nt
Type of the network for this HELLO.
static char * expiration
Credential TTL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
struct GNUNET_PeerIdentity peer
Peer Identity.
size_t value_size
Size of value BLOB.
Internal representation of a session by the plugin.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
GNUNET_NetworkType
Types of networks (with separate quotas) we support.
Definition: gnunet_nt_lib.h:35
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
char * key
Record key string.
struct Hello * h_tail
Kept in a DLL.
struct GNUNET_ATS_SessionHandle * sh_head
Kept in DLL per peer.
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
void * value
Record value BLOB.
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:1280
struct GNUNET_TIME_Absolute expiration
When does the HELLO expire?
static struct SolverHandle * sh
struct Hello * h_head
Kept in a DLL.
Entry in list of addresses we could try per peer.
static struct GNUNET_NAT_AUTO_Test * nt
Handle to a NAT test operation.
struct Peer * peer
Peer this hello belongs to.
struct GNUNET_PeerIdentity pid
Which peer is this for?
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
struct GNUNET_SCHEDULER_Task * task
Task used to try again to suggest an address for this peer.
#define GNUNET_PEERSTORE_TRANSPORT_URLADDRESS_KEY
Key used for storing addresses in URL format in the peerstore.
Information about preferences and sessions we track per peer.
static void suggest_start_cb(void *cls)
Consider suggesting a HELLO (without a session) to transport.
struct Hello * next
Kept in a DLL.
const char * address
The address we could try.
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 GNUNET_ATS_SessionHandle * sh
Is a session with this address already up? If not, set to NULL.
char * GNUNET_HELLO_extract_address(const void *raw, size_t raw_size, const struct GNUNET_PeerIdentity *pid, enum GNUNET_NetworkType *nt, struct GNUNET_TIME_Absolute *mono_time)
Check signature and extract address record.
Definition: hello-ng.c:108
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ peer_add()

static struct Peer* peer_add ( struct SimpleHandle h,
const struct GNUNET_PeerIdentity pid 
)
static

Find or add peer if necessary.

Parameters
hour plugin handle
pidthe peer identity to add/look for
Returns
a peer handle

Definition at line 544 of file plugin_ats2_simple.c.

References GNUNET_assert, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CONTAINER_multipeermap_put(), GNUNET_new, GNUNET_PEERSTORE_TRANSPORT_URLADDRESS_KEY, GNUNET_PEERSTORE_watch(), GNUNET_YES, h, Peer::h, lookup_peer(), p, SimpleHandle::peers, pid, Peer::pid, SimpleHandle::ps, watch_cb(), and Peer::wc.

Referenced by simple_preference_add(), and simple_session_add().

545 {
546  struct Peer *p = lookup_peer (h, pid);
547 
548  if (NULL != p)
549  return p;
550  p = GNUNET_new (struct Peer);
551  p->h = h;
552  p->pid = *pid;
553  p->wc = GNUNET_PEERSTORE_watch (h->ps,
554  "transport",
555  &p->pid,
557  &watch_cb,
558  p);
561  h->peers,
562  &p->pid,
563  p,
565 
566  return p;
567 }
struct GNUNET_PEERSTORE_WatchContext * GNUNET_PEERSTORE_watch(struct GNUNET_PEERSTORE_Handle *h, const char *sub_system, const struct GNUNET_PeerIdentity *peer, const char *key, GNUNET_PEERSTORE_Processor callback, void *callback_cls)
Request watching a given key User will be notified with any new values added to key.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static void watch_cb(void *cls, const struct GNUNET_PEERSTORE_Record *record, const char *emsg)
Function called by PEERSTORE for each matching record.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:99
struct GNUNET_PEERSTORE_Handle * ps
Handle to the peerstore service.
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
struct SimpleHandle * h
The handle for the proportional solver.
struct GNUNET_CONTAINER_MultiPeerMap * peers
Information we track for each peer.
There must only be one value per key; storing a value should fail if a value under the same key alrea...
struct GNUNET_PeerIdentity pid
Which peer is this for?
#define GNUNET_PEERSTORE_TRANSPORT_URLADDRESS_KEY
Key used for storing addresses in URL format in the peerstore.
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.
Information about preferences and sessions we track per peer.
struct Peer * lookup_peer(struct SimpleHandle *h, const struct GNUNET_PeerIdentity *pid)
Lookup peer in the peers map.
#define GNUNET_YES
Definition: gnunet_common.h:77
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
struct GNUNET_PEERSTORE_WatchContext * wc
Watch context where we are currently looking for HELLOs for this peer.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ peer_free()

static void peer_free ( struct Peer p)
static

Free the entry (and associated tasks) of peer p.

Note that p must be dead already (see peer_test_dead()).

Parameters
pthe peer to free

Definition at line 577 of file plugin_ats2_simple.c.

References GNUNET_assert, GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_multipeermap_remove(), GNUNET_free, GNUNET_PEERSTORE_watch_cancel(), GNUNET_SCHEDULER_cancel(), GNUNET_YES, h, Peer::h, Peer::h_head, Peer::h_tail, SimpleHandle::peers, Peer::pid, Hello::sh, Peer::sh_head, Peer::task, and Peer::wc.

Referenced by simple_preference_del(), and simple_session_del().

578 {
579  struct SimpleHandle *h = p->h;
580  struct Hello *hello;
581 
582  GNUNET_assert (NULL == p->sh_head);
583  while (NULL != (hello = p->h_head))
584  {
585  GNUNET_CONTAINER_DLL_remove (p->h_head, p->h_tail, hello);
586  GNUNET_assert (NULL == hello->sh);
587  GNUNET_free (hello);
588  }
589  if (NULL != p->task)
590  {
592  p->task = NULL;
593  }
594  if (NULL != p->wc)
595  {
597  p->wc = NULL;
598  }
601  GNUNET_free (p);
602 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
void GNUNET_PEERSTORE_watch_cancel(struct GNUNET_PEERSTORE_WatchContext *wc)
Cancel a watch request.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
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.
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:99
struct Hello * h_tail
Kept in a DLL.
struct GNUNET_ATS_SessionHandle * sh_head
Kept in DLL per peer.
struct SimpleHandle * h
The handle for the proportional solver.
struct GNUNET_CONTAINER_MultiPeerMap * peers
Information we track for each peer.
struct Hello * h_head
Kept in a DLL.
Entry in list of addresses we could try per peer.
struct GNUNET_PeerIdentity pid
Which peer is this for?
struct GNUNET_SCHEDULER_Task * task
Task used to try again to suggest an address for this peer.
#define GNUNET_YES
Definition: gnunet_common.h:77
struct GNUNET_ATS_SessionHandle * sh
Is a session with this address already up? If not, set to NULL.
A handle for the proportional solver.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_PEERSTORE_WatchContext * wc
Watch context where we are currently looking for HELLOs for this peer.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966
Here is the call graph for this function:
Here is the caller graph for this function:

◆ consider_notify_transport()

static void consider_notify_transport ( struct GNUNET_ATS_SessionHandle sh)
static

Check if the new allocation for sh is significantly different from the last one, and if so, tell transport.

Parameters
shsession handle to consider updating transport for

Definition at line 612 of file plugin_ats2_simple.c.

References GNUNET_ATS_PluginEnvironment::allocate_cb, GNUNET_ATS_SessionHandle::bw_in, GNUNET_ATS_SessionHandle::bw_out, GNUNET_ATS_PluginEnvironment::cls, GNUNET_ATS_SessionHandle::data, SimpleHandle::env, GNUNET_TIME_absolute_get(), GNUNET_TIME_absolute_get_duration(), h, Peer::h, GNUNET_ATS_SessionHandle::last_allocation, SimpleHandle::networks, GNUNET_ATS_Properties::nt, Hello::nt, Hello::peer, GNUNET_ATS_SessionHandle::peer, Peer::pid, GNUNET_ATS_SessionData::prop, GNUNET_TIME_Relative::rel_value_us, GNUNET_ATS_SessionHandle::session, GNUNET_ATS_SessionHandle::target_in, GNUNET_ATS_SessionHandle::target_out, Network::total_quota_in, Network::total_quota_out, and GNUNET_BANDWIDTH_Value32NBO::value__.

Referenced by update_allocation().

613 {
614  struct Peer *peer = sh->peer;
615  struct SimpleHandle *h = peer->h;
616  enum GNUNET_NetworkType nt = sh->data->prop.nt;
618  uint64_t sig_in;
619  uint64_t sig_out;
620  int64_t delta_in;
621  int64_t delta_out;
622 
624  /* A significant change is more than 10% of the quota,
625  which is given in bytes/second */
626  sig_in = h->networks[nt].total_quota_in * (delay.rel_value_us / 1000LL)
627  / 1000LL / 10;
628  sig_out = h->networks[nt].total_quota_out * (delay.rel_value_us / 1000LL)
629  / 1000LL / 10;
630  delta_in = ((int64_t) ntohl (sh->bw_in.value__)) - ((int64_t) sh->target_in);
631  delta_out = ((int64_t) ntohl (sh->bw_in.value__)) - ((int64_t) sh->target_in);
632  /* we want the absolute values */
633  if (delta_in < 0)
634  delta_in = -delta_in;
635  if (INT64_MIN == delta_in)
636  delta_in = INT64_MAX; /* Handle corner case: INT_MIN == - INT_MIN */
637  if (delta_out < 0)
638  delta_out = -delta_out;
639  if (INT64_MIN == delta_out)
640  delta_out = INT64_MAX; /* Handle corner case: INT_MIN == - INT_MIN */
641  if ((sig_in > delta_in) && (sig_out > delta_out))
642  return; /* insignificant change */
643  /* change is significant, tell transport! */
644  if (sh->target_in > UINT32_MAX)
645  sh->target_in = UINT32_MAX;
646  sh->bw_in.value__ = htonl ((uint32_t) sh->target_in);
647  if (sh->target_out > UINT32_MAX)
648  sh->target_out = UINT32_MAX;
649  sh->bw_out.value__ = htonl ((uint32_t) sh->target_out);
651  h->env->allocate_cb (h->env->cls,
652  sh->session,
653  &peer->pid,
654  sh->bw_in,
655  sh->bw_out);
656 }
uint64_t rel_value_us
The actual value.
unsigned long long total_quota_out
Total outbound quota.
const struct GNUNET_ATS_SessionData * data
Current performance data for this session.
uint64_t target_in
New BW-in allocation given to the transport service.
struct GNUNET_BANDWIDTH_Value32NBO bw_in
Last BW-in allocation given to the transport service.
struct Peer * peer
Peer this session is for.
GNUNET_NetworkType
Types of networks (with separate quotas) we support.
Definition: gnunet_nt_lib.h:35
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:99
uint32_t value__
The actual value (bytes per second).
struct GNUNET_ATS_PluginEnvironment * env
Our execution environment.
struct SimpleHandle * h
The handle for the proportional solver.
struct GNUNET_BANDWIDTH_Value32NBO bw_out
Last BW-out allocation given to the transport service.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
uint64_t target_out
New BW-out allocation given to the transport service.
static struct GNUNET_NAT_AUTO_Test * nt
Handle to a NAT test operation.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
unsigned long long total_quota_in
Total inbound quota.
struct GNUNET_PeerIdentity pid
Which peer is this for?
static struct GNUNET_TIME_Relative delay
When should dkg communication start?
enum GNUNET_NetworkType nt
Which network scope does the respective address belong to?
struct GNUNET_TIME_Absolute last_allocation
When did we last update transport about the allocation? Used to dampen the frequency of updates...
void(* allocate_cb)(void *cls, struct GNUNET_ATS_Session *session, const struct GNUNET_PeerIdentity *peer, struct GNUNET_BANDWIDTH_Value32NBO bw_in, struct GNUNET_BANDWIDTH_Value32NBO bw_out)
Tell the transport that it should allocate the given bandwidth to the specified session.
Information about preferences and sessions we track per peer.
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:373
struct Network networks[GNUNET_NT_COUNT]
Information we track per network type (quotas).
void * cls
Closure to pass to all callbacks in this struct.
A handle for the proportional solver.
Time for relative time used by GNUnet, in microseconds.
struct GNUNET_ATS_Session * session
The session in the main ATS service.
struct GNUNET_ATS_Properties prop
ATS performance characteristics for a session.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_counters()

static int update_counters ( void *  cls,
const struct GNUNET_PeerIdentity pid,
void *  value 
)
static

Function used to iterate over all peers and collect counter data.

Parameters
clsa struct Counters *
pididentity of the peer we process, unused
valuea struct Peer *
Returns
GNUNET_YES (continue to iterate)

Definition at line 707 of file plugin_ats2_simple.c.

References Peer::bw_by_pk, Counters::bw_in_by_nt, Counters::bw_out_by_nt, data, GNUNET_ATS_SessionHandle::data, GNUNET_ATS_Properties::delay, GNUNET_ATS_Properties::distance, GNUNET_assert, GNUNET_MAX, GNUNET_MIN, GNUNET_MQ_PREFERENCE_BANDWIDTH, GNUNET_MQ_PREFERENCE_COUNT, GNUNET_MQ_PREFERENCE_LATENCY, GNUNET_MQ_PREFERENCE_NONE, GNUNET_MQ_PREFERENCE_RELIABILITY, GNUNET_YES, GNUNET_ATS_Properties::goodput_in, GNUNET_ATS_Properties::goodput_out, MIN_BANDWIDTH_PER_SESSION, GNUNET_ATS_SessionHandle::next, Hello::nt, GNUNET_ATS_Properties::nt, Hello::peer, pk, GNUNET_ATS_SessionData::prop, GNUNET_TIME_Relative::rel_value_us, Hello::sh, Peer::sh_head, GNUNET_ATS_SessionHandle::target_out, GNUNET_ATS_Properties::utilization_out, and value.

Referenced by update().

708 {
709  struct Counters *c = cls;
710  struct Peer *peer = value;
712 
713  (void) pid;
714  if (NULL == peer->sh_head)
715  return GNUNET_YES; /* no available session, cannot allocate bandwidth */
716  memset (best, 0, sizeof(best));
717  for (struct GNUNET_ATS_SessionHandle *sh = peer->sh_head; NULL != sh;
718  sh = sh->next)
719  {
720  enum GNUNET_NetworkType nt = sh->data->prop.nt;
721 
722  sh->target_out = MIN_BANDWIDTH_PER_SESSION;
724  c->bw_in_by_nt[nt] +=
725  GNUNET_MAX (MIN_BANDWIDTH_PER_SESSION, sh->data->prop.goodput_in);
727  pk++)
728  {
729  /* General rule: always prefer smaller distance if possible,
730  otherwise decide by pk: */
731  switch (pk)
732  {
734  break;
735 
737  /* For bandwidth, we compare the sum of transmitted bytes and
738  confirmed transmitted bytes, so confirmed data counts twice */
739  if ((NULL == best[pk]) ||
740  (sh->data->prop.distance < best[pk]->data->prop.distance) ||
741  (sh->data->prop.utilization_out + sh->data->prop.goodput_out >
742  best[pk]->data->prop.utilization_out
743  + best[pk]->data->prop.goodput_out))
744  best[pk] = sh;
745  /* If both are equal (i.e. usually this happens if there is a zero), use
746  latency as a yardstick */
747  if ((sh->data->prop.utilization_out + sh->data->prop.goodput_out ==
748  best[pk]->data->prop.utilization_out
749  + best[pk]->data->prop.goodput_out) &&
750  (sh->data->prop.distance == best[pk]->data->prop.distance) &&
751  (sh->data->prop.delay.rel_value_us <
752  best[pk]->data->prop.delay.rel_value_us))
753  best[pk] = sh;
754  break;
755 
757  if ((NULL == best[pk]) ||
758  (sh->data->prop.distance < best[pk]->data->prop.distance) ||
759  ((sh->data->prop.distance == best[pk]->data->prop.distance) &&
760  (sh->data->prop.delay.rel_value_us <
761  best[pk]->data->prop.delay.rel_value_us)))
762  best[pk] = sh;
763  break;
764 
766  /* For reliability, we consider the ratio of goodput to utilization
767  (but use multiplicative formultations to avoid division by zero) */
768  if ((NULL == best[pk]) || (1ULL * sh->data->prop.goodput_out
769  * best[pk]->data->prop.utilization_out >
770  1ULL * sh->data->prop.utilization_out
771  * best[pk]->data->prop.goodput_out))
772  best[pk] = sh;
773  /* If both are equal (i.e. usually this happens if there is a zero), use
774  latency as a yardstick */
775  if ((1ULL * sh->data->prop.goodput_out
776  * best[pk]->data->prop.utilization_out ==
777  1ULL * sh->data->prop.utilization_out
778  * best[pk]->data->prop.goodput_out) &&
779  (sh->data->prop.distance == best[pk]->data->prop.distance) &&
780  (sh->data->prop.delay.rel_value_us <
781  best[pk]->data->prop.delay.rel_value_us))
782  best[pk] = sh;
783  break;
784  }
785  }
786  }
787  /* for first round, assign target bandwidth simply to sum of
788  requested bandwidth */
789  for (enum GNUNET_MQ_PreferenceKind pk =
790  1 /* skip GNUNET_MQ_PREFERENCE_NONE */;
792  pk++)
793  {
794  const struct GNUNET_ATS_SessionData *data = best[pk]->data;
795  enum GNUNET_NetworkType nt;
796 
797  GNUNET_assert (NULL != data);
798  nt = data->prop.nt;
799  best[pk]->target_out =
801  c->bw_out_by_nt[nt] +=
802  (uint64_t) (best[pk]->target_out - MIN_BANDWIDTH_PER_SESSION);
803  }
804  return GNUNET_YES;
805 }
uint64_t bw_by_pk[GNUNET_MQ_PREFERENCE_COUNT]
Array where we sum up the bandwidth requests received indexed by preference kind (see enum GNUNET_MQ_...
static struct GNUNET_CRYPTO_EddsaPrivateKey * pk
Private key of this peer.
uint64_t rel_value_us
The actual value.
const struct GNUNET_ATS_SessionData * data
Current performance data for this session.
uint32_t goodput_out
Confirmed successful payload on this connection from this peer to the other peer. ...
Internal representation of a session by the plugin.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
No preference was expressed.
uint64_t bw_out_by_nt[GNUNET_NT_COUNT]
Bandwidth that applications would prefer to allocate in this network type.
GNUNET_NetworkType
Types of networks (with separate quotas) we support.
Definition: gnunet_nt_lib.h:35
struct GNUNET_ATS_SessionHandle * sh_head
Kept in DLL per peer.
GNUNET_MQ_PreferenceKind
Enum defining all known preference categories.
static char * value
Value of the record to add/remove.
#define GNUNET_MQ_PREFERENCE_COUNT
#define GNUNET_MAX(a, b)
Definition: gnunet_common.h:82
static struct SolverHandle * sh
#define GNUNET_MIN(a, b)
Definition: gnunet_common.h:80
uint64_t bw_in_by_nt[GNUNET_NT_COUNT]
Current bandwidth utilization for this network type.
struct GNUNET_TIME_Relative delay
Delay.
The preferred transmission for this envelope focuses on maximizing bandwidth.
uint64_t target_out
New BW-out allocation given to the transport service.
static struct GNUNET_NAT_AUTO_Test * nt
Handle to a NAT test operation.
#define MIN_BANDWIDTH_PER_SESSION
What is the minimum bandwidth we always try to allocate for any session that is up? (May still be scaled down lower if the number of sessions is so high that the total bandwidth is insufficient to allow for this value to be granted.)
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
Plugin-relevant information about a session.
enum GNUNET_NetworkType nt
Which network scope does the respective address belong to?
Information about preferences and sessions we track per peer.
The preferred transmission for this envelope foces on minimizing latency.
Closure for update_counters and update_allocation.
#define GNUNET_YES
Definition: gnunet_common.h:77
uint32_t data
The data value.
unsigned int distance
Distance on network layer (required for distance-vector routing) in hops.
uint32_t utilization_out
Actual traffic on this connection from this peer to the other peer.
struct GNUNET_ATS_Properties prop
ATS performance characteristics for a session.
The preferred transmission for this envelope foces on reliability.
Here is the caller graph for this function:

◆ update_allocation()

static int update_allocation ( void *  cls,
const struct GNUNET_PeerIdentity pid,
void *  value 
)
static

Function used to iterate over all peers and collect counter data.

Parameters
clsa struct Counters *
pididentity of the peer we process, unused
valuea struct Peer *
Returns
GNUNET_YES (continue to iterate)

Definition at line 818 of file plugin_ats2_simple.c.

References consider_notify_transport(), GNUNET_ATS_SessionHandle::data, GNUNET_YES, GNUNET_ATS_SessionHandle::next, GNUNET_ATS_Properties::nt, Hello::nt, Hello::peer, GNUNET_ATS_SessionData::prop, Counters::scale_in, Counters::scale_out, Hello::sh, Peer::sh_head, GNUNET_ATS_SessionHandle::target_in, GNUNET_ATS_SessionHandle::target_out, and value.

Referenced by update().

821 {
822  struct Counters *c = cls;
823  struct Peer *peer = value;
824 
825  (void) pid;
826  for (struct GNUNET_ATS_SessionHandle *sh = peer->sh_head; NULL != sh;
827  sh = sh->next)
828  {
829  enum GNUNET_NetworkType nt = sh->data->prop.nt;
830 
831  sh->target_out = (uint64_t) (c->scale_out[nt] * sh->target_out);
832  sh->target_in = (uint64_t) (c->scale_in[nt] * sh->target_in);
834  }
835  return GNUNET_YES;
836 }
double scale_in[GNUNET_NT_COUNT]
By how much do we have to scale (up or down) our expectations for inbound bandwidth?
Internal representation of a session by the plugin.
GNUNET_NetworkType
Types of networks (with separate quotas) we support.
Definition: gnunet_nt_lib.h:35
double scale_out[GNUNET_NT_COUNT]
By how much do we have to scale (up or down) our expectations for outbound bandwidth?
struct GNUNET_ATS_SessionHandle * sh_head
Kept in DLL per peer.
static char * value
Value of the record to add/remove.
static struct SolverHandle * sh
static struct GNUNET_NAT_AUTO_Test * nt
Handle to a NAT test operation.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
static void consider_notify_transport(struct GNUNET_ATS_SessionHandle *sh)
Check if the new allocation for sh is significantly different from the last one, and if so...
Information about preferences and sessions we track per peer.
Closure for update_counters and update_allocation.
#define GNUNET_YES
Definition: gnunet_common.h:77
Here is the call graph for this function:
Here is the caller graph for this function:

◆ update()

static void update ( struct SimpleHandle h)
static

The world changed, recalculate our allocations.

Definition at line 843 of file plugin_ats2_simple.c.

References Counters::bw_in_by_nt, Counters::bw_out_by_nt, GNUNET_CONTAINER_multipeermap_iterate(), GNUNET_NT_COUNT, Counters::h, SimpleHandle::networks, Hello::nt, SimpleHandle::peers, Counters::scale_in, Counters::scale_out, Network::total_quota_in, Network::total_quota_out, update_allocation(), and update_counters().

Referenced by simple_preference_add(), simple_preference_del(), simple_session_add(), simple_session_del(), and simple_session_update().

844 {
845  struct Counters cnt = { .h = h };
846 
848  /* calculate how badly the missmatch between requested
849  allocations and available bandwidth is per network type */
850  for (enum GNUNET_NetworkType nt = 0; nt < GNUNET_NT_COUNT; nt++)
851  {
852  cnt.scale_out[nt] =
853  1.0 * cnt.bw_out_by_nt[nt] / h->networks[nt].total_quota_out;
854  cnt.scale_in[nt] =
855  1.0 * cnt.bw_in_by_nt[nt] / h->networks[nt].total_quota_in;
856  }
857  /* recalculate allocations, considering scaling factor, and
858  update transport if the change is significant */
860 }
double scale_in[GNUNET_NT_COUNT]
By how much do we have to scale (up or down) our expectations for inbound bandwidth?
unsigned long long total_quota_out
Total outbound quota.
static int update_counters(void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
Function used to iterate over all peers and collect counter data.
uint64_t bw_out_by_nt[GNUNET_NT_COUNT]
Bandwidth that applications would prefer to allocate in this network type.
GNUNET_NetworkType
Types of networks (with separate quotas) we support.
Definition: gnunet_nt_lib.h:35
double scale_out[GNUNET_NT_COUNT]
By how much do we have to scale (up or down) our expectations for outbound bandwidth?
uint64_t bw_in_by_nt[GNUNET_NT_COUNT]
Current bandwidth utilization for this network type.
struct GNUNET_CONTAINER_MultiPeerMap * peers
Information we track for each peer.
static struct GNUNET_NAT_AUTO_Test * nt
Handle to a NAT test operation.
unsigned long long total_quota_in
Total inbound quota.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
static int update_allocation(void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
Function used to iterate over all peers and collect counter data.
struct Network networks[GNUNET_NT_COUNT]
Information we track per network type (quotas).
Closure for update_counters and update_allocation.
struct SimpleHandle * h
Plugin&#39;s state.
#define GNUNET_NT_COUNT
Here is the call graph for this function:
Here is the caller graph for this function:

◆ simple_preference_add()

static struct GNUNET_ATS_PreferenceHandle* simple_preference_add ( void *  cls,
const struct GNUNET_ATS_Preference pref 
)
static

The plugin should begin to respect a new preference.

Parameters
clsthe closure
prefthe preference to add
Returns
plugin's internal representation, or NULL

Definition at line 871 of file plugin_ats2_simple.c.

References GNUNET_ATS_Preference::bw, Peer::bw_by_pk, SimpleHandle::bw_by_pk, GNUNET_assert, GNUNET_MQ_PREFERENCE_COUNT, h, p, GNUNET_ATS_Preference::peer, peer_add(), GNUNET_ATS_Preference::pk, update(), and GNUNET_BANDWIDTH_Value32NBO::value__.

Referenced by libgnunet_plugin_ats2_simple_init().

872 {
873  struct SimpleHandle *h = cls;
874  struct Peer *p = peer_add (h, &pref->peer);
875 
877  p->bw_by_pk[pref->pk] += ntohl (pref->bw.value__);
878  h->bw_by_pk[pref->pk] += ntohl (pref->bw.value__);
879  update (h);
880  return NULL;
881 }
uint64_t bw_by_pk[GNUNET_MQ_PREFERENCE_COUNT]
Array where we sum up the bandwidth requests received indexed by preference kind (see enum GNUNET_MQ_...
static void update(struct SimpleHandle *h)
The world changed, recalculate our allocations.
static struct Peer * peer_add(struct SimpleHandle *h, const struct GNUNET_PeerIdentity *pid)
Find or add peer if necessary.
enum GNUNET_MQ_PreferenceKind pk
What type of performance preference does the client have?
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
uint64_t bw_by_pk[GNUNET_MQ_PREFERENCE_COUNT]
Array where we sum up the bandwidth requests received indexed by preference kind (see enum GNUNET_MQ_...
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:99
uint32_t value__
The actual value (bytes per second).
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
#define GNUNET_MQ_PREFERENCE_COUNT
struct GNUNET_BANDWIDTH_Value32NBO bw
How much bandwidth in bytes/second does the application expect?
Information about preferences and sessions we track per peer.
A handle for the proportional solver.
struct GNUNET_PeerIdentity peer
Peer to get address suggestions for.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ simple_preference_del()

static void simple_preference_del ( void *  cls,
struct GNUNET_ATS_PreferenceHandle *  ph,
const struct GNUNET_ATS_Preference pref 
)
static

The plugin should end respecting a preference.

Parameters
clsthe closure
phwhatever preference_add returned
prefthe preference to delete
Returns
plugin's internal representation, or NULL

Definition at line 893 of file plugin_ats2_simple.c.

References GNUNET_ATS_Preference::bw, Peer::bw_by_pk, SimpleHandle::bw_by_pk, GNUNET_assert, GNUNET_MQ_PREFERENCE_COUNT, GNUNET_YES, h, lookup_peer(), p, GNUNET_ATS_Preference::peer, peer_free(), peer_test_dead(), GNUNET_ATS_Preference::pk, update(), and GNUNET_BANDWIDTH_Value32NBO::value__.

Referenced by libgnunet_plugin_ats2_simple_init().

896 {
897  struct SimpleHandle *h = cls;
898  struct Peer *p = lookup_peer (h, &pref->peer);
899 
900  GNUNET_assert (NULL != p);
902  p->bw_by_pk[pref->pk] -= ntohl (pref->bw.value__);
903  h->bw_by_pk[pref->pk] -= ntohl (pref->bw.value__);
904  if ((0 == p->bw_by_pk[pref->pk]) && (GNUNET_YES == peer_test_dead (p)))
905  peer_free (p);
906  update (h);
907 }
uint64_t bw_by_pk[GNUNET_MQ_PREFERENCE_COUNT]
Array where we sum up the bandwidth requests received indexed by preference kind (see enum GNUNET_MQ_...
static void update(struct SimpleHandle *h)
The world changed, recalculate our allocations.
enum GNUNET_MQ_PreferenceKind pk
What type of performance preference does the client have?
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
uint64_t bw_by_pk[GNUNET_MQ_PREFERENCE_COUNT]
Array where we sum up the bandwidth requests received indexed by preference kind (see enum GNUNET_MQ_...
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:99
uint32_t value__
The actual value (bytes per second).
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
#define GNUNET_MQ_PREFERENCE_COUNT
static int peer_test_dead(struct Peer *p)
Check if there is any interesting information left we store about the peer in p.
static void peer_free(struct Peer *p)
Free the entry (and associated tasks) of peer p.
struct GNUNET_BANDWIDTH_Value32NBO bw
How much bandwidth in bytes/second does the application expect?
Information about preferences and sessions we track per peer.
struct Peer * lookup_peer(struct SimpleHandle *h, const struct GNUNET_PeerIdentity *pid)
Lookup peer in the peers map.
#define GNUNET_YES
Definition: gnunet_common.h:77
A handle for the proportional solver.
struct GNUNET_PeerIdentity peer
Peer to get address suggestions for.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ simple_session_add()

static struct GNUNET_ATS_SessionHandle* simple_session_add ( void *  cls,
const struct GNUNET_ATS_SessionData data,
const char *  address 
)
static

Transport established a new session with performance characteristics given in data.

Parameters
clsclosure
dataperformance characteristics of sh
addressaddress information (for debugging)
Returns
handle by which the plugin will identify this session

Definition at line 920 of file plugin_ats2_simple.c.

References Hello::address, GNUNET_ATS_SessionHandle::address, Hello::backoff, data, GNUNET_ATS_SessionHandle::data, GNUNET_assert, GNUNET_CONTAINER_DLL_insert, GNUNET_malloc, GNUNET_TIME_UNIT_ZERO, h, Peer::h_head, GNUNET_ATS_SessionHandle::hello, Hello::next, p, GNUNET_ATS_SessionHandle::peer, GNUNET_ATS_SessionData::peer, peer_add(), GNUNET_ATS_SessionData::session, GNUNET_ATS_SessionHandle::session, Hello::sh, Peer::sh_head, Peer::sh_tail, and update().

Referenced by libgnunet_plugin_ats2_simple_init().

923 {
924  struct SimpleHandle *h = cls;
925  struct Peer *p = peer_add (h, &data->peer);
926  struct Hello *hello;
927  size_t alen;
929 
930  /* setup session handle */
931  GNUNET_assert (NULL != data);
932  if (NULL == address)
933  alen = 0;
934  else
935  alen = strlen (address) + 1;
936  sh = GNUNET_malloc (sizeof(struct GNUNET_ATS_SessionHandle) + alen);
937  sh->peer = p;
938  sh->session = data->session;
939  sh->data = data;
940  if (NULL == address)
941  {
942  sh->address = NULL;
943  }
944  else
945  {
946  memcpy (&sh[1], address, alen);
947  sh->address = (const char *) &sh[1];
948  }
950  if (NULL != address)
951  {
952  /* match HELLO */
953  hello = p->h_head;
954  while ((NULL != hello) && (0 != strcmp (address, hello->address)))
955  hello = hello->next;
956  if (NULL != hello)
957  {
958  hello->sh = sh;
960  sh->hello = hello;
961  }
962  }
963  update (h);
964  return sh;
965 }
struct GNUNET_ATS_Session * session
Handle to the session that has the given properties.
const struct GNUNET_ATS_SessionData * data
Current performance data for this session.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
static void update(struct SimpleHandle *h)
The world changed, recalculate our allocations.
static struct Peer * peer_add(struct SimpleHandle *h, const struct GNUNET_PeerIdentity *pid)
Find or add peer if necessary.
Internal representation of a session by the plugin.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_PeerIdentity peer
Peer the session is with.
struct Peer * peer
Peer this session is for.
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:99
struct GNUNET_ATS_SessionHandle * sh_head
Kept in DLL per peer.
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
static struct SolverHandle * sh
struct GNUNET_ATS_SessionHandle * sh_tail
Kept in DLL per peer.
struct Hello * h_head
Kept in a DLL.
Entry in list of addresses we could try per peer.
struct Hello * hello
Hello matching this session, or NULL for none.
#define GNUNET_TIME_UNIT_ZERO
Relative time zero.
struct GNUNET_TIME_Relative backoff
Current exponential backoff value.
Information about preferences and sessions we track per peer.
struct Hello * next
Kept in a DLL.
const char * address
The address we could try.
struct GNUNET_ATS_SessionHandle * sh
Is a session with this address already up? If not, set to NULL.
A handle for the proportional solver.
uint32_t data
The data value.
const char * address
Address used by this session (largely for debugging).
static char * address
GNS address for this phone.
#define GNUNET_malloc(size)
Wrapper around malloc.
struct GNUNET_ATS_Session * session
The session in the main ATS service.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ simple_session_update()

static void simple_session_update ( void *  cls,
struct GNUNET_ATS_SessionHandle sh,
const struct GNUNET_ATS_SessionData data 
)
static

data changed for a given sh, solver should consider the updated performance characteristics.

Parameters
clsclosure
shsession this is about
dataperformance characteristics of sh

Definition at line 977 of file plugin_ats2_simple.c.

References data, GNUNET_ATS_SessionHandle::data, GNUNET_assert, h, and update().

Referenced by libgnunet_plugin_ats2_simple_init().

980 {
981  struct SimpleHandle *h = cls;
982 
983  GNUNET_assert (NULL != data);
984  sh->data = data; /* this statement should not really do anything... */
985  update (h);
986 }
const struct GNUNET_ATS_SessionData * data
Current performance data for this session.
static void update(struct SimpleHandle *h)
The world changed, recalculate our allocations.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:99
A handle for the proportional solver.
uint32_t data
The data value.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ simple_session_del()

static void simple_session_del ( void *  cls,
struct GNUNET_ATS_SessionHandle sh,
const struct GNUNET_ATS_SessionData data 
)
static

A session went away.

Solver should update accordingly.

Parameters
clsclosure
shsession this is about
data(last) performance characteristics of sh

Definition at line 997 of file plugin_ats2_simple.c.

References GNUNET_assert, GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_SCHEDULER_add_now(), GNUNET_YES, h, GNUNET_ATS_SessionHandle::hello, p, GNUNET_ATS_SessionHandle::peer, peer_free(), peer_test_dead(), Hello::sh, Peer::sh_head, Peer::sh_tail, suggest_start_cb(), Peer::task, and update().

Referenced by libgnunet_plugin_ats2_simple_init().

1000 {
1001  struct SimpleHandle *h = cls;
1002  struct Peer *p = sh->peer;
1003  struct Hello *hello = sh->hello;
1004 
1005  /* clean up sh */
1007  if (NULL != hello)
1008  {
1009  GNUNET_assert (sh == hello->sh);
1010  hello->sh = NULL;
1011  /* session went down, if necessary restart suggesting
1012  addresses */
1013  if (NULL == p->task)
1015  }
1016  GNUNET_free (sh);
1017  /* del peer if otherwise dead */
1018  if ((NULL == p->sh_head) && (GNUNET_YES == peer_test_dead (p)))
1019  peer_free (p);
1020  update (h);
1021 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
static void update(struct SimpleHandle *h)
The world changed, recalculate our allocations.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct Peer * peer
Peer this session is for.
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:99
struct GNUNET_ATS_SessionHandle * sh_head
Kept in DLL per peer.
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
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:1280
struct GNUNET_ATS_SessionHandle * sh_tail
Kept in DLL per peer.
static int peer_test_dead(struct Peer *p)
Check if there is any interesting information left we store about the peer in p.
Entry in list of addresses we could try per peer.
static void peer_free(struct Peer *p)
Free the entry (and associated tasks) of peer p.
struct Hello * hello
Hello matching this session, or NULL for none.
struct GNUNET_SCHEDULER_Task * task
Task used to try again to suggest an address for this peer.
Information about preferences and sessions we track per peer.
static void suggest_start_cb(void *cls)
Consider suggesting a HELLO (without a session) to transport.
#define GNUNET_YES
Definition: gnunet_common.h:77
struct GNUNET_ATS_SessionHandle * sh
Is a session with this address already up? If not, set to NULL.
A handle for the proportional solver.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ libgnunet_plugin_ats2_simple_init()

void* libgnunet_plugin_ats2_simple_init ( void *  cls)

Function invoked when the plugin is loaded.

Parameters
[in,out]clsthe struct GNUNET_ATS_PluginEnvironment * to use; modified to return the API functions (ugh).
Returns
the struct SimpleHandle to pass as a closure

Definition at line 1035 of file plugin_ats2_simple.c.

References GNUNET_ATS_PluginEnvironment::cfg, GNUNET_ATS_SolverFunctions::cls, GNUNET_ATS_PluginEnvironment::cls, env, SimpleHandle::env, get_quota(), GNUNET_break, GNUNET_CONTAINER_multipeermap_create(), GNUNET_new, GNUNET_NT_COUNT, GNUNET_NT_to_string(), GNUNET_PEERSTORE_connect(), GNUNET_YES, name, SimpleHandle::networks, Hello::nt, SimpleHandle::peers, GNUNET_ATS_SolverFunctions::preference_add, GNUNET_ATS_SolverFunctions::preference_del, SimpleHandle::ps, GNUNET_ATS_SolverFunctions::session_add, GNUNET_ATS_SolverFunctions::session_del, GNUNET_ATS_SolverFunctions::session_update, sf, simple_preference_add(), simple_preference_del(), simple_session_add(), simple_session_del(), simple_session_update(), Network::total_quota_in, Network::total_quota_out, and Network::type.

1036 {
1037  static struct GNUNET_ATS_SolverFunctions sf;
1039  struct SimpleHandle *s;
1040 
1041  s = GNUNET_new (struct SimpleHandle);
1042  s->env = env;
1044  s->ps = GNUNET_PEERSTORE_connect (env->cfg);
1045  sf.cls = s;
1051  for (enum GNUNET_NetworkType nt = 0; nt < GNUNET_NT_COUNT; nt++)
1052  {
1053  const char *name = GNUNET_NT_to_string (nt);
1054 
1055  if (NULL == name)
1056  {
1057  GNUNET_break (0);
1058  break;
1059  }
1060  get_quota (env->cfg, name, "IN", &s->networks[nt].total_quota_in);
1061  get_quota (env->cfg, name, "OUT", &s->networks[nt].total_quota_out);
1062  s->networks[nt].type = nt;
1063  }
1064  return &sf;
1065 }
const char * GNUNET_NT_to_string(enum GNUNET_NetworkType net)
Convert a enum GNUNET_NetworkType to a string.
Definition: nt.c:44
unsigned long long total_quota_out
Total outbound quota.
void(* session_update)(void *cls, struct GNUNET_ATS_SessionHandle *sh, const struct GNUNET_ATS_SessionData *data)
data changed for a given sh, solver should consider the updated performance characteristics.
static struct GNUNET_ATS_SessionHandle * simple_session_add(void *cls, const struct GNUNET_ATS_SessionData *data, const char *address)
Transport established a new session with performance characteristics given in data.
static struct GNUNET_ATS_PreferenceHandle * simple_preference_add(void *cls, const struct GNUNET_ATS_Preference *pref)
The plugin should begin to respect a new preference.
static void simple_preference_del(void *cls, struct GNUNET_ATS_PreferenceHandle *ph, const struct GNUNET_ATS_Preference *pref)
The plugin should end respecting a preference.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
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 void simple_session_update(void *cls, struct GNUNET_ATS_SessionHandle *sh, const struct GNUNET_ATS_SessionData *data)
data changed for a given sh, solver should consider the updated performance characteristics.
GNUNET_NetworkType
Types of networks (with separate quotas) we support.
Definition: gnunet_nt_lib.h:35
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
void(* session_del)(void *cls, struct GNUNET_ATS_SessionHandle *sh, const struct GNUNET_ATS_SessionData *data)
A session went away.
struct GNUNET_ATS_PluginEnvironment * env
Our execution environment.
struct GNUNET_PEERSTORE_Handle * ps
Handle to the peerstore service.
struct GNUNET_ATS_PreferenceHandle *(* preference_add)(void *cls, const struct GNUNET_ATS_Preference *pref)
The plugin should begin to respect a new preference.
struct GNUNET_CONTAINER_MultiPeerMap * peers
Information we track for each peer.
struct GNUNET_ATS_SessionHandle *(* session_add)(void *cls, const struct GNUNET_ATS_SessionData *data, const char *address)
Transport established a new session with performance characteristics given in data.
static struct GNUNET_NAT_AUTO_Test * nt
Handle to a NAT test operation.
enum GNUNET_NetworkType type
ATS network type.
static void get_quota(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *nts, const char *direction, unsigned long long *quota)
Parse cfg for quota as specified for direction of network type nts.
unsigned long long total_quota_in
Total inbound quota.
struct GNUNET_PEERSTORE_Handle * GNUNET_PEERSTORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the PEERSTORE service.
const char * name
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
void * cls
Closure to pass to all solver functions in this struct.
static void simple_session_del(void *cls, struct GNUNET_ATS_SessionHandle *sh, const struct GNUNET_ATS_SessionData *data)
A session went away.
void(* preference_del)(void *cls, struct GNUNET_ATS_PreferenceHandle *ph, const struct GNUNET_ATS_Preference *pref)
The plugin should end respecting a preference.
struct Network networks[GNUNET_NT_COUNT]
Information we track per network type (quotas).
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration handle to be used by the solver.
void * cls
Closure to pass to all callbacks in this struct.
#define GNUNET_YES
Definition: gnunet_common.h:77
A handle for the proportional solver.
static struct GNUNET_ATS_SolverFunctions * sf
Solver handle.
The ATS plugin will pass a pointer to a struct of this type as to the initialization function of the ...
#define GNUNET_NT_COUNT
Here is the call graph for this function:

◆ libgnunet_plugin_ats2_simple_done()

void* libgnunet_plugin_ats2_simple_done ( void *  cls)

Function used to unload the plugin.

Parameters
clsreturn value from libgnunet_plugin_ats_proportional_init()

Definition at line 1074 of file plugin_ats2_simple.c.

References GNUNET_ATS_SolverFunctions::cls, GNUNET_break, GNUNET_CONTAINER_multipeermap_destroy(), GNUNET_CONTAINER_multipeermap_size(), GNUNET_free, GNUNET_NO, GNUNET_PEERSTORE_disconnect(), SimpleHandle::peers, SimpleHandle::ps, and sf.

1075 {
1076  struct GNUNET_ATS_SolverFunctions *sf = cls;
1077  struct SimpleHandle *s = sf->cls;
1078 
1082  GNUNET_free (s);
1083  return NULL;
1084 }
#define GNUNET_NO
Definition: gnunet_common.h:78
#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 GNUNET_PEERSTORE_Handle * ps
Handle to the peerstore service.
void GNUNET_PEERSTORE_disconnect(struct GNUNET_PEERSTORE_Handle *h, int sync_first)
Disconnect from the PEERSTORE service.
struct GNUNET_CONTAINER_MultiPeerMap * peers
Information we track for each peer.
void * cls
Closure to pass to all solver functions in this struct.
A handle for the proportional solver.
unsigned int GNUNET_CONTAINER_multipeermap_size(const struct GNUNET_CONTAINER_MultiPeerMap *map)
Get the number of key-value pairs in the map.
static struct GNUNET_ATS_SolverFunctions * sf
Solver handle.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function: