diff options
Diffstat (limited to 'src/transport/gnunet-service-transport_manipulation.c')
-rw-r--r-- | src/transport/gnunet-service-transport_manipulation.c | 203 |
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 | */ |
54 | struct TM_Peer; | 54 | struct TM_Peer; |
55 | 55 | ||
56 | /** | ||
57 | * Manipulation entry | ||
58 | */ | ||
56 | struct PropManipulationEntry | 59 | struct 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 | |||
239 | static void | 239 | static void |
240 | free_metric (struct TM_Peer *dest) | 240 | free_metric (struct TM_Peer *dest) |
241 | { | 241 | { |
@@ -250,69 +250,6 @@ free_metric (struct TM_Peer *dest) | |||
250 | } | 250 | } |
251 | } | 251 | } |
252 | 252 | ||
253 | static void | ||
254 | set_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 | |||
285 | static void | ||
286 | set_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); |