GNUnet  0.11.x
gnunet-service-transport_manipulation.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2010-2013 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 
27 #include "platform.h"
33 #include "transport.h"
34 
35 
39 struct TM_Peer
40 {
45 
50 
55 
60 
65 
70 
75 };
76 
77 
82 {
87 
92 
99  struct TM_Peer *tmp;
100 
105 
109  struct GNUNET_TIME_Absolute sent_at;
110 
114  void *msg;
115 
119  size_t msg_size;
120 
125 
130 
134  void *cont_cls;
135 };
136 
141 
146 
151 
156 
161 
166 
167 
173 void
175 {
176  static struct GNUNET_PeerIdentity zero;
177  struct TM_Peer *tmp;
178 
179  if (0 == memcmp (&tm->peer,
180  &zero,
181  sizeof(struct GNUNET_PeerIdentity)))
182  {
184  "Received traffic metrics for all peers\n");
187  return;
188  }
190  "Received traffic metrics for peer `%s'\n",
191  GNUNET_i2s (&tm->peer));
192  if (NULL ==
193  (tmp = GNUNET_CONTAINER_multipeermap_get (peers,
194  &tm->peer)))
195  {
196  tmp = GNUNET_new (struct TM_Peer);
197  tmp->peer = tm->peer;
199  &tm->peer,
200  tmp,
202  }
204  &tm->properties);
207 }
208 
209 
216 static void
217 send_delayed (void *cls)
218 {
219  struct DelayQueueEntry *dqe = cls;
220  struct DelayQueueEntry *next;
221  struct TM_Peer *tmp = dqe->tmp;
222 
225  if (NULL != tmp)
226  {
227  tmp->send_delay_task = NULL;
229  tmp->send_tail,
230  dqe);
231  next = tmp->send_head;
232  if (NULL != next)
233  {
234  /* More delayed messages */
236  &send_delayed,
237  next);
238  }
239  }
240  else
241  {
242  /* Remove from generic queue */
243  generic_send_delay_task = NULL;
244  GNUNET_CONTAINER_DLL_remove (generic_dqe_head,
245  generic_dqe_tail,
246  dqe);
247  next = generic_dqe_head;
248  if (NULL != next)
249  {
250  /* More delayed messages */
251  generic_send_delay_task = GNUNET_SCHEDULER_add_at (next->sent_at,
252  &send_delayed,
253  next);
254  }
255  }
256  GST_neighbours_send (&dqe->id,
257  dqe->msg,
258  dqe->msg_size,
259  dqe->timeout,
260  dqe->cont,
261  dqe->cont_cls);
262  GNUNET_free (dqe);
263 }
264 
265 
277 void
279  const void *msg,
280  size_t msg_size,
283  void *cont_cls)
284 {
285  struct TM_Peer *tmp;
286  struct DelayQueueEntry *dqe;
287  struct GNUNET_TIME_Relative delay;
288 
289  if (NULL != (tmp =
291  target)))
292  delay = tmp->delay_out;
293  else
294  delay = delay_out;
295  if (0 == delay.rel_value_us)
296  {
297  /* Normal sending */
298  GST_neighbours_send (target,
299  msg,
300  msg_size,
301  timeout,
302  cont, cont_cls);
303  return;
304  }
305  dqe = GNUNET_malloc (sizeof(struct DelayQueueEntry) + msg_size);
306  dqe->id = *target;
307  dqe->tmp = tmp;
309  dqe->cont = cont;
310  dqe->cont_cls = cont_cls;
311  dqe->msg = &dqe[1];
312  dqe->msg_size = msg_size;
313  dqe->timeout = timeout;
314  GNUNET_memcpy (dqe->msg,
315  msg,
316  msg_size);
317  if (NULL == tmp)
318  {
319  GNUNET_CONTAINER_DLL_insert_tail (generic_dqe_head,
320  generic_dqe_tail,
321  dqe);
322  if (NULL == generic_send_delay_task)
323  generic_send_delay_task = GNUNET_SCHEDULER_add_delayed (delay,
324  &send_delayed,
325  dqe);
326  }
327  else
328  {
330  tmp->send_tail,
331  dqe);
332  if (NULL == tmp->send_delay_task)
334  &send_delayed,
335  dqe);
336  }
338  "Delaying %u byte message to peer `%s' with peer specific delay for %s\n",
339  (unsigned int) msg_size,
340  GNUNET_i2s (target),
342  GNUNET_YES));
343 }
344 
345 
354 void
356  struct GNUNET_ATS_Session *session,
357  struct GNUNET_ATS_Properties *prop)
358 {
359  const struct GNUNET_PeerIdentity *peer = &address->peer;
360  struct TM_Peer *tmp;
361 
363  peer);
364  if (NULL != tmp)
365  *prop = tmp->properties;
366 }
367 
368 
381  const struct GNUNET_HELLO_Address *address,
382  struct GNUNET_ATS_Session *session,
383  const struct GNUNET_MessageHeader *message)
384 {
385  struct TM_Peer *tmp;
386  struct GNUNET_TIME_Relative quota_delay;
387  struct GNUNET_TIME_Relative m_delay;
388 
389  if (NULL !=
390  (tmp = GNUNET_CONTAINER_multipeermap_get (peers,
391  &address->peer)))
392  m_delay = tmp->delay_in;
393  else
394  m_delay = delay_in;
395 
396  quota_delay = GST_receive_callback (cls,
397  address,
398  session,
399  message);
400  m_delay = GNUNET_TIME_relative_max (m_delay,
401  quota_delay);
403  "Delaying next receive for peer `%s' for %s\n",
404  GNUNET_i2s (&address->peer),
406  GNUNET_YES));
407  return m_delay;
408 }
409 
410 
414 void
416 {
417  struct GNUNET_TIME_Relative delay;
418 
419  if ((GNUNET_OK ==
421  "transport",
422  "MANIPULATE_DELAY_IN",
423  &delay)) &&
424  (delay.rel_value_us > 0))
425  {
427  "Delaying inbound traffic for %s\n",
429  GNUNET_YES));
430  delay_in = delay;
431  }
432  if ((GNUNET_OK ==
434  "transport",
435  "MANIPULATE_DELAY_OUT",
436  &delay)) &&
437  (delay.rel_value_us > 0))
438  {
440  "Delaying outbound traffic for %s\n",
442  GNUNET_YES));
443  delay_out = delay;
444  }
446  GNUNET_NO);
447 }
448 
449 
455 void
457 {
458  struct TM_Peer *tmp;
459  struct DelayQueueEntry *dqe;
460  struct DelayQueueEntry *next;
461 
463  peer);
464  if (NULL != tmp)
465  {
466  while (NULL != (dqe = tmp->send_head))
467  {
469  tmp->send_tail,
470  dqe);
471  if (NULL != dqe->cont)
472  dqe->cont (dqe->cont_cls,
474  dqe->msg_size,
475  0);
476  GNUNET_free (dqe);
477  }
478  }
479  next = generic_dqe_head;
480  while (NULL != (dqe = next))
481  {
482  next = dqe->next;
483  if (0 == memcmp (peer,
484  &dqe->id,
485  sizeof(dqe->id)))
486  {
487  GNUNET_CONTAINER_DLL_remove (generic_dqe_head,
488  generic_dqe_tail,
489  dqe);
490  if (NULL != dqe->cont)
491  dqe->cont (dqe->cont_cls,
493  dqe->msg_size,
494  0);
495  GNUNET_free (dqe);
496  }
497  }
498  if (NULL != generic_send_delay_task)
499  {
500  GNUNET_SCHEDULER_cancel (generic_send_delay_task);
501  generic_send_delay_task = NULL;
502  if (NULL != generic_dqe_head)
503  generic_send_delay_task
504  = GNUNET_SCHEDULER_add_at (generic_dqe_head->sent_at,
505  &send_delayed,
506  generic_dqe_head);
507  }
508 }
509 
510 
519 static int
520 free_tmps (void *cls,
521  const struct GNUNET_PeerIdentity *key,
522  void *value)
523 {
524  struct TM_Peer *tmp = value;
525  struct DelayQueueEntry *dqe;
526 
529  key,
530  value));
531  while (NULL != (dqe = tmp->send_head))
532  {
534  tmp->send_tail,
535  dqe);
536  if (NULL != dqe->cont)
537  dqe->cont (dqe->cont_cls,
539  dqe->msg_size,
540  0);
541  GNUNET_free (dqe);
542  }
543  if (NULL != tmp->send_delay_task)
544  {
546  tmp->send_delay_task = NULL;
547  }
548  GNUNET_free (tmp);
549  return GNUNET_OK;
550 }
551 
552 
556 void
558 {
559  struct DelayQueueEntry *cur;
560 
562  &free_tmps,
563  NULL);
565  peers = NULL;
566  while (NULL != (cur = generic_dqe_head))
567  {
568  GNUNET_CONTAINER_DLL_remove (generic_dqe_head,
569  generic_dqe_tail,
570  cur);
571  if (NULL != cur->cont)
572  cur->cont (cur->cont_cls,
574  cur->msg_size,
575  0);
576  GNUNET_free (cur);
577  }
578  if (NULL != generic_send_delay_task)
579  {
580  GNUNET_SCHEDULER_cancel (generic_send_delay_task);
581  generic_send_delay_task = NULL;
582  }
583 }
584 
585 
586 /* end of file gnunet-service-transport_manipulation.c */
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
Entry in the delay queue for an outbound delayed message.
struct GNUNET_PeerIdentity peer
The identity of the peer to look up.
Definition: transport.h:508
struct DelayQueueEntry * send_head
Send queue DLL head.
struct DelayQueueEntry * send_tail
Send queue DLL tail.
int GNUNET_CONFIGURATION_get_value_time(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, struct GNUNET_TIME_Relative *time)
Get a configuration value that should be a relative time.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
void GST_manipulation_manipulate_metrics(const struct GNUNET_HELLO_Address *address, struct GNUNET_ATS_Session *session, struct GNUNET_ATS_Properties *prop)
Function that will be called to manipulate ATS information according to current manipulation settings...
void * cont_cls
Transports send continuation cls.
uint64_t rel_value_us
The actual value.
struct GNUNET_TIME_Relative delay_in
How long to delay incoming messages for this peer.
common internal definitions for transport service
struct GNUNET_TIME_Relative delay_out
How long to delay outgoing messages for this peer.
struct GNUNET_TIME_RelativeNBO delay_in
Fake delay to add on inbound traffic.
Definition: transport.h:518
struct TM_Peer * tmp
Peer this entry is belonging to if (NULL == tmp): enqueued in generic DLL and scheduled by generic_se...
struct GNUNET_TIME_Relative GNUNET_TIME_relative_max(struct GNUNET_TIME_Relative t1, struct GNUNET_TIME_Relative t2)
Return the maximum of two relative time values.
Definition: time.c:287
void GST_manipulation_stop()
Stop traffic manipulation.
int GST_neighbours_test_connected(const struct GNUNET_PeerIdentity *target)
Test if we&#39;re connected to the given peer.
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
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
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:78
static struct GNUNET_IDENTITY_Handle * id
Handle to identity service.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static int free_tmps(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Free manipulation information about a 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).
ATS performance characteristics for an address.
#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.
GST_NeighbourSendContinuation cont
Transports send continuation.
struct GNUNET_TIME_RelativeNBO delay_out
Fake delay to add on outbound traffic.
Definition: transport.h:523
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
void GST_manipulation_set_metric(const struct TrafficMetricMessage *tm)
Set traffic metric to manipulate.
struct GNUNET_SCHEDULER_Task * send_delay_task
Task to schedule delayed sendding.
struct GNUNET_TIME_Relative GST_manipulation_recv(void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_ATS_Session *session, const struct GNUNET_MessageHeader *message)
Adapter function between transport plugins and transport receive function manipulation delays for nex...
static struct GNUNET_TIME_Relative timeout
Desired timeout for the lookup (default is no timeout).
Definition: gnunet-abd.c:61
struct DelayQueueEntry * next
Previous in DLL.
static struct GNUNET_CONTAINER_MultiPeerMap * peers
Hashmap contain all peers currently manipulated.
, &#39; bother checking if a value already exists (faster than GNUNET_CONTAINER_MULTIHASHMAPOPTION_...
Struct containing information about manipulations to a specific peer.
static char * value
Value of the record to add/remove.
void GST_manipulation_init()
Initialize traffic manipulation.
Session handle for connections.
void GST_manipulation_peer_disconnect(const struct GNUNET_PeerIdentity *peer)
Notify manipulation about disconnect so it can discard queued messages.
neighbour manipulation API, allows manipulation of performance metrics (delay and towards ATS) ...
static void send_delayed(void *cls)
We have delayed transmission, now it is time to send the message.
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:687
struct DelayQueueEntry * prev
Next in DLL.
Message from the library to the transport service asking for binary addresses known for a peer...
Definition: transport.h:493
Internal representation of the hash map.
struct GNUNET_ATS_Properties properties
Manipulated properties to use for this peer.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_ntoh(struct GNUNET_TIME_RelativeNBO a)
Convert relative time from network byte order.
Definition: time.c:641
void GST_manipulation_send(const struct GNUNET_PeerIdentity *target, const void *msg, size_t msg_size, struct GNUNET_TIME_Relative timeout, GST_NeighbourSendContinuation cont, void *cont_cls)
Adapter function between transport&#39;s send function and transport plugins.
struct GNUNET_HashCode key
The key used in the DHT.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
struct GNUNET_ATS_PropertiesNBO properties
Fake properties to generate.
Definition: transport.h:513
struct GNUNET_TIME_Relative GST_receive_callback(void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_ATS_Session *session, const struct GNUNET_MessageHeader *message)
Function called by the transport for each received message.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
static struct GNUNET_TIME_Relative delay
When should dkg communication start?
struct GNUNET_PeerIdentity peer
For which peer is this an address?
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.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
The identity of the host (wraps the signing key of the peer).
static struct DelayQueueEntry * generic_dqe_head
DLL head for delayed messages based on general delay.
void GNUNET_ATS_properties_ntoh(struct GNUNET_ATS_Properties *hbo, const struct GNUNET_ATS_PropertiesNBO *nbo)
Convert ATS properties from network to host byte order.
static struct GNUNET_SCHEDULER_Task * generic_send_delay_task
Task to schedule delayed sending based on general delay.
An address for communicating with a 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.
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:134
void GST_neighbours_send(const struct GNUNET_PeerIdentity *target, const void *msg, size_t msg_size, struct GNUNET_TIME_Relative timeout, GST_NeighbourSendContinuation cont, void *cont_cls)
Transmit a message to the given target using the active connection.
struct GNUNET_TIME_Relative timeout
Message timeout.
Header for all communications.
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:77
static const struct GNUNET_CONFIGURATION_Handle * GST_cfg
Configuration handle.
struct GNUNET_TIME_Absolute sent_at
Absolute time when to send.
static struct DelayQueueEntry * generic_dqe_tail
DLL tail for delayed messages based on general delay.
struct GNUNET_PeerIdentity peer
Peer ID.
void(* GST_NeighbourSendContinuation)(void *cls, int success, size_t bytes_payload, size_t bytes_on_wire)
Function called after the transmission is done.
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:1230
struct GNUNET_PeerIdentity id
Peer ID.
static char * address
GNS address for this phone.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966