GNUnet  0.10.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 {
44 
49 
54 
59 
64 
69 
74 };
75 
76 
85 
90 
97  struct TM_Peer *tmp;
98 
103 
107  struct GNUNET_TIME_Absolute sent_at;
108 
112  void *msg;
113 
117  size_t msg_size;
118 
123 
128 
132  void *cont_cls;
133 };
134 
139 
144 
149 
154 
159 
164 
165 
171 void
173 {
174  static struct GNUNET_PeerIdentity zero;
175  struct TM_Peer *tmp;
176 
177  if (0 == memcmp(&tm->peer,
178  &zero,
179  sizeof(struct GNUNET_PeerIdentity)))
180  {
182  "Received traffic metrics for all peers\n");
185  return;
186  }
188  "Received traffic metrics for peer `%s'\n",
189  GNUNET_i2s(&tm->peer));
190  if (NULL ==
192  &tm->peer)))
193  {
194  tmp = GNUNET_new(struct TM_Peer);
195  tmp->peer = tm->peer;
197  &tm->peer,
198  tmp,
200  }
202  &tm->properties);
205 }
206 
207 
214 static void
215 send_delayed(void *cls)
216 {
217  struct DelayQueueEntry *dqe = cls;
218  struct DelayQueueEntry *next;
219  struct TM_Peer *tmp = dqe->tmp;
220 
223  if (NULL != tmp)
224  {
225  tmp->send_delay_task = NULL;
227  tmp->send_tail,
228  dqe);
229  next = tmp->send_head;
230  if (NULL != next)
231  {
232  /* More delayed messages */
234  &send_delayed,
235  next);
236  }
237  }
238  else
239  {
240  /* Remove from generic queue */
241  generic_send_delay_task = NULL;
242  GNUNET_CONTAINER_DLL_remove(generic_dqe_head,
243  generic_dqe_tail,
244  dqe);
245  next = generic_dqe_head;
246  if (NULL != next)
247  {
248  /* More delayed messages */
249  generic_send_delay_task = GNUNET_SCHEDULER_add_at(next->sent_at,
250  &send_delayed,
251  next);
252  }
253  }
254  GST_neighbours_send(&dqe->id,
255  dqe->msg,
256  dqe->msg_size,
257  dqe->timeout,
258  dqe->cont,
259  dqe->cont_cls);
260  GNUNET_free(dqe);
261 }
262 
263 
275 void
277  const void *msg,
278  size_t msg_size,
281  void *cont_cls)
282 {
283  struct TM_Peer *tmp;
284  struct DelayQueueEntry *dqe;
285  struct GNUNET_TIME_Relative delay;
286 
287  if (NULL != (tmp =
289  target)))
290  delay = tmp->delay_out;
291  else
292  delay = delay_out;
293  if (0 == delay.rel_value_us)
294  {
295  /* Normal sending */
296  GST_neighbours_send(target,
297  msg,
298  msg_size,
299  timeout,
300  cont, cont_cls);
301  return;
302  }
303  dqe = GNUNET_malloc(sizeof(struct DelayQueueEntry) + msg_size);
304  dqe->id = *target;
305  dqe->tmp = tmp;
307  dqe->cont = cont;
308  dqe->cont_cls = cont_cls;
309  dqe->msg = &dqe[1];
310  dqe->msg_size = msg_size;
311  dqe->timeout = timeout;
312  GNUNET_memcpy(dqe->msg,
313  msg,
314  msg_size);
315  if (NULL == tmp)
316  {
317  GNUNET_CONTAINER_DLL_insert_tail(generic_dqe_head,
318  generic_dqe_tail,
319  dqe);
320  if (NULL == generic_send_delay_task)
321  generic_send_delay_task = GNUNET_SCHEDULER_add_delayed(delay,
322  &send_delayed,
323  dqe);
324  }
325  else
326  {
328  tmp->send_tail,
329  dqe);
330  if (NULL == tmp->send_delay_task)
332  &send_delayed,
333  dqe);
334  }
336  "Delaying %u byte message to peer `%s' with peer specific delay for %s\n",
337  (unsigned int)msg_size,
338  GNUNET_i2s(target),
340  GNUNET_YES));
341 }
342 
343 
352 void
354  struct GNUNET_ATS_Session *session,
355  struct GNUNET_ATS_Properties *prop)
356 {
357  const struct GNUNET_PeerIdentity *peer = &address->peer;
358  struct TM_Peer *tmp;
359 
361  peer);
362  if (NULL != tmp)
363  *prop = tmp->properties;
364 }
365 
366 
379  const struct GNUNET_HELLO_Address *address,
380  struct GNUNET_ATS_Session *session,
381  const struct GNUNET_MessageHeader *message)
382 {
383  struct TM_Peer *tmp;
384  struct GNUNET_TIME_Relative quota_delay;
385  struct GNUNET_TIME_Relative m_delay;
386 
387  if (NULL !=
389  &address->peer)))
390  m_delay = tmp->delay_in;
391  else
392  m_delay = delay_in;
393 
394  quota_delay = GST_receive_callback(cls,
395  address,
396  session,
397  message);
398  m_delay = GNUNET_TIME_relative_max(m_delay,
399  quota_delay);
401  "Delaying next receive for peer `%s' for %s\n",
402  GNUNET_i2s(&address->peer),
404  GNUNET_YES));
405  return m_delay;
406 }
407 
408 
412 void
414 {
415  struct GNUNET_TIME_Relative delay;
416 
417  if ((GNUNET_OK ==
419  "transport",
420  "MANIPULATE_DELAY_IN",
421  &delay)) &&
422  (delay.rel_value_us > 0))
423  {
425  "Delaying inbound traffic for %s\n",
427  GNUNET_YES));
428  delay_in = delay;
429  }
430  if ((GNUNET_OK ==
432  "transport",
433  "MANIPULATE_DELAY_OUT",
434  &delay)) &&
435  (delay.rel_value_us > 0))
436  {
438  "Delaying outbound traffic for %s\n",
440  GNUNET_YES));
441  delay_out = delay;
442  }
444  GNUNET_NO);
445 }
446 
447 
453 void
455 {
456  struct TM_Peer *tmp;
457  struct DelayQueueEntry *dqe;
458  struct DelayQueueEntry *next;
459 
461  peer);
462  if (NULL != tmp)
463  {
464  while (NULL != (dqe = tmp->send_head))
465  {
467  tmp->send_tail,
468  dqe);
469  if (NULL != dqe->cont)
470  dqe->cont(dqe->cont_cls,
472  dqe->msg_size,
473  0);
474  GNUNET_free(dqe);
475  }
476  }
477  next = generic_dqe_head;
478  while (NULL != (dqe = next))
479  {
480  next = dqe->next;
481  if (0 == memcmp(peer,
482  &dqe->id,
483  sizeof(dqe->id)))
484  {
485  GNUNET_CONTAINER_DLL_remove(generic_dqe_head,
486  generic_dqe_tail,
487  dqe);
488  if (NULL != dqe->cont)
489  dqe->cont(dqe->cont_cls,
491  dqe->msg_size,
492  0);
493  GNUNET_free(dqe);
494  }
495  }
496  if (NULL != generic_send_delay_task)
497  {
498  GNUNET_SCHEDULER_cancel(generic_send_delay_task);
499  generic_send_delay_task = NULL;
500  if (NULL != generic_dqe_head)
501  generic_send_delay_task
502  = GNUNET_SCHEDULER_add_at(generic_dqe_head->sent_at,
503  &send_delayed,
504  generic_dqe_head);
505  }
506 }
507 
508 
517 static int
518 free_tmps(void *cls,
519  const struct GNUNET_PeerIdentity *key,
520  void *value)
521 {
522  struct TM_Peer *tmp = value;
523  struct DelayQueueEntry *dqe;
524 
527  key,
528  value));
529  while (NULL != (dqe = tmp->send_head))
530  {
532  tmp->send_tail,
533  dqe);
534  if (NULL != dqe->cont)
535  dqe->cont(dqe->cont_cls,
537  dqe->msg_size,
538  0);
539  GNUNET_free(dqe);
540  }
541  if (NULL != tmp->send_delay_task)
542  {
544  tmp->send_delay_task = NULL;
545  }
546  GNUNET_free(tmp);
547  return GNUNET_OK;
548 }
549 
550 
554 void
556 {
557  struct DelayQueueEntry *cur;
558 
560  &free_tmps,
561  NULL);
563  peers = NULL;
564  while (NULL != (cur = generic_dqe_head))
565  {
566  GNUNET_CONTAINER_DLL_remove(generic_dqe_head,
567  generic_dqe_tail,
568  cur);
569  if (NULL != cur->cont)
570  cur->cont(cur->cont_cls,
572  cur->msg_size,
573  0);
574  GNUNET_free(cur);
575  }
576  if (NULL != generic_send_delay_task)
577  {
578  GNUNET_SCHEDULER_cancel(generic_send_delay_task);
579  generic_send_delay_task = NULL;
580  }
581 }
582 
583 /* 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:494
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:504
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:509
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:1237
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
User defined timestamp for completing operations.
Definition: gnunet-arm.c:114
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.
Information about ongoing sessions of the transport client.
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:686
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:480
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:639
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:499
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:131
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:1214
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:956