diff options
author | Christian Grothoff <christian@grothoff.org> | 2015-02-10 23:24:01 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2015-02-10 23:24:01 +0000 |
commit | 1c323bd4cbb388a9e7515a1f733a3062bf093aee (patch) | |
tree | 7cc525d79149d44840b9f7a0040aaf3e69ecd665 /src/transport | |
parent | aedaaed687db1ff20b447378f01ad7306921450c (diff) |
fixing #3657 (replace ATS_Information with struct), but WIHTOUT fixing ATS testcases yet
Diffstat (limited to 'src/transport')
22 files changed, 630 insertions, 888 deletions
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. @@ -52,6 +54,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). * Used when transport determines that for some reason it @@ -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) - ? "<inbound>" - : 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) + ? "<inbound>" + : 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) - ? "<inbound>" - : 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) + ? "<inbound>" + : 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 @@ -331,6 +331,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) */ int expecting_welcome; @@ -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 @@ -173,12 +173,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. */ struct GNUNET_HELLO_Address *address; @@ -202,6 +196,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 * there might be code that still uses it; in this case, @@ -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 @@ -318,11 +318,6 @@ struct Plugin uint32_t myoptions; /** - * ATS network - */ - struct GNUNET_ATS_Information ats_network; - - /** * Are we using an abstract UNIX domain socket? */ int is_abstract; @@ -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: - * <code> - * 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); - * </code> - * 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); } |