From f735158d94616b75ade351a3cce226483b8af55e Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Mon, 19 Jan 2015 01:08:03 +0000 Subject: -towards improved ATS API, adding return value with address record when adding address, adding new subsystem with peer-to-address map to transport; causes various new assertions to fail, but no major regression -- not finished --- src/transport/Makefile.am | 14 + src/transport/gnunet-service-transport.c | 468 ++++++++------------- src/transport/gnunet-service-transport.h | 43 +- src/transport/gnunet-service-transport_ats.c | 441 +++++++++++++++++++ src/transport/gnunet-service-transport_ats.h | 119 ++++++ src/transport/gnunet-service-transport_blacklist.h | 25 +- src/transport/gnunet-service-transport_hello.h | 19 +- .../gnunet-service-transport_manipulation.c | 52 ++- .../gnunet-service-transport_manipulation.h | 18 +- .../gnunet-service-transport_neighbours.c | 371 ++++++++-------- .../gnunet-service-transport_neighbours.h | 82 ++-- .../gnunet-service-transport_validation.c | 56 ++- 12 files changed, 1112 insertions(+), 596 deletions(-) create mode 100644 src/transport/gnunet-service-transport_ats.c create mode 100644 src/transport/gnunet-service-transport_ats.h (limited to 'src/transport') diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am index d2dcd4236..749550657 100644 --- a/src/transport/Makefile.am +++ b/src/transport/Makefile.am @@ -240,6 +240,7 @@ gnunet_transport_LDADD = \ gnunet_service_transport_SOURCES = \ gnunet-service-transport.c gnunet-service-transport.h \ + gnunet-service-transport_ats.h gnunet-service-transport_ats.c \ gnunet-service-transport_blacklist.h gnunet-service-transport_blacklist.c \ gnunet-service-transport_clients.h gnunet-service-transport_clients.c \ gnunet-service-transport_hello.h gnunet-service-transport_hello.c \ @@ -980,6 +981,7 @@ test_quota_compliance_http_SOURCES = \ test_quota_compliance_http_LDADD = \ libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/ats/libgnunetats.la \ $(top_builddir)/src/util/libgnunetutil.la \ libgnunettransporttesting.la @@ -988,6 +990,7 @@ test_quota_compliance_http_asymmetric_SOURCES = \ test_quota_compliance_http_asymmetric_LDADD = \ libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/ats/libgnunetats.la \ $(top_builddir)/src/util/libgnunetutil.la \ libgnunettransporttesting.la @@ -996,6 +999,7 @@ test_quota_compliance_https_SOURCES = \ test_quota_compliance_https_LDADD = \ libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/ats/libgnunetats.la \ $(top_builddir)/src/util/libgnunetutil.la \ libgnunettransporttesting.la @@ -1004,6 +1008,7 @@ test_quota_compliance_https_asymmetric_SOURCES = \ test_quota_compliance_https_asymmetric_LDADD = \ libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/ats/libgnunetats.la \ $(top_builddir)/src/util/libgnunetutil.la \ libgnunettransporttesting.la @@ -1121,6 +1126,7 @@ test_quota_compliance_tcp_SOURCES = \ test_quota_compliance_tcp_LDADD = \ libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/ats/libgnunetats.la \ $(top_builddir)/src/util/libgnunetutil.la \ libgnunettransporttesting.la @@ -1129,6 +1135,7 @@ test_quota_compliance_tcp_asymmetric_SOURCES = \ test_quota_compliance_tcp_asymmetric_LDADD = \ libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/ats/libgnunetats.la \ $(top_builddir)/src/util/libgnunetutil.la \ libgnunettransporttesting.la @@ -1137,6 +1144,7 @@ test_quota_compliance_udp_SOURCES = \ test_quota_compliance_udp_LDADD = \ libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/ats/libgnunetats.la \ $(top_builddir)/src/util/libgnunetutil.la \ libgnunettransporttesting.la @@ -1145,6 +1153,7 @@ test_quota_compliance_unix_SOURCES = \ test_quota_compliance_unix_LDADD = \ libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/ats/libgnunetats.la \ $(top_builddir)/src/util/libgnunetutil.la \ libgnunettransporttesting.la @@ -1153,6 +1162,7 @@ test_quota_compliance_unix_asymmetric_SOURCES = \ test_quota_compliance_unix_asymmetric_LDADD = \ libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/ats/libgnunetats.la \ $(top_builddir)/src/util/libgnunetutil.la \ libgnunettransporttesting.la @@ -1161,6 +1171,7 @@ test_quota_compliance_wlan_SOURCES = \ test_quota_compliance_wlan_LDADD = \ libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/ats/libgnunetats.la \ $(top_builddir)/src/util/libgnunetutil.la \ libgnunettransporttesting.la @@ -1169,6 +1180,7 @@ test_quota_compliance_wlan_asymmetric_SOURCES = \ test_quota_compliance_wlan_asymmetric_LDADD = \ libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/ats/libgnunetats.la \ $(top_builddir)/src/util/libgnunetutil.la \ libgnunettransporttesting.la @@ -1178,6 +1190,7 @@ test_quota_compliance_bluetooth_LDADD = \ $(top_builddir)/src/nat/libgnunetnat.la \ libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/ats/libgnunetats.la \ $(top_builddir)/src/util/libgnunetutil.la \ libgnunettransporttesting.la @@ -1186,6 +1199,7 @@ test_quota_compliance_bluetooth_asymmetric_SOURCES = \ test_quota_compliance_bluetooth_asymmetric_LDADD = \ libgnunettransport.la \ $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/ats/libgnunetats.la \ $(top_builddir)/src/util/libgnunetutil.la \ libgnunettransporttesting.la diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c index 01ca2fc67..5126dad96 100644 --- a/src/transport/gnunet-service-transport.c +++ b/src/transport/gnunet-service-transport.c @@ -20,7 +20,7 @@ /** * @file transport/gnunet-service-transport.c - * @brief + * @brief main for gnunet-service-transport * @author Christian Grothoff */ #include "platform.h" @@ -31,6 +31,7 @@ #include "gnunet_peerinfo_service.h" #include "gnunet_ats_service.h" #include "gnunet-service-transport.h" +#include "gnunet-service-transport_ats.h" #include "gnunet-service-transport_blacklist.h" #include "gnunet-service-transport_clients.h" #include "gnunet-service-transport_hello.h" @@ -71,19 +72,21 @@ struct SessionKiller struct GNUNET_SCHEDULER_Task * task; }; + struct BlacklistCheckContext { struct BlacklistCheckContext *prev; - struct BlacklistCheckContext *next; + struct BlacklistCheckContext *next; struct GST_BlacklistCheck *blc; struct GNUNET_HELLO_Address *address; + struct Session *session; + struct GNUNET_MessageHeader *msg; - struct GNUNET_ATS_Information *ats; - uint32_t ats_count; + }; /* globals */ @@ -143,7 +146,14 @@ static struct SessionKiller *sk_head; */ static struct SessionKiller *sk_tail; +/** + * FIXME + */ struct BlacklistCheckContext *bc_head; + +/** + * FIXME + */ struct BlacklistCheckContext *bc_tail; @@ -172,7 +182,7 @@ transmit_our_hello (void *cls, const struct GNUNET_PeerIdentity *target, return; GST_neighbours_send (target, hello, ntohs (hello->size), hello_expiration, - NULL, NULL ); + NULL, NULL); } /** @@ -193,15 +203,18 @@ process_hello_update (void *cls, const struct GNUNET_MessageHeader *hello) * We received some payload. Prepare to pass it on to our clients. * * @param peer (claimed) identity of the other peer - * @param address the address - * @param session session used + * @param address address and (claimed) identity of the other peer + * @param session identifier used for this session (NULL for plugins + * that do not offer bi-directional communication to the sender + * using the same "connection") * @param message the message to process * @return how long the plugin should wait until receiving more data */ static struct GNUNET_TIME_Relative process_payload (const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_HELLO_Address *address, struct Session *session, - const struct GNUNET_MessageHeader *message) + const struct GNUNET_HELLO_Address *address, + struct Session *session, + const struct GNUNET_MessageHeader *message) { struct GNUNET_TIME_Relative ret; int do_forward; @@ -214,18 +227,18 @@ process_payload (const struct GNUNET_PeerIdentity *peer, ret = GST_neighbours_calculate_receive_delay (peer, msg_size, &do_forward); if (! GST_neighbours_test_connected (peer)) { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Discarded %u bytes type %u payload from peer `%s'\n", msg_size, - ntohs (message->type), GNUNET_i2s (peer)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Discarded %u bytes type %u payload from peer `%s'\n", + msg_size, + ntohs (message->type), + GNUNET_i2s (peer)); GNUNET_STATISTICS_update (GST_stats, gettext_noop - ("# bytes payload discarded due to not connected peer"), msg_size, - GNUNET_NO); + ("# bytes payload discarded due to not connected peer"), + msg_size, + GNUNET_NO); return ret; } - // FIXME: why is this call here? - GST_ats_add_address (address, session, NULL, 0); - if (GNUNET_YES != do_forward) return ret; im = (struct InboundMessage *) buf; @@ -237,6 +250,7 @@ process_payload (const struct GNUNET_PeerIdentity *peer, return ret; } + /** * Task to asynchronously terminate a session. * @@ -254,16 +268,25 @@ kill_session_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_free(sk); } + +/** + * FIXME. Also, consider moving the "bc_*" logic into + * blacklist.h? + */ static void -cancel_pending_blacklist_checks (const struct GNUNET_HELLO_Address *address, struct Session *session) +cancel_pending_blacklist_checks (const struct GNUNET_HELLO_Address *address, + struct Session *session) { struct BlacklistCheckContext *blctx; struct BlacklistCheckContext *next; + next = bc_head; for (blctx = next; NULL != blctx; blctx = next) { next = blctx->next; - if ((NULL != blctx->address) && (0 == GNUNET_HELLO_address_cmp(blctx->address, address)) && (blctx->session == session)) + if ( (NULL != blctx->address) && + (0 == GNUNET_HELLO_address_cmp(blctx->address, address)) && + (blctx->session == session)) { GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, blctx); if (NULL != blctx->blc) @@ -273,12 +296,12 @@ cancel_pending_blacklist_checks (const struct GNUNET_HELLO_Address *address, str } GNUNET_HELLO_address_free (blctx->address); GNUNET_free_non_null (blctx->msg); - GNUNET_free_non_null (blctx->ats); GNUNET_free (blctx); } } } + /** * Force plugin to terminate session due to communication * issue. @@ -287,7 +310,8 @@ cancel_pending_blacklist_checks (const struct GNUNET_HELLO_Address *address, str * @param session session to termiante */ static void -kill_session (const char *plugin_name, struct Session *session) +kill_session (const char *plugin_name, + struct Session *session) { struct GNUNET_TRANSPORT_PluginFunctions *plugin; struct SessionKiller *sk; @@ -306,14 +330,15 @@ kill_session (const char *plugin_name, struct Session *session) sk->session = session; sk->plugin = plugin; sk->task = GNUNET_SCHEDULER_add_now (&kill_session_task, sk); - GNUNET_CONTAINER_DLL_insert(sk_head, sk_tail, sk); + GNUNET_CONTAINER_DLL_insert (sk_head, + sk_tail, + sk); } - /** * Black list check result for try_connect call - * If connection to the peer is allowed request adddress and + * If connection to the peer is allowed request adddress and ??? * * @param cls blc_ctx bl context * @param peer the peer @@ -321,7 +346,8 @@ kill_session (const char *plugin_name, struct Session *session) */ static void connect_bl_check_cont (void *cls, - const struct GNUNET_PeerIdentity *peer, int result) + const struct GNUNET_PeerIdentity *peer, + int result) { struct BlacklistCheckContext *blctx = cls; @@ -335,8 +361,9 @@ connect_bl_check_cont (void *cls, "Received SYN message from peer `%s' with `%s' %p\n", GNUNET_i2s (peer), GST_plugins_a2s (blctx->address), blctx->session); - if (GNUNET_OK != GST_neighbours_handle_session_syn (blctx->msg, - &blctx->address->peer)) + if (GNUNET_OK != + GST_neighbours_handle_session_syn (blctx->msg, + &blctx->address->peer)) { cancel_pending_blacklist_checks (blctx->address, blctx->session); kill_session (blctx->address->transport_name, blctx->session); @@ -360,38 +387,6 @@ connect_bl_check_cont (void *cls, } -/** - * Black list check result for try_connect call - * If connection to the peer is allowed request adddress and - * - * @param cls blc_ctx bl context - * @param peer the peer - * @param result the result - */ -static void -connect_transport_bl_check_cont (void *cls, - const struct GNUNET_PeerIdentity *peer, int result) -{ - struct BlacklistCheckContext *blctx = cls; - - GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, blctx); - blctx->blc = NULL; - - if (GNUNET_OK == result) - { - /* Blacklist allows to speak to this transport */ - GST_ats_add_address (blctx->address, - blctx->session, - blctx->ats, blctx->ats_count); - } - - if (NULL != blctx->address) - GNUNET_HELLO_address_free (blctx->address); - GNUNET_free (blctx->msg); - GNUNET_free (blctx); -} - - /** * Function called by the transport for each received message. * @@ -426,7 +421,9 @@ GST_receive_callback (void *cls, GNUNET_i2s (&address->peer)); GNUNET_STATISTICS_update (GST_stats, gettext_noop - ("# bytes total received"), ntohs (message->size), GNUNET_NO); + ("# bytes total received"), + ntohs (message->size), + GNUNET_NO); GST_neighbours_notify_data_recv (&address->peer, address, session, message); switch (type) @@ -442,19 +439,23 @@ GST_receive_callback (void *cls, } return ret; case GNUNET_MESSAGE_TYPE_TRANSPORT_PING: - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, - "Processing `%s' from `%s'\n", "PING", GST_plugins_a2s (address)); - if (GNUNET_OK - != GST_validation_handle_ping (&address->peer, message, address, session)) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Processing `%s' from `%s'\n", "PING", + GST_plugins_a2s (address)); + if (GNUNET_OK != + GST_validation_handle_ping (&address->peer, + message, + address, + session)) { cancel_pending_blacklist_checks (address, session); kill_session (plugin_name, session); } break; case GNUNET_MESSAGE_TYPE_TRANSPORT_PONG: - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, - "Processing `%s' from `%s'\n", "PONG", - GST_plugins_a2s (address)); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Processing `%s' from `%s'\n", "PONG", + GST_plugins_a2s (address)); if (GNUNET_OK != GST_validation_handle_pong (&address->peer, message)) { GNUNET_break_op(0); @@ -475,18 +476,6 @@ GST_receive_callback (void *cls, { blctx->blc = blc; } - - blctx = GNUNET_new (struct BlacklistCheckContext); - blctx->address = GNUNET_HELLO_address_copy (address); - blctx->session = session; - blctx->msg = GNUNET_malloc (ntohs(message->size)); - memcpy (blctx->msg, message, ntohs(message->size)); - GNUNET_CONTAINER_DLL_insert (bc_head, bc_tail, blctx); - if (NULL != (blc = GST_blacklist_test_allowed (&address->peer, - address->transport_name, &connect_transport_bl_check_cont, blctx))) - { - blctx->blc = blc; - } break; case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_SYN_ACK: if (GNUNET_OK != GST_neighbours_handle_session_syn_ack (message, @@ -529,6 +518,7 @@ GST_receive_callback (void *cls, return ret; } + /** * Function that will be called for each address the transport * is aware that it might be reachable under. Update our HELLO. @@ -539,8 +529,9 @@ GST_receive_callback (void *cls, * @param address the address to add or remove */ static void -plugin_env_address_change_notification (void *cls, int add_remove, - const struct GNUNET_HELLO_Address *address) +plugin_env_address_change_notification (void *cls, + int add_remove, + const struct GNUNET_HELLO_Address *address) { static int addresses = 0; struct GNUNET_STATISTICS_Handle *cfg = GST_stats; @@ -562,11 +553,12 @@ plugin_env_address_change_notification (void *cls, int add_remove, } GNUNET_log(GNUNET_ERROR_TYPE_INFO, - "Transport now has %u addresses to communicate\n", addresses); - + "Transport now has %u addresses to communicate\n", + addresses); GST_hello_modify_addresses (add_remove, address); } + /** * Function that will be called whenever the plugin internally * cleans up a session pointer and hence the service needs to @@ -581,8 +573,9 @@ plugin_env_address_change_notification (void *cls, int add_remove, * @param session which session is being destoyed */ static void -plugin_env_session_end (void *cls, const struct GNUNET_HELLO_Address *address, - struct Session *session) +plugin_env_session_end (void *cls, + const struct GNUNET_HELLO_Address *address, + struct Session *session) { struct SessionKiller *sk; @@ -591,40 +584,30 @@ plugin_env_session_end (void *cls, const struct GNUNET_HELLO_Address *address, GNUNET_break (0); return; } - if (NULL == session) { GNUNET_break (0); return; } + GNUNET_assert (strlen (address->transport_name) > 0); - GNUNET_assert(strlen (address->transport_name) > 0); - GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Session %p to peer `%s' ended \n", - session, GNUNET_i2s (&address->peer)); - - GNUNET_log(GNUNET_ERROR_TYPE_INFO, - "Notification from plugin `%s' about terminated %s session %p from peer `%s' address `%s'\n", - address->transport_name, - GNUNET_HELLO_address_check_option (address, - GNUNET_HELLO_ADDRESS_INFO_INBOUND) ? "inbound" : "outbound", session, - GNUNET_i2s (&address->peer), GST_plugins_a2s (address)); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Notification from plugin `%s' about terminated %s session %p from peer `%s' address `%s'\n", + address->transport_name, + GNUNET_HELLO_address_check_option (address, + GNUNET_HELLO_ADDRESS_INFO_INBOUND) ? "inbound" : "outbound", session, + GNUNET_i2s (&address->peer), + GST_plugins_a2s (address)); GST_neighbours_session_terminated (&address->peer, session); - - GNUNET_log_from(GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, - "transport-ats", "Telling ATS to destroy session %p from peer %s\n", - session, GNUNET_i2s (&address->peer)); - - /* Tell ATS that session has ended */ - GNUNET_ATS_address_destroyed (GST_ats, address, session); - + GST_ats_del_session (address, session); cancel_pending_blacklist_checks (address, session); for (sk = sk_head; NULL != sk; sk = sk->next) { if (sk->session == session) { - GNUNET_CONTAINER_DLL_remove(sk_head, sk_tail, sk); + GNUNET_CONTAINER_DLL_remove (sk_head, sk_tail, sk); GNUNET_SCHEDULER_cancel (sk->task); GNUNET_free(sk); break; @@ -632,6 +615,7 @@ plugin_env_session_end (void *cls, const struct GNUNET_HELLO_Address *address, } } + /** * Function that will be called to figure if an address is an loopback, * LAN, WAN etc. address @@ -651,124 +635,12 @@ plugin_env_address_to_type (void *cls, GNUNET_break(0); return GNUNET_ATS_NET_UNSPECIFIED; } - if (((addr->sa_family != AF_INET) && (addrlen != sizeof(struct sockaddr_in))) - && ((addr->sa_family != AF_INET6) - && (addrlen != sizeof(struct sockaddr_in6))) - && (addr->sa_family != AF_UNIX)) - { - GNUNET_break(0); - return GNUNET_ATS_NET_UNSPECIFIED; - } return GNUNET_ATS_address_get_type (GST_ats, addr, addrlen); } -/** - * Notify ATS about the new address including the network this address is - * located in. - * - * @param address the address - * @param session the session - * @param ats ats information - * @param ats_count number of @a ats information - */ -void -GST_ats_add_address (const struct GNUNET_HELLO_Address *address, - struct Session *session, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count) -{ - struct GNUNET_TRANSPORT_PluginFunctions *papi; - struct GNUNET_ATS_Information ats2[ats_count + 1]; - uint32_t net; - - /* valid new address, let ATS know! */ - if (NULL == address->transport_name) - { - GNUNET_break(0); - return; - } - if (NULL == (papi = GST_plugins_find (address->transport_name))) - { - /* we don't have the plugin for this address */ - GNUNET_break(0); - return; - } - - if (GNUNET_YES == GNUNET_ATS_session_known (GST_ats, address, session)) - { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "ATS already knows the address, not passing it on again\n"); - return; - } - - 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_INFO, - "Notifying ATS about peer `%s''s new 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_ATS_address_add (GST_ats, address, session, - ats2, ats_count + 1); -} - - -/** - * Notify ATS about property changes to an address - * - * @param peer the peer - * @param address the address - * @param session the session - * @param ats performance information - * @param ats_count number of elements in @a ats - */ -void -GST_ats_update_metrics (const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_HELLO_Address *address, - struct Session *session, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count) -{ - struct GNUNET_ATS_Information *ats_new; - - if (GNUNET_NO == GNUNET_ATS_session_known (GST_ats, address, session)) - return; - - /* Call to manipulation to manipulate ATS information */ - ats_new = GST_manipulation_manipulate_metrics (peer, address, session, ats, - ats_count); - if (NULL == ats_new) - { - GNUNET_break(0); - return; - } - if (GNUNET_NO == GNUNET_ATS_address_update (GST_ats, address, session, - ats_new, ats_count)) - { - GNUNET_log(GNUNET_ERROR_TYPE_ERROR, - _("Address or session unknown: failed to update properties for peer `%s' plugin `%s' address `%s' session %p\n"), - GNUNET_i2s (peer), address->transport_name, GST_plugins_a2s (address), - session); - } - GNUNET_free(ats_new); -} - /** * Function that will be called to update metrics for an address * @@ -785,25 +657,16 @@ plugin_env_update_metrics (void *cls, const struct GNUNET_ATS_Information *ats, uint32_t ats_count) { - if ((NULL == ats) || (0 == ats_count)) - return; - GNUNET_assert(NULL != GST_ats); - - 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); - GST_ats_update_metrics (&address->peer, - address, + GST_ats_update_metrics (address, session, ats, ats_count); } /** - * Black list check result for try_connect call - * If connection to the peer is allowed request adddress and + * Black list check result from blacklist check triggered when a + * plugin gave us a new session in #plugin_env_session_start(). If + * connection to the peer is disallowed, kill the session. * * @param cls blc_ctx bl context * @param peer the peer @@ -811,26 +674,23 @@ plugin_env_update_metrics (void *cls, */ static void plugin_env_session_start_bl_check_cont (void *cls, - const struct GNUNET_PeerIdentity *peer, int result) + const struct GNUNET_PeerIdentity *peer, + int result) { struct BlacklistCheckContext *blctx = cls; - GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, blctx); + GNUNET_CONTAINER_DLL_remove (bc_head, + bc_tail, + blctx); blctx->blc = NULL; - - if (GNUNET_OK == result) - { - GST_ats_add_address (blctx->address, blctx->session, - blctx->ats, blctx->ats_count); - } - else + if (GNUNET_OK != result) { - cancel_pending_blacklist_checks (blctx->address, blctx->session); - kill_session (blctx->address->transport_name, blctx->session); + cancel_pending_blacklist_checks (blctx->address, + blctx->session); + kill_session (blctx->address->transport_name, + blctx->session); } - GNUNET_HELLO_address_free (blctx->address); - GNUNET_free_non_null (blctx->ats); GNUNET_free (blctx); } @@ -846,14 +706,13 @@ plugin_env_session_start_bl_check_cont (void *cls, */ static void plugin_env_session_start (void *cls, - struct GNUNET_HELLO_Address *address, + const struct GNUNET_HELLO_Address *address, struct Session *session, const struct GNUNET_ATS_Information *ats, uint32_t ats_count) { struct BlacklistCheckContext *blctx; struct GST_BlacklistCheck *blc; - int c; if (NULL == address) { @@ -865,30 +724,46 @@ plugin_env_session_start (void *cls, GNUNET_break(0); return; } - GNUNET_log(GNUNET_ERROR_TYPE_INFO, - "Notification from plugin `%s' about new %s session %p from peer `%s' address `%s'\n", - address->transport_name, + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Notification from plugin `%s' about new %s session %p from peer `%s' address `%s'\n", + address->transport_name, + GNUNET_HELLO_address_check_option (address, + GNUNET_HELLO_ADDRESS_INFO_INBOUND) ? "inbound" : "outbound", + session, + GNUNET_i2s (&address->peer), + GST_plugins_a2s (address)); + if (GNUNET_YES == GNUNET_HELLO_address_check_option (address, - GNUNET_HELLO_ADDRESS_INFO_INBOUND) ? "inbound" : "outbound", - session, GNUNET_i2s (&address->peer), GST_plugins_a2s (address)); - + GNUNET_HELLO_ADDRESS_INFO_INBOUND)) + { + /* inbound is always new */ + GST_ats_add_address (address, + session, + ats, + ats_count); + } + else + { + /* outbound should already be known */ + GST_ats_new_session (address, + session); + GST_ats_update_metrics (address, + session, + ats, + ats_count); + } /* Do blacklist check if communication with this peer is allowed */ blctx = GNUNET_new (struct BlacklistCheckContext); blctx->address = GNUNET_HELLO_address_copy (address); blctx->session = session; - if (ats_count > 0) - { - blctx->ats = GNUNET_malloc (ats_count * sizeof (struct GNUNET_ATS_Information)); - for (c = 0; c < ats_count; c++) - { - blctx->ats[c].type = ats[c].type; - blctx->ats[c].value = ats[c].value; - } - } - - GNUNET_CONTAINER_DLL_insert (bc_head, bc_tail, blctx); - if (NULL != (blc = GST_blacklist_test_allowed (&address->peer, address->transport_name, - &plugin_env_session_start_bl_check_cont, blctx))) + GNUNET_CONTAINER_DLL_insert (bc_head, + bc_tail, + blctx); + if (NULL != + (blc = GST_blacklist_test_allowed (&address->peer, + address->transport_name, + &plugin_env_session_start_bl_check_cont, + blctx))) { blctx->blc = blc; } @@ -927,9 +802,9 @@ ats_request_address_change (void *cls, /* ATS tells me to disconnect from peer */ if ((0 == bw_in) && (0 == bw_out)) { - GNUNET_log(GNUNET_ERROR_TYPE_INFO, - "ATS tells me to disconnect from peer `%s'\n", - GNUNET_i2s (&address->peer)); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "ATS tells me to disconnect from peer `%s'\n", + GNUNET_i2s (&address->peer)); GST_neighbours_force_disconnect (&address->peer); return; } @@ -952,9 +827,9 @@ ats_request_address_change (void *cls, */ static void neighbours_connect_notification (void *cls, - const struct GNUNET_PeerIdentity *peer, - struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, - struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out) + const struct GNUNET_PeerIdentity *peer, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out) { size_t len = sizeof(struct ConnectInfoMessage); char buf[len] GNUNET_ALIGN; @@ -962,8 +837,9 @@ neighbours_connect_notification (void *cls, connections++; GNUNET_log(GNUNET_ERROR_TYPE_INFO, - "We are now connected to peer `%s' and %u peers in total\n", - GNUNET_i2s (peer), connections); + "We are now connected to peer `%s' and %u peers in total\n", + GNUNET_i2s (peer), + connections); connect_msg->header.size = htons (sizeof(buf)); connect_msg->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT); connect_msg->id = *peer; @@ -988,8 +864,8 @@ neighbours_disconnect_notification (void *cls, connections--; GNUNET_log(GNUNET_ERROR_TYPE_INFO, - "Peer `%s' disconnected and we are connected to %u peers\n", - GNUNET_i2s (peer), connections); + "Peer `%s' disconnected and we are connected to %u peers\n", + GNUNET_i2s (peer), connections); GST_manipulation_peer_disconnect (peer); disconnect_msg.header.size = htons (sizeof(struct DisconnectInfoMessage)); @@ -1021,12 +897,12 @@ neighbours_changed_notification (void *cls, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out) { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Notifying about change for peer `%s' with address `%s' in state `%s' timing out at %s\n", - GNUNET_i2s (peer), - (NULL != address) ? GST_plugins_a2s (address) : "", - GNUNET_TRANSPORT_ps2s (state), - GNUNET_STRINGS_absolute_time_to_string (state_timeout)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Notifying about change for peer `%s' with address `%s' in state `%s' timing out at %s\n", + GNUNET_i2s (peer), + (NULL != address) ? GST_plugins_a2s (address) : "", + GNUNET_TRANSPORT_ps2s (state), + GNUNET_STRINGS_absolute_time_to_string (state_timeout)); GST_clients_broadcast_peer_notification (peer, address, @@ -1043,12 +919,13 @@ neighbours_changed_notification (void *cls, * @param tc task context (unused) */ static void -shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +shutdown_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) { GST_neighbours_stop (); GST_validation_stop (); GST_plugins_unload (); - + GST_ats_done (); GNUNET_ATS_scheduling_done (GST_ats); GST_ats = NULL; GST_clients_stop (); @@ -1083,8 +960,9 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) * @param c configuration to use */ static void -run (void *cls, struct GNUNET_SERVER_Handle *server, - const struct GNUNET_CONFIGURATION_Handle *c) +run (void *cls, + struct GNUNET_SERVER_Handle *server, + const struct GNUNET_CONFIGURATION_Handle *c) { char *keyfile; struct GNUNET_CRYPTO_EddsaPrivateKey *pk; @@ -1121,15 +999,16 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, GST_stats = GNUNET_STATISTICS_create ("transport", GST_cfg); GST_peerinfo = GNUNET_PEERINFO_connect (GST_cfg); GNUNET_CRYPTO_eddsa_key_get_public (GST_my_private_key, - &GST_my_identity.public_key); + &GST_my_identity.public_key); GNUNET_assert(NULL != GST_my_private_key); GNUNET_log(GNUNET_ERROR_TYPE_INFO, "My identity is `%4s'\n", GNUNET_i2s_full (&GST_my_identity)); - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, - NULL ); + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, + &shutdown_task, + NULL); if (NULL == GST_peerinfo) { GNUNET_log(GNUNET_ERROR_TYPE_ERROR, @@ -1152,8 +1031,10 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, } max_fd_rlimit = (9 * max_fd_rlimit) / 10; /* Keep 10% for rest of transport */ #endif - GNUNET_CONFIGURATION_get_value_number (GST_cfg, "transport", "MAX_FD", - &max_fd_cfg); + GNUNET_CONFIGURATION_get_value_number (GST_cfg, + "transport", + "MAX_FD", + &max_fd_cfg); if (max_fd_cfg > max_fd_rlimit) max_fd = max_fd_cfg; @@ -1162,9 +1043,9 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, if (max_fd < DEFAULT_MAX_FDS) max_fd = DEFAULT_MAX_FDS; - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Limiting number of sockets to %u: validation %u, neighbors: %u\n", - max_fd, (max_fd / 3), (max_fd / 3) * 2); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Limiting number of sockets to %u: validation %u, neighbors: %u\n", + max_fd, (max_fd / 3), (max_fd / 3) * 2); friend_only = GNUNET_CONFIGURATION_get_value_yesno (GST_cfg, "topology", "FRIENDS-ONLY"); @@ -1176,7 +1057,8 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, GST_blacklist_start (GST_server, GST_cfg, &GST_my_identity); GST_ats = GNUNET_ATS_scheduling_init (GST_cfg, &ats_request_address_change, - NULL ); + NULL); + GST_ats_init (); GST_manipulation_init (GST_cfg); GST_plugins_load (&GST_manipulation_recv, &GST_neighbours_register_quota_notification, diff --git a/src/transport/gnunet-service-transport.h b/src/transport/gnunet-service-transport.h index 67456bd46..34b0083a2 100644 --- a/src/transport/gnunet-service-transport.h +++ b/src/transport/gnunet-service-transport.h @@ -28,6 +28,7 @@ #include "gnunet_util_lib.h" #include "gnunet_statistics_service.h" +#include "gnunet_ats_service.h" #include "gnunet_transport_service.h" #define VERBOSE_VALIDATION GNUNET_YES @@ -85,52 +86,20 @@ typedef void * * @param cls closure, const char* with the name of the plugin we received the message from * @param address address and (claimed) identity of the other peer - * @param message the message, NULL if we only care about - * learning about the delay until we should receive again * @param session identifier used for this session (NULL for plugins * that do not offer bi-directional communication to the sender * using the same "connection") + * @param message the message, NULL if we only care about + * learning about the delay until we should receive again * @return how long the plugin should wait until receiving more data * (plugins that do not support this, can ignore the return value) */ struct GNUNET_TIME_Relative GST_receive_callback (void *cls, - const struct GNUNET_HELLO_Address *address, - struct Session *session, - const struct GNUNET_MessageHeader *message); - - -/** - * Notify ATS about the new address including the network this address is - * located in. - * - * @param address the address - * @param session the session - * @param ats ats information - * @param ats_count number of @a ats information - */ -void -GST_ats_add_address (const struct GNUNET_HELLO_Address *address, - struct Session *session, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count); - + const struct GNUNET_HELLO_Address *address, + struct Session *session, + const struct GNUNET_MessageHeader *message); -/** - * Notify ATS about property changes to an address - * - * @param peer the peer - * @param address the address - * @param session the session - * @param ats performance information - * @param ats_count number of elements in @a ats - */ -void -GST_ats_update_metrics (const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_HELLO_Address *address, - struct Session *session, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count); #endif /* end of file gnunet-service-transport_plugins.h */ diff --git a/src/transport/gnunet-service-transport_ats.c b/src/transport/gnunet-service-transport_ats.c new file mode 100644 index 000000000..c6975e526 --- /dev/null +++ b/src/transport/gnunet-service-transport_ats.c @@ -0,0 +1,441 @@ +/* + This file is part of GNUnet. + (C) 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 + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file transport/gnunet-service-transport_ats.h + * @brief interfacing between transport and ATS service + * @author Christian Grothoff + */ +#include "platform.h" +#include "gnunet-service-transport.h" +#include "gnunet-service-transport_ats.h" +#include "gnunet-service-transport_manipulation.h" +#include "gnunet-service-transport_plugins.h" +#include "gnunet_ats_service.h" + + +/** + * Information we track for each address known to ATS. + */ +struct AddressInfo +{ + + /** + * The address (with peer identity). + */ + struct GNUNET_HELLO_Address *address; + + /** + * Session (can be NULL) + */ + struct Session *session; + + /** + * Record with ATS API for the address. + */ + struct GNUNET_ATS_AddressRecord *ar; +}; + + +/** + * Map from peer identities to one or more `struct AddressInfo` values + * for the peer. + */ +static struct GNUNET_CONTAINER_MultiPeerMap *p2a; + + +/** + * Closure for #find_ai(). + */ +struct FindClosure +{ + + /** + * Session to look for (only used if the address is inbound). + */ + struct Session *session; + + /** + * Address to look for. + */ + const struct GNUNET_HELLO_Address *address; + + /** + * Where to store the result. + */ + struct AddressInfo *ret; + +}; + + +/** + * Find matching address info. + * + * @param cls the `struct FindClosure` + * @param key which peer is this about + * @param value the `struct AddressInfo` + * @return #GNUNET_YES to continue to iterate, #GNUNET_NO if we found the value + */ +static int +find_ai_cb (void *cls, + const struct GNUNET_PeerIdentity *key, + void *value) +{ + struct FindClosure *fc = cls; + struct AddressInfo *ai = value; + + if ( (0 == + GNUNET_HELLO_address_cmp (fc->address, + ai->address) ) && + (fc->session == ai->session) ) + { + fc->ret = ai; + return GNUNET_NO; + } + return GNUNET_YES; +} + + +/** + * Find the address information struct for the + * given address and session. + * + * @param address address to look for + * @param session session to match for inbound connections + * @return NULL if this combination is unknown + */ +static struct AddressInfo * +find_ai (const struct GNUNET_HELLO_Address *address, + struct Session *session) +{ + struct FindClosure fc; + + fc.address = address; + fc.session = session; + fc.ret = NULL; + GNUNET_CONTAINER_multipeermap_get_multiple (p2a, + &address->peer, + &find_ai_cb, + &fc); + return fc.ret; +} + + +/** + * Notify ATS about the new address including the network this address is + * located in. + * + * @param address the address + * @param session the session + * @param ats ats information + * @param ats_count number of @a ats information + */ +void +GST_ats_add_address (const struct GNUNET_HELLO_Address *address, + struct Session *session, + const struct GNUNET_ATS_Information *ats, + uint32_t ats_count) +{ + 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) + { + GNUNET_break(0); + return; + } + if (GNUNET_YES == + GNUNET_HELLO_address_check_option (address, + GNUNET_HELLO_ADDRESS_INFO_INBOUND)) + { + GNUNET_break (NULL != session); + } + else + { + GNUNET_break (NULL == session); + } + ai = find_ai (address, session); + if (NULL != ai) + { + GNUNET_break (0); + return; + } + if (NULL == (papi = GST_plugins_find (address->transport_name))) + { + /* we don't have the plugin for this address */ + GNUNET_break(0); + return; + } + if (NULL != session) + { + 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_INFO, + "Notifying ATS about peer `%s''s new 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)); + ar = GNUNET_ATS_address_add (GST_ats, + address, + session, + (NULL != session) ? ats2 : ats, + (NULL != session) ? ats_count + 1 : ats_count); + ai = GNUNET_new (struct AddressInfo); + ai->address = GNUNET_HELLO_address_copy (address); + ai->session = session; + ai->ar = ar; + (void) GNUNET_CONTAINER_multipeermap_put (p2a, + &ai->address->peer, + ai, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); +} + + +/** + * Notify ATS about a new session now existing for the given + * address. + * + * @param address the address + * @param session the session + */ +void +GST_ats_new_session (const struct GNUNET_HELLO_Address *address, + struct Session *session) +{ + struct AddressInfo *ai; + + ai = find_ai (address, NULL); + if (NULL == ai) + { + GNUNET_break (NULL != (find_ai (address, session))); + return; + } + 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)); + // FIXME: tell ATS API, but not using this call: + GNUNET_ATS_address_update (ai->ar, + session, + NULL, 0); + +} + + +/** + * Notify ATS that the session (but not the address) of + * a given address is no longer relevant. + * + * @param address the address + * @param session the session + */ +void +GST_ats_del_session (const struct GNUNET_HELLO_Address *address, + struct Session *session) +{ + struct AddressInfo *ai; + + if (NULL == session) + { + GNUNET_break (0); + return; + } + ai = find_ai (address, session); + if (NULL == ai) + { + /* We sometimes create sessions just for sending a PING, + and if those are destroyed 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; + } + 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)); + /* FIXME: if this was an *inbound* address, destroy it + FULLY here well; but use different API, as looking up + inbound address without session is not great... */ + GNUNET_ATS_address_destroyed (GST_ats, address, session); + if (GNUNET_YES == + GNUNET_HELLO_address_check_option (address, + GNUNET_HELLO_ADDRESS_INFO_INBOUND)) + GST_ats_expire_address (address); +} + + +/** + * Notify ATS about property changes to an address. + * + * @param address our information about the address + * @param session the session + * @param ats performance information + * @param ats_count number of elements in @a ats + */ +void +GST_ats_update_metrics (const struct GNUNET_HELLO_Address *address, + struct Session *session, + const struct GNUNET_ATS_Information *ats, + uint32_t ats_count) +{ + struct GNUNET_ATS_Information *ats_new; + struct AddressInfo *ai; + + ai = find_ai (address, session); + 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)) + 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); + GNUNET_ATS_address_update (ai->ar, + session, + ats_new, ats_count); + GNUNET_free_non_null (ats_new); +} + + +/** + * Notify ATS that the address has expired and thus cannot + * be used any longer. This function must only be called + * if the corresponding session is already gone. + * + * @param address the address + */ +void +GST_ats_expire_address (const struct GNUNET_HELLO_Address *address) +{ + struct AddressInfo *ai; + + ai = find_ai (address, NULL); + if (NULL == ai) + { + GNUNET_break (0); + return; + } + GNUNET_assert (GNUNET_YES == + GNUNET_CONTAINER_multipeermap_remove (p2a, + &address->peer, + ai)); + 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)); + GNUNET_ATS_address_destroyed (GST_ats, address, NULL); + GNUNET_HELLO_address_free (ai->address); + GNUNET_free (ai); +} + + +/** + * Initialize ATS subsystem. + */ +void +GST_ats_init () +{ + p2a = GNUNET_CONTAINER_multipeermap_create (4, GNUNET_YES); +} + + +/** + * Release memory used by the given address data. + * + * @param cls NULL + * @param key which peer is this about + * @param value the `struct AddressInfo` + * @return #GNUNET_OK (continue to iterate) + */ +static int +destroy_ai (void *cls, + const struct GNUNET_PeerIdentity *key, + void *value) +{ + struct AddressInfo *ai = value; + + GNUNET_HELLO_address_free (ai->address); + GNUNET_free (ai); + return GNUNET_OK; +} + + +/** + * Shutdown ATS subsystem. + */ +void +GST_ats_done () +{ + GNUNET_CONTAINER_multipeermap_iterate (p2a, + &destroy_ai, + NULL); + GNUNET_CONTAINER_multipeermap_destroy (p2a); + p2a = NULL; +} + +/* end of gnunet-service-transport_ats.c */ diff --git a/src/transport/gnunet-service-transport_ats.h b/src/transport/gnunet-service-transport_ats.h new file mode 100644 index 000000000..c7b826484 --- /dev/null +++ b/src/transport/gnunet-service-transport_ats.h @@ -0,0 +1,119 @@ +/* + This file is part of GNUnet. + (C) 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 + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file transport/gnunet-service-transport_ats.h + * @brief interfacing between transport and ATS service + * @author Christian Grothoff + * + * FIXME: + * - add API to give ATS feedback about an address that was + * suggested but did not work out (without fully 'deleting' + * it forever) + * - improve ATS API to take advantage of this new subsystem + * when calling ATS functions, make ATS API match this API + * more closely + * - combine with API to tell ATS about address "use" + */ +#ifndef GNUNET_SERVICE_TRANSPORT_ATS_H +#define GNUNET_SERVICE_TRANSPORT_ATS_H + +#include "gnunet_ats_service.h" + +/** + * Initialize ATS subsystem. + */ +void +GST_ats_init (void); + + +/** + * Shutdown ATS subsystem. + */ +void +GST_ats_done (void); + + +/** + * Notify ATS about the new address including the network this address is + * located in. + * + * @param address the address + * @param session the session + * @param ats ats information + * @param ats_count number of @a ats information + */ +void +GST_ats_add_address (const struct GNUNET_HELLO_Address *address, + struct Session *session, + const struct GNUNET_ATS_Information *ats, + uint32_t ats_count); + + +/** + * Notify ATS about a new session now existing for the given + * address. + * + * @param address the address + * @param session the session + */ +void +GST_ats_new_session (const struct GNUNET_HELLO_Address *address, + struct Session *session); + + +/** + * Notify ATS about property changes to an address + * + * @param address the address + * @param session the session + * @param ats performance information + * @param ats_count number of elements in @a ats + */ +void +GST_ats_update_metrics (const struct GNUNET_HELLO_Address *address, + struct Session *session, + const struct GNUNET_ATS_Information *ats, + uint32_t ats_count); + + +/** + * Notify ATS that the session (but not the address) of + * a given address is no longer relevant. + * + * @param address the address + * @param session the session + */ +void +GST_ats_del_session (const struct GNUNET_HELLO_Address *address, + struct Session *session); + + +/** + * Notify ATS that the address has expired and thus cannot + * be used any longer. This function must only be called + * if the corresponding session is already gone. + * + * @param address the address + */ +void +GST_ats_expire_address (const struct GNUNET_HELLO_Address *address); + + +#endif diff --git a/src/transport/gnunet-service-transport_blacklist.h b/src/transport/gnunet-service-transport_blacklist.h index a0ae5a959..c635566be 100644 --- a/src/transport/gnunet-service-transport_blacklist.h +++ b/src/transport/gnunet-service-transport_blacklist.h @@ -38,8 +38,8 @@ */ void GST_blacklist_start (struct GNUNET_SERVER_Handle *server, - const struct GNUNET_CONFIGURATION_Handle *cfg, - const struct GNUNET_PeerIdentity *my_id); + const struct GNUNET_CONFIGURATION_Handle *cfg, + const struct GNUNET_PeerIdentity *my_id); /** @@ -59,7 +59,8 @@ GST_blacklist_stop (void); * @param message the blacklist-init message that was sent */ void -GST_blacklist_handle_init (void *cls, struct GNUNET_SERVER_Client *client, +GST_blacklist_handle_init (void *cls, + struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message); @@ -71,7 +72,8 @@ GST_blacklist_handle_init (void *cls, struct GNUNET_SERVER_Client *client, * @param message the blacklist-init message that was sent */ void -GST_blacklist_handle_reply (void *cls, struct GNUNET_SERVER_Client *client, +GST_blacklist_handle_reply (void *cls, + struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message); @@ -97,12 +99,13 @@ struct GST_BlacklistCheck; * * @param cls closure * @param peer identity of peer that was tested - * @param result GNUNET_OK if the connection is allowed, - * GNUNET_NO if not + * @param result #GNUNET_OK if the connection is allowed, + * #GNUNET_NO if not */ -typedef void (*GST_BlacklistTestContinuation) (void *cls, - const struct GNUNET_PeerIdentity - * peer, int result); +typedef void +(*GST_BlacklistTestContinuation) (void *cls, + const struct GNUNET_PeerIdentity *peer, + int result); /** @@ -111,9 +114,9 @@ typedef void (*GST_BlacklistTestContinuation) (void *cls, * @param peer the identity of the peer to test * @param transport_name name of the transport to test, never NULL * @param cont function to call with result - * @param cont_cls closure for 'cont' + * @param cont_cls closure for @a cont * @return handle to the blacklist check, NULL if the decision - * was made instantly and 'cont' was already called + * was made instantly and @a cont was already called */ struct GST_BlacklistCheck * GST_blacklist_test_allowed (const struct GNUNET_PeerIdentity *peer, diff --git a/src/transport/gnunet-service-transport_hello.h b/src/transport/gnunet-service-transport_hello.h index 0c67cef4d..725a6167e 100644 --- a/src/transport/gnunet-service-transport_hello.h +++ b/src/transport/gnunet-service-transport_hello.h @@ -17,7 +17,6 @@ Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - /** * @file transport/gnunet-service-transport_hello.h * @brief hello API @@ -32,15 +31,15 @@ #include "gnunet_hello_lib.h" - /** * Signature of a function to call whenever our hello changes. * * @param cls closure * @param hello updated HELLO */ -typedef void (*GST_HelloCallback) (void *cls, - const struct GNUNET_MessageHeader * hello); +typedef void +(*GST_HelloCallback) (void *cls, + const struct GNUNET_MessageHeader *hello); /** @@ -48,10 +47,12 @@ typedef void (*GST_HelloCallback) (void *cls, * * @param friend_only use a friend only hello * @param cb function to call whenever our HELLO changes - * @param cb_cls closure for cb + * @param cb_cls closure for @a cb */ void -GST_hello_start (int friend_only, GST_HelloCallback cb, void *cb_cls); +GST_hello_start (int friend_only, + GST_HelloCallback cb, + void *cb_cls); /** @@ -73,7 +74,7 @@ GST_hello_get (void); /** * Add or remove an address from this peer's HELLO message. * - * @param addremove GNUNET_YES to add, GNUNET_NO to remove + * @param addremove #GNUNET_YES to add, #GNUNET_NO to remove * @param address address to add or remove */ void @@ -88,8 +89,8 @@ GST_hello_modify_addresses (int addremove, * @param sig location where to cache PONG signatures for this address [set] * @param sig_expiration how long until the current 'sig' expires? * (ZERO if sig was never created) [set] - * @return GNUNET_YES if this is one of our addresses, - * GNUNET_NO if not + * @return #GNUNET_YES if this is one of our addresses, + * #GNUNET_NO if not */ int GST_hello_test_address (const struct GNUNET_HELLO_Address *address, diff --git a/src/transport/gnunet-service-transport_manipulation.c b/src/transport/gnunet-service-transport_manipulation.c index 0d0249bc2..3d4701188 100644 --- a/src/transport/gnunet-service-transport_manipulation.c +++ b/src/transport/gnunet-service-transport_manipulation.c @@ -39,6 +39,7 @@ enum TRAFFIC_METRIC_DIRECTION TM_SEND = 0, TM_RECEIVE = 1, TM_BOTH = 2 }; + /** * Struct containing information about manipulations to a specific peer */ @@ -105,6 +106,7 @@ struct TM_Peer struct DelayQueueEntry *send_tail; }; + struct GST_ManipulationHandle { /** @@ -487,35 +489,39 @@ GST_manipulation_send(const struct GNUNET_PeerIdentity *target, const void *msg, * @param ats_count the number of ats information */ struct GNUNET_ATS_Information * -GST_manipulation_manipulate_metrics(const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_HELLO_Address *address, struct Session *session, - const struct GNUNET_ATS_Information *ats, uint32_t ats_count) +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_Information *ats_new = - GNUNET_malloc (sizeof (struct GNUNET_ATS_Information) *ats_count); + 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; - int d; - tmp = GNUNET_CONTAINER_multipeermap_get(man_handle.peers, peer); + 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); - } - + { + 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; } + /** * Adapter function between transport plugins and transport receive function * manipulation delays for next send. @@ -528,9 +534,9 @@ GST_manipulation_manipulate_metrics(const struct GNUNET_PeerIdentity *peer, */ struct GNUNET_TIME_Relative GST_manipulation_recv (void *cls, - const struct GNUNET_HELLO_Address *address, - struct Session *session, - const struct GNUNET_MessageHeader *message) + const struct GNUNET_HELLO_Address *address, + struct Session *session, + const struct GNUNET_MessageHeader *message) { struct TM_Peer *tmp; uint32_t p_recv_delay; diff --git a/src/transport/gnunet-service-transport_manipulation.h b/src/transport/gnunet-service-transport_manipulation.h index 668e91716..e020c3396 100644 --- a/src/transport/gnunet-service-transport_manipulation.h +++ b/src/transport/gnunet-service-transport_manipulation.h @@ -77,9 +77,10 @@ GST_manipulation_send (const struct GNUNET_PeerIdentity *target, */ struct GNUNET_TIME_Relative GST_manipulation_recv (void *cls, - const struct GNUNET_HELLO_Address *address, - struct Session *session, - const struct GNUNET_MessageHeader *message); + const struct GNUNET_HELLO_Address *address, + struct Session *session, + const struct GNUNET_MessageHeader *message); + /** * Function that will be called to manipulate ATS information according to @@ -90,13 +91,14 @@ GST_manipulation_recv (void *cls, * @param session the session * @param ats the ats information * @param ats_count the number of ats information + * @return modified @a ats information */ struct GNUNET_ATS_Information * -GST_manipulation_manipulate_metrics (const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_HELLO_Address *address, - struct Session *session, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count); +GST_manipulation_manipulate_metrics (const struct GNUNET_HELLO_Address *address, + struct Session *session, + const struct GNUNET_ATS_Information *ats, + uint32_t ats_count); + /** * Notify manipulation about disconnect so it can discard queued messages diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c index 1bf1fd754..40bad6d75 100644 --- a/src/transport/gnunet-service-transport_neighbours.c +++ b/src/transport/gnunet-service-transport_neighbours.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2010-2013 Christian Grothoff (and other contributing authors) + (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 @@ -25,13 +25,14 @@ */ #include "platform.h" #include "gnunet_ats_service.h" +#include "gnunet-service-transport_ats.h" +#include "gnunet-service-transport_blacklist.h" +#include "gnunet-service-transport_clients.h" #include "gnunet-service-transport_neighbours.h" #include "gnunet-service-transport_plugins.h" #include "gnunet-service-transport_validation.h" -#include "gnunet-service-transport_clients.h" #include "gnunet-service-transport.h" #include "gnunet_peerinfo_service.h" -#include "gnunet-service-transport_blacklist.h" #include "gnunet_constants.h" #include "transport.h" @@ -255,8 +256,6 @@ struct MessageQueue }; - - /** * A possible address we could use to communicate with a neighbour. */ @@ -301,6 +300,7 @@ struct NeighbourAddress uint32_t keep_alive_nonce; }; + /** * Entry in neighbours. */ @@ -344,12 +344,12 @@ struct NeighbourMapEntry * Main task that drives this peer (timeouts, keepalives, etc.). * Always runs the 'master_task'. */ - struct GNUNET_SCHEDULER_Task * task; + struct GNUNET_SCHEDULER_Task *task; /** * Task to disconnect neighbour after we received a DISCONNECT message */ - struct GNUNET_SCHEDULER_Task * delayed_disconnect_task; + struct GNUNET_SCHEDULER_Task *delayed_disconnect_task; /** * At what time should we sent the next keep-alive message? @@ -480,7 +480,7 @@ struct BlackListCheckContext /** - * Hash map from peer identities to the respective 'struct NeighbourMapEntry'. + * Hash map from peer identities to the respective `struct NeighbourMapEntry`. */ static struct GNUNET_CONTAINER_MultiPeerMap *neighbours; @@ -541,9 +541,15 @@ static unsigned long long bytes_in_send_queue; */ static struct GNUNET_SCHEDULER_Task * util_transmission_tk; - +/** + * FIXME + */ static struct GNUNET_CONTAINER_MultiPeerMap *registered_quota_notifications; + +/** + * FIXME + */ static char * print_ack_state (enum GST_ACK_State s) { @@ -589,6 +595,7 @@ test_connected (struct NeighbourMapEntry *n) return GNUNET_TRANSPORT_is_connected (n->state); } + /** * Send information about a new outbound quota to our clients. * @@ -701,9 +708,10 @@ set_timeout (struct NeighbourMapEntry *n, struct GNUNET_TIME_Absolute timeout) { n->timeout = timeout; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Neighbour `%s' changed timeout %s\n", - GNUNET_i2s (&n->id), - GNUNET_STRINGS_absolute_time_to_string (timeout)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Neighbour `%s' changed timeout %s\n", + GNUNET_i2s (&n->id), + GNUNET_STRINGS_absolute_time_to_string (timeout)); neighbour_change_cb (callback_cls, &n->id, n->primary_address.address, @@ -732,6 +740,7 @@ set_alternative_address (struct NeighbourMapEntry *n, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out) { struct GNUNET_TRANSPORT_PluginFunctions *papi; + if (NULL == (papi = GST_plugins_find (address->transport_name))) { GNUNET_break (0); @@ -750,14 +759,19 @@ set_alternative_address (struct NeighbourMapEntry *n, { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to obtain new session for peer `%s' and address '%s'\n", - GNUNET_i2s (&address->peer), GST_plugins_a2s (address)); - GNUNET_ATS_address_destroyed (GST_ats, address, NULL); + GNUNET_i2s (&address->peer), + GST_plugins_a2s (address)); + GNUNET_STATISTICS_update (GST_stats, + gettext_noop ("# session creation failed"), + 1, + GNUNET_NO); return; } - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Neighbour `%s' configured alternative address %s\n", - GNUNET_i2s (&n->id), - GST_plugins_a2s(address)); + GST_ats_new_session (address, session); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Neighbour `%s' configured alternative address %s\n", + GNUNET_i2s (&n->id), + GST_plugins_a2s(address)); n->alternative_address.address = GNUNET_HELLO_address_copy (address); n->alternative_address.bandwidth_in = bandwidth_in; @@ -802,8 +816,13 @@ set_primary_address (struct NeighbourMapEntry *n, if (is_active != n->primary_address.ats_active) { n->primary_address.ats_active = is_active; - GNUNET_ATS_address_in_use (GST_ats, n->primary_address.address, n->primary_address.session, is_active); - GST_validation_set_address_use (n->primary_address.address, n->primary_address.session, is_active); + GNUNET_ATS_address_in_use (GST_ats, + n->primary_address.address, + n->primary_address.session, + is_active); + GST_validation_set_address_use (n->primary_address.address, + n->primary_address.session, + is_active); } if (GNUNET_YES == is_active) { @@ -820,10 +839,13 @@ set_primary_address (struct NeighbourMapEntry *n, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to obtain new session for peer `%s' and address '%s'\n", GNUNET_i2s (&address->peer), GST_plugins_a2s (address)); - GNUNET_ATS_address_destroyed (GST_ats, address, NULL); + GNUNET_STATISTICS_update (GST_stats, + gettext_noop ("# session creation failed"), + 1, + GNUNET_NO); return; } - + GST_ats_new_session (address, session); n->primary_address.address = GNUNET_HELLO_address_copy (address); n->primary_address.bandwidth_in = bandwidth_in; n->primary_address.bandwidth_out = bandwidth_out; @@ -833,24 +855,31 @@ set_primary_address (struct NeighbourMapEntry *n, if (GNUNET_YES == is_active) { /* Telling ATS about new session */ - GNUNET_ATS_address_in_use (GST_ats, n->primary_address.address, n->primary_address.session, GNUNET_YES); - GST_validation_set_address_use (n->primary_address.address, n->primary_address.session, GNUNET_YES); + GNUNET_ATS_address_in_use (GST_ats, + n->primary_address.address, + n->primary_address.session, + GNUNET_YES); + GST_validation_set_address_use (n->primary_address.address, + n->primary_address.session, + GNUNET_YES); GST_neighbours_set_incoming_quota (&address->peer, bandwidth_in); send_outbound_quota (&address->peer, bandwidth_out); } - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Neighbour `%s' switched to address `%s'\n", - GNUNET_i2s (&n->id), - GST_plugins_a2s(address)); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Neighbour `%s' switched to address `%s'\n", + GNUNET_i2s (&n->id), + GST_plugins_a2s(address)); neighbour_change_cb (callback_cls, - &n->id, - n->primary_address.address, - n->state, n->timeout, - n->primary_address.bandwidth_in, - n->primary_address.bandwidth_out); + &n->id, + n->primary_address.address, + n->state, n->timeout, + n->primary_address.bandwidth_in, + n->primary_address.bandwidth_out); } + /** * Clear the primary address of a neighbour since this address is not * valid anymore and notify monitoring about it @@ -865,13 +894,14 @@ unset_primary_address (struct NeighbourMapEntry *n) /* Notify monitoring about it */ neighbour_change_cb (callback_cls, - &n->id, - NULL, - n->state, n->timeout, - n->primary_address.bandwidth_in, - n->primary_address.bandwidth_out); + &n->id, + NULL, + n->state, n->timeout, + n->primary_address.bandwidth_in, + n->primary_address.bandwidth_out); } + /** * Clear the alternative address of a neighbour since this address is not * valid anymore @@ -885,6 +915,7 @@ unset_alternative_address (struct NeighbourMapEntry *n) free_address (&n->alternative_address); } + /** * Free a neighbour map entry. * @@ -937,6 +968,8 @@ free_neighbour (struct NeighbourMapEntry *n, free_address (&n->alternative_address); /* cut all transport-level connection for this peer */ + // FIXME: might want to revisit this; maybe just + // shorten session timeout on plugin level? if ((GNUNET_NO == keep_sessions) && (NULL != backup_primary) && (NULL != (papi = GST_plugins_find (backup_primary->transport_name)))) @@ -1369,7 +1402,7 @@ send_keepalive (struct NeighbourMapEntry *n) */ void GST_neighbours_keepalive (const struct GNUNET_PeerIdentity *neighbour, - const struct GNUNET_MessageHeader *m) + const struct GNUNET_MessageHeader *m) { struct NeighbourMapEntry *n; const struct SessionKeepAliveMessage *msg_in; @@ -1422,7 +1455,7 @@ GST_neighbours_keepalive (const struct GNUNET_PeerIdentity *neighbour, */ void GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour, - const struct GNUNET_MessageHeader *m) + const struct GNUNET_MessageHeader *m) { struct NeighbourMapEntry *n; const struct SessionKeepAliveMessage *msg; @@ -1505,8 +1538,9 @@ GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour, else latency = n->latency.rel_value_us; ats.value = htonl (latency); - GST_ats_update_metrics (&n->id, n->primary_address.address, - n->primary_address.session, &ats, 1); + GST_ats_update_metrics (n->primary_address.address, + n->primary_address.session, + &ats, 1); } @@ -1655,12 +1689,13 @@ GST_neighbours_send (const struct GNUNET_PeerIdentity *target, const void *msg, n->task = GNUNET_SCHEDULER_add_now (&master_task, n); } + static void send_session_connect_cont (void *cls, - const struct GNUNET_PeerIdentity *target, - int result, - size_t size_payload, - size_t size_on_wire) + const struct GNUNET_PeerIdentity *target, + int result, + size_t size_payload, + size_t size_on_wire) { struct NeighbourMapEntry *n; @@ -1686,26 +1721,20 @@ send_session_connect_cont (void *cls, return; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - _("Failed to send SYN message to peer `%s' using address `%s' session %p\n"), - GNUNET_i2s (target), - GST_plugins_a2s (n->primary_address.address), - n->primary_address.session); + _("Failed to send SYN message to peer `%s' using address `%s' session %p\n"), + GNUNET_i2s (target), + GST_plugins_a2s (n->primary_address.address), + n->primary_address.session); switch (n->state) { case GNUNET_TRANSPORT_PS_SYN_SENT: /* Remove address and request and additional one */ - GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address, - n->primary_address.session); - GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address, NULL ); unset_primary_address (n); set_state_and_timeout (n, GNUNET_TRANSPORT_PS_INIT_ATS, - GNUNET_TIME_relative_to_absolute (FAST_RECONNECT_TIMEOUT)); + GNUNET_TIME_relative_to_absolute (FAST_RECONNECT_TIMEOUT)); break; case GNUNET_TRANSPORT_PS_RECONNECT_SENT: /* Remove address and request and additional one */ - GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address, - n->primary_address.session); - GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address, NULL ); unset_primary_address (n); set_state_and_timeout (n, GNUNET_TRANSPORT_PS_RECONNECT_ATS, GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT)); @@ -1714,10 +1743,6 @@ send_session_connect_cont (void *cls, /* Remove address and request and go back to primary address */ GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# Failed attempts to switch addresses (failed to send SYN CONT)"), 1, GNUNET_NO); - GNUNET_ATS_address_destroyed (GST_ats, n->alternative_address.address, - n->alternative_address.session); - GNUNET_ATS_address_destroyed (GST_ats, n->alternative_address.address, - NULL ); unset_alternative_address (n); set_state_and_timeout (n, GNUNET_TRANSPORT_PS_CONNECTED, GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT)); @@ -1756,6 +1781,8 @@ send_syn (struct NeighbourAddress *na) GNUNET_break (0); return; } + GST_ats_new_session (na->address, + na->session); GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# SYN messages sent"), @@ -1811,8 +1838,6 @@ send_syn (struct NeighbourAddress *na) disconnect_neighbour (n); break; } - GNUNET_ATS_address_destroyed (GST_ats, na->address, na->session); - GNUNET_ATS_address_destroyed (GST_ats, na->address, NULL); } GST_neighbours_notify_data_sent (&na->address->peer, na->address, @@ -1855,12 +1880,6 @@ send_session_connect_ack_cont (void *cls, GST_plugins_a2s (n->primary_address.address), n->primary_address.session); - /* Failed to send SYN_ACK message with this address */ - GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address, - n->primary_address.session); - GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address, - NULL); - /* Remove address and request and additional one */ unset_primary_address (n); n->ack_state = ACK_SEND_SYN_ACK; @@ -1903,6 +1922,7 @@ send_connect_ack_message (const struct GNUNET_HELLO_Address *address, GNUNET_break (0); return; } + GST_ats_new_session (address, session); GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# SYN_ACK messages sent"), @@ -1929,17 +1949,6 @@ send_connect_ack_message (const struct GNUNET_HELLO_Address *address, GNUNET_break (0); return; } - /* Hard failure to send the SYN_ACK message with this address: - Destroy session (and address) */ - if (GNUNET_YES == GNUNET_HELLO_address_check_option(address, - GNUNET_HELLO_ADDRESS_INFO_INBOUND)) - { - GNUNET_ATS_address_destroyed (GST_ats, address, session); - GNUNET_ATS_address_destroyed (GST_ats, address, NULL); - } - else - GNUNET_ATS_address_destroyed (GST_ats, address, session); - /* Remove address and request and additional one */ unset_primary_address (n); n->ack_state = ACK_SEND_SYN_ACK; @@ -1973,7 +1982,9 @@ find_notification_request (void *cls, const struct GNUNET_PeerIdentity *key, voi struct QuotaNotificationRequest *qnr = value; if ((qnr->session == qnr_ctx->session) && - (0 == memcmp (&qnr->peer, &qnr_ctx->peer, sizeof (struct GNUNET_PeerIdentity))) && + (0 == memcmp (&qnr->peer, + &qnr_ctx->peer, + sizeof (struct GNUNET_PeerIdentity))) && (0 == strcmp(qnr_ctx->plugin, qnr->plugin))) { qnr_ctx->res = value; @@ -1982,10 +1993,12 @@ find_notification_request (void *cls, const struct GNUNET_PeerIdentity *key, voi return GNUNET_YES; } + void -GST_neighbours_register_quota_notification(void *cls, - const struct GNUNET_PeerIdentity *peer, const char *plugin, - struct Session *session) +GST_neighbours_register_quota_notification (void *cls, + const struct GNUNET_PeerIdentity *peer, + const char *plugin, + struct Session *session) { struct QuotaNotificationRequest *qnr; struct QNR_LookContext qnr_ctx; @@ -2024,7 +2037,9 @@ GST_neighbours_register_quota_notification(void *cls, void GST_neighbours_unregister_quota_notification(void *cls, - const struct GNUNET_PeerIdentity *peer, const char *plugin, struct Session *session) + const struct GNUNET_PeerIdentity *peer, + const char *plugin, + struct Session *session) { struct QNR_LookContext qnr_ctx; @@ -2056,8 +2071,11 @@ GST_neighbours_unregister_quota_notification(void *cls, GNUNET_free (qnr_ctx.res); } + static int -notification_cb(void *cls, const struct GNUNET_PeerIdentity *key, void *value) +notification_cb (void *cls, + const struct GNUNET_PeerIdentity *key, + void *value) { /* struct NeighbourMapEntry *n = cls; */ struct QuotaNotificationRequest *qnr = value; @@ -2082,9 +2100,11 @@ notification_cb(void *cls, const struct GNUNET_PeerIdentity *key, void *value) return GNUNET_OK; } + static int -free_notification_cb(void *cls, const struct GNUNET_PeerIdentity *key, - void *value) +free_notification_cb (void *cls, + const struct GNUNET_PeerIdentity *key, + void *value) { /* struct NeighbourMapEntry *n = cls; */ struct QuotaNotificationRequest *qnr = value; @@ -2097,8 +2117,9 @@ free_notification_cb(void *cls, const struct GNUNET_PeerIdentity *key, return GNUNET_OK; } + static void -inbound_bw_tracker_update(void *cls) +inbound_bw_tracker_update (void *cls) { struct NeighbourMapEntry *n = cls; @@ -2144,18 +2165,44 @@ setup_neighbour (const struct GNUNET_PeerIdentity *peer) } +/** + * FIXME + */ struct BlacklistCheckSwitchContext { + /** + * FIXME + */ struct BlacklistCheckSwitchContext *prev; - struct BlacklistCheckSwitchContext *next; + /** + * FIXME + */ + struct BlacklistCheckSwitchContext *next; + /** + * FIXME + */ struct GST_BlacklistCheck *blc; + /** + * FIXME + */ struct GNUNET_HELLO_Address *address; + + /** + * FIXME + */ struct Session *session; + /** + * FIXME + */ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in; + + /** + * FIXME + */ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out; }; @@ -2465,18 +2512,13 @@ switch_address_bl_check_cont (void *cls, GNUNET_i2s (&blc_ctx->address->peer)); } - /* This address is blacklisted, delete address and session (if existing) in ATS */ - GNUNET_ATS_address_destroyed (GST_ats, blc_ctx->address, blc_ctx->session); - - if ( (GNUNET_YES == (GNUNET_HELLO_address_check_option (blc_ctx->address, - GNUNET_HELLO_ADDRESS_INFO_INBOUND))) && (NULL != blc_ctx->session)) - { - /* This is an inbound address, destroy full address */ - GNUNET_ATS_address_destroyed (GST_ats, blc_ctx->address, NULL ); - } + /* This address is blacklisted, delete session */ + /* FIXME: tell plugin to force killing session here and now! */ /* Remove blacklist check and clean up */ - GNUNET_CONTAINER_DLL_remove (pending_bc_head, pending_bc_tail, blc_ctx); + GNUNET_CONTAINER_DLL_remove (pending_bc_head, + pending_bc_tail, + blc_ctx); GNUNET_HELLO_address_free (blc_ctx->address); GNUNET_free (blc_ctx); return; @@ -2484,10 +2526,17 @@ switch_address_bl_check_cont (void *cls, if (NULL == blc_ctx->session) { - blc_ctx->session = papi->get_session (papi->cls, blc_ctx->address); + blc_ctx->session = papi->get_session (papi->cls, + blc_ctx->address); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Obtained new session for peer `%s' and address '%s': %p\n", - GNUNET_i2s (&blc_ctx->address->peer), GST_plugins_a2s (blc_ctx->address), blc_ctx->session); + GNUNET_i2s (&blc_ctx->address->peer), + GST_plugins_a2s (blc_ctx->address), + blc_ctx->session); + if (NULL != blc_ctx->session) + GST_ats_new_session (blc_ctx->address, + blc_ctx->session); + } if (NULL == blc_ctx->session) { @@ -2497,9 +2546,9 @@ switch_address_bl_check_cont (void *cls, GNUNET_i2s (&blc_ctx->address->peer), GST_plugins_a2s (blc_ctx->address)); /* Delete address in ATS */ - GNUNET_ATS_address_destroyed (GST_ats, blc_ctx->address, NULL); - - GNUNET_CONTAINER_DLL_remove (pending_bc_head, pending_bc_tail, blc_ctx); + GNUNET_CONTAINER_DLL_remove (pending_bc_head, + pending_bc_tail, + blc_ctx); GNUNET_HELLO_address_free (blc_ctx->address); GNUNET_free (blc_ctx); return; @@ -2721,21 +2770,15 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer, if (NULL == (GST_plugins_find (address->transport_name))) { /* we don't have the plugin for this address */ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Plugin `%s' is unknown, suggestion for peer %s ignored\n", - address->transport_name, - GNUNET_i2s (peer)); - GNUNET_ATS_address_destroyed (GST_ats, address, NULL); + GNUNET_break (0); return; } if ((NULL == session) && - (GNUNET_HELLO_address_check_option (address, GNUNET_HELLO_ADDRESS_INFO_INBOUND))) + (GNUNET_HELLO_address_check_option (address, + GNUNET_HELLO_ADDRESS_INFO_INBOUND))) { /* This is a inbound address and we do not have a session to use! */ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Inbound address without session `%s'! Destroying address...\n", - GST_plugins_a2s (address)); - GNUNET_ATS_address_destroyed (GST_ats, address, NULL); + GNUNET_break (0); return; } @@ -2766,6 +2809,15 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer, } +/** + * Function called to send network utilization data to ATS for + * each active connection. + * + * @param cls NULL + * @param key peer we send utilization data for + * @param value the `struct NeighbourMapEntry *` with data to send + * @return #GNUNET_OK (continue to iterate) + */ static int send_utilization_data (void *cls, const struct GNUNET_PeerIdentity *key, @@ -2779,6 +2831,8 @@ send_utilization_data (void *cls, uint32_t bps_out; struct GNUNET_TIME_Relative delta; + if (GNUNET_TRANSPORT_PS_CONNECTED != n->state) + return GNUNET_OK; delta = GNUNET_TIME_absolute_get_difference (n->last_util_transmission, GNUNET_TIME_absolute_get ()); @@ -2817,8 +2871,9 @@ send_utilization_data (void *cls, atsi[3].type = htonl (GNUNET_ATS_UTILIZATION_PAYLOAD_IN); atsi[3].value = htonl (bps_pl_in); - GST_ats_update_metrics (key, n->primary_address.address, - n->primary_address.session, atsi, 4); + GST_ats_update_metrics (n->primary_address.address, + n->primary_address.session, + atsi, 4); n->util_payload_bytes_recv = 0; n->util_payload_bytes_sent = 0; n->util_total_bytes_recv = 0; @@ -2952,12 +3007,6 @@ master_task (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connection to `%s' timed out waiting for other peer to send SYN_ACK\n", GNUNET_i2s (&n->id)); - /* We could not send to this address, delete address and session */ - if (NULL != n->primary_address.session) - GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address, - n->primary_address.session); - GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address, NULL); - /* Remove address and request and additional one */ unset_primary_address (n); set_state_and_timeout (n, GNUNET_TRANSPORT_PS_INIT_ATS, @@ -3023,8 +3072,10 @@ master_task (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connection to `%s' timed out, missing KEEPALIVE_RESPONSEs (after trying to SYN on alternative address)\n", GNUNET_i2s (&n->id)); - GNUNET_STATISTICS_update (GST_stats, gettext_noop - ("# Failed attempts to switch addresses (no response)"), 1, GNUNET_NO); + GNUNET_STATISTICS_update (GST_stats, + gettext_noop ("# Failed attempts to switch addresses (no response)"), + 1, + GNUNET_NO); disconnect_neighbour (n); return; } @@ -3161,17 +3212,12 @@ GST_neighbours_handle_session_syn_ack (const struct GNUNET_MessageHeader *messag n->primary_address.bandwidth_in, n->primary_address.bandwidth_out); /* Tell ATS that the outbound session we created to send SYN was successful */ - // FIXME: shouldn't ATS already know about *outbound* sessions - // in particular? - GST_ats_add_address (n->primary_address.address, - n->primary_address.session, - NULL, 0); set_primary_address (n, - n->primary_address.address, - n->primary_address.session, - n->primary_address.bandwidth_in, - n->primary_address.bandwidth_out, - GNUNET_YES); + n->primary_address.address, + n->primary_address.session, + n->primary_address.bandwidth_in, + n->primary_address.bandwidth_out, + GNUNET_YES); send_session_ack_message (n); break; case GNUNET_TRANSPORT_PS_SYN_RECV_ATS: @@ -3202,13 +3248,9 @@ GST_neighbours_handle_session_syn_ack (const struct GNUNET_MessageHeader *messag case GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT: /* new address worked; adopt it and go back to connected! */ set_state_and_timeout (n, GNUNET_TRANSPORT_PS_CONNECTED, - GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT)); + GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT)); GNUNET_break (GNUNET_NO == n->alternative_address.ats_active); - /* Notify about session... perhaps we obtained it */ - // FIXME: why is this needed? - GST_ats_add_address (n->alternative_address.address, - n->alternative_address.session, NULL, 0); /* Set primary addresses */ set_primary_address (n, n->alternative_address.address, n->alternative_address.session, n->alternative_address.bandwidth_in, @@ -3309,7 +3351,6 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer, GNUNET_i2s (peer)); /* Destroy the address since it cannot be used */ - GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address, NULL); unset_primary_address (n); set_state_and_timeout (n, GNUNET_TRANSPORT_PS_INIT_ATS, GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT)); @@ -3337,9 +3378,7 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer, GST_plugins_a2s (n->primary_address.address), n->primary_address.session, GNUNET_i2s (peer)); - /* Destroy the address since it cannot be used */ - GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address, NULL); unset_primary_address (n); set_state_and_timeout (n, GNUNET_TRANSPORT_PS_RECONNECT_ATS, GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT)); @@ -3358,13 +3397,7 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer, n->alternative_address.session); /* Destroy the inbound address since it cannot be used */ - if (GNUNET_YES - == GNUNET_HELLO_address_check_option (n->primary_address.address, - GNUNET_HELLO_ADDRESS_INFO_INBOUND)) - GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address, NULL); free_address (&n->primary_address); - - n->primary_address = n->alternative_address; memset (&n->alternative_address, 0, sizeof (struct NeighbourAddress)); set_state_and_timeout (n, GNUNET_TRANSPORT_PS_RECONNECT_SENT, @@ -3487,20 +3520,13 @@ GST_neighbours_handle_session_ack (const struct GNUNET_MessageHeader *message, set_state_and_timeout (n, GNUNET_TRANSPORT_PS_CONNECTED, GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT)); - /* Add session to ATS since no session was given (NULL) and we may have - * obtained a new session */ - // FIXME: likely not the best place to do this... - GST_ats_add_address (n->primary_address.address, - n->primary_address.session, - NULL, 0); - /* Set primary address to used */ set_primary_address (n, - n->primary_address.address, - n->primary_address.session, - n->primary_address.bandwidth_in, - n->primary_address.bandwidth_out, - GNUNET_YES); + n->primary_address.address, + n->primary_address.session, + n->primary_address.bandwidth_in, + n->primary_address.bandwidth_out, + GNUNET_YES); return GNUNET_OK; } @@ -3554,8 +3580,10 @@ GST_neighbours_set_incoming_quota (const struct GNUNET_PeerIdentity *neighbour, disconnect_neighbour (n); } -void delayed_disconnect (void *cls, - const struct GNUNET_SCHEDULER_TaskContext* tc) + +static void +delayed_disconnect (void *cls, + const struct GNUNET_SCHEDULER_TaskContext* tc) { struct NeighbourMapEntry *n = cls; @@ -3563,11 +3591,6 @@ void delayed_disconnect (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Disconnecting by request from peer %s\n", GNUNET_i2s (&n->id)); - - if (NULL != n->primary_address.address) - GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address, - n->primary_address.session); - free_neighbour (n, GNUNET_NO); } @@ -3871,16 +3894,18 @@ GST_neighbours_stop () GNUNET_SCHEDULER_cancel (util_transmission_tk); util_transmission_tk = NULL; } - - GNUNET_CONTAINER_multipeermap_iterate (neighbours, &disconnect_all_neighbours, - NULL ); + GNUNET_CONTAINER_multipeermap_iterate (neighbours, + &disconnect_all_neighbours, + NULL); GNUNET_CONTAINER_multipeermap_destroy (neighbours); next = pending_bc_head; - for (cur = next; NULL != cur; cur = next ) + for (cur = next; NULL != cur; cur = next) { next = cur->next; - GNUNET_CONTAINER_DLL_remove (pending_bc_head, pending_bc_tail, cur); + GNUNET_CONTAINER_DLL_remove (pending_bc_head, + pending_bc_tail, + cur); if (NULL != cur->blc) { @@ -3893,7 +3918,7 @@ GST_neighbours_stop () } GNUNET_CONTAINER_multipeermap_iterate (registered_quota_notifications, - &free_notification_cb, NULL); + &free_notification_cb, NULL); GNUNET_CONTAINER_multipeermap_destroy (registered_quota_notifications); registered_quota_notifications = NULL; diff --git a/src/transport/gnunet-service-transport_neighbours.h b/src/transport/gnunet-service-transport_neighbours.h index 49a54e9dd..744a3b913 100644 --- a/src/transport/gnunet-service-transport_neighbours.h +++ b/src/transport/gnunet-service-transport_neighbours.h @@ -86,10 +86,14 @@ GST_neighbours_test_connected (const struct GNUNET_PeerIdentity *target); * * @param cls closure * @param success #GNUNET_OK on success, #GNUNET_NO on failure, #GNUNET_SYSERR if we're not connected + * @param bytes_payload how much payload was transmitted + * @param bytes_on_wire how many bytes were used on the wire */ -typedef void (*GST_NeighbourSendContinuation) (void *cls, int success, - size_t bytes_payload, - size_t bytes_on_wire); +typedef void +(*GST_NeighbourSendContinuation) (void *cls, + int success, + size_t bytes_payload, + size_t bytes_on_wire); /** @@ -103,19 +107,33 @@ typedef void (*GST_NeighbourSendContinuation) (void *cls, int success, * @param cont_cls closure for @a cont */ void -GST_neighbours_send (const struct GNUNET_PeerIdentity *target, const void *msg, - size_t msg_size, struct GNUNET_TIME_Relative timeout, +GST_neighbours_send (const struct GNUNET_PeerIdentity *target, + const void *msg, + size_t msg_size, + struct GNUNET_TIME_Relative timeout, GST_NeighbourSendContinuation cont, void *cont_cls); + + +/** + * FIXME + */ void GST_neighbours_register_quota_notification (void *cls, const struct GNUNET_PeerIdentity *peer, const char *plugin, struct Session *session); + +/** + * FIXME + */ void -GST_neighbours_unregister_quota_notification(void *cls, - const struct GNUNET_PeerIdentity *peer, const char *plugin, struct Session *session); +GST_neighbours_unregister_quota_notification (void *cls, + const struct GNUNET_PeerIdentity *peer, + const char *plugin, + struct Session *session); + /** * We have received a message from the given sender. @@ -129,8 +147,9 @@ GST_neighbours_unregister_quota_notification(void *cls, * @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); /** @@ -155,7 +174,7 @@ GST_neighbours_keepalive (const struct GNUNET_PeerIdentity *neighbour, */ void GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour, - const struct GNUNET_MessageHeader *m); + const struct GNUNET_MessageHeader *m); /** @@ -189,13 +208,14 @@ GST_neighbours_force_disconnect (const struct GNUNET_PeerIdentity *target); * @param bandwidth_in inbound quota in NBO * @param bandwidth_out outbound quota in NBO */ -typedef void (*GST_NeighbourIterator) (void *cls, - const struct GNUNET_PeerIdentity *neighbour, - const struct GNUNET_HELLO_Address *address, - enum GNUNET_TRANSPORT_PeerState state, - struct GNUNET_TIME_Absolute state_timeout, - struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, - struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out); +typedef void +(*GST_NeighbourIterator) (void *cls, + const struct GNUNET_PeerIdentity *neighbour, + const struct GNUNET_HELLO_Address *address, + enum GNUNET_TRANSPORT_PeerState state, + struct GNUNET_TIME_Absolute state_timeout, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out); /** @@ -221,6 +241,9 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer, struct Session *session); +/** + * FIXME + */ void GST_neighbours_notify_data_recv (const struct GNUNET_PeerIdentity *peer, const struct GNUNET_HELLO_Address *address, @@ -228,6 +251,9 @@ GST_neighbours_notify_data_recv (const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *message); +/** + * FIXME + */ void GST_neighbours_notify_payload_recv (const struct GNUNET_PeerIdentity *peer, const struct GNUNET_HELLO_Address *address, @@ -235,11 +261,17 @@ GST_neighbours_notify_payload_recv (const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *message); +/** + * FIXME + */ void GST_neighbours_notify_payload_sent (const struct GNUNET_PeerIdentity *peer, size_t size); +/** + * FIXME + */ void GST_neighbours_notify_data_sent (const struct GNUNET_PeerIdentity *peer, const struct GNUNET_HELLO_Address *address, @@ -276,14 +308,14 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer, */ int GST_neighbours_handle_session_syn (const struct GNUNET_MessageHeader *message, - const struct GNUNET_PeerIdentity *peer); + const struct GNUNET_PeerIdentity *peer); /** * We received a 'SESSION_CONNECT_ACK' message from the other peer. * Consider switching to it. * - * @param message possibly a 'struct SessionConnectMessage' (check format) + * @param message possibly a `struct SessionConnectMessage` (check format) * @param peer identity of the peer to switch the address for * @param address address of the other peer, NULL if other peer * connected to us @@ -292,9 +324,9 @@ GST_neighbours_handle_session_syn (const struct GNUNET_MessageHeader *message, */ int GST_neighbours_handle_session_syn_ack (const struct GNUNET_MessageHeader *message, - const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_HELLO_Address *address, - struct Session *session); + const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_HELLO_Address *address, + struct Session *session); /** @@ -345,10 +377,8 @@ GST_neighbour_get_current_address (const struct GNUNET_PeerIdentity *peer); * @param msg the disconnect message */ void -GST_neighbours_handle_disconnect_message (const struct GNUNET_PeerIdentity - *peer, - const struct GNUNET_MessageHeader - *msg); +GST_neighbours_handle_disconnect_message (const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_MessageHeader *msg); #endif diff --git a/src/transport/gnunet-service-transport_validation.c b/src/transport/gnunet-service-transport_validation.c index b02c90009..03b125dc5 100644 --- a/src/transport/gnunet-service-transport_validation.c +++ b/src/transport/gnunet-service-transport_validation.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2010-2014 Christian Grothoff (and other contributing authors) + (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 @@ -24,12 +24,13 @@ * @author Christian Grothoff */ #include "platform.h" +#include "gnunet-service-transport_ats.h" +#include "gnunet-service-transport_blacklist.h" #include "gnunet-service-transport_clients.h" -#include "gnunet-service-transport_validation.h" -#include "gnunet-service-transport_plugins.h" #include "gnunet-service-transport_hello.h" -#include "gnunet-service-transport_blacklist.h" #include "gnunet-service-transport_neighbours.h" +#include "gnunet-service-transport_plugins.h" +#include "gnunet-service-transport_validation.h" #include "gnunet-service-transport.h" #include "gnunet_hello_lib.h" #include "gnunet_ats_service.h" @@ -253,6 +254,7 @@ struct ValidationEntry * Current state of this validation entry */ enum GNUNET_TRANSPORT_ValidationState state; + /** * Challenge number we used. */ @@ -274,6 +276,11 @@ struct ValidationEntry */ int expecting_pong; + /** + * Is this address known to ATS as valid right now? + */ + int known_to_ats; + /** * Which network type does our address belong to? */ @@ -445,6 +452,11 @@ cleanup_validation_entry (void *cls, GNUNET_break (GNUNET_OK == GNUNET_CONTAINER_multipeermap_remove (validation_map, &ve->pid, ve)); + if (GNUNET_YES == ve->known_to_ats) + { + GST_ats_expire_address (ve->address); + ve->known_to_ats = GNUNET_NO; + } GNUNET_HELLO_address_free (ve->address); if (NULL != ve->timeout_task) { @@ -593,7 +605,8 @@ transmit_ping_if_allowed (void *cls, { GNUNET_assert (NULL != papi->send); GNUNET_assert (NULL != papi->get_session); - struct Session * session = papi->get_session(papi->cls, ve->address); + struct Session *session = papi->get_session (papi->cls, + ve->address); if (NULL != session) { @@ -847,8 +860,11 @@ add_valid_address (void *cls, ats.type = htonl (GNUNET_ATS_NETWORK_TYPE); ats.value = htonl (ve->network); - GNUNET_ATS_address_add (GST_ats, address, NULL, &ats, 1); - + if (GNUNET_YES != ve->known_to_ats) + { + ve->known_to_ats = GNUNET_YES; + GST_ats_add_address (address, NULL, &ats, 1); + } return GNUNET_OK; } @@ -975,6 +991,7 @@ multicast_pong (void *cls, GNUNET_break (0); return; } + GST_ats_new_session (address, session); papi->send (papi->cls, session, (const char *) pong, ntohs (pong->header.size), @@ -1190,18 +1207,19 @@ GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender, /* first see if the session we got this PING from can be used to transmit * a response reliably */ - if (papi == NULL) + if (NULL == papi) + { ret = -1; + } else { - GNUNET_assert (papi->send != NULL); - GNUNET_assert (papi->get_session != NULL); - - if (session == NULL) + GNUNET_assert (NULL != papi->send); + GNUNET_assert (NULL != papi->get_session); + if (NULL == session) { session = papi->get_session (papi->cls, sender_address); } - if (session == NULL) + if (NULL == session) { GNUNET_break (0); ret = -1; @@ -1491,8 +1509,15 @@ GST_validation_handle_pong (const struct GNUNET_PeerIdentity *sender, 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); - // FIXME: add vs. update! - GNUNET_ATS_address_add (GST_ats, ve->address, NULL, ats, 2); + if (GNUNET_YES == ve->known_to_ats) + { + GST_ats_update_metrics (ve->address, NULL, ats, 2); + } + else + { + ve->known_to_ats = GNUNET_YES; + GST_ats_add_address (ve->address, NULL, ats, 2); + } } if (validations_running > 0) { @@ -1668,7 +1693,6 @@ GST_validation_set_address_use (const struct GNUNET_HELLO_Address *address, } if (ve->in_use == in_use) { - if (GNUNET_YES == in_use) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, -- cgit v1.2.3