From 1c323bd4cbb388a9e7515a1f733a3062bf093aee Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 10 Feb 2015 23:24:01 +0000 Subject: fixing #3657 (replace ATS_Information with struct), but WIHTOUT fixing ATS testcases yet --- src/Makefile.am | 3 +- src/ats-tests/ats-testing-preferences.c | 6 +- src/ats-tests/ats-testing.h | 6 +- src/ats-tool/gnunet-ats.c | 141 ++--- src/ats/Makefile.am | 34 +- src/ats/ats.h | 54 +- src/ats/ats_api_performance.c | 58 +- src/ats/ats_api_scanner.c | 52 +- src/ats/ats_api_scheduling.c | 77 +-- src/ats/gnunet-ats-solver-eval.c | 40 +- src/ats/gnunet-ats-solver-eval.h | 6 +- src/ats/gnunet-service-ats.c | 3 +- src/ats/gnunet-service-ats_addresses.c | 465 ++------------ src/ats/gnunet-service-ats_addresses.h | 43 +- src/ats/gnunet-service-ats_normalization.c | 299 ++++----- src/ats/gnunet-service-ats_normalization.h | 8 +- src/ats/gnunet-service-ats_performance.c | 39 +- src/ats/gnunet-service-ats_performance.h | 6 +- src/ats/gnunet-service-ats_plugins.c | 24 +- src/ats/gnunet-service-ats_plugins.h | 11 +- src/ats/gnunet-service-ats_preferences.c | 20 +- src/ats/gnunet-service-ats_scheduling.c | 53 +- src/ats/plugin_ats_mlp.c | 230 +++---- src/ats/plugin_ats_proportional.c | 45 +- src/ats/plugin_ats_ril.c | 50 +- src/ats/test_ats_api_common.h | 7 +- src/dv/gnunet-service-dv.c | 52 +- src/dv/plugin_transport_dv.c | 59 +- src/fs/gnunet-service-fs.c | 36 +- src/fs/gnunet-service-fs_cp.c | 9 +- src/fs/gnunet-service-fs_cp.h | 5 - src/include/gnunet_ats_plugin.h | 14 +- src/include/gnunet_ats_service.h | 205 +++---- src/include/gnunet_transport_plugin.h | 28 +- src/include/gnunet_transport_service.h | 31 +- src/testbed/gnunet-daemon-latency-logger.c | 22 +- src/testbed/gnunet-daemon-testbed-underlay.c | 18 +- src/transport/Makefile.am | 1 + src/transport/gnunet-service-transport.c | 33 +- src/transport/gnunet-service-transport_ats.c | 248 ++++---- src/transport/gnunet-service-transport_ats.h | 58 +- src/transport/gnunet-service-transport_clients.c | 3 +- .../gnunet-service-transport_manipulation.c | 667 +++++++-------------- .../gnunet-service-transport_manipulation.h | 39 +- .../gnunet-service-transport_neighbours.c | 49 +- src/transport/gnunet-service-transport_plugins.c | 18 +- .../gnunet-service-transport_validation.c | 29 +- src/transport/plugin_transport_http_client.c | 16 +- src/transport/plugin_transport_http_server.c | 40 +- src/transport/plugin_transport_tcp.c | 43 +- src/transport/plugin_transport_udp.c | 26 +- src/transport/plugin_transport_udp_broadcasting.c | 13 - src/transport/plugin_transport_unix.c | 19 +- src/transport/plugin_transport_wlan.c | 28 +- src/transport/test_plugin_transport.c | 10 +- .../test_transport_api_manipulation_recv_tcp.c | 22 +- .../test_transport_api_manipulation_send_tcp.c | 54 +- src/transport/transport.h | 26 +- src/transport/transport_api.c | 76 +-- 59 files changed, 1363 insertions(+), 2414 deletions(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 83648ded2..cdfd5f307 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -67,7 +67,6 @@ SUBDIRS = \ peerinfo-tool \ core \ $(TESTBED) \ - ats-tests \ nse \ dht \ hostlist \ @@ -91,3 +90,5 @@ SUBDIRS = \ pt \ integration-tests \ $(EXP_DIR) + +# ats-tests diff --git a/src/ats-tests/ats-testing-preferences.c b/src/ats-tests/ats-testing-preferences.c index 99dbdb0f9..e5f32d6b1 100644 --- a/src/ats-tests/ats-testing-preferences.c +++ b/src/ats-tests/ats-testing-preferences.c @@ -106,7 +106,10 @@ set_pref_task (void *cls, GNUNET_ATS_print_preference_type (p->pg->kind), pref_value); GNUNET_ATS_performance_change_preference(p->me->ats_perf_handle, - &p->dest->id, p->pg->kind, pref_value, GNUNET_ATS_PREFERENCE_END); + &p->dest->id, + p->pg->kind, + pref_value, + GNUNET_ATS_PREFERENCE_END); switch (p->pg->kind) { case GNUNET_ATS_PREFERENCE_BANDWIDTH: @@ -241,4 +244,3 @@ GNUNET_ATS_TEST_generate_preferences_stop_all () } /* end of file ats-testing-preferences.c */ - diff --git a/src/ats-tests/ats-testing.h b/src/ats-tests/ats-testing.h index 7b1633c28..a2e61c0d6 100644 --- a/src/ats-tests/ats-testing.h +++ b/src/ats-tests/ats-testing.h @@ -84,8 +84,7 @@ typedef void (*GNUNET_ATS_TEST_TopologySetupDoneCallback) (void *cls, * @param address_active is address active * @param bandwidth_out bandwidth outbound * @param bandwidth_in bandwidth inbound - * @param ats ats information - * @param ats_count number of ats inforation + * @param prop performance information */ typedef void (*GNUNET_ATS_TEST_LogRequest) (void *cls, @@ -93,8 +92,7 @@ typedef void int address_active, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count); + const struct GNUNET_ATS_Properties *prop); /** * Information we track for a peer in the testbed. diff --git a/src/ats-tool/gnunet-ats.c b/src/ats-tool/gnunet-ats.c index 612eb20ff..2d19df737 100644 --- a/src/ats-tool/gnunet-ats.c +++ b/src/ats-tool/gnunet-ats.c @@ -84,8 +84,6 @@ static char *opt_type_str; */ static unsigned int opt_pref_value; - - /** * Final status code. */ @@ -124,7 +122,7 @@ static struct GNUNET_CONFIGURATION_Handle *cfg; /** * Shutdown task */ -static struct GNUNET_SCHEDULER_Task * shutdown_task; +static struct GNUNET_SCHEDULER_Task *shutdown_task; /** * Hashmap to store addresses @@ -161,14 +159,9 @@ struct PendingResolutions struct GNUNET_TRANSPORT_AddressToStringContext *tats_ctx; /** - * Array of performance data. + * Performance data. */ - struct GNUNET_ATS_Information *ats; - - /** - * Length of the @e ats array. - */ - uint32_t ats_count; + struct GNUNET_ATS_Properties properties; /** * Amount of outbound bandwidth assigned by ATS. @@ -325,20 +318,15 @@ transport_addr_to_str_cb (void *cls, int res) { struct PendingResolutions *pr = cls; - char *ats_str; - char *ats_tmp; - char *ats_prop_value; - unsigned int c; - uint32_t ats_type; - uint32_t ats_value; - uint32_t network; if (NULL == address) { /* We're done */ - GNUNET_CONTAINER_DLL_remove(head, tail, pr); - GNUNET_free(pr->address); - GNUNET_free(pr); + GNUNET_CONTAINER_DLL_remove (head, + tail, + pr); + GNUNET_free (pr->address); + GNUNET_free (pr); stat_pending--; if ((GNUNET_YES == stat_receive_done) && (0 == stat_pending)) @@ -374,64 +362,15 @@ transport_addr_to_str_cb (void *cls, return; } - ats_str = GNUNET_strdup (pr->active ? _("active ") : _("inactive ")); - network = GNUNET_ATS_NET_UNSPECIFIED; - for (c = 0; c < pr->ats_count; c++) - { - ats_tmp = ats_str; - - ats_type = ntohl (pr->ats[c].type); - ats_value = ntohl (pr->ats[c].value); - - if (ats_type > GNUNET_ATS_PropertyCount) - { - FPRINTF (stderr, - "Invalid ATS property type %u %u for address %s\n", - ats_type, - pr->ats[c].type, - address); - continue; - } - - switch (ats_type) - { - case GNUNET_ATS_NETWORK_TYPE: - if (ats_value > GNUNET_ATS_NetworkTypeCount) - { - GNUNET_break(0); - continue; - } - network = ats_value; - GNUNET_asprintf (&ats_prop_value, - "%s", - GNUNET_ATS_print_network_type (ats_value)); - break; - default: - GNUNET_asprintf (&ats_prop_value, "%u", ats_value); - break; - } - if ((opt_verbose) && (ats_type < GNUNET_ATS_PropertyCount)) - { - GNUNET_asprintf (&ats_str, - "%s%s=%s, ", - ats_tmp, - GNUNET_ATS_print_property_type (ats_type), - ats_prop_value); - GNUNET_free(ats_tmp); - } - GNUNET_free(ats_prop_value); - } - FPRINTF (stderr, _("Peer `%s' plugin `%s', address `%s', `%s' bw out: %u Bytes/s, bw in %u Bytes/s, %s\n"), GNUNET_i2s (&pr->address->peer), pr->address->transport_name, address, - GNUNET_ATS_print_network_type (network), + GNUNET_ATS_print_network_type (pr->properties.scope), ntohl (pr->bandwidth_out.value__), ntohl (pr->bandwidth_in.value__), - ats_str); - GNUNET_free (ats_str); + pr->active ? _("active ") : _("inactive ")); } @@ -489,8 +428,7 @@ find_address_it (void *cls, * #GNUNET_SYSERR if this address is no longer available for ATS * @param bandwidth_out assigned outbound bandwidth for the connection * @param bandwidth_in assigned inbound bandwidth for the connection - * @param ats performance data for the address (as far as known) - * @param ats_count number of performance records in @a ats + * @param prop performance data for the address (as far as known) */ static void ats_perf_mon_cb (void *cls, @@ -498,8 +436,7 @@ ats_perf_mon_cb (void *cls, int active, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count) + const struct GNUNET_ATS_Properties *prop) { struct PendingResolutions *pr; struct PendingResolutions *cur; @@ -517,7 +454,6 @@ ats_perf_mon_cb (void *cls, GNUNET_HELLO_address_free (cur->address); GNUNET_free (cur); } - GNUNET_CONTAINER_multipeermap_iterate (addresses, &free_addr_it, NULL); @@ -530,15 +466,19 @@ ats_perf_mon_cb (void *cls, actx.src = address; actx.res = NULL; - GNUNET_CONTAINER_multipeermap_get_multiple (addresses, &address->peer, - &find_address_it, &actx); + GNUNET_CONTAINER_multipeermap_get_multiple (addresses, + &address->peer, + &find_address_it, + &actx); if (NULL == actx.res) { GNUNET_break (0); return; } - GNUNET_break( - GNUNET_OK == GNUNET_CONTAINER_multipeermap_remove (addresses, &address->peer, actx.res)); + GNUNET_break(GNUNET_OK == + GNUNET_CONTAINER_multipeermap_remove (addresses, + &address->peer, + actx.res)); FPRINTF (stderr, _("Removed address of peer `%s' with plugin `%s'\n"), GNUNET_i2s (&address->peer), @@ -554,8 +494,10 @@ ats_perf_mon_cb (void *cls, actx.src = address; actx.res = NULL; - GNUNET_CONTAINER_multipeermap_get_multiple (addresses, &address->peer, - &find_address_it, &actx); + GNUNET_CONTAINER_multipeermap_get_multiple (addresses, + &address->peer, + &find_address_it, + &actx); if ((NULL != actx.res)) { if ((bandwidth_in.value__ == actx.res->bandwidth_in.value__) && @@ -578,18 +520,15 @@ ats_perf_mon_cb (void *cls, a->bandwidth_in = bandwidth_in; a->bandwidth_out = bandwidth_out; a->active = active; - GNUNET_CONTAINER_multipeermap_put (addresses, &address->peer, a, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); + GNUNET_CONTAINER_multipeermap_put (addresses, + &address->peer, + a, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); } } - pr = GNUNET_malloc (sizeof (struct PendingResolutions) + - ats_count * sizeof (struct GNUNET_ATS_Information)); - - pr->ats_count = ats_count; - pr->ats = (struct GNUNET_ATS_Information *) &pr[1]; - if (ats_count > 0) - memcpy (pr->ats, ats, ats_count * sizeof(struct GNUNET_ATS_Information)); + pr = GNUNET_new (struct PendingResolutions); + pr->properties = *prop; pr->address = GNUNET_HELLO_address_copy (address); pr->bandwidth_in = bandwidth_in; pr->bandwidth_out = bandwidth_out; @@ -614,8 +553,7 @@ ats_perf_mon_cb (void *cls, to a peer * @param bandwidth_out assigned outbound bandwidth for the connection * @param bandwidth_in assigned inbound bandwidth for the connection - * @param ats performance data for the address (as far as known) - * @param ats_count number of performance records in @a ats + * @param prop performance data for the address (as far as known) */ static void ats_perf_cb (void *cls, @@ -623,8 +561,7 @@ ats_perf_cb (void *cls, int active, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count) + const struct GNUNET_ATS_Properties *prop) { struct PendingResolutions *pr; @@ -643,13 +580,8 @@ ats_perf_cb (void *cls, return; } - pr = GNUNET_malloc (sizeof (struct PendingResolutions) + - ats_count * sizeof (struct GNUNET_ATS_Information)); - - pr->ats_count = ats_count; - pr->ats = (struct GNUNET_ATS_Information *) &pr[1]; - if (ats_count > 0) - memcpy (pr->ats, ats, ats_count * sizeof(struct GNUNET_ATS_Information)); + pr = GNUNET_new (struct PendingResolutions); + pr->properties = *prop; pr->address = GNUNET_HELLO_address_copy (address); pr->bandwidth_in = bandwidth_in; pr->bandwidth_out = bandwidth_out; @@ -921,7 +853,10 @@ testservice_ats (void *cls, "%s", _("Cannot connect to ATS service, exiting...\n")); - GNUNET_ATS_performance_change_preference (ph, &pid, type, (double) opt_pref_value, + GNUNET_ATS_performance_change_preference (ph, + &pid, + type, + (double) opt_pref_value, GNUNET_ATS_PREFERENCE_END); shutdown_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, diff --git a/src/ats/Makefile.am b/src/ats/Makefile.am index 4491b08a2..2a14ae73f 100644 --- a/src/ats/Makefile.am +++ b/src/ats/Makefile.am @@ -18,8 +18,8 @@ if USE_COVERAGE AM_CFLAGS = -fprofile-arcs -ftest-coverage endif -noinst_PROGRAMS = \ - gnunet-ats-solver-eval +#noinst_PROGRAMS = \ +# gnunet-ats-solver-eval if HAVE_LIBGLPK GN_LIBGLPK = -lglpk @@ -42,21 +42,21 @@ plugin_LTLIBRARIES = \ $(GN_MLP_LIB) \ libgnunet_plugin_ats_ril.la -gnunet_ats_solver_eval_SOURCES = \ - gnunet-ats-solver-eval.c gnunet-ats-solver-eval.h \ - gnunet-service-ats_addresses.c gnunet-service-ats_addresses.h \ - gnunet-service-ats_plugins.c gnunet-service-ats_plugins.h \ - gnunet-service-ats_connectivity.c gnunet-service-ats_connectivity.h \ - gnunet-service-ats_feedback.c gnunet-service-ats_feedback.h \ - gnunet-service-ats_performance.c gnunet-service-ats_performance.h \ - gnunet-service-ats_reservations.c gnunet-service-ats_reservations.h \ - gnunet-service-ats_scheduling.c gnunet-service-ats_scheduling.h \ - gnunet-service-ats_normalization.c -gnunet_ats_solver_eval_LDADD = \ - $(top_builddir)/src/util/libgnunetutil.la \ - libgnunetats.la \ - $(top_builddir)/src/statistics/libgnunetstatistics.la \ - $(LTLIBINTL) +#gnunet_ats_solver_eval_SOURCES = \ +# gnunet-ats-solver-eval.c gnunet-ats-solver-eval.h \ +# gnunet-service-ats_addresses.c gnunet-service-ats_addresses.h \ +# gnunet-service-ats_plugins.c gnunet-service-ats_plugins.h \ +# gnunet-service-ats_connectivity.c gnunet-service-ats_connectivity.h \ +# gnunet-service-ats_feedback.c gnunet-service-ats_feedback.h \ +# gnunet-service-ats_performance.c gnunet-service-ats_performance.h \ +# gnunet-service-ats_reservations.c gnunet-service-ats_reservations.h \ +# gnunet-service-ats_scheduling.c gnunet-service-ats_scheduling.h \ +# gnunet-service-ats_normalization.c +#gnunet_ats_solver_eval_LDADD = \ +# $(top_builddir)/src/util/libgnunetutil.la \ +# libgnunetats.la \ +# $(top_builddir)/src/statistics/libgnunetstatistics.la \ +# $(LTLIBINTL) libgnunetats_la_SOURCES = \ ats_api_connectivity.c \ diff --git a/src/ats/ats.h b/src/ats/ats.h index d5d5d6c3f..7e411fb98 100644 --- a/src/ats/ats.h +++ b/src/ats/ats.h @@ -27,6 +27,8 @@ #define ATS_H #include "gnunet_util_lib.h" +#include "gnunet_ats_service.h" + /** * Flag used to indicate which type of client is connecting @@ -114,16 +116,6 @@ struct AddressAddMessage */ struct GNUNET_MessageHeader header; - /** - * Length of the `struct GNUNET_ATS_Information` array that follows this struct. - */ - uint32_t ats_count GNUNET_PACKED; - - /** - * Identity of the peer that this address is for. - */ - struct GNUNET_PeerIdentity peer; - /** * Number of bytes in the address that follows this struct. */ @@ -134,6 +126,11 @@ struct AddressAddMessage */ uint16_t plugin_name_length GNUNET_PACKED; + /** + * Identity of the peer that this address is for. + */ + struct GNUNET_PeerIdentity peer; + /** * Internal number this client will henceforth use to * refer to this address. @@ -146,8 +143,12 @@ struct AddressAddMessage */ uint32_t address_local_info GNUNET_PACKED; + /** + * Performance properties of the address. + */ + struct GNUNET_ATS_PropertiesNBO properties; + /* followed by: - * - struct GNUNET_ATS_Information [ats_count]; * - char address[address_length] * - char plugin_name[plugin_name_length] (including '\0'-termination). */ @@ -167,9 +168,9 @@ struct AddressUpdateMessage struct GNUNET_MessageHeader header; /** - * Length of the `struct GNUNET_ATS_Information` array that follows. + * Internal number this client uses to refer to this address. */ - uint32_t ats_count GNUNET_PACKED; + uint32_t session_id GNUNET_PACKED; /** * Which peer is this about? (Technically redundant, as the @@ -179,13 +180,9 @@ struct AddressUpdateMessage struct GNUNET_PeerIdentity peer; /** - * Internal number this client uses to refer to this address. - */ - uint32_t session_id GNUNET_PACKED; - - /* followed by: - * - struct GNUNET_ATS_Information [ats_count]; + * Performance properties of the address. */ + struct GNUNET_ATS_PropertiesNBO properties; }; @@ -294,17 +291,12 @@ struct PeerInformationMessage /** * */ - uint32_t ats_count GNUNET_PACKED; - - /** - * - */ - uint32_t address_active GNUNET_PACKED; + uint16_t address_length GNUNET_PACKED; /** * */ - uint32_t id GNUNET_PACKED; + uint16_t plugin_name_length GNUNET_PACKED; /** * @@ -314,12 +306,12 @@ struct PeerInformationMessage /** * */ - uint16_t address_length GNUNET_PACKED; + uint32_t address_active GNUNET_PACKED; /** * */ - uint16_t plugin_name_length GNUNET_PACKED; + uint32_t id GNUNET_PACKED; /** * @@ -331,8 +323,12 @@ struct PeerInformationMessage */ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in; + /** + * Performance properties of the address. + */ + struct GNUNET_ATS_PropertiesNBO properties; + /* followed by: - * - struct GNUNET_ATS_Information [ats_count]; * - char address[address_length] * - char plugin_name[plugin_name_length] (including '\0'-termination). */ diff --git a/src/ats/ats_api_performance.c b/src/ats/ats_api_performance.c index 51980f079..aaaaee089 100644 --- a/src/ats/ats_api_performance.c +++ b/src/ats/ats_api_performance.c @@ -364,35 +364,27 @@ process_pi_message (struct GNUNET_ATS_PerformanceHandle *ph, const struct GNUNET_MessageHeader *msg) { const struct PeerInformationMessage *pi; - const struct GNUNET_ATS_Information *atsi; const char *plugin_address; const char *plugin_name; struct GNUNET_HELLO_Address address; uint16_t plugin_address_length; uint16_t plugin_name_length; - uint32_t ats_count; int addr_active; + struct GNUNET_ATS_Properties prop; if (ntohs (msg->size) < sizeof(struct PeerInformationMessage)) { GNUNET_break(0); return GNUNET_SYSERR; } - pi = (const struct PeerInformationMessage *) msg; - ats_count = ntohl (pi->ats_count); plugin_address_length = ntohs (pi->address_length); plugin_name_length = ntohs (pi->plugin_name_length); addr_active = (int) ntohl (pi->address_active); - atsi = (const struct GNUNET_ATS_Information *) &pi[1]; - plugin_address = (const char *) &atsi[ats_count]; + plugin_address = (const char *) &pi[1]; plugin_name = &plugin_address[plugin_address_length]; if ((plugin_address_length + plugin_name_length - + ats_count * sizeof(struct GNUNET_ATS_Information) + sizeof(struct PeerInformationMessage) != ntohs (msg->size)) - || (ats_count - > GNUNET_SERVER_MAX_MESSAGE_SIZE - / sizeof(struct GNUNET_ATS_Information)) || (plugin_name[plugin_name_length - 1] != '\0')) { GNUNET_break(0); @@ -401,6 +393,8 @@ process_pi_message (struct GNUNET_ATS_PerformanceHandle *ph, if (NULL != ph->addr_info_cb) { + GNUNET_ATS_properties_ntoh (&prop, + &pi->properties); address.peer = pi->peer; address.address = plugin_address; address.address_length = plugin_address_length; @@ -410,7 +404,7 @@ process_pi_message (struct GNUNET_ATS_PerformanceHandle *ph, addr_active, pi->bandwidth_out, pi->bandwidth_in, - atsi, ats_count); + &prop); } return GNUNET_OK; } @@ -488,15 +482,14 @@ process_ar_message (struct GNUNET_ATS_PerformanceHandle *ph, const struct PeerInformationMessage *pi; struct GNUNET_ATS_AddressListHandle *alh; struct GNUNET_ATS_AddressListHandle *next; - const struct GNUNET_ATS_Information *atsi; const char *plugin_address; const char *plugin_name; struct GNUNET_HELLO_Address address; struct GNUNET_PeerIdentity allzeros; struct GNUNET_BANDWIDTH_Value32NBO bandwidth_zero; + struct GNUNET_ATS_Properties prop; uint16_t plugin_address_length; uint16_t plugin_name_length; - uint32_t ats_count; uint32_t active; uint32_t id; @@ -507,18 +500,13 @@ process_ar_message (struct GNUNET_ATS_PerformanceHandle *ph, } pi = (const struct PeerInformationMessage *) msg; id = ntohl (pi->id); - ats_count = ntohl (pi->ats_count); active = ntohl (pi->address_active); plugin_address_length = ntohs (pi->address_length); plugin_name_length = ntohs (pi->plugin_name_length); - atsi = (const struct GNUNET_ATS_Information *) &pi[1]; - plugin_address = (const char *) &atsi[ats_count]; + plugin_address = (const char *) &pi[1]; plugin_name = &plugin_address[plugin_address_length]; if ( (plugin_address_length + plugin_name_length - + ats_count * sizeof(struct GNUNET_ATS_Information) + sizeof (struct PeerInformationMessage) != ntohs (msg->size)) || - (ats_count > GNUNET_SERVER_MAX_MESSAGE_SIZE - / sizeof(struct GNUNET_ATS_Information)) || (plugin_name[plugin_name_length - 1] != '\0') ) { GNUNET_break(0); @@ -545,8 +533,7 @@ process_ar_message (struct GNUNET_ATS_PerformanceHandle *ph, memset (&allzeros, '\0', sizeof (allzeros)); if ( (0 == memcmp (&allzeros, &pi->peer, sizeof(allzeros))) && (0 == plugin_name_length) && - (0 == plugin_address_length) && - (0 == ats_count) ) + (0 == plugin_address_length) ) { /* Done */ LOG (GNUNET_ERROR_TYPE_DEBUG, @@ -561,7 +548,7 @@ process_ar_message (struct GNUNET_ATS_PerformanceHandle *ph, GNUNET_NO, bandwidth_zero, bandwidth_zero, - NULL, 0); + NULL); GNUNET_free (alh); return GNUNET_OK; } @@ -573,12 +560,16 @@ process_ar_message (struct GNUNET_ATS_PerformanceHandle *ph, if ( ( (GNUNET_YES == alh->all_addresses) || (GNUNET_YES == active) ) && (NULL != alh->cb) ) + { + GNUNET_ATS_properties_ntoh (&prop, + &pi->properties); alh->cb (ph->addr_info_cb_cls, &address, active, pi->bandwidth_out, pi->bandwidth_in, - atsi, ats_count); + &prop); + } return GNUNET_OK; } @@ -641,7 +632,7 @@ process_ats_message (void *cls, GNUNET_NO, GNUNET_BANDWIDTH_value_init (0), GNUNET_BANDWIDTH_value_init (0), - NULL, 0); + NULL); } ph->backoff = GNUNET_TIME_STD_BACKOFF (ph->backoff); ph->task = GNUNET_SCHEDULER_add_delayed (ph->backoff, @@ -917,8 +908,9 @@ GNUNET_ATS_performance_list_addresses_cancel (struct GNUNET_ATS_AddressListHandl const char * GNUNET_ATS_print_preference_type (uint32_t type) { - char *prefs[GNUNET_ATS_PreferenceCount] = GNUNET_ATS_PreferenceTypeString; - if (type < GNUNET_ATS_PreferenceCount) + const char *prefs[] = GNUNET_ATS_PreferenceTypeString; + + if (type < GNUNET_ATS_PREFERENCE_END) return prefs[type]; return NULL; } @@ -930,7 +922,7 @@ GNUNET_ATS_print_preference_type (uint32_t type) * * @param ph performance handle * @param peer identifies the peer - * @param ... 0-terminated specification of the desired changes + * @param ... #GNUNET_ATS_PREFERENCE_END-terminated specification of the desired changes */ void GNUNET_ATS_performance_change_preference (struct GNUNET_ATS_PerformanceHandle *ph, @@ -946,20 +938,18 @@ GNUNET_ATS_performance_change_preference (struct GNUNET_ATS_PerformanceHandle *p count = 0; va_start(ap, peer); - while (GNUNET_ATS_PREFERENCE_END != (kind = - va_arg (ap, enum GNUNET_ATS_PreferenceKind) )) + while (GNUNET_ATS_PREFERENCE_END != + (kind = va_arg (ap, enum GNUNET_ATS_PreferenceKind) )) { switch (kind) { case GNUNET_ATS_PREFERENCE_BANDWIDTH: count++; (void) va_arg (ap, double); - break; case GNUNET_ATS_PREFERENCE_LATENCY: count++; (void) va_arg (ap, double); - break; default: GNUNET_assert(0); @@ -1012,7 +1002,7 @@ GNUNET_ATS_performance_change_preference (struct GNUNET_ATS_PerformanceHandle *p * @param ph performance handle * @param scope the time interval this valid for: [now - scope .. now] * @param peer identifies the peer - * @param ... 0-terminated specification of the desired changes + * @param ... #GNUNET_ATS_PREFERENCE_END-terminated specification of the desired changes */ void GNUNET_ATS_performance_give_feedback (struct GNUNET_ATS_PerformanceHandle *ph, @@ -1029,8 +1019,8 @@ GNUNET_ATS_performance_give_feedback (struct GNUNET_ATS_PerformanceHandle *ph, count = 0; va_start(ap, scope); - while (GNUNET_ATS_PREFERENCE_END != (kind = - va_arg (ap, enum GNUNET_ATS_PreferenceKind) )) + while (GNUNET_ATS_PREFERENCE_END != + (kind = va_arg (ap, enum GNUNET_ATS_PreferenceKind) )) { switch (kind) { diff --git a/src/ats/ats_api_scanner.c b/src/ats/ats_api_scanner.c index 64c02acf6..f9c30770e 100644 --- a/src/ats/ats_api_scanner.c +++ b/src/ats/ats_api_scanner.c @@ -62,32 +62,38 @@ GNUNET_ATS_print_network_type (enum GNUNET_ATS_Network_Type net) /** - * Convert a ATS property to a string + * Convert ATS properties from host to network byte order. * - * @param type the property type - * @return a string or NULL if invalid + * @param nbo[OUT] value written + * @param hbo value read */ -const char * -GNUNET_ATS_print_property_type (enum GNUNET_ATS_Property type) +void +GNUNET_ATS_properties_hton (struct GNUNET_ATS_PropertiesNBO *nbo, + const struct GNUNET_ATS_Properties *hbo) { - switch (type) - { - case GNUNET_ATS_ARRAY_TERMINATOR: - return "TERMINATOR"; - case GNUNET_ATS_UTILIZATION_OUT: - return "UTILIZATION_UP"; - case GNUNET_ATS_UTILIZATION_IN: - return "UTILIZATION_DOWN"; - case GNUNET_ATS_NETWORK_TYPE: - return "NETWORK_TYPE"; - case GNUNET_ATS_QUALITY_NET_DELAY: - return "DELAY"; - case GNUNET_ATS_QUALITY_NET_DISTANCE: - return "DISTANCE"; - default: - GNUNET_break (0); - return NULL; - } + nbo->utilization_out = htonl (hbo->utilization_out); + nbo->utilization_in = htonl (hbo->utilization_in); + nbo->scope = htonl ((uint32_t) hbo->scope); + nbo->distance = htonl (hbo->distance); + nbo->delay = GNUNET_TIME_relative_hton (hbo->delay); +} + + +/** + * Convert ATS properties from network to host byte order. + * + * @param hbo[OUT] value written + * @param nbo value read + */ +void +GNUNET_ATS_properties_ntoh (struct GNUNET_ATS_Properties *hbo, + const struct GNUNET_ATS_PropertiesNBO *nbo) +{ + hbo->utilization_out = ntohl (nbo->utilization_out); + hbo->utilization_in = ntohl (nbo->utilization_in); + hbo->scope = ntohl ((uint32_t) nbo->scope); + hbo->distance = ntohl (nbo->distance); + hbo->delay = GNUNET_TIME_relative_ntoh (nbo->delay); } diff --git a/src/ats/ats_api_scheduling.c b/src/ats/ats_api_scheduling.c index ed82dd2ad..f02e4a9e7 100644 --- a/src/ats/ats_api_scheduling.c +++ b/src/ats/ats_api_scheduling.c @@ -73,14 +73,9 @@ struct GNUNET_ATS_AddressRecord struct Session *session; /** - * Array with performance data about the address. + * Performance data about the address. */ - struct GNUNET_ATS_Information *ats; - - /** - * Number of entries in @e ats. - */ - uint32_t ats_count; + struct GNUNET_ATS_PropertiesNBO properties; /** * Which slot (index) in the session array does @@ -487,7 +482,6 @@ send_add_address_message (struct GNUNET_ATS_SchedulingHandle *sh, { struct GNUNET_MQ_Envelope *ev; struct AddressAddMessage *m; - struct GNUNET_ATS_Information *am; char *pm; size_t namelen; size_t msize; @@ -497,16 +491,14 @@ send_add_address_message (struct GNUNET_ATS_SchedulingHandle *sh, namelen = (NULL == ar->address->transport_name) ? 0 : strlen (ar->address->transport_name) + 1; - msize = ar->address->address_length + - ar->ats_count * sizeof (struct GNUNET_ATS_Information) + namelen; - + msize = ar->address->address_length + namelen; ev = GNUNET_MQ_msg_extra (m, msize, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_ADD); - m->ats_count = htonl (ar->ats_count); m->peer = ar->address->peer; m->address_length = htons (ar->address->address_length); m->address_local_info = htonl ((uint32_t) ar->address->local_info); m->plugin_name_length = htons (namelen); m->session_id = htonl (ar->slot); + m->properties = ar->properties; LOG (GNUNET_ERROR_TYPE_DEBUG, "Adding address for peer `%s', plugin `%s', session %p slot %u\n", @@ -514,11 +506,7 @@ send_add_address_message (struct GNUNET_ATS_SchedulingHandle *sh, ar->address->transport_name, ar->session, ar->slot); - am = (struct GNUNET_ATS_Information *) &m[1]; - memcpy (am, - ar->ats, - ar->ats_count * sizeof (struct GNUNET_ATS_Information)); - pm = (char *) &am[ar->ats_count]; + pm = (char *) &m[1]; memcpy (pm, ar->address->address, ar->address->address_length); @@ -675,8 +663,7 @@ GNUNET_ATS_session_known (struct GNUNET_ATS_SchedulingHandle *sh, * @param sh handle * @param address the address * @param session session handle, can be NULL - * @param ats performance data for the address - * @param ats_count number of performance records in @a ats + * @param prop performance data for the address * @return handle to the address representation inside ATS, NULL * on error (i.e. ATS knows this exact address already) */ @@ -684,8 +671,7 @@ struct GNUNET_ATS_AddressRecord * GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh, const struct GNUNET_HELLO_Address *address, struct Session *session, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count) + const struct GNUNET_ATS_Properties *prop) { struct GNUNET_ATS_AddressRecord *ar; size_t namelen; @@ -701,13 +687,10 @@ GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh, namelen = (NULL == address->transport_name) ? 0 : strlen (address->transport_name) + 1; - msize = address->address_length + - ats_count * sizeof (struct GNUNET_ATS_Information) + namelen; + msize = address->address_length + namelen; if ((msize + sizeof (struct AddressUpdateMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || (address->address_length >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || - (namelen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || - (ats_count >= - GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_ATS_Information))) + (namelen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) ) { /* address too large for us, this should not happen */ GNUNET_break (0); @@ -729,12 +712,8 @@ GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh, ar->slot = s; ar->session = session; ar->address = GNUNET_HELLO_address_copy (address); - GNUNET_array_grow (ar->ats, - ar->ats_count, - ats_count); - memcpy (ar->ats, - ats, - ats_count * sizeof (struct GNUNET_ATS_Information)); + GNUNET_ATS_properties_hton (&ar->properties, + prop); sh->session_array[s] = ar; send_add_address_message (sh, ar); return ar; @@ -793,19 +772,15 @@ GNUNET_ATS_address_del_session (struct GNUNET_ATS_AddressRecord *ar, * for later use). Update bandwidth assignments. * * @param ar address record to update information for - * @param ats performance data for the address - * @param ats_count number of performance records in @a ats + * @param prop performance data for the address */ void GNUNET_ATS_address_update (struct GNUNET_ATS_AddressRecord *ar, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count) + const struct GNUNET_ATS_Properties *prop) { struct GNUNET_ATS_SchedulingHandle *sh = ar->sh; struct GNUNET_MQ_Envelope *ev; struct AddressUpdateMessage *m; - struct GNUNET_ATS_Information *am; - size_t msize; LOG (GNUNET_ERROR_TYPE_DEBUG, "Updating address for peer `%s', plugin `%s', session %p slot %u\n", @@ -813,25 +788,16 @@ GNUNET_ATS_address_update (struct GNUNET_ATS_AddressRecord *ar, ar->address->transport_name, ar->session, ar->slot); - GNUNET_array_grow (ar->ats, - ar->ats_count, - ats_count); - memcpy (ar->ats, - ats, - ats_count * sizeof (struct GNUNET_ATS_Information)); - + GNUNET_ATS_properties_hton (&ar->properties, + prop); if (NULL == sh->mq) return; /* disconnected, skip for now */ - msize = ar->ats_count * sizeof (struct GNUNET_ATS_Information); - ev = GNUNET_MQ_msg_extra (m, msize, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE); - m->ats_count = htonl (ar->ats_count); - m->peer = ar->address->peer; + ev = GNUNET_MQ_msg (m, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE); m->session_id = htonl (ar->slot); - am = (struct GNUNET_ATS_Information *) &m[1]; - memcpy (am, - ar->ats, - ar->ats_count * sizeof (struct GNUNET_ATS_Information)); - GNUNET_MQ_send (sh->mq, ev); + m->peer = ar->address->peer; + m->properties = ar->properties; + GNUNET_MQ_send (sh->mq, + ev); } @@ -857,9 +823,6 @@ GNUNET_ATS_address_destroy (struct GNUNET_ATS_AddressRecord *ar) GNUNET_break (NULL == ar->session); ar->session = NULL; ar->in_destroy = GNUNET_YES; - GNUNET_array_grow (ar->ats, - ar->ats_count, - 0); if (NULL == sh->mq) return; ev = GNUNET_MQ_msg (m, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_DESTROYED); diff --git a/src/ats/gnunet-ats-solver-eval.c b/src/ats/gnunet-ats-solver-eval.c index 8cf4b115b..5645e81c5 100644 --- a/src/ats/gnunet-ats-solver-eval.c +++ b/src/ats/gnunet-ats-solver-eval.c @@ -166,7 +166,8 @@ GNUNET_ATS_solver_logging_now (struct LoggingHandle *l) /* Store logging data here */ for (cur = peer_head; NULL != cur; cur = cur->next) { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Logging peer id %llu\n", cur->id); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Logging peer id %llu\n", cur->id); log_p = GNUNET_new (struct LoggingPeer); log_p->id = cur->id; @@ -176,16 +177,18 @@ GNUNET_ATS_solver_logging_now (struct LoggingHandle *l) { log_p->pref_abs[c] = cur->pref_abs[c]; log_p->pref_norm[c] = cur->pref_norm[c]; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\t %s = %.2f %.2f [abs/rel]\n", - GNUNET_ATS_print_preference_type(c), - log_p->pref_abs[c], log_p->pref_norm[c]); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "\t %s = %.2f %.2f [abs/rel]\n", + GNUNET_ATS_print_preference_type(c), + log_p->pref_abs[c], log_p->pref_norm[c]); } GNUNET_CONTAINER_DLL_insert_tail(lts->head, lts->tail, log_p); for (cur_addr = cur->addr_head; NULL != cur_addr; cur_addr = cur_addr->next) { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Logging peer id %llu address %llu \n", - cur->id, cur_addr->aid); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Logging peer id %llu address %llu\n", + cur->id, cur_addr->aid); log_a = GNUNET_new (struct LoggingAddress); log_a->aid = cur_addr->aid; log_a->active = cur_addr->ats_addr->active; @@ -196,9 +199,11 @@ GNUNET_ATS_solver_logging_now (struct LoggingHandle *l) { log_a->prop_abs[c] = cur_addr->prop_abs[c]; log_a->prop_norm[c] = cur_addr->prop_norm[c]; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\t %s = %.2f %.2f [abs/rel]\n", - GNUNET_ATS_print_property_type(c), - log_a->prop_abs[c], log_a->prop_norm[c]); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "\t %s = %.2f %.2f [abs/rel]\n", + GNUNET_ATS_print_property_type(c), + log_a->prop_abs[c], + log_a->prop_norm[c]); } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\t Active = %i\n", log_a->active); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\t BW in = %llu\n", log_a->assigned_bw_in); @@ -209,16 +214,17 @@ GNUNET_ATS_solver_logging_now (struct LoggingHandle *l) } } + static void logging_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct LoggingHandle *l = cls; - l->logging_task = NULL; + l->logging_task = NULL; GNUNET_ATS_solver_logging_now (l); - - l->logging_task = GNUNET_SCHEDULER_add_delayed (l->log_freq, &logging_task, l); - + l->logging_task = GNUNET_SCHEDULER_add_delayed (l->log_freq, + &logging_task, + l); } struct LoggingHandle * @@ -395,7 +401,9 @@ GNUNET_ATS_solver_logging_write_to_disk (struct LoggingHandle *l, int add_time_s GNUNET_ATS_print_property_type(c), log_a->prop_abs[c], log_a->prop_norm[c]);*/ GNUNET_asprintf(&propstring_tmp,"%s%.3f;%.3f;", - propstring, log_a->prop_abs[c], log_a->prop_norm[c]); + propstring, + log_a->prop_abs[c], + log_a->prop_norm[c]); GNUNET_free (propstring); propstring = GNUNET_strdup(propstring_tmp); GNUNET_free (propstring_tmp); @@ -519,10 +527,10 @@ GNUNET_ATS_solver_logging_free (struct LoggingHandle *l) /** * Property Generators */ - static struct PropertyGenerator *prop_gen_head; static struct PropertyGenerator *prop_gen_tail; + static double get_property (struct PropertyGenerator *pg) { @@ -3001,7 +3009,7 @@ get_preferences_cb (void *cls, const struct GNUNET_PeerIdentity *id) } else return GAS_preference_get_by_peer (NULL, - id); + id); } diff --git a/src/ats/gnunet-ats-solver-eval.h b/src/ats/gnunet-ats-solver-eval.h index bc5083e34..44ccfe081 100644 --- a/src/ats/gnunet-ats-solver-eval.h +++ b/src/ats/gnunet-ats-solver-eval.h @@ -120,8 +120,8 @@ struct LoggingPeer long long unsigned int id; struct GNUNET_PeerIdentity peer_id; - double pref_abs[GNUNET_ATS_PreferenceCount]; - double pref_norm[GNUNET_ATS_PreferenceCount]; + double pref_abs[GNUNET_ATS_PREFERENCE_END]; + double pref_norm[GNUNET_ATS_PREFERENCE_END]; int is_requested; struct LoggingAddress *addr_head; @@ -215,7 +215,7 @@ struct GNUNET_ATS_TEST_Operation enum OperationType type; enum GeneratorType gen_type; enum GNUNET_ATS_PreferenceKind pref_type; - enum GNUNET_ATS_Property prop_type; + // enum GNUNET_ATS_Property prop_type; }; struct Episode diff --git a/src/ats/gnunet-service-ats.c b/src/ats/gnunet-service-ats.c index 716bd6332..8570b57b6 100644 --- a/src/ats/gnunet-service-ats.c +++ b/src/ats/gnunet-service-ats.c @@ -177,7 +177,8 @@ run (void *cls, {&GAS_handle_address_add, NULL, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_ADD, 0}, {&GAS_handle_address_update, NULL, - GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE, 0}, + GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE, + sizeof (struct AddressUpdateMessage) }, {&GAS_handle_address_destroyed, NULL, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_DESTROYED, sizeof (struct AddressDestroyedMessage) }, diff --git a/src/ats/gnunet-service-ats_addresses.c b/src/ats/gnunet-service-ats_addresses.c index c4d7f2da9..17f030a6c 100644 --- a/src/ats/gnunet-service-ats_addresses.c +++ b/src/ats/gnunet-service-ats_addresses.c @@ -31,186 +31,6 @@ #include "gnunet-service-ats_plugins.h" -/** - * NOTE: Do not change this documentation. This documentation is based on - * gnunet.org:/vcs/fsnsg/2014-p2p-ats.git/tech-doku/ats-tech-guide.tex - * use build_txt.sh to generate plaintext output - * - * 1 ATS addresses : ATS address management - * - * This ATS addresses ("addresses") component manages the addresses known to - * ATS service and suggests addresses to transport service when it is - * interested in address suggestion for a peer. ATS addresses also - * instantiates the bandwidth assignment mechanism (solver), notifies it - * about changes to addresses and forwards changes to bandwidth assignments - * to transport, depending if transport is interested in this change. - * - * 1.1 Input data - * - * 1.1.1 Addresses - * - * Addresses are added by specifying peer ID, plugin, address, address length - * and session, if available. ATS information can be specified if available. - * - * 1.1.2 Networks - * - * ATS specifies a fix set of networks an address can belong to. For each - * network an inbound and outbound quota will be specified. The available - * networks and addtional helper varaibles are defined in - * gnunet_ats_service.h. At the moment 5 networks are defined: - * * GNUNET_ATS_NET_UNSPECIFIED - * * GNUNET_ATS_NET_LOOPBACK - * * GNUNET_ATS_NET_LAN - * * GNUNET_ATS_NET_WAN - * * GNUNET_ATS_NET_WLAN - * - * The total number of networks defined is stored in - * GNUNET_ATS_NetworkTypeCount GNUNET_ATS_NetworkType can be used array - * initializer for an int array, while GNUNET_ATS_NetworkType is an - * initializer for a char array containing a string description of all - * networks - * - * 1.1.3 Quotas - * - * An inbound and outbound quota for each of the networks mentioned in 1.1.2 - * is loaded from ats configuration during initialization. This quota defines - * to total amount of inbound and outbound traffic allowed for a specific - * network. The configuration values used are in section ats: - * * "NETWORK"_QUOTA_IN = - * * "NETWORK"_QUOTA_IN = - * - * You can specify quotas by setting the to a: - * * unrestricted: unlimited - * * number of bytes: e.g. 10240 - * * fancy value: e.g. 64 Kib - * - * unlimited is defined as GNUNET_ATS_MaxBandwidthString and equivalent to - * the value GNUNET_ATS_MaxBandwidth Important predefined values for quotas - * are: - * * GNUNET_ATS_DefaultBandwidth: 65536 - * * GNUNET_ATS_MaxBandwidth: UINT32_MAX - * * GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT: 1024 - * - * Details of loading quotas and default values will be described on - * - * 1.1.4 Preference values - * - * 1.2 Data structures used - * - * Addresse uses struct ATS_Address for each address. The structs are stored - * in a linked list and provides a pointer void *solver_information for the - * solver to store address specific information. It provides the int values - * active which is set to GNUNET_YES if the address is select for transport - * use and used, representing that transport service is actively using this - * address. Address information are stored in peer, addr, addr_len, plugin. - * - * 1.3 Initialization - * - * During initialization a hashmap to store addresses is created. The quotas - * for all networks defined for ATS are loaded from configuration. For each - * network first the logic will check if the string - * GNUNET_ATS_MaxBandwidthString is configured, if not it will try to convert - * the configured value as a fancy size and if this fails it will try to use - * it as a value_number. If no configuration value is found it will assign - * GNUNET_ATS_DefaultBandwidth. The most important step is to load the - * configured solver using configuration "[ats]:MODE". Current solvers are - * MODE_PROPORTIONAL, MODE_MLP. Interaction is done using a solver API - * - * 1.4 Solver API - * - * Solver functions: - * * s_init: init the solver with required information - * * s_add: add a new address - * * s_update: update ATS values or session for an address - * * s_get: get prefered address for a peer - * * s_del: delete an address - * * s_pref: change preference value for a peer - * * s_done: shutdown solver - * - * Callbacks: addresses provides a bandwidth_changed_cb callback to the - * solver which is called when bandwidth assigned to peer has changed - * - * 1.5 Shutdown - * - * During shutdown all addresses are freed and the solver told to shutdown - * - * 1.6 Addresses and sessions - * - * Addresses consist of the address itself and a numerical session. When a - * new address without a session is added it has no session, so it gets - * session 0 assigned. When an address with a session is added and an address - * object with session 0 is found, this object is updated with the session - * otherwise a new address object with this session assigned is created. - * - * 1.6.1 Terminology - * - * Addresses a1,a2 with session s1, s2 are "exact" if: - * (a1 == a2)&&(s1 == s2) - * Addresses a1,a2 with session s1, s2 are "equivalent" if: - * (a1 == a2)&&((s1 == s2)||(s1 == 0)||(s2 == 0) - * - * 1.7 Address management - * - * Transport service notifies ATS about changes to the addresses known to - * him. - * - * 1.7.1 Adding an address - * - * When transport learns a new address it tells ATS and ATS is telling - * addresses about it using GAS_address_add. If not known to addresses it - * creates a new address object and calls solver's s_add. ATS information are - * deserialized and solver is notified about the session and ATS information - * using s_update. - * - * 1.7.2 Updating an address - * - * Addresses does an lookup up for the existing address with the given - * session. If disassembles included ATS information and notifies the solver - * using s_update about the update. - * - * 1.7.3 Deleting an address - * - * Addresses does an lookup for the exact address and session and if removes - * this address. If session != 0 the session is set to 0 and the address is - * kept. If session == 0, the addresses is removed. - * - * 1.7.4 Requesting an address suggestion - * - * The address client issues a request address message to be notified about - * address suggestions for a specific peer. Addresses asks the solver with - * s_get. If no address is available, it will not send a response, otherwise - * it will respond with the choosen address. - * - * 1.7.5 Address suggestions - * - * Addresses will notify the client automatically on any bandwidth_changed_cb - * by the solver if a address suggestion request is pending. If no address is - * available it will not respond at all If the client is not interested - * anymore, it has to cancel the address suggestion request. - * - * 1.7.6 Address lifecycle - * - * * (add address) - * * (updated address) - * * (delete address) - * - * 1.8 Bandwidth assignment - * - * The addresses are used to perform resource allocation operations. ATS - * addresses takes care of instantiating the solver configured and notifies - * the respective solver about address changes and receives changes to the - * bandwidth assignment from the solver. The current bandwidth assignment is - * sent to transport. The specific solvers will be described in the specific - * section. - * - * 1.9 Changing peer preferences - * - * The bandwidth assigned to a peer can be influenced by setting a preference - * for a peer. The prefernce will be given to to the solver with s_pref which - * has to take care of the preference value - */ - - /** * A multihashmap to store all addresses */ @@ -230,124 +50,6 @@ update_addresses_stat () } -/** - * Disassemble ATS information and update performance information in address - * - * Updates existing information and adds new information - * - * @param dest destination address - * @param update source ATS information - * @param update_count number of ATS information in @a update - * @param delta_dest ats performance information which were updated - * including previous value - * @param delta_count number of ATS information in the @a delta_dest - * @return #GNUNET_YES if address was address updated, GNUNET_NO otherwise - */ -static unsigned int -disassemble_ats_information (struct ATS_Address *dest, - const struct GNUNET_ATS_Information *update, - uint32_t update_count, - struct GNUNET_ATS_Information **delta_dest, - uint32_t *delta_count) -{ - int c1; - int c2; - int found; - int change; - struct GNUNET_ATS_Information add_atsi[update_count]; - struct GNUNET_ATS_Information delta_atsi[update_count]; - struct GNUNET_ATS_Information *tmp_atsi; - uint32_t add_atsi_count; - uint32_t delta_atsi_count; - - change = GNUNET_NO; - add_atsi_count = 0; - delta_atsi_count = 0; - - if (0 == update_count) - return GNUNET_NO; - - if (NULL == dest->atsi) - { - /* Create performance information */ - dest->atsi = - GNUNET_malloc (update_count * sizeof (struct GNUNET_ATS_Information)); - dest->atsi_count = update_count; - memcpy (dest->atsi, - update, - update_count * sizeof(struct GNUNET_ATS_Information)); - *delta_dest = - GNUNET_malloc (update_count * sizeof (struct GNUNET_ATS_Information)); - for (c1 = 0; c1 < update_count; c1++) - { - (*delta_dest)[c1].type = update[c1].type; - (*delta_dest)[c1].value = htonl (GNUNET_ATS_VALUE_UNDEFINED); - } - (*delta_count) = update_count; - return GNUNET_YES; - } - - for (c1 = 0; c1 < update_count; c1++) - { - /* Update existing performance information */ - found = GNUNET_NO; - for (c2 = 0; c2 < dest->atsi_count; c2++) - { - if (update[c1].type == dest->atsi[c2].type) - { - if (update[c1].value != dest->atsi[c2].value) - { - /* Save previous value in delta */ - delta_atsi[delta_atsi_count] = dest->atsi[c2]; - delta_atsi_count++; - /* Set new value */ - dest->atsi[c2].value = update[c1].value; - change = GNUNET_YES; - } - found = GNUNET_YES; - break; - } - } - if (GNUNET_NO == found) - { - add_atsi[add_atsi_count] = update[c1]; - add_atsi_count++; - delta_atsi[delta_atsi_count].type = update[c1].type; - delta_atsi[delta_atsi_count].value = htonl (GNUNET_ATS_VALUE_UNDEFINED); - delta_atsi_count++; - } - } - - if (add_atsi_count > 0) - { - /* Extend ats performance information */ - - tmp_atsi = GNUNET_malloc ((dest->atsi_count + add_atsi_count) * - (sizeof (struct GNUNET_ATS_Information))); - memcpy (tmp_atsi, dest->atsi, - dest->atsi_count * sizeof(struct GNUNET_ATS_Information)); - memcpy (&tmp_atsi[dest->atsi_count], add_atsi, - add_atsi_count * sizeof(struct GNUNET_ATS_Information)); - GNUNET_free (dest->atsi); - dest->atsi = tmp_atsi; - dest->atsi_count = dest->atsi_count + add_atsi_count; - change = GNUNET_YES; - } - - if (delta_atsi_count > 0) - { - /* Copy delta */ - (*delta_dest) = - GNUNET_malloc (delta_atsi_count * sizeof (struct GNUNET_ATS_Information)); - memcpy ((*delta_dest), delta_atsi, - delta_atsi_count * sizeof(struct GNUNET_ATS_Information)); - (*delta_count) = delta_atsi_count; - } - - return change; -} - - /** * Free the given address * @@ -366,15 +68,29 @@ free_address (struct ATS_Address *addr) addr->addr, addr->addr_len, GNUNET_NO, - NULL, 0, + NULL, GNUNET_BANDWIDTH_ZERO, GNUNET_BANDWIDTH_ZERO); GNUNET_free (addr->plugin); - GNUNET_free_non_null (addr->atsi); GNUNET_free (addr); } +/** + * Initialize @a norm. Sets all historic values to undefined. + * + * @param norm normalization data to initialize + */ +static void +init_norm (struct GAS_NormalizationInfo *norm) +{ + unsigned int c; + + for (c = 0; c < GAS_normalization_queue_length; c++) + norm->atsi_abs[c] = UINT64_MAX; +} + + /** * Create a ATS_address with the given information * @@ -395,8 +111,6 @@ create_address (const struct GNUNET_PeerIdentity *peer, uint32_t session_id) { struct ATS_Address *aa; - unsigned int c1; - unsigned int c2; aa = GNUNET_malloc (sizeof (struct ATS_Address) + plugin_addr_len); aa->peer = *peer; @@ -408,14 +122,10 @@ create_address (const struct GNUNET_PeerIdentity *peer, aa->plugin = GNUNET_strdup (plugin_name); aa->session_id = session_id; aa->local_address_info = local_address_info; - - for (c1 = 0; c1 < GNUNET_ATS_QualityPropertiesCount; c1++) - { - aa->atsin[c1].avg_queue_index = 0; - aa->atsin[c1].norm = DEFAULT_REL_QUALITY; - for (c2 = 0; c2 < GAS_normalization_queue_length; c2++) - aa->atsin[c1].atsi_abs[c2] = GNUNET_ATS_VALUE_UNDEFINED; - } + init_norm (&aa->norm_delay); + init_norm (&aa->norm_distance); + init_norm (&aa->norm_utilization_in); + init_norm (&aa->norm_utilization_out); return aa; } @@ -485,31 +195,6 @@ find_exact_address (const struct GNUNET_PeerIdentity *peer, } -/** - * Extract an ATS performance info from an address - * - * @param address the address - * @param type the type to extract in HBO - * @return the value in HBO or #GNUNET_ATS_VALUE_UNDEFINED in HBO if value does not exist - */ -static int -get_performance_info (struct ATS_Address *address, - uint32_t type) -{ - uint32_t c1; - - if ((NULL == address->atsi) || (0 == address->atsi_count)) - return GNUNET_ATS_VALUE_UNDEFINED; - - for (c1 = 0; c1 < address->atsi_count; c1++) - { - if (ntohl (address->atsi[c1].type) == type) - return ntohl (address->atsi[c1].value); - } - return GNUNET_ATS_VALUE_UNDEFINED; -} - - /** * Add a new address for a peer. * @@ -519,8 +204,7 @@ get_performance_info (struct ATS_Address *address, * @param plugin_addr_len length of the plugin address in @a plugin_addr * @param local_address_info the local address for the address * @param session_id session id, can be 0 - * @param atsi performance information for this address - * @param atsi_count number of performance information contained in @a atsi + * @param prop performance information for this address */ void GAS_addresses_add (const struct GNUNET_PeerIdentity *peer, @@ -529,15 +213,12 @@ GAS_addresses_add (const struct GNUNET_PeerIdentity *peer, size_t plugin_addr_len, uint32_t local_address_info, uint32_t session_id, - const struct GNUNET_ATS_Information *atsi, - uint32_t atsi_count) + const struct GNUNET_ATS_Properties *prop) { struct ATS_Address *new_address; - struct GNUNET_ATS_Information *atsi_delta; - uint32_t atsi_delta_count; - uint32_t addr_net; - if (NULL != find_exact_address (peer, session_id)) + if (NULL != find_exact_address (peer, + session_id)) { GNUNET_break (0); return; @@ -548,17 +229,8 @@ GAS_addresses_add (const struct GNUNET_PeerIdentity *peer, plugin_addr_len, local_address_info, session_id); - atsi_delta = NULL; - disassemble_ats_information (new_address, - atsi, atsi_count, - &atsi_delta, - &atsi_delta_count); - GNUNET_free_non_null (atsi_delta); - addr_net = get_performance_info (new_address, GNUNET_ATS_NETWORK_TYPE); - if (GNUNET_ATS_VALUE_UNDEFINED == addr_net) - addr_net = GNUNET_ATS_NET_UNSPECIFIED; - /* Add a new address */ + new_address->properties = *prop; new_address->t_added = GNUNET_TIME_absolute_get(); new_address->t_last_activity = GNUNET_TIME_absolute_get(); GNUNET_assert(GNUNET_OK == @@ -573,11 +245,8 @@ GAS_addresses_add (const struct GNUNET_PeerIdentity *peer, session_id); /* Tell solver about new address */ GAS_plugin_solver_lock (); - GAS_plugin_new_address (new_address, - addr_net); - GAS_normalization_update_property (new_address, - atsi, - atsi_count); + GAS_plugin_new_address (new_address); + GAS_normalization_update_property (new_address); // FIXME: needed? GAS_plugin_solver_unlock (); /* Notify performance clients about new address */ GAS_performance_notify_all_clients (&new_address->peer, @@ -585,8 +254,7 @@ GAS_addresses_add (const struct GNUNET_PeerIdentity *peer, new_address->addr, new_address->addr_len, new_address->active, - new_address->atsi, - new_address->atsi_count, + &new_address->properties, GNUNET_BANDWIDTH_value_init (new_address->assigned_bw_out), GNUNET_BANDWIDTH_value_init (new_address->assigned_bw_in)); } @@ -597,18 +265,14 @@ GAS_addresses_add (const struct GNUNET_PeerIdentity *peer, * * @param peer peer * @param session_id session id, never 0 - * @param atsi performance information for this address - * @param atsi_count number of performance information contained in @a atsi + * @param prop performance information for this address */ void GAS_addresses_update (const struct GNUNET_PeerIdentity *peer, uint32_t session_id, - const struct GNUNET_ATS_Information *atsi, - uint32_t atsi_count) + const struct GNUNET_ATS_Properties *prop) { struct ATS_Address *aa; - struct GNUNET_ATS_Information *atsi_delta; - uint32_t atsi_delta_count; /* Get existing address */ aa = find_exact_address (peer, @@ -630,30 +294,18 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer, /* Update address */ aa->t_last_activity = GNUNET_TIME_absolute_get(); - atsi_delta = NULL; - atsi_delta_count = 0; - if (GNUNET_YES == - disassemble_ats_information (aa, atsi, - atsi_count, - &atsi_delta, - &atsi_delta_count)) - { - /* Notify performance clients about updated address */ - GAS_performance_notify_all_clients (&aa->peer, - aa->plugin, - aa->addr, - aa->addr_len, - aa->active, - aa->atsi, - aa->atsi_count, - GNUNET_BANDWIDTH_value_init (aa->assigned_bw_out), - GNUNET_BANDWIDTH_value_init (aa->assigned_bw_in)); - - GAS_normalization_update_property (aa, - atsi, - atsi_count); - } - GNUNET_free_non_null (atsi_delta); + aa->properties = *prop; + /* Notify performance clients about updated address */ + GAS_performance_notify_all_clients (&aa->peer, + aa->plugin, + aa->addr, + aa->addr_len, + aa->active, + prop, + GNUNET_BANDWIDTH_value_init (aa->assigned_bw_out), + GNUNET_BANDWIDTH_value_init (aa->assigned_bw_in)); + + GAS_normalization_update_property (aa); } @@ -793,7 +445,7 @@ peerinfo_it (void *cls, addr->addr, addr->addr_len, addr->active, - addr->atsi, addr->atsi_count, + &addr->properties, GNUNET_BANDWIDTH_value_init (addr->assigned_bw_out), GNUNET_BANDWIDTH_value_init (addr->assigned_bw_in)); return GNUNET_OK; @@ -839,7 +491,7 @@ GAS_addresses_get_peer_info (const struct GNUNET_PeerIdentity *peer, pi_it (pi_it_cls, NULL, NULL, NULL, 0, GNUNET_NO, - NULL, 0, + NULL, GNUNET_BANDWIDTH_ZERO, GNUNET_BANDWIDTH_ZERO); } @@ -879,8 +531,7 @@ struct AddressIteration * @param plugin_addr address * @param plugin_addr_len length of @a plugin_addr * @param active #GNUNET_YES if this address is actively used - * @param atsi ats performance information - * @param atsi_count number of ats performance elements in @a atsi + * @param prop performance information * @param bandwidth_out current outbound bandwidth assigned to address * @param bandwidth_in current inbound bandwidth assigned to address */ @@ -891,13 +542,11 @@ transmit_req_addr (struct AddressIteration *ai, const void *plugin_addr, size_t plugin_addr_len, int active, - const struct GNUNET_ATS_Information *atsi, - uint32_t atsi_count, + const struct GNUNET_ATS_Properties *prop, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in) { - struct GNUNET_ATS_Information *atsp; struct PeerInformationMessage *msg; char *addrp; size_t plugin_name_length; @@ -909,18 +558,13 @@ transmit_req_addr (struct AddressIteration *ai, else plugin_name_length = 0; msize = sizeof (struct PeerInformationMessage) + - atsi_count * sizeof (struct GNUNET_ATS_Information) + plugin_addr_len + plugin_name_length; char buf[msize] GNUNET_ALIGN; GNUNET_assert (msize < GNUNET_SERVER_MAX_MESSAGE_SIZE); - GNUNET_assert (atsi_count < - GNUNET_SERVER_MAX_MESSAGE_SIZE / - sizeof (struct GNUNET_ATS_Information)); msg = (struct PeerInformationMessage *) buf; msg->header.size = htons (msize); msg->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_ADDRESSLIST_RESPONSE); - msg->ats_count = htonl (atsi_count); msg->id = htonl (ai->id); if (NULL != id) msg->peer = *id; @@ -931,9 +575,9 @@ transmit_req_addr (struct AddressIteration *ai, msg->plugin_name_length = htons (plugin_name_length); msg->bandwidth_out = bandwidth_out; msg->bandwidth_in = bandwidth_in; - atsp = (struct GNUNET_ATS_Information *) &msg[1]; - memcpy (atsp, atsi, sizeof (struct GNUNET_ATS_Information) * atsi_count); - addrp = (char *) &atsp[atsi_count]; + GNUNET_ATS_properties_hton (&msg->properties, + prop); + addrp = (char *) &msg[1]; if (NULL != plugin_addr) memcpy (addrp, plugin_addr, plugin_addr_len); if (NULL != plugin_name) @@ -962,8 +606,7 @@ transmit_req_addr (struct AddressIteration *ai, * @param plugin_addr address * @param plugin_addr_len length of @a plugin_addr * @param active is address actively used - * @param atsi ats performance information - * @param atsi_count number of ats performance elements in @a atsi + * @param prop performance information * @param bandwidth_out current outbound bandwidth assigned to address * @param bandwidth_in current inbound bandwidth assigned to address */ @@ -974,8 +617,7 @@ req_addr_peerinfo_it (void *cls, const void *plugin_addr, size_t plugin_addr_len, int active, - const struct GNUNET_ATS_Information *atsi, - uint32_t atsi_count, + const struct GNUNET_ATS_Properties *prop, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in) { @@ -1006,8 +648,7 @@ req_addr_peerinfo_it (void *cls, plugin_name, plugin_addr, plugin_addr_len, active, - atsi, - atsi_count, + prop, bandwidth_out, bandwidth_in); } @@ -1061,7 +702,7 @@ GAS_handle_request_address_list (void *cls, transmit_req_addr (&ai, NULL, NULL, NULL, 0, GNUNET_NO, - NULL, 0, + NULL, GNUNET_BANDWIDTH_ZERO, GNUNET_BANDWIDTH_ZERO); GNUNET_SERVER_receive_done (client, diff --git a/src/ats/gnunet-service-ats_addresses.h b/src/ats/gnunet-service-ats_addresses.h index 2be8277e1..072a3d078 100644 --- a/src/ats/gnunet-service-ats_addresses.h +++ b/src/ats/gnunet-service-ats_addresses.h @@ -235,12 +235,12 @@ struct GAS_NormalizationInfo /** * Averaging queue */ - uint32_t atsi_abs[GAS_normalization_queue_length]; + uint64_t atsi_abs[GAS_normalization_queue_length]; /** * Averaged ATSI values from queue */ - uint32_t avg; + uint64_t avg; /** * Normalized values from queue to a range of values [1.0...2.0] @@ -277,7 +277,7 @@ struct ATS_Address /** * ATS performance information for this address */ - struct GNUNET_ATS_Information *atsi; + struct GNUNET_ATS_Properties properties; /** * Time when address had last activity (update, in uses) @@ -336,10 +336,25 @@ struct ATS_Address int active; /** - * Normalized ATS performance information for this address - * Each entry can be accessed using the GNUNET_ATS_QualityProperties avg_queue_index + * Normalized delay information for this address. */ - struct GAS_NormalizationInfo atsin[GNUNET_ATS_QualityPropertiesCount]; + struct GAS_NormalizationInfo norm_delay; + + /** + * Normalized distance information for this address. + */ + struct GAS_NormalizationInfo norm_distance; + + /** + * Normalized utilization inbound for this address. + */ + struct GAS_NormalizationInfo norm_utilization_in; + + /** + * Normalized utilization outbound for this address. + */ + struct GAS_NormalizationInfo norm_utilization_out; + }; @@ -375,8 +390,7 @@ GAS_addresses_done (void); * @param plugin_addr_len length of the @a plugin_addr * @param local_address_info the local address for the address * @param session_id session id, can never be 0. - * @param atsi performance information for this address - * @param atsi_count number of performance information contained in @a atsi + * @param prop performance information for this address */ void GAS_addresses_add (const struct GNUNET_PeerIdentity *peer, @@ -385,8 +399,7 @@ GAS_addresses_add (const struct GNUNET_PeerIdentity *peer, size_t plugin_addr_len, uint32_t local_address_info, uint32_t session_id, - const struct GNUNET_ATS_Information *atsi, - uint32_t atsi_count); + const struct GNUNET_ATS_Properties *prop); /** @@ -394,14 +407,12 @@ GAS_addresses_add (const struct GNUNET_PeerIdentity *peer, * * @param peer peer * @param session_id session id, can never be 0 - * @param atsi performance information for this address - * @param atsi_count number of performance information contained in @a atsi + * @param prop performance information for this address */ void GAS_addresses_update (const struct GNUNET_PeerIdentity *peer, uint32_t session_id, - const struct GNUNET_ATS_Information *atsi, - uint32_t atsi_count); + const struct GNUNET_ATS_Properties *prop); /** @@ -432,7 +443,6 @@ GAS_addresses_destroy_all (void); * @param plugin_addr_len length of @a plugin_addr * @param address_active is address actively used * @param atsi ats performance information - * @param atsi_count number of ats performance elements in @a atsi * @param bandwidth_out current outbound bandwidth assigned to address * @param bandwidth_in current inbound bandwidth assigned to address */ @@ -443,8 +453,7 @@ typedef void const void *plugin_addr, size_t plugin_addr_len, const int address_active, - const struct GNUNET_ATS_Information *atsi, - uint32_t atsi_count, + const struct GNUNET_ATS_Properties *prop, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in); diff --git a/src/ats/gnunet-service-ats_normalization.c b/src/ats/gnunet-service-ats_normalization.c index 936f8ca34..c10e5070f 100644 --- a/src/ats/gnunet-service-ats_normalization.c +++ b/src/ats/gnunet-service-ats_normalization.c @@ -37,103 +37,65 @@ /** * Range information for normalization of quality properties. */ -struct Property +struct PropertyRange { - /** - * Index into the properties array. - */ - uint32_t prop_type; - - /** - * Corresponding enum value of the respective quality property. - */ - enum GNUNET_ATS_Property atsi_type; - /** * Minimum value we see for this property across all addresses. */ - uint32_t min; + struct GNUNET_ATS_Properties min; /** * Maximum value we see for this property across all addresses. */ - uint32_t max; + struct GNUNET_ATS_Properties max; }; /** * Range information for all quality properties we see. */ -static struct Property properties[GNUNET_ATS_QualityPropertiesCount]; - +static struct PropertyRange property_range; /** * Add the value from @a atsi to the running average of the * given @a ni quality property. * + * @param current_val the updated value * @param ni normalization information to update - * @param atsi the ats information */ static void -property_average (struct GAS_NormalizationInfo *ni, - const struct GNUNET_ATS_Information *atsi) +update_avg (uint64_t current_val, + struct GAS_NormalizationInfo *ni) { - uint32_t current_val; - uint32_t res; - uint64_t sum; + double sum; uint32_t count; unsigned int c1; - current_val = ntohl (atsi->value); - GNUNET_assert (GNUNET_ATS_VALUE_UNDEFINED != current_val); ni->atsi_abs[ni->avg_queue_index++] = current_val; if (GAS_normalization_queue_length == ni->avg_queue_index) ni->avg_queue_index = 0; count = 0; - sum = 0; + sum = 0.0; for (c1 = 0; c1 < GAS_normalization_queue_length; c1++) { - if (GNUNET_ATS_VALUE_UNDEFINED != ni->atsi_abs[c1]) + if (UINT64_MAX != ni->atsi_abs[c1]) { count++; - sum += ni->atsi_abs[c1]; + sum += (double) ni->atsi_abs[c1]; } } GNUNET_assert (0 != count); - res = sum / count; - ni->avg = res; + ni->avg = sum / count; } -/** - * Closure for #find_min_max_it(). - */ -struct FindMinMaxCtx -{ - /** - * Property we are looking for. - */ - struct Property *p; - - /** - * Set to mimimum value observed. - */ - uint32_t min; - - /** - * Set to maximum value observed. - */ - uint32_t max; -}; - - /** * Function called for all addresses and peers to find the minimum and * maximum (averaged) values for a given quality property. Given * those, we can then calculate the normalized score. * - * @param cls the `struct FindMinMaxCtx` + * @param cls the `struct PropertyRange` * @param h which peer are we looking at (ignored) * @param k the address for that peer * @return #GNUNET_OK (continue to iterate) @@ -143,23 +105,55 @@ find_min_max_it (void *cls, const struct GNUNET_PeerIdentity *h, void *k) { - struct FindMinMaxCtx *find_res = cls; + struct PropertyRange *pr = cls; const struct ATS_Address *a = k; - find_res->max = GNUNET_MAX (find_res->max, - a->atsin[find_res->p->prop_type].avg); - find_res->min = GNUNET_MIN (find_res->min, - a->atsin[find_res->p->prop_type].avg); + pr->max.utilization_out = GNUNET_MAX (pr->max.utilization_out, + a->properties.utilization_out); + pr->max.utilization_in = GNUNET_MAX (pr->max.utilization_in, + a->properties.utilization_in); + pr->max.distance = GNUNET_MAX (pr->max.distance, + a->properties.distance); + pr->max.delay = GNUNET_TIME_relative_max (pr->max.delay, + a->properties.delay); + pr->min.utilization_out = GNUNET_MIN (pr->min.utilization_out, + a->properties.utilization_out); + pr->min.utilization_in = GNUNET_MIN (pr->min.utilization_in, + a->properties.utilization_in); + pr->min.distance = GNUNET_MIN (pr->min.distance, + a->properties.distance); + pr->min.delay = GNUNET_TIME_relative_min (pr->min.delay, + a->properties.delay); return GNUNET_OK; } +/** + * Compute the normalized value from the given @a ni range + * data and the average value. + * + * @param min minimum value + * @param max maximum value + * @param ni normalization information to update + */ +static void +update_norm (uint64_t min, + uint64_t max, + struct GAS_NormalizationInfo *ni) +{ + /* max - 2 * min + avg_value / (max - min) */ + if (min < max) + ni->norm = DEFAULT_REL_QUALITY + (ni->avg - min) / (double) (max - min); + else + ni->norm = DEFAULT_REL_QUALITY; +} + + /** * Normalize the property value for a given address based - * on the range we know that property value has globally. + * on the range we know that property values have globally. * - * @param cls the `struct Property` with details on the - * property and its global range + * @param cls NULL * @param key which peer are we looking at (ignored) * @param value the address for that peer, from where we get * the original value and where we write the @@ -171,33 +165,20 @@ normalize_address (void *cls, const struct GNUNET_PeerIdentity *key, void *value) { - struct Property *p = cls; struct ATS_Address *address = value; - double delta; - double update; - uint32_t avg_value; - - avg_value = address->atsin[p->prop_type].avg; - delta = p->max - p->min; - /* max - 2 * min + avg_value / (max - min) */ - if (delta > DBL_EPSILON) - update = DEFAULT_REL_QUALITY + (avg_value - p->min) / delta; - else - update = DEFAULT_REL_QUALITY; - if (update == address->atsin[p->prop_type].norm) - return GNUNET_OK; - address->atsin[p->prop_type].norm = update; - - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Normalize `%s' address %p's '%s' with value %u to range [%u..%u] = %.3f\n", - GNUNET_i2s (&address->peer), - address, - GNUNET_ATS_print_property_type (p->atsi_type), - address->atsin[p->prop_type].avg, - p->min, - p->max, - address->atsin[p->prop_type].norm); + update_norm (property_range.min.delay.rel_value_us, + property_range.max.delay.rel_value_us, + &address->norm_delay); + update_norm (property_range.min.distance, + property_range.max.distance, + &address->norm_distance); + update_norm (property_range.min.utilization_in, + property_range.max.utilization_in, + &address->norm_utilization_in); + update_norm (property_range.min.utilization_out, + property_range.max.utilization_out, + &address->norm_utilization_out); return GNUNET_OK; } @@ -205,8 +186,7 @@ normalize_address (void *cls, /** * Notify about change in normalized property. * - * @param cls the `struct Property` with details on the - * property and its global range + * @param cls NULL * @param key which peer are we looking at (ignored) * @param value the address for that peer * @return #GNUNET_OK (continue to iterate) @@ -216,104 +196,84 @@ notify_change (void *cls, const struct GNUNET_PeerIdentity *key, void *value) { - struct Property *p = cls; struct ATS_Address *address = value; - GAS_plugin_notify_property_changed (address, - p->atsi_type, - address->atsin[p->prop_type].norm); + GAS_plugin_notify_property_changed (address); return GNUNET_OK; } +/** + * Initialize property range to the values corresponding + * to an empty set. + * + * @param pr range to initialize + */ +static void +init_range (struct PropertyRange *pr) +{ + memset (pr, 0, sizeof (struct PropertyRange)); + pr->min.utilization_out = UINT32_MAX; + pr->min.utilization_in = UINT32_MAX; + pr->min.distance = UINT32_MAX; + pr->min.delay = GNUNET_TIME_UNIT_FOREVER_REL; +} + + /** * Update and normalize atsi performance information * * @param address the address to update - * @param atsi the array of performance information - * @param atsi_count the number of atsi information in the array */ void -GAS_normalization_update_property (struct ATS_Address *address, - const struct GNUNET_ATS_Information *atsi, - uint32_t atsi_count) +GAS_normalization_update_property (struct ATS_Address *address) { - unsigned int c1; - unsigned int c2; - uint32_t current_type; - uint32_t old; - struct FindMinMaxCtx find_ctx; + const struct GNUNET_ATS_Properties *prop = &address->properties; + struct PropertyRange range; int range_changed; LOG (GNUNET_ERROR_TYPE_DEBUG, - "Updating %u elements for peer `%s'\n", - atsi_count, + "Updating properties for peer `%s'\n", GNUNET_i2s (&address->peer)); GAS_plugin_solver_lock (); - for (c1 = 0; c1 < atsi_count; c1++) + update_avg (prop->delay.rel_value_us, + &address->norm_delay); + update_avg (prop->distance, + &address->norm_distance); + update_avg (prop->utilization_in, + &address->norm_utilization_in); + update_avg (prop->utilization_in, + &address->norm_utilization_out); + + init_range (&range); + GNUNET_CONTAINER_multipeermap_iterate (GSA_addresses, + &find_min_max_it, + &range); + if (0 != memcmp (&range, + &property_range, + sizeof (struct PropertyRange))) { - current_type = ntohl (atsi[c1].type); - - for (c2 = 0; c2 < GNUNET_ATS_QualityPropertiesCount; c2++) - if (current_type == properties[c2].atsi_type) - break; - if (GNUNET_ATS_QualityPropertiesCount == c2) - { - /* Not a quality property, continue with next element */ - continue; - } - /* Calculate running average */ - old = address->atsin[c2].avg; - property_average (&address->atsin[c2], - &atsi[c1]); - if (old == address->atsin[c2].avg) - continue; /* no change */ - range_changed = GNUNET_NO; - if ( (old == properties[c2].min) || - (old == properties[c2].max) || - (address->atsin[c2].avg < properties[c2].min) || - (address->atsin[c2].avg > properties[c2].max) ) - { - /* need to re-calculate min/max range, as it may have changed */ - find_ctx.p = &properties[c2]; - find_ctx.max = 0; - find_ctx.min = UINT32_MAX; - if (0 == - GNUNET_CONTAINER_multipeermap_iterate (GSA_addresses, - &find_min_max_it, - &find_ctx)) - { - GNUNET_break(0); - continue; - } - if ( (find_ctx.min != properties[c2].min) || - (find_ctx.max != properties[c2].max) ) - { - properties[c2].min = find_ctx.min; - properties[c2].max = find_ctx.max; - /* limits changed, (re)normalize all addresses */ - range_changed = GNUNET_YES; - } - } - if (GNUNET_YES == range_changed) - GNUNET_CONTAINER_multipeermap_iterate (GSA_addresses, - &normalize_address, - &properties[c2]); - else - normalize_address (&properties[c2], - &address->peer, - address); - /* after all peers have been updated, notify about changes */ - if (GNUNET_YES == range_changed) - GNUNET_CONTAINER_multipeermap_iterate (GSA_addresses, - ¬ify_change, - &properties[c2]); - else - notify_change (&properties[c2], - &address->peer, - address); - + /* limits changed, (re)normalize all addresses */ + property_range = range; + range_changed = GNUNET_YES; } + if (GNUNET_YES == range_changed) + GNUNET_CONTAINER_multipeermap_iterate (GSA_addresses, + &normalize_address, + NULL); + else + normalize_address (NULL, + &address->peer, + address); + /* after all peers have been updated, notify about changes */ + if (GNUNET_YES == range_changed) + GNUNET_CONTAINER_multipeermap_iterate (GSA_addresses, + ¬ify_change, + NULL); + else + notify_change (NULL, + &address->peer, + address); GAS_plugin_solver_unlock (); } @@ -324,16 +284,7 @@ GAS_normalization_update_property (struct ATS_Address *address, void GAS_normalization_start () { - unsigned int c1; - const unsigned int existing_properties[] = GNUNET_ATS_QualityProperties; - - for (c1 = 0; c1 < GNUNET_ATS_QualityPropertiesCount; c1++) - { - properties[c1].prop_type = c1; - properties[c1].atsi_type = existing_properties[c1]; - properties[c1].min = UINT32_MAX; - properties[c1].max = 0; - } + init_range (&property_range); } diff --git a/src/ats/gnunet-service-ats_normalization.h b/src/ats/gnunet-service-ats_normalization.h index 2ce9d726f..2a9f68b60 100644 --- a/src/ats/gnunet-service-ats_normalization.h +++ b/src/ats/gnunet-service-ats_normalization.h @@ -35,16 +35,12 @@ /** - * Update and normalize a @a atsi performance information + * Update and normalize a @a prop performance information * * @param address the address to update - * @param atsi the array of performance information - * @param atsi_count the number of atsi information in the array */ void -GAS_normalization_update_property (struct ATS_Address *address, - const struct GNUNET_ATS_Information *atsi, - uint32_t atsi_count); +GAS_normalization_update_property (struct ATS_Address *address); /** diff --git a/src/ats/gnunet-service-ats_performance.c b/src/ats/gnunet-service-ats_performance.c index 0f17f0bec..c3d9e78eb 100644 --- a/src/ats/gnunet-service-ats_performance.c +++ b/src/ats/gnunet-service-ats_performance.c @@ -54,8 +54,7 @@ static struct GNUNET_SERVER_NotificationContext *nc_pic; * to maintain a connection to a peer; * #GNUNET_NO if the address is not actively used; * #GNUNET_SYSERR if this address is no longer available for ATS - * @param atsi performance data for the address - * @param atsi_count number of performance records in @a atsi + * @param prop performance data for the address * @param bandwidth_out assigned outbound bandwidth * @param bandwidth_in assigned inbound bandwidth */ @@ -66,40 +65,34 @@ notify_client (struct GNUNET_SERVER_Client *client, const void *plugin_addr, size_t plugin_addr_len, int active, - const struct GNUNET_ATS_Information *atsi, - uint32_t atsi_count, + const struct GNUNET_ATS_Properties *prop, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in) { struct PeerInformationMessage *msg; size_t plugin_name_length = strlen (plugin_name) + 1; size_t msize = - sizeof (struct PeerInformationMessage) + - atsi_count * sizeof (struct GNUNET_ATS_Information) + plugin_addr_len + - plugin_name_length; + sizeof (struct PeerInformationMessage) + + plugin_addr_len + + plugin_name_length; char buf[msize] GNUNET_ALIGN; - struct GNUNET_ATS_Information *atsp; struct GNUNET_SERVER_NotificationContext *nc; char *addrp; GNUNET_assert (msize < GNUNET_SERVER_MAX_MESSAGE_SIZE); - GNUNET_assert (atsi_count < - GNUNET_SERVER_MAX_MESSAGE_SIZE / - sizeof (struct GNUNET_ATS_Information)); msg = (struct PeerInformationMessage *) buf; msg->header.size = htons (msize); msg->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_PEER_INFORMATION); msg->id = htonl (0); - msg->ats_count = htonl (atsi_count); msg->peer = *peer; msg->address_length = htons (plugin_addr_len); msg->address_active = ntohl ((uint32_t) active); msg->plugin_name_length = htons (plugin_name_length); msg->bandwidth_out = bandwidth_out; msg->bandwidth_in = bandwidth_in; - atsp = (struct GNUNET_ATS_Information *) &msg[1]; - memcpy (atsp, atsi, sizeof (struct GNUNET_ATS_Information) * atsi_count); - addrp = (char *) &atsp[atsi_count]; + GNUNET_ATS_properties_hton (&msg->properties, + prop); + addrp = (char *) &msg[1]; memcpy (addrp, plugin_addr, plugin_addr_len); strcpy (&addrp[plugin_addr_len], plugin_name); if (NULL == client) @@ -137,8 +130,7 @@ notify_client (struct GNUNET_SERVER_Client *client, * to maintain a connection to a peer; * #GNUNET_NO if the address is not actively used; * #GNUNET_SYSERR if this address is no longer available for ATS - * @param atsi performance data for the address - * @param atsi_count number of performance records in @a atsi + * @param prop performance data for the address * @param bandwidth_out assigned outbound bandwidth * @param bandwidth_in assigned inbound bandwidth */ @@ -148,8 +140,7 @@ GAS_performance_notify_all_clients (const struct GNUNET_PeerIdentity *peer, const void *plugin_addr, size_t plugin_addr_len, int active, - const struct GNUNET_ATS_Information *atsi, - uint32_t atsi_count, + const struct GNUNET_ATS_Properties *prop, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in) { @@ -159,7 +150,7 @@ GAS_performance_notify_all_clients (const struct GNUNET_PeerIdentity *peer, plugin_addr, plugin_addr_len, active, - atsi, atsi_count, + prop, bandwidth_out, bandwidth_in); GNUNET_STATISTICS_update (GSA_stats, @@ -178,8 +169,7 @@ GAS_performance_notify_all_clients (const struct GNUNET_PeerIdentity *peer, * @param plugin_addr address * @param plugin_addr_len length of @a plugin_addr * @param active is address actively used - * @param atsi ats performance information - * @param atsi_count number of ats performance elements in @a atsi + * @param prop performance information * @param bandwidth_out current outbound bandwidth assigned to address * @param bandwidth_in current inbound bandwidth assigned to address */ @@ -190,8 +180,7 @@ peerinfo_it (void *cls, const void *plugin_addr, size_t plugin_addr_len, int active, - const struct GNUNET_ATS_Information *atsi, - uint32_t atsi_count, + const struct GNUNET_ATS_Properties *prop, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in) { @@ -211,7 +200,7 @@ peerinfo_it (void *cls, plugin_addr, plugin_addr_len, active, - atsi, atsi_count, + prop, bandwidth_out, bandwidth_in); } diff --git a/src/ats/gnunet-service-ats_performance.h b/src/ats/gnunet-service-ats_performance.h index 87712552f..abdeb975f 100644 --- a/src/ats/gnunet-service-ats_performance.h +++ b/src/ats/gnunet-service-ats_performance.h @@ -44,8 +44,7 @@ * to maintain a connection to a peer; * #GNUNET_NO if the address is not actively used; * #GNUNET_SYSERR if this address is no longer available for ATS - * @param atsi performance data for the address - * @param atsi_count number of performance records in @a atsi + * @param prop performance data for the address * @param bandwidth_out assigned outbound bandwidth * @param bandwidth_in assigned inbound bandwidth */ @@ -55,8 +54,7 @@ GAS_performance_notify_all_clients (const struct GNUNET_PeerIdentity *peer, const void *plugin_addr, size_t plugin_addr_len, int active, - const struct GNUNET_ATS_Information *atsi, - uint32_t atsi_count, + const struct GNUNET_ATS_Properties *prop, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in); diff --git a/src/ats/gnunet-service-ats_plugins.c b/src/ats/gnunet-service-ats_plugins.c index fbc047a33..b0bbb910b 100644 --- a/src/ats/gnunet-service-ats_plugins.c +++ b/src/ats/gnunet-service-ats_plugins.c @@ -70,22 +70,15 @@ GAS_plugin_notify_preference_changed (const struct GNUNET_PeerIdentity *peer, /** - * The relative value for a property changed + * The relative value for a property changed. * - * @param address the peer - * @param type the ATS type - * @param prop_rel the new relative preference value + * @param address the peer for which a property changed */ void -GAS_plugin_notify_property_changed (struct ATS_Address *address, - enum GNUNET_ATS_Property type, - double prop_rel) +GAS_plugin_notify_property_changed (struct ATS_Address *address) { sf->s_address_update_property (sf->cls, - address, - type, - 0, - prop_rel); + address); } @@ -221,8 +214,7 @@ bandwidth_changed_cb (void *cls, address->addr, address->addr_len, address->active, - address->atsi, - address->atsi_count, + &address->properties, GNUNET_BANDWIDTH_value_init (address->assigned_bw_out), GNUNET_BANDWIDTH_value_init (address->assigned_bw_in)); @@ -481,15 +473,13 @@ GAS_plugin_done () * for talking to the respective peer. * * @param new_address the new address - * @param addr_net network scope the address is in */ void -GAS_plugin_new_address (struct ATS_Address *new_address, - enum GNUNET_ATS_Network_Type addr_net) +GAS_plugin_new_address (struct ATS_Address *new_address) { sf->s_add (sf->cls, new_address, - addr_net); + new_address->properties.scope); /* FIXME: remove 3rd arg here! */ } diff --git a/src/ats/gnunet-service-ats_plugins.h b/src/ats/gnunet-service-ats_plugins.h index 7d76f6431..66eafa4c8 100644 --- a/src/ats/gnunet-service-ats_plugins.h +++ b/src/ats/gnunet-service-ats_plugins.h @@ -65,16 +65,12 @@ GAS_plugin_notify_preference_changed (const struct GNUNET_PeerIdentity *peer, /** - * The relative value for a property changed + * The relative value for a property changed. * * @param address the peer - * @param type the ATS type - * @param prop_rel the new relative property value */ void -GAS_plugin_notify_property_changed (struct ATS_Address *address, - enum GNUNET_ATS_Property type, - double prop_rel); +GAS_plugin_notify_property_changed (struct ATS_Address *address); /** @@ -85,8 +81,7 @@ GAS_plugin_notify_property_changed (struct ATS_Address *address, * @param addr_net network scope the address is in */ void -GAS_plugin_new_address (struct ATS_Address *new_address, - enum GNUNET_ATS_Network_Type addr_net); +GAS_plugin_new_address (struct ATS_Address *new_address); /** diff --git a/src/ats/gnunet-service-ats_preferences.c b/src/ats/gnunet-service-ats_preferences.c index 3be6d3525..8c0b13ab0 100644 --- a/src/ats/gnunet-service-ats_preferences.c +++ b/src/ats/gnunet-service-ats_preferences.c @@ -62,7 +62,7 @@ struct PeerRelative * Array of relative preference values, to be indexed by * an `enum GNUNET_ATS_PreferenceKind`. */ - double f_rel[GNUNET_ATS_PreferenceCount]; + double f_rel[GNUNET_ATS_PREFERENCE_END]; /** * Number of clients that are expressing a preference for @@ -99,14 +99,14 @@ struct PreferencePeer * Absolute preference values for all preference types * as expressed by this client for this peer. */ - double f_abs[GNUNET_ATS_PreferenceCount]; + double f_abs[GNUNET_ATS_PREFERENCE_END]; /** * Relative preference values for all preference types, * normalized in [0..1] based on how the respective * client scored other peers. */ - double f_rel[GNUNET_ATS_PreferenceCount]; + double f_rel[GNUNET_ATS_PREFERENCE_END]; }; @@ -144,7 +144,7 @@ struct PreferenceClient * Array of sums of absolute preferences for all * peers as expressed by this client. */ - double f_abs_sum[GNUNET_ATS_PreferenceCount]; + double f_abs_sum[GNUNET_ATS_PREFERENCE_END]; }; @@ -353,7 +353,7 @@ age_values (void *cls, int dead; dead = GNUNET_YES; - for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) + for (i = 0; i < GNUNET_ATS_PREFERENCE_END; i++) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Aging preference for peer `%s'\n", @@ -563,7 +563,7 @@ update_preference (struct GNUNET_SERVER_Client *client, struct PeerRelative *r_cur; unsigned int i; - if (kind >= GNUNET_ATS_PreferenceCount) + if (kind >= GNUNET_ATS_PREFERENCE_END) { GNUNET_break(0); return; @@ -584,7 +584,7 @@ update_preference (struct GNUNET_SERVER_Client *client, c_cur = GNUNET_new (struct PreferenceClient); c_cur->peer2pref = GNUNET_CONTAINER_multipeermap_create (16, GNUNET_NO); - for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) + for (i = 0; i < GNUNET_ATS_PREFERENCE_END; i++) c_cur->f_abs_sum[i] = DEFAULT_ABS_PREFERENCE; GNUNET_CONTAINER_DLL_insert (pc_head, pc_tail, @@ -598,7 +598,7 @@ update_preference (struct GNUNET_SERVER_Client *client, { /* Create struct for peer */ r_cur = GNUNET_new (struct PeerRelative); - for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) + for (i = 0; i < GNUNET_ATS_PREFERENCE_END; i++) r_cur->f_rel[i] = DEFAULT_REL_PREFERENCE; GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multipeermap_put (preference_peers, @@ -614,7 +614,7 @@ update_preference (struct GNUNET_SERVER_Client *client, { /* Not found: create new peer entry */ p_cur = GNUNET_new (struct PreferencePeer); - for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) + for (i = 0; i < GNUNET_ATS_PREFERENCE_END; i++) { /* Default value per peer absolute preference for a preference*/ p_cur->f_abs[i] = DEFAULT_ABS_PREFERENCE; @@ -710,7 +710,7 @@ GAS_preference_init () preference_peers = GNUNET_CONTAINER_multipeermap_create (16, GNUNET_NO); - for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) + for (i = 0; i < GNUNET_ATS_PREFERENCE_END; i++) defvalues.f_rel[i] = DEFAULT_REL_PREFERENCE; } diff --git a/src/ats/gnunet-service-ats_scheduling.c b/src/ats/gnunet-service-ats_scheduling.c index 74b83bf45..c5539897b 100644 --- a/src/ats/gnunet-service-ats_scheduling.c +++ b/src/ats/gnunet-service-ats_scheduling.c @@ -135,13 +135,12 @@ GAS_handle_address_add (void *cls, const struct GNUNET_MessageHeader *message) { const struct AddressAddMessage *m; - const struct GNUNET_ATS_Information *atsi; const char *address; const char *plugin_name; uint16_t address_length; uint16_t plugin_name_length; - uint32_t ats_count; uint16_t size; + struct GNUNET_ATS_Properties prop; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", @@ -154,38 +153,38 @@ GAS_handle_address_add (void *cls, return; } m = (const struct AddressAddMessage *) message; - ats_count = ntohl (m->ats_count); address_length = ntohs (m->address_length); plugin_name_length = ntohs (m->plugin_name_length); - atsi = (const struct GNUNET_ATS_Information *) &m[1]; - address = (const char *) &atsi[ats_count]; + address = (const char *) &m[1]; if (plugin_name_length != 0) plugin_name = &address[address_length]; else plugin_name = ""; if ((address_length + plugin_name_length + - ats_count * sizeof (struct GNUNET_ATS_Information) + sizeof (struct AddressAddMessage) != ntohs (message->size)) || - (ats_count > - GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_ATS_Information)) || - ((plugin_name_length > 0) && (plugin_name[plugin_name_length - 1] != '\0'))) + ( (plugin_name_length > 0) && + (plugin_name[plugin_name_length - 1] != '\0') ) ) { GNUNET_break (0); GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } GNUNET_STATISTICS_update (GSA_stats, - "# addresses created", 1, + "# addresses created", + 1, GNUNET_NO); + GNUNET_ATS_properties_ntoh (&prop, + &m->properties); GAS_addresses_add (&m->peer, plugin_name, address, address_length, ntohl (m->address_local_info), ntohl (m->session_id), - atsi, ats_count); - GNUNET_SERVER_receive_done (client, GNUNET_OK); + &prop); + GNUNET_SERVER_receive_done (client, + GNUNET_OK); } @@ -202,38 +201,20 @@ GAS_handle_address_update (void *cls, const struct GNUNET_MessageHeader *message) { const struct AddressUpdateMessage *m; - const struct GNUNET_ATS_Information *atsi; - uint32_t ats_count; - uint16_t size; + struct GNUNET_ATS_Properties prop; - size = ntohs (message->size); - if (size < sizeof (struct AddressUpdateMessage)) - { - GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; - } m = (const struct AddressUpdateMessage *) message; - ats_count = ntohl (m->ats_count); - atsi = (const struct GNUNET_ATS_Information *) &m[1]; - - if ((ats_count * sizeof (struct GNUNET_ATS_Information) + - sizeof (struct AddressUpdateMessage) != ntohs (message->size)) || - (ats_count > - GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_ATS_Information))) - { - GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; - } GNUNET_STATISTICS_update (GSA_stats, "# address updates received", 1, GNUNET_NO); + GNUNET_ATS_properties_ntoh (&prop, + &m->properties); GAS_addresses_update (&m->peer, ntohl (m->session_id), - atsi, ats_count); - GNUNET_SERVER_receive_done (client, GNUNET_OK); + &prop); + GNUNET_SERVER_receive_done (client, + GNUNET_OK); } diff --git a/src/ats/plugin_ats_mlp.c b/src/ats/plugin_ats_mlp.c index b97261d46..7d402044f 100644 --- a/src/ats/plugin_ats_mlp.c +++ b/src/ats/plugin_ats_mlp.c @@ -62,6 +62,29 @@ enum MLP_Output_Format }; +enum QualityMetrics +{ + RQ_QUALITY_METRIC_DELAY = 0, + RQ_QUALITY_METRIC_DISTANCE = 1, + RQ_QUALITY_METRIC_COUNT = 2 +}; + + +static const char * +print_quality_type (enum QualityMetrics qm) +{ + switch (qm){ + case RQ_QUALITY_METRIC_DELAY: + return "delay"; + case RQ_QUALITY_METRIC_DISTANCE: + return "distance"; + default: + GNUNET_break (0); + return NULL; + } +} + + struct MLP_Solution { int lp_res; @@ -125,7 +148,7 @@ struct MLP_Problem /* Row index constraint 9: relativity*/ unsigned int r_c9; /* Row indices quality metrics */ - int r_q[GNUNET_ATS_QualityPropertiesCount]; + int r_q[RQ_QUALITY_METRIC_COUNT]; /* Row indices ATS network quotas */ int r_quota[GNUNET_ATS_NetworkTypeCount]; @@ -136,7 +159,7 @@ struct MLP_Problem /* Column index Proportionality (R) column */ int c_r; /* Column index quality metrics */ - int c_q[GNUNET_ATS_QualityPropertiesCount]; + int c_q[RQ_QUALITY_METRIC_COUNT]; /* Problem matrix */ /* Current index */ @@ -161,23 +184,17 @@ struct MLP_Variables /* LP MIP Gap */ double lp_mip_gap; - /* ATS Quality metrics - * - * Array with GNUNET_ATS_QualityPropertiesCount elements - * contains mapping to GNUNET_ATS_Property*/ - int q[GNUNET_ATS_QualityPropertiesCount]; - - /* Number of quality metrics */ + /* Number of quality metrics @deprecated, use RQ_QUALITY_METRIC_COUNT */ int m_q; /* Number of quality metrics */ int m_rc; /* Quality metric coefficients*/ - double co_Q[GNUNET_ATS_QualityPropertiesCount]; + double co_Q[RQ_QUALITY_METRIC_COUNT]; /* Ressource costs coefficients*/ - double co_RC[GNUNET_ATS_QualityPropertiesCount]; + double co_RC[RQ_QUALITY_METRIC_COUNT]; /* Diversity coefficient */ double co_D; @@ -207,7 +224,7 @@ struct MLP_Variables * array with GNUNET_ATS_QualityPropertiesCount elements * contains mapping to GNUNET_ATS_Property * */ - int rc[GNUNET_ATS_QualityPropertiesCount]; + int rc[RQ_QUALITY_METRIC_COUNT]; }; @@ -584,7 +601,7 @@ mlp_delete_problem (struct GAS_MLP_Handle *mlp) mlp->p.r_c4 = MLP_UNDEFINED; mlp->p.r_c6 = MLP_UNDEFINED; mlp->p.r_c9 = MLP_UNDEFINED; - for (c = 0; c < mlp->pv.m_q ; c ++) + for (c = 0; c < RQ_QUALITY_METRIC_COUNT ; c ++) mlp->p.r_q[c] = MLP_UNDEFINED; for (c = 0; c < GNUNET_ATS_NetworkTypeCount; c ++) mlp->p.r_quota[c] = MLP_UNDEFINED; @@ -679,30 +696,6 @@ mlp_solve_to_string (int retcode) } } -/** - * Extract an ATS performance info from an address - * - * @param address the address - * @param type the type to extract in HBO - * @return the value in HBO or GNUNET_ATS_VALUE_UNDEFINED in HBO if value does not exist - */ -static uint32_t -get_performance_info (struct ATS_Address *address, uint32_t type) -{ - int c1; - GNUNET_assert (NULL != address); - - if ((NULL == address->atsi) || (0 == address->atsi_count)) - return GNUNET_ATS_VALUE_UNDEFINED; - - for (c1 = 0; c1 < address->atsi_count; c1++) - { - if (ntohl (address->atsi[c1].type) == type) - return ntohl (address->atsi[c1].value); - } - return GNUNET_ATS_VALUE_UNDEFINED; -} - struct CountContext { @@ -960,7 +953,6 @@ mlp_create_problem_add_address_information (void *cls, struct ATS_Peer *peer; struct MLP_information *mlpi; char *name; - double prop; double cur_bigm; uint32_t addr_net; uint32_t addr_net_index; @@ -979,7 +971,7 @@ mlp_create_problem_add_address_information (void *cls, return GNUNET_OK; } - addr_net = get_performance_info (address, GNUNET_ATS_NETWORK_TYPE); + addr_net = address->properties.scope; for (addr_net_index = 0; addr_net_index < GNUNET_ATS_NetworkTypeCount; addr_net_index++) { if (mlp->pv.quota_index[addr_net_index] == addr_net) @@ -1110,22 +1102,16 @@ mlp_create_problem_add_address_information (void *cls, /* For all quality metrics, set quality of this address */ if (GNUNET_YES == mlp->opt_dbg_optimize_quality) { - for (c = 0; c < mlp->pv.m_q; c++) - { - prop = address->atsin[c].norm; - if ((prop < 1.0) && (prop > 2.0)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "PROP == %.3f \t ", - prop); - GNUNET_break (0); - } - mlp_create_problem_set_value (p, - p->r_q[c], - mlpi->c_b, - prop, - __LINE__); - } + mlp_create_problem_set_value (p, + p->r_q[RQ_QUALITY_METRIC_DELAY], + mlpi->c_b, + address->norm_delay.norm, + __LINE__); + mlp_create_problem_set_value (p, + p->r_q[RQ_QUALITY_METRIC_DISTANCE], + mlpi->c_b, + address->norm_distance.norm, + __LINE__); } } @@ -1183,11 +1169,14 @@ mlp_create_problem_add_invariant_rows (struct GAS_MLP_Handle *mlp, struct MLP_Pr { for (c = 0; c < mlp->pv.m_q; c++) { - GNUNET_asprintf (&name, "c7_q%i_%s", c, - GNUNET_ATS_print_property_type (mlp->pv.q[c])); + GNUNET_asprintf (&name, + "c7_q%i_%s", c, + print_quality_type (c)); p->r_q[c] = mlp_create_problem_create_constraint (p, name, GLP_FX, 0.0, 0.0); GNUNET_free (name); - mlp_create_problem_set_value (p, p->r_q[c], p->c_q[c], -1, __LINE__); + mlp_create_problem_set_value (p, + p->r_q[c], + p->c_q[c], -1, __LINE__); } } } @@ -1222,7 +1211,7 @@ mlp_create_problem_add_invariant_columns (struct GAS_MLP_Handle *mlp, struct MLP { for (c = 0; c < mlp->pv.m_q; c++) { - GNUNET_asprintf (&name, "q_%u", mlp->pv.q[c]); + GNUNET_asprintf (&name, "q_%u", c); p->c_q[c] = mlp_create_problem_create_column (p, name, GLP_CV, GLP_LO, 0.0, 0.0, mlp->pv.co_Q[c]); GNUNET_free (name); } @@ -1866,13 +1855,10 @@ GAS_mlp_address_add (void *solver, { struct GAS_MLP_Handle *mlp = solver; - GNUNET_assert (NULL != solver); - GNUNET_assert (NULL != address); - if (GNUNET_ATS_NetworkTypeCount <= network) { - GNUNET_break (0); - return; + GNUNET_break (0); + return; } if (NULL == address->solver_information) @@ -1911,36 +1897,23 @@ GAS_mlp_address_add (void *solver, * * @param solver solver handle * @param address the address - * @param type the ATSI type in HBO - * @param abs_value the absolute value of the property - * @param rel_value the normalized value */ static void GAS_mlp_address_property_changed (void *solver, - struct ATS_Address *address, - enum GNUNET_ATS_Property type, - uint32_t abs_value, - double rel_value) + struct ATS_Address *address) { struct MLP_information *mlpi = address->solver_information; struct GAS_MLP_Handle *mlp = solver; - int c1; - int type_index; - - GNUNET_assert (NULL != solver); - GNUNET_assert (NULL != address); if (NULL == mlpi) { - LOG (GNUNET_ERROR_TYPE_INFO, - _("Updating address property `%s' for peer `%s' %p not added before\n"), - GNUNET_ATS_print_property_type (type), - GNUNET_i2s(&address->peer), - address); - GNUNET_break (0); - return; + LOG (GNUNET_ERROR_TYPE_INFO, + _("Updating address property for peer `%s' %p not added before\n"), + GNUNET_i2s (&address->peer), + address); + GNUNET_break (0); + return; } - if (NULL == GNUNET_CONTAINER_multipeermap_get (mlp->requested_peers, &address->peer)) @@ -1948,34 +1921,26 @@ GAS_mlp_address_property_changed (void *solver, /* Peer is not requested, so no need to update problem */ return; } - LOG (GNUNET_ERROR_TYPE_INFO, "Updating property `%s' address for peer `%s' to abs %llu rel %.3f\n", - GNUNET_ATS_print_property_type (type), - GNUNET_i2s(&address->peer), - abs_value, - rel_value); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Updating properties for peer `%s'\n", + GNUNET_i2s(&address->peer)); if (GNUNET_YES == mlp->opt_dbg_feasibility_only) return; - /* Find row index */ - type_index = -1; - for (c1 = 0; c1 < mlp->pv.m_q; c1++) - { - if (type == mlp->pv.q[c1]) - { - type_index = c1; - break; - } - } - if (-1 == type_index) - { - GNUNET_break (0); - return; /* quality index not found */ - } - /* Update c7) [r_q[index]][c_b] = f_q * q_averaged[type_index] */ - if (GNUNET_YES == mlp_create_problem_update_value (&mlp->p, - mlp->p.r_q[type_index], mlpi->c_b, rel_value, __LINE__)) + if ( (GNUNET_YES == + mlp_create_problem_update_value (&mlp->p, + mlp->p.r_q[RQ_QUALITY_METRIC_DELAY], + mlpi->c_b, + address->norm_delay.norm, + __LINE__)) || + (GNUNET_YES == + mlp_create_problem_update_value (&mlp->p, + mlp->p.r_q[RQ_QUALITY_METRIC_DISTANCE], + mlpi->c_b, + address->norm_distance.norm, + __LINE__)) ) { mlp->stat_mlp_prob_updated = GNUNET_YES; if (GNUNET_YES == mlp->opt_mlp_auto_solve) @@ -2037,17 +2002,14 @@ get_peer_pref_value (struct GAS_MLP_Handle *mlp, preferences = mlp->env->get_preferences (mlp->env->cls, peer); res = 0.0; - for (c = 0; c < GNUNET_ATS_PreferenceCount; c++) + for (c = 0; c < GNUNET_ATS_PREFERENCE_END; c++) { - if (c != GNUNET_ATS_PREFERENCE_END) - { - /* fprintf (stderr, "VALUE[%u] %s %.3f \n", - * c, GNUNET_i2s (&cur->addr->peer), t[c]); */ - res += preferences[c]; - } + /* fprintf (stderr, "VALUE[%u] %s %.3f \n", + * c, GNUNET_i2s (&cur->addr->peer), t[c]); */ + res += preferences[c]; } - res /= (GNUNET_ATS_PreferenceCount -1); + res /= GNUNET_ATS_PREFERENCE_END; res += 1.0; LOG (GNUNET_ERROR_TYPE_DEBUG, @@ -2646,34 +2608,28 @@ libgnunet_plugin_ats_mlp_init (void *cls) } /* Get quality metric coefficients from configuration */ - int i_delay = MLP_NaN; - int i_distance = MLP_NaN; - int q[GNUNET_ATS_QualityPropertiesCount] = GNUNET_ATS_QualityProperties; - for (c = 0; c < GNUNET_ATS_QualityPropertiesCount; c++) + for (c = 0; c < RQ_QUALITY_METRIC_COUNT; c++) { /* initialize quality coefficients with default value 1.0 */ - mlp->pv.co_Q[c] = MLP_DEFAULT_QUALITY; - - mlp->pv.q[c] = q[c]; - if (q[c] == GNUNET_ATS_QUALITY_NET_DELAY) - i_delay = c; - if (q[c] == GNUNET_ATS_QUALITY_NET_DISTANCE) - i_distance = c; + mlp->pv.co_Q[c] = MLP_DEFAULT_QUALITY; } - if ( (i_delay != MLP_NaN) && - (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (env->cfg, "ats", - "MLP_COEFFICIENT_QUALITY_DELAY", &tmp)) ) - mlp->pv.co_Q[i_delay] = (double) tmp / 100; + + if (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_size (env->cfg, "ats", + "MLP_COEFFICIENT_QUALITY_DELAY", + &tmp)) + mlp->pv.co_Q[RQ_QUALITY_METRIC_DELAY] = (double) tmp / 100; else - mlp->pv.co_Q[i_delay] = MLP_DEFAULT_QUALITY; + mlp->pv.co_Q[RQ_QUALITY_METRIC_DELAY] = MLP_DEFAULT_QUALITY; - if ( (i_distance != MLP_NaN) && - (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (env->cfg, "ats", - "MLP_COEFFICIENT_QUALITY_DISTANCE", &tmp)) ) - mlp->pv.co_Q[i_distance] = (double) tmp / 100; + if (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_size (env->cfg, "ats", + "MLP_COEFFICIENT_QUALITY_DISTANCE", + &tmp)) + mlp->pv.co_Q[RQ_QUALITY_METRIC_DISTANCE] = (double) tmp / 100; else - mlp->pv.co_Q[i_distance] = MLP_DEFAULT_QUALITY; + mlp->pv.co_Q[RQ_QUALITY_METRIC_DISTANCE] = MLP_DEFAULT_QUALITY; /* Get minimum bandwidth per used address from configuration */ if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (env->cfg, "ats", @@ -2759,7 +2715,7 @@ libgnunet_plugin_ats_mlp_init (void *cls) /* Setting MLP Input variables */ mlp->pv.b_min = b_min; mlp->pv.n_min = n_min; - mlp->pv.m_q = GNUNET_ATS_QualityPropertiesCount; + mlp->pv.m_q = RQ_QUALITY_METRIC_COUNT; mlp->stat_mlp_prob_changed = GNUNET_NO; mlp->stat_mlp_prob_updated = GNUNET_NO; mlp->opt_mlp_auto_solve = GNUNET_YES; diff --git a/src/ats/plugin_ats_proportional.c b/src/ats/plugin_ats_proportional.c index 69afa8a52..9ad00bbb3 100644 --- a/src/ats/plugin_ats_proportional.c +++ b/src/ats/plugin_ats_proportional.c @@ -25,8 +25,8 @@ */ #include "platform.h" #include "gnunet_statistics_service.h" -#include "gnunet_ats_plugin.h" #include "gnunet_ats_service.h" +#include "gnunet_ats_plugin.h" #include "gnunet-service-ats_addresses.h" #define LOG(kind,...) GNUNET_log_from (kind, "ats-proportional",__VA_ARGS__) @@ -308,7 +308,8 @@ distribute_bandwidth (struct GAS_PROPORTIONAL_Handle *s, continue; peer_relative_prefs = s->env->get_preferences (s->env->cls, &aw->addr->peer); - sum_relative_peer_prefences += peer_relative_prefs[GNUNET_ATS_PREFERENCE_BANDWIDTH]; + sum_relative_peer_prefences + += peer_relative_prefs[GNUNET_ATS_PREFERENCE_BANDWIDTH]; count_addresses++; } if (count_addresses != net->active_addresses) @@ -503,27 +504,6 @@ struct FindBestAddressCtx }; -/** - * Find index of a ATS property type in the quality properties array. - * - * @param type ATS property type - * @return index in the quality array, #GNUNET_SYSERR if the type - * was not a quality property - */ -static int -find_quality_property_index (enum GNUNET_ATS_Property type) -{ - enum GNUNET_ATS_Property existing_types[] = GNUNET_ATS_QualityProperties; - unsigned int c; - - for (c = 0; c < GNUNET_ATS_QualityPropertiesCount; c++) - if (existing_types[c] == type) - return c; - GNUNET_break (0); - return GNUNET_SYSERR; -} - - /** * Find a "good" address to use for a peer by iterating over the * addresses for this peer. If we already have an existing address, @@ -548,7 +528,6 @@ find_best_address_it (void *cls, double best_distance; double cur_delay; double cur_distance; - int index; unsigned int con; int bw_available; int need; @@ -601,12 +580,10 @@ find_best_address_it (void *cls, } /* Now compare ATS information */ - index = find_quality_property_index (GNUNET_ATS_QUALITY_NET_DISTANCE); - cur_distance = current->atsin[index].norm; - best_distance = ctx->best->atsin[index].norm; - index = find_quality_property_index (GNUNET_ATS_QUALITY_NET_DELAY); - cur_delay = current->atsin[index].norm; - best_delay = ctx->best->atsin[index].norm; + cur_distance = current->norm_distance.norm; + best_distance = ctx->best->norm_distance.norm; + cur_delay = current->norm_delay.norm; + best_delay = ctx->best->norm_delay.norm; /* user shorter distance */ if (cur_distance < best_distance) @@ -1006,16 +983,10 @@ GAS_proportional_bulk_stop (void *solver) * * @param solver solver handle * @param address the address - * @param type the ATSI type - * @param abs_value the absolute value of the property - * @param rel_value the normalized value */ static void GAS_proportional_address_property_changed (void *solver, - struct ATS_Address *address, - enum GNUNET_ATS_Property type, - uint32_t abs_value, - double rel_value) + struct ATS_Address *address) { struct GAS_PROPORTIONAL_Handle *s = solver; struct AddressWrapper *asi = address->solver_information; diff --git a/src/ats/plugin_ats_ril.c b/src/ats/plugin_ats_ril.c index 78f58e609..0d8b2290c 100644 --- a/src/ats/plugin_ats_ril.c +++ b/src/ats/plugin_ats_ril.c @@ -934,29 +934,6 @@ envi_get_state (struct GAS_RIL_Handle *solver, struct RIL_Peer_Agent *agent) return state; } -/** - * Retrieves an ATS information value of an address - * - * @param address the address in question - * @param type the ATS information type - * @return the value - */ -static unsigned int -ril_get_atsi (struct ATS_Address *address, uint32_t type) -{ - int c1; - GNUNET_assert(NULL != address); - - if ((NULL == address->atsi) || (0 == address->atsi_count)) - return GNUNET_ATS_QUALITY_NET_DELAY == type ? UINT32_MAX : 1; - - for (c1 = 0; c1 < address->atsi_count; c1++) - { - if (ntohl (address->atsi[c1].type) == type) - return ntohl (address->atsi[c1].value); - } - return GNUNET_ATS_QUALITY_NET_DELAY == type ? UINT32_MAX : 1; -} /** * Returns the utility value of the connection an agent manages @@ -975,16 +952,12 @@ agent_get_utility (struct RIL_Peer_Agent *agent) preferences = agent->envi->env->get_preferences (agent->envi->env->cls, &agent->peer); - delay_atsi = (double) ril_get_atsi (agent->address_inuse, GNUNET_ATS_QUALITY_NET_DELAY); + delay_atsi = agent->address_inuse->norm_delay.norm; delay_norm = RIL_UTILITY_DELAY_MAX*exp(-delay_atsi*0.00001); pref_match = preferences[GNUNET_ATS_PREFERENCE_LATENCY] * delay_norm; pref_match += preferences[GNUNET_ATS_PREFERENCE_BANDWIDTH] * sqrt((double) (agent->bw_in/RIL_MIN_BW) * (double) (agent->bw_out/RIL_MIN_BW)); -// sqrt((double) (ril_get_atsi (agent->address_inuse, GNUNET_ATS_UTILIZATION_IN)/RIL_MIN_BW) * (double) (ril_get_atsi (agent->address_inuse, GNUNET_ATS_UTILIZATION_OUT)/RIL_MIN_BW)); - -// return (double) (agent->bw_in/RIL_MIN_BW); -// return sqrt((double) (agent->bw_in/RIL_MIN_BW) * (double) (agent->bw_out/RIL_MIN_BW)); return pref_match; } @@ -1799,9 +1772,9 @@ ril_network_get_utilized (struct GAS_RIL_Handle *solver, enum GNUNET_ATS_Network if (net->type == type) { if (direction_in) - sum += ril_get_atsi (cur->address_inuse, GNUNET_ATS_UTILIZATION_IN); + sum += cur->address_inuse->norm_utilization_in.norm; else - sum += ril_get_atsi (cur->address_inuse, GNUNET_ATS_UTILIZATION_OUT); + sum += cur->address_inuse->norm_utilization_out.norm; } } } @@ -2373,27 +2346,16 @@ GAS_ril_address_delete (void *solver, * * @param solver solver handle * @param address the address - * @param type the ATSI type - * @param abs_value the absolute value of the property - * @param rel_value the normalized value */ static void GAS_ril_address_property_changed (void *solver, - struct ATS_Address *address, - enum GNUNET_ATS_Property type, - uint32_t abs_value, - double rel_value) + struct ATS_Address *address) { struct GAS_RIL_Handle *s = solver; LOG(GNUNET_ERROR_TYPE_DEBUG, - "API_address_property_changed() Property '%s' for peer '%s' address %s changed " - "to %.2f \n", - GNUNET_ATS_print_property_type (type), - GNUNET_i2s (&address->peer), - address->addr, rel_value); - - + "Properties for peer '%s' address changed\n", + GNUNET_i2s (&address->peer)); s->parameters.temperature = s->parameters.temperature_init; s->parameters.epsilon = s->parameters.epsilon_init; ril_step (s); diff --git a/src/ats/test_ats_api_common.h b/src/ats/test_ats_api_common.h index 233af72cd..091eb59b6 100644 --- a/src/ats/test_ats_api_common.h +++ b/src/ats/test_ats_api_common.h @@ -38,8 +38,7 @@ struct Test_Address void *addr; size_t addr_len; - struct GNUNET_ATS_Information *ats; - int ats_count; + struct GNUNET_ATS_Properties properties; void *session; }; @@ -61,13 +60,11 @@ free_test_address (struct Test_Address *dest); void create_test_address (struct Test_Address *dest, char * plugin, void *session, void *addr, size_t addrlen); + int compare_addresses (const struct GNUNET_HELLO_Address *address1, void *session1, const struct GNUNET_HELLO_Address *address2, void *session2); -int -compare_ats (const struct GNUNET_ATS_Information *ats_is, uint32_t ats_count_is, - const struct GNUNET_ATS_Information *ats_should, uint32_t ats_count_should); struct ATS_Address * create_address (const struct GNUNET_PeerIdentity *peer, diff --git a/src/dv/gnunet-service-dv.c b/src/dv/gnunet-service-dv.c index 93cc0628f..7ea4a300e 100644 --- a/src/dv/gnunet-service-dv.c +++ b/src/dv/gnunet-service-dv.c @@ -1158,46 +1158,6 @@ schedule_refresh_routes () } -/** - * Get distance information from 'atsi'. - * - * @param atsi performance data - * @param atsi_count number of entries in atsi - * @return connected transport distance - */ -static uint32_t -get_atsi_distance (const struct GNUNET_ATS_Information *atsi, - uint32_t atsi_count) -{ - uint32_t i; - - for (i = 0; i < atsi_count; i++) - if (ntohl (atsi[i].type) == GNUNET_ATS_QUALITY_NET_DISTANCE) - return (0 == ntohl (atsi[i].value)) ? DIRECT_NEIGHBOR_COST : ntohl (atsi[i].value); // FIXME: 0 check should not be required once ATS is fixed! - /* If we do not have explicit distance data, assume direct neighbor. */ - return DIRECT_NEIGHBOR_COST; -} - - -/** - * Get network information from 'atsi'. - * - * @param atsi performance data - * @param atsi_count number of entries in atsi - * @return connected transport network - */ -static enum GNUNET_ATS_Network_Type -get_atsi_network (const struct GNUNET_ATS_Information *atsi, - uint32_t atsi_count) -{ - uint32_t i; - - for (i = 0; i < atsi_count; i++) - if (ntohl (atsi[i].type) == GNUNET_ATS_NETWORK_TYPE) - return (enum GNUNET_ATS_Network_Type) ntohl (atsi[i].value); - return GNUNET_ATS_NET_UNSPECIFIED; -} - /** * Multipeermap iterator for freeing routes that go via a particular * neighbor that disconnected and is thus no longer available. @@ -1308,8 +1268,7 @@ handle_direct_disconnect (struct DirectNeighbor *neighbor) * #GNUNET_SYSERR if this address is no longer available for ATS * @param bandwidth_out assigned outbound bandwidth for the connection * @param bandwidth_in assigned inbound bandwidth for the connection - * @param ats performance data for the address (as far as known) - * @param ats_count number of performance records in @a ats + * @param prop performance data for the address (as far as known) */ static void handle_ats_update (void *cls, @@ -1317,12 +1276,11 @@ handle_ats_update (void *cls, int active, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count) + const struct GNUNET_ATS_Properties *prop) { struct DirectNeighbor *neighbor; uint32_t distance; - enum GNUNET_ATS_Network_Type network = GNUNET_ATS_NET_UNSPECIFIED; + enum GNUNET_ATS_Network_Type network; if (NULL == address) { @@ -1335,8 +1293,8 @@ handle_ats_update (void *cls, // FIXME: handle disconnect/inactive case too! return; } - distance = get_atsi_distance (ats, ats_count); - network = get_atsi_network (ats, ats_count); + distance = prop->distance; + network = prop->scope; GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != network); /* check if entry exists */ neighbor = GNUNET_CONTAINER_multipeermap_get (direct_neighbors, diff --git a/src/dv/plugin_transport_dv.c b/src/dv/plugin_transport_dv.c index 382e57596..f84c4a1b6 100644 --- a/src/dv/plugin_transport_dv.c +++ b/src/dv/plugin_transport_dv.c @@ -234,14 +234,12 @@ static void notify_distance_change (struct Session *session) { struct Plugin *plugin = session->plugin; - struct GNUNET_ATS_Information ats; if (GNUNET_YES != session->active) return; - ats.type = htonl ((uint32_t) GNUNET_ATS_QUALITY_NET_DISTANCE); - ats.value = htonl (session->distance); - plugin->env->update_address_metrics (plugin->env->cls, - session->address, session, &ats, 1); + plugin->env->update_address_distance (plugin->env->cls, + session->address, + session->distance); } @@ -260,21 +258,20 @@ unbox_cb (void *cls, { struct Plugin *plugin = cls; struct Session *session = client; - struct GNUNET_ATS_Information ats; - ats.type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); - ats.value = htonl (session->distance); session->active = GNUNET_YES; LOG (GNUNET_ERROR_TYPE_DEBUG, "Delivering message of type %u with %u bytes from peer `%s'\n", ntohs (message->type), ntohs (message->size), GNUNET_i2s (&session->sender)); - - plugin->env->receive (plugin->env->cls, session->address, session, + plugin->env->receive (plugin->env->cls, + session->address, + session, message); - plugin->env->update_address_metrics (plugin->env->cls, - session->address, session, &ats, 1); + plugin->env->update_address_distance (plugin->env->cls, + session->address, + session->distance); return GNUNET_OK; } @@ -294,12 +291,12 @@ handle_dv_message_received (void *cls, const struct GNUNET_MessageHeader *msg) { struct Plugin *plugin = cls; - struct GNUNET_ATS_Information ats; struct Session *session; LOG (GNUNET_ERROR_TYPE_DEBUG, "Received DV_MESSAGE_RECEIVED message for peer `%s': new distance %u\n", - GNUNET_i2s (sender), distance); + GNUNET_i2s (sender), + distance); session = GNUNET_CONTAINER_multipeermap_get (plugin->sessions, sender); if (NULL == session) @@ -320,17 +317,19 @@ handle_dv_message_received (void *cls, GNUNET_NO); return; } - ats.type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); - ats.value = htonl (distance); session->active = GNUNET_YES; LOG (GNUNET_ERROR_TYPE_DEBUG, "Delivering message of type %u with %u bytes from peer `%s'\n", ntohs (msg->type), ntohs (msg->size), GNUNET_i2s (sender)); - plugin->env->receive (plugin->env->cls, session->address, session, msg); - plugin->env->update_address_metrics (plugin->env->cls, - session->address, session, &ats, 1); + plugin->env->receive (plugin->env->cls, + session->address, + session, + msg); + plugin->env->update_address_distance (plugin->env->cls, + session->address, + session->distance); } @@ -350,7 +349,6 @@ handle_dv_connect (void *cls, { struct Plugin *plugin = cls; struct Session *session; - struct GNUNET_ATS_Information ats[2]; GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != network); /** @@ -358,8 +356,7 @@ handle_dv_connect (void *cls, * If you remove it, also remove libgnunetats linkage from Makefile.am */ LOG (GNUNET_ERROR_TYPE_DEBUG, - "Received `%s' message for peer `%s' with next hop in network %s\n", - "DV_CONNECT", + "Received DV_CONNECT message for peer `%s' with next hop in network %s\n", GNUNET_i2s (peer), GNUNET_ATS_print_network_type (network)); @@ -375,7 +372,8 @@ handle_dv_connect (void *cls, session = GNUNET_new (struct Session); session->address = GNUNET_HELLO_address_allocate (peer, "dv", - NULL, 0, GNUNET_HELLO_ADDRESS_INFO_NONE); + NULL, 0, + GNUNET_HELLO_ADDRESS_INFO_NONE); session->sender = *peer; session->plugin = plugin; session->distance = distance; @@ -391,14 +389,15 @@ handle_dv_connect (void *cls, GNUNET_i2s (peer), distance); - /* Notify transport and ats about new connection */ - ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); - ats[0].value = htonl (distance); - ats[1].type = htonl (GNUNET_ATS_NETWORK_TYPE); - ats[1].value = htonl ((uint32_t) network); session->active = GNUNET_YES; - plugin->env->session_start (plugin->env->cls, session->address, - session, ats, 2); + plugin->env->session_start (plugin->env->cls, + session->address, + session, + network); + plugin->env->update_address_distance (plugin->env->cls, + session->address, + session->distance); + notify_session_monitor (session->plugin, session, GNUNET_TRANSPORT_SS_UP); diff --git a/src/fs/gnunet-service-fs.c b/src/fs/gnunet-service-fs.c index 1ff0f0496..260ffc902 100644 --- a/src/fs/gnunet-service-fs.c +++ b/src/fs/gnunet-service-fs.c @@ -241,14 +241,13 @@ GSF_test_get_load_too_high_ (uint32_t priority) /** * We've received peer performance information. Update * our running average for the P2P latency. -* + * * @param cls closure * @param address the address * @param active is this address in active use * @param bandwidth_out assigned outbound bandwidth for the connection * @param bandwidth_in assigned inbound bandwidth for the connection - * @param ats performance data for the address (as far as known) - * @param ats_count number of performance records in @a ats + * @param prop performance data for the address (as far as known) */ static void update_latencies (void *cls, @@ -256,12 +255,8 @@ update_latencies (void *cls, int active, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count) + const struct GNUNET_ATS_Properties *prop) { - unsigned int i; - struct GNUNET_TIME_Relative latency; - if (NULL == address) { /* ATS service temporarily disconnected */ @@ -270,22 +265,15 @@ update_latencies (void *cls, if (GNUNET_YES != active) return; - for (i = 0; i < ats_count; i++) - { - if (GNUNET_ATS_QUALITY_NET_DELAY != ntohl (ats[i].type)) - continue; - latency.rel_value_us = ntohl (ats[i].value); - GSF_update_peer_latency_ (&address->peer, - latency); - GSF_avg_latency.rel_value_us = - (GSF_avg_latency.rel_value_us * 31 + - GNUNET_MIN (5000, ntohl (ats[i].value))) / 32; - GNUNET_STATISTICS_set (GSF_stats, - gettext_noop - ("# running average P2P latency (ms)"), - GSF_avg_latency.rel_value_us / 1000LL, GNUNET_NO); - break; - } + GSF_update_peer_latency_ (&address->peer, + prop->delay); + GSF_avg_latency.rel_value_us = + (GSF_avg_latency.rel_value_us * 31 + + GNUNET_MIN (5000, prop->delay.rel_value_us)) / 32; + GNUNET_STATISTICS_set (GSF_stats, + gettext_noop ("# running average P2P latency (ms)"), + GSF_avg_latency.rel_value_us / 1000LL, + GNUNET_NO); } diff --git a/src/fs/gnunet-service-fs_cp.c b/src/fs/gnunet-service-fs_cp.c index f7d64a49e..749ef15c7 100644 --- a/src/fs/gnunet-service-fs_cp.c +++ b/src/fs/gnunet-service-fs_cp.c @@ -348,7 +348,6 @@ GSF_update_peer_latency_ (const struct GNUNET_PeerIdentity *id, if (NULL == cp) return; /* we're not yet connected at the core level, ignore */ GNUNET_LOAD_value_set_decline (cp->ppd.transmission_delay, latency); - /* LATER: merge atsi into cp's performance data (if we ever care...) */ } @@ -416,9 +415,11 @@ schedule_transmission (struct GSF_PeerTransmitHandle *pth) if (0 != cp->inc_preference) { - GNUNET_ATS_performance_change_preference (GSF_ats, &target, GNUNET_ATS_PREFERENCE_BANDWIDTH, - (double) cp->inc_preference, - GNUNET_ATS_PREFERENCE_END); + GNUNET_ATS_performance_change_preference (GSF_ats, + &target, + GNUNET_ATS_PREFERENCE_BANDWIDTH, + (double) cp->inc_preference, + GNUNET_ATS_PREFERENCE_END); cp->inc_preference = 0; } diff --git a/src/fs/gnunet-service-fs_cp.h b/src/fs/gnunet-service-fs_cp.h index 502b8652f..eca6ff1ed 100644 --- a/src/fs/gnunet-service-fs_cp.h +++ b/src/fs/gnunet-service-fs_cp.h @@ -66,11 +66,6 @@ struct GSF_PeerPerformanceData { - /** - * Transport performance data. - */ - struct GNUNET_ATS_Information *atsi; - /** * List of the last clients for which this peer successfully * answered a query. diff --git a/src/include/gnunet_ats_plugin.h b/src/include/gnunet_ats_plugin.h index 4d6fa43f4..75d7ce3f8 100644 --- a/src/include/gnunet_ats_plugin.h +++ b/src/include/gnunet_ats_plugin.h @@ -34,13 +34,11 @@ #include "gnunet_ats_service.h" #include "gnunet_statistics_service.h" - /** * Representation of an address the plugin can choose from. */ struct ATS_Address; - /** * Change the preference for a peer * @@ -125,16 +123,10 @@ typedef void * * @param solver solver handle * @param address the address - * @param type the ATSI type in HBO - * @param abs_value the absolute value of the property - * @param rel_value the normalized value */ typedef void (*GAS_solver_address_property_changed) (void *solver, - struct ATS_Address *address, - enum GNUNET_ATS_Property type, - uint32_t abs_value, - double rel_value); + struct ATS_Address *address); /** @@ -386,8 +378,8 @@ typedef void /** - * Callback to call from solver to obtain application preference values for a - * peer + * Callback to call from solver to obtain application preference + * values for a peer. * * @param cls the cls * @param id the peer id diff --git a/src/include/gnunet_ats_service.h b/src/include/gnunet_ats_service.h index 437984402..8b28f5dc7 100644 --- a/src/include/gnunet_ats_service.h +++ b/src/include/gnunet_ats_service.h @@ -100,137 +100,118 @@ enum GNUNET_ATS_Network_Type /** - * Enum defining all known property types for ATS Enum values are used - * in the GNUNET_ATS_Information struct as - * (key,value)-pairs. - * - * Cost are always stored in uint32_t, so all units used to define costs - * have to be normalized to fit in uint32_t [0 .. UINT32_MAX-1] - * - * UINT32_MAX is reserved for uninitialized values #GNUNET_ATS_VALUE_UNDEFINED + * ATS performance characteristics for an address. */ -enum GNUNET_ATS_Property +struct GNUNET_ATS_Properties { - /** - * End of the array. - * @deprecated - */ - GNUNET_ATS_ARRAY_TERMINATOR = 0, - /** * Actual traffic on this connection from this peer to the other peer. - * Includes transport overhead + * Includes transport overhead. * * Unit: [bytes/second] */ - GNUNET_ATS_UTILIZATION_OUT = 1, + uint32_t utilization_out; /** * Actual traffic on this connection from the other peer to this peer. - * Includes transport overhead + * Includes transport overhead. * * Unit: [bytes/second] */ - GNUNET_ATS_UTILIZATION_IN = 2, + uint32_t utilization_in; /** - * Is this address located in WAN, LAN or a loopback address - * Value is element of GNUNET_ATS_Network_Type + * Which network scope does the respective address belong to? + * This property does not change. */ - GNUNET_ATS_NETWORK_TYPE = 3, + enum GNUNET_ATS_Network_Type scope; /** - * Delay - * Time between when the time packet is sent and the packet arrives - * - * Unit: [microseconds] - * - * Examples: - * - * LAN : 1 - * WLAN : 2 - * Dialup: 500 + * Distance on network layer (required for distance-vector routing) + * in hops. Zero for direct connections (i.e. plain TCP/UDP). */ - GNUNET_ATS_QUALITY_NET_DELAY = 4, + unsigned int distance; /** - * Distance on network layer (required for distance-vector routing). - * - * Unit: [DV-hops] + * Delay. Time between when the time packet is sent and the packet + * arrives. FOREVER if we did not measure yet. */ - GNUNET_ATS_QUALITY_NET_DISTANCE = 5 - -/** - * Number of property types supported by ATS - */ -#define GNUNET_ATS_PropertyCount 6 - + struct GNUNET_TIME_Relative delay; }; /** - * Number of ATS quality properties + * ATS performance characteristics for an address in + * network byte order (for IPC). */ -#define GNUNET_ATS_QualityPropertiesCount 2 +struct GNUNET_ATS_PropertiesNBO +{ -/** - * ATS quality properties as array initializer - */ -#define GNUNET_ATS_QualityProperties { GNUNET_ATS_QUALITY_NET_DELAY, GNUNET_ATS_QUALITY_NET_DISTANCE } + /** + * Actual traffic on this connection from this peer to the other peer. + * Includes transport overhead. + * + * Unit: [bytes/second] + */ + uint32_t utilization_out GNUNET_PACKED; -/** - * ATS quality properties as string array initializer - */ -#define GNUNET_ATS_QualityPropertiesString {"Delay", "Distance"} + /** + * Actual traffic on this connection from the other peer to this peer. + * Includes transport overhead. + * + * Unit: [bytes/second] + */ + uint32_t utilization_in GNUNET_PACKED; -GNUNET_NETWORK_STRUCT_BEGIN + /** + * Which network scope does the respective address belong to? + * This property does not change. + */ + uint32_t scope GNUNET_PACKED; -/** - * struct used to communicate the transport's properties like cost and - * quality of service as well as high-level constraints on resource - * consumption. - * - * +---+ - * +-----------+ Constraints | | Plugin properties +---------+ - * | Highlevel |------------> |ATS| <------------------|Transport| - * | Component | ATS struct | | ATS struct | Plugin | - * +-----------+ | | +---------+ - * +---+ - * - * This structure will be used by transport plugins to communicate - * costs to ATS or by higher level components to tell ATS their - * constraints. Always a pair of (GNUNET_ATS_Property, - * uint32_t value). Value is always uint32_t, so all units used to - * define costs have to be normalized to fit uint32_t. - */ -struct GNUNET_ATS_Information -{ /** - * ATS property type, in network byte order. + * Distance on network layer (required for distance-vector routing) + * in hops. Zero for direct connections (i.e. plain TCP/UDP). */ - uint32_t type GNUNET_PACKED; + uint32_t distance GNUNET_PACKED; /** - * ATS property value, in network byte order. + * Delay. Time between when the time packet is sent and the packet + * arrives. FOREVER if we did not measure yet. */ - uint32_t value GNUNET_PACKED; + struct GNUNET_TIME_RelativeNBO delay; + }; -GNUNET_NETWORK_STRUCT_END + /* ********************* LAN Characterization library ************************ */ /* Note: these functions do not really communicate with the ATS service */ + /** - * Convert a ATS property to a string + * Convert ATS properties from host to network byte order. * - * @param type the property type - * @return a string or NULL if invalid + * @param nbo[OUT] value written + * @param hbo value read */ -const char * -GNUNET_ATS_print_property_type (enum GNUNET_ATS_Property type); +void +GNUNET_ATS_properties_hton (struct GNUNET_ATS_PropertiesNBO *nbo, + const struct GNUNET_ATS_Properties *hbo); + + +/** + * Convert ATS properties from network to host byte order. + * + * @param hbo[OUT] value written + * @param nbo value read + */ +void +GNUNET_ATS_properties_ntoh (struct GNUNET_ATS_Properties *hbo, + const struct GNUNET_ATS_PropertiesNBO *nbo); + /** @@ -367,11 +348,11 @@ struct Session; */ typedef void (*GNUNET_ATS_AddressSuggestionCallback) (void *cls, - const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_HELLO_Address *address, - struct Session *session, - struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, - struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in); + const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_HELLO_Address *address, + struct Session *session, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in); /** @@ -424,8 +405,7 @@ struct GNUNET_ATS_AddressRecord; * @param sh handle * @param address the address * @param session session handle (if available, i.e. for incoming connections) - * @param ats performance data for the address - * @param ats_count number of performance records in @a ats + * @param prop performance data for the address * @return handle to the address representation inside ATS, NULL * on error (i.e. ATS knows this exact address already, or * address is invalid) @@ -434,8 +414,7 @@ struct GNUNET_ATS_AddressRecord * GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh, const struct GNUNET_HELLO_Address *address, struct Session *session, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count); + const struct GNUNET_ATS_Properties *prop); /** @@ -477,13 +456,11 @@ GNUNET_ATS_address_del_session (struct GNUNET_ATS_AddressRecord *ar, * suggest to switch addresses. * * @param ar address record to update information for - * @param ats performance data for the address - * @param ats_count number of performance records in @a ats + * @param prop performance data for the address */ void GNUNET_ATS_address_update (struct GNUNET_ATS_AddressRecord *ar, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count); + const struct GNUNET_ATS_Properties *prop); /** @@ -515,8 +492,7 @@ struct GNUNET_ATS_PerformanceHandle; * #GNUNET_SYSERR if this address is no longer available for ATS * @param bandwidth_out assigned outbound bandwidth for the connection * @param bandwidth_in assigned inbound bandwidth for the connection - * @param ats performance data for the address (as far as known) - * @param ats_count number of performance records in @a ats + * @param prop performance data for the address */ typedef void (*GNUNET_ATS_AddressInformationCallback) (void *cls, @@ -524,8 +500,7 @@ typedef void int address_active, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count); + const struct GNUNET_ATS_Properties *prop); /** @@ -650,7 +625,7 @@ GNUNET_ATS_reserve_bandwidth_cancel (struct GNUNET_ATS_ReservationContext *rc); /** * ATS preference types as string array initializer */ -#define GNUNET_ATS_PreferenceTypeString {"END", "BANDWIDTH", "LATENCY"} +#define GNUNET_ATS_PreferenceTypeString {"BANDWIDTH", "LATENCY", "END" } /** * Enum defining all known preference categories. @@ -658,18 +633,13 @@ GNUNET_ATS_reserve_bandwidth_cancel (struct GNUNET_ATS_ReservationContext *rc); enum GNUNET_ATS_PreferenceKind { - /** - * End of preference list. - */ - GNUNET_ATS_PREFERENCE_END = 0, - /** * Change the peer's bandwidth value (value per byte of bandwidth in * the goal function) to the given amount. The argument is followed * by a double value giving the desired value (can be negative). * Preference changes are forgotten if peers disconnect. */ - GNUNET_ATS_PREFERENCE_BANDWIDTH = 1, + GNUNET_ATS_PREFERENCE_BANDWIDTH = 0, /** * Change the peer's latency value to the given amount. The @@ -678,13 +648,12 @@ enum GNUNET_ATS_PreferenceKind * the inverse of the latency in microseconds (minimum: 1 * microsecond) multiplied by the latency preferences. */ - GNUNET_ATS_PREFERENCE_LATENCY = 2 - -/** - * Number of preference types supported by ATS - */ -#define GNUNET_ATS_PreferenceCount 3 + GNUNET_ATS_PREFERENCE_LATENCY = 1, + /** + * End of preference list. + */ + GNUNET_ATS_PREFERENCE_END = 2 }; @@ -703,9 +672,9 @@ GNUNET_ATS_print_preference_type (enum GNUNET_ATS_PreferenceKind type); * Change preferences for the given peer. Preference changes are forgotten if peers * disconnect. * - * @param ph performance handle - * @param peer identifies the peer - * @param ... 0-terminated specification of the desired changes + * @param ph performance handle @param peer identifies the peer + * @param ... #GNUNET_ATS_PREFERENCE_END-terminated specification of the + * desired changes */ void GNUNET_ATS_performance_change_preference (struct GNUNET_ATS_PerformanceHandle *ph, @@ -728,7 +697,7 @@ GNUNET_ATS_performance_change_preference (struct GNUNET_ATS_PerformanceHandle *p * @param ph performance handle * @param scope the time interval this valid for: [now - scope .. now] * @param peer identifies the peer - * @param ... 0-terminated specification of the desired changes + * @param ... #GNUNET_ATS_PREFERENCE_END-terminated specification of the desired changes */ void GNUNET_ATS_performance_give_feedback (struct GNUNET_ATS_PerformanceHandle *ph, diff --git a/src/include/gnunet_transport_plugin.h b/src/include/gnunet_transport_plugin.h index 90a85356b..f8394ebc5 100644 --- a/src/include/gnunet_transport_plugin.h +++ b/src/include/gnunet_transport_plugin.h @@ -80,15 +80,13 @@ typedef void * @param cls unused * @param address the address * @param session the new session - * @param ats ats information - * @param ats_count number of @a ats information + * @param net network information */ typedef void (*GNUNET_TRANSPORT_SessionStart) (void *cls, const struct GNUNET_HELLO_Address *address, struct Session *session, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count); + enum GNUNET_ATS_Network_Type net); /** @@ -137,22 +135,16 @@ typedef enum GNUNET_ATS_Network_Type /** - * Function called when quality properties of an address change. + * Function called when distance of an address changes. * * @param cls closure * @param peer peer - * @param address address - * @param address_len length of the @a address - * @param session session - * @param ats ATS information - * @param ats_count number entries in the @a ats array + * @param distance new distance */ typedef void -(*GNUNET_TRANSPORT_UpdateAddressMetrics) (void *cls, - const struct GNUNET_HELLO_Address *address, - struct Session *session, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count); +(*GNUNET_TRANSPORT_UpdateAddressDistance) (void *cls, + const struct GNUNET_HELLO_Address *address, + uint32_t distance); /** @@ -269,10 +261,10 @@ struct GNUNET_TRANSPORT_PluginEnvironment GNUNET_TRANSPORT_AddressToType get_address_type; /** - * Function that will be called to figure if an address is an loopback, - * LAN, WAN etc. address + * Function that will be called by DV to update distance for + * an address. */ - GNUNET_TRANSPORT_UpdateAddressMetrics update_address_metrics; + GNUNET_TRANSPORT_UpdateAddressDistance update_address_distance; /** * What is the maximum number of connections that this transport diff --git a/src/include/gnunet_transport_service.h b/src/include/gnunet_transport_service.h index 85d28ddd2..655704b1e 100644 --- a/src/include/gnunet_transport_service.h +++ b/src/include/gnunet_transport_service.h @@ -333,34 +333,19 @@ GNUNET_TRANSPORT_check_peer_connected (struct GNUNET_TRANSPORT_Handle *handle, * * @param handle transport handle * @param peer the peer to set the metric for - * @param inbound set inbound direction (#GNUNET_YES or #GNUNET_NO) - * @param outbound set outbound direction (#GNUNET_YES or #GNUNET_NO) - * @param ats the metric as ATS information - * @param ats_count the number of metrics + * @param prop the performance metrics to set + * @param delay_in inbound delay to introduce + * @param delay_out outbound delay to introduce * - * Supported ATS values: - * #GNUNET_ATS_QUALITY_NET_DELAY (value in ms) - * #GNUNET_ATS_QUALITY_NET_DISTANCE (value in count(hops)) - * - * Example - * To enforce a delay of 10 ms for peer p1 in sending direction use: - * - * struct GNUNET_ATS_Information ats; - * ats.type = ntohl (GNUNET_ATS_QUALITY_NET_DELAY); - * ats.value = ntohl (10); - * GNUNET_TRANSPORT_set_traffic_metric (th, p1, TM_SEND, &ats, 1); - * - * Note: - * Delay restrictions in receiving direction will be enforced with - * 1 message delay. + * Note: Delay restrictions in receiving direction will be enforced + * with one message delay. */ void GNUNET_TRANSPORT_set_traffic_metric (struct GNUNET_TRANSPORT_Handle *handle, const struct GNUNET_PeerIdentity *peer, - int inbound, - int outbound, - const struct GNUNET_ATS_Information *ats, - size_t ats_count); + const struct GNUNET_ATS_Properties *prop, + struct GNUNET_TIME_Relative delay_in, + struct GNUNET_TIME_Relative delay_out); /* *************************** HELLO *************************** */ diff --git a/src/testbed/gnunet-daemon-latency-logger.c b/src/testbed/gnunet-daemon-latency-logger.c index a8951c3dd..2dca73768 100644 --- a/src/testbed/gnunet-daemon-latency-logger.c +++ b/src/testbed/gnunet-daemon-latency-logger.c @@ -68,7 +68,8 @@ struct Entry struct GNUNET_PeerIdentity id; /** - * The last known value for latency + * The last known value for latency. + * FIXME: type! */ unsigned int latency; @@ -166,8 +167,7 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) * #GNUNET_SYSERR if this address is no longer available for ATS * @param bandwidth_out assigned outbound bandwidth for the connection * @param bandwidth_in assigned inbound bandwidth for the connection - * @param ats performance data for the address (as far as known) - * @param ats_count number of performance records in 'ats' + * @param prop performance data for the address (as far as known) */ static void addr_info_cb (void *cls, @@ -175,8 +175,7 @@ addr_info_cb (void *cls, int address_active, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count) + const struct GNUNET_ATS_Properties *prop) { static const char *query_insert = "INSERT INTO ats_info(" @@ -189,8 +188,7 @@ addr_info_cb (void *cls, " datetime('now')" ");"; struct Entry *entry; - int latency; - unsigned int cnt; + int latency; /* FIXME: type!? */ if (NULL == address) { @@ -201,15 +199,7 @@ addr_info_cb (void *cls, GNUNET_assert (NULL != db); if (GNUNET_YES != address_active) return; - for (cnt = 0; cnt < ats_count; cnt++) - { - if (GNUNET_ATS_QUALITY_NET_DELAY == ntohl (ats[cnt].type)) - goto insert; - } - return; - - insert: - latency = (int) ntohl (ats[cnt].value); + latency = (int) prop->delay.rel_value_us; entry = NULL; if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (map, &address->peer)) diff --git a/src/testbed/gnunet-daemon-testbed-underlay.c b/src/testbed/gnunet-daemon-testbed-underlay.c index 49bfc64bf..e41cf4a4d 100644 --- a/src/testbed/gnunet-daemon-testbed-underlay.c +++ b/src/testbed/gnunet-daemon-testbed-underlay.c @@ -365,13 +365,15 @@ run (void *cls, char *const *args, const char *cfgfile, struct WhiteListRow *wl_head; struct WhiteListRow *wl_entry; struct GNUNET_PeerIdentity identity; - struct GNUNET_ATS_Information params[1]; + struct GNUNET_ATS_Properties prop; + struct GNUNET_TIME_Relative delay; unsigned long long pid; unsigned int nrows; int ret; - if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (c, "TESTBED", - "PEERID", &pid)) + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_number (c, "TESTBED", + "PEERID", &pid)) { GNUNET_break (0); return; @@ -418,11 +420,11 @@ run (void *cls, char *const *args, const char *cfgfile, goto close_db; } map = GNUNET_CONTAINER_multipeermap_create (nrows, GNUNET_NO); - params[0].type = GNUNET_ATS_QUALITY_NET_DELAY; while (NULL != (wl_entry = wl_head)) { wl_head = wl_entry->next; - params[0].value = wl_entry->latency; + delay.rel_value_us = wl_entry->latency; + memset (&prop, 0, sizeof (prop)); GNUNET_assert (GNUNET_OK == get_identity (wl_entry->id, &identity)); GNUNET_break (GNUNET_OK == GNUNET_CONTAINER_multipeermap_put (map, &identity, &identity, @@ -432,9 +434,9 @@ run (void *cls, char *const *args, const char *cfgfile, GNUNET_i2s (&identity)); GNUNET_TRANSPORT_set_traffic_metric (transport, &identity, - GNUNET_YES, - GNUNET_YES, /* FIXME: Separate inbound, outboud metrics */ - params, 1); + &prop, + delay, + delay); GNUNET_free (wl_entry); } bh = GNUNET_TRANSPORT_blacklist (c, &check_access, NULL); diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am index 3c479f8fe..289fcd4c0 100644 --- a/src/transport/Makefile.am +++ b/src/transport/Makefile.am @@ -169,6 +169,7 @@ libgnunettransport_la_SOURCES = \ transport_api_monitor_validation.c libgnunettransport_la_LIBADD = \ $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/ats/libgnunetats.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(GN_LIBINTL) libgnunettransport_la_LDFLAGS = \ diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c index 5840eec5e..efbd67619 100644 --- a/src/transport/gnunet-service-transport.c +++ b/src/transport/gnunet-service-transport.c @@ -743,18 +743,17 @@ plugin_env_session_start_bl_check_cont (void *cls, * @param cls unused * @param address the address * @param session the new session - * @param ats ats information - * @param ats_count number of @a ats information + * @param scope network scope information */ static void plugin_env_session_start (void *cls, const struct GNUNET_HELLO_Address *address, struct Session *session, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count) + enum GNUNET_ATS_Network_Type scope) { struct BlacklistCheckContext *blctx; struct GST_BlacklistCheck *blc; + struct GNUNET_ATS_Properties prop; if (NULL == address) { @@ -767,9 +766,8 @@ plugin_env_session_start (void *cls, return; } GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Notification from plugin `%s' about new session %p from peer `%s' address `%s'\n", + "Notification from plugin `%s' about new session from peer `%s' address `%s'\n", address->transport_name, - session, GNUNET_i2s (&address->peer), GST_plugins_a2s (address)); if (GNUNET_YES == @@ -779,22 +777,12 @@ plugin_env_session_start (void *cls, /* inbound is always new, but outbound MAY already be known, but for example for UNIX, we have symmetric connections and thus we may not know the address yet; add if necessary! */ + /* FIXME: maybe change API here so we just pass scope? */ + memset (&prop, 0, sizeof (prop)); + prop.scope = scope; GST_ats_add_inbound_address (address, session, - ats, - ats_count); - } - else - { - if (GNUNET_YES == - GST_ats_is_known (address, - session)) - { - GST_ats_update_metrics (address, - session, - ats, - ats_count); - } + &prop); } /* Do blacklist check if communication with this peer is allowed */ blctx = GNUNET_new (struct BlacklistCheckContext); @@ -1034,7 +1022,7 @@ run (void *cls, &ats_request_address_change, NULL); GST_ats_init (); - GST_manipulation_init (GST_cfg); + GST_manipulation_init (); GST_plugins_load (&GST_manipulation_recv, &plugin_env_address_change_notification, &plugin_env_session_start, @@ -1053,7 +1041,8 @@ run (void *cls, * @return 0 ok, 1 on error */ int -main (int argc, char * const *argv) +main (int argc, + char * const *argv) { return (GNUNET_OK 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 @@ #include "gnunet-service-transport_plugins.h" #include "gnunet_ats_service.h" +#define LOG(kind,...) GNUNET_log_from(kind, "transport-ats", __VA_ARGS__) + /** * Information we track for each address known to ATS. @@ -51,6 +53,11 @@ struct AddressInfo */ struct GNUNET_ATS_AddressRecord *ar; + /** + * Performance properties of this address. + */ + struct GNUNET_ATS_Properties properties; + /** * Time until when this address is blocked and should thus not be * made available to ATS (@e ar should be NULL until this time). @@ -256,16 +263,15 @@ unblock_address (void *cls, struct AddressInfo *ai = cls; ai->unblock_task = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Unblocking address %s of peer %s\n", - GST_plugins_a2s (ai->address), - GNUNET_i2s (&ai->address->peer)); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Unblocking address %s of peer %s\n", + GST_plugins_a2s (ai->address), + GNUNET_i2s (&ai->address->peer)); ai->ar = GNUNET_ATS_address_add (GST_ats, ai->address, ai->session, - NULL, 0); + &ai->properties); GNUNET_break (NULL != ai->ar); - /* FIXME: should pass ATS information here! */ } @@ -299,15 +305,15 @@ GST_ats_block_address (const struct GNUNET_HELLO_Address *address, if (GNUNET_YES == GNUNET_HELLO_address_check_option (address, GNUNET_HELLO_ADDRESS_INFO_INBOUND)) - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Removing address %s of peer %s from use (inbound died)\n", - GST_plugins_a2s (address), - GNUNET_i2s (&address->peer)); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Removing address %s of peer %s from use (inbound died)\n", + GST_plugins_a2s (address), + GNUNET_i2s (&address->peer)); else - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Blocking address %s of peer %s from use for a while\n", - GST_plugins_a2s (address), - GNUNET_i2s (&address->peer)); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Blocking address %s of peer %s from use for a while\n", + GST_plugins_a2s (address), + GNUNET_i2s (&address->peer)); /* destroy session and address */ if ( (NULL == session) || (GNUNET_NO == @@ -332,20 +338,15 @@ GST_ats_block_address (const struct GNUNET_HELLO_Address *address, * * @param address the address * @param session the session - * @param ats ats information - * @param ats_count number of @a ats information + * @param prop performance information */ void GST_ats_add_inbound_address (const struct GNUNET_HELLO_Address *address, struct Session *session, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count) + const struct GNUNET_ATS_Properties *prop) { - struct GNUNET_TRANSPORT_PluginFunctions *papi; - struct GNUNET_ATS_Information ats2[ats_count + 1]; struct GNUNET_ATS_AddressRecord *ar; struct AddressInfo *ai; - uint32_t net; /* valid new address, let ATS know! */ if (NULL == address->transport_name) @@ -365,40 +366,24 @@ GST_ats_add_inbound_address (const struct GNUNET_HELLO_Address *address, GNUNET_break (0); return; } - papi = GST_plugins_find (address->transport_name); - GNUNET_assert (NULL != papi); - net = papi->get_network (papi->cls, session); - if (GNUNET_ATS_NET_UNSPECIFIED == net) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Could not obtain a valid network for `%s' %s (%s)\n"), - GNUNET_i2s (&address->peer), - GST_plugins_a2s (address), - address->transport_name); - return; - } - ats2[0].type = htonl (GNUNET_ATS_NETWORK_TYPE); - ats2[0].value = htonl (net); - memcpy (&ats2[1], - ats, - sizeof(struct GNUNET_ATS_Information) * ats_count); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Notifying ATS about peer `%s''s new inbound address `%s' session %p in network %s\n", - GNUNET_i2s (&address->peer), - (0 == address->address_length) - ? "" - : GST_plugins_a2s (address), - session, - GNUNET_ATS_print_network_type (net)); + GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != prop->scope); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Notifying ATS about peer `%s''s new inbound address `%s' session %p in network %s\n", + GNUNET_i2s (&address->peer), + (0 == address->address_length) + ? "" + : GST_plugins_a2s (address), + session, + GNUNET_ATS_print_network_type (prop->scope)); ar = GNUNET_ATS_address_add (GST_ats, address, session, - (NULL != session) ? ats2 : ats, - (NULL != session) ? ats_count + 1 : ats_count); + prop); GNUNET_break (NULL != ar); ai = GNUNET_new (struct AddressInfo); ai->address = GNUNET_HELLO_address_copy (address); ai->session = session; + ai->properties = *prop; ai->ar = ar; (void) GNUNET_CONTAINER_multipeermap_put (p2a, &ai->address->peer, @@ -413,13 +398,11 @@ GST_ats_add_inbound_address (const struct GNUNET_HELLO_Address *address, * located in. The address must NOT be inbound and must be new to ATS. * * @param address the address - * @param ats ats information - * @param ats_count number of @a ats information + * @param prop performance information */ void GST_ats_add_address (const struct GNUNET_HELLO_Address *address, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count) + const struct GNUNET_ATS_Properties *prop) { struct GNUNET_ATS_AddressRecord *ar; struct AddressInfo *ai; @@ -435,21 +418,21 @@ GST_ats_add_address (const struct GNUNET_HELLO_Address *address, GNUNET_HELLO_ADDRESS_INFO_INBOUND)); ai = find_ai_no_session (address); GNUNET_assert (NULL == ai); - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Notifying ATS about peer `%s''s new address `%s'\n", - GNUNET_i2s (&address->peer), - (0 == address->address_length) - ? "" - : GST_plugins_a2s (address)); + LOG (GNUNET_ERROR_TYPE_INFO, + "Notifying ATS about peer `%s''s new address `%s'\n", + GNUNET_i2s (&address->peer), + (0 == address->address_length) + ? "" + : GST_plugins_a2s (address)); ar = GNUNET_ATS_address_add (GST_ats, address, NULL, - ats, - ats_count); + prop); GNUNET_break (NULL != ar); ai = GNUNET_new (struct AddressInfo); ai->address = GNUNET_HELLO_address_copy (address); ai->ar = ar; + ai->properties = *prop; (void) GNUNET_CONTAINER_multipeermap_put (p2a, &ai->address->peer, ai, @@ -484,11 +467,9 @@ GST_ats_new_session (const struct GNUNET_HELLO_Address *address, } GNUNET_break (NULL == ai->session); ai->session = session; - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, - "transport-ats", - "Telling ATS about new session %p for peer %s\n", - session, - GNUNET_i2s (&address->peer)); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Telling ATS about new session for peer %s\n", + GNUNET_i2s (&address->peer)); if (NULL != ai->ar) GNUNET_ATS_address_add_session (ai->ar, session); @@ -528,11 +509,10 @@ GST_ats_del_session (const struct GNUNET_HELLO_Address *address, } GNUNET_assert (session == ai->session); ai->session = NULL; - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, - "transport-ats", - "Telling ATS to destroy session %p from peer %s\n", - session, - GNUNET_i2s (&address->peer)); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Telling ATS to destroy session %p from peer %s\n", + session, + GNUNET_i2s (&address->peer)); if (NULL == ai->ar) { /* 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, /** - * Notify ATS about property changes to an address. + * Notify ATS about DV distance change to an address's. * - * @param address our information about the address - * @param session the session - * @param ats performance information - * @param ats_count number of elements in @a ats + * @param address the address + * @param distance new distance value */ void -GST_ats_update_metrics (const struct GNUNET_HELLO_Address *address, - struct Session *session, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count) +GST_ats_update_distance (const struct GNUNET_HELLO_Address *address, + uint32_t distance) { - struct GNUNET_ATS_Information *ats_new; struct AddressInfo *ai; - ai = find_ai (address, session); + ai = find_ai_no_session (address); if (NULL == ai) - { - /* We sometimes create sessions just for sending a PING, - and if we get metrics for those, they were never known to - ATS which means we end up here (however, in this - case, the address must be an outbound address). */ - GNUNET_break (GNUNET_YES != - GNUNET_HELLO_address_check_option (address, - GNUNET_HELLO_ADDRESS_INFO_INBOUND)); return; - } - /* Call to manipulation to manipulate ATS information */ - GNUNET_assert (NULL != GST_ats); - if ((NULL == ats) || (0 == ats_count)) + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Updated distance for peer `%s' to %u\n", + GNUNET_i2s (&address->peer), + distance); + ai->properties.distance = distance; + GST_manipulation_manipulate_metrics (address, + ai->session, + &ai->properties); + if (NULL != ai->ar) + GNUNET_ATS_address_update (ai->ar, + &ai->properties); +} + + +/** + * Notify ATS about property changes to an address's properties. + * + * @param address the address + * @param delay new delay value + */ +void +GST_ats_update_delay (const struct GNUNET_HELLO_Address *address, + struct GNUNET_TIME_Relative delay) +{ + struct AddressInfo *ai; + + ai = find_ai_no_session (address); + if (NULL == ai) + return; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Updated latency for peer `%s' to %s\n", + GNUNET_i2s (&address->peer), + GNUNET_STRINGS_relative_time_to_string (delay, + GNUNET_YES)); + ai->properties.delay = delay; + GST_manipulation_manipulate_metrics (address, + ai->session, + &ai->properties); + if (NULL != ai->ar) + GNUNET_ATS_address_update (ai->ar, + &ai->properties); +} + + +/** + * Notify ATS about utilization changes to an address. + * + * @param address our information about the address + * @param bps_in new utilization inbound + * @param bps_out new utilization outbound + */ +void +GST_ats_update_utilization (const struct GNUNET_HELLO_Address *address, + uint32_t bps_in, + uint32_t bps_out) +{ + struct AddressInfo *ai; + + ai = find_ai_no_session (address); + if (NULL == ai) return; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Updating metrics for peer `%s' address %s session %p\n", - GNUNET_i2s (&address->peer), - GST_plugins_a2s (address), - session); - ats_new = GST_manipulation_manipulate_metrics (address, - session, - ats, - ats_count); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Updating utilization for peer `%s' address %s: %u/%u\n", + GNUNET_i2s (&address->peer), + GST_plugins_a2s (address), + (unsigned int) bps_in, + (unsigned int) bps_out); + ai->properties.utilization_in = bps_in; + ai->properties.utilization_out = bps_out; + GST_manipulation_manipulate_metrics (address, + ai->session, + &ai->properties); if (NULL != ai->ar) GNUNET_ATS_address_update (ai->ar, - ats_new, - ats_count); - GNUNET_free_non_null (ats_new); + &ai->properties); } @@ -616,10 +639,10 @@ GST_ats_expire_address (const struct GNUNET_HELLO_Address *address) { struct AddressInfo *ai; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Address %s of peer %s expired\n", - GST_plugins_a2s (address), - GNUNET_i2s (&address->peer)); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Address %s of peer %s expired\n", + GST_plugins_a2s (address), + GNUNET_i2s (&address->peer)); ai = find_ai_no_session (address); if (NULL == ai) { @@ -632,10 +655,9 @@ GST_ats_expire_address (const struct GNUNET_HELLO_Address *address) ai)); publish_p2a_stat_update (); GNUNET_break (NULL == ai->session); - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, - "transport-ats", - "Telling ATS to destroy address from peer %s\n", - GNUNET_i2s (&address->peer)); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Telling ATS to destroy address from peer %s\n", + GNUNET_i2s (&address->peer)); if (NULL != ai->ar) { /* We usually should not have a session here when we diff --git a/src/transport/gnunet-service-transport_ats.h b/src/transport/gnunet-service-transport_ats.h index f09b52375..780e66f60 100644 --- a/src/transport/gnunet-service-transport_ats.h +++ b/src/transport/gnunet-service-transport_ats.h @@ -78,14 +78,12 @@ GST_ats_block_address (const struct GNUNET_HELLO_Address *address, * * @param address the address * @param session the session - * @param ats ats information - * @param ats_count number of @a ats information + * @param prop performance information */ void GST_ats_add_inbound_address (const struct GNUNET_HELLO_Address *address, struct Session *session, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count); + const struct GNUNET_ATS_Properties *prop); /** @@ -93,13 +91,11 @@ GST_ats_add_inbound_address (const struct GNUNET_HELLO_Address *address, * located in. The address must NOT be inbound and must be new to ATS. * * @param address the address - * @param ats ats information - * @param ats_count number of @a ats information + * @param prop performance information */ void GST_ats_add_address (const struct GNUNET_HELLO_Address *address, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count); + const struct GNUNET_ATS_Properties *prop); /** @@ -115,18 +111,54 @@ GST_ats_new_session (const struct GNUNET_HELLO_Address *address, /** - * Notify ATS about property changes to an address + * Notify ATS about property changes to an address's properties. + * FIXME: we probably want to split this one up for the different + * updatable properties. * * @param address the address * @param session the session - * @param ats performance information - * @param ats_count number of elements in @a ats + * @param prop updated performance information */ void GST_ats_update_metrics (const struct GNUNET_HELLO_Address *address, struct Session *session, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count); + const struct GNUNET_ATS_Properties *prop); + + +/** + * Notify ATS about utilization changes to an address. + * + * @param address our information about the address + * @param bps_in new utilization inbound + * @param bps_out new utilization outbound + */ +void +GST_ats_update_utilization (const struct GNUNET_HELLO_Address *address, + uint32_t bps_in, + uint32_t bps_out); + + +/** + * Notify ATS about property changes to an address's properties. + * + * @param address the address + * @param session the session + * @param delay new delay value + */ +void +GST_ats_update_delay (const struct GNUNET_HELLO_Address *address, + struct GNUNET_TIME_Relative delay); + + +/** + * Notify ATS about property changes to an address's properties. + * + * @param address the address + * @param distance new distance value + */ +void +GST_ats_update_distance (const struct GNUNET_HELLO_Address *address, + uint32_t distance); /** diff --git a/src/transport/gnunet-service-transport_clients.c b/src/transport/gnunet-service-transport_clients.c index 87bc0699b..0700aef0d 100644 --- a/src/transport/gnunet-service-transport_clients.c +++ b/src/transport/gnunet-service-transport_clients.c @@ -1515,7 +1515,8 @@ GST_clients_start (struct GNUNET_SERVER_Handle *server) GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_REPLY, sizeof (struct BlacklistMessage)}, {&GST_manipulation_set_metric, NULL, - GNUNET_MESSAGE_TYPE_TRANSPORT_TRAFFIC_METRIC, 0}, + GNUNET_MESSAGE_TYPE_TRANSPORT_TRAFFIC_METRIC, + sizeof (struct TrafficMetricMessage) }, {&clients_handle_monitor_plugins, NULL, GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PLUGIN_START, sizeof (struct GNUNET_MessageHeader) }, diff --git a/src/transport/gnunet-service-transport_manipulation.c b/src/transport/gnunet-service-transport_manipulation.c index f52634edc..b58ade999 100644 --- a/src/transport/gnunet-service-transport_manipulation.c +++ b/src/transport/gnunet-service-transport_manipulation.c @@ -34,66 +34,36 @@ #include "gnunet-service-transport.h" #include "transport.h" -enum TRAFFIC_METRIC_DIRECTION -{ - TM_SEND = 0, TM_RECEIVE = 1, TM_BOTH = 2 -}; - /** * Struct containing information about manipulations to a specific peer */ -struct TM_Peer; - -/** - * Manipulation entry - */ -struct PropManipulationEntry +struct TM_Peer { /** - * Next in DLL - */ - struct PropManipulationEntry *next; - - /** - * Previous in DLL - */ - struct PropManipulationEntry *prev; - - /** - * ATS type in HBO + * Peer ID */ - uint32_t type; + struct GNUNET_PeerIdentity peer; /** - * Value in HBO + * How long to delay incoming messages for this peer. */ - uint32_t metrics[TM_BOTH]; + struct GNUNET_TIME_Relative delay_in; -}; - -/** - * Struct containing information about manipulations to a specific peer - */ -struct TM_Peer -{ /** - * Peer ID + * How long to delay outgoing messages for this peer. */ - struct GNUNET_PeerIdentity peer; - - struct PropManipulationEntry *head; - struct PropManipulationEntry *tail; + struct GNUNET_TIME_Relative delay_out; /** - * Peer specific manipulation metrics + * Manipulated properties to use for this peer. */ - uint32_t metrics[TM_BOTH][GNUNET_ATS_QualityPropertiesCount]; + struct GNUNET_ATS_Properties properties; /** * Task to schedule delayed sendding */ - struct GNUNET_SCHEDULER_Task * send_delay_task; + struct GNUNET_SCHEDULER_Task *send_delay_task; /** * Send queue DLL head @@ -107,19 +77,6 @@ struct TM_Peer }; -struct GST_ManipulationHandle -{ - /** - * Hashmap contain all peers currently manipulated - */ - struct GNUNET_CONTAINER_MultiPeerMap *peers; - - /** - * Peer containing information for general manipulation - */ - struct TM_Peer general; -}; - /** * Entry in the delay queue for an outbound delayed message */ @@ -136,9 +93,10 @@ struct DelayQueueEntry struct DelayQueueEntry *next; /** - * Peer this entry is belonging to - * if (NULL == tmp): enqueued in generic DLL and scheduled by generic_send_delay_task - * else: enqueued in tmp->send_head and tmp->send_tail and scheduled by tmp->send_delay_task + * Peer this entry is belonging to if (NULL == tmp): enqueued in + * generic DLL and scheduled by generic_send_delay_task else: + * enqueued in tmp->send_head and tmp->send_tail and scheduled by + * tmp->send_delay_task */ struct TM_Peer *tmp; @@ -178,91 +136,35 @@ struct DelayQueueEntry void *cont_cls; }; -struct GST_ManipulationHandle man_handle; - /** - * DLL head for delayed messages based on general delay + * Hashmap contain all peers currently manipulated */ -struct DelayQueueEntry *generic_dqe_head; +static struct GNUNET_CONTAINER_MultiPeerMap *peers; /** - * DLL tail for delayed messages based on general delay + * Inbound delay to apply to all peers. */ -struct DelayQueueEntry *generic_dqe_tail; +static struct GNUNET_TIME_Relative delay_in; /** - * Task to schedule delayed sending based on general delay + * Outbound delay to apply to all peers. */ -struct GNUNET_SCHEDULER_Task * generic_send_delay_task; - - -static void -set_metric(struct TM_Peer *dest, int direction, uint32_t type, uint32_t value) -{ - struct PropManipulationEntry *cur; - for (cur = dest->head; NULL != cur; cur = cur->next) - { - if (cur->type == type) - break; - } - if (NULL == cur) - { - cur = GNUNET_new (struct PropManipulationEntry); - GNUNET_CONTAINER_DLL_insert(dest->head, dest->tail, cur); - cur->type = type; - cur->metrics[TM_SEND] = UINT32_MAX; - cur->metrics[TM_RECEIVE] = UINT32_MAX; - } - - switch (direction) - { - case TM_BOTH: - cur->metrics[TM_SEND] = value; - cur->metrics[TM_RECEIVE] = value; - break; - case TM_SEND: - cur->metrics[TM_SEND] = value; - break; - case TM_RECEIVE: - cur->metrics[TM_RECEIVE] = value; - break; - default: - break; - } -} - - -static uint32_t -find_metric(struct TM_Peer *dest, uint32_t type, int direction) -{ - struct PropManipulationEntry *cur; - - for (cur = dest->head; NULL != cur; cur = cur->next) - { - if (cur->type == type) - return cur->metrics[direction]; - - } - return UINT32_MAX; -} +static struct GNUNET_TIME_Relative delay_out; +/** + * DLL head for delayed messages based on general delay + */ +static struct DelayQueueEntry *generic_dqe_head; /** - * Clean up metrics for a peer + * DLL tail for delayed messages based on general delay */ -static void -free_metric(struct TM_Peer *dest) -{ - struct PropManipulationEntry *cur; - struct PropManipulationEntry *next; +static struct DelayQueueEntry *generic_dqe_tail; - for (cur = dest->head; NULL != cur; cur = next) - { - next = cur->next; - GNUNET_CONTAINER_DLL_remove(dest->head, dest->tail, cur); - GNUNET_free(cur); - } -} +/** + * Task to schedule delayed sending based on general delay + */ +static struct GNUNET_SCHEDULER_Task *generic_send_delay_task; /** @@ -273,134 +175,106 @@ free_metric(struct TM_Peer *dest) * @param message containing information */ void -GST_manipulation_set_metric(void *cls, struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) +GST_manipulation_set_metric (void *cls, + struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader *message) { - struct TrafficMetricMessage *tm = (struct TrafficMetricMessage *) message; - struct GNUNET_PeerIdentity dummy; - struct GNUNET_ATS_Information *ats; + const struct TrafficMetricMessage *tm; + static struct GNUNET_PeerIdentity zero; struct TM_Peer *tmp; - uint32_t type; - uint32_t value; - uint16_t direction; - int c; - int c2; - - if (0 == ntohs(tm->ats_count)) - GNUNET_SERVER_receive_done(client, GNUNET_SYSERR); - - direction = TM_BOTH; - switch (ntohs(tm->direction)) - { - case 1: - direction = TM_SEND; - break; - case 2: - direction = TM_RECEIVE; - break; - case 3: - direction = TM_BOTH; - break; - default: - break; - } - - memset(&dummy, '\0', sizeof(struct GNUNET_PeerIdentity)); - if (0 == memcmp(&tm->peer, &dummy, sizeof(struct GNUNET_PeerIdentity))) - { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Received traffic metrics for all peers \n"); - - ats = (struct GNUNET_ATS_Information *) &tm[1]; - for (c = 0; c < ntohs(tm->ats_count); c++) - { - type = htonl(ats[c].type); - value = htonl(ats[c].value); - set_metric(&man_handle.general, direction, type, value); - } - return; - } - - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Received traffic metrics for peer `%s'\n", GNUNET_i2s(&tm->peer)); - - if (NULL - == (tmp = GNUNET_CONTAINER_multipeermap_get(man_handle.peers, &tm->peer))) - { - tmp = GNUNET_new (struct TM_Peer); - tmp->peer = (tm->peer); - for (c = 0; c < TM_BOTH; c++) - { - for (c2 = 0; c2 < GNUNET_ATS_QualityPropertiesCount; c2++) - { - tmp->metrics[c][c2] = UINT32_MAX; - } - } - GNUNET_CONTAINER_multipeermap_put(man_handle.peers, &tm->peer, tmp, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); - } - ats = (struct GNUNET_ATS_Information *) &tm[1]; - for (c = 0; c < ntohs(tm->ats_count); c++) - { - type = htonl(ats[c].type); - value = htonl(ats[c].value); - set_metric(tmp, direction, type, value); - } - - GNUNET_SERVER_receive_done(client, GNUNET_OK); + tm = (const struct TrafficMetricMessage *) message; + if (0 == memcmp (&tm->peer, + &zero, + sizeof(struct GNUNET_PeerIdentity))) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received traffic metrics for all peers\n"); + delay_in = GNUNET_TIME_relative_ntoh (tm->delay_in); + delay_out = GNUNET_TIME_relative_ntoh (tm->delay_out); + GNUNET_SERVER_receive_done (client, + GNUNET_OK); + return; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received traffic metrics for peer `%s'\n", + GNUNET_i2s(&tm->peer)); + if (NULL == + (tmp = GNUNET_CONTAINER_multipeermap_get (peers, + &tm->peer))) + { + tmp = GNUNET_new (struct TM_Peer); + tmp->peer = tm->peer; + GNUNET_CONTAINER_multipeermap_put (peers, + &tm->peer, + tmp, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); + } + GNUNET_ATS_properties_ntoh (&tmp->properties, + &tm->properties); + tmp->delay_in = GNUNET_TIME_relative_ntoh (tm->delay_in); + tmp->delay_out = GNUNET_TIME_relative_ntoh (tm->delay_out); + GNUNET_SERVER_receive_done (client, + GNUNET_OK); } +/** + * We have delayed transmission, now it is time to send the + * message. + * + * @param cls the `struct DelayQueueEntry` to transmit + * @param tc unused + */ static void -send_delayed(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +send_delayed (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) { struct DelayQueueEntry *dqe = cls; struct DelayQueueEntry *next; struct TM_Peer *tmp = dqe->tmp; struct GNUNET_TIME_Relative delay; + GNUNET_break (GNUNET_YES == + GST_neighbours_test_connected (&dqe->id)); if (NULL != tmp) + { + tmp->send_delay_task = NULL; + GNUNET_CONTAINER_DLL_remove (tmp->send_head, + tmp->send_tail, + dqe); + next = tmp->send_head; + if (NULL != next) { - GNUNET_break (GNUNET_YES == - GST_neighbours_test_connected (&dqe->id)); - tmp->send_delay_task = NULL; - GNUNET_CONTAINER_DLL_remove (tmp->send_head, - tmp->send_tail, - dqe); - GST_neighbours_send (&dqe->id, - dqe->msg, - dqe->msg_size, - dqe->timeout, - dqe->cont, - dqe->cont_cls); - - next = tmp->send_head; - if (NULL != next) - { - /* More delayed messages */ - delay = GNUNET_TIME_absolute_get_remaining(next->sent_at); - tmp->send_delay_task = GNUNET_SCHEDULER_add_delayed(delay, - &send_delayed, next); - } + /* More delayed messages */ + delay = GNUNET_TIME_absolute_get_remaining(next->sent_at); + tmp->send_delay_task = GNUNET_SCHEDULER_add_delayed(delay, + &send_delayed, next); } + } else + { + /* Remove from generic queue */ + generic_send_delay_task = NULL; + GNUNET_CONTAINER_DLL_remove (generic_dqe_head, + generic_dqe_tail, + dqe); + next = generic_dqe_head; + if (NULL != next) { - /* Remove from generic queue */ - GNUNET_break(GNUNET_YES == GST_neighbours_test_connected (&dqe->id)); - generic_send_delay_task = NULL; - GNUNET_CONTAINER_DLL_remove(generic_dqe_head, generic_dqe_tail, dqe); - GST_neighbours_send(&dqe->id, dqe->msg, dqe->msg_size, dqe->timeout, - dqe->cont, dqe->cont_cls); - next = generic_dqe_head; - if (NULL != next) - { - /* More delayed messages */ - delay = GNUNET_TIME_absolute_get_remaining(next->sent_at); - generic_send_delay_task = GNUNET_SCHEDULER_add_delayed(delay, - &send_delayed, next); - } + /* More delayed messages */ + delay = GNUNET_TIME_absolute_get_remaining(next->sent_at); + generic_send_delay_task = GNUNET_SCHEDULER_add_delayed (delay, + &send_delayed, + next); } + } + GST_neighbours_send (&dqe->id, + dqe->msg, + dqe->msg_size, + dqe->timeout, + dqe->cont, + dqe->cont_cls); GNUNET_free(dqe); } @@ -427,41 +301,14 @@ GST_manipulation_send (const struct GNUNET_PeerIdentity *target, struct TM_Peer *tmp; struct DelayQueueEntry *dqe; struct GNUNET_TIME_Relative delay; - int do_delay; - do_delay = GNUNET_NO; if (NULL != (tmp = - GNUNET_CONTAINER_multipeermap_get (man_handle.peers, + GNUNET_CONTAINER_multipeermap_get (peers, target))) - { - GNUNET_break (GNUNET_YES == - GST_neighbours_test_connected(target)); - /* check for peer-specific delay */ - if (UINT32_MAX != - find_metric (tmp, - GNUNET_ATS_QUALITY_NET_DELAY, - TM_SEND)) - { - /* We have a delay */ - delay.rel_value_us = find_metric(tmp, GNUNET_ATS_QUALITY_NET_DELAY, - TM_SEND); - do_delay = GNUNET_YES; - } - } - else if (UINT32_MAX != - find_metric(&man_handle.general, - GNUNET_ATS_QUALITY_NET_DELAY, - TM_SEND)) - { - GNUNET_break (GNUNET_YES == - GST_neighbours_test_connected (target)); - /* We have a delay */ - delay.rel_value_us = find_metric (&man_handle.general, - GNUNET_ATS_QUALITY_NET_DELAY, - TM_SEND); - do_delay = GNUNET_YES; - } - if (GNUNET_NO == do_delay) + delay = tmp->delay_out; + else + delay = delay_out; + if (0 == delay.rel_value_us) { /* Normal sending */ GST_neighbours_send (target, @@ -516,46 +363,22 @@ GST_manipulation_send (const struct GNUNET_PeerIdentity *target, * Function that will be called to manipulate ATS information according to * current manipulation settings * - * @param peer the peer * @param address binary address * @param session the session - * @param ats the ats information - * @param ats_count the number of ats information + * @param prop[IN|OUT] metrics to modify */ -struct GNUNET_ATS_Information * +void GST_manipulation_manipulate_metrics (const struct GNUNET_HELLO_Address *address, struct Session *session, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count) + struct GNUNET_ATS_Properties *prop) { const struct GNUNET_PeerIdentity *peer = &address->peer; - struct GNUNET_ATS_Information *ats_new; struct TM_Peer *tmp; - uint32_t m_tmp; - uint32_t g_tmp; - uint32_t d; - - if (0 == ats_count) - return NULL; - ats_new = GNUNET_malloc (sizeof (struct GNUNET_ATS_Information) * ats_count); - tmp = GNUNET_CONTAINER_multipeermap_get (man_handle.peers, peer); - for (d = 0; d < ats_count; d++) - { - ats_new[d] = ats[d]; - m_tmp = UINT32_MAX; - if (NULL != tmp) - m_tmp = find_metric (tmp, ntohl(ats[d].type), - TM_RECEIVE); - g_tmp = find_metric (&man_handle.general, - ntohl(ats[d].type), - TM_RECEIVE); - - if (UINT32_MAX != g_tmp) - ats_new[d].value = htonl(g_tmp); - if (UINT32_MAX != m_tmp) - ats_new[d].value = htonl(m_tmp); - } - return ats_new; + + tmp = GNUNET_CONTAINER_multipeermap_get (peers, + peer); + if (NULL != tmp) + *prop = tmp->properties; } @@ -576,32 +399,22 @@ GST_manipulation_recv (void *cls, const struct GNUNET_MessageHeader *message) { struct TM_Peer *tmp; - uint32_t p_recv_delay; - uint32_t g_recv_delay; struct GNUNET_TIME_Relative quota_delay; struct GNUNET_TIME_Relative m_delay; - g_recv_delay = find_metric(&man_handle.general, GNUNET_ATS_QUALITY_NET_DELAY, - TM_RECEIVE); - if ((g_recv_delay >= GNUNET_TIME_UNIT_ZERO.rel_value_us) - && (UINT32_MAX != g_recv_delay)) - m_delay.rel_value_us = g_recv_delay; /* Global delay */ + if (NULL != + (tmp = GNUNET_CONTAINER_multipeermap_get (peers, + &address->peer))) + m_delay = tmp->delay_in; else - m_delay = GNUNET_TIME_UNIT_ZERO; - - if (NULL != (tmp = GNUNET_CONTAINER_multipeermap_get(man_handle.peers, &address->peer))) - { - /* Manipulate receive delay */ - p_recv_delay = find_metric(tmp, GNUNET_ATS_QUALITY_NET_DELAY, TM_RECEIVE); - if (UINT32_MAX != p_recv_delay) - m_delay.rel_value_us = p_recv_delay; /* Peer specific delay */ - } - - quota_delay = GST_receive_callback(cls, address, session, message); - - if (quota_delay.rel_value_us > m_delay.rel_value_us) - m_delay = quota_delay; - + m_delay = delay_in; + + quota_delay = GST_receive_callback (cls, + address, + session, + message); + m_delay = GNUNET_TIME_relative_max (m_delay, + quota_delay); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Delaying next receive for peer `%s' for %s\n", GNUNET_i2s (&address->peer), @@ -613,63 +426,110 @@ GST_manipulation_recv (void *cls, /** * Initialize traffic manipulation - * - * @param GST_cfg configuration handle */ void -GST_manipulation_init(const struct GNUNET_CONFIGURATION_Handle *GST_cfg) +GST_manipulation_init () { - unsigned long long tmp; struct GNUNET_TIME_Relative delay; if ( (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_number(GST_cfg, - "transport", - "MANIPULATE_DISTANCE_IN", - &tmp)) && - (tmp > 0) ) + GNUNET_CONFIGURATION_get_value_time (GST_cfg, + "transport", + "MANIPULATE_DELAY_IN", + &delay)) && + (delay.rel_value_us > 0) ) { - GNUNET_log(GNUNET_ERROR_TYPE_INFO, - "Setting inbound distance_in to %llu\n", - (unsigned long long) tmp); - set_metric (&man_handle.general, - TM_RECEIVE, - GNUNET_ATS_QUALITY_NET_DISTANCE, - tmp); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Delaying inbound traffic for %s\n", + GNUNET_STRINGS_relative_time_to_string (delay, + GNUNET_YES)); + delay_in = delay; } + if ( (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_time (GST_cfg, + "transport", + "MANIPULATE_DELAY_OUT", + &delay)) && + (delay.rel_value_us > 0) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Delaying outbound traffic for %s\n", + GNUNET_STRINGS_relative_time_to_string (delay, + GNUNET_YES)); + delay_out = delay; + } + peers = GNUNET_CONTAINER_multipeermap_create (4, + GNUNET_NO); +} - if ((GNUNET_OK - == GNUNET_CONFIGURATION_get_value_number(GST_cfg, "transport", - "MANIPULATE_DISTANCE_OUT", &tmp)) && (tmp > 0)) - { - GNUNET_log(GNUNET_ERROR_TYPE_INFO, - "Setting outbound distance_in to %llu\n", (unsigned long long) tmp); - set_metric(&man_handle.general, TM_SEND, GNUNET_ATS_QUALITY_NET_DISTANCE, - tmp); - } - if ((GNUNET_OK - == GNUNET_CONFIGURATION_get_value_time(GST_cfg, "transport", - "MANIPULATE_DELAY_IN", &delay)) && (delay.rel_value_us > 0)) +/** + * Notify manipulation about disconnect so it can discard queued messages + * + * @param peer the disconnecting peer + */ +void +GST_manipulation_peer_disconnect (const struct GNUNET_PeerIdentity *peer) +{ + struct TM_Peer *tmp; + struct DelayQueueEntry *dqe; + struct DelayQueueEntry *next; + + tmp = GNUNET_CONTAINER_multipeermap_get (peers, + peer); + if (NULL != tmp) + { + while (NULL != (dqe = tmp->send_head)) { - GNUNET_log(GNUNET_ERROR_TYPE_INFO, - "Delaying inbound traffic for %s\n", GNUNET_STRINGS_relative_time_to_string (delay, GNUNET_YES)); - set_metric(&man_handle.general, TM_RECEIVE, GNUNET_ATS_QUALITY_NET_DELAY, - delay.rel_value_us); + GNUNET_CONTAINER_DLL_remove (tmp->send_head, + tmp->send_tail, + dqe); + if (NULL != dqe->cont) + dqe->cont (dqe->cont_cls, + GNUNET_SYSERR, + dqe->msg_size, + 0); + GNUNET_free(dqe); } - if ((GNUNET_OK - == GNUNET_CONFIGURATION_get_value_time(GST_cfg, "transport", - "MANIPULATE_DELAY_OUT", &delay)) && (delay.rel_value_us > 0)) + } + next = generic_dqe_head; + while (NULL != (dqe = next)) + { + next = dqe->next; + if (0 == memcmp(peer, &dqe->id, sizeof(dqe->id))) { - GNUNET_log(GNUNET_ERROR_TYPE_INFO, - "Delaying outbound traffic for %s\n", GNUNET_STRINGS_relative_time_to_string (delay, GNUNET_YES)); - set_metric(&man_handle.general, TM_SEND, GNUNET_ATS_QUALITY_NET_DELAY, - delay.rel_value_us); + GNUNET_CONTAINER_DLL_remove (generic_dqe_head, + generic_dqe_tail, + dqe); + if (NULL != dqe->cont) + dqe->cont (dqe->cont_cls, + GNUNET_SYSERR, + dqe->msg_size, + 0); + GNUNET_free(dqe); } - man_handle.peers = GNUNET_CONTAINER_multipeermap_create(10, GNUNET_NO); + } + if (NULL != generic_send_delay_task) + { + GNUNET_SCHEDULER_cancel (generic_send_delay_task); + generic_send_delay_task = NULL; + if (NULL != generic_dqe_head) + generic_send_delay_task + = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining(generic_dqe_head->sent_at), + &send_delayed, + generic_dqe_head); + } } +/** + * Free manipulation information about a peer. + * + * @param cls NULL + * @param key peer the info is about + * @param value a `struct TM_Peer` to free + * @return #GNUNET_OK (continue to iterate) + */ static int free_tmps (void *cls, const struct GNUNET_PeerIdentity *key, @@ -678,13 +538,10 @@ free_tmps (void *cls, struct TM_Peer *tmp = value; struct DelayQueueEntry *dqe; - if (NULL == tmp) - return GNUNET_OK; GNUNET_break (GNUNET_YES == - GNUNET_CONTAINER_multipeermap_remove (man_handle.peers, + GNUNET_CONTAINER_multipeermap_remove (peers, key, value)); - free_metric (tmp); while (NULL != (dqe = tmp->send_head)) { GNUNET_CONTAINER_DLL_remove (tmp->send_head, @@ -699,89 +556,27 @@ free_tmps (void *cls, } if (NULL != tmp->send_delay_task) { - GNUNET_SCHEDULER_cancel(tmp->send_delay_task); + GNUNET_SCHEDULER_cancel (tmp->send_delay_task); tmp->send_delay_task = NULL; } - GNUNET_free(tmp); + GNUNET_free (tmp); return GNUNET_OK; } -/** - * Notify manipulation about disconnect so it can discard queued messages - * - * @param peer the disconnecting peer - */ -void -GST_manipulation_peer_disconnect (const struct GNUNET_PeerIdentity *peer) -{ - struct TM_Peer *tmp; - struct DelayQueueEntry *dqe; - struct DelayQueueEntry *next; - - if (NULL != (tmp = GNUNET_CONTAINER_multipeermap_get(man_handle.peers, peer))) - { - while (NULL != (dqe = tmp->send_head)) - { - GNUNET_CONTAINER_DLL_remove (tmp->send_head, - tmp->send_tail, - dqe); - if (NULL != dqe->cont) - dqe->cont (dqe->cont_cls, - GNUNET_SYSERR, - dqe->msg_size, - 0); - GNUNET_free(dqe); - } - } - else if (UINT32_MAX != find_metric (&man_handle.general, - GNUNET_ATS_QUALITY_NET_DELAY, - TM_SEND)) - { - next = generic_dqe_head; - while (NULL != (dqe = next)) - { - next = dqe->next; - if (0 == memcmp(peer, &dqe->id, sizeof(dqe->id))) - { - GNUNET_CONTAINER_DLL_remove (generic_dqe_head, - generic_dqe_tail, - dqe); - if (NULL != dqe->cont) - dqe->cont (dqe->cont_cls, - GNUNET_SYSERR, - dqe->msg_size, - 0); - GNUNET_free(dqe); - } - } - if (NULL != generic_send_delay_task) - { - GNUNET_SCHEDULER_cancel (generic_send_delay_task); - generic_send_delay_task = NULL; - if (NULL != generic_dqe_head) - generic_send_delay_task - = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining(generic_dqe_head->sent_at), - &send_delayed, - generic_dqe_head); - } - } -} - - /** * Stop traffic manipulation */ void -GST_manipulation_stop() +GST_manipulation_stop () { struct DelayQueueEntry *cur; - GNUNET_CONTAINER_multipeermap_iterate (man_handle.peers, + GNUNET_CONTAINER_multipeermap_iterate (peers, &free_tmps, NULL); - GNUNET_CONTAINER_multipeermap_destroy (man_handle.peers); - + GNUNET_CONTAINER_multipeermap_destroy (peers); + peers = NULL; while (NULL != (cur = generic_dqe_head)) { GNUNET_CONTAINER_DLL_remove (generic_dqe_head, @@ -799,8 +594,6 @@ GST_manipulation_stop() GNUNET_SCHEDULER_cancel (generic_send_delay_task); generic_send_delay_task = NULL; } - free_metric (&man_handle.general); - man_handle.peers = NULL; } /* end of file gnunet-service-transport_manipulation.c */ diff --git a/src/transport/gnunet-service-transport_manipulation.h b/src/transport/gnunet-service-transport_manipulation.h index 8a3ab9849..1f87de249 100644 --- a/src/transport/gnunet-service-transport_manipulation.h +++ b/src/transport/gnunet-service-transport_manipulation.h @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2010,2011 Christian Grothoff (and other contributing authors) + Copyright (C) 2010-2015 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -20,7 +20,8 @@ /** * @file transport/gnunet-service-transport_neighbours.h - * @brief neighbour management API + * @brief neighbour manipulation API, allows manipulation of + * performance metrics (delay and towards ATS) * @author Christian Grothoff */ #ifndef GNUNET_SERVICE_TRANSPORT_MANIPULATION_H @@ -44,10 +45,11 @@ * @param client client sending message * @param message containing information */ - void -GST_manipulation_set_metric (void *cls, struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message); +GST_manipulation_set_metric (void *cls, + struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader *message); + /** * Adapter function between transport's send function and transport plugins @@ -61,9 +63,12 @@ GST_manipulation_set_metric (void *cls, struct GNUNET_SERVER_Client *client, */ void GST_manipulation_send (const struct GNUNET_PeerIdentity *target, - const void *msg, size_t msg_size, - struct GNUNET_TIME_Relative timeout, - GST_NeighbourSendContinuation cont, void *cont_cls); + const void *msg, + size_t msg_size, + struct GNUNET_TIME_Relative timeout, + GST_NeighbourSendContinuation cont, + void *cont_cls); + /** * Adapter function between transport plugins and transport receive function @@ -86,18 +91,14 @@ GST_manipulation_recv (void *cls, * Function that will be called to manipulate ATS information according to * current manipulation settings * - * @param peer the peer * @param address binary address * @param session the session - * @param ats the ats information - * @param ats_count the number of ats information - * @return modified @a ats information + * @param prop[IN|OUT] metrics to modify */ -struct GNUNET_ATS_Information * +void GST_manipulation_manipulate_metrics (const struct GNUNET_HELLO_Address *address, struct Session *session, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count); + struct GNUNET_ATS_Properties *prop); /** @@ -108,19 +109,19 @@ GST_manipulation_manipulate_metrics (const struct GNUNET_HELLO_Address *address, void GST_manipulation_peer_disconnect (const struct GNUNET_PeerIdentity *peer); + /** * Initialize traffic manipulation - * - * @param GST_cfg configuration handle */ void -GST_manipulation_init (const struct GNUNET_CONFIGURATION_Handle *GST_cfg); +GST_manipulation_init (void); + /** * Stop traffic manipulation */ void -GST_manipulation_stop (); +GST_manipulation_stop (void); #endif /* end of file gnunet-service-transport_neighbours.h */ diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c index 5cfb5ed6d..623712efa 100644 --- a/src/transport/gnunet-service-transport_neighbours.c +++ b/src/transport/gnunet-service-transport_neighbours.c @@ -1481,7 +1481,6 @@ GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour, struct NeighbourMapEntry *n; const struct SessionKeepAliveMessage *msg; struct GNUNET_TRANSPORT_PluginFunctions *papi; - struct GNUNET_ATS_Information ats; struct GNUNET_TIME_Relative latency; if (sizeof (struct SessionKeepAliveMessage) != ntohs (m->size)) @@ -1524,8 +1523,9 @@ GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour, else { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received keep alive response from peer `%s' for session %p\n", - GNUNET_i2s (&n->id), n->primary_address.session); + "Received keep alive response from peer `%s' for session %p\n", + GNUNET_i2s (&n->id), + n->primary_address.session); } @@ -1533,9 +1533,12 @@ GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour, if (NULL != (papi = GST_plugins_find (n->primary_address.address->transport_name))) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Updating session for peer `%s' for session %p\n", - GNUNET_i2s (&n->id), n->primary_address.session); - papi->update_session_timeout (papi->cls, &n->id, n->primary_address.session); + "Updating session for peer `%s' for session %p\n", + GNUNET_i2s (&n->id), + n->primary_address.session); + papi->update_session_timeout (papi->cls, + &n->id, + n->primary_address.session); } else { @@ -1554,15 +1557,8 @@ GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour, GNUNET_i2s (&n->id), GNUNET_STRINGS_relative_time_to_string (latency, GNUNET_YES)); - /* append latency */ - ats.type = htonl (GNUNET_ATS_QUALITY_NET_DELAY); - ats.value = htonl ( (latency.rel_value_us > UINT32_MAX) - ? UINT32_MAX - : (uint32_t) latency.rel_value_us ); - GST_ats_update_metrics (n->primary_address.address, - n->primary_address.session, - &ats, - 1); + GST_ats_update_delay (n->primary_address.address, + GNUNET_TIME_relative_divide (latency, 2)); } @@ -1579,8 +1575,9 @@ GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour, * @return how long to wait before reading more from this sender */ struct GNUNET_TIME_Relative -GST_neighbours_calculate_receive_delay (const struct GNUNET_PeerIdentity - *sender, ssize_t size, int *do_forward) +GST_neighbours_calculate_receive_delay (const struct GNUNET_PeerIdentity *sender, + ssize_t size, + int *do_forward) { struct NeighbourMapEntry *n; struct GNUNET_TIME_Relative ret; @@ -2824,7 +2821,6 @@ send_utilization_data (void *cls, void *value) { struct NeighbourMapEntry *n = value; - struct GNUNET_ATS_Information atsi[2]; uint32_t bps_in; uint32_t bps_out; struct GNUNET_TIME_Relative delta; @@ -2846,14 +2842,9 @@ send_utilization_data (void *cls, GNUNET_i2s (key), bps_in, bps_out); - atsi[0].type = htonl (GNUNET_ATS_UTILIZATION_OUT); - atsi[0].value = htonl (bps_out); - atsi[1].type = htonl (GNUNET_ATS_UTILIZATION_IN); - atsi[1].value = htonl (bps_in); - GST_ats_update_metrics (n->primary_address.address, - n->primary_address.session, - atsi, - 2); + GST_ats_update_utilization (n->primary_address.address, + bps_in, + bps_out); n->util_total_bytes_recv = 0; n->util_total_bytes_sent = 0; n->last_util_transmission = GNUNET_TIME_absolute_get (); @@ -3426,9 +3417,9 @@ GST_neighbours_handle_session_ack (const struct GNUNET_MessageHeader *message, return GNUNET_SYSERR; } GNUNET_STATISTICS_update (GST_stats, - gettext_noop - ("# ACK messages received"), - 1, GNUNET_NO); + gettext_noop ("# ACK messages received"), + 1, + GNUNET_NO); if (NULL == (n = lookup_neighbour (&address->peer))) { GNUNET_break_op (0); diff --git a/src/transport/gnunet-service-transport_plugins.c b/src/transport/gnunet-service-transport_plugins.c index 1571cee71..cbfa50afd 100644 --- a/src/transport/gnunet-service-transport_plugins.c +++ b/src/transport/gnunet-service-transport_plugins.c @@ -85,19 +85,15 @@ static struct TransportPlugin *plugins_tail; * @param cls closure * @param address address to update metrics for * @param session the session - * @param ats the ats information to update - * @param ats_count the number of @a ats elements + * @param distance new distance */ static void -plugin_env_update_metrics (void *cls, - const struct GNUNET_HELLO_Address *address, - struct Session *session, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count) +plugin_env_update_distance (void *cls, + const struct GNUNET_HELLO_Address *address, + uint32_t distance) { - GST_ats_update_metrics (address, - session, - ats, ats_count); + GST_ats_update_distance (address, + distance); } @@ -191,7 +187,7 @@ GST_plugins_load (GNUNET_TRANSPORT_PluginReceiveCallback recv_cb, plug->env.session_start = session_start_cb; plug->env.session_end = session_end_cb; plug->env.get_address_type = &plugin_env_address_to_type; - plug->env.update_address_metrics = &plugin_env_update_metrics; + plug->env.update_address_distance = &plugin_env_update_distance; plug->env.max_connections = tneigh; plug->env.stats = GST_stats; GNUNET_CONTAINER_DLL_insert (plugins_head, diff --git a/src/transport/gnunet-service-transport_validation.c b/src/transport/gnunet-service-transport_validation.c index d8966f1a4..b6b323bd0 100644 --- a/src/transport/gnunet-service-transport_validation.c +++ b/src/transport/gnunet-service-transport_validation.c @@ -804,7 +804,7 @@ add_valid_address (void *cls, const struct GNUNET_HELLO_Message *hello = cls; struct ValidationEntry *ve; struct GNUNET_PeerIdentity pid; - struct GNUNET_ATS_Information ats; + struct GNUNET_ATS_Properties prop; if (0 == GNUNET_TIME_absolute_get_remaining (expiration).rel_value_us) return GNUNET_OK; /* expired */ @@ -832,13 +832,13 @@ add_valid_address (void *cls, ve->revalidation_task = GNUNET_SCHEDULER_add_now (&revalidate_address, ve); } validation_entry_changed (ve, GNUNET_TRANSPORT_VS_UPDATE); - - ats.type = htonl (GNUNET_ATS_NETWORK_TYPE); - ats.value = htonl (ve->network); + memset (&prop, 0, sizeof (prop)); + prop.scope = ve->network; + prop.delay = GNUNET_TIME_relative_divide (ve->latency, 2); if (GNUNET_YES != ve->known_to_ats) { ve->known_to_ats = GNUNET_YES; - GST_ats_add_address (address, &ats, 1); + GST_ats_add_address (address, &prop); } return GNUNET_OK; } @@ -1465,23 +1465,20 @@ GST_validation_handle_pong (const struct GNUNET_PeerIdentity *sender, ve->pong_sig_valid_until = GNUNET_TIME_absolute_ntoh (pong->expiration); ve->latency = GNUNET_TIME_absolute_get_duration (ve->send_time); { - struct GNUNET_ATS_Information ats[2]; - - ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DELAY); - ats[0].value = htonl ((uint32_t) ve->latency.rel_value_us); - ats[1].type = htonl (GNUNET_ATS_NETWORK_TYPE); - ats[1].value = htonl ((uint32_t) ve->network); if (GNUNET_YES == ve->known_to_ats) { - GST_ats_update_metrics (ve->address, - NULL, - ats, - 2); + GST_ats_update_delay (ve->address, + GNUNET_TIME_relative_divide (ve->latency, 2)); } else { + struct GNUNET_ATS_Properties prop; + + memset (&prop, 0, sizeof (prop)); + prop.scope = ve->network; + prop.delay = GNUNET_TIME_relative_divide (ve->latency, 2); ve->known_to_ats = GNUNET_YES; - GST_ats_add_address (ve->address, ats, 2); + GST_ats_add_address (ve->address, &prop); } } if (validations_running > 0) diff --git a/src/transport/plugin_transport_http_client.c b/src/transport/plugin_transport_http_client.c index 6e994d467..165045a8a 100644 --- a/src/transport/plugin_transport_http_client.c +++ b/src/transport/plugin_transport_http_client.c @@ -264,7 +264,7 @@ struct Session /** * ATS network type. */ - enum GNUNET_ATS_Network_Type ats_address_network_type; + enum GNUNET_ATS_Network_Type scope; }; @@ -1169,23 +1169,13 @@ client_receive_mst_cb (void *cls, struct Session *s = cls; struct HTTP_Client_Plugin *plugin; struct GNUNET_TIME_Relative delay; - struct GNUNET_ATS_Information atsi; char *stat_txt; plugin = s->plugin; - GNUNET_break (s->ats_address_network_type != GNUNET_ATS_NET_UNSPECIFIED); - atsi.type = htonl (GNUNET_ATS_NETWORK_TYPE); - atsi.value = htonl (s->ats_address_network_type); - delay = s->plugin->env->receive (plugin->env->cls, s->address, s, message); - plugin->env->update_address_metrics (plugin->env->cls, - s->address, - s, - &atsi, 1); - GNUNET_asprintf (&stat_txt, "# bytes received via %s_client", plugin->protocol); @@ -1943,7 +1933,7 @@ static enum GNUNET_ATS_Network_Type http_client_plugin_get_network (void *cls, struct Session *session) { - return session->ats_address_network_type; + return session->scope; } @@ -2057,7 +2047,7 @@ http_client_plugin_get_session (void *cls, s = GNUNET_new (struct Session); s->plugin = plugin; s->address = GNUNET_HELLO_address_copy (address); - s->ats_address_network_type = net_type; + s->scope = net_type; s->put.state = H_NOT_CONNECTED; s->timeout = GNUNET_TIME_relative_to_absolute (HTTP_CLIENT_SESSION_TIMEOUT); diff --git a/src/transport/plugin_transport_http_server.c b/src/transport/plugin_transport_http_server.c index 9d956b29d..9d34ef291 100644 --- a/src/transport/plugin_transport_http_server.c +++ b/src/transport/plugin_transport_http_server.c @@ -255,9 +255,9 @@ struct Session uint32_t tag; /** - * ATS network type in NBO + * ATS network type. */ - uint32_t ats_address_network_type; + enum GNUNET_ATS_Network_Type scope; /** * #GNUNET_YES if this session is known to the service. @@ -1363,13 +1363,13 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin, struct ServerRequest *sc = NULL; const union MHD_ConnectionInfo *conn_info; struct HttpAddress *addr; - struct GNUNET_ATS_Information ats; struct GNUNET_PeerIdentity target; size_t addr_len; struct SessionTagContext stc; uint32_t options; int direction = GNUNET_SYSERR; unsigned int to; + enum GNUNET_ATS_Network_Type scope; conn_info = MHD_get_connection_info (mhd_connection, MHD_CONNECTION_INFO_CLIENT_ADDRESS); @@ -1424,36 +1424,32 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin, conn_info->client_addr, sizeof (struct sockaddr_in)); addr_len = http_common_address_get_size (addr); - ats.type = htonl (GNUNET_ATS_NETWORK_TYPE); - ats.value = htonl (plugin->env->get_address_type (plugin->env->cls, - conn_info->client_addr, - sizeof (struct sockaddr_in))); + scope = plugin->env->get_address_type (plugin->env->cls, + conn_info->client_addr, + sizeof (struct sockaddr_in)); break; case (AF_INET6): addr = http_common_address_from_socket (plugin->protocol, conn_info->client_addr, sizeof (struct sockaddr_in6)); addr_len = http_common_address_get_size (addr); - ats.type = htonl (GNUNET_ATS_NETWORK_TYPE); - ats.value = htonl (plugin->env->get_address_type (plugin->env->cls, - conn_info->client_addr, - sizeof (struct sockaddr_in6))); + scope = plugin->env->get_address_type (plugin->env->cls, + conn_info->client_addr, + sizeof (struct sockaddr_in6)); break; default: /* external host name */ - ats.type = htonl (GNUNET_ATS_NETWORK_TYPE); - ats.value = htonl (GNUNET_ATS_NET_WAN); return NULL; } s = GNUNET_new (struct Session); s->target = target; s->plugin = plugin; + s->scope = scope; s->address = GNUNET_HELLO_address_allocate (&s->target, PLUGIN_NAME, addr, addr_len, GNUNET_HELLO_ADDRESS_INFO_INBOUND); - s->ats_address_network_type = ats.value; s->next_receive = GNUNET_TIME_UNIT_ZERO_ABS; s->tag = stc.tag; s->timeout = GNUNET_TIME_relative_to_absolute (HTTP_SERVER_SESSION_TIMEOUT); @@ -1526,7 +1522,7 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin, plugin->env->session_start (plugin->env->cls, s->address, s, - NULL, 0); + s->scope); } if ( (NULL == s->server_recv) || @@ -1659,23 +1655,16 @@ server_receive_mst_cb (void *cls, { struct Session *s = cls; struct HTTP_Server_Plugin *plugin = s->plugin; - struct GNUNET_ATS_Information atsi; struct GNUNET_TIME_Relative delay; char *stat_txt; - atsi.type = htonl (GNUNET_ATS_NETWORK_TYPE); - atsi.value = s->ats_address_network_type; - GNUNET_break (s->ats_address_network_type != - ntohl (GNUNET_ATS_NET_UNSPECIFIED)); - if (GNUNET_NO == s->known_to_service) { s->known_to_service = GNUNET_YES; plugin->env->session_start (plugin->env->cls, s->address, s, - NULL, - 0); + s->scope); notify_session_monitor (plugin, s, GNUNET_TRANSPORT_SS_UP); @@ -1684,9 +1673,6 @@ server_receive_mst_cb (void *cls, s->address, s, message); - plugin->env->update_address_metrics (plugin->env->cls, - s->address, s, - &atsi, 1); GNUNET_asprintf (&stat_txt, "# bytes received via %s_server", plugin->protocol); @@ -3287,7 +3273,7 @@ static enum GNUNET_ATS_Network_Type http_server_plugin_get_network (void *cls, struct Session *session) { - return ntohl (session->ats_address_network_type); + return session->scope; } diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c index 5396d5247..19ce855d8 100644 --- a/src/transport/plugin_transport_tcp.c +++ b/src/transport/plugin_transport_tcp.c @@ -330,6 +330,11 @@ struct Session */ unsigned int msgs_in_queue; + /** + * Network type of the address. + */ + enum GNUNET_ATS_Network_Type scope; + /** * Are we still expecting the welcome message? (#GNUNET_YES/#GNUNET_NO) */ @@ -340,12 +345,9 @@ struct Session */ int is_nat; - /** - * ATS network type in NBO - */ - enum GNUNET_ATS_Network_Type ats_address_network_type; }; + /** * Encapsulation of all of the state of the plugin. */ @@ -1011,7 +1013,7 @@ create_session (struct Plugin *plugin, session->address = GNUNET_HELLO_address_copy (address); session->target = address->peer; session->expecting_welcome = GNUNET_YES; - session->ats_address_network_type = GNUNET_ATS_NET_UNSPECIFIED; + session->scope = GNUNET_ATS_NET_UNSPECIFIED; pm = GNUNET_malloc (sizeof (struct PendingMessage) + sizeof (struct WelcomeMessage)); pm->msg = (const char *) &pm[1]; @@ -1627,7 +1629,7 @@ tcp_plugin_get_session (void *cls, } net_type = plugin->env->get_address_type (plugin->env->cls, sb, sbs); - + GNUNET_break (net_type != GNUNET_ATS_NET_UNSPECIFIED); if ((is_natd == GNUNET_YES) && (addrlen == sizeof(struct IPv6TcpAddress))) { @@ -1661,8 +1663,7 @@ tcp_plugin_get_session (void *cls, address, NULL, GNUNET_YES); - session->ats_address_network_type = net_type; - GNUNET_break (session->ats_address_network_type != GNUNET_ATS_NET_UNSPECIFIED); + session->scope = net_type; session->nat_connection_timeout = GNUNET_SCHEDULER_add_delayed (NAT_TIMEOUT, &nat_connect_timeout, session); @@ -1759,9 +1760,9 @@ tcp_plugin_get_session (void *cls, address, GNUNET_SERVER_connect_socket (plugin->server, sa), GNUNET_NO); - session->ats_address_network_type = net_type; - GNUNET_break (session->ats_address_network_type != GNUNET_ATS_NET_UNSPECIFIED); - GNUNET_SERVER_client_set_user_context(session->client, session); + session->scope = net_type; + GNUNET_SERVER_client_set_user_context (session->client, + session); GNUNET_CONTAINER_multipeermap_put (plugin->sessionmap, &session->target, session, @@ -2253,6 +2254,7 @@ handle_tcp_nat_probe (void *cls, GNUNET_SERVER_receive_done (client, GNUNET_OK); } + /** * We've received a welcome from this peer via TCP. Possibly create a * fresh client record and send back our welcome. @@ -2276,8 +2278,6 @@ handle_tcp_welcome (void *cls, struct IPv6TcpAddress t6; const struct sockaddr_in *s4; const struct sockaddr_in6 *s6; - struct GNUNET_ATS_Information ats; - if (0 == memcmp (&wm->clientIdentity, plugin->env->my_identity, @@ -2369,12 +2369,10 @@ handle_tcp_welcome (void *cls, client, GNUNET_NO); GNUNET_HELLO_address_free (address); - session->ats_address_network_type + session->scope = plugin->env->get_address_type (plugin->env->cls, vaddr, alen); - ats.type = htonl (GNUNET_ATS_NETWORK_TYPE); - ats.value = htonl (session->ats_address_network_type); LOG (GNUNET_ERROR_TYPE_DEBUG, "Creating new%s session %p for peer `%s' client %p \n", GNUNET_HELLO_address_check_option (session->address, @@ -2395,7 +2393,7 @@ handle_tcp_welcome (void *cls, plugin->env->session_start (plugin->env->cls, session->address, session, - &ats, 1); + session->scope); notify_session_monitor (plugin, session, GNUNET_TRANSPORT_SS_INIT); @@ -2443,7 +2441,6 @@ handle_tcp_data (void *cls, struct Session *session; struct GNUNET_TIME_Relative delay; uint16_t type; - struct GNUNET_ATS_Information distance; type = ntohs (message->type); if ( (GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_WELCOME == type) || @@ -2507,10 +2504,6 @@ handle_tcp_data (void *cls, ntohs (message->size), GNUNET_NO); - distance.type = htonl (GNUNET_ATS_NETWORK_TYPE); - distance.value = htonl ((uint32_t) session->ats_address_network_type); - GNUNET_break (session->ats_address_network_type != GNUNET_ATS_NET_UNSPECIFIED); - GNUNET_assert (GNUNET_CONTAINER_multipeermap_contains_value (plugin->sessionmap, &session->target, session)); @@ -2518,10 +2511,6 @@ handle_tcp_data (void *cls, session->address, session, message); - plugin->env->update_address_metrics (plugin->env->cls, - session->address, - session, - &distance, 1); reschedule_session_timeout (session); if (0 == delay.rel_value_us) { @@ -2680,7 +2669,7 @@ static enum GNUNET_ATS_Network_Type tcp_plugin_get_network (void *cls, struct Session *session) { - return session->ats_address_network_type; + return session->scope; } diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c index f185c8738..477efc0a1 100644 --- a/src/transport/plugin_transport_udp.c +++ b/src/transport/plugin_transport_udp.c @@ -172,12 +172,6 @@ struct Session */ struct GNUNET_TIME_Relative last_expected_msg_delay; - /** - * Address metrics (as set by the "update_address_metrics" by - * the environment). - */ - struct GNUNET_ATS_Information ats; - /** * Our own address. */ @@ -201,6 +195,11 @@ struct Session */ unsigned int rc; + /** + * Network type of the address. + */ + enum GNUNET_ATS_Network_Type scope; + /** * Is this session about to be destroyed (sometimes we cannot * destroy a session immediately as below us on the stack @@ -1595,7 +1594,7 @@ static enum GNUNET_ATS_Network_Type udp_get_network (void *cls, struct Session *session) { - return ntohl (session->ats.value); + return session->scope; } @@ -1742,11 +1741,8 @@ udp_plugin_create_session (void *cls, struct Session *s; s = create_session (plugin, address); - s->ats.type = htonl (GNUNET_ATS_NETWORK_TYPE); - s->ats.value = htonl (network_type); + s->scope = network_type; - if (NULL == s) - return NULL; /* protocol not supported or address invalid */ LOG (GNUNET_ERROR_TYPE_DEBUG, "Creating new session %p for peer `%s' address `%s'\n", s, @@ -2213,16 +2209,11 @@ process_inbound_tokenized_messages (void *cls, if (GNUNET_YES == si->session->in_destroy) return GNUNET_OK; /* setup ATS */ - GNUNET_break (ntohl (si->session->ats.value) != GNUNET_ATS_NET_UNSPECIFIED); reschedule_session_timeout (si->session); delay = plugin->env->receive (plugin->env->cls, si->session->address, si->session, hdr); - plugin->env->update_address_metrics (plugin->env->cls, - si->session->address, - si->session, - &si->session->ats, 1); si->session->flow_delay_for_other_peer = delay; return GNUNET_OK; } @@ -2274,8 +2265,7 @@ process_udp_message (struct Plugin *plugin, plugin->env->session_start (plugin->env->cls, address, s, - NULL, - 0); + s->scope); notify_session_monitor (s->plugin, s, GNUNET_TRANSPORT_SS_INIT); diff --git a/src/transport/plugin_transport_udp_broadcasting.c b/src/transport/plugin_transport_udp_broadcasting.c index 413c79564..e7b7cdc23 100644 --- a/src/transport/plugin_transport_udp_broadcasting.c +++ b/src/transport/plugin_transport_udp_broadcasting.c @@ -142,7 +142,6 @@ broadcast_mst_cb (void *cls, struct GNUNET_HELLO_Address *address; const struct GNUNET_MessageHeader *hello; const struct UDP_Beacon_Message *msg; - struct GNUNET_ATS_Information atsi; msg = (const struct UDP_Beacon_Message *) message; @@ -156,13 +155,6 @@ broadcast_mst_cb (void *cls, udp_address_to_string (NULL, mc->udp_addr, mc->udp_addr_len)); - - /* setup ATS */ - atsi.type = htonl (GNUNET_ATS_NETWORK_TYPE); - atsi.value = htonl (mc->ats_address_network_type); - GNUNET_break (ntohl(mc->ats_address_network_type) != - GNUNET_ATS_NET_UNSPECIFIED); - hello = (struct GNUNET_MessageHeader *) &msg[1]; address = GNUNET_HELLO_address_allocate (&msg->sender, PLUGIN_NAME, @@ -173,11 +165,6 @@ broadcast_mst_cb (void *cls, address, NULL, hello); - plugin->env->update_address_metrics (plugin->env->cls, - address, - NULL, - &atsi, - 1); GNUNET_HELLO_address_free (address); GNUNET_STATISTICS_update (plugin->env->stats, _("# Multicast HELLO beacons received via UDP"), diff --git a/src/transport/plugin_transport_unix.c b/src/transport/plugin_transport_unix.c index 160aaddaf..ddb5f747c 100644 --- a/src/transport/plugin_transport_unix.c +++ b/src/transport/plugin_transport_unix.c @@ -317,11 +317,6 @@ struct Plugin */ uint32_t myoptions; - /** - * ATS network - */ - struct GNUNET_ATS_Information ats_network; - /** * Are we using an abstract UNIX domain socket? */ @@ -947,12 +942,12 @@ static void unix_demultiplexer (struct Plugin *plugin, struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *currhdr, - const struct UnixAddress *ua, size_t ua_len) + const struct UnixAddress *ua, + size_t ua_len) { struct Session *session; struct GNUNET_HELLO_Address *address; - GNUNET_break (ntohl(plugin->ats_network.value) != GNUNET_ATS_NET_UNSPECIFIED); GNUNET_assert (ua_len >= sizeof (struct UnixAddress)); LOG (GNUNET_ERROR_TYPE_DEBUG, "Received message from %s\n", @@ -975,7 +970,7 @@ unix_demultiplexer (struct Plugin *plugin, plugin->env->session_start (NULL, session->address, session, - &plugin->ats_network, 1); + GNUNET_ATS_NET_LOOPBACK); } else { @@ -986,10 +981,6 @@ unix_demultiplexer (struct Plugin *plugin, session->address, session, currhdr); - plugin->env->update_address_metrics (plugin->env->cls, - session->address, - session, - &plugin->ats_network, 1); } @@ -1387,10 +1378,6 @@ unix_transport_server_start (void *cls) plugin->unix_socket_path[0] = '@'; un->sun_path[0] = '\0'; } - plugin->ats_network.type = htonl (GNUNET_ATS_NETWORK_TYPE); - plugin->ats_network.value = htonl (plugin->env->get_address_type (plugin->env->cls, - (const struct sockaddr *) un, - un_len)); plugin->unix_sock.desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_DGRAM, 0); if (NULL == plugin->unix_sock.desc) diff --git a/src/transport/plugin_transport_wlan.c b/src/transport/plugin_transport_wlan.c index 42b7d8669..c0e629b83 100644 --- a/src/transport/plugin_transport_wlan.c +++ b/src/transport/plugin_transport_wlan.c @@ -98,6 +98,15 @@ #define WLAN_MTU 1430 +/** + * Which network scope do we belong to? + */ +#if BUILD_WLAN +static const enum GNUNET_ATS_Network_Type scope = GNUNET_ATS_NET_WLAN; +#else +static const enum GNUNET_ATS_Network_Type scope = GNUNET_ATS_NET_BT; +#endif + /** * Maximum number of messages in defragmentation queue per MAC @@ -1428,19 +1437,12 @@ process_data (void *cls, struct Plugin *plugin = cls; struct GNUNET_HELLO_Address *address; struct MacAndSession *mas = client; - struct GNUNET_ATS_Information ats; struct FragmentMessage *fm; struct GNUNET_PeerIdentity tmpsource; const struct WlanHeader *wlanheader; int ret; uint16_t msize; - ats.type = htonl (GNUNET_ATS_NETWORK_TYPE); -#if BUILD_WLAN - ats.value = htonl (GNUNET_ATS_NET_WLAN); -#else - ats.value = htonl (GNUNET_ATS_NET_BT); -#endif msize = ntohs (hdr->size); GNUNET_STATISTICS_update (plugin->env->stats, @@ -1489,16 +1491,12 @@ process_data (void *cls, plugin->env->session_start (plugin->env->cls, address, mas->session, - &ats, 1); + scope); } plugin->env->receive (plugin->env->cls, address, mas->session, hdr); - plugin->env->update_address_metrics (plugin->env->cls, - address, - mas->session, - &ats, 1); GNUNET_HELLO_address_free (address); break; case GNUNET_MESSAGE_TYPE_FRAGMENT: @@ -1615,7 +1613,7 @@ process_data (void *cls, plugin->env->session_start (plugin->env->cls, address, mas->session, - NULL, 0); + scope); LOG (GNUNET_ERROR_TYPE_DEBUG, "Notifying transport about peer `%s''s new session %p \n", GNUNET_i2s (&wlanheader->sender), @@ -1654,10 +1652,6 @@ process_data (void *cls, mas->session->address, mas->session, hdr); - plugin->env->update_address_metrics (plugin->env->cls, - mas->session->address, - mas->session, - &ats, 1); break; } return GNUNET_OK; diff --git a/src/transport/test_plugin_transport.c b/src/transport/test_plugin_transport.c index 1bd0a2dcd..df7c7b23f 100644 --- a/src/transport/test_plugin_transport.c +++ b/src/transport/test_plugin_transport.c @@ -522,11 +522,9 @@ env_session_end (void *cls, static void -env_update_metrics (void *cls, - const struct GNUNET_HELLO_Address *address, - struct Session *session, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count) +env_update_distance (void *cls, + const struct GNUNET_HELLO_Address *address, + uint32_t distance) { } @@ -542,7 +540,7 @@ setup_plugin_environment () env.receive = &env_receive; env.notify_address = &env_notify_address; env.get_address_type = &env_get_address_type; - env.update_address_metrics = &env_update_metrics; + env.update_address_distance = &env_update_distance; env.get_our_hello = &env_get_our_hello; env.session_end = &env_session_end; } diff --git a/src/transport/test_transport_api_manipulation_recv_tcp.c b/src/transport/test_transport_api_manipulation_recv_tcp.c index 7aaa9caee..ffb725efd 100644 --- a/src/transport/test_transport_api_manipulation_recv_tcp.c +++ b/src/transport/test_transport_api_manipulation_recv_tcp.c @@ -197,21 +197,25 @@ notify_receive (void *cls, const struct GNUNET_PeerIdentity *peer, if (messages_recv <= 1) { - /* Received non-delayed message */ - dur_normal = GNUNET_TIME_absolute_get_duration(start_normal); + /* Received non-delayed message */ + dur_normal = GNUNET_TIME_absolute_get_duration(start_normal); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received non-delayed message %u after %s\n", messages_recv, GNUNET_STRINGS_relative_time_to_string (dur_normal, GNUNET_YES)); - struct GNUNET_ATS_Information ats[2]; - ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DELAY); - ats[0].value = htonl (1000 * 1000LL); - ats[1].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); - ats[1].value = htonl (10); - - GNUNET_TRANSPORT_set_traffic_metric (p1->th, &p2->id, GNUNET_YES, GNUNET_NO, ats, 2); + struct GNUNET_ATS_Properties prop; + struct GNUNET_TIME_Relative delay; + + delay.rel_value_us = 1000 * 1000LL; + memset (&prop, 0, sizeof (prop)); + prop.distance = 10; + GNUNET_TRANSPORT_set_traffic_metric (p1->th, + &p2->id, + &prop, + delay, + GNUNET_TIME_UNIT_ZERO); send_task = GNUNET_SCHEDULER_add_now (&sendtask, NULL); } if (2 == messages_recv) diff --git a/src/transport/test_transport_api_manipulation_send_tcp.c b/src/transport/test_transport_api_manipulation_send_tcp.c index 90d0ef994..3043dc037 100644 --- a/src/transport/test_transport_api_manipulation_send_tcp.c +++ b/src/transport/test_transport_api_manipulation_send_tcp.c @@ -272,35 +272,46 @@ notify_ready (void *cls, size_t size, void *buf) static void -sendtask (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +sendtask (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct GNUNET_ATS_Information ats[1]; - send_task = NULL; + struct GNUNET_TIME_Relative delay; + struct GNUNET_ATS_Properties prop; + send_task = NULL; if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) return; char *receiver_s = GNUNET_strdup (GNUNET_i2s (&p1->id)); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending message from peer %u (`%4s') -> peer %u (`%s') !\n", - p2->no, GNUNET_i2s (&p2->id), p1->no, receiver_s); + p2->no, + GNUNET_i2s (&p2->id), + p1->no, + receiver_s); GNUNET_free (receiver_s); if (0 == messages_recv) { - start_normal = GNUNET_TIME_absolute_get(); + start_normal = GNUNET_TIME_absolute_get (); } if (1 == messages_recv) { - ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DELAY); - ats[0].value = htonl (1000LL * 1000LL); - GNUNET_TRANSPORT_set_traffic_metric (p2->th, &p1->id, GNUNET_NO, GNUNET_YES, ats, 1); - ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); - ats[0].value = htonl (10); - GNUNET_TRANSPORT_set_traffic_metric (p1->th, &p2->id, GNUNET_YES, GNUNET_YES, ats, 1); - - start_delayed = GNUNET_TIME_absolute_get(); + memset (&prop, 0, sizeof (prop)); + delay.rel_value_us = 1000LL * 1000LL; + GNUNET_TRANSPORT_set_traffic_metric (p2->th, + &p1->id, + &prop, + GNUNET_TIME_UNIT_ZERO, + delay); + prop.distance = 10; + GNUNET_TRANSPORT_set_traffic_metric (p1->th, + &p2->id, + &prop, + delay, + delay); + start_delayed = GNUNET_TIME_absolute_get(); } s_sending = GNUNET_YES; @@ -358,7 +369,8 @@ testing_connect_cb (struct PeerContext *p1, struct PeerContext *p2, void *cls) cc = NULL; char *p1_c = GNUNET_strdup (GNUNET_i2s (&p1->id)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peers connected: %u (%s) <-> %u (%s)\n", + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Peers connected: %u (%s) <-> %u (%s)\n", p1->no, p1_c, p2->no, GNUNET_i2s (&p2->id)); GNUNET_free (p1_c); @@ -386,16 +398,8 @@ start_cb (struct PeerContext *p, void *cls) "Test tries to connect peer %u (`%s') -> peer %u (`%s')\n", p1->no, sender_c, p2->no, GNUNET_i2s (&p2->id)); GNUNET_free (sender_c); - /* - struct GNUNET_ATS_Information ats[2]; - ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DELAY); - ats[0].value = htonl (1000); - ats[1].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); - ats[1].value = htonl (10); - - GNUNET_TRANSPORT_set_traffic_metric (p1->th, &p2->id, TM_RECEIVE, ats, 2); -*/ - cc = GNUNET_TRANSPORT_TESTING_connect_peers (tth, p1, p2, &testing_connect_cb, + cc = GNUNET_TRANSPORT_TESTING_connect_peers (tth, p1, p2, + &testing_connect_cb, NULL); } @@ -485,4 +489,4 @@ main (int argc, char *argv[]) return ret; } -/* end of test_transport_api.c */ +/* end of test_transport_api_manipulation_send_tcp.c */ diff --git a/src/transport/transport.h b/src/transport/transport.h index 9ee672d3a..15cf936f7 100644 --- a/src/transport/transport.h +++ b/src/transport/transport.h @@ -468,7 +468,7 @@ struct ValidationMonitorMessage /** * One shot call or continous replies? */ - uint32_t one_shot; + uint32_t one_shot GNUNET_PACKED; /** * The identity of the peer to look up. @@ -492,7 +492,7 @@ struct PeerMonitorMessage /** * One shot call or continous replies? */ - uint32_t one_shot; + uint32_t one_shot GNUNET_PACKED; /** * The identity of the peer to look up. @@ -514,19 +514,29 @@ struct TrafficMetricMessage struct GNUNET_MessageHeader header; /** - * SEND, RECEIVE or BOTH? + * Always zero. */ - uint16_t direction; + uint32_t reserved GNUNET_PACKED; /** - * Traffic metrics count + * The identity of the peer to look up. */ - uint16_t ats_count; + struct GNUNET_PeerIdentity peer; /** - * The identity of the peer to look up. + * Fake properties to generate. */ - struct GNUNET_PeerIdentity peer; + struct GNUNET_ATS_PropertiesNBO properties; + + /** + * Fake delay to add on inbound traffic. + */ + struct GNUNET_TIME_RelativeNBO delay_in; + + /** + * Fake delay to add on outbound traffic. + */ + struct GNUNET_TIME_RelativeNBO delay_out; }; diff --git a/src/transport/transport_api.c b/src/transport/transport_api.c index d672b4d46..6e47b269b 100644 --- a/src/transport/transport_api.c +++ b/src/transport/transport_api.c @@ -1054,7 +1054,8 @@ schedule_transmission (struct GNUNET_TRANSPORT_Handle *h) * @return a `struct GNUNET_TRANSPORT_TransmitHandle` */ static struct GNUNET_TRANSPORT_TransmitHandle * -schedule_control_transmit (struct GNUNET_TRANSPORT_Handle *h, size_t size, +schedule_control_transmit (struct GNUNET_TRANSPORT_Handle *h, + size_t size, GNUNET_TRANSPORT_TransmitReadyNotify notify, void *notify_cls) { @@ -1476,7 +1477,9 @@ send_hello (void *cls, size_t size, void *buf) * @return number of bytes copied to @a buf */ static size_t -send_metric (void *cls, size_t size, void *buf) +send_metric (void *cls, + size_t size, + void *buf) { struct TrafficMetricMessage *msg = cls; uint16_t ssize; @@ -1484,14 +1487,12 @@ send_metric (void *cls, size_t size, void *buf) if (NULL == buf) { LOG (GNUNET_ERROR_TYPE_DEBUG, - "Timeout while trying to transmit `%s' request.\n", - "TRAFFIC_METRIC"); + "Timeout while trying to transmit TRAFFIC_METRIC request.\n"); GNUNET_free (msg); return 0; } LOG (GNUNET_ERROR_TYPE_DEBUG, - "Transmitting `%s' request.\n", - "TRAFFIC_METRIC"); + "Transmitting TRAFFIC_METRIC request.\n"); ssize = ntohs (msg->header.size); GNUNET_assert (size >= ssize); memcpy (buf, msg, ssize); @@ -1505,56 +1506,35 @@ send_metric (void *cls, size_t size, void *buf) * * @param handle transport handle * @param peer the peer to set the metric for - * @param inbound set inbound direction (#GNUNET_YES or #GNUNET_NO) - * @param outbound set outbound direction (#GNUNET_YES or #GNUNET_NO) - * @param ats the metric as ATS information - * @param ats_count the number of metrics + * @param prop the performance metrics to set + * @param delay_in inbound delay to introduce + * @param delay_out outbound delay to introduce * - * Supported ATS values: - * #GNUNET_ATS_QUALITY_NET_DELAY (value in ms) - * #GNUNET_ATS_QUALITY_NET_DISTANCE (value in count(hops)) - * - * Example: - * To enforce a delay of 10 ms for peer p1 in sending direction use: - * - * struct GNUNET_ATS_Information ats; - * ats.type = ntohl (GNUNET_ATS_QUALITY_NET_DELAY); - * ats.value = ntohl (10); - * GNUNET_TRANSPORT_set_traffic_metric (th, p1, TM_SEND, &ats, 1); - * - * Note: - * Delay restrictions in receiving direction will be enforced with - * 1 message delay. + * Note: Delay restrictions in receiving direction will be enforced + * with one message delay. */ void GNUNET_TRANSPORT_set_traffic_metric (struct GNUNET_TRANSPORT_Handle *handle, - const struct GNUNET_PeerIdentity *peer, - int inbound, - int outbound, - const struct GNUNET_ATS_Information *ats, - size_t ats_count) + const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_ATS_Properties *prop, + struct GNUNET_TIME_Relative delay_in, + struct GNUNET_TIME_Relative delay_out) { struct TrafficMetricMessage *msg; - GNUNET_assert ((outbound == GNUNET_YES) || (outbound == GNUNET_NO)); - GNUNET_assert ((inbound == GNUNET_YES) || (inbound == GNUNET_NO)); - if ((GNUNET_NO == inbound) && (GNUNET_NO == outbound)) - return; - if (0 == ats_count) - return; - - size_t len = sizeof (struct TrafficMetricMessage) + - ats_count * sizeof (struct GNUNET_ATS_Information); - - msg = GNUNET_malloc (len); - msg->header.size = htons (len); + msg = GNUNET_new (struct TrafficMetricMessage); + msg->header.size = htons (sizeof (struct TrafficMetricMessage)); msg->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_TRAFFIC_METRIC); - msg->direction = htons (0 + outbound + 2 * inbound); - msg->ats_count = htons (ats_count); - msg->peer = (*peer); - memcpy (&msg[1], ats, ats_count * sizeof (struct GNUNET_ATS_Information)); - schedule_control_transmit (handle, len, - &send_metric, msg); + msg->reserved = htonl (0); + msg->peer = *peer; + GNUNET_ATS_properties_hton (&msg->properties, + prop); + msg->delay_in = GNUNET_TIME_relative_hton (delay_in); + msg->delay_out = GNUNET_TIME_relative_hton (delay_out); + schedule_control_transmit (handle, + sizeof (struct TrafficMetricMessage), + &send_metric, + msg); } -- cgit v1.2.3