From 6c147cc9bfa5ac134269593d6e4dbcd0be66ac91 Mon Sep 17 00:00:00 2001 From: Matthias Wachs Date: Fri, 15 Jun 2012 09:09:32 +0000 Subject: [PATCH] - changes related to ATS_address_add + testcases for address deletion and adding --- src/ats/Makefile.am | 8 +- src/ats/gnunet-service-ats_addresses.c | 110 +++++---- src/ats/test_ats_api_reset_backoff.c | 1 + src/ats/test_ats_api_scheduling.c | 15 +- src/ats/test_ats_api_scheduling_add_address.c | 13 +- .../test_ats_api_scheduling_destroy_address.c | 228 ++++++++++++++++++ .../gnunet-service-transport_neighbours.c | 10 +- .../gnunet-service-transport_validation.c | 4 +- 8 files changed, 308 insertions(+), 81 deletions(-) create mode 100644 src/ats/test_ats_api_scheduling_destroy_address.c diff --git a/src/ats/Makefile.am b/src/ats/Makefile.am index 5b1c6b2e4..87a7fc05a 100644 --- a/src/ats/Makefile.am +++ b/src/ats/Makefile.am @@ -54,9 +54,10 @@ gnunet_service_ats_LDADD = \ check_PROGRAMS = \ + test_ats_api_scheduling_add_address \ test_ats_api_scheduling \ + test_ats_api_scheduling_destroy_address \ test_ats_api_reset_backoff \ - test_ats_api_scheduling_add_address \ $(GN_MLP_TEST) \ $(GN_MLP_TEST_AVG) \ $(GN_MLP_PERF) @@ -111,6 +112,11 @@ test_ats_api_scheduling_add_address_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/ats/libgnunetats.la +test_ats_api_scheduling_destroy_address_SOURCES = \ + test_ats_api_scheduling_destroy_address.c +test_ats_api_scheduling_destroy_address_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/ats/libgnunetats.la #test_ats_api_scheduling_get_type_SOURCES = \ # test_ats_api_scheduling_get_type.c diff --git a/src/ats/gnunet-service-ats_addresses.c b/src/ats/gnunet-service-ats_addresses.c index 854716dc7..aedef817f 100644 --- a/src/ats/gnunet-service-ats_addresses.c +++ b/src/ats/gnunet-service-ats_addresses.c @@ -288,6 +288,44 @@ find_address (const struct GNUNET_PeerIdentity *peer, } +static struct ATS_Address * +lookup_address (const struct GNUNET_PeerIdentity *peer, + const char *plugin_name, const void *plugin_addr, + size_t plugin_addr_len, uint32_t session_id, + const struct GNUNET_ATS_Information *atsi, + uint32_t atsi_count) +{ + struct ATS_Address *aa; + struct ATS_Address *old; + + aa = create_address (peer, + plugin_name, + plugin_addr, plugin_addr_len, + session_id); + + aa->mlp_information = NULL; + aa->ats = GNUNET_malloc (atsi_count * sizeof (struct GNUNET_ATS_Information)); + aa->ats_count = atsi_count; + memcpy (aa->ats, atsi, atsi_count * sizeof (struct GNUNET_ATS_Information)); + + /* Get existing address or address with session == 0 */ + old = find_address (peer, aa); + if (old == NULL) + { + GNUNET_free (aa); + return NULL; + } + else if (old->session_id != session_id) + { + + GNUNET_free (aa); + GNUNET_break (0); + return NULL; + } + + return old; +} + static int compare_address_session_it (void *cls, const struct GNUNET_HashCode * key, void *value) { @@ -400,7 +438,6 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer, const struct GNUNET_ATS_Information *atsi, uint32_t atsi_count) { - struct ATS_Address *aa; struct ATS_Address *old; uint32_t i; @@ -409,51 +446,17 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer, GNUNET_assert (NULL != addresses); - aa = create_address (peer, - plugin_name, - plugin_addr, plugin_addr_len, - session_id); - - aa->mlp_information = NULL; - aa->ats = GNUNET_malloc (atsi_count * sizeof (struct GNUNET_ATS_Information)); - aa->ats_count = atsi_count; - memcpy (aa->ats, atsi, atsi_count * sizeof (struct GNUNET_ATS_Information)); - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating address for peer `%s' %u\n", - GNUNET_i2s (peer), - session_id); - - /* Get existing address or address with session == 0 */ - old = find_address (peer, aa); + /* Get existing address */ + old = lookup_address(peer, plugin_name, plugin_addr, plugin_addr_len, + session_id, atsi, atsi_count); if (old == NULL) { - GNUNET_assert (GNUNET_OK == - GNUNET_CONTAINER_multihashmap_put (addresses, - &peer->hashPubKey, aa, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); -#if DEBUG_ATS - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Added new address for peer `%s' %p\n", - GNUNET_i2s (peer), aa); -#endif - old = aa; - } - else - { -#if DEBUG_ATS - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Updated existing address for peer `%s' %p old session %u new session %u\n", - GNUNET_i2s (peer), old, - old->session_id, session_id); -#endif - GNUNET_free_non_null (old->ats); - old->session_id = session_id; - old->ats = NULL; - old->ats_count = 0; - old->ats = aa->ats; - old->ats_count = aa->ats_count; - GNUNET_free (aa->plugin); - GNUNET_free (aa); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Tried to update unknown address for peer `%s' `%s' session id %u\n", + GNUNET_i2s (peer), plugin_name, session_id); + GNUNET_break (0); + return; } + for (i = 0; i < atsi_count; i++) switch (ntohl (atsi[i].type)) { @@ -578,10 +581,23 @@ GAS_addresses_destroy (const struct GNUNET_PeerIdentity *peer, size_t plugin_addr_len, uint32_t session_id) { struct ATS_Address *aa; + struct ATS_Address *old; if (GNUNET_NO == running) return; + /* Get existing address */ + old = lookup_address(peer, plugin_name, plugin_addr, plugin_addr_len, + session_id, NULL, 0); + if (old == NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Tried to destroy unknown address for peer `%s' `%s' session id %u\n", + GNUNET_i2s (peer), plugin_name, session_id); + GNUNET_break (0); + return; + } + + GNUNET_break (0 < strlen (plugin_name)); aa = create_address (peer, plugin_name, plugin_addr, plugin_addr_len, session_id); @@ -692,20 +708,16 @@ GAS_addresses_in_use (const struct GNUNET_PeerIdentity *peer, GNUNET_i2s (peer), in_use); #endif - struct ATS_Address *aa; struct ATS_Address *old; if (GNUNET_NO == running) return GNUNET_SYSERR; - aa = create_address (peer, plugin_name, plugin_addr, plugin_addr_len, session_id); - old = find_exact_address (peer, aa); - free_address (aa); - + old = lookup_address (peer, plugin_name, plugin_addr, plugin_addr_len, session_id, NULL, 0); if (NULL == old) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unknown address `%s', %s %u %s \n", + "Trying to set unknown address `%s', %s %u %s \n", GNUNET_i2s (peer), plugin_name, session_id, (GNUNET_NO == in_use) ? "NO" : "YES"); diff --git a/src/ats/test_ats_api_reset_backoff.c b/src/ats/test_ats_api_reset_backoff.c index 38c18e1ac..859cfc215 100644 --- a/src/ats/test_ats_api_reset_backoff.c +++ b/src/ats/test_ats_api_reset_backoff.c @@ -273,6 +273,7 @@ check (void *cls, char *const *args, const char *cfgfile, hello_addr.transport_name = address.plugin; hello_addr.address = address.addr; hello_addr.address_length = address.addr_len; + GNUNET_ATS_address_add (ats, &hello_addr, address.session, NULL, 0); GNUNET_ATS_address_update (ats, &hello_addr, address.session, NULL, 0); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Requesting address for peer `%s'\n", diff --git a/src/ats/test_ats_api_scheduling.c b/src/ats/test_ats_api_scheduling.c index c9d2206b3..6a8e53395 100644 --- a/src/ats/test_ats_api_scheduling.c +++ b/src/ats/test_ats_api_scheduling.c @@ -134,15 +134,6 @@ address_suggest_cb (void *cls, const struct GNUNET_HELLO_Address *address, address->address_length)); GNUNET_assert (addr[0].session == session); - - /* TODO ats merge - * GNUNET_assert (ats_count == 2); - * GNUNET_assert (atsi[0].type == htons (1)); - * GNUNET_assert (atsi[0].type == htons (2)); - * GNUNET_assert (atsi[1].type == htons (2)); - * GNUNET_assert (atsi[1].type == htons (2)); - */ - ret = 0; GNUNET_SCHEDULER_add_now (&end, NULL); @@ -199,6 +190,7 @@ check (void *cls, char *const *args, const char *cfgfile, address0.transport_name = addr[0].plugin; address0.address = addr[0].addr; address0.address_length = addr[0].addr_len; + GNUNET_ATS_address_add (ats, &address0, addr[0].session, NULL, 0); GNUNET_ATS_address_update (ats, &address0, addr[0].session, NULL, 0); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing ATS info creation\n"); @@ -218,11 +210,6 @@ check (void *cls, char *const *args, const char *cfgfile, GNUNET_ATS_address_update (ats, &address0, addr[0].session, atsi, 2); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing manual address deletion \n"); - address0.peer = p[1].id; // FIXME: why? typo in old code? - GNUNET_ATS_address_update (ats, &address0, addr[0].session, NULL, 0); - GNUNET_ATS_address_destroyed (ats, &address0, addr[0].session); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Requesting peer `%s'\n", GNUNET_i2s (&p[0].id)); GNUNET_ATS_suggest_address (ats, &p[0].id); diff --git a/src/ats/test_ats_api_scheduling_add_address.c b/src/ats/test_ats_api_scheduling_add_address.c index 04ece4044..f3f0f55a7 100644 --- a/src/ats/test_ats_api_scheduling_add_address.c +++ b/src/ats/test_ats_api_scheduling_add_address.c @@ -18,17 +18,10 @@ Boston, MA 02111-1307, USA. */ /** - * @file ats/test_ats_api_scheduling.c - * @brief test automatic transport selection scheduling API + * @file ats/test_ats_api_scheduling_add_address.c + * @brief test adding addresses in automatic transport selection scheduling API * @author Christian Grothoff * @author Matthias Wachs - * - * TODO: - * - write test case - * - extend API to get performance data - * - implement simplistic strategy based on say 'lowest latency' or strict ordering - * - extend API to get peer preferences, implement proportional bandwidth assignment - * - re-implement API against a real ATS service (!) */ #include "platform.h" #include "gnunet_ats_service.h" @@ -223,4 +216,4 @@ main (int argc, char *argv[]) return ret; } -/* end of file test_ats_api_scheduling.c */ +/* end of file test_ats_api_scheduling_add_address.c */ diff --git a/src/ats/test_ats_api_scheduling_destroy_address.c b/src/ats/test_ats_api_scheduling_destroy_address.c new file mode 100644 index 000000000..ae2b4727d --- /dev/null +++ b/src/ats/test_ats_api_scheduling_destroy_address.c @@ -0,0 +1,228 @@ +/* + This file is part of GNUnet. + (C) 2010,2011 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 ats/test_ats_api_scheduling_destroy_address.c + * @brief test destroying addresses in automatic transport selection scheduling API + * @author Christian Grothoff + * @author Matthias Wachs + * + */ +#include "platform.h" +#include "gnunet_ats_service.h" +#include "ats.h" + +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) + +static GNUNET_SCHEDULER_TaskIdentifier die_task; + +static struct GNUNET_ATS_SchedulingHandle *ats; + +struct GNUNET_OS_Process *arm_proc; + + + +static int ret; +static int stage; + +struct Address +{ + char *plugin; + size_t plugin_len; + + void *addr; + size_t addr_len; + + struct GNUNET_ATS_Information *ats; + int ats_count; + + void *session; +}; + +struct PeerContext +{ + struct GNUNET_PeerIdentity id; + + struct Address *addr; +}; + +struct Address addr; +struct PeerContext p; +struct GNUNET_ATS_Information atsi; +struct GNUNET_HELLO_Address address0; + +static void +stop_arm () +{ + if (0 != GNUNET_OS_process_kill (arm_proc, SIGTERM)) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); + GNUNET_OS_process_wait (arm_proc); + GNUNET_OS_process_destroy (arm_proc); + arm_proc = NULL; +} + + +static void +end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + die_task = GNUNET_SCHEDULER_NO_TASK; + if (ats != NULL) + GNUNET_ATS_scheduling_done (ats); + + ret = GNUNET_SYSERR; + + stop_arm (); +} + + +static void +end () +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down\n"); + if (die_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (die_task); + die_task = GNUNET_SCHEDULER_NO_TASK; + } + + GNUNET_ATS_scheduling_done (ats); + + if (2 == stage) + ret = 0; + else + { + GNUNET_break (0); + ret = 1; + } + + stop_arm (); +} + + +static void +address_suggest_cb (void *cls, const struct GNUNET_HELLO_Address *address, + struct Session *session, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, + const struct GNUNET_ATS_Information *atsi, + uint32_t ats_count) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage %u: ATS suggests address `%s' session %p\n", + stage, GNUNET_i2s (&address->peer), session); + GNUNET_ATS_reset_backoff(ats, &address->peer); + + GNUNET_assert (0 == + memcmp (&address->peer, &p.id, + sizeof (struct GNUNET_PeerIdentity))); + GNUNET_assert (0 == strcmp (address->transport_name, addr.plugin)); + GNUNET_assert (address->address_length == addr.addr_len); + GNUNET_assert (0 == + memcmp (address->address, addr.plugin, + address->address_length)); + GNUNET_assert (addr.session == session); + + if (0 == stage) + { + /* Delete session */ + GNUNET_ATS_address_destroyed (ats, &address0, addr.session); + addr.session = NULL; + GNUNET_ATS_suggest_address (ats, &p.id); + } + if (1 == stage) + { + /* Delete address */ + GNUNET_ATS_address_destroyed (ats, &address0, addr.session); + addr.session = NULL; + GNUNET_ATS_suggest_address (ats, &p.id); + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &end, NULL); + } + stage++; +} + +void +start_arm (const char *cfgname) +{ + arm_proc = + GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", + "gnunet-service-arm", + "-c", cfgname, NULL); +} + +static void +check (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + ret = GNUNET_SYSERR; + + die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL); + start_arm (cfgfile); + + ats = GNUNET_ATS_scheduling_init (cfg, &address_suggest_cb, NULL); + + if (ats == NULL) + { + ret = GNUNET_SYSERR; + end (); + return; + } + + /* set up peer */ + GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, + &p.id.hashPubKey); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n", + GNUNET_i2s (&p.id)); + + addr.plugin = "test"; + addr.session = &addr; + addr.addr = GNUNET_strdup ("test"); + addr.addr_len = 4; + + /* Adding address with session */ + address0.peer = p.id; + address0.transport_name = addr.plugin; + address0.address = addr.addr; + address0.address_length = addr.addr_len; + GNUNET_ATS_address_add (ats, &address0, addr.session, NULL, 0); + + GNUNET_ATS_suggest_address (ats, &p.id); +} + +int +main (int argc, char *argv[]) +{ + static char *const argv2[] = { "test_ats_api_scheduling_destroy_address", + "-c", + "test_ats_api.conf", + "-L", "WARNING", + NULL + }; + + static struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2, + "test_ats_api_scheduling_destroy_address", "nohelp", options, &check, + NULL); + + + return ret; +} + +/* end of file test_ats_api_scheduling_destroy_address.c */ diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c index edefbd2a6..dd724e87b 100644 --- a/src/transport/gnunet-service-transport_neighbours.c +++ b/src/transport/gnunet-service-transport_neighbours.c @@ -832,7 +832,7 @@ set_address (struct NeighbourAddress *na, if (GNUNET_YES == is_active) { /* Telling ATS about new session */ - GNUNET_ATS_address_update (GST_ats, na->address, na->session, NULL, 0); + GNUNET_ATS_address_add (GST_ats, na->address, na->session, NULL, 0); GNUNET_ATS_address_in_use (GST_ats, na->address, na->session, GNUNET_YES); GST_validation_set_address_use (na->address, na->session, GNUNET_YES, __LINE__); @@ -1731,10 +1731,10 @@ handle_test_blacklist_cont (void *cls, if (GNUNET_OK == result) { /* valid new address, let ATS know! */ - GNUNET_ATS_address_update (GST_ats, - bcc->na.address, - bcc->na.session, - bcc->ats, bcc->ats_count); + GNUNET_ATS_address_add (GST_ats, + bcc->na.address, + bcc->na.session, + bcc->ats, bcc->ats_count); } if (NULL == (n = lookup_neighbour (peer))) goto cleanup; /* nobody left to care about new address */ diff --git a/src/transport/gnunet-service-transport_validation.c b/src/transport/gnunet-service-transport_validation.c index 89977eac4..3e6100a29 100644 --- a/src/transport/gnunet-service-transport_validation.c +++ b/src/transport/gnunet-service-transport_validation.c @@ -661,7 +661,7 @@ add_valid_address (void *cls, const struct GNUNET_HELLO_Address *address, if (GNUNET_SCHEDULER_NO_TASK == ve->revalidation_task) ve->revalidation_task = GNUNET_SCHEDULER_add_now (&revalidate_address, ve); - GNUNET_ATS_address_update (GST_ats, address, NULL, NULL, 0); + GNUNET_ATS_address_add (GST_ats, address, NULL, NULL, 0); return GNUNET_OK; } @@ -1094,7 +1094,7 @@ GST_validation_handle_pong (const struct GNUNET_PeerIdentity *sender, ats.type = htonl (GNUNET_ATS_QUALITY_NET_DELAY); ats.value = htonl ((uint32_t) ve->latency.rel_value); - GNUNET_ATS_address_update (GST_ats, ve->address, NULL, &ats, 1); + GNUNET_ATS_address_add (GST_ats, ve->address, NULL, &ats, 1); } /* build HELLO to store in PEERINFO */ ve->copied = GNUNET_NO; -- 2.25.1