aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2013-04-03 15:49:00 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2013-04-03 15:49:00 +0000
commitc3a4702f0f1a31c9c47bd3f267f4227f9f9e8aba (patch)
tree77cd945570bd28fd8b27c1e9be93620f4b68f9e4
parentb2f1b737d50733230d2897f8e3362ed5d1558912 (diff)
downloadgnunet-c3a4702f0f1a31c9c47bd3f267f4227f9f9e8aba.tar.gz
gnunet-c3a4702f0f1a31c9c47bd3f267f4227f9f9e8aba.zip
generic ats support
-rw-r--r--src/transport/gnunet-service-transport_manipulation.c203
1 files changed, 53 insertions, 150 deletions
diff --git a/src/transport/gnunet-service-transport_manipulation.c b/src/transport/gnunet-service-transport_manipulation.c
index 0b88ad20b..4d6c3de9d 100644
--- a/src/transport/gnunet-service-transport_manipulation.c
+++ b/src/transport/gnunet-service-transport_manipulation.c
@@ -53,13 +53,29 @@ struct GST_ManipulationHandle man_handle;
53 */ 53 */
54struct TM_Peer; 54struct TM_Peer;
55 55
56/**
57 * Manipulation entry
58 */
56struct PropManipulationEntry 59struct PropManipulationEntry
57{ 60{
61 /**
62 * Next in DLL
63 */
58 struct PropManipulationEntry *next; 64 struct PropManipulationEntry *next;
65
66 /**
67 * Previous in DLL
68 */
59 struct PropManipulationEntry *prev; 69 struct PropManipulationEntry *prev;
60 70
71 /**
72 * ATS type in HBO
73 */
61 uint32_t type; 74 uint32_t type;
62 75
76 /**
77 * Value in HBO
78 */
63 uint32_t metrics[TM_BOTH]; 79 uint32_t metrics[TM_BOTH];
64 80
65}; 81};
@@ -106,30 +122,10 @@ struct GST_ManipulationHandle
106 */ 122 */
107 struct GNUNET_CONTAINER_MultiHashMap *peers; 123 struct GNUNET_CONTAINER_MultiHashMap *peers;
108 124
109 struct TM_Peer general;
110
111 /**
112 * General inbound delay
113 */
114 struct GNUNET_TIME_Relative delay_recv;
115
116 /** 125 /**
117 * General outbound delay 126 * Peer containing information for general manipulation
118 */ 127 */
119 struct GNUNET_TIME_Relative delay_send; 128 struct TM_Peer general;
120
121 /**
122 * General inbound distance
123 */
124 unsigned long long distance_recv;
125
126 /**
127 * General outbound distance
128 */
129 unsigned long long distance_send;
130
131 struct PropManipulationEntry *head;
132 struct PropManipulationEntry *tail;
133}; 129};
134 130
135 131
@@ -236,6 +232,10 @@ find_metric (struct TM_Peer *dest, uint32_t type, int direction)
236 return UINT32_MAX; 232 return UINT32_MAX;
237} 233}
238 234
235/**
236 * Clean up metrics for a peer
237 */
238
239static void 239static void
240free_metric (struct TM_Peer *dest) 240free_metric (struct TM_Peer *dest)
241{ 241{
@@ -250,69 +250,6 @@ free_metric (struct TM_Peer *dest)
250 } 250 }
251} 251}
252 252
253static void
254set_delay(struct TM_Peer *tmp, struct GNUNET_PeerIdentity *peer, int direction, uint32_t value)
255{
256 uint32_t val;
257 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Set traffic metrics %s for peer `%s' in direction %s to %u\n",
258 "DELAY", GNUNET_i2s(peer),
259 (TM_BOTH == direction) ? "BOTH" : (TM_SEND == direction) ? "SEND": "RECEIVE", value);
260
261 if (UINT32_MAX == value)
262 val = UINT32_MAX - 1; /* prevent overflow */
263 else if (0 == value)
264 val = UINT32_MAX; /* disable */
265 else
266 val = value;
267
268 switch (direction) {
269 case TM_BOTH:
270 tmp->metrics[TM_SEND][DELAY] = val;
271 tmp->metrics[TM_RECEIVE][DELAY] = val;
272 break;
273 case TM_SEND:
274 tmp->metrics[TM_SEND][DELAY] = val;
275 break;
276 case TM_RECEIVE:
277 tmp->metrics[TM_RECEIVE][DELAY] = val;
278 break;
279 default:
280 break;
281 }
282
283}
284
285static void
286set_distance (struct TM_Peer *tmp, struct GNUNET_PeerIdentity *peer, int direction, uint32_t value)
287{
288 uint32_t val;
289 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Set traffic metrics %s for peer `%s' in direction %s to %u\n",
290 "DISTANCE", GNUNET_i2s(peer),
291 (TM_BOTH == direction) ? "BOTH" : (TM_SEND == direction) ? "SEND": "RECEIVE", value);
292
293 if (UINT32_MAX == value)
294 val = UINT32_MAX - 1; /* prevent overflow */
295 else if (0 == value)
296 val = UINT32_MAX; /* disable */
297 else
298 val = value;
299
300 switch (direction) {
301 case TM_BOTH:
302 tmp->metrics[TM_SEND][DISTANCE] = val;
303 tmp->metrics[TM_RECEIVE][DISTANCE] = val;
304 break;
305 case TM_SEND:
306 tmp->metrics[TM_SEND][DISTANCE] = val;
307 break;
308 case TM_RECEIVE:
309 tmp->metrics[TM_RECEIVE][DISTANCE] = val;
310 break;
311 default:
312 break;
313 }
314}
315
316 253
317/** 254/**
318 * Set traffic metric to manipulate 255 * Set traffic metric to manipulate
@@ -360,28 +297,9 @@ GST_manipulation_set_metric (void *cls, struct GNUNET_SERVER_Client *client,
360 ats = (struct GNUNET_ATS_Information *) &tm[1]; 297 ats = (struct GNUNET_ATS_Information *) &tm[1];
361 for (c = 0; c < ntohs (tm->ats_count); c++) 298 for (c = 0; c < ntohs (tm->ats_count); c++)
362 { 299 {
363 set_metric (&man_handle.general, direction, ats[c].type, ats[c].value);
364
365 type = htonl (ats[c].type); 300 type = htonl (ats[c].type);
366 value = htonl (ats[c].value); 301 value = htonl (ats[c].value);
367 302 set_metric (&man_handle.general, direction, type, value);
368 switch (type) {
369 case GNUNET_ATS_QUALITY_NET_DELAY:
370 if ((TM_RECEIVE == direction) || (TM_BOTH == direction))
371 man_handle.delay_recv.rel_value = value;
372 if ((TM_SEND == direction) || (TM_BOTH == direction))
373 man_handle.delay_send.rel_value = value;
374 break;
375 case GNUNET_ATS_QUALITY_NET_DISTANCE:
376 if ((TM_RECEIVE == direction) || (TM_BOTH == direction))
377 man_handle.distance_recv = value;
378 if ((TM_SEND == direction) || (TM_BOTH == direction))
379 man_handle.distance_send = value;
380 break;
381 default:
382 break;
383 }
384
385 } 303 }
386 return; 304 return;
387 } 305 }
@@ -408,20 +326,7 @@ GST_manipulation_set_metric (void *cls, struct GNUNET_SERVER_Client *client,
408 { 326 {
409 type = htonl (ats[c].type); 327 type = htonl (ats[c].type);
410 value = htonl (ats[c].value); 328 value = htonl (ats[c].value);
411 329 set_metric (tmp, direction, type, value);
412 set_metric (tmp, direction, ats[c].type, ats[c].value);
413
414
415 switch (type) {
416 case GNUNET_ATS_QUALITY_NET_DELAY:
417 set_delay (tmp, &tm->peer, direction, value);
418 break;
419 case GNUNET_ATS_QUALITY_NET_DISTANCE:
420 set_distance (tmp, &tm->peer, direction, value);
421 break;
422 default:
423 break;
424 }
425 } 330 }
426 331
427 GNUNET_SERVER_receive_done (client, GNUNET_OK); 332 GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -473,10 +378,10 @@ GST_manipulation_send (const struct GNUNET_PeerIdentity *target, const void *msg
473 { 378 {
474 /* Manipulate here */ 379 /* Manipulate here */
475 /* Delay */ 380 /* Delay */
476 if (UINT32_MAX != ntohl (find_metric(tmp, htonl (GNUNET_ATS_QUALITY_NET_DELAY), TM_SEND))) 381 if (UINT32_MAX != find_metric(tmp, GNUNET_ATS_QUALITY_NET_DELAY, TM_SEND))
477 { 382 {
478 /* We have a delay */ 383 /* We have a delay */
479 delay.rel_value = ntohl (find_metric(tmp, htonl (GNUNET_ATS_QUALITY_NET_DELAY), TM_SEND)); 384 delay.rel_value = find_metric(tmp, GNUNET_ATS_QUALITY_NET_DELAY, TM_SEND);
480 dqe = GNUNET_malloc (sizeof (struct DelayQueueEntry) + msg_size); 385 dqe = GNUNET_malloc (sizeof (struct DelayQueueEntry) + msg_size);
481 dqe->tmp = tmp; 386 dqe->tmp = tmp;
482 dqe->sent_at = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), delay); 387 dqe->sent_at = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), delay);
@@ -492,10 +397,10 @@ GST_manipulation_send (const struct GNUNET_PeerIdentity *target, const void *msg
492 return; 397 return;
493 } 398 }
494 } 399 }
495 else if (UINT32_MAX != ntohl (find_metric (&man_handle.general, htonl (GNUNET_ATS_QUALITY_NET_DELAY), TM_SEND))) 400 else if (UINT32_MAX != find_metric (&man_handle.general, GNUNET_ATS_QUALITY_NET_DELAY, TM_SEND))
496 { 401 {
497 /* We have a delay */ 402 /* We have a delay */
498 delay.rel_value = ntohl (find_metric (&man_handle.general, htonl (GNUNET_ATS_QUALITY_NET_DELAY), TM_SEND)); 403 delay.rel_value = find_metric (&man_handle.general, GNUNET_ATS_QUALITY_NET_DELAY, TM_SEND);
499 dqe = GNUNET_malloc (sizeof (struct DelayQueueEntry) + msg_size); 404 dqe = GNUNET_malloc (sizeof (struct DelayQueueEntry) + msg_size);
500 dqe->tmp = tmp; 405 dqe->tmp = tmp;
501 dqe->sent_at = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), delay); 406 dqe->sent_at = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), delay);
@@ -535,29 +440,24 @@ GST_manipulation_manipulate_metrics (const struct GNUNET_PeerIdentity *peer,
535{ 440{
536 struct GNUNET_ATS_Information *ats_new = GNUNET_malloc (sizeof (struct GNUNET_ATS_Information) *ats_count); 441 struct GNUNET_ATS_Information *ats_new = GNUNET_malloc (sizeof (struct GNUNET_ATS_Information) *ats_count);
537 struct TM_Peer *tmp; 442 struct TM_Peer *tmp;
538 uint32_t m_distance; 443 uint32_t m_tmp;
444 uint32_t g_tmp;
539 int d; 445 int d;
540 m_distance = 0; 446 tmp = GNUNET_CONTAINER_multihashmap_get (man_handle.peers, &peer->hashPubKey);
541 if (NULL != (tmp = GNUNET_CONTAINER_multihashmap_get (man_handle.peers, &peer->hashPubKey)))
542 {
543 if (UINT32_MAX != tmp->metrics[TM_RECEIVE][DISTANCE])
544 m_distance = tmp->metrics[TM_RECEIVE][DISTANCE];
545 }
546 447
547 for (d = 0; d < ats_count; d++) 448 for (d = 0; d < ats_count; d++)
548 { 449 {
549 ats_new[d] = ats[d]; 450 ats_new[d] = ats[d];
550 if (ntohl(ats[d].type) == GNUNET_ATS_QUALITY_NET_DISTANCE) 451 m_tmp = UINT32_MAX;
551 { 452 g_tmp = UINT32_MAX;
552 if (m_distance > 0) 453 if (NULL != tmp)
553 { 454 m_tmp = find_metric (tmp, ntohl(ats[d].type), TM_RECEIVE);
554 ats_new[d].value = htonl(m_distance); 455 g_tmp = find_metric (&man_handle.general, ntohl(ats[d].type), TM_RECEIVE);
555 } 456
556 else if (man_handle.distance_recv > 0) 457 if (UINT32_MAX != g_tmp)
557 { 458 ats_new[d].value = htonl(g_tmp);
558 ats_new[d].value = htonl(man_handle.distance_recv); 459 if (UINT32_MAX != m_tmp)
559 } 460 ats_new[d].value = htonl(m_tmp);
560 }
561 } 461 }
562 462
563 return ats_new; 463 return ats_new;
@@ -585,20 +485,23 @@ GST_manipulation_recv (void *cls,
585 uint16_t sender_address_len) 485 uint16_t sender_address_len)
586{ 486{
587 struct TM_Peer *tmp; 487 struct TM_Peer *tmp;
588 488 uint32_t p_recv_delay;
489 uint32_t g_recv_delay;
589 struct GNUNET_TIME_Relative quota_delay; 490 struct GNUNET_TIME_Relative quota_delay;
590 struct GNUNET_TIME_Relative m_delay; 491 struct GNUNET_TIME_Relative m_delay;
591 492
592 if (man_handle.delay_recv.rel_value > GNUNET_TIME_UNIT_ZERO.rel_value) 493 g_recv_delay = find_metric (&man_handle.general, GNUNET_ATS_QUALITY_NET_DELAY, TM_RECEIVE);
593 m_delay = man_handle.delay_recv; /* Global delay */ 494 if ((g_recv_delay >= GNUNET_TIME_UNIT_ZERO.rel_value) && (UINT32_MAX != g_recv_delay))
495 m_delay.rel_value = g_recv_delay; /* Global delay */
594 else 496 else
595 m_delay = GNUNET_TIME_UNIT_ZERO; 497 m_delay = GNUNET_TIME_UNIT_ZERO;
596 498
597 if (NULL != (tmp = GNUNET_CONTAINER_multihashmap_get (man_handle.peers, &peer->hashPubKey))) 499 if (NULL != (tmp = GNUNET_CONTAINER_multihashmap_get (man_handle.peers, &peer->hashPubKey)))
598 { 500 {
599 /* Manipulate receive delay */ 501 /* Manipulate receive delay */
600 if (UINT32_MAX != tmp->metrics[TM_RECEIVE][DELAY]) 502 p_recv_delay = find_metric (tmp, GNUNET_ATS_QUALITY_NET_DELAY, TM_RECEIVE);
601 m_delay.rel_value = tmp->metrics[TM_RECEIVE][DELAY]; /* Peer specific delay */ 503 if (UINT32_MAX != p_recv_delay)
504 m_delay.rel_value = p_recv_delay; /* Peer specific delay */
602 } 505 }
603 506
604 quota_delay = GST_receive_callback (cls, peer, message, 507 quota_delay = GST_receive_callback (cls, peer, message,
@@ -625,7 +528,7 @@ GST_manipulation_init (const struct GNUNET_CONFIGURATION_Handle *GST_cfg)
625 { 528 {
626 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Setting inbound distance_in to %u\n", 529 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Setting inbound distance_in to %u\n",
627 (unsigned long long) tmp); 530 (unsigned long long) tmp);
628 set_metric (&man_handle.general, TM_RECEIVE, htonl (GNUNET_ATS_QUALITY_NET_DISTANCE), htonl(tmp)); 531 set_metric (&man_handle.general, TM_RECEIVE, GNUNET_ATS_QUALITY_NET_DISTANCE, tmp);
629 } 532 }
630 533
631 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (GST_cfg, 534 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (GST_cfg,
@@ -633,7 +536,7 @@ GST_manipulation_init (const struct GNUNET_CONFIGURATION_Handle *GST_cfg)
633 { 536 {
634 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Setting outbound distance_in to %u\n", 537 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Setting outbound distance_in to %u\n",
635 (unsigned long long) tmp); 538 (unsigned long long) tmp);
636 set_metric (&man_handle.general, TM_SEND, htonl (GNUNET_ATS_QUALITY_NET_DISTANCE), htonl(tmp)); 539 set_metric (&man_handle.general, TM_SEND, GNUNET_ATS_QUALITY_NET_DISTANCE, tmp);
637 } 540 }
638 541
639 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (GST_cfg, 542 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (GST_cfg,
@@ -641,7 +544,7 @@ GST_manipulation_init (const struct GNUNET_CONFIGURATION_Handle *GST_cfg)
641 { 544 {
642 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Delaying inbound traffic for %llu ms\n", 545 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Delaying inbound traffic for %llu ms\n",
643 (unsigned long long) tmp); 546 (unsigned long long) tmp);
644 set_metric (&man_handle.general, TM_RECEIVE, htonl (GNUNET_ATS_QUALITY_NET_DELAY), htonl(tmp)); 547 set_metric (&man_handle.general, TM_RECEIVE, GNUNET_ATS_QUALITY_NET_DELAY, tmp);
645 } 548 }
646 549
647 550
@@ -650,7 +553,7 @@ GST_manipulation_init (const struct GNUNET_CONFIGURATION_Handle *GST_cfg)
650 { 553 {
651 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Delaying outbound traffic for %llu ms\n", 554 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Delaying outbound traffic for %llu ms\n",
652 (unsigned long long) tmp); 555 (unsigned long long) tmp);
653 set_metric (&man_handle.general, TM_SEND, htonl (GNUNET_ATS_QUALITY_NET_DELAY), htonl(tmp)); 556 set_metric (&man_handle.general, TM_SEND, GNUNET_ATS_QUALITY_NET_DELAY, tmp);
654 } 557 }
655 558
656 man_handle.peers = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); 559 man_handle.peers = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO);