diff options
Diffstat (limited to 'src/fs/gnunet-service-fs.c')
-rw-r--r-- | src/fs/gnunet-service-fs.c | 116 |
1 files changed, 88 insertions, 28 deletions
diff --git a/src/fs/gnunet-service-fs.c b/src/fs/gnunet-service-fs.c index 139cb5aa9..3886e1de3 100644 --- a/src/fs/gnunet-service-fs.c +++ b/src/fs/gnunet-service-fs.c | |||
@@ -283,6 +283,16 @@ struct ConnectedPeer | |||
283 | struct GNUNET_LOAD_Value *transmission_delay; | 283 | struct GNUNET_LOAD_Value *transmission_delay; |
284 | 284 | ||
285 | /** | 285 | /** |
286 | * Context of our GNUNET_CORE_peer_change_preference call (or NULL). | ||
287 | */ | ||
288 | struct GNUNET_CORE_InformationRequestContext *irc; | ||
289 | |||
290 | /** | ||
291 | * Request for which 'irc' is currently active (or NULL). | ||
292 | */ | ||
293 | struct PendingRequest *pr; | ||
294 | |||
295 | /** | ||
286 | * Time when the last transmission request was issued. | 296 | * Time when the last transmission request was issued. |
287 | */ | 297 | */ |
288 | struct GNUNET_TIME_Absolute last_transmission_request_start; | 298 | struct GNUNET_TIME_Absolute last_transmission_request_start; |
@@ -554,14 +564,14 @@ struct PendingRequest | |||
554 | struct GNUNET_CONTAINER_BloomFilter *bf; | 564 | struct GNUNET_CONTAINER_BloomFilter *bf; |
555 | 565 | ||
556 | /** | 566 | /** |
557 | * Context of our GNUNET_CORE_peer_change_preference call. | 567 | * Reference to DHT get operation for this request (or NULL). |
558 | */ | 568 | */ |
559 | struct GNUNET_CORE_InformationRequestContext *irc; | 569 | struct GNUNET_DHT_GetHandle *dht_get; |
560 | 570 | ||
561 | /** | 571 | /** |
562 | * Reference to DHT get operation for this request (or NULL). | 572 | * Context of our GNUNET_CORE_peer_change_preference call. |
563 | */ | 573 | */ |
564 | struct GNUNET_DHT_GetHandle *dht_get; | 574 | struct ConnectedPeer *pirc; |
565 | 575 | ||
566 | /** | 576 | /** |
567 | * Hash code of all replies that we have seen so far (only valid | 577 | * Hash code of all replies that we have seen so far (only valid |
@@ -1524,10 +1534,11 @@ destroy_pending_request (struct PendingRequest *pr) | |||
1524 | GNUNET_CONTAINER_bloomfilter_free (pr->bf); | 1534 | GNUNET_CONTAINER_bloomfilter_free (pr->bf); |
1525 | pr->bf = NULL; | 1535 | pr->bf = NULL; |
1526 | } | 1536 | } |
1527 | if (pr->irc != NULL) | 1537 | if (pr->pirc != NULL) |
1528 | { | 1538 | { |
1529 | GNUNET_CORE_peer_change_preference_cancel (pr->irc); | 1539 | GNUNET_CORE_peer_change_preference_cancel (pr->pirc->irc); |
1530 | pr->irc = NULL; | 1540 | pr->pirc->irc = NULL; |
1541 | pr->pirc = NULL; | ||
1531 | } | 1542 | } |
1532 | if (pr->replies_seen != NULL) | 1543 | if (pr->replies_seen != NULL) |
1533 | { | 1544 | { |
@@ -1816,6 +1827,14 @@ peer_disconnect_handler (void *cls, | |||
1816 | GNUNET_CONTAINER_multihashmap_remove (connected_peers, | 1827 | GNUNET_CONTAINER_multihashmap_remove (connected_peers, |
1817 | &peer->hashPubKey, | 1828 | &peer->hashPubKey, |
1818 | cp)); | 1829 | cp)); |
1830 | if (cp->irc != NULL) | ||
1831 | { | ||
1832 | GNUNET_CORE_peer_change_preference_cancel (cp->irc); | ||
1833 | cp->irc = NULL; | ||
1834 | cp->pr->pirc = NULL; | ||
1835 | cp->pr = NULL; | ||
1836 | } | ||
1837 | |||
1819 | /* remove this peer from migration considerations; schedule | 1838 | /* remove this peer from migration considerations; schedule |
1820 | alternatives */ | 1839 | alternatives */ |
1821 | next = mig_head; | 1840 | next = mig_head; |
@@ -2124,8 +2143,28 @@ transmit_to_peer (void *cls, | |||
2124 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2143 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2125 | "Dropping message, core too busy.\n"); | 2144 | "Dropping message, core too busy.\n"); |
2126 | #endif | 2145 | #endif |
2146 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2147 | "Dropping message, core too busy.\n"); | ||
2127 | GNUNET_LOAD_update (cp->transmission_delay, | 2148 | GNUNET_LOAD_update (cp->transmission_delay, |
2128 | UINT64_MAX); | 2149 | UINT64_MAX); |
2150 | |||
2151 | if (NULL != (pm = cp->pending_messages_head)) | ||
2152 | { | ||
2153 | GNUNET_CONTAINER_DLL_remove (cp->pending_messages_head, | ||
2154 | cp->pending_messages_tail, | ||
2155 | pm); | ||
2156 | cp->pending_requests--; | ||
2157 | destroy_pending_message (pm, 0); | ||
2158 | } | ||
2159 | if (NULL != (pm = cp->pending_messages_head)) | ||
2160 | { | ||
2161 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == cp->delayed_transmission_request_task); | ||
2162 | min_delay = GNUNET_TIME_absolute_get_remaining (pm->delay_until); | ||
2163 | cp->delayed_transmission_request_task | ||
2164 | = GNUNET_SCHEDULER_add_delayed (min_delay, | ||
2165 | &delayed_transmission_request, | ||
2166 | cp); | ||
2167 | } | ||
2129 | return 0; | 2168 | return 0; |
2130 | } | 2169 | } |
2131 | GNUNET_LOAD_update (cp->transmission_delay, | 2170 | GNUNET_LOAD_update (cp->transmission_delay, |
@@ -2567,16 +2606,6 @@ target_reservation_cb (void *cls, | |||
2567 | uint32_t bm; | 2606 | uint32_t bm; |
2568 | unsigned int i; | 2607 | unsigned int i; |
2569 | 2608 | ||
2570 | pr->irc = NULL; | ||
2571 | if (peer == NULL) | ||
2572 | { | ||
2573 | /* error in communication with core, try again later */ | ||
2574 | if (pr->task == GNUNET_SCHEDULER_NO_TASK) | ||
2575 | pr->task = GNUNET_SCHEDULER_add_delayed (get_processing_delay (), | ||
2576 | &forward_request_task, | ||
2577 | pr); | ||
2578 | return; | ||
2579 | } | ||
2580 | /* (3) transmit, update ttl/priority */ | 2609 | /* (3) transmit, update ttl/priority */ |
2581 | cp = GNUNET_CONTAINER_multihashmap_get (connected_peers, | 2610 | cp = GNUNET_CONTAINER_multihashmap_get (connected_peers, |
2582 | &peer->hashPubKey); | 2611 | &peer->hashPubKey); |
@@ -2593,6 +2622,17 @@ target_reservation_cb (void *cls, | |||
2593 | pr); | 2622 | pr); |
2594 | return; | 2623 | return; |
2595 | } | 2624 | } |
2625 | cp->irc = NULL; | ||
2626 | pr->pirc = NULL; | ||
2627 | if (peer == NULL) | ||
2628 | { | ||
2629 | /* error in communication with core, try again later */ | ||
2630 | if (pr->task == GNUNET_SCHEDULER_NO_TASK) | ||
2631 | pr->task = GNUNET_SCHEDULER_add_delayed (get_processing_delay (), | ||
2632 | &forward_request_task, | ||
2633 | pr); | ||
2634 | return; | ||
2635 | } | ||
2596 | no_route = GNUNET_NO; | 2636 | no_route = GNUNET_NO; |
2597 | if (amount == 0) | 2637 | if (amount == 0) |
2598 | { | 2638 | { |
@@ -2710,6 +2750,11 @@ struct PeerSelectionContext | |||
2710 | */ | 2750 | */ |
2711 | double target_score; | 2751 | double target_score; |
2712 | 2752 | ||
2753 | /** | ||
2754 | * Does it make sense to we re-try quickly again? | ||
2755 | */ | ||
2756 | int fast_retry; | ||
2757 | |||
2713 | }; | 2758 | }; |
2714 | 2759 | ||
2715 | 2760 | ||
@@ -2738,7 +2783,7 @@ target_peer_select_cb (void *cls, | |||
2738 | unsigned int pc; | 2783 | unsigned int pc; |
2739 | 2784 | ||
2740 | /* 1) check that this peer is not the initiator */ | 2785 | /* 1) check that this peer is not the initiator */ |
2741 | if (cp == pr->cp) | 2786 | if (cp == pr->cp) |
2742 | { | 2787 | { |
2743 | #if DEBUG_FS | 2788 | #if DEBUG_FS |
2744 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2789 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -2746,6 +2791,11 @@ target_peer_select_cb (void *cls, | |||
2746 | #endif | 2791 | #endif |
2747 | return GNUNET_YES; /* skip */ | 2792 | return GNUNET_YES; /* skip */ |
2748 | } | 2793 | } |
2794 | if (cp->irc != NULL) | ||
2795 | { | ||
2796 | psc->fast_retry = GNUNET_YES; | ||
2797 | return GNUNET_YES; /* skip: already querying core about this peer for other reasons */ | ||
2798 | } | ||
2749 | 2799 | ||
2750 | /* 2) check if we have already (recently) forwarded to this peer */ | 2800 | /* 2) check if we have already (recently) forwarded to this peer */ |
2751 | /* 2a) this particular request */ | 2801 | /* 2a) this particular request */ |
@@ -2755,6 +2805,8 @@ target_peer_select_cb (void *cls, | |||
2755 | { | 2805 | { |
2756 | pc = pr->used_targets[i].num_requests; | 2806 | pc = pr->used_targets[i].num_requests; |
2757 | GNUNET_assert (pc > 0); | 2807 | GNUNET_assert (pc > 0); |
2808 | /* FIXME: make re-enabling a peer independent of how often | ||
2809 | this function is called??? */ | ||
2758 | if (0 != GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, | 2810 | if (0 != GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, |
2759 | RETRY_PROBABILITY_INV * pc)) | 2811 | RETRY_PROBABILITY_INV * pc)) |
2760 | { | 2812 | { |
@@ -2824,19 +2876,19 @@ target_peer_select_cb (void *cls, | |||
2824 | if (pr->target_pid == cp->pid) | 2876 | if (pr->target_pid == cp->pid) |
2825 | score += 100.0; | 2877 | score += 100.0; |
2826 | /* store best-fit in closure */ | 2878 | /* store best-fit in closure */ |
2827 | #if DEBUG_FS | ||
2828 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2829 | "Peer `%s' gets score %f for forwarding query, max is %f\n", | ||
2830 | GNUNET_h2s (key), | ||
2831 | score, | ||
2832 | psc->target_score); | ||
2833 | #endif | ||
2834 | score++; /* avoid zero */ | 2879 | score++; /* avoid zero */ |
2835 | if (score > psc->target_score) | 2880 | if (score > psc->target_score) |
2836 | { | 2881 | { |
2837 | psc->target_score = score; | 2882 | psc->target_score = score; |
2838 | psc->target.hashPubKey = *key; | 2883 | psc->target.hashPubKey = *key; |
2839 | } | 2884 | } |
2885 | #if DEBUG_FS | ||
2886 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2887 | "Peer `%s' gets score %f for forwarding query, max is %8f\n", | ||
2888 | GNUNET_h2s (key), | ||
2889 | score, | ||
2890 | psc->target_score); | ||
2891 | #endif | ||
2840 | return GNUNET_YES; | 2892 | return GNUNET_YES; |
2841 | } | 2893 | } |
2842 | 2894 | ||
@@ -2916,7 +2968,7 @@ forward_request_task (void *cls, | |||
2916 | struct GNUNET_TIME_Relative delay; | 2968 | struct GNUNET_TIME_Relative delay; |
2917 | 2969 | ||
2918 | pr->task = GNUNET_SCHEDULER_NO_TASK; | 2970 | pr->task = GNUNET_SCHEDULER_NO_TASK; |
2919 | if (pr->irc != NULL) | 2971 | if (pr->pirc != NULL) |
2920 | { | 2972 | { |
2921 | #if DEBUG_FS | 2973 | #if DEBUG_FS |
2922 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2974 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -2949,12 +3001,16 @@ forward_request_task (void *cls, | |||
2949 | /* (1) select target */ | 3001 | /* (1) select target */ |
2950 | psc.pr = pr; | 3002 | psc.pr = pr; |
2951 | psc.target_score = -DBL_MAX; | 3003 | psc.target_score = -DBL_MAX; |
3004 | psc.fast_retry = GNUNET_NO; | ||
2952 | GNUNET_CONTAINER_multihashmap_iterate (connected_peers, | 3005 | GNUNET_CONTAINER_multihashmap_iterate (connected_peers, |
2953 | &target_peer_select_cb, | 3006 | &target_peer_select_cb, |
2954 | &psc); | 3007 | &psc); |
2955 | if (psc.target_score == -DBL_MAX) | 3008 | if (psc.target_score == -DBL_MAX) |
2956 | { | 3009 | { |
2957 | delay = get_processing_delay (); | 3010 | if (psc.fast_retry == GNUNET_YES) |
3011 | delay = GNUNET_TIME_UNIT_MILLISECONDS; /* FIXME: store adaptive fast-retry value in 'pr' */ | ||
3012 | else | ||
3013 | delay = get_processing_delay (); | ||
2958 | #if DEBUG_FS | 3014 | #if DEBUG_FS |
2959 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3015 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2960 | "No peer selected for forwarding of query `%s', will try again in %llu ms!\n", | 3016 | "No peer selected for forwarding of query `%s', will try again in %llu ms!\n", |
@@ -2996,7 +3052,10 @@ forward_request_task (void *cls, | |||
2996 | cp = GNUNET_CONTAINER_multihashmap_get (connected_peers, | 3052 | cp = GNUNET_CONTAINER_multihashmap_get (connected_peers, |
2997 | &psc.target.hashPubKey); | 3053 | &psc.target.hashPubKey); |
2998 | GNUNET_assert (NULL != cp); | 3054 | GNUNET_assert (NULL != cp); |
2999 | pr->irc = GNUNET_CORE_peer_change_preference (core, | 3055 | GNUNET_assert (cp->irc == NULL); |
3056 | pr->pirc = cp; | ||
3057 | cp->pr = pr; | ||
3058 | cp->irc = GNUNET_CORE_peer_change_preference (core, | ||
3000 | &psc.target, | 3059 | &psc.target, |
3001 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, | 3060 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, |
3002 | GNUNET_BANDWIDTH_value_init (UINT32_MAX), | 3061 | GNUNET_BANDWIDTH_value_init (UINT32_MAX), |
@@ -3004,6 +3063,7 @@ forward_request_task (void *cls, | |||
3004 | cp->inc_preference, | 3063 | cp->inc_preference, |
3005 | &target_reservation_cb, | 3064 | &target_reservation_cb, |
3006 | pr); | 3065 | pr); |
3066 | GNUNET_assert (cp->irc != NULL); | ||
3007 | cp->inc_preference = 0; | 3067 | cp->inc_preference = 0; |
3008 | } | 3068 | } |
3009 | else | 3069 | else |