diff options
author | ng0 <ng0@n0.is> | 2019-02-26 08:36:07 +0000 |
---|---|---|
committer | ng0 <ng0@n0.is> | 2019-02-26 08:36:07 +0000 |
commit | faf2ff1ed44cedbfa163c90e7860ec3ce9b6031f (patch) | |
tree | d180b055b9c205c934c5ec7944ffdf43bb761ef8 /src | |
parent | 5f80de3fbc0c4b43fb93d0ef4460aea16b2c78e0 (diff) | |
parent | c55c08bd1e45ea3ce5f4a659344e0bbb0ad8c294 (diff) | |
download | gnunet-faf2ff1ed44cedbfa163c90e7860ec3ce9b6031f.tar.gz gnunet-faf2ff1ed44cedbfa163c90e7860ec3ce9b6031f.zip |
Merge branch 'master' of gnunet.org:gnunet
Diffstat (limited to 'src')
-rw-r--r-- | src/cadet/cadet_api.c | 4 | ||||
-rw-r--r-- | src/rps/Makefile.am | 1 | ||||
-rw-r--r-- | src/rps/gnunet-rps-profiler.c | 32 | ||||
-rw-r--r-- | src/rps/gnunet-service-rps.c | 168 | ||||
-rw-r--r-- | src/rps/gnunet-service-rps_sampler.h | 6 | ||||
-rw-r--r-- | src/rps/rps-sampler_common.c | 6 | ||||
-rw-r--r-- | src/rps/rps-test_util.c | 56 | ||||
-rw-r--r-- | src/rps/rps-test_util.h | 5 | ||||
-rw-r--r-- | src/set/gnunet-service-set.c | 5 | ||||
-rw-r--r-- | src/transport/gnunet-service-transport.c | 12 | ||||
-rw-r--r-- | src/transport/gnunet-service-transport_neighbours.c | 9 | ||||
-rw-r--r-- | src/transport/transport_api_core.c | 10 | ||||
-rw-r--r-- | src/util/disk.c | 18 |
13 files changed, 177 insertions, 155 deletions
diff --git a/src/cadet/cadet_api.c b/src/cadet/cadet_api.c index ce2356216..b0016d2a8 100644 --- a/src/cadet/cadet_api.c +++ b/src/cadet/cadet_api.c | |||
@@ -507,7 +507,9 @@ cadet_mq_error_handler (void *cls, | |||
507 | } | 507 | } |
508 | else | 508 | else |
509 | { | 509 | { |
510 | GNUNET_break (0); | 510 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
511 | "MQ error in communication with CADET: %d\n", | ||
512 | error); | ||
511 | if (NULL != ch->disconnects) | 513 | if (NULL != ch->disconnects) |
512 | ch->disconnects (ch->ctx, | 514 | ch->disconnects (ch->ctx, |
513 | ch); | 515 | ch); |
diff --git a/src/rps/Makefile.am b/src/rps/Makefile.am index a356d3dbc..b391eb8ae 100644 --- a/src/rps/Makefile.am +++ b/src/rps/Makefile.am | |||
@@ -60,7 +60,6 @@ gnunet_service_rps_SOURCES = \ | |||
60 | gnunet-service-rps_sampler.h gnunet-service-rps_sampler.c \ | 60 | gnunet-service-rps_sampler.h gnunet-service-rps_sampler.c \ |
61 | gnunet-service-rps_custommap.h gnunet-service-rps_custommap.c \ | 61 | gnunet-service-rps_custommap.h gnunet-service-rps_custommap.c \ |
62 | gnunet-service-rps_view.h gnunet-service-rps_view.c \ | 62 | gnunet-service-rps_view.h gnunet-service-rps_view.c \ |
63 | rps-test_util.h rps-test_util.c \ | ||
64 | gnunet-service-rps.c | 63 | gnunet-service-rps.c |
65 | 64 | ||
66 | 65 | ||
diff --git a/src/rps/gnunet-rps-profiler.c b/src/rps/gnunet-rps-profiler.c index 98fc8dccb..cdf555432 100644 --- a/src/rps/gnunet-rps-profiler.c +++ b/src/rps/gnunet-rps-profiler.c | |||
@@ -11,7 +11,7 @@ | |||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Affero General Public License for more details. | 13 | Affero General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU Affero General Public License | 15 | You should have received a copy of the GNU Affero General Public License |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | 17 | ||
@@ -2685,6 +2685,7 @@ post_profiler (struct RPSPeer *rps_peer) | |||
2685 | post_test_shutdown_ready_cb, | 2685 | post_test_shutdown_ready_cb, |
2686 | stat_iterator, | 2686 | stat_iterator, |
2687 | (struct STATcls *) stat_cls); | 2687 | (struct STATcls *) stat_cls); |
2688 | GNUNET_assert (NULL != rps_peer->h_stat_get); | ||
2688 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2689 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2689 | "Requested statistics for %s (peer %" PRIu32 ")\n", | 2690 | "Requested statistics for %s (peer %" PRIu32 ")\n", |
2690 | stat_type_strings [stat_type], | 2691 | stat_type_strings [stat_type], |
@@ -2830,7 +2831,8 @@ run (void *cls, | |||
2830 | 2831 | ||
2831 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "This is the profiler\n"); | 2832 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "This is the profiler\n"); |
2832 | cur_test_run.name = "test-rps-profiler"; | 2833 | cur_test_run.name = "test-rps-profiler"; |
2833 | if (0 == num_peers) num_peers = 10; | 2834 | if (0 == num_peers) |
2835 | num_peers = 10; | ||
2834 | mal_type = 3; | 2836 | mal_type = 3; |
2835 | cur_test_run.init_peer = profiler_init_peer; | 2837 | cur_test_run.init_peer = profiler_init_peer; |
2836 | //cur_test_run.pre_test = mal_pre; | 2838 | //cur_test_run.pre_test = mal_pre; |
@@ -2956,25 +2958,21 @@ main (int argc, char *argv[]) | |||
2956 | "COUNT", | 2958 | "COUNT", |
2957 | gettext_noop ("number of peers to start"), | 2959 | gettext_noop ("number of peers to start"), |
2958 | &num_peers), | 2960 | &num_peers), |
2959 | |||
2960 | GNUNET_GETOPT_option_relative_time ('d', | 2961 | GNUNET_GETOPT_option_relative_time ('d', |
2961 | "duration", | 2962 | "duration", |
2962 | "DURATION", | 2963 | "DURATION", |
2963 | gettext_noop ("duration of the profiling"), | 2964 | gettext_noop ("duration of the profiling"), |
2964 | &duration), | 2965 | &duration), |
2965 | |||
2966 | GNUNET_GETOPT_option_relative_time ('t', | 2966 | GNUNET_GETOPT_option_relative_time ('t', |
2967 | "timeout", | 2967 | "timeout", |
2968 | "TIMEOUT", | 2968 | "TIMEOUT", |
2969 | gettext_noop ("timeout for the profiling"), | 2969 | gettext_noop ("timeout for the profiling"), |
2970 | &timeout), | 2970 | &timeout), |
2971 | |||
2972 | GNUNET_GETOPT_option_uint ('r', | 2971 | GNUNET_GETOPT_option_uint ('r', |
2973 | "num-requests", | 2972 | "num-requests", |
2974 | "COUNT", | 2973 | "COUNT", |
2975 | gettext_noop ("number of PeerIDs to request"), | 2974 | gettext_noop ("number of PeerIDs to request"), |
2976 | &cur_test_run.num_requests), | 2975 | &cur_test_run.num_requests), |
2977 | |||
2978 | GNUNET_GETOPT_OPTION_END | 2976 | GNUNET_GETOPT_OPTION_END |
2979 | }; | 2977 | }; |
2980 | 2978 | ||
@@ -2994,22 +2992,24 @@ main (int argc, char *argv[]) | |||
2994 | { | 2992 | { |
2995 | ret_value = 1; | 2993 | ret_value = 1; |
2996 | } | 2994 | } |
2997 | if (GNUNET_OK != ret_value) | 2995 | if (0 != ret_value) |
2998 | { | 2996 | { |
2999 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 2997 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
3000 | "Test did not run successfully!\n"); | 2998 | "Test did not run successfully!\n"); |
3001 | } | 2999 | } |
3002 | 3000 | else | |
3003 | ret_value = cur_test_run.eval_cb(); | ||
3004 | if (NO_COLLECT_VIEW == cur_test_run.have_collect_view) | ||
3005 | { | 3001 | { |
3006 | GNUNET_array_grow (rps_peers->cur_view, | 3002 | ret_value = cur_test_run.eval_cb(); |
3007 | rps_peers->cur_view_count, | 3003 | if (NO_COLLECT_VIEW == cur_test_run.have_collect_view) |
3008 | 0); | 3004 | { |
3005 | GNUNET_array_grow (rps_peers->cur_view, | ||
3006 | rps_peers->cur_view_count, | ||
3007 | 0); | ||
3008 | } | ||
3009 | GNUNET_free (rps_peers); | ||
3010 | GNUNET_free (rps_peer_ids); | ||
3011 | GNUNET_CONTAINER_multipeermap_destroy (peer_map); | ||
3009 | } | 3012 | } |
3010 | GNUNET_free (rps_peers); | ||
3011 | GNUNET_free (rps_peer_ids); | ||
3012 | GNUNET_CONTAINER_multipeermap_destroy (peer_map); | ||
3013 | return ret_value; | 3013 | return ret_value; |
3014 | } | 3014 | } |
3015 | 3015 | ||
diff --git a/src/rps/gnunet-service-rps.c b/src/rps/gnunet-service-rps.c index 05d5c91c3..098c71f93 100644 --- a/src/rps/gnunet-service-rps.c +++ b/src/rps/gnunet-service-rps.c | |||
@@ -283,6 +283,20 @@ struct AttackedPeer | |||
283 | #endif /* ENABLE_MALICIOUS */ | 283 | #endif /* ENABLE_MALICIOUS */ |
284 | 284 | ||
285 | /** | 285 | /** |
286 | * @brief This number determines the number of slots for files that represent | ||
287 | * histograms | ||
288 | */ | ||
289 | #define HISTOGRAM_FILE_SLOTS 32 | ||
290 | |||
291 | /** | ||
292 | * @brief The size (in bytes) a file needs to store the histogram | ||
293 | * | ||
294 | * Per slot: 1 newline, up to 4 chars, | ||
295 | * Additionally: 1 null termination | ||
296 | */ | ||
297 | #define SIZE_DUMP_FILE (HISTOGRAM_FILE_SLOTS * 5) + 1 | ||
298 | |||
299 | /** | ||
286 | * @brief One Sub. | 300 | * @brief One Sub. |
287 | * | 301 | * |
288 | * Essentially one instance of brahms that only connects to other instances | 302 | * Essentially one instance of brahms that only connects to other instances |
@@ -357,16 +371,6 @@ struct Sub | |||
357 | uint32_t num_observed_peers; | 371 | uint32_t num_observed_peers; |
358 | 372 | ||
359 | /** | 373 | /** |
360 | * @brief File name to log number of pushes per round to | ||
361 | */ | ||
362 | char *file_name_push_recv; | ||
363 | |||
364 | /** | ||
365 | * @brief File name to log number of pushes per round to | ||
366 | */ | ||
367 | char *file_name_pull_delays; | ||
368 | |||
369 | /** | ||
370 | * @brief Multipeermap (ab-) used to count unique peer_ids | 374 | * @brief Multipeermap (ab-) used to count unique peer_ids |
371 | */ | 375 | */ |
372 | struct GNUNET_CONTAINER_MultiPeerMap *observed_unique_peers; | 376 | struct GNUNET_CONTAINER_MultiPeerMap *observed_unique_peers; |
@@ -418,7 +422,16 @@ struct Sub | |||
418 | * | 422 | * |
419 | * Number at index i represents the number of rounds with i observed pushes. | 423 | * Number at index i represents the number of rounds with i observed pushes. |
420 | */ | 424 | */ |
421 | uint32_t push_recv[256]; | 425 | uint32_t push_recv[HISTOGRAM_FILE_SLOTS]; |
426 | |||
427 | /** | ||
428 | * @brief Histogram of deltas between the expected and actual number of | ||
429 | * received pushes. | ||
430 | * | ||
431 | * As half of the entries are expected to be negative, this is shifted by | ||
432 | * #HISTOGRAM_FILE_SLOTS/2. | ||
433 | */ | ||
434 | uint32_t push_delta[HISTOGRAM_FILE_SLOTS]; | ||
422 | 435 | ||
423 | /** | 436 | /** |
424 | * @brief Number of pull replies with this delay measured in rounds. | 437 | * @brief Number of pull replies with this delay measured in rounds. |
@@ -426,7 +439,7 @@ struct Sub | |||
426 | * Number at index i represents the number of pull replies with a delay of i | 439 | * Number at index i represents the number of pull replies with a delay of i |
427 | * rounds. | 440 | * rounds. |
428 | */ | 441 | */ |
429 | uint32_t pull_delays[256]; | 442 | uint32_t pull_delays[HISTOGRAM_FILE_SLOTS]; |
430 | }; | 443 | }; |
431 | 444 | ||
432 | 445 | ||
@@ -2376,6 +2389,12 @@ hist_update (const struct GNUNET_PeerIdentity *ids, | |||
2376 | for (i = 0; i < num_peers; i++) | 2389 | for (i = 0; i < num_peers; i++) |
2377 | { | 2390 | { |
2378 | int inserted; | 2391 | int inserted; |
2392 | if (GNUNET_YES != check_peer_known (sub->peer_map, &ids[i])) | ||
2393 | { | ||
2394 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
2395 | "Peer in history update not known!\n"); | ||
2396 | continue; | ||
2397 | } | ||
2379 | inserted = insert_in_view (sub, &ids[i]); | 2398 | inserted = insert_in_view (sub, &ids[i]); |
2380 | if (GNUNET_OK == inserted) | 2399 | if (GNUNET_OK == inserted) |
2381 | { | 2400 | { |
@@ -2890,10 +2909,6 @@ new_sub (const struct GNUNET_HashCode *hash, | |||
2890 | #ifdef TO_FILE | 2909 | #ifdef TO_FILE |
2891 | sub->file_name_observed_log = store_prefix_file_name (&own_identity, | 2910 | sub->file_name_observed_log = store_prefix_file_name (&own_identity, |
2892 | "observed"); | 2911 | "observed"); |
2893 | sub->file_name_push_recv = store_prefix_file_name (&own_identity, | ||
2894 | "push_recv"); | ||
2895 | sub->file_name_pull_delays = store_prefix_file_name (&own_identity, | ||
2896 | "pull_delays"); | ||
2897 | sub->num_observed_peers = 0; | 2912 | sub->num_observed_peers = 0; |
2898 | sub->observed_unique_peers = GNUNET_CONTAINER_multipeermap_create (1, | 2913 | sub->observed_unique_peers = GNUNET_CONTAINER_multipeermap_create (1, |
2899 | GNUNET_NO); | 2914 | GNUNET_NO); |
@@ -2919,6 +2934,50 @@ new_sub (const struct GNUNET_HashCode *hash, | |||
2919 | } | 2934 | } |
2920 | 2935 | ||
2921 | 2936 | ||
2937 | #ifdef TO_FILE | ||
2938 | /** | ||
2939 | * @brief Write all numbers in the given array into the given file | ||
2940 | * | ||
2941 | * Single numbers devided by a newline | ||
2942 | * | ||
2943 | * @param hist_array[] the array to dump | ||
2944 | * @param file_name file to dump into | ||
2945 | */ | ||
2946 | static void | ||
2947 | write_histogram_to_file (const uint32_t hist_array[], | ||
2948 | const char *file_name) | ||
2949 | { | ||
2950 | char collect_str[SIZE_DUMP_FILE + 1] = ""; | ||
2951 | char *recv_str_iter; | ||
2952 | char *file_name_full; | ||
2953 | |||
2954 | recv_str_iter = collect_str; | ||
2955 | file_name_full = store_prefix_file_name (&own_identity, | ||
2956 | file_name); | ||
2957 | for (uint32_t i = 0; i < HISTOGRAM_FILE_SLOTS; i++) | ||
2958 | { | ||
2959 | char collect_str_tmp[8]; | ||
2960 | |||
2961 | GNUNET_snprintf (collect_str_tmp, | ||
2962 | sizeof (collect_str_tmp), | ||
2963 | "%" PRIu32 "\n", | ||
2964 | hist_array[i]); | ||
2965 | recv_str_iter = stpncpy (recv_str_iter, | ||
2966 | collect_str_tmp, | ||
2967 | 6); | ||
2968 | } | ||
2969 | (void) stpcpy (recv_str_iter, | ||
2970 | "\n"); | ||
2971 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2972 | "Writing push stats to disk\n"); | ||
2973 | to_file_w_len (file_name_full, | ||
2974 | SIZE_DUMP_FILE, | ||
2975 | collect_str); | ||
2976 | GNUNET_free (file_name_full); | ||
2977 | } | ||
2978 | #endif /* TO_FILE */ | ||
2979 | |||
2980 | |||
2922 | /** | 2981 | /** |
2923 | * @brief Destroy Sub. | 2982 | * @brief Destroy Sub. |
2924 | * | 2983 | * |
@@ -2927,12 +2986,6 @@ new_sub (const struct GNUNET_HashCode *hash, | |||
2927 | static void | 2986 | static void |
2928 | destroy_sub (struct Sub *sub) | 2987 | destroy_sub (struct Sub *sub) |
2929 | { | 2988 | { |
2930 | #ifdef TO_FILE | ||
2931 | #define SIZE_DUMP_FILE 1536 /* 256 * 6 (1 whitespace, 1 comma, up to 4 chars) */ | ||
2932 | char push_recv_str[SIZE_DUMP_FILE + 1] = ""; | ||
2933 | char pull_delays_str[SIZE_DUMP_FILE + 1] = ""; | ||
2934 | char *recv_str_iter; | ||
2935 | #endif /* TO_FILE */ | ||
2936 | GNUNET_assert (NULL != sub); | 2989 | GNUNET_assert (NULL != sub); |
2937 | GNUNET_assert (NULL != sub->do_round_task); | 2990 | GNUNET_assert (NULL != sub->do_round_task); |
2938 | GNUNET_SCHEDULER_cancel (sub->do_round_task); | 2991 | GNUNET_SCHEDULER_cancel (sub->do_round_task); |
@@ -2960,51 +3013,16 @@ destroy_sub (struct Sub *sub) | |||
2960 | sub->file_name_observed_log = NULL; | 3013 | sub->file_name_observed_log = NULL; |
2961 | 3014 | ||
2962 | /* Write push frequencies to disk */ | 3015 | /* Write push frequencies to disk */ |
2963 | recv_str_iter = push_recv_str; | 3016 | write_histogram_to_file (sub->push_recv, |
2964 | for (uint32_t i = 0; i < 256; i++) | 3017 | "push_recv"); |
2965 | { | ||
2966 | char push_recv_str_tmp[8]; | ||
2967 | 3018 | ||
2968 | GNUNET_snprintf (push_recv_str_tmp, | 3019 | /* Write push deltas to disk */ |
2969 | sizeof (push_recv_str_tmp), | 3020 | write_histogram_to_file (sub->push_delta, |
2970 | "%" PRIu32 "\n", | 3021 | "push_delta"); |
2971 | sub->push_recv[i]); | ||
2972 | recv_str_iter = stpncpy (recv_str_iter, | ||
2973 | push_recv_str_tmp, | ||
2974 | 6); | ||
2975 | } | ||
2976 | (void) stpcpy (recv_str_iter, | ||
2977 | "\n"); | ||
2978 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2979 | "Writing push stats to disk\n"); | ||
2980 | to_file_w_len (sub->file_name_push_recv, | ||
2981 | SIZE_DUMP_FILE, | ||
2982 | push_recv_str); | ||
2983 | GNUNET_free (sub->file_name_push_recv); | ||
2984 | sub->file_name_push_recv = NULL; | ||
2985 | 3022 | ||
2986 | /* Write pull delays to disk */ | 3023 | /* Write pull delays to disk */ |
2987 | recv_str_iter = pull_delays_str; | 3024 | write_histogram_to_file (sub->pull_delays, |
2988 | for (uint32_t i = 0; i < 256; i++) | 3025 | "pull_delays"); |
2989 | { | ||
2990 | char pull_delays_str_tmp[8]; | ||
2991 | |||
2992 | GNUNET_snprintf (pull_delays_str_tmp, | ||
2993 | sizeof (pull_delays_str_tmp), | ||
2994 | "%" PRIu32 "\n", | ||
2995 | sub->pull_delays[i]); | ||
2996 | recv_str_iter = stpncpy (recv_str_iter, | ||
2997 | pull_delays_str_tmp, | ||
2998 | 6); | ||
2999 | } | ||
3000 | (void) stpcpy (recv_str_iter, | ||
3001 | "\n"); | ||
3002 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Writing pull delays to disk\n"); | ||
3003 | to_file_w_len (sub->file_name_pull_delays, | ||
3004 | SIZE_DUMP_FILE, | ||
3005 | pull_delays_str); | ||
3006 | GNUNET_free (sub->file_name_pull_delays); | ||
3007 | sub->file_name_pull_delays = NULL; | ||
3008 | 3026 | ||
3009 | GNUNET_CONTAINER_multipeermap_destroy (sub->observed_unique_peers); | 3027 | GNUNET_CONTAINER_multipeermap_destroy (sub->observed_unique_peers); |
3010 | sub->observed_unique_peers = NULL; | 3028 | sub->observed_unique_peers = NULL; |
@@ -4338,10 +4356,10 @@ do_round (void *cls) | |||
4338 | if (sub == msub) | 4356 | if (sub == msub) |
4339 | { | 4357 | { |
4340 | GNUNET_STATISTICS_update(stats, "# rounds blocked", 1, GNUNET_NO); | 4358 | GNUNET_STATISTICS_update(stats, "# rounds blocked", 1, GNUNET_NO); |
4341 | if (CustomPeerMap_size (sub->push_map) > alpha * View_size (sub->view) && | 4359 | if (CustomPeerMap_size (sub->push_map) > alpha * sub->view_size_est_need && |
4342 | !(0 >= CustomPeerMap_size (sub->pull_map))) | 4360 | !(0 >= CustomPeerMap_size (sub->pull_map))) |
4343 | GNUNET_STATISTICS_update(stats, "# rounds blocked - too many pushes", 1, GNUNET_NO); | 4361 | GNUNET_STATISTICS_update(stats, "# rounds blocked - too many pushes", 1, GNUNET_NO); |
4344 | if (CustomPeerMap_size (sub->push_map) > alpha * View_size (sub->view) && | 4362 | if (CustomPeerMap_size (sub->push_map) > alpha * sub->view_size_est_need && |
4345 | (0 >= CustomPeerMap_size (sub->pull_map))) | 4363 | (0 >= CustomPeerMap_size (sub->pull_map))) |
4346 | GNUNET_STATISTICS_update(stats, "# rounds blocked - too many pushes, no pull replies", 1, GNUNET_NO); | 4364 | GNUNET_STATISTICS_update(stats, "# rounds blocked - too many pushes, no pull replies", 1, GNUNET_NO); |
4347 | if (0 >= CustomPeerMap_size (sub->push_map) && | 4365 | if (0 >= CustomPeerMap_size (sub->push_map) && |
@@ -4351,13 +4369,27 @@ do_round (void *cls) | |||
4351 | (0 >= CustomPeerMap_size (sub->pull_map))) | 4369 | (0 >= CustomPeerMap_size (sub->pull_map))) |
4352 | GNUNET_STATISTICS_update(stats, "# rounds blocked - no pushes, no pull replies", 1, GNUNET_NO); | 4370 | GNUNET_STATISTICS_update(stats, "# rounds blocked - no pushes, no pull replies", 1, GNUNET_NO); |
4353 | if (0 >= CustomPeerMap_size (sub->pull_map) && | 4371 | if (0 >= CustomPeerMap_size (sub->pull_map) && |
4354 | CustomPeerMap_size (sub->push_map) > alpha * View_size (sub->view) && | 4372 | CustomPeerMap_size (sub->push_map) > alpha * sub->view_size_est_need && |
4355 | 0 >= CustomPeerMap_size (sub->push_map)) | 4373 | 0 >= CustomPeerMap_size (sub->push_map)) |
4356 | GNUNET_STATISTICS_update(stats, "# rounds blocked - no pull replies", 1, GNUNET_NO); | 4374 | GNUNET_STATISTICS_update(stats, "# rounds blocked - no pull replies", 1, GNUNET_NO); |
4357 | } | 4375 | } |
4358 | } | 4376 | } |
4359 | // TODO independent of that also get some peers from CADET_get_peers()? | 4377 | // TODO independent of that also get some peers from CADET_get_peers()? |
4360 | sub->push_recv[CustomPeerMap_size (sub->push_map)]++; | 4378 | if (CustomPeerMap_size (sub->push_map) < HISTOGRAM_FILE_SLOTS) |
4379 | { | ||
4380 | sub->push_recv[CustomPeerMap_size (sub->push_map)]++; | ||
4381 | } | ||
4382 | else | ||
4383 | { | ||
4384 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
4385 | "Push map size too big for histogram (%u, %u)\n", | ||
4386 | CustomPeerMap_size (sub->push_map), | ||
4387 | HISTOGRAM_FILE_SLOTS); | ||
4388 | } | ||
4389 | // FIXME check bounds of histogram | ||
4390 | sub->push_delta[(CustomPeerMap_size (sub->push_map) - | ||
4391 | sub->view_size_est_need) + | ||
4392 | (HISTOGRAM_FILE_SLOTS/2)]++; | ||
4361 | if (sub == msub) | 4393 | if (sub == msub) |
4362 | { | 4394 | { |
4363 | GNUNET_STATISTICS_set (stats, | 4395 | GNUNET_STATISTICS_set (stats, |
diff --git a/src/rps/gnunet-service-rps_sampler.h b/src/rps/gnunet-service-rps_sampler.h index 9f60aa7c9..921570f7d 100644 --- a/src/rps/gnunet-service-rps_sampler.h +++ b/src/rps/gnunet-service-rps_sampler.h | |||
@@ -90,6 +90,12 @@ RPS_sampler_update (struct RPS_Sampler *sampler, | |||
90 | * | 90 | * |
91 | * Used to get rid of a PeerID. | 91 | * Used to get rid of a PeerID. |
92 | * | 92 | * |
93 | * FIXME: This should also consider currently pending requests | ||
94 | * (Pending requests already collect peerids. As long as not all | ||
95 | * requested IDs have been collected, they are kept. | ||
96 | * Ideally, the @p id should be removed from all pending requests. This | ||
97 | * seems quite complicated.) | ||
98 | * | ||
93 | * @param sampler the sampler to reinitialise a sampler in. | 99 | * @param sampler the sampler to reinitialise a sampler in. |
94 | * @param id the id of the samplers to update. | 100 | * @param id the id of the samplers to update. |
95 | */ | 101 | */ |
diff --git a/src/rps/rps-sampler_common.c b/src/rps/rps-sampler_common.c index e34cdd67b..2b0569c61 100644 --- a/src/rps/rps-sampler_common.c +++ b/src/rps/rps-sampler_common.c | |||
@@ -215,6 +215,12 @@ RPS_sampler_update (struct RPS_Sampler *sampler, | |||
215 | * | 215 | * |
216 | * Used to get rid of a PeerID. | 216 | * Used to get rid of a PeerID. |
217 | * | 217 | * |
218 | * FIXME: This should also consider currently pending requests | ||
219 | * (Pending requests already collect peerids. As long as not all | ||
220 | * requested IDs have been collected, they are kept. | ||
221 | * Ideally, the @p id should be removed from all pending requests. This | ||
222 | * seems quite complicated.) | ||
223 | * | ||
218 | * @param sampler the sampler to reinitialise a sampler element in. | 224 | * @param sampler the sampler to reinitialise a sampler element in. |
219 | * @param id the id of the sampler elements to update. | 225 | * @param id the id of the sampler elements to update. |
220 | */ | 226 | */ |
diff --git a/src/rps/rps-test_util.c b/src/rps/rps-test_util.c index 85829f247..077750329 100644 --- a/src/rps/rps-test_util.c +++ b/src/rps/rps-test_util.c | |||
@@ -11,7 +11,7 @@ | |||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Affero General Public License for more details. | 13 | Affero General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU Affero General Public License | 15 | You should have received a copy of the GNU Affero General Public License |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | 17 | ||
@@ -414,44 +414,6 @@ auth_key_to_string (struct GNUNET_CRYPTO_AuthKey auth_key) | |||
414 | return name_buf; | 414 | return name_buf; |
415 | } | 415 | } |
416 | 416 | ||
417 | |||
418 | |||
419 | char * | ||
420 | create_file (const char *name) | ||
421 | { | ||
422 | int size; | ||
423 | size_t name_buf_size; | ||
424 | char *name_buf; | ||
425 | char *prefix; | ||
426 | char *file_name; | ||
427 | |||
428 | prefix = "/tmp/rps/"; | ||
429 | name_buf_size = (strlen (prefix) + strlen (name) + 2) * sizeof (char); | ||
430 | name_buf = GNUNET_malloc (name_buf_size); | ||
431 | |||
432 | size = GNUNET_snprintf (name_buf, name_buf_size, "%s%s", prefix, name); | ||
433 | if (0 > size) | ||
434 | LOG (GNUNET_ERROR_TYPE_WARNING, "Failed to create name_buf\n"); | ||
435 | |||
436 | if (GNUNET_YES != GNUNET_DISK_directory_create (prefix)) | ||
437 | { | ||
438 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
439 | "Could not create directory %s.\n", | ||
440 | prefix); | ||
441 | } | ||
442 | |||
443 | if (NULL == strstr (name, "sampler_el")) | ||
444 | {/* only append random string to sampler */ | ||
445 | if (NULL == (file_name = GNUNET_DISK_mktemp (name_buf))) | ||
446 | LOG (GNUNET_ERROR_TYPE_WARNING, "Could not create file\n"); | ||
447 | |||
448 | GNUNET_free (name_buf); | ||
449 | return file_name; | ||
450 | } | ||
451 | |||
452 | return name_buf; | ||
453 | } | ||
454 | |||
455 | #endif /* TO_FILE */ | 417 | #endif /* TO_FILE */ |
456 | 418 | ||
457 | 419 | ||
@@ -479,23 +441,23 @@ string_to_auth_key (const char *str) | |||
479 | * @return #GNUNET_YES on success | 441 | * @return #GNUNET_YES on success |
480 | * #GNUNET_SYSERR on failure | 442 | * #GNUNET_SYSERR on failure |
481 | */ | 443 | */ |
482 | static int ensure_folder_exist (void) | 444 | static int |
445 | ensure_folder_exist (void) | ||
483 | { | 446 | { |
484 | if (GNUNET_NO == GNUNET_DISK_directory_test ("/tmp/rps/", GNUNET_NO)) | 447 | if (GNUNET_OK != |
485 | { | 448 | GNUNET_DISK_directory_create ("/tmp/rps")) |
486 | GNUNET_DISK_directory_create ("/tmp/rps"); | ||
487 | } | ||
488 | if (GNUNET_YES != GNUNET_DISK_directory_test ("/tmp/rps/", GNUNET_NO)) | ||
489 | { | 449 | { |
490 | LOG (GNUNET_ERROR_TYPE_ERROR, "Could not create directory `/tmp/rps'\n"); | 450 | LOG (GNUNET_ERROR_TYPE_ERROR, |
451 | "Could not create directory `/tmp/rps'\n"); | ||
491 | return GNUNET_SYSERR; | 452 | return GNUNET_SYSERR; |
492 | } | 453 | } |
493 | return GNUNET_YES; | 454 | return GNUNET_YES; |
494 | } | 455 | } |
495 | 456 | ||
457 | |||
496 | char * | 458 | char * |
497 | store_prefix_file_name (const struct GNUNET_PeerIdentity *peer, | 459 | store_prefix_file_name (const struct GNUNET_PeerIdentity *peer, |
498 | const char *prefix) | 460 | const char *prefix) |
499 | { | 461 | { |
500 | int len_file_name; | 462 | int len_file_name; |
501 | int out_size; | 463 | int out_size; |
diff --git a/src/rps/rps-test_util.h b/src/rps/rps-test_util.h index 484d0f7da..ace833034 100644 --- a/src/rps/rps-test_util.h +++ b/src/rps/rps-test_util.h | |||
@@ -37,8 +37,6 @@ auth_key_to_string (struct GNUNET_CRYPTO_AuthKey auth_key); | |||
37 | struct GNUNET_CRYPTO_AuthKey | 37 | struct GNUNET_CRYPTO_AuthKey |
38 | string_to_auth_key (const char *str); | 38 | string_to_auth_key (const char *str); |
39 | 39 | ||
40 | char * | ||
41 | create_file (const char *name); | ||
42 | 40 | ||
43 | /** | 41 | /** |
44 | * @brief Get file handle | 42 | * @brief Get file handle |
@@ -64,9 +62,10 @@ close_all_files (); | |||
64 | * This function is used to facilitate writing important information to disk | 62 | * This function is used to facilitate writing important information to disk |
65 | */ | 63 | */ |
66 | #ifdef TO_FILE | 64 | #ifdef TO_FILE |
67 | #define to_file(file_name, ...) do {GNUNET_assert (NULL != file_name);\ | 65 | #define to_file(file_name, ...) do { \ |
68 | char tmp_buf[512] = "";\ | 66 | char tmp_buf[512] = "";\ |
69 | int size;\ | 67 | int size;\ |
68 | if (NULL == file_name) return; \ | ||
70 | size = GNUNET_snprintf(tmp_buf,sizeof(tmp_buf),__VA_ARGS__);\ | 69 | size = GNUNET_snprintf(tmp_buf,sizeof(tmp_buf),__VA_ARGS__);\ |
71 | if (0 > size)\ | 70 | if (0 > size)\ |
72 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING,\ | 71 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING,\ |
diff --git a/src/set/gnunet-service-set.c b/src/set/gnunet-service-set.c index c71eb6edc..71f74594f 100644 --- a/src/set/gnunet-service-set.c +++ b/src/set/gnunet-service-set.c | |||
@@ -1221,8 +1221,11 @@ _GSS_operation_destroy2 (struct Operation *op) | |||
1221 | GNUNET_CADET_channel_destroy (channel); | 1221 | GNUNET_CADET_channel_destroy (channel); |
1222 | } | 1222 | } |
1223 | if (NULL != op->listener) | 1223 | if (NULL != op->listener) |
1224 | { | ||
1224 | incoming_destroy (op); | 1225 | incoming_destroy (op); |
1225 | else if (NULL != op->set) | 1226 | return; |
1227 | } | ||
1228 | if (NULL != op->set) | ||
1226 | op->set->vt->channel_death (op); | 1229 | op->set->vt->channel_death (op); |
1227 | else | 1230 | else |
1228 | _GSS_operation_destroy (op, | 1231 | _GSS_operation_destroy (op, |
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c index d3d2a86a3..c621ea686 100644 --- a/src/transport/gnunet-service-transport.c +++ b/src/transport/gnunet-service-transport.c | |||
@@ -1341,7 +1341,6 @@ void | |||
1341 | GST_clients_broadcast (const struct GNUNET_MessageHeader *msg, | 1341 | GST_clients_broadcast (const struct GNUNET_MessageHeader *msg, |
1342 | int may_drop) | 1342 | int may_drop) |
1343 | { | 1343 | { |
1344 | struct TransportClient *tc; | ||
1345 | int done; | 1344 | int done; |
1346 | 1345 | ||
1347 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1346 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -1349,7 +1348,9 @@ GST_clients_broadcast (const struct GNUNET_MessageHeader *msg, | |||
1349 | (unsigned int) ntohs (msg->type), | 1348 | (unsigned int) ntohs (msg->type), |
1350 | (unsigned int) ntohs (msg->size)); | 1349 | (unsigned int) ntohs (msg->size)); |
1351 | done = GNUNET_NO; | 1350 | done = GNUNET_NO; |
1352 | for (tc = clients_head; NULL != tc; tc = tc->next) | 1351 | for (struct TransportClient *tc = clients_head; |
1352 | NULL != tc; | ||
1353 | tc = tc->next) | ||
1353 | { | 1354 | { |
1354 | if ( (GNUNET_YES == may_drop) && | 1355 | if ( (GNUNET_YES == may_drop) && |
1355 | (CT_CORE != tc->type) ) | 1356 | (CT_CORE != tc->type) ) |
@@ -1382,13 +1383,14 @@ GST_clients_broadcast_peer_notification (const struct GNUNET_PeerIdentity *peer, | |||
1382 | { | 1383 | { |
1383 | struct GNUNET_MQ_Envelope *env; | 1384 | struct GNUNET_MQ_Envelope *env; |
1384 | struct PeerIterateResponseMessage *msg; | 1385 | struct PeerIterateResponseMessage *msg; |
1385 | struct TransportClient *tc; | 1386 | |
1386 | |||
1387 | msg = compose_address_iterate_response_message (peer, | 1387 | msg = compose_address_iterate_response_message (peer, |
1388 | address); | 1388 | address); |
1389 | msg->state = htonl (state); | 1389 | msg->state = htonl (state); |
1390 | msg->state_timeout = GNUNET_TIME_absolute_hton (state_timeout); | 1390 | msg->state_timeout = GNUNET_TIME_absolute_hton (state_timeout); |
1391 | for (tc = clients_head; NULL != tc; tc = tc->next) | 1391 | for (struct TransportClient *tc = clients_head; |
1392 | NULL != tc; | ||
1393 | tc = tc->next) | ||
1392 | { | 1394 | { |
1393 | if (CT_MONITOR != tc->type) | 1395 | if (CT_MONITOR != tc->type) |
1394 | continue; | 1396 | continue; |
diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c index 72c425591..3472e8ee0 100644 --- a/src/transport/gnunet-service-transport_neighbours.c +++ b/src/transport/gnunet-service-transport_neighbours.c | |||
@@ -713,7 +713,7 @@ set_state_and_timeout (struct NeighbourMapEntry *n, | |||
713 | struct GNUNET_TIME_Absolute timeout) | 713 | struct GNUNET_TIME_Absolute timeout) |
714 | { | 714 | { |
715 | if (GNUNET_TRANSPORT_is_connected (s) && | 715 | if (GNUNET_TRANSPORT_is_connected (s) && |
716 | ! GNUNET_TRANSPORT_is_connected (n->state) ) | 716 | (! GNUNET_TRANSPORT_is_connected (n->state)) ) |
717 | { | 717 | { |
718 | neighbours_connect_notification (n); | 718 | neighbours_connect_notification (n); |
719 | GNUNET_STATISTICS_set (GST_stats, | 719 | GNUNET_STATISTICS_set (GST_stats, |
@@ -721,8 +721,8 @@ set_state_and_timeout (struct NeighbourMapEntry *n, | |||
721 | ++neighbours_connected, | 721 | ++neighbours_connected, |
722 | GNUNET_NO); | 722 | GNUNET_NO); |
723 | } | 723 | } |
724 | if (! GNUNET_TRANSPORT_is_connected (s) && | 724 | if ((! GNUNET_TRANSPORT_is_connected (s)) && |
725 | GNUNET_TRANSPORT_is_connected (n->state) ) | 725 | GNUNET_TRANSPORT_is_connected (n->state) ) |
726 | { | 726 | { |
727 | GNUNET_STATISTICS_set (GST_stats, | 727 | GNUNET_STATISTICS_set (GST_stats, |
728 | gettext_noop ("# peers connected"), | 728 | gettext_noop ("# peers connected"), |
@@ -948,7 +948,8 @@ free_neighbour (struct NeighbourMapEntry *n) | |||
948 | } | 948 | } |
949 | GNUNET_assert (GNUNET_YES == | 949 | GNUNET_assert (GNUNET_YES == |
950 | GNUNET_CONTAINER_multipeermap_remove (neighbours, | 950 | GNUNET_CONTAINER_multipeermap_remove (neighbours, |
951 | &n->id, n)); | 951 | &n->id, |
952 | n)); | ||
952 | 953 | ||
953 | /* Cancel address requests for this peer */ | 954 | /* Cancel address requests for this peer */ |
954 | if (NULL != n->suggest_handle) | 955 | if (NULL != n->suggest_handle) |
diff --git a/src/transport/transport_api_core.c b/src/transport/transport_api_core.c index 75287b5e7..aa6da0098 100644 --- a/src/transport/transport_api_core.c +++ b/src/transport/transport_api_core.c | |||
@@ -747,18 +747,18 @@ handle_set_quota (void *cls, | |||
747 | struct GNUNET_TRANSPORT_CoreHandle *h = cls; | 747 | struct GNUNET_TRANSPORT_CoreHandle *h = cls; |
748 | struct Neighbour *n; | 748 | struct Neighbour *n; |
749 | 749 | ||
750 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
751 | "Receiving SET_QUOTA message for `%s' with quota %u\n", | ||
752 | GNUNET_i2s (&qm->peer), | ||
753 | ntohl (qm->quota.value__)); | ||
750 | n = neighbour_find (h, | 754 | n = neighbour_find (h, |
751 | &qm->peer); | 755 | &qm->peer); |
752 | if (NULL == n) | 756 | if (NULL == n) |
753 | { | 757 | { |
754 | GNUNET_break (0); | 758 | GNUNET_break (0); /* FIXME: julius reports this assertion fails sometimes? */ |
755 | disconnect_and_schedule_reconnect (h); | 759 | disconnect_and_schedule_reconnect (h); |
756 | return; | 760 | return; |
757 | } | 761 | } |
758 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
759 | "Receiving SET_QUOTA message for `%s' with quota %u\n", | ||
760 | GNUNET_i2s (&qm->peer), | ||
761 | ntohl (qm->quota.value__)); | ||
762 | GNUNET_BANDWIDTH_tracker_update_quota (&n->out_tracker, | 762 | GNUNET_BANDWIDTH_tracker_update_quota (&n->out_tracker, |
763 | qm->quota); | 763 | qm->quota); |
764 | } | 764 | } |
diff --git a/src/util/disk.c b/src/util/disk.c index de37cba0a..4f78c7747 100644 --- a/src/util/disk.c +++ b/src/util/disk.c | |||
@@ -11,7 +11,7 @@ | |||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Affero General Public License for more details. | 13 | Affero General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU Affero General Public License | 15 | You should have received a copy of the GNU Affero General Public License |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | 17 | ||
@@ -625,7 +625,8 @@ GNUNET_DISK_mktemp (const char *t) | |||
625 | * does not exist or stat'ed | 625 | * does not exist or stat'ed |
626 | */ | 626 | */ |
627 | int | 627 | int |
628 | GNUNET_DISK_directory_test (const char *fil, int is_readable) | 628 | GNUNET_DISK_directory_test (const char *fil, |
629 | int is_readable) | ||
629 | { | 630 | { |
630 | struct stat filestat; | 631 | struct stat filestat; |
631 | int ret; | 632 | int ret; |
@@ -639,7 +640,7 @@ GNUNET_DISK_directory_test (const char *fil, int is_readable) | |||
639 | } | 640 | } |
640 | if (!S_ISDIR (filestat.st_mode)) | 641 | if (!S_ISDIR (filestat.st_mode)) |
641 | { | 642 | { |
642 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 643 | LOG (GNUNET_ERROR_TYPE_INFO, |
643 | "A file already exits with the same name %s\n", fil); | 644 | "A file already exits with the same name %s\n", fil); |
644 | return GNUNET_NO; | 645 | return GNUNET_NO; |
645 | } | 646 | } |
@@ -720,7 +721,10 @@ GNUNET_DISK_directory_create (const char *dir) | |||
720 | 721 | ||
721 | rdir = GNUNET_STRINGS_filename_expand (dir); | 722 | rdir = GNUNET_STRINGS_filename_expand (dir); |
722 | if (rdir == NULL) | 723 | if (rdir == NULL) |
724 | { | ||
725 | GNUNET_break (0); | ||
723 | return GNUNET_SYSERR; | 726 | return GNUNET_SYSERR; |
727 | } | ||
724 | 728 | ||
725 | len = strlen (rdir); | 729 | len = strlen (rdir); |
726 | #ifndef MINGW | 730 | #ifndef MINGW |
@@ -756,6 +760,9 @@ GNUNET_DISK_directory_create (const char *dir) | |||
756 | ret = GNUNET_DISK_directory_test (rdir, GNUNET_NO); | 760 | ret = GNUNET_DISK_directory_test (rdir, GNUNET_NO); |
757 | if (GNUNET_NO == ret) | 761 | if (GNUNET_NO == ret) |
758 | { | 762 | { |
763 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
764 | "Creating directory `%s' failed", | ||
765 | rdir); | ||
759 | GNUNET_free (rdir); | 766 | GNUNET_free (rdir); |
760 | return GNUNET_SYSERR; | 767 | return GNUNET_SYSERR; |
761 | } | 768 | } |
@@ -780,6 +787,9 @@ GNUNET_DISK_directory_create (const char *dir) | |||
780 | ret = GNUNET_DISK_directory_test (rdir, GNUNET_NO); | 787 | ret = GNUNET_DISK_directory_test (rdir, GNUNET_NO); |
781 | if (GNUNET_NO == ret) | 788 | if (GNUNET_NO == ret) |
782 | { | 789 | { |
790 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
791 | "Creating directory `%s' failed", | ||
792 | rdir); | ||
783 | GNUNET_free (rdir); | 793 | GNUNET_free (rdir); |
784 | return GNUNET_SYSERR; | 794 | return GNUNET_SYSERR; |
785 | } | 795 | } |
@@ -2684,7 +2694,7 @@ purge_cfg_dir (void *cls, | |||
2684 | { | 2694 | { |
2685 | const char *option = cls; | 2695 | const char *option = cls; |
2686 | char *tmpname; | 2696 | char *tmpname; |
2687 | 2697 | ||
2688 | if (GNUNET_OK != | 2698 | if (GNUNET_OK != |
2689 | GNUNET_CONFIGURATION_get_value_filename (cfg, | 2699 | GNUNET_CONFIGURATION_get_value_filename (cfg, |
2690 | "PATHS", | 2700 | "PATHS", |