diff options
Diffstat (limited to 'src/transport/gnunet-service-transport_ats.c')
-rw-r--r-- | src/transport/gnunet-service-transport_ats.c | 248 |
1 files changed, 135 insertions, 113 deletions
diff --git a/src/transport/gnunet-service-transport_ats.c b/src/transport/gnunet-service-transport_ats.c index 613f35ec2..3976ae3d9 100644 --- a/src/transport/gnunet-service-transport_ats.c +++ b/src/transport/gnunet-service-transport_ats.c | |||
@@ -29,6 +29,8 @@ | |||
29 | #include "gnunet-service-transport_plugins.h" | 29 | #include "gnunet-service-transport_plugins.h" |
30 | #include "gnunet_ats_service.h" | 30 | #include "gnunet_ats_service.h" |
31 | 31 | ||
32 | #define LOG(kind,...) GNUNET_log_from(kind, "transport-ats", __VA_ARGS__) | ||
33 | |||
32 | 34 | ||
33 | /** | 35 | /** |
34 | * Information we track for each address known to ATS. | 36 | * Information we track for each address known to ATS. |
@@ -52,6 +54,11 @@ struct AddressInfo | |||
52 | struct GNUNET_ATS_AddressRecord *ar; | 54 | struct GNUNET_ATS_AddressRecord *ar; |
53 | 55 | ||
54 | /** | 56 | /** |
57 | * Performance properties of this address. | ||
58 | */ | ||
59 | struct GNUNET_ATS_Properties properties; | ||
60 | |||
61 | /** | ||
55 | * Time until when this address is blocked and should thus not be | 62 | * Time until when this address is blocked and should thus not be |
56 | * made available to ATS (@e ar should be NULL until this time). | 63 | * made available to ATS (@e ar should be NULL until this time). |
57 | * Used when transport determines that for some reason it | 64 | * Used when transport determines that for some reason it |
@@ -256,16 +263,15 @@ unblock_address (void *cls, | |||
256 | struct AddressInfo *ai = cls; | 263 | struct AddressInfo *ai = cls; |
257 | 264 | ||
258 | ai->unblock_task = NULL; | 265 | ai->unblock_task = NULL; |
259 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 266 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
260 | "Unblocking address %s of peer %s\n", | 267 | "Unblocking address %s of peer %s\n", |
261 | GST_plugins_a2s (ai->address), | 268 | GST_plugins_a2s (ai->address), |
262 | GNUNET_i2s (&ai->address->peer)); | 269 | GNUNET_i2s (&ai->address->peer)); |
263 | ai->ar = GNUNET_ATS_address_add (GST_ats, | 270 | ai->ar = GNUNET_ATS_address_add (GST_ats, |
264 | ai->address, | 271 | ai->address, |
265 | ai->session, | 272 | ai->session, |
266 | NULL, 0); | 273 | &ai->properties); |
267 | GNUNET_break (NULL != ai->ar); | 274 | GNUNET_break (NULL != ai->ar); |
268 | /* FIXME: should pass ATS information here! */ | ||
269 | } | 275 | } |
270 | 276 | ||
271 | 277 | ||
@@ -299,15 +305,15 @@ GST_ats_block_address (const struct GNUNET_HELLO_Address *address, | |||
299 | if (GNUNET_YES == | 305 | if (GNUNET_YES == |
300 | GNUNET_HELLO_address_check_option (address, | 306 | GNUNET_HELLO_address_check_option (address, |
301 | GNUNET_HELLO_ADDRESS_INFO_INBOUND)) | 307 | GNUNET_HELLO_ADDRESS_INFO_INBOUND)) |
302 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 308 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
303 | "Removing address %s of peer %s from use (inbound died)\n", | 309 | "Removing address %s of peer %s from use (inbound died)\n", |
304 | GST_plugins_a2s (address), | 310 | GST_plugins_a2s (address), |
305 | GNUNET_i2s (&address->peer)); | 311 | GNUNET_i2s (&address->peer)); |
306 | else | 312 | else |
307 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 313 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
308 | "Blocking address %s of peer %s from use for a while\n", | 314 | "Blocking address %s of peer %s from use for a while\n", |
309 | GST_plugins_a2s (address), | 315 | GST_plugins_a2s (address), |
310 | GNUNET_i2s (&address->peer)); | 316 | GNUNET_i2s (&address->peer)); |
311 | /* destroy session and address */ | 317 | /* destroy session and address */ |
312 | if ( (NULL == session) || | 318 | if ( (NULL == session) || |
313 | (GNUNET_NO == | 319 | (GNUNET_NO == |
@@ -332,20 +338,15 @@ GST_ats_block_address (const struct GNUNET_HELLO_Address *address, | |||
332 | * | 338 | * |
333 | * @param address the address | 339 | * @param address the address |
334 | * @param session the session | 340 | * @param session the session |
335 | * @param ats ats information | 341 | * @param prop performance information |
336 | * @param ats_count number of @a ats information | ||
337 | */ | 342 | */ |
338 | void | 343 | void |
339 | GST_ats_add_inbound_address (const struct GNUNET_HELLO_Address *address, | 344 | GST_ats_add_inbound_address (const struct GNUNET_HELLO_Address *address, |
340 | struct Session *session, | 345 | struct Session *session, |
341 | const struct GNUNET_ATS_Information *ats, | 346 | const struct GNUNET_ATS_Properties *prop) |
342 | uint32_t ats_count) | ||
343 | { | 347 | { |
344 | struct GNUNET_TRANSPORT_PluginFunctions *papi; | ||
345 | struct GNUNET_ATS_Information ats2[ats_count + 1]; | ||
346 | struct GNUNET_ATS_AddressRecord *ar; | 348 | struct GNUNET_ATS_AddressRecord *ar; |
347 | struct AddressInfo *ai; | 349 | struct AddressInfo *ai; |
348 | uint32_t net; | ||
349 | 350 | ||
350 | /* valid new address, let ATS know! */ | 351 | /* valid new address, let ATS know! */ |
351 | if (NULL == address->transport_name) | 352 | if (NULL == address->transport_name) |
@@ -365,40 +366,24 @@ GST_ats_add_inbound_address (const struct GNUNET_HELLO_Address *address, | |||
365 | GNUNET_break (0); | 366 | GNUNET_break (0); |
366 | return; | 367 | return; |
367 | } | 368 | } |
368 | papi = GST_plugins_find (address->transport_name); | 369 | GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != prop->scope); |
369 | GNUNET_assert (NULL != papi); | 370 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
370 | net = papi->get_network (papi->cls, session); | 371 | "Notifying ATS about peer `%s''s new inbound address `%s' session %p in network %s\n", |
371 | if (GNUNET_ATS_NET_UNSPECIFIED == net) | 372 | GNUNET_i2s (&address->peer), |
372 | { | 373 | (0 == address->address_length) |
373 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 374 | ? "<inbound>" |
374 | _("Could not obtain a valid network for `%s' %s (%s)\n"), | 375 | : GST_plugins_a2s (address), |
375 | GNUNET_i2s (&address->peer), | 376 | session, |
376 | GST_plugins_a2s (address), | 377 | GNUNET_ATS_print_network_type (prop->scope)); |
377 | address->transport_name); | ||
378 | return; | ||
379 | } | ||
380 | ats2[0].type = htonl (GNUNET_ATS_NETWORK_TYPE); | ||
381 | ats2[0].value = htonl (net); | ||
382 | memcpy (&ats2[1], | ||
383 | ats, | ||
384 | sizeof(struct GNUNET_ATS_Information) * ats_count); | ||
385 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
386 | "Notifying ATS about peer `%s''s new inbound address `%s' session %p in network %s\n", | ||
387 | GNUNET_i2s (&address->peer), | ||
388 | (0 == address->address_length) | ||
389 | ? "<inbound>" | ||
390 | : GST_plugins_a2s (address), | ||
391 | session, | ||
392 | GNUNET_ATS_print_network_type (net)); | ||
393 | ar = GNUNET_ATS_address_add (GST_ats, | 378 | ar = GNUNET_ATS_address_add (GST_ats, |
394 | address, | 379 | address, |
395 | session, | 380 | session, |
396 | (NULL != session) ? ats2 : ats, | 381 | prop); |
397 | (NULL != session) ? ats_count + 1 : ats_count); | ||
398 | GNUNET_break (NULL != ar); | 382 | GNUNET_break (NULL != ar); |
399 | ai = GNUNET_new (struct AddressInfo); | 383 | ai = GNUNET_new (struct AddressInfo); |
400 | ai->address = GNUNET_HELLO_address_copy (address); | 384 | ai->address = GNUNET_HELLO_address_copy (address); |
401 | ai->session = session; | 385 | ai->session = session; |
386 | ai->properties = *prop; | ||
402 | ai->ar = ar; | 387 | ai->ar = ar; |
403 | (void) GNUNET_CONTAINER_multipeermap_put (p2a, | 388 | (void) GNUNET_CONTAINER_multipeermap_put (p2a, |
404 | &ai->address->peer, | 389 | &ai->address->peer, |
@@ -413,13 +398,11 @@ GST_ats_add_inbound_address (const struct GNUNET_HELLO_Address *address, | |||
413 | * located in. The address must NOT be inbound and must be new to ATS. | 398 | * located in. The address must NOT be inbound and must be new to ATS. |
414 | * | 399 | * |
415 | * @param address the address | 400 | * @param address the address |
416 | * @param ats ats information | 401 | * @param prop performance information |
417 | * @param ats_count number of @a ats information | ||
418 | */ | 402 | */ |
419 | void | 403 | void |
420 | GST_ats_add_address (const struct GNUNET_HELLO_Address *address, | 404 | GST_ats_add_address (const struct GNUNET_HELLO_Address *address, |
421 | const struct GNUNET_ATS_Information *ats, | 405 | const struct GNUNET_ATS_Properties *prop) |
422 | uint32_t ats_count) | ||
423 | { | 406 | { |
424 | struct GNUNET_ATS_AddressRecord *ar; | 407 | struct GNUNET_ATS_AddressRecord *ar; |
425 | struct AddressInfo *ai; | 408 | struct AddressInfo *ai; |
@@ -435,21 +418,21 @@ GST_ats_add_address (const struct GNUNET_HELLO_Address *address, | |||
435 | GNUNET_HELLO_ADDRESS_INFO_INBOUND)); | 418 | GNUNET_HELLO_ADDRESS_INFO_INBOUND)); |
436 | ai = find_ai_no_session (address); | 419 | ai = find_ai_no_session (address); |
437 | GNUNET_assert (NULL == ai); | 420 | GNUNET_assert (NULL == ai); |
438 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 421 | LOG (GNUNET_ERROR_TYPE_INFO, |
439 | "Notifying ATS about peer `%s''s new address `%s'\n", | 422 | "Notifying ATS about peer `%s''s new address `%s'\n", |
440 | GNUNET_i2s (&address->peer), | 423 | GNUNET_i2s (&address->peer), |
441 | (0 == address->address_length) | 424 | (0 == address->address_length) |
442 | ? "<inbound>" | 425 | ? "<inbound>" |
443 | : GST_plugins_a2s (address)); | 426 | : GST_plugins_a2s (address)); |
444 | ar = GNUNET_ATS_address_add (GST_ats, | 427 | ar = GNUNET_ATS_address_add (GST_ats, |
445 | address, | 428 | address, |
446 | NULL, | 429 | NULL, |
447 | ats, | 430 | prop); |
448 | ats_count); | ||
449 | GNUNET_break (NULL != ar); | 431 | GNUNET_break (NULL != ar); |
450 | ai = GNUNET_new (struct AddressInfo); | 432 | ai = GNUNET_new (struct AddressInfo); |
451 | ai->address = GNUNET_HELLO_address_copy (address); | 433 | ai->address = GNUNET_HELLO_address_copy (address); |
452 | ai->ar = ar; | 434 | ai->ar = ar; |
435 | ai->properties = *prop; | ||
453 | (void) GNUNET_CONTAINER_multipeermap_put (p2a, | 436 | (void) GNUNET_CONTAINER_multipeermap_put (p2a, |
454 | &ai->address->peer, | 437 | &ai->address->peer, |
455 | ai, | 438 | ai, |
@@ -484,11 +467,9 @@ GST_ats_new_session (const struct GNUNET_HELLO_Address *address, | |||
484 | } | 467 | } |
485 | GNUNET_break (NULL == ai->session); | 468 | GNUNET_break (NULL == ai->session); |
486 | ai->session = session; | 469 | ai->session = session; |
487 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 470 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
488 | "transport-ats", | 471 | "Telling ATS about new session for peer %s\n", |
489 | "Telling ATS about new session %p for peer %s\n", | 472 | GNUNET_i2s (&address->peer)); |
490 | session, | ||
491 | GNUNET_i2s (&address->peer)); | ||
492 | if (NULL != ai->ar) | 473 | if (NULL != ai->ar) |
493 | GNUNET_ATS_address_add_session (ai->ar, | 474 | GNUNET_ATS_address_add_session (ai->ar, |
494 | session); | 475 | session); |
@@ -528,11 +509,10 @@ GST_ats_del_session (const struct GNUNET_HELLO_Address *address, | |||
528 | } | 509 | } |
529 | GNUNET_assert (session == ai->session); | 510 | GNUNET_assert (session == ai->session); |
530 | ai->session = NULL; | 511 | ai->session = NULL; |
531 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 512 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
532 | "transport-ats", | 513 | "Telling ATS to destroy session %p from peer %s\n", |
533 | "Telling ATS to destroy session %p from peer %s\n", | 514 | session, |
534 | session, | 515 | GNUNET_i2s (&address->peer)); |
535 | GNUNET_i2s (&address->peer)); | ||
536 | if (NULL == ai->ar) | 516 | if (NULL == ai->ar) |
537 | { | 517 | { |
538 | /* If ATS doesn't know about the address/session, and this | 518 | /* If ATS doesn't know about the address/session, and this |
@@ -555,52 +535,95 @@ GST_ats_del_session (const struct GNUNET_HELLO_Address *address, | |||
555 | 535 | ||
556 | 536 | ||
557 | /** | 537 | /** |
558 | * Notify ATS about property changes to an address. | 538 | * Notify ATS about DV distance change to an address's. |
559 | * | 539 | * |
560 | * @param address our information about the address | 540 | * @param address the address |
561 | * @param session the session | 541 | * @param distance new distance value |
562 | * @param ats performance information | ||
563 | * @param ats_count number of elements in @a ats | ||
564 | */ | 542 | */ |
565 | void | 543 | void |
566 | GST_ats_update_metrics (const struct GNUNET_HELLO_Address *address, | 544 | GST_ats_update_distance (const struct GNUNET_HELLO_Address *address, |
567 | struct Session *session, | 545 | uint32_t distance) |
568 | const struct GNUNET_ATS_Information *ats, | ||
569 | uint32_t ats_count) | ||
570 | { | 546 | { |
571 | struct GNUNET_ATS_Information *ats_new; | ||
572 | struct AddressInfo *ai; | 547 | struct AddressInfo *ai; |
573 | 548 | ||
574 | ai = find_ai (address, session); | 549 | ai = find_ai_no_session (address); |
575 | if (NULL == ai) | 550 | if (NULL == ai) |
576 | { | ||
577 | /* We sometimes create sessions just for sending a PING, | ||
578 | and if we get metrics for those, they were never known to | ||
579 | ATS which means we end up here (however, in this | ||
580 | case, the address must be an outbound address). */ | ||
581 | GNUNET_break (GNUNET_YES != | ||
582 | GNUNET_HELLO_address_check_option (address, | ||
583 | GNUNET_HELLO_ADDRESS_INFO_INBOUND)); | ||
584 | return; | 551 | return; |
585 | } | 552 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
586 | /* Call to manipulation to manipulate ATS information */ | 553 | "Updated distance for peer `%s' to %u\n", |
587 | GNUNET_assert (NULL != GST_ats); | 554 | GNUNET_i2s (&address->peer), |
588 | if ((NULL == ats) || (0 == ats_count)) | 555 | distance); |
556 | ai->properties.distance = distance; | ||
557 | GST_manipulation_manipulate_metrics (address, | ||
558 | ai->session, | ||
559 | &ai->properties); | ||
560 | if (NULL != ai->ar) | ||
561 | GNUNET_ATS_address_update (ai->ar, | ||
562 | &ai->properties); | ||
563 | } | ||
564 | |||
565 | |||
566 | /** | ||
567 | * Notify ATS about property changes to an address's properties. | ||
568 | * | ||
569 | * @param address the address | ||
570 | * @param delay new delay value | ||
571 | */ | ||
572 | void | ||
573 | GST_ats_update_delay (const struct GNUNET_HELLO_Address *address, | ||
574 | struct GNUNET_TIME_Relative delay) | ||
575 | { | ||
576 | struct AddressInfo *ai; | ||
577 | |||
578 | ai = find_ai_no_session (address); | ||
579 | if (NULL == ai) | ||
580 | return; | ||
581 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
582 | "Updated latency for peer `%s' to %s\n", | ||
583 | GNUNET_i2s (&address->peer), | ||
584 | GNUNET_STRINGS_relative_time_to_string (delay, | ||
585 | GNUNET_YES)); | ||
586 | ai->properties.delay = delay; | ||
587 | GST_manipulation_manipulate_metrics (address, | ||
588 | ai->session, | ||
589 | &ai->properties); | ||
590 | if (NULL != ai->ar) | ||
591 | GNUNET_ATS_address_update (ai->ar, | ||
592 | &ai->properties); | ||
593 | } | ||
594 | |||
595 | |||
596 | /** | ||
597 | * Notify ATS about utilization changes to an address. | ||
598 | * | ||
599 | * @param address our information about the address | ||
600 | * @param bps_in new utilization inbound | ||
601 | * @param bps_out new utilization outbound | ||
602 | */ | ||
603 | void | ||
604 | GST_ats_update_utilization (const struct GNUNET_HELLO_Address *address, | ||
605 | uint32_t bps_in, | ||
606 | uint32_t bps_out) | ||
607 | { | ||
608 | struct AddressInfo *ai; | ||
609 | |||
610 | ai = find_ai_no_session (address); | ||
611 | if (NULL == ai) | ||
589 | return; | 612 | return; |
590 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 613 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
591 | "Updating metrics for peer `%s' address %s session %p\n", | 614 | "Updating utilization for peer `%s' address %s: %u/%u\n", |
592 | GNUNET_i2s (&address->peer), | 615 | GNUNET_i2s (&address->peer), |
593 | GST_plugins_a2s (address), | 616 | GST_plugins_a2s (address), |
594 | session); | 617 | (unsigned int) bps_in, |
595 | ats_new = GST_manipulation_manipulate_metrics (address, | 618 | (unsigned int) bps_out); |
596 | session, | 619 | ai->properties.utilization_in = bps_in; |
597 | ats, | 620 | ai->properties.utilization_out = bps_out; |
598 | ats_count); | 621 | GST_manipulation_manipulate_metrics (address, |
622 | ai->session, | ||
623 | &ai->properties); | ||
599 | if (NULL != ai->ar) | 624 | if (NULL != ai->ar) |
600 | GNUNET_ATS_address_update (ai->ar, | 625 | GNUNET_ATS_address_update (ai->ar, |
601 | ats_new, | 626 | &ai->properties); |
602 | ats_count); | ||
603 | GNUNET_free_non_null (ats_new); | ||
604 | } | 627 | } |
605 | 628 | ||
606 | 629 | ||
@@ -616,10 +639,10 @@ GST_ats_expire_address (const struct GNUNET_HELLO_Address *address) | |||
616 | { | 639 | { |
617 | struct AddressInfo *ai; | 640 | struct AddressInfo *ai; |
618 | 641 | ||
619 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 642 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
620 | "Address %s of peer %s expired\n", | 643 | "Address %s of peer %s expired\n", |
621 | GST_plugins_a2s (address), | 644 | GST_plugins_a2s (address), |
622 | GNUNET_i2s (&address->peer)); | 645 | GNUNET_i2s (&address->peer)); |
623 | ai = find_ai_no_session (address); | 646 | ai = find_ai_no_session (address); |
624 | if (NULL == ai) | 647 | if (NULL == ai) |
625 | { | 648 | { |
@@ -632,10 +655,9 @@ GST_ats_expire_address (const struct GNUNET_HELLO_Address *address) | |||
632 | ai)); | 655 | ai)); |
633 | publish_p2a_stat_update (); | 656 | publish_p2a_stat_update (); |
634 | GNUNET_break (NULL == ai->session); | 657 | GNUNET_break (NULL == ai->session); |
635 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 658 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
636 | "transport-ats", | 659 | "Telling ATS to destroy address from peer %s\n", |
637 | "Telling ATS to destroy address from peer %s\n", | 660 | GNUNET_i2s (&address->peer)); |
638 | GNUNET_i2s (&address->peer)); | ||
639 | if (NULL != ai->ar) | 661 | if (NULL != ai->ar) |
640 | { | 662 | { |
641 | /* We usually should not have a session here when we | 663 | /* We usually should not have a session here when we |