diff options
Diffstat (limited to 'src/ats/gnunet-service-ats_preferences.c')
-rw-r--r-- | src/ats/gnunet-service-ats_preferences.c | 264 |
1 files changed, 115 insertions, 149 deletions
diff --git a/src/ats/gnunet-service-ats_preferences.c b/src/ats/gnunet-service-ats_preferences.c index c9559ba89..297db7d7e 100644 --- a/src/ats/gnunet-service-ats_preferences.c +++ b/src/ats/gnunet-service-ats_preferences.c | |||
@@ -446,35 +446,122 @@ update_abs_preference (struct PreferenceClient *c, | |||
446 | 446 | ||
447 | 447 | ||
448 | /** | 448 | /** |
449 | * Change the preference for a peer | 449 | * Normalize an updated preference value |
450 | * | 450 | * |
451 | * @param client the client sending this request | 451 | * @param client the client with this preference |
452 | * @param peer the peer id | 452 | * @param peer the peer to change the preference for |
453 | * @param kind the preference kind to change | 453 | * @param kind the kind to change the preference |
454 | * @param score_abs the new preference score | 454 | * @param score_abs the normalized score |
455 | */ | 455 | */ |
456 | static void | 456 | static void |
457 | preference_change (struct GNUNET_SERVER_Client *client, | 457 | normalize_preference (struct GNUNET_SERVER_Client *client, |
458 | const struct GNUNET_PeerIdentity *peer, | 458 | const struct GNUNET_PeerIdentity *peer, |
459 | enum GNUNET_ATS_PreferenceKind kind, | 459 | enum GNUNET_ATS_PreferenceKind kind, |
460 | float score_abs) | 460 | float score_abs) |
461 | { | 461 | { |
462 | if (GNUNET_NO == | 462 | struct PreferenceClient *c_cur; |
463 | GNUNET_CONTAINER_multipeermap_contains (GSA_addresses, | 463 | struct PreferencePeer *p_cur; |
464 | peer)) | 464 | struct PeerRelative *r_cur; |
465 | double old_value; | ||
466 | int i; | ||
467 | |||
468 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
469 | "Client changes preference for peer `%s' for `%s' to %.2f\n", | ||
470 | GNUNET_i2s (peer), | ||
471 | GNUNET_ATS_print_preference_type (kind), | ||
472 | score_abs); | ||
473 | |||
474 | if (kind >= GNUNET_ATS_PreferenceCount) | ||
465 | { | 475 | { |
466 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 476 | GNUNET_break(0); |
467 | "Received CHANGE_PREFERENCE for unknown peer `%s'\n", | ||
468 | GNUNET_i2s (peer)); | ||
469 | return; | 477 | return; |
470 | } | 478 | } |
471 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 479 | |
472 | "Received CHANGE_PREFERENCE for peer `%s'\n", | 480 | /* Find preference client */ |
473 | GNUNET_i2s (peer)); | 481 | for (c_cur = pc_head; NULL != c_cur; c_cur = c_cur->next) |
474 | GAS_normalization_normalize_preference (client, | 482 | if (client == c_cur->client) |
475 | peer, | 483 | break; |
476 | kind, | 484 | /* Not found: create new preference client */ |
477 | score_abs); | 485 | if (NULL == c_cur) |
486 | { | ||
487 | c_cur = GNUNET_new (struct PreferenceClient); | ||
488 | c_cur->client = client; | ||
489 | for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) | ||
490 | { | ||
491 | c_cur->f_abs_sum[i] = DEFAULT_ABS_PREFERENCE; | ||
492 | c_cur->f_rel_sum[i] = DEFAULT_REL_PREFERENCE; | ||
493 | } | ||
494 | GNUNET_CONTAINER_DLL_insert (pc_head, | ||
495 | pc_tail, | ||
496 | c_cur); | ||
497 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
498 | "Adding new client %p\n", | ||
499 | c_cur); | ||
500 | } | ||
501 | |||
502 | /* Find entry for peer */ | ||
503 | for (p_cur = c_cur->p_head; NULL != p_cur; p_cur = p_cur->next) | ||
504 | if (0 == memcmp (&p_cur->id, | ||
505 | peer, | ||
506 | sizeof (p_cur->id))) | ||
507 | break; | ||
508 | |||
509 | /* Not found: create new peer entry */ | ||
510 | if (NULL == p_cur) | ||
511 | { | ||
512 | p_cur = GNUNET_new (struct PreferencePeer); | ||
513 | p_cur->client = c_cur; | ||
514 | p_cur->id = *peer; | ||
515 | for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) | ||
516 | { | ||
517 | /* Default value per peer absolute preference for a preference: 0 */ | ||
518 | p_cur->f_abs[i] = DEFAULT_ABS_PREFERENCE; | ||
519 | /* Default value per peer relative preference for a quality: 1.0 */ | ||
520 | p_cur->f_rel[i] = DEFAULT_REL_PREFERENCE; | ||
521 | p_cur->next_aging[i] = GNUNET_TIME_UNIT_FOREVER_ABS; | ||
522 | } | ||
523 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
524 | "Adding new peer %p for client %p\n", | ||
525 | p_cur, | ||
526 | c_cur); | ||
527 | GNUNET_CONTAINER_DLL_insert (c_cur->p_head, | ||
528 | c_cur->p_tail, | ||
529 | p_cur); | ||
530 | } | ||
531 | |||
532 | /* Create struct for peer */ | ||
533 | if (NULL == | ||
534 | GNUNET_CONTAINER_multipeermap_get (preference_peers, | ||
535 | peer)) | ||
536 | { | ||
537 | r_cur = GNUNET_new (struct PeerRelative); | ||
538 | r_cur->id = *peer; | ||
539 | for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) | ||
540 | r_cur->f_rel[i] = DEFAULT_REL_PREFERENCE; | ||
541 | GNUNET_assert(GNUNET_OK == | ||
542 | GNUNET_CONTAINER_multipeermap_put (preference_peers, | ||
543 | &r_cur->id, | ||
544 | r_cur, | ||
545 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
546 | } | ||
547 | |||
548 | /* Update absolute value */ | ||
549 | old_value = p_cur->f_abs[kind]; | ||
550 | update_abs_preference (c_cur, p_cur, kind, score_abs); | ||
551 | if (p_cur->f_abs[kind] == old_value) | ||
552 | return; | ||
553 | |||
554 | GAS_plugin_solver_lock (); | ||
555 | run_preference_update (c_cur, | ||
556 | p_cur, | ||
557 | kind, | ||
558 | score_abs); | ||
559 | GAS_plugin_solver_unlock (); | ||
560 | |||
561 | if (NULL == aging_task) | ||
562 | aging_task = GNUNET_SCHEDULER_add_delayed (PREF_AGING_INTERVAL, | ||
563 | &preference_aging, | ||
564 | NULL); | ||
478 | } | 565 | } |
479 | 566 | ||
480 | 567 | ||
@@ -497,8 +584,7 @@ GAS_handle_preference_change (void *cls, | |||
497 | uint32_t i; | 584 | uint32_t i; |
498 | 585 | ||
499 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 586 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
500 | "Received `%s' message\n", | 587 | "Received PREFERENCE_CHANGE message\n"); |
501 | "PREFERENCE_CHANGE"); | ||
502 | msize = ntohs (message->size); | 588 | msize = ntohs (message->size); |
503 | if (msize < sizeof (struct ChangePreferenceMessage)) | 589 | if (msize < sizeof (struct ChangePreferenceMessage)) |
504 | { | 590 | { |
@@ -521,11 +607,11 @@ GAS_handle_preference_change (void *cls, | |||
521 | 1, GNUNET_NO); | 607 | 1, GNUNET_NO); |
522 | pi = (const struct PreferenceInformation *) &msg[1]; | 608 | pi = (const struct PreferenceInformation *) &msg[1]; |
523 | for (i = 0; i < nump; i++) | 609 | for (i = 0; i < nump; i++) |
524 | preference_change (client, | 610 | normalize_preference (client, |
525 | &msg->peer, | 611 | &msg->peer, |
526 | (enum GNUNET_ATS_PreferenceKind) | 612 | (enum GNUNET_ATS_PreferenceKind) |
527 | ntohl (pi[i].preference_kind), | 613 | ntohl (pi[i].preference_kind), |
528 | pi[i].preference_value); | 614 | pi[i].preference_value); |
529 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 615 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
530 | } | 616 | } |
531 | 617 | ||
@@ -619,126 +705,6 @@ GAS_preference_done () | |||
619 | 705 | ||
620 | 706 | ||
621 | /** | 707 | /** |
622 | * Normalize an updated preference value | ||
623 | * | ||
624 | * @param client the client with this preference | ||
625 | * @param peer the peer to change the preference for | ||
626 | * @param kind the kind to change the preference | ||
627 | * @param score_abs the normalized score | ||
628 | */ | ||
629 | void | ||
630 | GAS_normalization_normalize_preference (struct GNUNET_SERVER_Client *client, | ||
631 | const struct GNUNET_PeerIdentity *peer, | ||
632 | enum GNUNET_ATS_PreferenceKind kind, | ||
633 | float score_abs) | ||
634 | { | ||
635 | struct PreferenceClient *c_cur; | ||
636 | struct PreferencePeer *p_cur; | ||
637 | struct PeerRelative *r_cur; | ||
638 | double old_value; | ||
639 | int i; | ||
640 | |||
641 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
642 | "Client changes preference for peer `%s' for `%s' to %.2f\n", | ||
643 | GNUNET_i2s (peer), | ||
644 | GNUNET_ATS_print_preference_type (kind), | ||
645 | score_abs); | ||
646 | |||
647 | if (kind >= GNUNET_ATS_PreferenceCount) | ||
648 | { | ||
649 | GNUNET_break(0); | ||
650 | return; | ||
651 | } | ||
652 | |||
653 | /* Find preference client */ | ||
654 | for (c_cur = pc_head; NULL != c_cur; c_cur = c_cur->next) | ||
655 | if (client == c_cur->client) | ||
656 | break; | ||
657 | /* Not found: create new preference client */ | ||
658 | if (NULL == c_cur) | ||
659 | { | ||
660 | c_cur = GNUNET_new (struct PreferenceClient); | ||
661 | c_cur->client = client; | ||
662 | for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) | ||
663 | { | ||
664 | c_cur->f_abs_sum[i] = DEFAULT_ABS_PREFERENCE; | ||
665 | c_cur->f_rel_sum[i] = DEFAULT_REL_PREFERENCE; | ||
666 | } | ||
667 | GNUNET_CONTAINER_DLL_insert (pc_head, | ||
668 | pc_tail, | ||
669 | c_cur); | ||
670 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
671 | "Adding new client %p\n", | ||
672 | c_cur); | ||
673 | } | ||
674 | |||
675 | /* Find entry for peer */ | ||
676 | for (p_cur = c_cur->p_head; NULL != p_cur; p_cur = p_cur->next) | ||
677 | if (0 == memcmp (&p_cur->id, | ||
678 | peer, | ||
679 | sizeof (p_cur->id))) | ||
680 | break; | ||
681 | |||
682 | /* Not found: create new peer entry */ | ||
683 | if (NULL == p_cur) | ||
684 | { | ||
685 | p_cur = GNUNET_new (struct PreferencePeer); | ||
686 | p_cur->client = c_cur; | ||
687 | p_cur->id = *peer; | ||
688 | for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) | ||
689 | { | ||
690 | /* Default value per peer absolute preference for a preference: 0 */ | ||
691 | p_cur->f_abs[i] = DEFAULT_ABS_PREFERENCE; | ||
692 | /* Default value per peer relative preference for a quality: 1.0 */ | ||
693 | p_cur->f_rel[i] = DEFAULT_REL_PREFERENCE; | ||
694 | p_cur->next_aging[i] = GNUNET_TIME_UNIT_FOREVER_ABS; | ||
695 | } | ||
696 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
697 | "Adding new peer %p for client %p\n", | ||
698 | p_cur, | ||
699 | c_cur); | ||
700 | GNUNET_CONTAINER_DLL_insert (c_cur->p_head, | ||
701 | c_cur->p_tail, | ||
702 | p_cur); | ||
703 | } | ||
704 | |||
705 | /* Create struct for peer */ | ||
706 | if (NULL == | ||
707 | GNUNET_CONTAINER_multipeermap_get (preference_peers, | ||
708 | peer)) | ||
709 | { | ||
710 | r_cur = GNUNET_new (struct PeerRelative); | ||
711 | r_cur->id = *peer; | ||
712 | for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) | ||
713 | r_cur->f_rel[i] = DEFAULT_REL_PREFERENCE; | ||
714 | GNUNET_assert(GNUNET_OK == | ||
715 | GNUNET_CONTAINER_multipeermap_put (preference_peers, | ||
716 | &r_cur->id, | ||
717 | r_cur, | ||
718 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
719 | } | ||
720 | |||
721 | /* Update absolute value */ | ||
722 | old_value = p_cur->f_abs[kind]; | ||
723 | update_abs_preference (c_cur, p_cur, kind, score_abs); | ||
724 | if (p_cur->f_abs[kind] == old_value) | ||
725 | return; | ||
726 | |||
727 | GAS_plugin_solver_lock (); | ||
728 | run_preference_update (c_cur, | ||
729 | p_cur, | ||
730 | kind, | ||
731 | score_abs); | ||
732 | GAS_plugin_solver_unlock (); | ||
733 | |||
734 | if (NULL == aging_task) | ||
735 | aging_task = GNUNET_SCHEDULER_add_delayed (PREF_AGING_INTERVAL, | ||
736 | &preference_aging, | ||
737 | NULL); | ||
738 | } | ||
739 | |||
740 | |||
741 | /** | ||
742 | * Get the normalized preference values for a specific peer or | 708 | * Get the normalized preference values for a specific peer or |
743 | * the default values if | 709 | * the default values if |
744 | * | 710 | * |